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); } } }