diff --git a/src/main/java/xonin/backhand/BackhandLateMixins.java b/src/main/java/xonin/backhand/BackhandLateMixins.java deleted file mode 100644 index 787e527..0000000 --- a/src/main/java/xonin/backhand/BackhandLateMixins.java +++ /dev/null @@ -1,23 +0,0 @@ -package xonin.backhand; - -import java.util.List; -import java.util.Set; - -import com.gtnewhorizon.gtnhmixins.ILateMixinLoader; -import com.gtnewhorizon.gtnhmixins.LateMixin; - -import xonin.backhand.mixins.Mixins; - -@LateMixin -public class BackhandLateMixins implements ILateMixinLoader { - - @Override - public String getMixinConfig() { - return "mixins.backhand.late.json"; - } - - @Override - public List getMixins(Set loadedMods) { - return Mixins.getLateMixins(loadedMods); - } -} diff --git a/src/main/java/xonin/backhand/api/core/BackhandUtils.java b/src/main/java/xonin/backhand/api/core/BackhandUtils.java index 766104c..488ff24 100644 --- a/src/main/java/xonin/backhand/api/core/BackhandUtils.java +++ b/src/main/java/xonin/backhand/api/core/BackhandUtils.java @@ -1,5 +1,7 @@ package xonin.backhand.api.core; +import java.util.ArrayList; +import java.util.List; import java.util.function.BooleanSupplier; import javax.annotation.Nullable; @@ -15,6 +17,8 @@ @ParametersAreNonnullByDefault public final class BackhandUtils { + public static final List> offhandPriorityItems = new ArrayList<>(); + public static void swapOffhandItem(EntityPlayer player) { ItemStack mainHand = player.getCurrentEquippedItem(); player.setCurrentItemOrArmor(0, BackhandUtils.getOffhandItem(player)); @@ -62,4 +66,11 @@ public static boolean isUsingOffhand(EntityPlayer player) { public static int getOffhandSlot(EntityPlayer player) { return ((IOffhandInventory) player.inventory).backhand$getOffhandSlot(); } + + /** + * Adds an item that when held in the main hand will execute the offhand item action before the main hand action + */ + public static void addOffhandPriorityItem(Class itemClass) { + offhandPriorityItems.add(itemClass); + } } diff --git a/src/main/java/xonin/backhand/client/ClientProxy.java b/src/main/java/xonin/backhand/client/ClientProxy.java index cdefad9..df5ce15 100644 --- a/src/main/java/xonin/backhand/client/ClientProxy.java +++ b/src/main/java/xonin/backhand/client/ClientProxy.java @@ -1,16 +1,11 @@ package xonin.backhand.client; -import java.util.ArrayList; -import java.util.List; - import net.minecraft.client.settings.KeyBinding; import org.lwjgl.input.Keyboard; import cpw.mods.fml.client.registry.ClientRegistry; -import tconstruct.library.tools.HarvestTool; import xonin.backhand.CommonProxy; -import xonin.backhand.utils.Mods; public class ClientProxy extends CommonProxy { @@ -19,14 +14,9 @@ public class ClientProxy extends CommonProxy { Keyboard.KEY_F, "key.categories.gameplay"); - public static final List> offhandPriorityItems = new ArrayList<>(); - @Override public void load() { + super.load(); ClientRegistry.registerKeyBinding(swapOffhand); - - if (Mods.TINKERS_CONSTRUCT.isLoaded()) { - offhandPriorityItems.add(HarvestTool.class); - } } } diff --git a/src/main/java/xonin/backhand/compat/EFRCompat.java b/src/main/java/xonin/backhand/compat/EFRCompat.java new file mode 100644 index 0000000..a032e0e --- /dev/null +++ b/src/main/java/xonin/backhand/compat/EFRCompat.java @@ -0,0 +1,36 @@ +package xonin.backhand.compat; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraftforge.event.entity.living.LivingHurtEvent; + +import com.gtnewhorizon.gtnhlib.eventbus.EventBusSubscriber; + +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import ganymedes01.etfuturum.ModItems; +import ganymedes01.etfuturum.core.handlers.ServerEventHandler; +import xonin.backhand.api.core.BackhandUtils; +import xonin.backhand.utils.Mods; + +@SuppressWarnings("unused") +@EventBusSubscriber +public class EFRCompat { + + @EventBusSubscriber.Condition + public static boolean register() { + return Mods.ET_FUTURUM.isLoaded(); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public static void onEntityHurt(LivingHurtEvent event) { + if (!(event.entityLiving instanceof EntityPlayer player)) return; + ItemStack offhand = BackhandUtils.getOffhandItem(player); + if (offhand == null) return; + Item totem = ModItems.TOTEM_OF_UNDYING.get(); + if (totem.equals(offhand.getItem())) { + BackhandUtils.useOffhandItem(player, () -> ServerEventHandler.INSTANCE.handleTotemCheck(player, event)); + } + } +} diff --git a/src/main/java/xonin/backhand/compat/TConstructCompat.java b/src/main/java/xonin/backhand/compat/TConstructCompat.java new file mode 100644 index 0000000..c4510dd --- /dev/null +++ b/src/main/java/xonin/backhand/compat/TConstructCompat.java @@ -0,0 +1,103 @@ +package xonin.backhand.compat; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.event.entity.living.LivingAttackEvent; +import net.minecraftforge.event.entity.living.LivingHurtEvent; + +import com.gtnewhorizon.gtnhlib.eventbus.EventBusSubscriber; + +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import tconstruct.library.tools.HarvestTool; +import tconstruct.library.weaponry.IWindup; +import tconstruct.tools.TinkerToolEvents; +import tconstruct.tools.TinkerTools; +import tconstruct.weaponry.client.CrosshairHandler; +import tconstruct.world.TinkerWorldEvents; +import xonin.backhand.api.core.BackhandUtils; +import xonin.backhand.utils.Mods; + +@SuppressWarnings("unused") +@EventBusSubscriber +public class TConstructCompat { + + private static CrosshairHandler crosshairHandler; + private static MethodHandle onHurt, onAttack; + + @EventBusSubscriber.Condition + public static boolean register() { + if (Mods.TINKERS_CONSTRUCT.isLoaded()) { + try { + // Gotta hide those NEW instructions from the JVM + crosshairHandler = CrosshairHandler.class.getConstructor() + .newInstance(); + // These need to be MethodHandles since the compiler complains about Mobs-Info not being present + // otherwise + onHurt = MethodHandles.publicLookup() + .findVirtual( + TinkerWorldEvents.class, + "onHurt", + MethodType.methodType(void.class, LivingHurtEvent.class)) + .bindTo( + TinkerWorldEvents.class.getConstructor() + .newInstance()); + onAttack = MethodHandles.publicLookup() + .findVirtual( + TinkerToolEvents.class, + "onAttack", + MethodType.methodType(void.class, LivingAttackEvent.class)) + .bindTo( + TinkerToolEvents.class.getConstructor() + .newInstance()); + } catch (Exception ignored) {} + BackhandUtils.addOffhandPriorityItem(HarvestTool.class); + return true; + } + return false; + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public static void onEntityHurt(LivingHurtEvent event) { + if (!(event.entityLiving instanceof EntityPlayer player) || event.ammount == 0) return; + ItemStack offhandItem = BackhandUtils.getOffhandItem(player); + if (offhandItem == null) return; + if (offhandItem.getItem() == TinkerTools.cutlass || offhandItem.getItem() == TinkerTools.battlesign) { + BackhandUtils.useOffhandItem(player, () -> { + try { + onHurt.invokeWithArguments(event); + } catch (Throwable ignored) {} + }); + } + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public static void onAttack(LivingAttackEvent event) { + if (!(event.entityLiving instanceof EntityPlayer player)) return; + ItemStack offhand = BackhandUtils.getOffhandItem(player); + if (offhand == null) return; + if (offhand.getItem() == TinkerTools.battlesign) { + BackhandUtils.useOffhandItem(player, () -> { + try { + onAttack.invokeWithArguments(event); + } catch (Throwable ignored) {} + }); + } + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public static void onRenderOverlay(RenderGameOverlayEvent.Pre event) { + if (event.type != RenderGameOverlayEvent.ElementType.CROSSHAIRS) return; + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + ItemStack offhand = BackhandUtils.getOffhandItem(player); + if (offhand != null && offhand.getItem() instanceof IWindup) { + BackhandUtils.useOffhandItem(player, () -> crosshairHandler.onRenderOverlay(event)); + } + } +} diff --git a/src/main/java/xonin/backhand/coremod/BackhandLoadingPlugin.java b/src/main/java/xonin/backhand/coremod/BackhandLoadingPlugin.java index 4121874..4039cf9 100644 --- a/src/main/java/xonin/backhand/coremod/BackhandLoadingPlugin.java +++ b/src/main/java/xonin/backhand/coremod/BackhandLoadingPlugin.java @@ -4,6 +4,9 @@ import java.util.Map; import java.util.Set; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader; import cpw.mods.fml.relauncher.IFMLLoadingPlugin; @@ -11,6 +14,8 @@ public final class BackhandLoadingPlugin implements IFMLLoadingPlugin, IEarlyMixinLoader { + public static final Logger LOGGER = LogManager.getLogger(BackhandLoadingPlugin.class); + @Override public String[] getASMTransformerClass() { return null; diff --git a/src/main/java/xonin/backhand/mixins/Mixins.java b/src/main/java/xonin/backhand/mixins/Mixins.java index 959a914..db69dee 100644 --- a/src/main/java/xonin/backhand/mixins/Mixins.java +++ b/src/main/java/xonin/backhand/mixins/Mixins.java @@ -9,7 +9,7 @@ import java.util.stream.Collectors; import cpw.mods.fml.relauncher.FMLLaunchHandler; -import xonin.backhand.Backhand; +import xonin.backhand.coremod.BackhandLoadingPlugin; public enum Mixins { @@ -39,17 +39,7 @@ public enum Mixins { "minecraft.MixinGuiContainerCreative") .setPhase(Phase.EARLY) .setSide(Side.CLIENT) - .addTargetedMod(TargetedMod.VANILLA)), - ET_FUTURUM_TOTEM_SUPPORT( - new Builder("Et Futurum Totem Support").addMixinClasses("etfuturum.MixinServerEventHandler") - .setPhase(Phase.LATE) - .setSide(Side.BOTH) - .addTargetedMod(TargetedMod.ET_FUTURUM)), - TINKERS_CROSSHAIR_FIX(new Builder("Fix crosshair not rendering for offhand weapon") - .addMixinClasses("tconstruct.MixinCrosshairHandler") - .setPhase(Phase.LATE) - .setSide(Side.CLIENT) - .addTargetedMod(TargetedMod.TINKERS_CONSTRUCT)),; + .addTargetedMod(TargetedMod.VANILLA)),; private final List mixinClasses; private final Supplier applyIf; @@ -86,7 +76,7 @@ public static List getEarlyMixins(Set loadedCoreMods) { } } } - Backhand.LOGGER.info("Not loading the following EARLY mixins: {}", notLoading); + BackhandLoadingPlugin.LOGGER.info("Not loading the following EARLY mixins: {}", notLoading); return mixins; } @@ -102,7 +92,7 @@ public static List getLateMixins(Set loadedMods) { } } } - Backhand.LOGGER.info("Not loading the following LATE mixins: {}", notLoading.toString()); + BackhandLoadingPlugin.LOGGER.info("Not loading the following LATE mixins: {}", notLoading.toString()); return mixins; } diff --git a/src/main/java/xonin/backhand/mixins/TargetedMod.java b/src/main/java/xonin/backhand/mixins/TargetedMod.java index c075c24..9785e2b 100644 --- a/src/main/java/xonin/backhand/mixins/TargetedMod.java +++ b/src/main/java/xonin/backhand/mixins/TargetedMod.java @@ -2,9 +2,7 @@ public enum TargetedMod { - VANILLA("Minecraft", null), - ET_FUTURUM("Et Futurum Requiem", "ganymedes01.etfuturum.mixinplugin.EtFuturumEarlyMixins", "etfuturum"), - TINKERS_CONSTRUCT("Tinkers' Construct", null, "TConstruct"); + VANILLA("Minecraft", null); /** The "name" in the @Mod annotation */ public final String modName; diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinMinecraft.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinMinecraft.java index 0a60b6a..7991315 100644 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinMinecraft.java +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinMinecraft.java @@ -28,7 +28,6 @@ import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.client.ClientProxy; import xonin.backhand.client.utils.BackhandRenderHelper; import xonin.backhand.utils.BackhandConfig; @@ -267,7 +266,7 @@ public void func_147121_ag() { private boolean backhand$doesOffhandNeedPriority(ItemStack mainHandItem) { if (mainHandItem == null) return false; - for (Class clazz : ClientProxy.offhandPriorityItems) { + for (Class clazz : BackhandUtils.offhandPriorityItems) { if (clazz.isAssignableFrom( mainHandItem.getItem() .getClass())) { diff --git a/src/main/java/xonin/backhand/mixins/late/etfuturum/MixinServerEventHandler.java b/src/main/java/xonin/backhand/mixins/late/etfuturum/MixinServerEventHandler.java deleted file mode 100644 index 753b308..0000000 --- a/src/main/java/xonin/backhand/mixins/late/etfuturum/MixinServerEventHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -package xonin.backhand.mixins.late.etfuturum; - -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraftforge.event.entity.living.LivingHurtEvent; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import ganymedes01.etfuturum.ModItems; -import ganymedes01.etfuturum.core.handlers.ServerEventHandler; -import xonin.backhand.api.core.BackhandUtils; - -@Mixin(value = ServerEventHandler.class, remap = false) -public abstract class MixinServerEventHandler { - - @Shadow - public abstract void handleTotemCheck(EntityLivingBase entity, LivingHurtEvent event); - - @Unique - private boolean backhand$skipCheck; - - @Inject( - method = "handleTotemCheck", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/entity/EntityLivingBase;getHeldItem()Lnet/minecraft/item/ItemStack;", - remap = true, - ordinal = 0), - cancellable = true) - private void backhand$useOffhandTotem(EntityLivingBase entity, LivingHurtEvent event, CallbackInfo ci) { - if (backhand$skipCheck || !(entity instanceof EntityPlayer player)) return; - ItemStack offhand = BackhandUtils.getOffhandItem(player); - if (offhand == null) return; - Item totem = ModItems.TOTEM_OF_UNDYING.get(); - if (totem.equals(offhand.getItem())) { - ci.cancel(); - backhand$skipCheck = true; - BackhandUtils.useOffhandItem(player, () -> handleTotemCheck(entity, event)); - backhand$skipCheck = false; - } - } -} diff --git a/src/main/java/xonin/backhand/mixins/late/tconstruct/MixinCrosshairHandler.java b/src/main/java/xonin/backhand/mixins/late/tconstruct/MixinCrosshairHandler.java deleted file mode 100644 index a7ceb30..0000000 --- a/src/main/java/xonin/backhand/mixins/late/tconstruct/MixinCrosshairHandler.java +++ /dev/null @@ -1,34 +0,0 @@ -package xonin.backhand.mixins.late.tconstruct; - -import net.minecraft.client.Minecraft; -import net.minecraft.item.ItemStack; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; - -import tconstruct.library.weaponry.IWindup; -import tconstruct.weaponry.client.CrosshairHandler; -import xonin.backhand.api.core.BackhandUtils; - -@Mixin(CrosshairHandler.class) -public class MixinCrosshairHandler { - - @ModifyExpressionValue( - method = "onRenderOverlay", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/entity/EntityClientPlayerMP;getCurrentEquippedItem()Lnet/minecraft/item/ItemStack;", - ordinal = 0), - remap = false) - private ItemStack backhand$onRenderOverlay(ItemStack original) { - if (original == null || !(original.getItem() instanceof IWindup)) { - ItemStack offhand = BackhandUtils.getOffhandItem(Minecraft.getMinecraft().thePlayer); - if (offhand != null && offhand.getItem() instanceof IWindup) { - return offhand; - } - } - return original; - } -} diff --git a/src/main/java/xonin/backhand/utils/Mods.java b/src/main/java/xonin/backhand/utils/Mods.java index 60b62d1..f473cbe 100644 --- a/src/main/java/xonin/backhand/utils/Mods.java +++ b/src/main/java/xonin/backhand/utils/Mods.java @@ -6,7 +6,8 @@ public enum Mods { INV_TWEAKS("inventorytweaks"), DOUBLE_WIDE_SURPRISE("dws"), - TINKERS_CONSTRUCT("TConstruct"),; + TINKERS_CONSTRUCT("TConstruct"), + ET_FUTURUM("etfuturum"),; private final String modId; private Boolean loaded;