diff --git a/src/main/java/ftbsc/bscv/modules/self/NoSlow.java b/src/main/java/ftbsc/bscv/modules/self/NoSlow.java new file mode 100644 index 0000000..a704ee2 --- /dev/null +++ b/src/main/java/ftbsc/bscv/modules/self/NoSlow.java @@ -0,0 +1,16 @@ +package ftbsc.bscv.modules.self; + +import com.google.auto.service.AutoService; + +import ftbsc.bscv.api.ILoadable; +import ftbsc.bscv.modules.AbstractModule; +import ftbsc.bscv.patches.NoSlowPatch.PlayerSlowDownEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +@AutoService(ILoadable.class) +public class NoSlow extends AbstractModule { + @SubscribeEvent + public void onPlayerSlowDown(PlayerSlowDownEvent event) { + event.setCanceled(true); + } +} diff --git a/src/main/java/ftbsc/bscv/patches/NoSlowPatch.java b/src/main/java/ftbsc/bscv/patches/NoSlowPatch.java new file mode 100644 index 0000000..98400ef --- /dev/null +++ b/src/main/java/ftbsc/bscv/patches/NoSlowPatch.java @@ -0,0 +1,64 @@ +package ftbsc.bscv.patches; + +import ftbsc.lll.processor.annotations.Injector; +import ftbsc.lll.processor.annotations.Patch; +import ftbsc.lll.processor.annotations.Target; +import ftbsc.lll.tools.InsnSequence; +import ftbsc.lll.tools.PatternMatcher; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.Cancelable; +import net.minecraftforge.eventbus.api.Event; + +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.*; + +public class NoSlowPatch { + + @Cancelable + public static class PlayerSlowDownEvent extends Event { } + + public static boolean shouldSlowPlayer() { + return MinecraftForge.EVENT_BUS.post(new PlayerSlowDownEvent()); + } + + @Patch(value = ClientPlayerEntity.class, reason = "add hook to cancel slowing down effect of using items") + public abstract static class SlowDownOverride implements Opcodes { + @Target + abstract void aiStep(); + + @Injector + public void inject(ClassNode clazz, MethodNode main) { + AbstractInsnNode found = PatternMatcher.builder() + .opcodes(ALOAD, INVOKEVIRTUAL, IFEQ, ALOAD, INVOKEVIRTUAL, IFNE) + .ignoreFrames() + .ignoreLabels() + .ignoreLineNumbers() + .build() + .find(main) + .getLast(); + + AbstractInsnNode after = PatternMatcher.builder() + .opcodes(ALOAD, ICONST_0, PUTFIELD) + .ignoreFrames() + .ignoreLabels() + .ignoreLineNumbers() + .build() + .find(main) + .getLast(); + + LabelNode skip = new LabelNode(); // TODO can we get the label that the original IF is jumping to without adding one ourselves? + InsnSequence is = new InsnSequence(); + is.add(new MethodInsnNode( + INVOKESTATIC, + "ftbsc/bscv/patches/NoSlowPatch", + "shouldSlowPlayer", + "()Z" + )); + is.add(new JumpInsnNode(IFNE, skip)); + + main.instructions.insert(found, is); + main.instructions.insert(after, skip); + } + } +}