diff --git a/dependencies.gradle b/dependencies.gradle index 7f72087..79e353a 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -34,9 +34,9 @@ * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph */ dependencies { - api("com.github.GTNewHorizons:GTNHLib:0.6.0:dev") - runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.7.13-GTNH:dev") + api("com.github.GTNewHorizons:GTNHLib:0.6.2:dev") + compileOnly("com.github.GTNewHorizons:TinkersConstruct:1.13.4-GTNH:dev") + runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.7.18-GTNH:dev") compileOnly("com.github.GTNewHorizons:inventory-tweaks:1.7.0:dev") - compileOnly(deobf("https://github.com/Roadhog360/Et-Futurum-Requiem/releases/download/2.6.0/Et_Futurum_Requiem-2.6.0-nomixin.jar", "Et Futurum Requiem")) - compileOnly("com.github.GTNewHorizons:CarpentersBlocks:3.7.0-GTNH:dev") + compileOnly(rfg.deobf('maven.modrinth:etfuturum:2.6.2')) } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c35211..a4b76b9 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/settings.gradle b/settings.gradle index 16e84e7..dd825d7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,5 +17,5 @@ pluginManagement { } plugins { - id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.30' + id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.31' } diff --git a/src/main/java/xonin/backhand/Backhand.java b/src/main/java/xonin/backhand/Backhand.java index 921770b..2493f40 100644 --- a/src/main/java/xonin/backhand/Backhand.java +++ b/src/main/java/xonin/backhand/Backhand.java @@ -2,7 +2,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.server.MinecraftServer; -import net.minecraftforge.common.MinecraftForge; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -11,12 +10,10 @@ import com.gtnewhorizon.gtnhlib.config.ConfigurationManager; import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; -import cpw.mods.fml.common.event.FMLServerStoppingEvent; import xonin.backhand.packet.BackhandPacketHandler; import xonin.backhand.utils.BackhandConfig; import xonin.backhand.utils.BackhandConfigClient; @@ -37,11 +34,9 @@ public class Backhand { @SidedProxy(clientSide = "xonin.backhand.client.ClientProxy", serverSide = "xonin.backhand.CommonProxy") public static CommonProxy proxy; public static BackhandPacketHandler packetHandler; - public static boolean isEFRLoaded; @Mod.EventHandler public void load(FMLPreInitializationEvent event) { - isEFRLoaded = Loader.isModLoaded("etfuturum"); try { ConfigurationManager.registerConfig(BackhandConfig.class); ConfigurationManager.registerConfig(BackhandConfigClient.class); @@ -50,16 +45,6 @@ public void load(FMLPreInitializationEvent event) { } proxy.load(); - - MinecraftForge.EVENT_BUS.register(new ServerEventsHandler()); - FMLCommonHandler.instance() - .bus() - .register(new ServerTickHandler()); - - MinecraftForge.EVENT_BUS.register(HookContainerClass.INSTANCE); - FMLCommonHandler.instance() - .bus() - .register(HookContainerClass.INSTANCE); } @Mod.EventHandler @@ -68,11 +53,6 @@ public void init(FMLInitializationEvent event) { packetHandler.register(); } - @Mod.EventHandler - public void onServerStopping(FMLServerStoppingEvent event) { - proxy.onServerStopping(event); - } - public static MinecraftServer getServer() { return FMLCommonHandler.instance() .getMinecraftServerInstance(); diff --git a/src/main/java/xonin/backhand/CommonProxy.java b/src/main/java/xonin/backhand/CommonProxy.java index 4cc40ce..7454f82 100644 --- a/src/main/java/xonin/backhand/CommonProxy.java +++ b/src/main/java/xonin/backhand/CommonProxy.java @@ -1,60 +1,51 @@ package xonin.backhand; +import javax.annotation.Nullable; + +import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.FakePlayer; + +import com.gtnewhorizon.gtnhlib.eventbus.EventBusSubscriber; -import cpw.mods.fml.common.event.FMLServerStoppingEvent; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.PlayerEvent; import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.utils.EnumAnimations; +import xonin.backhand.packet.OffhandConfigSyncPacket; +import xonin.backhand.packet.OffhandSyncItemPacket; +@EventBusSubscriber public class CommonProxy { - public static ItemStack offhandItemUsed; - - public void load() { - - } + public void load() {} - public void onServerStopping(FMLServerStoppingEvent event) { - for (EntityPlayer player : Backhand.getServer() - .getConfigurationManager().playerEntityList) { - if (BackhandUtils.getOffhandItem(player) != null) { - BackhandUtils.resetAndDelayHotswap(player, 0); + @SubscribeEvent + public static void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) { + if (!(event.player instanceof EntityPlayerMP playerMP)) { + return; + } + Backhand.packetHandler.sendPacketToPlayer(new OffhandConfigSyncPacket().generatePacket(), playerMP); + ItemStack offhandItem = BackhandUtils.getOffhandItem(playerMP); + if (Backhand.isOffhandBlacklisted(offhandItem)) { + BackhandUtils.setPlayerOffhandItem(playerMP, null); + if (!playerMP.inventory.addItemStackToInventory(offhandItem)) { + event.player.entityDropItem(offhandItem, 0); } } } - public EntityPlayer getClientPlayer() { - return null; - } - - public void sendAnimationPacket(EnumAnimations animation, EntityPlayer entityPlayer) {} - - // Should not be called on the server anyway - public boolean isRightClickHeld() { - return false; - } - - public int getRightClickCounter() { - return 0; - } - - public void setRightClickCounter(int i) {} - - public int getRightClickDelay() { - return 0; - } - - // Should not be called on the server anyway - public boolean isLeftClickHeld() { - return false; + @SubscribeEvent + public static void addTracking(net.minecraftforge.event.entity.player.PlayerEvent.StartTracking event) { + if (event.entityPlayer instanceof EntityPlayerMP playerMP && isValidPlayer(event.target)) { + Backhand.packetHandler + .sendPacketToPlayer(new OffhandSyncItemPacket((EntityPlayer) event.target).generatePacket(), playerMP); + } } - // Should not be called on the server anyway - public int getLeftClickCounter() { - return 0; + private static boolean isValidPlayer(@Nullable Entity entity) { + return entity instanceof EntityPlayerMP playerMP + && !(entity instanceof FakePlayer || playerMP.playerNetServerHandler == null); } - - // Should not be called on the server anyway - public void setLeftClickCounter(int i) {} } diff --git a/src/main/java/xonin/backhand/HookContainerClass.java b/src/main/java/xonin/backhand/HookContainerClass.java deleted file mode 100644 index 989927b..0000000 --- a/src/main/java/xonin/backhand/HookContainerClass.java +++ /dev/null @@ -1,377 +0,0 @@ -package xonin.backhand; - -import net.minecraft.block.Block; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityList; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemBucket; -import net.minecraft.item.ItemDoor; -import net.minecraft.item.ItemMonsterPlacer; -import net.minecraft.item.ItemRedstone; -import net.minecraft.item.ItemReed; -import net.minecraft.item.ItemSeedFood; -import net.minecraft.item.ItemSign; -import net.minecraft.item.ItemSkull; -import net.minecraft.item.ItemStack; -import net.minecraft.util.MathHelper; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; -import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.entity.EntityEvent; -import net.minecraftforge.event.entity.EntityJoinWorldEvent; -import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; - -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.eventhandler.EventPriority; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import xonin.backhand.api.PlayerEventChild; -import xonin.backhand.api.core.BackhandTranslator; -import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.api.core.IBackhandPlayer; -import xonin.backhand.api.core.InventoryPlayerBackhand; -import xonin.backhand.api.core.OffhandExtendedProperty; -import xonin.backhand.packet.OffhandConfigSyncPacket; -import xonin.backhand.packet.OffhandPlaceBlockPacket; -import xonin.backhand.packet.OffhandSyncItemPacket; -import xonin.backhand.utils.BackhandConfig; -import xonin.backhand.utils.EnumAnimations; - -public final class HookContainerClass { - - public static final HookContainerClass INSTANCE = new HookContainerClass(); - - private HookContainerClass() {} - - private boolean isFake(Entity entity) { - return entity instanceof FakePlayer; - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public void onEntityJoin(EntityJoinWorldEvent event) { - if (event.entity instanceof EntityPlayer player && !(isFake(player))) { - if (FMLCommonHandler.instance() - .getEffectiveSide() == Side.SERVER) { - if (!(player.inventory instanceof InventoryPlayerBackhand)) { - Backhand.LOGGER.info("Player inventory has been replaced with {}", player.inventory.getClass()); - } - Backhand.packetHandler.sendPacketToPlayer( - new OffhandConfigSyncPacket(player).generatePacket(), - (EntityPlayerMP) event.entity); - Backhand.packetHandler.sendPacketToPlayer( - new OffhandSyncItemPacket(player).generatePacket(), - (EntityPlayerMP) event.entity); - } - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - if (Backhand.isOffhandBlacklisted(offhandItem)) { - BackhandUtils.setPlayerOffhandItem(player, null); - if (!player.inventory.addItemStackToInventory(offhandItem)) { - event.entity.entityDropItem(offhandItem, 0); - } - } - } - } - - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onEntityConstructing(EntityEvent.EntityConstructing event) { - if (!(event.entity instanceof EntityPlayer player && !(isFake(event.entity)))) return; - event.entity.registerExtendedProperties("OffhandStorage", new OffhandExtendedProperty(player)); - } - - public static MovingObjectPosition getRaytraceBlock(EntityPlayer p) { - float scaleFactor = 1.0F; - float rotPitch = p.prevRotationPitch + (p.rotationPitch - p.prevRotationPitch) * scaleFactor; - float rotYaw = p.prevRotationYaw + (p.rotationYaw - p.prevRotationYaw) * scaleFactor; - double testX = p.prevPosX + (p.posX - p.prevPosX) * scaleFactor; - double testY = p.prevPosY + (p.posY - p.prevPosY) * scaleFactor + 1.62D - p.yOffset;// 1.62 is player eye height - double testZ = p.prevPosZ + (p.posZ - p.prevPosZ) * scaleFactor; - Vec3 testVector = Vec3.createVectorHelper(testX, testY, testZ); - float var14 = MathHelper.cos(-rotYaw * 0.017453292F - (float) Math.PI); - float var15 = MathHelper.sin(-rotYaw * 0.017453292F - (float) Math.PI); - float var16 = -MathHelper.cos(-rotPitch * 0.017453292F); - float vectorY = MathHelper.sin(-rotPitch * 0.017453292F); - float vectorX = var15 * var16; - float vectorZ = var14 * var16; - double reachLength = 5.0D; - Vec3 testVectorFar = testVector.addVector(vectorX * reachLength, vectorY * reachLength, vectorZ * reachLength); - return p.worldObj.rayTraceBlocks(testVector, testVectorFar, false); - } - - @SubscribeEvent - public void playerInteract(PlayerInteractEvent event) { - if (isFake(event.entityPlayer)) return; - - if (!BackhandConfig.EmptyOffhand && BackhandUtils.getOffhandItem(event.entityPlayer) == null) { - return; - } - - if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_AIR - || event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) {// Right click - ItemStack mainHandItem = event.entityPlayer.getCurrentEquippedItem(); - ItemStack offhandItem = BackhandUtils.getOffhandItem(event.entityPlayer); - - if (mainHandItem != null - && (BackhandUtils.checkForRightClickFunction(mainHandItem) || offhandItem == null)) { - return; - } - - if (event.action != PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK && Backhand.proxy.isRightClickHeld()) { - Backhand.proxy.setRightClickCounter(Backhand.proxy.getRightClickCounter() + 1); - if (Backhand.proxy.getRightClickCounter() > 1) { - return; - } - } - - if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK && mainHandItem != null - && mainHandItem.getItem() instanceof ItemMonsterPlacer) { - if (event.world.isRemote && !event.entityPlayer.capabilities.isCreativeMode) { - mainHandItem.stackSize--; - } - } - - boolean swingHand = true; - PlayerInteractEvent.Result blk = event.useBlock; - PlayerInteractEvent.Result itm = event.useItem; - event.useBlock = PlayerInteractEvent.Result.DENY; - MovingObjectPosition mop = getRaytraceBlock(event.entityPlayer); - if (mop != null) { - event.setCanceled(true); - int i = mop.blockX, j = mop.blockY, k = mop.blockZ; - - if (!event.entityPlayer.isSneaking() - && canBlockBeInteractedWith(event.entityPlayer.worldObj, i, j, k)) { - event.setCanceled(false); - event.useBlock = blk; - event.useItem = itm; - swingHand = false; - } - } - if (event.entityPlayer.worldObj.isRemote && !BackhandUtils.usagePriorAttack(offhandItem) - && BackhandConfig.OffhandAttack - && swingHand) { - HookContainerClass.sendOffSwingEventNoCheck(event.entityPlayer, mainHandItem, offhandItem); - } - } - } - - private static String[] activatedBlockMethodNames = { - BackhandTranslator.getMapedMethodName("Block", "func_149727_a", "onBlockActivated"), - BackhandTranslator.getMapedMethodName("Block", "func_149699_a", "onBlockClicked") }; - private static Class[][] activatedBlockMethodParams = { - new Class[] { World.class, int.class, int.class, int.class, EntityPlayer.class, int.class, float.class, - float.class, float.class }, - new Class[] { World.class, int.class, int.class, int.class, EntityPlayer.class } }; - - @SuppressWarnings("unchecked") - public static boolean canBlockBeInteractedWith(World worldObj, int x, int y, int z) { - if (worldObj == null) return false; - Block block = worldObj.getBlock(x, y, z); - if (block == null) return false; - if (block.getClass() - .equals(Block.class)) return false; - try { - Class c = block.getClass(); - while (!(c.equals(Block.class))) { - try { - try { - c.getDeclaredMethod(activatedBlockMethodNames[0], activatedBlockMethodParams[0]); - return true; - } catch (NoSuchMethodException ignored) {} - - try { - c.getDeclaredMethod(activatedBlockMethodNames[1], activatedBlockMethodParams[1]); - return true; - } catch (NoSuchMethodException ignored) {} - } catch (NoClassDefFoundError ignored) { - - } - - c = c.getSuperclass(); - } - - return false; - } catch (NullPointerException e) { - return true; - } - } - - public static boolean changedHeldItemTooltips = false; - // used in hostwapping the item to dig with, to remember where to return the main slot to - public static int prevOffhandOffset; - - public static boolean isItemBlock(Item item) { - return item instanceof ItemBlock || item instanceof ItemDoor - || item instanceof ItemSign - || item instanceof ItemReed - || item instanceof ItemSeedFood - || item instanceof ItemRedstone - || item instanceof ItemBucket - || item instanceof ItemSkull; - } - - /** - * Attempts to right-click-use an item by the given EntityPlayer - */ - public static boolean tryUseItem(EntityPlayer player, ItemStack itemStack, Side side) { - if (side.isClient()) { - Backhand.packetHandler.sendPacketToServer( - new OffhandPlaceBlockPacket(-1, -1, -1, 255, itemStack, 0.0F, 0.0F, 0.0F).generatePacket()); - } - - if (itemStack == null || player.getCurrentEquippedItem() == null) return false; - - final int i = itemStack.stackSize; - final int j = itemStack.getItemDamage(); - ItemStack prevHeldItem = player.getCurrentEquippedItem(); - - player.setCurrentItemOrArmor(0, itemStack); - ItemStack itemUsed = player.getCurrentEquippedItem() - .copy(); - ItemStack itemStackResult = itemStack.useItemRightClick(player.getEntityWorld(), player); - if (!ItemStack.areItemStacksEqual(itemUsed, itemStackResult)) { - BackhandUtils.setPlayerOffhandItem(player, itemStackResult); - BackhandUtils.getOffhandEP(player).syncOffhand = true; - if (player.getCurrentEquippedItem() == null || player.getCurrentEquippedItem().stackSize == 0) { - ForgeEventFactory.onPlayerDestroyItem(player, player.getCurrentEquippedItem()); - } - } - - player.setCurrentItemOrArmor(0, prevHeldItem); - CommonProxy.offhandItemUsed = itemStackResult; - - if (itemStackResult == itemStack && itemStackResult.stackSize == i - && (!side.isServer() - || itemStackResult.getMaxItemUseDuration() <= 0 && itemStackResult.getItemDamage() == j)) { - return false; - } else { - BackhandUtils.setPlayerOffhandItem(player, itemStackResult); - if (side.isServer() && (player).capabilities.isCreativeMode) { - itemStackResult.stackSize = i; - if (itemStackResult.isItemStackDamageable()) { - itemStackResult.setItemDamage(j); - } - } - if (itemStackResult.stackSize <= 0) { - BackhandUtils.setPlayerOffhandItem(player, null); - ForgeEventFactory.onPlayerDestroyItem(player, itemStackResult); - } - if (side.isServer() && !player.isUsingItem()) { - ((EntityPlayerMP) player).sendContainerToPlayer(player.inventoryContainer); - } - return true; - } - } - - @SideOnly(Side.CLIENT) - public static void sendOffSwingEvent(PlayerEvent event, ItemStack mainHandItem, ItemStack offhandItem) { - if (!MinecraftForge.EVENT_BUS.post(new PlayerEventChild.OffhandSwingEvent(event, mainHandItem, offhandItem))) { - ((IBackhandPlayer) event.entityPlayer).swingOffItem(); - Backhand.proxy.sendAnimationPacket(EnumAnimations.OffHandSwing, event.entityPlayer); - } - } - - @SideOnly(Side.CLIENT) - public static void sendOffSwingEventNoCheck(EntityPlayer player, ItemStack mainHandItem, ItemStack offhandItem) { - ((IBackhandPlayer) player).swingOffItem(); - Backhand.proxy.sendAnimationPacket(EnumAnimations.OffHandSwing, player); - } - - @SideOnly(Side.CLIENT) - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onOffhandSwing(PlayerEventChild.OffhandSwingEvent event) {} - - public boolean interactWithNoEvent(EntityPlayer pl, Entity p_70998_1_) { - ItemStack itemstack = pl.getCurrentEquippedItem(); - ItemStack itemstack1 = ItemStack.copyItemStack(itemstack); - - if (!p_70998_1_.interactFirst(pl)) { - if (itemstack != null && p_70998_1_ instanceof EntityLivingBase) { - if (pl.capabilities.isCreativeMode) { - itemstack = itemstack1; - } - - if (itemstack.interactWithEntity(pl, (EntityLivingBase) p_70998_1_)) { - if (itemstack.stackSize <= 0 && !pl.capabilities.isCreativeMode) { - pl.destroyCurrentEquippedItem(); - } - - return true; - } - } - - return false; - } else { - if (itemstack != null && itemstack == pl.getCurrentEquippedItem()) { - if (itemstack.stackSize <= 0 && !pl.capabilities.isCreativeMode) { - pl.destroyCurrentEquippedItem(); - } else if (itemstack.stackSize < itemstack1.stackSize && pl.capabilities.isCreativeMode) { - itemstack.stackSize = itemstack1.stackSize; - } - } - - return true; - } - } - - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onOffhandAttack(PlayerEventChild.OffhandAttackEvent event) { - if (event.offHand != null) { - if (hasEntityInteraction( - event.getPlayer().capabilities.isCreativeMode ? event.offHand.copy() : event.offHand, - event.getTarget(), - event.getPlayer(), - false)) { - event.setCanceled(true); - if (event.offHand.stackSize <= 0 && !event.getPlayer().capabilities.isCreativeMode) { - ItemStack orig = event.offHand; - BackhandUtils.setPlayerOffhandItem(event.getPlayer(), null); - MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(event.getPlayer(), orig)); - } - } - } - } - - /** - * Check if a stack has a specific interaction with an entity. - * Use a call to {@link net.minecraft.item.ItemStack#interactWithEntity(EntityPlayer, EntityLivingBase)} - * - * @param itemStack to interact last with - * @param entity to interact first with - * @param entityPlayer holding the stack - * @param asTest if data should be cloned before testing - * @return true if a specific interaction exist (and has been done if asTest is false) - */ - private boolean hasEntityInteraction(ItemStack itemStack, Entity entity, EntityPlayer entityPlayer, - boolean asTest) { - if (asTest) { - Entity clone = EntityList.createEntityByName(EntityList.getEntityString(entity), entity.worldObj); - if (clone != null) { - clone.copyDataFrom(entity, true); - return !clone.interactFirst(entityPlayer) && clone instanceof EntityLivingBase - && itemStack.copy() - .interactWithEntity(entityPlayer, (EntityLivingBase) clone); - } - } else if (!entity.interactFirst(entityPlayer) && entity instanceof EntityLivingBase) { - return itemStack.interactWithEntity(entityPlayer, (EntityLivingBase) entity); - } - return false; - } - - @SubscribeEvent - public void addTracking(PlayerEvent.StartTracking event) { - if (event.target instanceof EntityPlayer && !isFake(event.target)) { - ((EntityPlayerMP) event.entityPlayer).playerNetServerHandler - .sendPacket(new OffhandSyncItemPacket((EntityPlayer) event.target).generatePacket()); - } - } -} diff --git a/src/main/java/xonin/backhand/ServerEventsHandler.java b/src/main/java/xonin/backhand/ServerEventsHandler.java deleted file mode 100644 index 7928dae..0000000 --- a/src/main/java/xonin/backhand/ServerEventsHandler.java +++ /dev/null @@ -1,158 +0,0 @@ -package xonin.backhand; - -import net.minecraft.block.BlockDispenser; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBow; -import net.minecraft.item.ItemStack; -import net.minecraft.util.RegistrySimple; -import net.minecraftforge.event.entity.living.LivingDeathEvent; -import net.minecraftforge.event.entity.living.LivingHurtEvent; -import net.minecraftforge.event.entity.player.ArrowNockEvent; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; -import net.minecraftforge.event.entity.player.PlayerUseItemEvent; - -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.eventhandler.EventPriority; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.relauncher.Side; -import ganymedes01.etfuturum.ModItems; -import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.api.core.OffhandExtendedProperty; -import xonin.backhand.utils.BackhandConfig; - -public class ServerEventsHandler { - - public static int fireworkHotSwapped = -1; - - @SubscribeEvent - public void onPlayerInteractNonVanilla(PlayerInteractEvent event) { - if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_AIR) { - EntityPlayer player = event.entityPlayer; - ItemStack mainhandItem = player.getHeldItem(); - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - if ((mainhandItem == null - || mainhandItem.getItem() != Items.fireworks && !BackhandUtils.usagePriorAttack(mainhandItem)) - && offhandItem != null - && offhandItem.getItem() == Items.fireworks) { - fireworkHotSwapped = 1; - } - } - } - - @SubscribeEvent - public void onLivingDeath(LivingDeathEvent event) { - if (!(event.entityLiving instanceof EntityPlayer player)) return; - - if (!BackhandUtils.hasOffhandInventory(player)) { - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - player.func_146097_a(offhandItem, true, false); - BackhandUtils.setPlayerOffhandItem(player, null); - } - } - - @SubscribeEvent - public void onLivingHurt(LivingHurtEvent event) { - if (!(event.entityLiving instanceof EntityPlayer player) || event.entityLiving.getHealth() - event.ammount > 0) - return; - - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - ItemStack mainhandItem = player.getCurrentEquippedItem(); - OffhandExtendedProperty offhandProp = BackhandUtils.getOffhandEP(player); - - if (offhandItem == null) { - return; - } - - if (Backhand.isEFRLoaded) { - Item totem = ModItems.TOTEM_OF_UNDYING.get(); - - if (offhandItem.getItem() == totem && (mainhandItem == null || mainhandItem.getItem() != totem)) { - BackhandUtils.swapOffhandItem(player, 5); - offhandProp.regularHotSwap = true; - } - } - } - - @SubscribeEvent - public void onItemUseStart(PlayerUseItemEvent.Start event) { - EntityPlayer player = event.entityPlayer; - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - ItemStack mainhandItem = player.getCurrentEquippedItem(); - boolean mainhandUse = BackhandUtils.checkForRightClickFunction(mainhandItem); - - if (offhandItem != null && !mainhandUse) { - event.setCanceled(true); - } - } - - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onArrowNock(ArrowNockEvent event) { - if (!BackhandConfig.UseOffhandArrows) { - return; - } - EntityPlayer player = event.entityPlayer; - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - if (offhandItem != null) { - if (!((RegistrySimple) BlockDispenser.dispenseBehaviorRegistry).containsKey(offhandItem.getItem())) { - return; - } - - event.setCanceled(true); - player.setItemInUse( - event.result, - event.result.getItem() - .getMaxItemUseDuration(event.result)); - } - } - - @SubscribeEvent - public void onItemFinish(PlayerUseItemEvent.Finish event) { - EntityPlayer player = event.entityPlayer; - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - ItemStack mainhandItem = player.getCurrentEquippedItem(); - OffhandExtendedProperty offhandProp = BackhandUtils.getOffhandEP(player); - boolean mainhandUse = BackhandUtils.checkForRightClickFunction(mainhandItem); - if (offhandItem == null || mainhandUse || offhandProp == null) { - return; - } - if (FMLCommonHandler.instance() - .getEffectiveSide() == Side.SERVER && !ServerTickHandler.tickStartItems.containsKey(player.getUniqueID())) { - BackhandUtils.swapOffhandItem(player); - offhandProp.regularHotSwap = true; - } - } - - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onItemStop(PlayerUseItemEvent.Stop event) { - EntityPlayer player = event.entityPlayer; - ItemStack mainhandItem = player.getCurrentEquippedItem(); - OffhandExtendedProperty offhandProp = BackhandUtils.getOffhandEP(player); - boolean skip = BackhandUtils.checkForRightClickFunction(mainhandItem) - || BackhandUtils.getOffhandItem(player) == null; - - if (!skip && !ServerTickHandler.tickStartItems.containsKey(player.getUniqueID()) - && !offhandProp.regularHotSwap) { - BackhandUtils.swapOffhandItem(player); - offhandProp.regularHotSwap = true; - return; - } - - if (!BackhandConfig.UseOffhandArrows || !(event.item.getItem() instanceof ItemBow)) { - return; - } - - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - if (offhandItem != null) { - if (!((RegistrySimple) BlockDispenser.dispenseBehaviorRegistry).containsKey(offhandItem.getItem())) { - return; - } - - if (offhandItem.getItem() != Items.arrow) { - offhandProp.regularHotSwap = true; - BackhandUtils.swapOffhandItem(player, 5); - } - } - } -} diff --git a/src/main/java/xonin/backhand/ServerTickHandler.java b/src/main/java/xonin/backhand/ServerTickHandler.java deleted file mode 100644 index 0e80357..0000000 --- a/src/main/java/xonin/backhand/ServerTickHandler.java +++ /dev/null @@ -1,155 +0,0 @@ -package xonin.backhand; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; - -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.eventhandler.EventPriority; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.TickEvent; -import cpw.mods.fml.relauncher.Side; -import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.api.core.OffhandExtendedProperty; -import xonin.backhand.packet.OffhandSyncItemPacket; -import xonin.backhand.utils.BackhandConfig; - -public class ServerTickHandler { - - public ItemStack prevStackInSlot; - public int blacklistDelay = -1; - - public static final HashMap> tickStartItems = new HashMap<>(); - - public static void resetTickingHotswap(EntityPlayerMP player) { - List tickedItems = tickStartItems.get(player.getUniqueID()); - if (tickedItems != null) { - BackhandUtils.getOffhandEP(player).ignoreSetSlot = false; - player.setCurrentItemOrArmor(0, tickedItems.get(0)); - BackhandUtils.setPlayerOffhandItem(player, tickedItems.get(1)); - tickStartItems.remove(player.getUniqueID()); - } - } - - public static void tickHotswap(EntityPlayerMP player) { - ItemStack mainhand = ItemStack.copyItemStack(player.getCurrentEquippedItem()); - ItemStack offhand = BackhandUtils.getOffhandItem(player); - if (offhand == null || player.currentWindowId != 0) return; - UUID key = player.getUniqueID(); - if (!BackhandUtils.checkForRightClickFunction(mainhand)) { - if (!tickStartItems.containsKey(key)) { - BackhandUtils.getOffhandEP(player).ignoreSetSlot = true; - } - tickStartItems.put(key, Arrays.asList(mainhand, offhand)); - player.setCurrentItemOrArmor( - 0, - tickStartItems.get(key) - .get(1)); - BackhandUtils.getOffhandEP(player).activeSlot = player.inventory.currentItem - + player.inventory.mainInventory.length; - } - } - - @SubscribeEvent - public void onUpdateWorld(TickEvent.WorldTickEvent event) { - if (FMLCommonHandler.instance() - .getEffectiveSide() != Side.SERVER) { - return; - } - if (BackhandConfig.OffhandTickHotswap) { - for (EntityPlayer player : event.world.playerEntities) { - if (!(player instanceof EntityPlayerMP playerMP)) continue; - OffhandExtendedProperty offhandProp = BackhandUtils.getOffhandEP(player); - - if (event.phase == TickEvent.Phase.START && !player.isUsingItem() - && offhandProp.tickingHotswapDelay <= 0) { - tickHotswap(playerMP); - } else { - if (offhandProp.tickingHotswapDelay > 0) offhandProp.tickingHotswapDelay--; - resetTickingHotswap(playerMP); - } - } - } - } - - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onUpdatePlayer(TickEvent.PlayerTickEvent event) { - EntityPlayer player = event.player; - OffhandExtendedProperty offhandProp = BackhandUtils.getOffhandEP(player); - - if (FMLCommonHandler.instance() - .getEffectiveSide() != Side.SERVER) { - if (offhandProp.regularHotSwap) { - BackhandUtils.swapOffhandItem(player); - offhandProp.regularHotSwap = false; - } - return; - } - - ItemStack offhand = BackhandUtils.getOffhandItem(player); - - if (event.phase == TickEvent.Phase.END) { - if (blacklistDelay > 0) { - blacklistDelay--; - } - if (Backhand.isOffhandBlacklisted(offhand)) { - if (!ItemStack.areItemStacksEqual(offhand, prevStackInSlot)) { - blacklistDelay = 10; - } else if (blacklistDelay == 0) { - BackhandUtils.setPlayerOffhandItem(player, null); - - boolean foundSlot = false; - for (int i = 0; i < player.inventory.getSizeInventory() - 4; i++) { - if (i == BackhandConfig.AlternateOffhandSlot) continue; - if (player.inventory.getStackInSlot(i) == null) { - player.inventory.setInventorySlotContents(i, offhand); - foundSlot = true; - break; - } - } - if (!foundSlot) { - player.entityDropItem(offhand, 0); - } - player.inventoryContainer.detectAndSendChanges(); - } - } - prevStackInSlot = offhand; - } - - if (offhandProp.syncOffhand) { - if (!tickStartItems.containsKey(player.getUniqueID())) { - Backhand.packetHandler.sendPacketToAll(new OffhandSyncItemPacket(player).generatePacket()); - } - offhandProp.syncOffhand = false; - } - - if (offhandProp.regularHotSwap) { - BackhandUtils.swapOffhandItem(player, 5); - offhandProp.regularHotSwap = false; - } - - if (ServerEventsHandler.fireworkHotSwapped > 0) { - ServerEventsHandler.fireworkHotSwapped--; - } else if (ServerEventsHandler.fireworkHotSwapped == 0) { - BackhandUtils.swapOffhandItem(player); - ServerEventsHandler.fireworkHotSwapped--; - MinecraftForge.EVENT_BUS.post( - new PlayerInteractEvent( - player, - PlayerInteractEvent.Action.RIGHT_CLICK_AIR, - (int) player.posX, - (int) player.posY, - (int) player.posZ, - -1, - player.worldObj)); - BackhandUtils.swapOffhandItem(player); - } - } -} diff --git a/src/main/java/xonin/backhand/api/PlayerEventChild.java b/src/main/java/xonin/backhand/api/PlayerEventChild.java deleted file mode 100644 index ebb0239..0000000 --- a/src/main/java/xonin/backhand/api/PlayerEventChild.java +++ /dev/null @@ -1,167 +0,0 @@ -package xonin.backhand.api; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraftforge.event.entity.player.EntityInteractEvent; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; - -import cpw.mods.fml.common.eventhandler.Cancelable; - -public abstract class PlayerEventChild extends PlayerEvent { - - /** - * The event that this event is a child of - */ - public final PlayerEvent parent; - - public PlayerEventChild(PlayerEvent parent) { - super(parent.entityPlayer); - this.parent = parent; - } - - public void setCancelParentEvent(boolean cancel) { - parent.setCanceled(cancel); - } - - @Override - public void setCanceled(boolean cancel) { - super.setCanceled(cancel); - parent.setCanceled(cancel); - } - - @Override - public void setResult(Result value) { - super.setResult(value); - parent.setResult(value); - } - - public EntityPlayer getPlayer() { - return parent.entityPlayer; - } - - /** - * Called when a player right clicks in battlemode - * The parent event can be either {@link PlayerInteractEvent} or {@link EntityInteractEvent} if the - * OffhandAttackEvent allowed swinging - * Both {@link ItemStack} can be null - * If cancelled, no offhand swinging will be performed - */ - @Cancelable - public static class OffhandSwingEvent extends PlayerEventChild { - - public final ItemStack mainHand; - public final ItemStack offHand; - - @Deprecated - public OffhandSwingEvent(PlayerEvent parent, ItemStack mainHand, ItemStack offHand) { - this(parent, offHand); - } - - public OffhandSwingEvent(PlayerEvent parent, ItemStack offHand) { - super(parent); - this.mainHand = parent.entityPlayer.getCurrentEquippedItem(); - this.offHand = offHand; - } - - public boolean onEntity() { - return parent instanceof EntityInteractEvent; - } - - public boolean onBlock() { - return parent instanceof PlayerInteractEvent; - } - } - - /** - * Called when a player right clicks an entity in battlemode - * Both {@link ItemStack} can be null - * Cancelling will prevent any further processing and prevails over the boolean fields - */ - @Cancelable - public static class OffhandAttackEvent extends PlayerEventChild { - - /** - * If we should call the OffhandSwingEvent and perform swinging animation - */ - public boolean swingOffhand = true; - /** - * If we should perform an attack on the entity with the offhand item - * Note: Will post AttackEntityEvent and Item#onLeftClickEntity(ItemStack, EntityPlayer, Entity) - * with InventoryPlayer#currentItem offset to the offhand. - */ - public boolean shouldAttack = true; - /** - * If we should Prevent PlayerInteractEvent.Action.RIGHT_CLICK_AIR and - * ItemStack#useItemRightClick(World, EntityPlayer) - * from being called for the item in main hand. - */ - public boolean cancelParent = true; - /** - * The base entity interaction event - * This event has already been posted in EventBus, handled by all potential listeners and was not cancelled. - * Changing its state will have no effect. - */ - public final EntityInteractEvent event; - /** - * Content of the main hand slot - */ - public final ItemStack mainHand; - /** - * Content of the off hand slot - */ - public final ItemStack offHand; - - @Deprecated - public OffhandAttackEvent(EntityInteractEvent parent, ItemStack mainHand, ItemStack offHand) { - this(parent, offHand); - } - - public OffhandAttackEvent(EntityInteractEvent parent, ItemStack offHand) { - super(parent); - this.event = parent; - this.mainHand = parent.entityPlayer.getCurrentEquippedItem(); - this.offHand = offHand; - } - - public Entity getTarget() { - return ((EntityInteractEvent) parent).target; - } - } - - /** - * This event replicates the event usage of {@link PlayerInteractEvent} for the item in left hand on right click, - * allowing support for other mods that use such event to customize item usage - * Item#onItemUseFirst, Item#onItemRightClick and Item#onItemUse will then get called the same way as with the item - * in the player right hand for PlayerInteractEvent - */ - @Cancelable - public static class UseOffhandItemEvent extends PlayerEventChild { - - /** - * If we should call the OffhandSwingEvent and perform swinging animation - */ - public boolean swingOffhand; - /** - * The {@link ItemStack} held in left hand - */ - public final ItemStack offhand; - /** - * The equivalent {@link PlayerInteractEvent} that would have been triggered if the offhand item was held in - * right hand and right click was pressed - */ - public final PlayerInteractEvent event; - - public UseOffhandItemEvent(PlayerInteractEvent event, ItemStack offhand) { - super(event); - this.event = event; - this.offhand = offhand; - this.swingOffhand = onBlock(); - } - - public boolean onBlock() { - return event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK; - } - } -} diff --git a/src/main/java/xonin/backhand/api/core/BackhandTranslator.java b/src/main/java/xonin/backhand/api/core/BackhandTranslator.java deleted file mode 100644 index 0c6845d..0000000 --- a/src/main/java/xonin/backhand/api/core/BackhandTranslator.java +++ /dev/null @@ -1,32 +0,0 @@ -package xonin.backhand.api.core; - -import net.minecraft.launchwrapper.Launch; - -public class BackhandTranslator { - - static { - obfuscatedEnv = (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); - } - - public static boolean obfuscatedEnv; - - public static String getMapedClassName(String className) { - return "net/minecraft/" + className.replace(".", "/"); - } - - /** @deprecated */ - @Deprecated - public static String getMapedMethodName(String className, String methodName, String devName) { - return getMapedMethodName(methodName, devName); - } - - public static String getMapedMethodName(String methodName, String devName) { - return obfuscatedEnv ? devName : methodName; - } - - /** @deprecated */ - @Deprecated - public static String getMapedMethodDesc(String className, String methodName, String devDesc) { - return devDesc; - } -} diff --git a/src/main/java/xonin/backhand/api/core/BackhandUtils.java b/src/main/java/xonin/backhand/api/core/BackhandUtils.java index 1836f4f..766104c 100644 --- a/src/main/java/xonin/backhand/api/core/BackhandUtils.java +++ b/src/main/java/xonin/backhand/api/core/BackhandUtils.java @@ -1,525 +1,65 @@ package xonin.backhand.api.core; -import java.io.Closeable; -import java.io.IOException; +import java.util.function.BooleanSupplier; import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.attributes.BaseAttributeMap; +import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.EnumAction; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBed; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemBook; -import net.minecraft.item.ItemBow; -import net.minecraft.item.ItemBucket; -import net.minecraft.item.ItemDoor; -import net.minecraft.item.ItemEgg; -import net.minecraft.item.ItemEnderPearl; -import net.minecraft.item.ItemHangingEntity; -import net.minecraft.item.ItemHoe; -import net.minecraft.item.ItemMonsterPlacer; -import net.minecraft.item.ItemRedstone; -import net.minecraft.item.ItemReed; -import net.minecraft.item.ItemSeedFood; -import net.minecraft.item.ItemSign; -import net.minecraft.item.ItemSkull; -import net.minecraft.item.ItemSnowball; import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemSword; -import net.minecraft.item.ItemTool; -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTSizeTracker; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraftforge.common.IExtendedEntityProperties; -import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.entity.player.AttackEntityEvent; - -import com.google.common.io.ByteArrayDataInput; -import com.google.common.io.ByteArrayDataOutput; - -import xonin.backhand.Backhand; -import xonin.backhand.ServerTickHandler; -import xonin.backhand.utils.BackhandConfig; /** * Store commonly used method, mostly for the {@link EntityPlayer} {@link ItemStack}s management */ -public class BackhandUtils { - - private static String[] itemBlackListMethodNames = { - BackhandTranslator.getMapedMethodName("Item", "func_77648_a", "onItemUse"), - BackhandTranslator.getMapedMethodName("Item", "func_77659_a", "onItemRightClick"), - BackhandTranslator.getMapedMethodName("Item", "func_111207_a", "itemInteractionForEntity") }; - - /** - * Method arguments classes that are not allowed in {@link Item} subclasses for common wielding - */ - private static Class[][] itemBlackListMethodParams = { - new Class[] { ItemStack.class, EntityPlayer.class, World.class, int.class, int.class, int.class, int.class, - float.class, float.class, float.class }, - new Class[] { ItemStack.class, World.class, EntityPlayer.class }, - new Class[] { ItemStack.class, EntityPlayer.class, EntityLivingBase.class } }; - private static ItemStack prevNotWieldable; - /** - * The generic attack damage key for {@link ItemStack#getAttributeModifiers()} - */ - private static String genericAttack = SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName(); - - public static boolean hasOffhandInventory(EntityPlayer player) { - return player.inventory instanceof InventoryPlayerBackhand; - } +@ParametersAreNonnullByDefault +public final class BackhandUtils { public static void swapOffhandItem(EntityPlayer player) { - swapOffhandItem(player, 0); - } - - public static void swapOffhandItem(EntityPlayer player, int delayHotswap) { - if (delayHotswap > 0) resetAndDelayHotswap(player, delayHotswap); - final ItemStack mainhandItem = getLegalStack(player.getCurrentEquippedItem()); - final ItemStack offhandItem = getLegalStack(BackhandUtils.getOffhandItem(player)); - BackhandUtils.setPlayerCurrentItem(player, offhandItem); - BackhandUtils.setPlayerOffhandItem(player, mainhandItem); - if (BackhandConfig.UseInventorySlot) { - player.inventoryContainer.detectAndSendChanges(); - } - } - - public static void setPlayerCurrentItem(EntityPlayer player, ItemStack stack) { - player.inventory.setInventorySlotContents(player.inventory.currentItem, stack); + ItemStack mainHand = player.getCurrentEquippedItem(); + player.setCurrentItemOrArmor(0, BackhandUtils.getOffhandItem(player)); + BackhandUtils.setPlayerOffhandItem(player, mainHand); } - public static void setPlayerOffhandItem(EntityPlayer player, ItemStack stack) { - if (!Backhand.isOffhandBlacklisted(stack)) { - if (BackhandConfig.UseInventorySlot) { - player.inventory.setInventorySlotContents(BackhandConfig.AlternateOffhandSlot, stack); - } else { - getOffhandEP(player).setOffhandItem(stack); - } - } + public static void setPlayerOffhandItem(EntityPlayer player, @Nullable ItemStack stack) { + ((IOffhandInventory) player.inventory).backhand$setOffhandItem(stack); } public static @Nullable ItemStack getOffhandItem(EntityPlayer player) { - if (player instanceof FakePlayer) return null; - - if (BackhandConfig.UseInventorySlot) { - return player.inventory.getStackInSlot(BackhandConfig.AlternateOffhandSlot); - } else { - return getOffhandEP(player).getOffhandItem(); - } - } - - public static OffhandExtendedProperty getOffhandEP(EntityPlayer player) { - IExtendedEntityProperties prop = player.getExtendedProperties("OffhandStorage"); - - if (prop instanceof OffhandExtendedProperty offhandProp) { - return offhandProp; - } - // Probably a fake player, return a dummy property - return new OffhandExtendedProperty(player); - } - - /** - * Defines a generic weapon - * - * @param main the item to check - * @return true if the item is a generic weapon - */ - public static boolean isWeapon(ItemStack main) { - if (main.getMaxStackSize() == 1 && main.getMaxDamage() > 0 && !main.getHasSubtypes())// Usual values for tools, - // sword, and bow - return true; - else if (main == prevNotWieldable)// Prevent lag from check spam - return false; - prevNotWieldable = main; - return false; - } - - /** - * Defines a combination of left hand/right hand items that is valid to wield - * - * @param main item to be in the right hand - * @param off item to be in the left hand - * @return true if the right hand item allows left hand item - */ - public static boolean isMainHand(ItemStack main, ItemStack off) { - if (main == null) return true; - else if (usagePriorAttack(main))// "Usable" item - return off == null || !usagePriorAttack(off);// With empty hand or non "usable item" - else if (isWeapon(main))// A generic weapon - return main.getItemUseAction() == EnumAction.bow || main.getAttributeModifiers() - .containsKey(genericAttack);// With either bow or generic attack, or registered - return false; - } - - /** - * Defines a item which can be wield in the left hand - * - * @param off the item to be wield in left hand - * @return true if the item is allowed in left hand - */ - public static boolean isOffHand(ItemStack off) { - if (off == null) return true; - else if (isWeapon(off))// A generic weapon - return off.getAttributeModifiers() - .containsKey(genericAttack);// with a generic attack or registered - return false; + return ((IOffhandInventory) player.inventory).backhand$getOffhandItem(); } - /** - * Patch in EntityPlayer#onUpdate() to support hotswap of itemInUse - * - * @param entityPlayer - * @param itemInUse - * @return - */ - public static ItemStack getCurrentItemOnUpdate(EntityPlayer entityPlayer, ItemStack itemInUse) { - ItemStack itemStack = getOffhandItem(entityPlayer); - if (itemInUse == itemStack) { - return itemStack; - } - return entityPlayer.getCurrentEquippedItem(); + public static void useOffhandItem(EntityPlayer player, Runnable action) { + useOffhandItem(player, true, action); } - /** - * Defines a item which "use" (effect on right click) should have priority over its "attack" (effect on left click) - * - * @param itemStack the item which will be "used", instead of attacking - * @return true if such item prefer being "used" - */ - public static boolean usagePriorAttack(ItemStack itemStack) { - if (itemStack == null) { - return false; - } - if (itemStack.getItemUseAction() == EnumAction.drink || itemStack.getItemUseAction() == EnumAction.eat - || itemStack.getItemUseAction() == EnumAction.bow) { + public static void useOffhandItem(EntityPlayer player, boolean syncSlot, Runnable action) { + useOffhandItem(player, syncSlot, () -> { + action.run(); return true; - } - return !(itemStack.getItem() instanceof ItemSword) - && (checkForRightClickFunction(itemStack) || isCommonlyUsable(itemStack.getItem())); - } - - /** - * Defines items that are usually usable (the vanilla instances do, at least) - * - * @param item the instance to consider for usability - * @return true if it is commonly usable - */ - public static boolean isCommonlyUsable(Item item) { - return isBow(item) || item.getClass() - .toString() - .equalsIgnoreCase("class D.f") - || item instanceof ItemBed - || item instanceof ItemHangingEntity - || item instanceof ItemBook - || isItemBlock(item) - || item instanceof ItemHoe - || item instanceof ItemSnowball - || item instanceof ItemEnderPearl - || item instanceof ItemEgg - || item instanceof ItemMonsterPlacer; - } - // item instanceof ItemCrossbow || item instanceof ItemMounter || item instanceof ItemTeleporter || item instanceof - // ItemElementalStaff || item instanceof ItemGun || item instanceof ItemNpcMovingPath || item instanceof - // ItemMachineGun || item instanceof ItemMusket || item instanceof ItemNpcCloner || item instanceof ItemNpcScripter - // || item instanceof SpellBase || item instanceof ItemNpcWand || item instanceof ItemShield || item instanceof - // ItemSlingshot || item instanceof ItemSoulstoneFilled || item instanceof ItemSoulstoneEmpty || item instanceof - // ItemStaff || item instanceof ItemThrowingWeapon || item instanceof ItemThrowingShuriken - - /** - * Defines a bow - * - * @param item the instance - * @return true if it is considered a generic enough bow - */ - public static boolean isBow(Item item) { - return item instanceof ItemBow; - } - - public static boolean isItemBlock(Item item) { - return item instanceof ItemBlock || item instanceof ItemDoor - || item instanceof ItemSign - || item instanceof ItemReed - || item instanceof ItemSeedFood - || item instanceof ItemRedstone - || item instanceof ItemBucket - || item instanceof ItemSkull; + }); } - @SuppressWarnings("unchecked") - public static boolean hasEntityInteraction(ItemStack stack) { - if (stack == null) { - return false; - } - try { - Class c = stack.getItem() - .getClass(); - while (!(c.equals(Item.class) || c.equals(ItemTool.class) || c.equals(ItemSword.class))) { - try { - try { - c.getDeclaredMethod(itemBlackListMethodNames[2], itemBlackListMethodParams[2]); - return true; - } catch (NoSuchMethodException ignored) {} - } catch (NoClassDefFoundError ignored) {} - - c = c.getSuperclass(); - } - - return false; - } catch (NullPointerException e) { - return true; - } + public static boolean useOffhandItem(EntityPlayer player, BooleanSupplier action) { + return useOffhandItem(player, true, action); } - @SuppressWarnings("unchecked") - public static boolean checkForRightClickFunction(ItemStack stack) { - if (stack == null) { - return false; - } - try { - if (stack.getItemUseAction() == EnumAction.block || stack.getItemUseAction() == EnumAction.none) { - - Class c = stack.getItem() - .getClass(); - while (!(c.equals(Item.class) || c.equals(ItemTool.class) || c.equals(ItemSword.class))) { - try { - for (int i = 0; i < itemBlackListMethodNames.length; i++) { - try { - c.getDeclaredMethod(itemBlackListMethodNames[i], itemBlackListMethodParams[i]); - return true; - } catch (NoSuchMethodException ignored) {} - } - } catch (NoClassDefFoundError ignored) {} - - c = c.getSuperclass(); - } - - return false; - } else { - return true; - } - } catch (NullPointerException e) { - return true; + public static boolean useOffhandItem(EntityPlayer player, boolean syncSlot, BooleanSupplier action) { + int oldSlot = player.inventory.currentItem; + player.inventory.currentItem = ((IOffhandInventory) player.inventory).backhand$getOffhandSlot(); + boolean result = action.getAsBoolean(); + player.inventory.currentItem = oldSlot; + if (syncSlot && player.worldObj.isRemote) { + Minecraft.getMinecraft().playerController.syncCurrentPlayItem(); } + return result; } - @SuppressWarnings("unchecked") - public static boolean checkForRightClickFunctionNoAction(ItemStack stack) { - if (stack == null) { - return false; - } - try { - Class c = stack.getItem() - .getClass(); - while (!(c.equals(Item.class) || c.equals(ItemTool.class) || c.equals(ItemSword.class))) { - try { - for (int i = 0; i < itemBlackListMethodNames.length; i++) { - try { - c.getDeclaredMethod(itemBlackListMethodNames[i], itemBlackListMethodParams[i]); - return true; - } catch (NoSuchMethodException ignored) {} - } - } catch (NoClassDefFoundError ignored) {} - - c = c.getSuperclass(); - } - - return false; - } catch (NullPointerException e) { - return true; - } - } - - /** - * Reads a {@link ItemStack} from the InputStream - */ - public static ItemStack readItemStack(ByteArrayDataInput par0DataInputStream) throws IOException { - ItemStack itemstack = null; - int short1 = par0DataInputStream.readInt(); - - if (short1 >= 0) { - byte b0 = par0DataInputStream.readByte(); - short short2 = par0DataInputStream.readShort(); - itemstack = new ItemStack(Item.getItemById(short1), b0, short2); - itemstack.stackTagCompound = readNBTTagCompound(par0DataInputStream); - } - - return itemstack; - } - - /** - * Reads a compressed {@link NBTTagCompound} from the InputStream - */ - public static NBTTagCompound readNBTTagCompound(ByteArrayDataInput par0DataInputStream) throws IOException { - short short1 = par0DataInputStream.readShort(); - - if (short1 < 0) { - return null; - } else { - byte[] abyte = new byte[short1]; - par0DataInputStream.readFully(abyte); - - return CompressedStreamTools.func_152457_a(abyte, NBTSizeTracker.field_152451_a); - } - } - - /** - * Writes a {@link ItemStack} to the OutputStream - * - * @param par1DataOutputStream the output stream - * @param par0ItemStack to write - * @throws IOException - */ - public static void writeItemStack(ByteArrayDataOutput par1DataOutputStream, ItemStack par0ItemStack) - throws IOException { - - if (par0ItemStack == null) { - par1DataOutputStream.writeShort(-1); - } else { - par1DataOutputStream.writeInt(Item.getIdFromItem(par0ItemStack.getItem())); - par1DataOutputStream.writeByte(par0ItemStack.stackSize); - par1DataOutputStream.writeShort(par0ItemStack.getItemDamage()); - NBTTagCompound nbttagcompound = null; - - if (par0ItemStack.getItem() - .isDamageable() - || par0ItemStack.getItem() - .getShareTag()) { - nbttagcompound = par0ItemStack.stackTagCompound; - } - - writeNBTTagCompound(nbttagcompound, par1DataOutputStream); - } - } - - /** - * Writes a compressed {@link NBTTagCompound} to the output - * - * @param par0NBTTagCompound - * @param par1DataOutputStream - * @throws IOException - */ - protected static void writeNBTTagCompound(NBTTagCompound par0NBTTagCompound, - ByteArrayDataOutput par1DataOutputStream) throws IOException { - if (par0NBTTagCompound == null) { - par1DataOutputStream.writeShort(-1); - } else { - byte[] abyte = CompressedStreamTools.compress(par0NBTTagCompound); - par1DataOutputStream.writeShort((short) abyte.length); - par1DataOutputStream.write(abyte); - } - } - - /** - * Basically, a copy of {@link EntityPlayer#attackTargetEntityWithCurrentItem(Entity)}, adapted for the offhand - * Hotswap the "current item" value to the offhand, then refresh the player attributes according to the newly - * selected item - * Reset everything back if the attack is cancelled by {@link AttackEntityEvent} or - * {@link Item#onLeftClickEntity(ItemStack, EntityPlayer, Entity)} - * - * @param player the attacker - * @param par1Entity the attacked - */ - public static void attackTargetEntityWithCurrentOffItem(EntityPlayer player, Entity par1Entity) { - final ItemStack oldItem = player.getCurrentEquippedItem(); - final ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - if (!BackhandConfig.OffhandAttack || (offhandItem == null && !BackhandConfig.EmptyOffhand)) return; - - BackhandUtils.setPlayerCurrentItem(player, offhandItem); - refreshAttributes(player.getAttributeMap(), oldItem, player.getCurrentEquippedItem()); - - int prevDamage = offhandItem != null ? offhandItem.getItemDamage() : 0; - int damage = offhandItem == null ? 1 : offhandItem.getMaxDamage() - offhandItem.getItemDamage(); - player.attackTargetEntityWithCurrentItem(par1Entity); - - refreshAttributes(player.getAttributeMap(), player.getCurrentEquippedItem(), oldItem); - BackhandUtils.setPlayerCurrentItem(player, oldItem); - - if (offhandItem != null && damage <= 0 && offhandItem.getItemDamage() < prevDamage) { - BackhandUtils.setPlayerOffhandItem(player, null); - ForgeEventFactory.onPlayerDestroyItem(player, offhandItem); - } - } - - /** - * Refresh the attribute map by removing from the old item and applying the current item - * - * @param attributeMap the map to refresh - * @param oldItem the old item whose attributes will be removed - * @param currentItem the current item whose attributes will be applied - */ - public static void refreshAttributes(BaseAttributeMap attributeMap, ItemStack oldItem, ItemStack currentItem) { - if (oldItem != null) attributeMap.removeAttributeModifiers(oldItem.getAttributeModifiers()); - if (currentItem != null) attributeMap.applyAttributeModifiers(currentItem.getAttributeModifiers()); - } - - /** - * Helper to close a stream fail-safely by printing the error stack trace - * - * @param c the stream to close - */ - public static void closeStream(Closeable c) { - try { - if (c != null) { - c.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Patch over the PlayerUseItemEvent.Finish in EntityPlayer#onItemUseFinish() to pass the previous stacksize - * - * @param entityPlayer the {@link EntityPlayer} who finished using the itemInUse - * @param itemInUse the {@link ItemStack} which finished being used - * @param itemInUseCount the {@link EntityPlayer} item use count - * @param previousStackSize the itemInUse {@link ItemStack#stackSize} before - * {@link ItemStack#onFoodEaten(World, EntityPlayer)} - * @param result from itemInUse#onFoodEaten(entityPlayer.worldObj, entityPlayer) - * @return the final resulting {@link ItemStack} - */ - public static ItemStack beforeFinishUseEvent(EntityPlayer entityPlayer, ItemStack itemInUse, int itemInUseCount, - ItemStack result, int previousStackSize) { - if (result != itemInUse || (result != null && result.stackSize != previousStackSize)) { - // Compare with either hands content - if (itemInUse == entityPlayer.getCurrentEquippedItem()) { - if (result != null && result.stackSize == 0) { - setPlayerCurrentItem(entityPlayer, null); - } else { - setPlayerCurrentItem(entityPlayer, result); - } - } else if (itemInUse == getOffhandItem(entityPlayer)) { - if (result != null && result.stackSize == 0) { - setPlayerOffhandItem(entityPlayer, null); - } else { - setPlayerOffhandItem(entityPlayer, result); - } - } - } - // Reset stuff so that vanilla doesn't do anything - entityPlayer.clearItemInUse(); - return null; - } - - public static ItemStack getLegalStack(ItemStack stack) { - if (stack != null && stack.stackSize == 0) { - return null; - } - - return stack; + public static boolean isUsingOffhand(EntityPlayer player) { + return ((IBackhandPlayer) player).isUsingOffhand(); } - public static void resetAndDelayHotswap(EntityPlayer player, int delayTicks) { - if (!(player instanceof EntityPlayerMP playerMP)) return; - ServerTickHandler.resetTickingHotswap(playerMP); - getOffhandEP(player).tickingHotswapDelay = delayTicks; + public static int getOffhandSlot(EntityPlayer player) { + return ((IOffhandInventory) player.inventory).backhand$getOffhandSlot(); } } diff --git a/src/main/java/xonin/backhand/api/core/IBackhandPlayer.java b/src/main/java/xonin/backhand/api/core/IBackhandPlayer.java index b35c004..f536948 100644 --- a/src/main/java/xonin/backhand/api/core/IBackhandPlayer.java +++ b/src/main/java/xonin/backhand/api/core/IBackhandPlayer.java @@ -1,12 +1,11 @@ package xonin.backhand.api.core; -import net.minecraft.entity.Entity; - /** * Interface added to EntityPlayer to support offhand management - * + * * @author GotoLink */ + public interface IBackhandPlayer { /** @@ -19,11 +18,10 @@ public interface IBackhandPlayer { */ float getOffSwingProgress(float frame); - /** - * Hotswap the EntityPlayer current item to offhand, behaves like - * EntityPlayer#attackTargetEntityWithCurrentItem(Entity) - * - * @param target to attack - */ - void attackTargetEntityWithCurrentOffItem(Entity target); + void setOffhandItemInUse(boolean usingOffhand); + + boolean isOffhandItemInUse(); + + boolean isUsingOffhand(); + } diff --git a/src/main/java/xonin/backhand/api/core/IOffhandInventory.java b/src/main/java/xonin/backhand/api/core/IOffhandInventory.java new file mode 100644 index 0000000..2830433 --- /dev/null +++ b/src/main/java/xonin/backhand/api/core/IOffhandInventory.java @@ -0,0 +1,18 @@ +package xonin.backhand.api.core; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; + +public interface IOffhandInventory { + + ItemStack backhand$getOffhandItem(); + + void backhand$setOffhandItem(ItemStack stack); + + int backhand$getOffhandSlot(); + + static boolean isValidSwitch(int id, EntityPlayer player) { + return (id >= 0 && id < InventoryPlayer.getHotbarSize()) || id == BackhandUtils.getOffhandSlot(player); + } +} diff --git a/src/main/java/xonin/backhand/api/core/InventoryPlayerBackhand.java b/src/main/java/xonin/backhand/api/core/InventoryPlayerBackhand.java deleted file mode 100644 index 32caee7..0000000 --- a/src/main/java/xonin/backhand/api/core/InventoryPlayerBackhand.java +++ /dev/null @@ -1,161 +0,0 @@ -package xonin.backhand.api.core; - -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; - -import xonin.backhand.Backhand; -import xonin.backhand.utils.BackhandConfig; - -/** - * User: nerd-boy - * Date: 15/07/13 - * Time: 3:08 PM - * Replacement for the player inventory - */ -public class InventoryPlayerBackhand extends InventoryPlayer { - - public static final int OFFHAND_HOTBAR_SLOT = 9; - - public InventoryPlayerBackhand(EntityPlayer entityPlayer) { - super(entityPlayer); - } - - /** - * Patch used for "set current slot" vanilla packets - * - * @param id the value to test for currentItem setting - * @return true if it is possible for currentItem to be set with this value - */ - public static boolean isValidSwitch(int id) { - return (id >= 0 && id < getHotbarSize()) || id == OFFHAND_HOTBAR_SLOT; - } - - public ItemStack getOffhandItem() { - return BackhandUtils.getOffhandEP(player) - .getOffhandItem(); - } - - public void setOffhandItem(ItemStack stack) { - BackhandUtils.getOffhandEP(player) - .setOffhandItem(stack); - } - - public int clearInventory(Item item, int metadata) { - int amount = 0; - ItemStack itemstack = this.getOffhandItem(); - if (itemstack != null && (item == null || itemstack.getItem() == item) - && (metadata <= -1 || itemstack.getItemDamage() == metadata)) { - amount += itemstack.stackSize; - this.setOffhandItem(null); - } - - return amount + super.clearInventory(item, metadata); - } - - public boolean addItemStackToInventory(ItemStack itemStack) { - if (itemStack == null || itemStack.stackSize == 0 || itemStack.getItem() == null) return false; - - if (!Backhand.isOffhandBlacklisted(itemStack)) { - if (BackhandConfig.OffhandPickup && this.getOffhandItem() == null && getFirstEmptyStack() == -1) { - this.setOffhandItem(ItemStack.copyItemStack(itemStack)); - itemStack.stackSize = 0; - BackhandUtils.getOffhandEP(player).syncOffhand = true; - return true; - } - - if (this.getOffhandItem() != null && this.getOffhandItem() - .getItem() == itemStack.getItem() - && this.getOffhandItem() - .isStackable() - && this.getOffhandItem().stackSize < this.getOffhandItem() - .getMaxStackSize() - && this.getOffhandItem().stackSize < this.getInventoryStackLimit() - && (!this.getOffhandItem() - .getHasSubtypes() - || this.getOffhandItem() - .getItemDamage() == itemStack.getItemDamage()) - && ItemStack.areItemStackTagsEqual(this.getOffhandItem(), itemStack)) { - if (this.getOffhandItem().stackSize + itemStack.stackSize > this.getOffhandItem() - .getMaxStackSize()) { - itemStack.stackSize -= this.getOffhandItem().stackSize; - this.getOffhandItem().stackSize = this.getOffhandItem() - .getMaxStackSize(); - BackhandUtils.getOffhandEP(player).syncOffhand = true; - return super.addItemStackToInventory(itemStack); - } else { - this.getOffhandItem().stackSize += itemStack.stackSize; - itemStack.stackSize = 0; - BackhandUtils.getOffhandEP(player).syncOffhand = true; - return true; - } - } - } - return super.addItemStackToInventory(itemStack); - } - - public boolean consumeInventoryItem(Item item) { - if (this.getOffhandItem() != null && this.getOffhandItem() - .getItem() == item) { - if (--this.getOffhandItem().stackSize <= 0) { - this.setOffhandItem(null); - } - return true; - } else { - return super.consumeInventoryItem(item); - } - } - - public boolean hasItem(Item item) { - if (this.getOffhandItem() != null && this.getOffhandItem() - .getItem() == item) { - return true; - } - - return super.hasItem(item); - } - - /** - * Copy the slots content from another instance, usually for changing dimensions - * - * @param par1InventoryPlayer the instance to copy from - */ - @Override - public void copyInventory(InventoryPlayer par1InventoryPlayer) { - this.mainInventory = new ItemStack[par1InventoryPlayer.mainInventory.length]; - this.armorInventory = new ItemStack[par1InventoryPlayer.armorInventory.length]; - super.copyInventory(par1InventoryPlayer); - if (par1InventoryPlayer instanceof InventoryPlayerBackhand) { - this.setOffhandItem( - ItemStack.copyItemStack(((InventoryPlayerBackhand) par1InventoryPlayer).getOffhandItem())); - } - } - - public void dropAllItems() { - super.dropAllItems(); - this.player.func_146097_a(this.getOffhandItem(), true, false); - this.setOffhandItem(null); - } - - @Override - public boolean func_146025_b(Block block) { - if (!super.func_146025_b(block)) { - ItemStack offhand = getOffhandItem(); - if (offhand != null && getCurrentItem() != null && offhand.getItem() == getCurrentItem().getItem()) { - return offhand.func_150998_b(block); - } - return false; - } - return true; - } - - @Override - public ItemStack getCurrentItem() { - if (currentItem == InventoryPlayerBackhand.OFFHAND_HOTBAR_SLOT) { - return BackhandUtils.getOffhandItem(player); - } - return super.getCurrentItem(); - } -} diff --git a/src/main/java/xonin/backhand/api/core/OffhandExtendedProperty.java b/src/main/java/xonin/backhand/api/core/OffhandExtendedProperty.java deleted file mode 100644 index 7e568e3..0000000 --- a/src/main/java/xonin/backhand/api/core/OffhandExtendedProperty.java +++ /dev/null @@ -1,51 +0,0 @@ -package xonin.backhand.api.core; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraftforge.common.IExtendedEntityProperties; - -public class OffhandExtendedProperty implements IExtendedEntityProperties { - - public EntityPlayer player; - public boolean syncOffhand = true; - private ItemStack offhandItem; - public boolean ignoreSetSlot = false; - public int activeSlot = -1; - public boolean regularHotSwap = false; - public int tickingHotswapDelay = 0; - - public OffhandExtendedProperty(EntityPlayer player) { - this.player = player; - } - - @Override - public void saveNBTData(NBTTagCompound compound) { - if (offhandItem != null) { - compound.setTag("OffhandItemStack", offhandItem.writeToNBT(new NBTTagCompound())); - } - } - - @Override - public void loadNBTData(NBTTagCompound compound) { - if (compound.hasKey("OffhandItemStack")) { - this.setOffhandItem(ItemStack.loadItemStackFromNBT(compound.getCompoundTag("OffhandItemStack"))); - } - } - - @Override - public void init(Entity entity, World world) {} - - public ItemStack getOffhandItem() { - return offhandItem; - } - - public void setOffhandItem(ItemStack stack) { - if (!ItemStack.areItemStacksEqual(stack, this.offhandItem)) { - this.syncOffhand = true; - } - this.offhandItem = stack; - } -} diff --git a/src/main/java/xonin/backhand/client/BackhandClientTickHandler.java b/src/main/java/xonin/backhand/client/BackhandClientTickHandler.java deleted file mode 100644 index bdacd08..0000000 --- a/src/main/java/xonin/backhand/client/BackhandClientTickHandler.java +++ /dev/null @@ -1,399 +0,0 @@ -package xonin.backhand.client; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockGrass; -import net.minecraft.block.BlockLog; -import net.minecraft.block.material.Material; -import net.minecraft.client.Minecraft; -import net.minecraft.client.audio.PositionedSoundRecord; -import net.minecraft.client.multiplayer.PlayerControllerMP; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemAxe; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemBow; -import net.minecraft.item.ItemSpade; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemSword; -import net.minecraft.network.play.client.C07PacketPlayerDigging; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.Vec3; -import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; - -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.TickEvent; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import xonin.backhand.Backhand; -import xonin.backhand.CommonProxy; -import xonin.backhand.HookContainerClass; -import xonin.backhand.api.PlayerEventChild; -import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.api.core.IBackhandPlayer; -import xonin.backhand.api.core.InventoryPlayerBackhand; -import xonin.backhand.client.utils.BackhandClientUtils; -import xonin.backhand.packet.OffhandAttackPacket; -import xonin.backhand.packet.OffhandPlaceBlockPacket; -import xonin.backhand.packet.OffhandToServerPacket; -import xonin.backhand.utils.BackhandConfig; - -public final class BackhandClientTickHandler { - - public final Minecraft mc = Minecraft.getMinecraft(); - public static float ticksBeforeUse = 0; - public static boolean prevRightClickHeld = false; - public static int attackDelay = 0; - - public BackhandClientTickHandler() {} - - @SubscribeEvent - @SideOnly(Side.CLIENT) - public void onPlayerTick(TickEvent.PlayerTickEvent event) { - if (event.player == mc.thePlayer) { - if (event.phase == TickEvent.Phase.START) { - if (ticksBeforeUse > 0) ticksBeforeUse--; - tickStart(mc.thePlayer); - } - } - } - - @SideOnly(Side.CLIENT) - public void tickStart(EntityPlayer player) { - ItemStack mainhand = player.getCurrentEquippedItem(); - ItemStack offhand = BackhandUtils.getOffhandItem(player); - boolean mainhandUse = BackhandUtils.checkForRightClickFunction(mainhand); - boolean offhandUse = BackhandUtils.checkForRightClickFunction(offhand); - if (attackDelay > 0) { - attackDelay--; - } - - boolean usedItem = false; - if (offhand != null) { - if (mc.gameSettings.keyBindUseItem.getIsKeyPressed()) { - if (ticksBeforeUse == 0) { - usedItem = tryCheckUseItem(offhand, player); - } - } else { - ticksBeforeUse = 0; - } - } - if (mc.gameSettings.keyBindUseItem.getIsKeyPressed() && attackDelay == 0 && !usedItem) { - if (!prevRightClickHeld && player.getItemInUse() == null && !mainhandUse && !offhandUse) { - tryAttackEntity(player); - } - prevRightClickHeld = true; - } else { - prevRightClickHeld = false; - } - if (player.getItemInUse() == null) { - CommonProxy.offhandItemUsed = null; - } - } - - public void tryAttackEntity(EntityPlayer player) { - Minecraft mc = Minecraft.getMinecraft(); - if (mc.objectMouseOver != null - && mc.objectMouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY) { - Entity target = mc.objectMouseOver.entityHit; - mc.getNetHandler() - .addToSendQueue(new OffhandAttackPacket(player, target).generatePacket()); - } - } - - @SideOnly(Side.CLIENT) - public boolean tryCheckUseItem(ItemStack offhandItem, EntityPlayer player) { - MovingObjectPosition mouseOver = mc.objectMouseOver; - - if (offhandItem.getItem() instanceof ItemBow && !BackhandConfig.UseOffhandBow) { - return false; - } - - ItemStack mainHandItem = player.getCurrentEquippedItem(); - if (mainHandItem != null && (BackhandUtils.checkForRightClickFunction(mainHandItem) - || HookContainerClass.isItemBlock(mainHandItem.getItem()) - || player.getItemInUse() == mainHandItem)) { - ticksBeforeUse = 10; - return false; - } - - if (mouseOver != null && mouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { - if (BackhandClientUtils - .canBlockBeInteractedWith(offhandItem, mouseOver.blockX, mouseOver.blockY, mouseOver.blockZ) - && !BackhandUtils.getOffhandItem(player) - .getItem() - .doesSneakBypassUse(player.worldObj, mouseOver.blockX, mouseOver.blockY, mouseOver.blockZ, player) - && !(offhandItem.getItem() instanceof ItemBlock)) { - ticksBeforeUse = 4; - return false; - } - } - - boolean interacted = false; - if (BackhandUtils.usagePriorAttack(offhandItem)) { - boolean flag = true; - if (mouseOver != null) { - if (mouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY) { - if (mc.playerController.interactWithEntitySendPacket(player, mouseOver.entityHit)) { - flag = false; - interacted = true; - } - } - - if (flag) { - offhandItem = BackhandUtils.getOffhandItem(player); - PlayerEventChild.UseOffhandItemEvent useItemEvent = new PlayerEventChild.UseOffhandItemEvent( - new PlayerInteractEvent( - player, - PlayerInteractEvent.Action.RIGHT_CLICK_AIR, - 0, - 0, - 0, - -1, - player.worldObj), - offhandItem); - if (offhandItem != null && !MinecraftForge.EVENT_BUS.post(useItemEvent)) { - interacted = HookContainerClass.tryUseItem(player, offhandItem, Side.CLIENT); - } - } - - offhandItem = BackhandUtils.getOffhandItem(player); - if (offhandItem != null && mouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { - int j = mouseOver.blockX; - int k = mouseOver.blockY; - int l = mouseOver.blockZ; - if (!player.worldObj.getBlock(j, k, l) - .isAir(player.worldObj, j, k, l)) { - int i1 = mouseOver.sideHit; - PlayerEventChild.UseOffhandItemEvent useItemEvent = new PlayerEventChild.UseOffhandItemEvent( - new PlayerInteractEvent( - player, - PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK, - j, - k, - l, - i1, - player.worldObj), - offhandItem); - if (player.capabilities.allowEdit || !HookContainerClass.isItemBlock(offhandItem.getItem())) { - if (!MinecraftForge.EVENT_BUS.post(useItemEvent) && onPlayerPlaceBlock( - mc.playerController, - player, - offhandItem, - j, - k, - l, - i1, - mouseOver.hitVec)) { - ((IBackhandPlayer) player).swingOffItem(); - interacted = true; - } - } - if (offhandItem.stackSize == 0) { - BackhandUtils.setPlayerOffhandItem(player, null); - } - } - } - } - ticksBeforeUse = 4; - } - - return interacted; - } - - private boolean onPlayerPlaceBlock(PlayerControllerMP controller, EntityPlayer player, ItemStack offhand, int i, - int j, int k, int l, Vec3 hitVec) { - float f = (float) hitVec.xCoord - i; - float f1 = (float) hitVec.yCoord - j; - float f2 = (float) hitVec.zCoord - k; - boolean flag = false; - int i1; - final World worldObj = player.worldObj; - - Minecraft mc = Minecraft.getMinecraft(); - MovingObjectPosition objectMouseOver = mc.objectMouseOver; - Block block = mc.theWorld.getBlock(objectMouseOver.blockX, objectMouseOver.blockY, objectMouseOver.blockZ); - - Block b = worldObj.getBlock(i, j, k); - boolean blockActivated = b.onBlockActivated(worldObj, i, j, k, player, l, f, f1, f2); - boolean prevSneaking = player.isSneaking(); - player.setSneaking(true); - boolean blockSneakActivated = b.onBlockActivated(worldObj, i, j, k, player, l, f, f1, f2); - player.setSneaking(prevSneaking); - - if (blockActivated && !(player.isSneaking() && blockSneakActivated)) { - return false; - } - - if (player.getCurrentEquippedItem() != null) { - if ((block instanceof BlockLog && player.getCurrentEquippedItem() - .getItem() instanceof ItemAxe) || (block instanceof BlockGrass - && player.getCurrentEquippedItem() - .getItem() instanceof ItemSpade)) { - return false; - } - } - - if (offhand.getItem() - .onItemUseFirst(offhand, player, worldObj, i, j, k, l, f, f1, f2)) { - return true; - } - if (!flag && offhand.getItem() instanceof ItemBlock itemblock) { - if (!itemblock.func_150936_a(worldObj, i, j, k, l, player, offhand)) { - return false; - } - } - Backhand.packetHandler - .sendPacketToServer(new OffhandPlaceBlockPacket(i, j, k, l, offhand, f, f1, f2).generatePacket()); - if (flag) { - return true; - } else { - if (controller.isInCreativeMode()) { - i1 = offhand.getItemDamage(); - int j1 = offhand.stackSize; - boolean flag1 = offhand.tryPlaceItemIntoWorld(player, worldObj, i, j, k, l, f, f1, f2); - offhand.setItemDamage(i1); - offhand.stackSize = j1; - if (flag1) { - HookContainerClass.sendOffSwingEventNoCheck(player, offhand, player.getCurrentEquippedItem()); - } - return flag1; - } else { - if (!offhand.tryPlaceItemIntoWorld(player, worldObj, i, j, k, l, f, f1, f2)) { - return false; - } - if (offhand.stackSize <= 0) { - ForgeEventFactory.onPlayerDestroyItem(player, offhand); - } - HookContainerClass.sendOffSwingEventNoCheck(player, offhand, player.getCurrentEquippedItem()); - return true; - } - } - } - - @SideOnly(Side.CLIENT) - public static void tryBreakBlockOffhand(MovingObjectPosition objectMouseOver, ItemStack offhandItem, - ItemStack mainHandItem, TickEvent.PlayerTickEvent event) { - Minecraft mcInstance = Minecraft.getMinecraft(); - int i = objectMouseOver.blockX; - int j = objectMouseOver.blockY; - int k = objectMouseOver.blockZ; - int prevHeldItem = event.player.inventory.currentItem; - boolean broken = false; - - if (mcInstance.thePlayer.capabilities.isCreativeMode) { - if (ClientTickHandler.delay <= 0) { - mcInstance.effectRenderer.addBlockHitEffects(i, j, k, objectMouseOver); - mcInstance.effectRenderer.addBlockHitEffects(i, j, k, objectMouseOver); - if (!(BackhandUtils.usagePriorAttack(offhandItem)) - && (offhandItem == null || !(offhandItem.getItem() instanceof ItemSword))) { - PlayerControllerMP - .clickBlockCreative(mcInstance, mcInstance.playerController, i, j, k, objectMouseOver.sideHit); - HookContainerClass.sendOffSwingEventNoCheck(event.player, mainHandItem, offhandItem); - mcInstance.getNetHandler() - .addToSendQueue(new C07PacketPlayerDigging(2, i, j, k, objectMouseOver.sideHit)); - } - ClientTickHandler.delay = 20; - } - return; - } - if (mcInstance.theWorld.getBlock(i, j, k) - .getMaterial() != Material.air) { - if (mcInstance.playerController.blockHitDelay > 0) { - --mcInstance.playerController.blockHitDelay; - } else { - mcInstance.playerController.isHittingBlock = true; - - if (mcInstance.playerController.currentBlockX != i || mcInstance.playerController.currentBlockY != j - || mcInstance.playerController.currentblockZ != k) { - mcInstance.playerController.curBlockDamageMP = 0f; - } - - mcInstance.playerController.currentBlockX = i; - mcInstance.playerController.currentBlockY = j; - mcInstance.playerController.currentblockZ = k; - - if (offhandItem != null) { - if (mcInstance.gameSettings.heldItemTooltips) { - mcInstance.gameSettings.heldItemTooltips = false; - HookContainerClass.changedHeldItemTooltips = true; - } - - mcInstance.thePlayer.inventory.currentItem = InventoryPlayerBackhand.OFFHAND_HOTBAR_SLOT; - mcInstance.playerController.currentItemHittingBlock = BackhandUtils - .getOffhandItem(mcInstance.thePlayer); - mcInstance.playerController.syncCurrentPlayItem(); - } - - Block block = mcInstance.theWorld.getBlock(i, j, k); - if (block.getMaterial() == Material.air) { - mcInstance.playerController.isHittingBlock = false; - return; - } - BackhandClientUtils.countToCancel = 5; - mcInstance.playerController.curBlockDamageMP += block - .getPlayerRelativeBlockHardness(mcInstance.thePlayer, mcInstance.thePlayer.worldObj, i, j, k); - - if (mcInstance.playerController.stepSoundTickCounter % 4.0F == 0.0F) { - mcInstance.getSoundHandler() - .playSound( - new PositionedSoundRecord( - new ResourceLocation(block.stepSound.getStepResourcePath()), - (block.stepSound.getVolume() + 1.0F) / 8.0F, - block.stepSound.getPitch() * 0.5F, - (float) i + 0.5F, - (float) j + 0.5F, - (float) k + 0.5F)); - } - - ++mcInstance.playerController.stepSoundTickCounter; - - if (mcInstance.playerController.curBlockDamageMP >= 1.0F) { - - ItemStack itemstack = mcInstance.thePlayer.getCurrentEquippedItem(); - - if (itemstack != null) { - int prevDamage = itemstack.getItemDamage(); - int damage = itemstack.getMaxDamage() - itemstack.getItemDamage(); - itemstack.func_150999_a(mcInstance.theWorld, block, i, j, k, mcInstance.thePlayer); - if (itemstack.stackSize == 0 || (damage <= 0 && prevDamage < itemstack.getItemDamage())) { - broken = true; - mcInstance.thePlayer.destroyCurrentEquippedItem(); - } - } - mcInstance.playerController.isHittingBlock = false; - mcInstance.getNetHandler() - .addToSendQueue(new C07PacketPlayerDigging(2, i, j, k, objectMouseOver.sideHit)); - mcInstance.playerController.onPlayerDestroyBlock(i, j, k, objectMouseOver.sideHit); - mcInstance.playerController.curBlockDamageMP = 0.0F; - mcInstance.playerController.stepSoundTickCounter = 0.0F; - mcInstance.playerController.blockHitDelay = 5; - } - mcInstance.theWorld.destroyBlockInWorldPartially( - mcInstance.thePlayer.getEntityId(), - mcInstance.playerController.currentBlockX, - mcInstance.playerController.currentBlockY, - mcInstance.playerController.currentblockZ, - (int) (mcInstance.playerController.curBlockDamageMP * 10.0F) - 1); - } - - if (mcInstance.thePlayer.isCurrentToolAdventureModeExempt(i, j, k)) { - mcInstance.effectRenderer.addBlockHitEffects(i, j, k, objectMouseOver); - } - HookContainerClass.sendOffSwingEventNoCheck(event.player, mainHandItem, offhandItem); // force offhand swing - // anyway because we - // broke a block - } - event.player.inventory.currentItem = prevHeldItem; - mcInstance.playerController.syncCurrentPlayItem(); - - if (broken) { - BackhandUtils.setPlayerOffhandItem(event.player, null); - mcInstance.getNetHandler() - .addToSendQueue(new OffhandToServerPacket(null, event.player).generatePacket()); - } - } -} diff --git a/src/main/java/xonin/backhand/client/ClientEventHandler.java b/src/main/java/xonin/backhand/client/ClientEventHandler.java index bdfece4..fa9d1ab 100644 --- a/src/main/java/xonin/backhand/client/ClientEventHandler.java +++ b/src/main/java/xonin/backhand/client/ClientEventHandler.java @@ -1,6 +1,9 @@ package xonin.backhand.client; +import static xonin.backhand.utils.Mods.DOUBLE_WIDE_SURPRISE; + import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.client.gui.GuiIngame; import net.minecraft.client.model.ModelBiped; import net.minecraft.client.renderer.RenderHelper; @@ -15,21 +18,37 @@ import net.minecraftforge.client.event.RenderLivingEvent; import net.minecraftforge.client.event.RenderPlayerEvent; +import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; +import com.gtnewhorizon.gtnhlib.eventbus.EventBusSubscriber; + import cpw.mods.fml.common.eventhandler.EventPriority; import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.InputEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import cpw.mods.fml.relauncher.Side; +import invtweaks.InvTweaks; import xonin.backhand.api.core.BackhandUtils; import xonin.backhand.client.utils.BackhandRenderHelper; +import xonin.backhand.packet.OffhandSwapPacket; import xonin.backhand.utils.BackhandConfig; +import xonin.backhand.utils.Mods; +@EventBusSubscriber(side = Side.CLIENT) public class ClientEventHandler { - public static EntityPlayer renderingPlayer; + public static boolean prevInvTweaksAutoRefill; + public static boolean prevInvTweaksBreakRefill; + + public static int invTweaksDelay; + public static boolean allowSwap = true; + + public static int renderPass; @SubscribeEvent - public void renderHotbarOverlay(RenderGameOverlayEvent event) { + public static void renderHotbarOverlay(RenderGameOverlayEvent event) { if (event.type == RenderGameOverlayEvent.ElementType.HOTBAR) { Minecraft mc = Minecraft.getMinecraft(); renderHotbar( @@ -40,7 +59,29 @@ public void renderHotbarOverlay(RenderGameOverlayEvent event) { } } - protected void renderHotbar(GuiIngame gui, int width, int height, float partialTicks) { + @SubscribeEvent + public static void onKeyInputEvent(InputEvent.KeyInputEvent event) { + Minecraft mc = Minecraft.getMinecraft(); + EntityClientPlayerMP player = mc.thePlayer; + + if (ClientProxy.swapOffhand.getIsKeyPressed() && Keyboard.isKeyDown(Keyboard.getEventKey()) && allowSwap) { + allowSwap = false; + invTweaksSwapPatch(); + player.sendQueue.addToSendQueue(new OffhandSwapPacket(player).generatePacket()); + } + } + + @SubscribeEvent + public static void onClientTick(TickEvent.ClientTickEvent event) { + if (invTweaksDelay > 0) { + invTweaksDelay--; + if (invTweaksDelay == 0) { + restoreInvTweaksConfigs(); + } + } + } + + private static void renderHotbar(GuiIngame gui, int width, int height, float partialTicks) { Minecraft mc = Minecraft.getMinecraft(); ItemStack itemstack = BackhandUtils.getOffhandItem(mc.thePlayer); if (itemstack == null) { @@ -54,14 +95,14 @@ protected void renderHotbar(GuiIngame gui, int width, int height, float partialT GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); mc.renderEngine.bindTexture(new ResourceLocation("textures/gui/widgets.png")); - gui.drawTexturedModalRect(width / 2 - 125, height - 22, 0, 0, 11, 22); - gui.drawTexturedModalRect(width / 2 - 125 + 11, height - 22, 182 - 11, 0, 11, 22); - + int offset = DOUBLE_WIDE_SURPRISE.isLoaded() ? 212 : 125; + gui.drawTexturedModalRect(width / 2 - offset, height - 22, 0, 0, 11, 22); + gui.drawTexturedModalRect(width / 2 - offset + 11, height - 22, 182 - 11, 0, 11, 22); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL12.GL_RESCALE_NORMAL); RenderHelper.enableGUIStandardItemLighting(); - int x = width / 2 - 122; + int x = width / 2 - offset + 3; int z = height - 16 - 3; renderOffhandInventorySlot(x, z, partialTicks); @@ -71,7 +112,7 @@ protected void renderHotbar(GuiIngame gui, int width, int height, float partialT mc.mcProfiler.endSection(); } - protected void renderOffhandInventorySlot(int p_73832_2_, int p_73832_3_, float p_73832_4_) { + private static void renderOffhandInventorySlot(int p_73832_2_, int p_73832_3_, float p_73832_4_) { Minecraft mc = Minecraft.getMinecraft(); ItemStack itemstack = BackhandUtils.getOffhandItem(mc.thePlayer); @@ -98,10 +139,8 @@ protected void renderOffhandInventorySlot(int p_73832_2_, int p_73832_3_, float } } - public static int renderPass; - @SubscribeEvent - public void onRenderHand(RenderHandEvent event) { + public static void onRenderHand(RenderHandEvent event) { renderPass = event.renderPass; } @@ -110,9 +149,8 @@ public void onRenderHand(RenderHandEvent event) { * And stop the right hand inappropriate bending */ @SubscribeEvent(priority = EventPriority.LOW) - public void renderPlayerLeftItemUsage(RenderLivingEvent.Pre event) { + public static void renderPlayerLeftItemUsage(RenderLivingEvent.Pre event) { if (event.entity instanceof EntityPlayer entityPlayer) { - renderingPlayer = entityPlayer; ItemStack offhand = BackhandUtils.getOffhandItem(entityPlayer); if (offhand != null && event.renderer instanceof RenderPlayer renderer) { renderer.modelArmorChestplate.heldItemLeft = renderer.modelArmor.heldItemLeft = renderer.modelBipedMain.heldItemLeft = 1; @@ -135,21 +173,50 @@ public void renderPlayerLeftItemUsage(RenderLivingEvent.Pre event) { * Reset models to default values */ @SubscribeEvent(priority = EventPriority.LOW) - public void resetPlayerLeftHand(RenderPlayerEvent.Post event) { + public static void resetPlayerLeftHand(RenderPlayerEvent.Post event) { event.renderer.modelArmorChestplate.heldItemLeft = event.renderer.modelArmor.heldItemLeft = event.renderer.modelBipedMain.heldItemLeft = 0; } @SubscribeEvent - public void render3rdPersonOffhand(RenderPlayerEvent.Specials.Post event) { + public static void render3rdPersonOffhand(RenderPlayerEvent.Specials.Post event) { if (!BackhandConfig.EmptyOffhand && BackhandUtils.getOffhandItem(event.entityPlayer) == null) { return; } GL11.glPushMatrix(); ModelBiped biped = event.renderer.modelBipedMain; - BackhandRenderHelper.itemRenderer.updateEquippedItem(); - BackhandRenderHelper.itemRenderer - .renderOffhandItemIn3rdPerson(event.entityPlayer, biped, event.partialRenderTick); + BackhandRenderHelper.renderOffhandItemIn3rdPerson(event.entityPlayer, biped, event.partialRenderTick); GL11.glPopMatrix(); } + + public static void restoreInvTweaksConfigs() { + if (!Mods.INV_TWEAKS.isLoaded()) return; + InvTweaks.getConfigManager() + .getConfig() + .setProperty("enableAutoRefill", String.valueOf(prevInvTweaksAutoRefill)); + InvTweaks.getConfigManager() + .getConfig() + .setProperty("autoRefillBeforeBreak", String.valueOf(prevInvTweaksBreakRefill)); + } + + public static void invTweaksSwapPatch() { + if (!Mods.INV_TWEAKS.isLoaded()) return; + if (invTweaksDelay <= 0) { + prevInvTweaksAutoRefill = Boolean.parseBoolean( + InvTweaks.getConfigManager() + .getConfig() + .getProperty("enableAutoRefill")); + prevInvTweaksBreakRefill = Boolean.parseBoolean( + InvTweaks.getConfigManager() + .getConfig() + .getProperty("autoRefillBeforeBreak")); + InvTweaks.getConfigManager() + .getConfig() + .setProperty("enableAutoRefill", "false"); + InvTweaks.getConfigManager() + .getConfig() + .setProperty("autoRefillBeforeBreak", "false"); + } + invTweaksDelay = 15; + } } diff --git a/src/main/java/xonin/backhand/client/ClientProxy.java b/src/main/java/xonin/backhand/client/ClientProxy.java index 5fb7545..cdefad9 100644 --- a/src/main/java/xonin/backhand/client/ClientProxy.java +++ b/src/main/java/xonin/backhand/client/ClientProxy.java @@ -1,18 +1,16 @@ package xonin.backhand.client; -import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityClientPlayerMP; +import java.util.ArrayList; +import java.util.List; + import net.minecraft.client.settings.KeyBinding; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.common.MinecraftForge; import org.lwjgl.input.Keyboard; import cpw.mods.fml.client.registry.ClientRegistry; -import cpw.mods.fml.common.FMLCommonHandler; +import tconstruct.library.tools.HarvestTool; import xonin.backhand.CommonProxy; -import xonin.backhand.packet.OffhandAnimationPacket; -import xonin.backhand.utils.EnumAnimations; +import xonin.backhand.utils.Mods; public class ClientProxy extends CommonProxy { @@ -20,65 +18,15 @@ public class ClientProxy extends CommonProxy { "Swap Offhand", Keyboard.KEY_F, "key.categories.gameplay"); - public static int rightClickCounter = 0; - - public void load() { - MinecraftForge.EVENT_BUS.register(new ClientEventHandler()); - FMLCommonHandler.instance() - .bus() - .register(new ClientTickHandler()); - FMLCommonHandler.instance() - .bus() - .register(new BackhandClientTickHandler()); - ClientRegistry.registerKeyBinding(swapOffhand); - } + public static final List> offhandPriorityItems = new ArrayList<>(); @Override - public EntityPlayer getClientPlayer() { - return Minecraft.getMinecraft().thePlayer; - } + public void load() { + ClientRegistry.registerKeyBinding(swapOffhand); - @Override - public void sendAnimationPacket(EnumAnimations animation, EntityPlayer entityPlayer) { - if (entityPlayer instanceof EntityClientPlayerMP) { - ((EntityClientPlayerMP) entityPlayer).sendQueue - .addToSendQueue(new OffhandAnimationPacket(animation, entityPlayer).generatePacket()); + if (Mods.TINKERS_CONSTRUCT.isLoaded()) { + offhandPriorityItems.add(HarvestTool.class); } } - - @Override - public boolean isRightClickHeld() { - return Minecraft.getMinecraft().gameSettings.keyBindUseItem.getIsKeyPressed(); - } - - @Override - public int getRightClickCounter() { - return rightClickCounter; - } - - @Override - public int getRightClickDelay() { - return ClientTickHandler.delay; - } - - @Override - public void setRightClickCounter(int i) { - rightClickCounter = i; - } - - @Override - public boolean isLeftClickHeld() { - return Minecraft.getMinecraft().gameSettings.keyBindAttack.getIsKeyPressed(); - } - - @Override - public int getLeftClickCounter() { - return Minecraft.getMinecraft().leftClickCounter; - } - - @Override - public void setLeftClickCounter(int i) { - Minecraft.getMinecraft().leftClickCounter = i; - } } diff --git a/src/main/java/xonin/backhand/client/ClientTickHandler.java b/src/main/java/xonin/backhand/client/ClientTickHandler.java deleted file mode 100644 index 80a0fc0..0000000 --- a/src/main/java/xonin/backhand/client/ClientTickHandler.java +++ /dev/null @@ -1,152 +0,0 @@ -package xonin.backhand.client; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityClientPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.util.MovingObjectPosition; - -import org.lwjgl.input.Keyboard; - -import cpw.mods.fml.common.Optional; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.InputEvent; -import cpw.mods.fml.common.gameevent.TickEvent; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import invtweaks.InvTweaks; -import xonin.backhand.Backhand; -import xonin.backhand.HookContainerClass; -import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.client.utils.BackhandClientUtils; -import xonin.backhand.packet.OffhandSwapPacket; -import xonin.backhand.utils.BackhandConfig; - -public class ClientTickHandler { - - public static int delay; - public static boolean prevInvTweaksAutoRefill; - public static boolean prevInvTweaksBreakRefill; - - public static int invTweaksDelay; - public static boolean allowSwap = true; - - @SubscribeEvent - public void onKeyInputEvent(InputEvent.KeyInputEvent event) { - Minecraft mc = Minecraft.getMinecraft(); - EntityClientPlayerMP player = mc.thePlayer; - - if (ClientProxy.swapOffhand.getIsKeyPressed() && Keyboard.isKeyDown(Keyboard.getEventKey()) && allowSwap) { - allowSwap = false; - try { - this.getClass() - .getMethod("invTweaksSwapPatch"); - invTweaksSwapPatch(); - } catch (Exception ignored) {} - player.sendQueue.addToSendQueue(new OffhandSwapPacket(player).generatePacket()); - } - } - - @Optional.Method(modid = "inventorytweaks") - public void invTweaksSwapPatch() { - if (invTweaksDelay <= 0) { - prevInvTweaksAutoRefill = Boolean.parseBoolean( - InvTweaks.getConfigManager() - .getConfig() - .getProperty("enableAutoRefill")); - prevInvTweaksBreakRefill = Boolean.parseBoolean( - InvTweaks.getConfigManager() - .getConfig() - .getProperty("autoRefillBeforeBreak")); - InvTweaks.getConfigManager() - .getConfig() - .setProperty("enableAutoRefill", "false"); - InvTweaks.getConfigManager() - .getConfig() - .setProperty("autoRefillBeforeBreak", "false"); - } - invTweaksDelay = 15; - } - - @SubscribeEvent - public void onClientTick(TickEvent.ClientTickEvent event) { - if (invTweaksDelay > 0) { - invTweaksDelay--; - if (invTweaksDelay == 0) { - try { - this.getClass() - .getMethod("restoreInvTweaksConfigs"); - restoreInvTweaksConfigs(); - } catch (Exception ignored) {} - } - } - } - - @Optional.Method(modid = "inventorytweaks") - public void restoreInvTweaksConfigs() { - InvTweaks.getConfigManager() - .getConfig() - .setProperty("enableAutoRefill", String.valueOf(prevInvTweaksAutoRefill)); - InvTweaks.getConfigManager() - .getConfig() - .setProperty("autoRefillBeforeBreak", String.valueOf(prevInvTweaksBreakRefill)); - } - - @SideOnly(Side.CLIENT) - @SubscribeEvent - public void clientHelper(TickEvent.PlayerTickEvent event) { - if (ClientTickHandler.delay > 0) { - ClientTickHandler.delay--; - } - - if (!BackhandConfig.OffhandBreakBlocks) { - return; - } - - if (!BackhandConfig.EmptyOffhand && BackhandUtils.getOffhandItem(event.player) == null) { - return; - } - - if (!Backhand.proxy.isRightClickHeld()) { - Backhand.proxy.setRightClickCounter(0); - } - - ItemStack mainHandItem = event.player.getCurrentEquippedItem(); - ItemStack offhandItem = BackhandUtils.getOffhandItem(event.player); - - if (mainHandItem != null && (BackhandUtils.checkForRightClickFunction(mainHandItem) || offhandItem == null)) { - return; - } - - Minecraft mc = Minecraft.getMinecraft(); - - if (event.player.worldObj.isRemote && Backhand.proxy.getLeftClickCounter() <= 0 - && mc.objectMouseOver != null - && mc.objectMouseOver.typeOfHit != MovingObjectPosition.MovingObjectType.ENTITY) { - if (event.player.capabilities.allowEdit) { - if (Backhand.proxy.isRightClickHeld() - && !(mainHandItem != null && BackhandUtils.isItemBlock(mainHandItem.getItem()))) { - MovingObjectPosition mop = HookContainerClass.getRaytraceBlock(event.player); - if (offhandItem != null && HookContainerClass.isItemBlock(offhandItem.getItem())) { - if (!BackhandUtils.usagePriorAttack(offhandItem) && mop != null) { - BackhandClientTickHandler.tryBreakBlockOffhand(mop, offhandItem, mainHandItem, event); - Backhand.proxy.setLeftClickCounter(10); - } else { - mc.playerController.resetBlockRemoving(); - } - } else { - if (mop != null && !BackhandUtils.usagePriorAttack(offhandItem) - && !BackhandClientUtils - .canBlockBeInteractedWith(offhandItem, mop.blockX, mop.blockY, mop.blockZ)) { - BackhandClientTickHandler.tryBreakBlockOffhand(mop, offhandItem, mainHandItem, event); - Backhand.proxy.setLeftClickCounter(10); - } else { - mc.playerController.resetBlockRemoving(); - } - } - } else if (!Backhand.proxy.isLeftClickHeld()) { - mc.playerController.resetBlockRemoving(); - } - } - } - } -} diff --git a/src/main/java/xonin/backhand/client/renderer/ItemRendererOffhand.java b/src/main/java/xonin/backhand/client/renderer/ItemRendererOffhand.java deleted file mode 100644 index 18a00d9..0000000 --- a/src/main/java/xonin/backhand/client/renderer/ItemRendererOffhand.java +++ /dev/null @@ -1,172 +0,0 @@ -package xonin.backhand.client.renderer; - -import net.minecraft.block.Block; -import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityClientPlayerMP; -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.EnumAction; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraftforge.client.IItemRenderer; -import net.minecraftforge.client.MinecraftForgeClient; - -import org.lwjgl.opengl.GL11; - -import xonin.backhand.api.core.BackhandUtils; - -public class ItemRendererOffhand extends ItemRenderer { - - public ItemRendererOffhand(Minecraft mc) { - super(mc); - } - - public void renderOffhandItemIn3rdPerson(EntityPlayer player, ModelBiped modelBipedMain, float frame) { - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - float f2; - float f4; - - if (offhandItem != null) { - GL11.glPushMatrix(); - modelBipedMain.bipedLeftArm.postRender(0.0625F); - GL11.glTranslatef( - -modelBipedMain.bipedLeftArm.rotationPointX * 0.0625F, - -modelBipedMain.bipedLeftArm.rotationPointY * 0.0625F, - -modelBipedMain.bipedLeftArm.rotationPointZ * 0.0625F); - GL11.glScalef(-1, 1, 1); - GL11.glTranslatef( - -modelBipedMain.bipedLeftArm.rotationPointX * 0.0625F, - modelBipedMain.bipedLeftArm.rotationPointY * 0.0625F, - -modelBipedMain.bipedLeftArm.rotationPointZ * 0.0625F); - - GL11.glTranslatef(-0.0625F, 0.4375F, 0.0625F); - - if (player.fishEntity != null) { - offhandItem = new ItemStack(Items.stick); - } - - EnumAction enumaction = null; - - if (player.getItemInUseCount() > 0) { - enumaction = offhandItem.getItemUseAction(); - } - - IItemRenderer customRenderer = MinecraftForgeClient - .getItemRenderer(offhandItem, IItemRenderer.ItemRenderType.EQUIPPED); - boolean is3D = (customRenderer != null && customRenderer.shouldUseRenderHelper( - IItemRenderer.ItemRenderType.EQUIPPED, - offhandItem, - IItemRenderer.ItemRendererHelper.BLOCK_3D)); - - if (is3D || offhandItem.getItem() instanceof ItemBlock && RenderBlocks.renderItemIn3d( - Block.getBlockFromItem(offhandItem.getItem()) - .getRenderType())) { - f2 = 0.5F; - GL11.glTranslatef(0.0F, 0.1875F, -0.3125F); - f2 *= 0.75F; - GL11.glRotatef(20.0F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); - GL11.glScalef(-f2, -f2, f2); - } else if (offhandItem.getItem() == Items.bow) { - f2 = 0.625F; - GL11.glTranslatef(0.0F, 0.125F, 0.3125F); - GL11.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F); - GL11.glScalef(f2, -f2, f2); - GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); - } else if (offhandItem.getItem() - .isFull3D()) { - f2 = 0.625F; - - if (offhandItem.getItem() - .shouldRotateAroundWhenRendering()) { - GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); - GL11.glTranslatef(0.0F, -0.125F, 0.0F); - } - - if (player.getItemInUseCount() > 0 && enumaction == EnumAction.block) { - GL11.glTranslatef(0.05F, 0.0F, -0.1F); - GL11.glRotatef(-50.0F, 0.0F, 1.0F, 0.0F); - GL11.glRotatef(-10.0F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(-60.0F, 0.0F, 0.0F, 1.0F); - } - - GL11.glTranslatef(0.0F, 0.1875F, 0.0F); - GL11.glScalef(f2, -f2, f2); - GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); - } else { - f2 = 0.375F; - GL11.glTranslatef(0.25F, 0.1875F, -0.1875F); - GL11.glScalef(f2, f2, f2); - GL11.glRotatef(60.0F, 0.0F, 0.0F, 1.0F); - GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(20.0F, 0.0F, 0.0F, 1.0F); - } - - float f3; - int k; - float f12; - - if (offhandItem.getItem() - .requiresMultipleRenderPasses()) { - for (k = 0; k < offhandItem.getItem() - .getRenderPasses(offhandItem.getItemDamage()); ++k) { - int i = offhandItem.getItem() - .getColorFromItemStack(offhandItem, k); - f12 = (float) (i >> 16 & 255) / 255.0F; - f3 = (float) (i >> 8 & 255) / 255.0F; - f4 = (float) (i & 255) / 255.0F; - GL11.glColor4f(f12, f3, f4, 1.0F); - this.renderItem(player, offhandItem, k); - } - } else { - k = offhandItem.getItem() - .getColorFromItemStack(offhandItem, 0); - float f11 = (float) (k >> 16 & 255) / 255.0F; - f12 = (float) (k >> 8 & 255) / 255.0F; - f3 = (float) (k & 255) / 255.0F; - GL11.glColor4f(f11, f12, f3, 1.0F); - this.renderItem(player, offhandItem, 0); - } - - GL11.glPopMatrix(); - } - } - - public void updateEquippedItem() { - this.prevEquippedProgress = this.equippedProgress; - EntityClientPlayerMP player = this.mc.thePlayer; - ItemStack itemstack = BackhandUtils.getOffhandItem(player); - boolean flag = itemstack == this.itemToRender; - - if (itemstack != null && this.itemToRender != null - && itemstack != this.itemToRender - && itemstack.getItem() == this.itemToRender.getItem() - && itemstack.getItemDamage() == this.itemToRender.getItemDamage()) { - this.itemToRender = itemstack; - flag = true; - } - - float f = 0.4F; - float f1 = flag ? 1.0F : 0.0F; - float f2 = f1 - this.equippedProgress; - - if (f2 < -f) { - f2 = -f; - } - - if (f2 > f) { - f2 = f; - } - - this.equippedProgress += f2 / 2.0F; - - if (this.equippedProgress < 0.1F) { - this.itemToRender = itemstack; - } - } -} diff --git a/src/main/java/xonin/backhand/client/utils/BackhandClientUtils.java b/src/main/java/xonin/backhand/client/utils/BackhandClientUtils.java deleted file mode 100644 index 97f170a..0000000 --- a/src/main/java/xonin/backhand/client/utils/BackhandClientUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -package xonin.backhand.client.utils; - -import net.minecraft.client.entity.EntityOtherPlayerMP; -import net.minecraft.item.ItemStack; - -import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.client.world.ClientFakePlayer; - -public final class BackhandClientUtils { - - public static boolean disableMainhandAnimation = false; - public static int countToCancel = 0; - public static float firstPersonFrame; - public static boolean offhandFPRender; - public static boolean receivedConfigs = false; - - /** - * Patch over EntityOtherPlayerMP#onUpdate() to update isItemInUse field - * - * @param player the player whose #onUpdate method is triggered - * @param isItemInUse the old value for isItemInUse field - * @return the new value for isItemInUse field - */ - public static boolean entityOtherPlayerIsItemInUseHook(EntityOtherPlayerMP player, boolean isItemInUse) { - ItemStack itemStack = player.getCurrentEquippedItem(); - ItemStack offhand = BackhandUtils.getOffhandItem(player); - if (BackhandUtils.usagePriorAttack(offhand)) itemStack = offhand; - if (!isItemInUse && player.isEating() && itemStack != null) { - player.setItemInUse(itemStack, itemStack.getMaxItemUseDuration()); - return true; - } else if (isItemInUse && !player.isEating()) { - player.clearItemInUse(); - return false; - } else { - return isItemInUse; - } - } - - public static boolean canBlockBeInteractedWith(ItemStack offhand, int x, int y, int z) { - try { - return ClientFakePlayer.INSTANCE.simulateBlockInteraction(offhand, x, y, z); - } catch (Exception e) { - // Something went wrong, block the offhand interaction - return true; - } - } -} diff --git a/src/main/java/xonin/backhand/client/utils/BackhandRenderHelper.java b/src/main/java/xonin/backhand/client/utils/BackhandRenderHelper.java index 46dd236..7d1bf15 100644 --- a/src/main/java/xonin/backhand/client/utils/BackhandRenderHelper.java +++ b/src/main/java/xonin/backhand/client/utils/BackhandRenderHelper.java @@ -1,53 +1,34 @@ package xonin.backhand.client.utils; +import net.minecraft.block.Block; import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.client.model.ModelBiped; import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.EnumAction; +import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.util.MathHelper; -import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.IItemRenderer; +import net.minecraftforge.client.MinecraftForgeClient; import org.lwjgl.opengl.GL11; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import xonin.backhand.api.core.BackhandUtils; import xonin.backhand.api.core.IBackhandPlayer; -import xonin.backhand.client.renderer.ItemRendererOffhand; public final class BackhandRenderHelper { - public static final float RENDER_UNIT = 1F / 16F;// 0.0625 - public static final ItemRendererOffhand itemRenderer = new ItemRendererOffhand(Minecraft.getMinecraft()); - - private static final ResourceLocation ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); - - public static final float[] arrowX = new float[64]; - public static final float[] arrowY = new float[arrowX.length]; - public static final float[] arrowDepth = new float[arrowX.length]; - public static final float[] arrowPitch = new float[arrowX.length]; - public static final float[] arrowYaw = new float[arrowX.length]; - - static { - for (int i = 0; i < arrowX.length; i++) { - double r = Math.random() * 5; - double theta = Math.random() * Math.PI * 2; - - arrowX[i] = (float) (r * Math.cos(theta)); - arrowY[i] = (float) (r * Math.sin(theta)); - arrowDepth[i] = (float) (Math.random() * 0.5 + 0.5F); - - arrowPitch[i] = (float) (Math.random() * 50 - 25); - arrowYaw[i] = (float) (Math.random() * 50 - 25); - } - } + public static final ItemRenderer itemRenderer = new ItemRenderer(Minecraft.getMinecraft()); + public static float firstPersonFrame; @SuppressWarnings("SuspiciousNameCombination") public static void moveOffHandArm(Entity entity, ModelBiped biped, float frame) { if (entity instanceof IBackhandPlayer player && (player != Minecraft.getMinecraft().thePlayer - || player.getOffSwingProgress(BackhandClientUtils.firstPersonFrame) != 0)) { + || player.getOffSwingProgress(BackhandRenderHelper.firstPersonFrame) != 0)) { float offhandSwing = player.getOffSwingProgress(frame); if (offhandSwing > 0.0F) { @@ -72,82 +53,116 @@ public static void moveOffHandArm(Entity entity, ModelBiped biped, float frame) } } - public static void applyColorFromItemStack(ItemStack itemStack, int pass) { - int col = itemStack.getItem() - .getColorFromItemStack(itemStack, pass); - float r = (float) (col >> 16 & 255) / 255.0F; - float g = (float) (col >> 8 & 255) / 255.0F; - float b = (float) (col & 255) / 255.0F; - GL11.glColor4f(r, g, b, 1.0F); - } - - @SideOnly(Side.CLIENT) - public static void renderEnchantmentEffects(Tessellator tessellator) { - GL11.glDepthFunc(GL11.GL_EQUAL); - GL11.glDisable(GL11.GL_LIGHTING); - Minecraft.getMinecraft().renderEngine.bindTexture(ITEM_GLINT); - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); - float f7 = 0.76F; - GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); - GL11.glMatrixMode(GL11.GL_TEXTURE); - GL11.glPushMatrix(); - float f8 = 0.125F; - GL11.glScalef(f8, f8, f8); - float f9 = (float) (Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; - GL11.glTranslatef(f9, 0.0F, 0.0F); - GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, RENDER_UNIT); - GL11.glPopMatrix(); - GL11.glPushMatrix(); - GL11.glScalef(f8, f8, f8); - f9 = (float) (Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; - GL11.glTranslatef(-f9, 0.0F, 0.0F); - GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, RENDER_UNIT); - GL11.glPopMatrix(); - GL11.glMatrixMode(GL11.GL_MODELVIEW); - GL11.glDisable(GL11.GL_BLEND); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glDepthFunc(GL11.GL_LEQUAL); - } - - public static void renderTexturedQuad(int x, int y, float z, int width, int height) { - Tessellator tessellator = Tessellator.instance; - tessellator.startDrawingQuads(); - tessellator.addVertexWithUV((double) (x + 0), (double) (y + height), (double) z, 0D, 1D); - tessellator.addVertexWithUV((double) (x + width), (double) (y + height), (double) z, 1D, 1D); - tessellator.addVertexWithUV((double) (x + width), (double) (y + 0), (double) z, 1D, 0D); - tessellator.addVertexWithUV((double) (x + 0), (double) (y + 0), (double) z, 0D, 0D); - tessellator.draw(); - } - - public static void renderOffhandItem(ItemRenderer otherItemRenderer, float frame) { - Minecraft mc = Minecraft.getMinecraft(); - EntityClientPlayerMP player = mc.thePlayer; - - GL11.glPushMatrix(); - GL11.glScalef(-1, 1, 1); - - ItemStack itemToRender = otherItemRenderer.itemToRender; - float equippedProgress = otherItemRenderer.equippedProgress; - float prevEquippedProgress = otherItemRenderer.prevEquippedProgress; + public static void renderOffhandItemIn3rdPerson(EntityPlayer player, ModelBiped modelBipedMain, float frame) { + ItemStack offhandItem = BackhandUtils.getOffhandItem(player); + float f2; + float f4; + + if (offhandItem != null) { + GL11.glPushMatrix(); + modelBipedMain.bipedLeftArm.postRender(0.0625F); + GL11.glTranslatef( + -modelBipedMain.bipedLeftArm.rotationPointX * 0.0625F, + -modelBipedMain.bipedLeftArm.rotationPointY * 0.0625F, + -modelBipedMain.bipedLeftArm.rotationPointZ * 0.0625F); + GL11.glScalef(-1, 1, 1); + GL11.glTranslatef( + -modelBipedMain.bipedLeftArm.rotationPointX * 0.0625F, + modelBipedMain.bipedLeftArm.rotationPointY * 0.0625F, + -modelBipedMain.bipedLeftArm.rotationPointZ * 0.0625F); + + GL11.glTranslatef(-0.0625F, 0.4375F, 0.0625F); + + if (player.fishEntity != null) { + offhandItem = new ItemStack(Items.stick); + } - otherItemRenderer.itemToRender = itemRenderer.itemToRender; - otherItemRenderer.equippedProgress = itemRenderer.equippedProgress; - otherItemRenderer.prevEquippedProgress = itemRenderer.prevEquippedProgress; + EnumAction enumaction = null; - float f3 = player.prevRenderArmPitch + (player.renderArmPitch - player.prevRenderArmPitch) * frame; - float f4 = player.prevRenderArmYaw + (player.renderArmYaw - player.prevRenderArmYaw) * frame; - GL11.glRotatef((player.rotationPitch - f3) * -0.1F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef((player.rotationYaw - f4) * -0.1F, 0.0F, 1.0F, 0.0F); + if (player.getItemInUseCount() > 0) { + enumaction = offhandItem.getItemUseAction(); + } - otherItemRenderer.renderItemInFirstPerson(frame); + IItemRenderer customRenderer = MinecraftForgeClient + .getItemRenderer(offhandItem, IItemRenderer.ItemRenderType.EQUIPPED); + boolean is3D = (customRenderer != null && customRenderer.shouldUseRenderHelper( + IItemRenderer.ItemRenderType.EQUIPPED, + offhandItem, + IItemRenderer.ItemRendererHelper.BLOCK_3D)); + + if (is3D || offhandItem.getItem() instanceof ItemBlock && RenderBlocks.renderItemIn3d( + Block.getBlockFromItem(offhandItem.getItem()) + .getRenderType())) { + f2 = 0.5F; + GL11.glTranslatef(0.0F, 0.1875F, -0.3125F); + f2 *= 0.75F; + GL11.glRotatef(20.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(-f2, -f2, f2); + } else if (offhandItem.getItem() == Items.bow) { + f2 = 0.625F; + GL11.glTranslatef(0.0F, 0.125F, 0.3125F); + GL11.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(f2, -f2, f2); + GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + } else if (offhandItem.getItem() + .isFull3D()) { + f2 = 0.625F; + + if (offhandItem.getItem() + .shouldRotateAroundWhenRendering()) { + GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(0.0F, -0.125F, 0.0F); + } + + if (player.getItemInUseCount() > 0 && enumaction == EnumAction.block) { + GL11.glTranslatef(0.05F, 0.0F, -0.1F); + GL11.glRotatef(-50.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-10.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(-60.0F, 0.0F, 0.0F, 1.0F); + } + + GL11.glTranslatef(0.0F, 0.1875F, 0.0F); + GL11.glScalef(f2, -f2, f2); + GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + } else { + f2 = 0.375F; + GL11.glTranslatef(0.25F, 0.1875F, -0.1875F); + GL11.glScalef(f2, f2, f2); + GL11.glRotatef(60.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(20.0F, 0.0F, 0.0F, 1.0F); + } - otherItemRenderer.itemToRender = itemToRender; - otherItemRenderer.equippedProgress = equippedProgress; - otherItemRenderer.prevEquippedProgress = prevEquippedProgress; + float f3; + int k; + float f12; + + if (offhandItem.getItem() + .requiresMultipleRenderPasses()) { + for (k = 0; k < offhandItem.getItem() + .getRenderPasses(offhandItem.getItemDamage()); ++k) { + int i = offhandItem.getItem() + .getColorFromItemStack(offhandItem, k); + f12 = (float) (i >> 16 & 255) / 255.0F; + f3 = (float) (i >> 8 & 255) / 255.0F; + f4 = (float) (i & 255) / 255.0F; + GL11.glColor4f(f12, f3, f4, 1.0F); + itemRenderer.renderItem(player, offhandItem, k); + } + } else { + k = offhandItem.getItem() + .getColorFromItemStack(offhandItem, 0); + float f11 = (float) (k >> 16 & 255) / 255.0F; + f12 = (float) (k >> 8 & 255) / 255.0F; + f3 = (float) (k & 255) / 255.0F; + GL11.glColor4f(f11, f12, f3, 1.0F); + itemRenderer.renderItem(player, offhandItem, 0); + } - GL11.glPopMatrix(); + GL11.glPopMatrix(); + } } } diff --git a/src/main/java/xonin/backhand/client/world/ClientFakePlayer.java b/src/main/java/xonin/backhand/client/world/ClientFakePlayer.java deleted file mode 100644 index e543971..0000000 --- a/src/main/java/xonin/backhand/client/world/ClientFakePlayer.java +++ /dev/null @@ -1,107 +0,0 @@ -package xonin.backhand.client.world; - -import java.util.UUID; - -import net.minecraft.block.Block; -import net.minecraft.client.Minecraft; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.stats.StatBase; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.DamageSource; -import net.minecraft.util.IChatComponent; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.world.World; - -import com.mojang.authlib.GameProfile; - -public class ClientFakePlayer extends EntityPlayer { - - public static final ClientFakePlayer INSTANCE = new ClientFakePlayer(); - - public ClientFakePlayer() { - super(DummyWorld.INSTANCE, new GameProfile(UUID.randomUUID(), "[BackhandClient]")); - } - - @Override - public void addChatMessage(IChatComponent message) {} - - @Override - public boolean canCommandSenderUseCommand(int i, String s) { - return false; - } - - @Override - public ChunkCoordinates getPlayerCoordinates() { - return new ChunkCoordinates(0, 0, 0); - } - - @Override - public void addChatComponentMessage(IChatComponent message) {} - - @Override - public void addStat(StatBase par1StatBase, int par2) {} - - @Override - public void openGui(Object mod, int modGuiId, World world, int x, int y, int z) {} - - @Override - public boolean isEntityInvulnerable() { - return true; - } - - @Override - public boolean canAttackPlayer(EntityPlayer player) { - return false; - } - - @Override - public void onDeath(DamageSource source) {} - - @Override - public void onUpdate() {} - - @Override - public void travelToDimension(int dim) {} - - public boolean simulateBlockInteraction(ItemStack offhand, int x, int y, int z) { - Minecraft mc = Minecraft.getMinecraft(); - MovingObjectPosition mop = mc.objectMouseOver; - ItemStack stack = ItemStack.copyItemStack(offhand); - - if (mop == null) return false; - - float subX = (float) mop.hitVec.xCoord - x; - float subY = (float) mop.hitVec.yCoord - y; - float subZ = (float) mop.hitVec.zCoord - z; - - copyPlayerPosition(mc.thePlayer); - Block block = DummyWorld.INSTANCE.copyAndSetBlock(mc.theWorld, x, y, z, mop); - - if (block == null || block == Blocks.air) return false; - - prepareForInteraction(mc.thePlayer, stack); - - return block.onBlockActivated(DummyWorld.INSTANCE, x, y, z, this, mop.sideHit, subX, subY, subZ); - } - - private void prepareForInteraction(EntityPlayer player, ItemStack stack) { - copyPlayerPosition(player); - inventory.copyInventory(player.inventory); - setCurrentItemOrArmor(0, stack); - experienceLevel = player.experienceLevel; - experienceTotal = player.experienceTotal; - experience = player.experience; - capabilities = player.capabilities; - isAirBorne = player.isAirBorne; - inWater = player.isInWater(); - fallDistance = player.fallDistance; - this.setSprinting(player.isSprinting()); - } - - public void copyPlayerPosition(EntityPlayer player) { - this.setPositionAndRotation(player.posX, player.posY, player.posZ, player.rotationYaw, player.rotationPitch); - this.setSneaking(player.isSneaking()); - } -} diff --git a/src/main/java/xonin/backhand/client/world/DummyChunkProvider.java b/src/main/java/xonin/backhand/client/world/DummyChunkProvider.java deleted file mode 100644 index 50222c8..0000000 --- a/src/main/java/xonin/backhand/client/world/DummyChunkProvider.java +++ /dev/null @@ -1,97 +0,0 @@ -package xonin.backhand.client.world; - -import java.util.List; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import net.minecraft.entity.EnumCreatureType; -import net.minecraft.util.IProgressUpdate; -import net.minecraft.util.LongHashMap; -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.ChunkPosition; -import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.IChunkProvider; - -public class DummyChunkProvider implements IChunkProvider { - - private final World world; - private LongHashMap loadedChunks = new LongHashMap(); - - public DummyChunkProvider(World world) { - this.world = world; - } - - @Nullable - @Override - public Chunk loadChunk(int x, int z) { - return (Chunk) loadedChunks.getValueByKey(ChunkCoordIntPair.chunkXZ2Int(x, z)); - } - - @Nonnull - @Override - public Chunk provideChunk(int x, int z) { - long chunkKey = ChunkCoordIntPair.chunkXZ2Int(x, z); - if (loadedChunks.containsItem(chunkKey)) { - return (Chunk) loadedChunks.getValueByKey(chunkKey); - } - - Chunk chunk = new Chunk(world, x, z); - loadedChunks.add(chunkKey, chunk); - return chunk; - } - - @Override - public void populate(IChunkProvider p_73153_1_, int p_73153_2_, int p_73153_3_) {} - - @Override - public boolean saveChunks(boolean p_73151_1_, IProgressUpdate p_73151_2_) { - return false; - } - - @Override - public boolean unloadQueuedChunks() { - return false; - } - - @Override - public boolean canSave() { - return false; - } - - @Nonnull - @Override - public String makeString() { - return "Dummy"; - } - - @Override - public List getPossibleCreatures(EnumCreatureType p_73155_1_, int p_73155_2_, - int p_73155_3_, int p_73155_4_) { - return null; - } - - @Override - public ChunkPosition func_147416_a(World p_147416_1_, String p_147416_2_, int p_147416_3_, int p_147416_4_, - int p_147416_5_) { - return null; - } - - @Override - public int getLoadedChunkCount() { - return 0; - } - - @Override - public void recreateStructures(int p_82695_1_, int p_82695_2_) {} - - @Override - public void saveExtraData() {} - - @Override - public boolean chunkExists(int x, int z) { - return true; - } -} diff --git a/src/main/java/xonin/backhand/client/world/DummySaveHandler.java b/src/main/java/xonin/backhand/client/world/DummySaveHandler.java deleted file mode 100644 index a7789a3..0000000 --- a/src/main/java/xonin/backhand/client/world/DummySaveHandler.java +++ /dev/null @@ -1,99 +0,0 @@ -package xonin.backhand.client.world; - -import java.io.File; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraft.world.WorldProvider; -import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.storage.IChunkLoader; -import net.minecraft.world.storage.IPlayerFileData; -import net.minecraft.world.storage.ISaveHandler; -import net.minecraft.world.storage.WorldInfo; - -public class DummySaveHandler implements ISaveHandler, IPlayerFileData, IChunkLoader { - - @Nullable - @Override - public WorldInfo loadWorldInfo() { - return null; - } - - @Override - public void checkSessionLock() {} - - @Nonnull - @Override - public IChunkLoader getChunkLoader(@Nonnull WorldProvider provider) { - return this; - } - - @Nonnull - @Override - public IPlayerFileData getSaveHandler() { - return this; - } - - @Override - public void saveWorldInfoWithPlayer(@Nonnull WorldInfo worldInformation, @Nonnull NBTTagCompound tagCompound) {} - - @Override - public void saveWorldInfo(@Nonnull WorldInfo worldInformation) {} - - @Nonnull - @Override - public File getWorldDirectory() { - return null; - } - - @Nonnull - @Override - public File getMapFileFromName(@Nonnull String mapName) { - return null; - } - - @Override - public String getWorldDirectoryName() { - return null; - } - - @Nullable - @Override - public Chunk loadChunk(@Nonnull World worldIn, int x, int z) { - return null; - } - - @Override - public void saveChunk(@Nonnull World worldIn, @Nonnull Chunk chunkIn) {} - - @Override - public void saveExtraChunkData(@Nonnull World worldIn, @Nonnull Chunk chunkIn) {} - - @Override - public void chunkTick() {} - - @Override - public void saveExtraData() {} - - @Override - public void flush() {} - - @Override - public void writePlayerData(@Nonnull EntityPlayer player) {} - - @Nullable - @Override - public NBTTagCompound readPlayerData(@Nonnull EntityPlayer player) { - return null; - } - - @Nonnull - @Override - public String[] getAvailablePlayerDat() { - return new String[0]; - } -} diff --git a/src/main/java/xonin/backhand/client/world/DummyWorld.java b/src/main/java/xonin/backhand/client/world/DummyWorld.java deleted file mode 100644 index 13ad6ca..0000000 --- a/src/main/java/xonin/backhand/client/world/DummyWorld.java +++ /dev/null @@ -1,149 +0,0 @@ -package xonin.backhand.client.world; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import net.minecraft.block.Block; -import net.minecraft.entity.Entity; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.profiler.Profiler; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.world.EnumSkyBlock; -import net.minecraft.world.World; -import net.minecraft.world.WorldProviderSurface; -import net.minecraft.world.WorldSettings; -import net.minecraft.world.WorldType; -import net.minecraft.world.chunk.IChunkProvider; - -import com.gtnewhorizon.gtnhlib.util.CoordinatePacker; - -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import it.unimi.dsi.fastutil.longs.LongSet; - -public class DummyWorld extends World { - - private static final WorldSettings DEFAULT_SETTINGS = new WorldSettings( - 1L, - WorldSettings.GameType.SURVIVAL, - true, - false, - WorldType.DEFAULT); - - public static final DummyWorld INSTANCE = new DummyWorld(); - private static final LongSet placedBlocks = new LongOpenHashSet(); - private static final Long2ObjectMap tileEntities = new Long2ObjectOpenHashMap<>(); - - public DummyWorld() { - super(new DummySaveHandler(), "DummyServer", DEFAULT_SETTINGS, new WorldProviderSurface(), new Profiler()); - // Guarantee the dimension ID was not reset by the provider - this.provider.setDimension(Integer.MAX_VALUE); - int providerDim = this.provider.dimensionId; - this.provider.worldObj = this; - this.provider.setDimension(providerDim); - this.chunkProvider = this.createChunkProvider(); - this.calculateInitialSkylight(); - this.calculateInitialWeatherBody(); - } - - @Override - public void updateEntities() {} - - @Override - public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) {} - - @Override - protected int func_152379_p() { - return 0; - } - - @Override - public Entity getEntityByID(int p_73045_1_) { - return null; - } - - @Nonnull - @Override - protected IChunkProvider createChunkProvider() { - return new DummyChunkProvider(this); - } - - @Override - public boolean setBlock(int x, int y, int z, Block blockIn, int metadataIn, int flags) { - if (super.setBlock(x, y, z, blockIn, metadataIn, flags)) { - long key = CoordinatePacker.pack(x, y, z); - if (blockIn != Blocks.air) { - placedBlocks.add(key); - } - return true; - } - return false; - } - - @Override - public boolean updateLightByType(EnumSkyBlock p_147463_1_, int p_147463_2_, int p_147463_3_, int p_147463_4_) { - return true; - } - - @Override - public void setTileEntity(int x, int y, int z, TileEntity tile) { - if (tile == null || tile.isInvalid()) return; - long key = CoordinatePacker.pack(x, y, z); - tileEntities.put(key, tile); - } - - @Override - public TileEntity getTileEntity(int x, int y, int z) { - return tileEntities.get(CoordinatePacker.pack(x, y, z)); - } - - @Override - public void removeTileEntity(int x, int y, int z) { - tileEntities.remove(CoordinatePacker.pack(x, y, z)); - } - - @Nullable - public Block copyAndSetBlock(World world, int x, int y, int z, MovingObjectPosition mop) { - resetWorld(); - Block block = world.getBlock(x, y, z); - - if (block == null || block == Blocks.air) return null; - - int meta = block.getDamageValue(world, x, y, z); - ItemStack stack = block.getPickBlock(mop, world, x, y, z, ClientFakePlayer.INSTANCE); - boolean placed = false; - - if (stack != null) { - for (int i = 0; i < 6; i++) { - // Adjust when placing on a block "below" - int aY = i == 1 ? y - 1 : y; - if (stack.getItem() - .onItemUse(stack, ClientFakePlayer.INSTANCE, this, x, aY, z, i, x, aY, z)) { - placed = true; - break; - } - } - } - - if (!placed) { - setBlock(x, y, z, block, meta, 3); - } - - return getBlock(x, y, z); - } - - private void resetWorld() { - if (placedBlocks.isEmpty()) return; - for (long key : placedBlocks) { - int x = CoordinatePacker.unpackX(key); - int y = CoordinatePacker.unpackY(key); - int z = CoordinatePacker.unpackZ(key); - setBlockToAir(x, y, z); - tileEntities.clear(); - } - placedBlocks.clear(); - } -} diff --git a/src/main/java/xonin/backhand/constants/EnumPacketClient.java b/src/main/java/xonin/backhand/constants/EnumPacketClient.java deleted file mode 100644 index f69fa7b..0000000 --- a/src/main/java/xonin/backhand/constants/EnumPacketClient.java +++ /dev/null @@ -1,3 +0,0 @@ -package xonin.backhand.constants; - -public enum EnumPacketClient {} diff --git a/src/main/java/xonin/backhand/constants/EnumPacketServer.java b/src/main/java/xonin/backhand/constants/EnumPacketServer.java deleted file mode 100644 index d1daaa7..0000000 --- a/src/main/java/xonin/backhand/constants/EnumPacketServer.java +++ /dev/null @@ -1,3 +0,0 @@ -package xonin.backhand.constants; - -public enum EnumPacketServer {} diff --git a/src/main/java/xonin/backhand/mixins/Mixins.java b/src/main/java/xonin/backhand/mixins/Mixins.java index 1ddfca6..959a914 100644 --- a/src/main/java/xonin/backhand/mixins/Mixins.java +++ b/src/main/java/xonin/backhand/mixins/Mixins.java @@ -16,10 +16,13 @@ public enum Mixins { MINECRAFT(new Builder("Shared MC Mixins") .addMixinClasses( "minecraft.MixinEntityPlayer", - "minecraft.MixinEntityPlayerMP", - "minecraft.MixinItemStack", "minecraft.MixinNetHandlerPlayServer", - "minecraft.MixinEntityItem") + "minecraft.MixinItemBow", + "minecraft.MixinEntityFishHook", + "minecraft.MixinInventoryPlayer", + "minecraft.MixinContainerPlayer", + "minecraft.MixinItemStack", + "minecraft.MixinEntityLivingBase") .setPhase(Phase.EARLY) .setSide(Side.BOTH) .addTargetedMod(TargetedMod.VANILLA)), @@ -30,18 +33,23 @@ public enum Mixins { "minecraft.MixinItemRenderer", "minecraft.MixinModelBiped", "minecraft.MixinNetHandlerPlayClient", - "minecraft.MixinPlayerControllerMP", - "minecraft.MixinItemBow", - "minecraft.MixinItemStackClient", - "minecraft.MixinWorld") + "minecraft.MixinMinecraft", + "minecraft.MixinGuiInventory", + "minecraft.MixinEntityRenderer", + "minecraft.MixinGuiContainerCreative") .setPhase(Phase.EARLY) .setSide(Side.CLIENT) .addTargetedMod(TargetedMod.VANILLA)), - FIX_SIMULATED_INTERACTION_NPE(new Builder("Fix NPE when simulating interaction with CB blocks") - .addMixinClasses("carpentersblocks.MixinPlayerPermissions") + 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.CARPENTERS_BLOCKS)); + .addTargetedMod(TargetedMod.TINKERS_CONSTRUCT)),; private final List mixinClasses; private final Supplier applyIf; diff --git a/src/main/java/xonin/backhand/mixins/TargetedMod.java b/src/main/java/xonin/backhand/mixins/TargetedMod.java index 5c3abda..c075c24 100644 --- a/src/main/java/xonin/backhand/mixins/TargetedMod.java +++ b/src/main/java/xonin/backhand/mixins/TargetedMod.java @@ -3,7 +3,8 @@ public enum TargetedMod { VANILLA("Minecraft", null), - CARPENTERS_BLOCKS("Carpenter's Blocks", null, "CarpentersBlocks"); + ET_FUTURUM("Et Futurum Requiem", "ganymedes01.etfuturum.mixinplugin.EtFuturumEarlyMixins", "etfuturum"), + TINKERS_CONSTRUCT("Tinkers' Construct", null, "TConstruct"); /** The "name" in the @Mod annotation */ public final String modName; diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinContainerPlayer.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinContainerPlayer.java new file mode 100644 index 0000000..a6d22bd --- /dev/null +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinContainerPlayer.java @@ -0,0 +1,24 @@ +package xonin.backhand.mixins.early.minecraft; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ContainerPlayer; +import net.minecraft.inventory.Slot; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import xonin.backhand.api.core.BackhandUtils; + +@Mixin(ContainerPlayer.class) +public abstract class MixinContainerPlayer extends Container { + + @Inject(method = "", at = @At(value = "TAIL")) + private void backhand2$addOffhandSlot(InventoryPlayer p_i1819_1_, boolean p_i1819_2_, EntityPlayer p_i1819_3_, + CallbackInfo ci) { + addSlotToContainer(new Slot(p_i1819_1_, BackhandUtils.getOffhandSlot(p_i1819_3_), 80, 65)); + } +} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityFishHook.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityFishHook.java new file mode 100644 index 0000000..b348088 --- /dev/null +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityFishHook.java @@ -0,0 +1,32 @@ +package xonin.backhand.mixins.early.minecraft; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityFishHook; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import xonin.backhand.api.core.BackhandUtils; + +@Mixin(EntityFishHook.class) +public abstract class MixinEntityFishHook { + + @Shadow + public EntityPlayer field_146042_b; + + @Inject( + method = "onUpdate", + cancellable = true, + at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/projectile/EntityFishHook;setDead()V", ordinal = 0)) + private void backhand$onUpdate(CallbackInfo ci) { + ItemStack itemstack = BackhandUtils.getOffhandItem(field_146042_b); + if (itemstack != null && Items.fishing_rod.equals(itemstack.getItem())) { + ci.cancel(); + } + } +} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityItem.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityItem.java deleted file mode 100644 index fccf7cd..0000000 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityItem.java +++ /dev/null @@ -1,24 +0,0 @@ -package xonin.backhand.mixins.early.minecraft; - -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.player.EntityPlayer; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import xonin.backhand.api.core.BackhandUtils; - -@Mixin(EntityItem.class) -public abstract class MixinEntityItem { - - @Inject( - method = "onCollideWithPlayer", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/entity/item/EntityItem;getEntityItem()Lnet/minecraft/item/ItemStack;")) - private void backhand$resetHotswapOnPickup(EntityPlayer entityIn, CallbackInfo ci) { - BackhandUtils.resetAndDelayHotswap(entityIn, 0); - } -} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityLivingBase.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityLivingBase.java new file mode 100644 index 0000000..55b9351 --- /dev/null +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityLivingBase.java @@ -0,0 +1,44 @@ +package xonin.backhand.mixins.early.minecraft; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import org.spongepowered.asm.mixin.Mixin; +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 com.llamalad7.mixinextras.sugar.Local; + +import xonin.backhand.Backhand; +import xonin.backhand.api.core.BackhandUtils; +import xonin.backhand.packet.OffhandSyncItemPacket; + +@Mixin(EntityLivingBase.class) +public abstract class MixinEntityLivingBase extends Entity { + + @Unique + private ItemStack backhand$previousOffhandStack; + + public MixinEntityLivingBase(World worldIn) { + super(worldIn); + } + + @Inject( + method = "onUpdate", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;areItemStacksEqual(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemStack;)Z", + ordinal = 0)) + private void backhand$updateOffhandItem(CallbackInfo ci, @Local(name = "j") int index) { + if (!((EntityLivingBase) (Object) this instanceof EntityPlayer player) || index > 0) return; + ItemStack offhand = BackhandUtils.getOffhandItem(player); + if (ItemStack.areItemStacksEqual(backhand$previousOffhandStack, offhand)) return; + backhand$previousOffhandStack = offhand; + Backhand.packetHandler.sendPacketToAllTracking(player, new OffhandSyncItemPacket(player).generatePacket()); + } +} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityOtherPlayerMP.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityOtherPlayerMP.java index 84cd711..1702f1f 100644 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityOtherPlayerMP.java +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityOtherPlayerMP.java @@ -5,45 +5,32 @@ import net.minecraft.item.ItemStack; import net.minecraft.world.World; +import org.spongepowered.asm.lib.Opcodes; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.Redirect; import com.mojang.authlib.GameProfile; import xonin.backhand.api.core.BackhandUtils; +import xonin.backhand.api.core.IBackhandPlayer; @Mixin(EntityOtherPlayerMP.class) -public abstract class MixinEntityOtherPlayerMP extends AbstractClientPlayer { - - @Shadow - private boolean isItemInUse; +public abstract class MixinEntityOtherPlayerMP extends AbstractClientPlayer implements IBackhandPlayer { private MixinEntityOtherPlayerMP(World p_i45074_1_, GameProfile p_i45074_2_) { super(p_i45074_1_, p_i45074_2_); } - @Inject( + @Redirect( method = "onUpdate", - cancellable = true, at = @At( value = "FIELD", - target = "Lnet/minecraft/client/entity/EntityOtherPlayerMP;isItemInUse:Z", - ordinal = 0)) - private void backhand$isItemInUseHook(CallbackInfo ci) { - ItemStack itemStack = getCurrentEquippedItem(); - ItemStack offhand = BackhandUtils.getOffhandItem(this); - if (BackhandUtils.usagePriorAttack(offhand)) itemStack = offhand; - if (!isItemInUse && isEating() && itemStack != null) { - setItemInUse(itemStack, itemStack.getMaxItemUseDuration()); - isItemInUse = true; - } else if (isItemInUse && !isEating()) { - clearItemInUse(); - isItemInUse = false; - } - ci.cancel(); + opcode = Opcodes.GETFIELD, + args = "array=get", + target = "Lnet/minecraft/entity/player/InventoryPlayer;mainInventory:[Lnet/minecraft/item/ItemStack;")) + private ItemStack backhand$isItemInUseHook(ItemStack[] array, int index) { + if (isOffhandItemInUse()) return BackhandUtils.getOffhandItem(this); + return array[index]; } - } diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayer.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayer.java index 7086937..82ca2cc 100644 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayer.java +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayer.java @@ -1,23 +1,35 @@ package xonin.backhand.mixins.early.minecraft; -import net.minecraft.entity.Entity; +import java.util.Objects; + +import net.minecraft.block.BlockDispenser; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; +import net.minecraft.network.play.server.S0BPacketAnimation; +import net.minecraft.util.RegistrySimple; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; 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 com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import xonin.backhand.Backhand; import xonin.backhand.api.core.BackhandUtils; import xonin.backhand.api.core.IBackhandPlayer; -import xonin.backhand.api.core.InventoryPlayerBackhand; +import xonin.backhand.api.core.IOffhandInventory; +import xonin.backhand.packet.OffhandSyncOffhandUse; @Mixin(EntityPlayer.class) public abstract class MixinEntityPlayer extends EntityLivingBase implements IBackhandPlayer { @@ -25,9 +37,7 @@ public abstract class MixinEntityPlayer extends EntityLivingBase implements IBac @Shadow private ItemStack itemInUse; @Shadow - private int itemInUseCount; - @Shadow - public InventoryPlayer inventory = new InventoryPlayerBackhand((EntityPlayer) (Object) this); + public InventoryPlayer inventory; @Unique private float backhand$offHandSwingProgress = 0F; @Unique @@ -37,31 +47,20 @@ public abstract class MixinEntityPlayer extends EntityLivingBase implements IBac @Unique private boolean backhand$isOffHandSwingInProgress = false; @Unique - private int backhand$specialActionTimer = 0; + private boolean backhand$isOffhandItemInUs = false; private MixinEntityPlayer(World p_i1594_1_) { super(p_i1594_1_); } - // TODO: Why are we doing this? - @ModifyReturnValue(method = "isPlayer", at = @At(value = "RETURN")) - private boolean backhand$isPlayer(boolean original) { - return false; - } - - @ModifyExpressionValue( - method = "onItemUseFinish", - at = @At( - value = "INVOKE", - target = "Lnet/minecraftforge/event/ForgeEventFactory;onItemUseFinish(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/item/ItemStack;ILnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;", - remap = false)) - private ItemStack backhand$onItemUseFinish$beforeFinishUse(ItemStack itemStack) { - return BackhandUtils.beforeFinishUseEvent( - (EntityPlayer) (Object) this, - this.itemInUse, - this.itemInUseCount, - itemStack, - this.itemInUse.stackSize); + @WrapMethod(method = "onItemUseFinish") + private void backhand$onItemUseFinishEnd(Operation original) { + EntityPlayer player = (EntityPlayer) (Object) this; + if (Objects.equals(itemInUse, BackhandUtils.getOffhandItem(player))) { + BackhandUtils.useOffhandItem(player, () -> original.call()); + } else { + original.call(); + } } @ModifyExpressionValue( @@ -78,20 +77,107 @@ private MixinEntityPlayer(World p_i1594_1_) { return original; } + @Inject( + method = "setItemInUse", + at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayer;setEating(Z)V")) + private void backhand$setItemInUse(ItemStack p_71008_1_, int p_71008_2_, CallbackInfo ci) { + if (Objects.equals(p_71008_1_, BackhandUtils.getOffhandItem((EntityPlayer) (Object) this))) { + backhand$updateOffhandUse(true); + } else if (isOffhandItemInUse()) { + backhand$updateOffhandUse(false); + } + } + + @Inject( + method = "clearItemInUse", + at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayer;setEating(Z)V")) + private void backhand$clearOffhand(CallbackInfo ci) { + if (isOffhandItemInUse()) { + backhand$updateOffhandUse(false); + } + } + + @Inject(method = "updateEntityActionState", at = @At(value = "TAIL")) + private void backhand$updateOffhandSwingProgress(CallbackInfo ci) { + this.backhand$prevOffHandSwingProgress = this.backhand$offHandSwingProgress; + int var1 = this.getArmSwingAnimationEnd(); + if (this.backhand$isOffHandSwingInProgress) { + ++this.backhand$offHandSwingProgressInt; + if (this.backhand$offHandSwingProgressInt >= var1) { + this.backhand$offHandSwingProgressInt = 0; + this.backhand$isOffHandSwingInProgress = false; + } + } else { + this.backhand$offHandSwingProgressInt = 0; + } + + this.backhand$offHandSwingProgress = (float) this.backhand$offHandSwingProgressInt / (float) var1; + } + + @WrapWithCondition( + method = "stopUsingItem", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;onPlayerStoppedUsing(Lnet/minecraft/world/World;Lnet/minecraft/entity/player/EntityPlayer;I)V")) + private boolean backhand$stopUsingItem(ItemStack stack, World world, EntityPlayer player, int p_77974_3_) { + ItemStack offhand = BackhandUtils.getOffhandItem(player); + if (offhand != null && !isUsingOffhand() + && stack.getItemUseAction() == EnumAction.bow + && ((RegistrySimple) BlockDispenser.dispenseBehaviorRegistry).containsKey(offhand.getItem())) { + // Swap the offhand item into the first available slot to give it usage priority + int slot = (inventory.currentItem == 0) ? 1 : 0; + ItemStack swappedStack = player.inventory.mainInventory[slot]; + inventory.mainInventory[slot] = offhand; + BackhandUtils.setPlayerOffhandItem(player, swappedStack); + stack.onPlayerStoppedUsing(world, player, p_77974_3_); + player.inventory.mainInventory[slot] = backhand$getLegalStack(swappedStack); + BackhandUtils.setPlayerOffhandItem(player, backhand$getLegalStack(offhand)); + return false; + } + return true; + } + + @Unique + private void backhand$updateOffhandUse(boolean state) { + EntityPlayer player = (EntityPlayer) (Object) this; + Backhand.packetHandler + .sendPacketToAllTracking(player, new OffhandSyncOffhandUse(player, state).generatePacket()); + setOffhandItemInUse(state); + } + @Override - public void attackTargetEntityWithCurrentOffItem(Entity target) { - BackhandUtils.attackTargetEntityWithCurrentOffItem((EntityPlayer) (Object) this, target); + public void swingItem() { + if (isUsingOffhand()) { + this.swingOffItem(); + } else { + super.swingItem(); + } } @Override public void swingOffItem() { + EntityPlayer player = (EntityPlayer) (Object) this; + ItemStack stack = BackhandUtils.getOffhandItem(player); + if (stack != null && stack.getItem() != null + && BackhandUtils.useOffhandItem( + player, + false, + () -> stack.getItem() + .onEntitySwing(player, stack))) { + return; + } + if (!this.backhand$isOffHandSwingInProgress || this.backhand$offHandSwingProgressInt >= this.getArmSwingAnimationEnd() / 2 || this.backhand$offHandSwingProgressInt < 0) { this.backhand$offHandSwingProgressInt = -1; this.backhand$isOffHandSwingInProgress = true; - } + if (worldObj instanceof WorldServer world) { + world.getEntityTracker() + .func_151247_a(this, new S0BPacketAnimation(this, 99)); + } + } } @Override @@ -105,29 +191,23 @@ public float getOffSwingProgress(float frame) { } @Override - protected void updateArmSwingProgress() { - super.updateArmSwingProgress(); - this.backhand$prevOffHandSwingProgress = this.backhand$offHandSwingProgress; - int var1 = this.getArmSwingAnimationEnd(); - if (this.backhand$isOffHandSwingInProgress) { - ++this.backhand$offHandSwingProgressInt; - if (this.backhand$offHandSwingProgressInt >= var1) { - this.backhand$offHandSwingProgressInt = 0; - this.backhand$isOffHandSwingInProgress = false; - } - } else { - this.backhand$offHandSwingProgressInt = 0; - } + public void setOffhandItemInUse(boolean usingOffhand) { + this.backhand$isOffhandItemInUs = usingOffhand; + } - this.backhand$offHandSwingProgress = (float) this.backhand$offHandSwingProgressInt / (float) var1; - if (this.backhand$specialActionTimer > 0) { - this.backhand$isOffHandSwingInProgress = false; - this.isSwingInProgress = false; - this.backhand$offHandSwingProgress = 0.0F; - this.backhand$offHandSwingProgressInt = 0; - this.swingProgress = 0.0F; - this.swingProgressInt = 0; - } + @Override + public boolean isOffhandItemInUse() { + return this.backhand$isOffhandItemInUs; + } + @Override + public boolean isUsingOffhand() { + return inventory.currentItem == ((IOffhandInventory) inventory).backhand$getOffhandSlot(); + } + + @Unique + private ItemStack backhand$getLegalStack(ItemStack stack) { + if (stack == null || stack.stackSize == 0) return null; + return stack; } } diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayerClient.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayerClient.java index 0bd95bd..6d1c8b9 100644 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayerClient.java +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayerClient.java @@ -1,45 +1,30 @@ package xonin.backhand.mixins.early.minecraft; -import net.minecraft.client.Minecraft; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemBow; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; +import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.Shadow; import xonin.backhand.api.core.IBackhandPlayer; -import xonin.backhand.client.utils.BackhandClientUtils; @Mixin(EntityPlayer.class) public abstract class MixinEntityPlayerClient extends EntityLivingBase implements IBackhandPlayer { - private MixinEntityPlayerClient(World p_i1594_1_) { - super(p_i1594_1_); - } + @Shadow + public InventoryPlayer inventory; - @Inject(method = "getItemIcon", at = @At(value = "HEAD")) - private void backhand2$getItemIcon(ItemStack itemStackIn, int p_70620_2_, CallbackInfoReturnable cir) { - EntityPlayer player = Minecraft.getMinecraft().thePlayer; - if (itemStackIn == player.getCurrentEquippedItem() && player.getCurrentEquippedItem() != null - && player.getItemInUse() != null - && player.getCurrentEquippedItem() - .getItem() instanceof ItemBow - && player.getCurrentEquippedItem() != player.getItemInUse()) { - BackhandClientUtils.disableMainhandAnimation = true; - } + public MixinEntityPlayerClient(World p_i1594_1_) { + super(p_i1594_1_); } @Override - public float getSwingProgress(float partialTicks) { - if (BackhandClientUtils.offhandFPRender) { - return getOffSwingProgress(partialTicks); + public float getSwingProgress(float p_70678_1_) { + if (isUsingOffhand()) { + return getOffSwingProgress(p_70678_1_); } - return super.getSwingProgress(partialTicks); + return super.getSwingProgress(p_70678_1_); } } diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayerMP.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayerMP.java deleted file mode 100644 index 3dcba09..0000000 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityPlayerMP.java +++ /dev/null @@ -1,31 +0,0 @@ -package xonin.backhand.mixins.early.minecraft; - -import java.util.List; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.inventory.Container; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.mojang.authlib.GameProfile; - -import xonin.backhand.api.core.BackhandUtils; - -@Mixin(EntityPlayerMP.class) -public abstract class MixinEntityPlayerMP extends EntityPlayer { - - public MixinEntityPlayerMP(World p_i45324_1_, GameProfile p_i45324_2_) { - super(p_i45324_1_, p_i45324_2_); - } - - @Inject(method = "sendContainerAndContentsToPlayer", at = @At(value = "TAIL")) - private void backhand$syncOffhand(Container p_71110_1_, List p_71110_2_, CallbackInfo ci) { - BackhandUtils.getOffhandEP(this).syncOffhand = true; - } -} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityRenderer.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityRenderer.java new file mode 100644 index 0000000..d3545da --- /dev/null +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinEntityRenderer.java @@ -0,0 +1,26 @@ +package xonin.backhand.mixins.early.minecraft; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.EntityRenderer; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import xonin.backhand.api.core.BackhandUtils; +import xonin.backhand.client.utils.BackhandRenderHelper; + +@Mixin(EntityRenderer.class) +public abstract class MixinEntityRenderer { + + @Inject( + method = "updateRenderer", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ItemRenderer;updateEquippedItem()V")) + private void backhand$updateOffhandItem(CallbackInfo ci) { + BackhandUtils.useOffhandItem( + Minecraft.getMinecraft().thePlayer, + false, + BackhandRenderHelper.itemRenderer::updateEquippedItem); + } +} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinGuiContainerCreative.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinGuiContainerCreative.java new file mode 100644 index 0000000..07cdfd5 --- /dev/null +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinGuiContainerCreative.java @@ -0,0 +1,26 @@ +package xonin.backhand.mixins.early.minecraft; + +import net.minecraft.client.gui.inventory.GuiContainerCreative; +import net.minecraft.creativetab.CreativeTabs; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.llamalad7.mixinextras.sugar.Local; + +@Mixin(GuiContainerCreative.class) +public abstract class MixinGuiContainerCreative { + + @Inject( + method = "setCurrentCreativeTab", + at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 1)) + protected void backhand$removeOffhandSlot(CreativeTabs p_147050_1_, CallbackInfo ci, + @Local GuiContainerCreative.ContainerCreative container) { + GuiContainerCreative.CreativeSlot slot = (GuiContainerCreative.CreativeSlot) container.inventorySlots + .get(container.inventorySlots.size() - 1); + slot.xDisplayPosition = -2000; + slot.yDisplayPosition = -2000; + } +} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinGuiInventory.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinGuiInventory.java new file mode 100644 index 0000000..b5e2422 --- /dev/null +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinGuiInventory.java @@ -0,0 +1,43 @@ +package xonin.backhand.mixins.early.minecraft; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.inventory.GuiInventory; +import net.minecraft.client.renderer.InventoryEffectRenderer; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.inventory.Container; + +import org.lwjgl.opengl.GL11; +import org.spongepowered.asm.mixin.Mixin; +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; + +@Mixin(GuiInventory.class) +public abstract class MixinGuiInventory extends InventoryEffectRenderer { + + public MixinGuiInventory(Container p_i1089_1_) { + super(p_i1089_1_); + } + + @Inject(method = "drawGuiContainerBackgroundLayer", at = @At("TAIL")) + protected void backhand$drawOffhandSlot(float partialTicks, int mouseX, int mouseY, CallbackInfo ci) { + backhand$drawItemStackSlot(guiLeft + 78, guiTop + 63); + } + + @Unique + private static void backhand$drawItemStackSlot(int x, int y) { + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + Minecraft.getMinecraft() + .getTextureManager() + .bindTexture(Gui.statIcons); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(x + 1, y + 1 + 18, 0, 0 * 0.0078125f, 18 * 0.0078125f); + tessellator.addVertexWithUV(x + 1 + 18, y + 1 + 18, 0, 18 * 0.0078125f, 18 * 0.0078125f); + tessellator.addVertexWithUV(x + 1 + 18, y + 1, 0, 18 * 0.0078125f, 0 * 0.0078125f); + tessellator.addVertexWithUV(x + 1, y + 1, 0, 0 * 0.0078125f, 0 * 0.0078125f); + tessellator.draw(); + } +} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinInventoryPlayer.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinInventoryPlayer.java new file mode 100644 index 0000000..61e8614 --- /dev/null +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinInventoryPlayer.java @@ -0,0 +1,151 @@ +package xonin.backhand.mixins.early.minecraft; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagList; + +import org.spongepowered.asm.lib.Opcodes; +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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.sugar.Local; + +import xonin.backhand.api.core.IOffhandInventory; +import xonin.backhand.utils.BackhandConfig; + +@Mixin(InventoryPlayer.class) +public abstract class MixinInventoryPlayer implements IOffhandInventory { + + @Shadow + public int currentItem; + + @Shadow + public EntityPlayer player; + + @Shadow + public ItemStack[] mainInventory; + + @Shadow + public abstract boolean addItemStackToInventory(ItemStack p_70441_1_); + + @Shadow + public abstract int getInventoryStackLimit(); + + @Unique + private int backhand$offhandSlot; + + @Unique + private List backhand$bg2Stacks = new ArrayList<>(); + + @Inject( + method = "readFromNBT", + at = @At( + value = "FIELD", + opcode = Opcodes.PUTFIELD, + target = "Lnet/minecraft/entity/player/InventoryPlayer;mainInventory:[Lnet/minecraft/item/ItemStack;", + shift = At.Shift.AFTER)) + private void backhand$addOffhandSlot(NBTTagList p_70443_1_, CallbackInfo ci) { + backhand$offhandSlot = mainInventory.length; + mainInventory = new ItemStack[mainInventory.length + 1]; + } + + @Inject( + method = "readFromNBT", + at = @At( + value = "FIELD", + opcode = Opcodes.GETFIELD, + target = "Lnet/minecraft/entity/player/InventoryPlayer;mainInventory:[Lnet/minecraft/item/ItemStack;", + ordinal = 0)) + private void backhand$importBG2Items(NBTTagList p_70443_1_, CallbackInfo ci, @Local ItemStack stack, + @Local(name = "j") int index) { + if (index >= 150 && index < 168) { + backhand$bg2Stacks.add(stack); + } + } + + @Inject(method = "readFromNBT", at = @At(value = "TAIL")) + private void backhand$giveBG2Items(NBTTagList p_70443_1_, CallbackInfo ci) { + for (ItemStack stack : backhand$bg2Stacks) { + if (!addItemStackToInventory(stack)) { + player.entityDropItem(stack, 0.0F); + } + } + + backhand$bg2Stacks = null; + } + + @Inject( + method = "", + at = @At( + value = "FIELD", + opcode = Opcodes.PUTFIELD, + target = "Lnet/minecraft/entity/player/InventoryPlayer;mainInventory:[Lnet/minecraft/item/ItemStack;", + shift = At.Shift.AFTER)) + private void backhand$addOffhandSlot(EntityPlayer p_i1750_1_, CallbackInfo ci) { + backhand$offhandSlot = mainInventory.length; + mainInventory = new ItemStack[mainInventory.length + 1]; + } + + @ModifyReturnValue(method = "getCurrentItem", at = @At("RETURN")) + private ItemStack backhand$getOffhandItem(ItemStack original) { + if (currentItem == backhand$getOffhandSlot()) { + return backhand$getOffhandItem(); + } + return original; + } + + @ModifyReturnValue(method = "getFirstEmptyStack", at = @At("RETURN")) + private int backhand$checkOffhandPickup(int original) { + if (!BackhandConfig.OffhandPickup && original == backhand$getOffhandSlot()) { + return -1; + } + return original; + } + + @Inject(method = "storeItemStack", at = @At("HEAD"), cancellable = true) + private void backhand$storeItemStack(ItemStack checkStack, CallbackInfoReturnable cir) { + ItemStack stack = player.getHeldItem(); + if (stack != null && checkStack(stack, checkStack)) { + cir.setReturnValue(currentItem); + } + + stack = backhand$getOffhandItem(); + if (stack != null && checkStack(stack, checkStack)) { + cir.setReturnValue(backhand$getOffhandSlot()); + } + } + + @Unique + private boolean checkStack(ItemStack a, ItemStack b) { + return a.getItem() == b.getItem() && a.isStackable() + && a.stackSize < a.getMaxStackSize() + && a.stackSize < getInventoryStackLimit() + && (!a.getHasSubtypes() || a.getItemDamage() == b.getItemDamage()) + && ItemStack.areItemStackTagsEqual(a, b); + } + + @Override + public ItemStack backhand$getOffhandItem() { + return mainInventory[backhand$getOffhandSlot()]; + } + + @Override + public void backhand$setOffhandItem(ItemStack stack) { + mainInventory[backhand$getOffhandSlot()] = stack; + } + + @Override + public int backhand$getOffhandSlot() { + return backhand$offhandSlot; + } +} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemBow.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemBow.java index 9f51e62..0e80e8d 100644 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemBow.java +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemBow.java @@ -1,31 +1,34 @@ package xonin.backhand.mixins.early.minecraft; -import net.minecraft.client.Minecraft; +import net.minecraft.block.BlockDispenser; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemBow; -import net.minecraft.util.IIcon; +import net.minecraft.item.ItemStack; +import net.minecraft.util.RegistrySimple; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import xonin.backhand.client.utils.BackhandClientUtils; +import xonin.backhand.api.core.BackhandUtils; @Mixin(ItemBow.class) public abstract class MixinItemBow extends Item { - @SideOnly(Side.CLIENT) - @ModifyReturnValue(method = "getItemIconForUseDuration", at = @At("RETURN")) - private IIcon backhand$cancelAnimation(IIcon original) { - if (BackhandClientUtils.disableMainhandAnimation) { - BackhandClientUtils.disableMainhandAnimation = false; - EntityPlayer player = Minecraft.getMinecraft().thePlayer; - return getIcon(player.getCurrentEquippedItem(), 0, player, player.getItemInUse(), 0); + @ModifyExpressionValue( + method = "onItemRightClick", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/player/InventoryPlayer;hasItem(Lnet/minecraft/item/Item;)Z")) + private boolean backhand$checkOffhand(boolean original, @Local(argsOnly = true) EntityPlayer player) { + if (!original) { + ItemStack offhand = BackhandUtils.getOffhandItem(player); + return offhand != null + && ((RegistrySimple) BlockDispenser.dispenseBehaviorRegistry).containsKey(offhand.getItem()); } - return original; + return true; } } diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemRenderer.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemRenderer.java index a6ac6d8..05096fb 100644 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemRenderer.java +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemRenderer.java @@ -1,8 +1,8 @@ package xonin.backhand.mixins.early.minecraft; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemMap; import net.minecraft.item.ItemStack; @@ -14,8 +14,6 @@ import xonin.backhand.api.core.BackhandUtils; import xonin.backhand.api.core.IBackhandPlayer; -import xonin.backhand.client.ClientEventHandler; -import xonin.backhand.client.utils.BackhandClientUtils; import xonin.backhand.client.utils.BackhandRenderHelper; import xonin.backhand.utils.BackhandConfig; import xonin.backhand.utils.BackhandConfigClient; @@ -25,10 +23,8 @@ public abstract class MixinItemRenderer { @Inject(method = "renderItemInFirstPerson", at = @At("RETURN")) private void backhand$renderItemInFirstPerson(float frame, CallbackInfo ci) { - if (BackhandClientUtils.offhandFPRender) return; - - EntityPlayer player = Minecraft.getMinecraft().thePlayer; - ClientEventHandler.renderingPlayer = player; + EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer; + if (BackhandUtils.isUsingOffhand(player)) return; ItemStack mainhandItem = player.getCurrentEquippedItem(); ItemStack offhandItem = BackhandUtils.getOffhandItem(player); @@ -43,13 +39,19 @@ public abstract class MixinItemRenderer { return; } - BackhandClientUtils.firstPersonFrame = frame; - BackhandRenderHelper.itemRenderer.updateEquippedItem(); - BackhandClientUtils.offhandFPRender = true; + BackhandRenderHelper.firstPersonFrame = frame; GL11.glEnable(GL11.GL_CULL_FACE); GL11.glCullFace(GL11.GL_FRONT); - BackhandRenderHelper.renderOffhandItem((ItemRenderer) (Object) this, frame); + GL11.glPushMatrix(); + GL11.glScalef(-1, 1, 1); + float f3 = player.prevRenderArmPitch + (player.renderArmPitch - player.prevRenderArmPitch) * frame; + float f4 = player.prevRenderArmYaw + (player.renderArmYaw - player.prevRenderArmYaw) * frame; + GL11.glRotatef((player.rotationPitch - f3) * -0.1F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef((player.rotationYaw - f4) * -0.1F, 0.0F, 1.0F, 0.0F); + BackhandUtils + .useOffhandItem(player, false, () -> BackhandRenderHelper.itemRenderer.renderItemInFirstPerson(frame)); + GL11.glPopMatrix(); GL11.glCullFace(GL11.GL_BACK); - BackhandClientUtils.offhandFPRender = false; } + } diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemStack.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemStack.java index 8c21b0c..c2047c7 100644 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemStack.java +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemStack.java @@ -1,30 +1,32 @@ package xonin.backhand.mixins.early.minecraft; -import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.event.ForgeEventFactory; +import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import xonin.backhand.api.core.BackhandUtils; @Mixin(ItemStack.class) public abstract class MixinItemStack { - @Inject(method = "damageItem", at = @At(value = "TAIL")) - private void backhand$damageOffhand(int p_77972_1_, EntityLivingBase entity, CallbackInfo ci) { - if (!(entity instanceof EntityPlayer player) || entity instanceof FakePlayer) return; - - ItemStack itemStack = (ItemStack) (Object) this; - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - if (offhandItem != null && itemStack == offhandItem && itemStack.stackSize == 0) { - BackhandUtils.setPlayerOffhandItem(player, null); - ForgeEventFactory.onPlayerDestroyItem(player, offhandItem); + @WrapWithCondition( + method = "updateAnimation", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/Item;onUpdate(Lnet/minecraft/item/ItemStack;Lnet/minecraft/world/World;Lnet/minecraft/entity/Entity;IZ)V")) + private boolean backhand$updateOffhand(Item item, ItemStack stack, World worldIn, Entity entityIn, int index, + boolean p_77663_5_) { + if (entityIn instanceof EntityPlayer player && index == BackhandUtils.getOffhandSlot(player)) { + BackhandUtils.useOffhandItem(player, () -> item.onUpdate(stack, worldIn, entityIn, index, p_77663_5_)); + return false; } + return true; } } diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemStackClient.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemStackClient.java deleted file mode 100644 index 5ee3bd4..0000000 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinItemStackClient.java +++ /dev/null @@ -1,42 +0,0 @@ -package xonin.backhand.mixins.early.minecraft; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumAction; -import net.minecraft.item.ItemStack; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -import com.llamalad7.mixinextras.injector.ModifyReturnValue; - -import xonin.backhand.HookContainerClass; -import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.client.ClientEventHandler; - -@Mixin(ItemStack.class) -public abstract class MixinItemStackClient { - - @ModifyReturnValue(method = "getItemUseAction", at = @At(value = "TAIL")) - private EnumAction backhand$getOffhandUseAction(EnumAction original) { - if (original == EnumAction.none || ClientEventHandler.renderingPlayer == null) { - return original; - } - EntityPlayer player = ClientEventHandler.renderingPlayer; - ItemStack itemStack = (ItemStack) (Object) this; - ItemStack offhandItem = BackhandUtils.getOffhandItem(player); - if (offhandItem != null) { - ItemStack mainHandItem = player.getCurrentEquippedItem(); - if (mainHandItem != null && (BackhandUtils.checkForRightClickFunctionNoAction(mainHandItem) - || HookContainerClass.isItemBlock(mainHandItem.getItem()))) { - if (itemStack == offhandItem) { - return EnumAction.none; - } - } else if (itemStack == mainHandItem && (!(BackhandUtils.checkForRightClickFunctionNoAction(offhandItem) - || HookContainerClass.isItemBlock(offhandItem.getItem())) || player.getItemInUse() != mainHandItem)) { - return EnumAction.none; - } - } - return original; - } - -} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinMinecraft.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinMinecraft.java new file mode 100644 index 0000000..0a60b6a --- /dev/null +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinMinecraft.java @@ -0,0 +1,280 @@ +package xonin.backhand.mixins.early.minecraft; + +import net.minecraft.block.material.Material; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityClientPlayerMP; +import net.minecraft.client.multiplayer.PlayerControllerMP; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.client.particle.EffectRenderer; +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.ItemStack; +import net.minecraft.util.MovingObjectPosition; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; + +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +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.Constant; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyConstant; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +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; + +@Mixin(Minecraft.class) +public abstract class MixinMinecraft { + + @Shadow + public EntityClientPlayerMP thePlayer; + + @Shadow + public WorldClient theWorld; + + @Shadow + public MovingObjectPosition objectMouseOver; + + @Shadow + public PlayerControllerMP playerController; + + @Shadow + private int rightClickDelayTimer; + + @Shadow + @Final + private static Logger logger; + + @Shadow + public EntityRenderer entityRenderer; + + @Shadow + public EffectRenderer effectRenderer; + @Unique + private int backhand$breakBlockTimer = 0; + + /** + * @author Lyft + * @reason Offhand support + * Don't change this methods visibility despite what mixin debug says. + * Some mods AT this and changing the visibility will break them. + */ + @Overwrite + public void func_147121_ag() { + rightClickDelayTimer = 4; + ItemStack mainHandItem = thePlayer.inventory.getCurrentItem(); + ItemStack offhandItem = BackhandUtils.getOffhandItem(thePlayer); + boolean useAction = true; + + if (objectMouseOver == null) { + logger.warn("Null returned as 'hitResult', this shouldn't happen!"); + return; + } + + switch (objectMouseOver.typeOfHit) { + case ENTITY -> { + if (playerController.interactWithEntitySendPacket(thePlayer, objectMouseOver.entityHit)) { + useAction = false; + } else if (BackhandUtils.useOffhandItem( + thePlayer, + () -> playerController.interactWithEntitySendPacket(thePlayer, objectMouseOver.entityHit))) { + useAction = false; + } + } + case BLOCK -> { + int x = objectMouseOver.blockX; + int y = objectMouseOver.blockY; + int z = objectMouseOver.blockZ; + + if (!theWorld.getBlock(x, y, z) + .isAir(theWorld, x, y, z)) { + int mainOriginalSize = mainHandItem != null ? mainHandItem.stackSize : 0; + int offhandOriginalSize = offhandItem != null ? offhandItem.stackSize : 0; + + useAction = !backhand$rightClickBlock(mainHandItem, offhandItem); + + if (mainHandItem != null) { + if (mainHandItem.stackSize == 0) { + thePlayer.setCurrentItemOrArmor(0, null); + } else if (mainHandItem.stackSize != mainOriginalSize) { + entityRenderer.itemRenderer.resetEquippedProgress(); + } + } + + if (offhandItem != null) { + if (offhandItem.stackSize == 0) { + BackhandUtils.setPlayerOffhandItem(thePlayer, null); + } else if (offhandItem.stackSize != offhandOriginalSize) { + BackhandRenderHelper.itemRenderer.resetEquippedProgress(); + } + } + } + } + } + + if (!useAction) return; + boolean result = !net.minecraftforge.event.ForgeEventFactory + .onPlayerInteract( + thePlayer, + net.minecraftforge.event.entity.player.PlayerInteractEvent.Action.RIGHT_CLICK_AIR, + 0, + 0, + 0, + -1, + theWorld) + .isCanceled(); + if (result && mainHandItem != null && playerController.sendUseItem(thePlayer, theWorld, mainHandItem)) { + entityRenderer.itemRenderer.resetEquippedProgress2(); + } + + if (offhandItem == null || thePlayer.getItemInUse() != null) return; + useAction = !BackhandUtils.useOffhandItem(thePlayer, () -> { + PlayerInteractEvent useItemEvent = new PlayerInteractEvent( + thePlayer, + PlayerInteractEvent.Action.RIGHT_CLICK_AIR, + 0, + 0, + -1, + 0, + theWorld); + if (!MinecraftForge.EVENT_BUS.post(useItemEvent)) { + if (playerController.sendUseItem(thePlayer, theWorld, offhandItem)) { + BackhandRenderHelper.itemRenderer.resetEquippedProgress(); + } + + return thePlayer.getItemInUse() != null; + } + return false; + }); + + if (!useAction) return; + switch (objectMouseOver.typeOfHit) { + case ENTITY -> { + if (BackhandConfig.OffhandAttack) { + BackhandUtils.useOffhandItem(thePlayer, () -> { + thePlayer.swingItem(); + playerController.attackEntity(thePlayer, objectMouseOver.entityHit); + }); + } + } + case BLOCK -> { + if (BackhandConfig.OffhandBreakBlocks && offhandItem.getItemUseAction() == EnumAction.none) { + BackhandUtils.useOffhandItem(thePlayer, () -> { + backhand$breakBlockTimer = 5; + playerController.clickBlock( + objectMouseOver.blockX, + objectMouseOver.blockY, + objectMouseOver.blockZ, + objectMouseOver.sideHit); + }); + } + } + } + } + + @WrapWithCondition( + method = "func_147115_a", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/multiplayer/PlayerControllerMP;resetBlockRemoving()V")) + private boolean backhand$pauseReset(PlayerControllerMP instance) { + if (backhand$breakBlockTimer > 0) { + backhand$breakBlockTimer--; + return false; + } + return true; + } + + @Inject(method = "func_147115_a", at = @At(value = "HEAD")) + private void backhand$breakBlockOffhand(boolean leftClick, CallbackInfo ci) { + if (backhand$breakBlockTimer > 0) { + BackhandUtils.useOffhandItem(thePlayer, () -> { + int i = objectMouseOver.blockX; + int j = objectMouseOver.blockY; + int k = objectMouseOver.blockZ; + + if (theWorld.getBlock(i, j, k) + .getMaterial() != Material.air) { + playerController.onPlayerDamageBlock(i, j, k, objectMouseOver.sideHit); + + if (thePlayer.isCurrentToolAdventureModeExempt(i, j, k)) { + effectRenderer.addBlockHitEffects(i, j, k, objectMouseOver); + thePlayer.swingItem(); + } + } + }); + } + } + + @ModifyConstant(method = "func_147112_ai", constant = @Constant(intValue = 9)) + private int backhand$adjustSlotOffset(int constant) { + return 10; + } + + @Unique + private boolean backhand$rightClickBlock(ItemStack mainHandItem, ItemStack offhandItem) { + int x = objectMouseOver.blockX; + int y = objectMouseOver.blockY; + int z = objectMouseOver.blockZ; + + boolean result; + + if (offhandItem != null && backhand$doesOffhandNeedPriority(mainHandItem)) { + result = BackhandUtils.useOffhandItem(thePlayer, () -> backhand$rightClickBlock(offhandItem, x, y, z)); + if (!result) { + result = backhand$rightClickBlock(mainHandItem, x, y, z); + } + } else { + result = backhand$rightClickBlock(mainHandItem, x, y, z); + if (!result && offhandItem != null) { + result = BackhandUtils.useOffhandItem(thePlayer, () -> backhand$rightClickBlock(offhandItem, x, y, z)); + } + } + + return result; + } + + @Unique + private boolean backhand$rightClickBlock(ItemStack stack, int x, int y, int z) { + boolean result = !net.minecraftforge.event.ForgeEventFactory + .onPlayerInteract( + thePlayer, + net.minecraftforge.event.entity.player.PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK, + x, + y, + z, + objectMouseOver.sideHit, + theWorld) + .isCanceled(); + if (result && playerController + .onPlayerRightClick(thePlayer, theWorld, stack, x, y, z, objectMouseOver.sideHit, objectMouseOver.hitVec)) { + thePlayer.swingItem(); + return true; + } + return false; + } + + @Unique + private boolean backhand$doesOffhandNeedPriority(ItemStack mainHandItem) { + if (mainHandItem == null) return false; + + for (Class clazz : ClientProxy.offhandPriorityItems) { + if (clazz.isAssignableFrom( + mainHandItem.getItem() + .getClass())) { + return true; + } + } + + return false; + } +} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinModelBiped.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinModelBiped.java index 4ba3936..ed44b62 100644 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinModelBiped.java +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinModelBiped.java @@ -8,13 +8,17 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.MathHelper; +import org.spongepowered.asm.lib.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import xonin.backhand.api.core.BackhandUtils; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; + +import xonin.backhand.api.core.IBackhandPlayer; import xonin.backhand.client.utils.BackhandRenderHelper; @Mixin(ModelBiped.class) @@ -35,19 +39,16 @@ public abstract class MixinModelBiped extends ModelBase { BackhandRenderHelper.moveOffHandArm(entity, (ModelBiped) (Object) this, f6); } - @Inject( + @ModifyExpressionValue( method = "setRotationAngles", at = @At( value = "FIELD", - target = "Lnet/minecraft/client/model/ModelBiped;aimedBow:Z", - shift = At.Shift.BY, - by = 2), - cancellable = true) - private void backhand$moveOffhandAimedBow(float f1, float f2, float f3, float f4, float f5, float f6, Entity entity, - CallbackInfo ci) { + opcode = Opcodes.GETFIELD, + target = "Lnet/minecraft/client/model/ModelBiped;aimedBow:Z")) + private boolean backhand$moveOffhandAimedBow(boolean original, @Local(argsOnly = true, ordinal = 2) float f3, + @Local(argsOnly = true) Entity entity) { if (entity instanceof EntityPlayer player && entity == Minecraft.getMinecraft().thePlayer - && BackhandUtils.getOffhandItem(player) != null - && player.getItemInUse() == BackhandUtils.getOffhandItem(player)) { + && ((IBackhandPlayer) player).isOffhandItemInUse()) { bipedLeftArm.rotateAngleZ = 0.0F; bipedRightArm.rotateAngleZ = 0.0F; bipedLeftArm.rotateAngleY = 0.1F + bipedHead.rotateAngleY; @@ -60,8 +61,9 @@ public abstract class MixinModelBiped extends ModelBase { bipedRightArm.rotateAngleZ += MathHelper.cos(f3 * 0.09F) * 0.05F + 0.05F; bipedLeftArm.rotateAngleX -= MathHelper.sin(f3 * 0.067F) * 0.05F; bipedRightArm.rotateAngleX += MathHelper.sin(f3 * 0.067F) * 0.05F; - ci.cancel(); + return false; } + return original; } } diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinNetHandlerPlayClient.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinNetHandlerPlayClient.java index b9c5984..4c8f443 100644 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinNetHandlerPlayClient.java +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinNetHandlerPlayClient.java @@ -1,17 +1,28 @@ package xonin.backhand.mixins.early.minecraft; +import net.minecraft.client.Minecraft; import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.entity.Entity; +import net.minecraft.network.play.server.S0BPacketAnimation; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; -import xonin.backhand.api.core.InventoryPlayerBackhand; +import xonin.backhand.api.core.IBackhandPlayer; +import xonin.backhand.api.core.IOffhandInventory; @Mixin(NetHandlerPlayClient.class) public abstract class MixinNetHandlerPlayClient { + @Shadow + private Minecraft gameController; + @ModifyExpressionValue( method = "handleHeldItemChange", at = @At( @@ -20,6 +31,16 @@ public abstract class MixinNetHandlerPlayClient { ordinal = 1)) private int backhand$isValidInventorySlot(int original) { // return a valid int e.g. between 0 and < 9 - return InventoryPlayerBackhand.isValidSwitch(original) ? 0 : -1; + return IOffhandInventory.isValidSwitch(original, gameController.thePlayer) ? 0 : -1; + } + + @Inject( + method = "handleAnimation", + at = @At(value = "INVOKE", target = "Lnet/minecraft/network/play/server/S0BPacketAnimation;func_148977_d()I")) + private void backhand$handleOffhandSwing(S0BPacketAnimation packetIn, CallbackInfo ci, @Local Entity entity) { + if (!(entity instanceof IBackhandPlayer player)) return; + if (packetIn.func_148978_c() == 99) { + player.swingOffItem(); + } } } diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinNetHandlerPlayServer.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinNetHandlerPlayServer.java index dc6261e..df1b92e 100644 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinNetHandlerPlayServer.java +++ b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinNetHandlerPlayServer.java @@ -1,26 +1,20 @@ package xonin.backhand.mixins.early.minecraft; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.EnumAction; -import net.minecraft.item.ItemStack; import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.network.Packet; -import net.minecraft.network.play.client.C02PacketUseEntity; -import net.minecraft.network.play.client.C07PacketPlayerDigging; -import net.minecraft.network.play.server.S2FPacketSetSlot; import net.minecraft.server.management.ItemInWorldManager; 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 com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.api.core.InventoryPlayerBackhand; +import xonin.backhand.api.core.IOffhandInventory; +import xonin.backhand.utils.BackhandConfig; @Mixin(NetHandlerPlayServer.class) public abstract class MixinNetHandlerPlayServer { @@ -28,9 +22,6 @@ public abstract class MixinNetHandlerPlayServer { @Shadow public EntityPlayerMP playerEntity; - @Unique - private boolean backhand$swappedOffhand = false; - @ModifyExpressionValue( method = "processHeldItemChange", at = @At( @@ -39,82 +30,24 @@ public abstract class MixinNetHandlerPlayServer { ordinal = 1)) private int backhand$isValidInventorySlot(int original) { // return a valid int e.g. between 0 and < 9 - return InventoryPlayerBackhand.isValidSwitch(original) ? 0 : -1; + return IOffhandInventory.isValidSwitch(original, playerEntity) ? 0 : -1; } - @Inject( + @WrapWithCondition( method = "processPlayerDigging", at = @At( value = "INVOKE", target = "Lnet/minecraft/server/management/ItemInWorldManager;uncheckedTryHarvestBlock(III)V")) - private void backhand$playerDigging(C07PacketPlayerDigging packetIn, CallbackInfo ci) { - ItemInWorldManager instance = playerEntity.theItemInWorldManager; - int x = packetIn.func_149505_c(); - int y = packetIn.func_149503_d(); - int z = packetIn.func_149502_e(); - instance.theWorld.destroyBlockInWorldPartially(instance.thisPlayerMP.getEntityId(), x, y, z, -1); - instance.tryHarvestBlock(x, y, z); + private boolean backhand$playerDigging(ItemInWorldManager instance, int l, int block, int i) { + return BackhandConfig.OffhandBreakBlocks || !BackhandUtils.isUsingOffhand(playerEntity); } - @Inject( - method = "processPlayerDigging", + @WrapWithCondition( + method = "processUseEntity", at = @At( value = "INVOKE", - target = "Lnet/minecraft/entity/player/EntityPlayerMP;dropOneItem(Z)Lnet/minecraft/entity/item/EntityItem;")) - private void backhand$playerDropItem(C07PacketPlayerDigging packetIn, CallbackInfo ci) { - BackhandUtils.resetAndDelayHotswap(playerEntity, 5); - } - - @Inject(method = "processUseEntity", at = @At("HEAD")) - private void backhand$hotswapOnEntityInteract(C02PacketUseEntity packetIn, CallbackInfo ci) { - if (backhand$shouldSwapOffhand(packetIn.func_149565_c())) { - BackhandUtils.swapOffhandItem(playerEntity); - backhand$swappedOffhand = true; - } - } - - @Inject( - method = "processUseEntity", - at = { - @At( - value = "INVOKE", - target = "Lnet/minecraft/network/NetHandlerPlayServer;kickPlayerFromServer(Ljava/lang/String;)V"), - @At(value = "TAIL") }) - private void backhand$swapBackPostEntityInteract(C02PacketUseEntity packetIn, CallbackInfo ci) { - if (backhand$swappedOffhand) { - BackhandUtils.swapOffhandItem(playerEntity); - } - backhand$swappedOffhand = false; - } - - @Inject(method = "sendPacket", at = @At(value = "HEAD"), cancellable = true) - private void backhand$skipSetSlotOnHotswap(Packet packetIn, CallbackInfo ci) { - if (packetIn instanceof S2FPacketSetSlot setSlotPacket) { - if (backhand$shouldSkipSetSlot(setSlotPacket)) { - ci.cancel(); - } - } - } - - @Unique - private boolean backhand$shouldSwapOffhand(C02PacketUseEntity.Action action) { - ItemStack offhandStack = BackhandUtils.getOffhandItem(playerEntity); - return !playerEntity.isUsingItem() && BackhandUtils.checkForRightClickFunction(offhandStack) - && offhandStack.getItemUseAction() != EnumAction.bow - && !BackhandUtils.checkForRightClickFunction(playerEntity.getCurrentEquippedItem()) - && action == C02PacketUseEntity.Action.INTERACT; - } - - @Unique - private boolean backhand$shouldSkipSetSlot(S2FPacketSetSlot setSlotPacket) { - int packetWindowId = setSlotPacket.field_149179_a; - int packetSlot = setSlotPacket.field_149177_b; - ItemStack packetStack = setSlotPacket.field_149178_c; - ItemStack offhandStack = BackhandUtils.getOffhandItem(playerEntity); - return offhandStack != null && BackhandUtils.getOffhandEP(playerEntity).ignoreSetSlot - && packetStack != null - && packetSlot == BackhandUtils.getOffhandEP(playerEntity).activeSlot - && packetStack.getItem() == offhandStack.getItem() - && packetWindowId != -1; + target = "Lnet/minecraft/entity/player/EntityPlayerMP;attackTargetEntityWithCurrentItem(Lnet/minecraft/entity/Entity;)V")) + private boolean backhand$checkOffhandAttack(EntityPlayerMP instance, Entity entity) { + return BackhandConfig.OffhandAttack || !BackhandUtils.isUsingOffhand(playerEntity); } } diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinPlayerControllerMP.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinPlayerControllerMP.java deleted file mode 100644 index 4c3179c..0000000 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinPlayerControllerMP.java +++ /dev/null @@ -1,33 +0,0 @@ -package xonin.backhand.mixins.early.minecraft; - -import net.minecraft.client.multiplayer.PlayerControllerMP; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.llamalad7.mixinextras.injector.ModifyReturnValue; - -import xonin.backhand.client.BackhandClientTickHandler; -import xonin.backhand.client.utils.BackhandClientUtils; - -@Mixin(PlayerControllerMP.class) -public abstract class MixinPlayerControllerMP { - - @Inject(method = "resetBlockRemoving", at = @At("HEAD"), cancellable = true) - private void backhand$cancelRemoval(CallbackInfo ci) { - if (BackhandClientUtils.countToCancel > 0) { - BackhandClientUtils.countToCancel--; - ci.cancel(); - } - } - - @ModifyReturnValue(method = "interactWithEntitySendPacket", at = @At("RETURN")) - private boolean backhand$setAttackDelay(boolean original) { - if (original) { - BackhandClientTickHandler.attackDelay = 5; - } - return original; - } -} diff --git a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinWorld.java b/src/main/java/xonin/backhand/mixins/early/minecraft/MixinWorld.java deleted file mode 100644 index 96256dc..0000000 --- a/src/main/java/xonin/backhand/mixins/early/minecraft/MixinWorld.java +++ /dev/null @@ -1,23 +0,0 @@ -package xonin.backhand.mixins.early.minecraft; - -import net.minecraft.world.IBlockAccess; -import net.minecraft.world.World; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import xonin.backhand.client.world.DummyWorld; - -@Mixin(World.class) -public abstract class MixinWorld { - - @Inject(method = "doesBlockHaveSolidTopSurface", at = @At(value = "HEAD"), cancellable = true) - private static void backhand$allowPlacementInDummyWorld(IBlockAccess worldIn, int x, int y, int z, - CallbackInfoReturnable cir) { - if (worldIn instanceof DummyWorld) { - cir.setReturnValue(true); - } - } -} diff --git a/src/main/java/xonin/backhand/mixins/late/carpentersblocks/MixinPlayerPermissions.java b/src/main/java/xonin/backhand/mixins/late/carpentersblocks/MixinPlayerPermissions.java deleted file mode 100644 index 39de8b9..0000000 --- a/src/main/java/xonin/backhand/mixins/late/carpentersblocks/MixinPlayerPermissions.java +++ /dev/null @@ -1,25 +0,0 @@ -package xonin.backhand.mixins.late.carpentersblocks; - -import net.minecraft.entity.player.EntityPlayer; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import com.carpentersblocks.util.protection.IProtected; -import com.carpentersblocks.util.protection.PlayerPermissions; - -import xonin.backhand.client.world.ClientFakePlayer; - -@Mixin(value = PlayerPermissions.class, remap = false) -public abstract class MixinPlayerPermissions { - - @Inject(method = "hasElevatedPermission", at = @At(value = "HEAD"), cancellable = true) - private static void backhand$fixFakePlayerNPE(IProtected object, EntityPlayer entityPlayer, - boolean enforceOwnership, CallbackInfoReturnable cir) { - if (entityPlayer instanceof ClientFakePlayer) { - cir.setReturnValue(true); - } - } -} diff --git a/src/main/java/xonin/backhand/mixins/late/etfuturum/MixinServerEventHandler.java b/src/main/java/xonin/backhand/mixins/late/etfuturum/MixinServerEventHandler.java new file mode 100644 index 0000000..753b308 --- /dev/null +++ b/src/main/java/xonin/backhand/mixins/late/etfuturum/MixinServerEventHandler.java @@ -0,0 +1,49 @@ +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 new file mode 100644 index 0000000..a7ceb30 --- /dev/null +++ b/src/main/java/xonin/backhand/mixins/late/tconstruct/MixinCrosshairHandler.java @@ -0,0 +1,34 @@ +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/packet/BackhandPacketHandler.java b/src/main/java/xonin/backhand/packet/BackhandPacketHandler.java index 28b422a..65ce08e 100644 --- a/src/main/java/xonin/backhand/packet/BackhandPacketHandler.java +++ b/src/main/java/xonin/backhand/packet/BackhandPacketHandler.java @@ -3,9 +3,11 @@ import java.util.Hashtable; import java.util.Map; +import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.world.WorldServer; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; @@ -14,7 +16,7 @@ import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.network.internal.FMLProxyPacket; import cpw.mods.fml.relauncher.Side; -import xonin.backhand.Backhand; +import cpw.mods.fml.relauncher.SideOnly; public final class BackhandPacketHandler { @@ -23,13 +25,10 @@ public final class BackhandPacketHandler { public BackhandPacketHandler() { map.put(OffhandSyncItemPacket.packetName, new OffhandSyncItemPacket()); - map.put(OffhandAnimationPacket.packetName, new OffhandAnimationPacket()); - map.put(OffhandPlaceBlockPacket.packetName, new OffhandPlaceBlockPacket()); - map.put(OffhandToServerPacket.packetName, new OffhandToServerPacket()); map.put(OffhandSwapPacket.packetName, new OffhandSwapPacket()); map.put(OffhandSwapClientPacket.packetName, new OffhandSwapClientPacket()); - map.put(OffhandAttackPacket.packetName, new OffhandAttackPacket()); map.put(OffhandConfigSyncPacket.packetName, new OffhandConfigSyncPacket()); + map.put(OffhandSyncOffhandUse.packetName, new OffhandSyncOffhandUse()); } public void register() { @@ -48,9 +47,10 @@ public void onServerPacket(FMLNetworkEvent.ServerCustomPacketEvent event) { } @SubscribeEvent + @SideOnly(Side.CLIENT) public void onClientPacket(FMLNetworkEvent.ClientCustomPacketEvent event) { map.get(event.packet.channel()) - .process(event.packet.payload(), Backhand.proxy.getClientPlayer()); + .process(event.packet.payload(), Minecraft.getMinecraft().thePlayer); } public void sendPacketToPlayer(FMLProxyPacket packet, EntityPlayerMP player) { @@ -84,4 +84,10 @@ public void sendPacketToAll(FMLProxyPacket packet) { .sendToAll(packet); } } + + public void sendPacketToAllTracking(Entity entity, FMLProxyPacket packet) { + if (!(entity.worldObj instanceof WorldServer world)) return; + world.getEntityTracker() + .func_151247_a(entity, packet); + } } diff --git a/src/main/java/xonin/backhand/packet/OffhandAnimationPacket.java b/src/main/java/xonin/backhand/packet/OffhandAnimationPacket.java deleted file mode 100644 index d71eff8..0000000 --- a/src/main/java/xonin/backhand/packet/OffhandAnimationPacket.java +++ /dev/null @@ -1,60 +0,0 @@ -package xonin.backhand.packet; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.world.WorldServer; - -import cpw.mods.fml.common.network.ByteBufUtils; -import io.netty.buffer.ByteBuf; -import xonin.backhand.api.core.IBackhandPlayer; -import xonin.backhand.utils.EnumAnimations; - -/** - * User: nerd-boy - * Date: 26/06/13 - * Time: 1:47 PM - */ -public final class OffhandAnimationPacket extends AbstractPacket { - - public static final String packetName = "MB2|Animation"; - private EnumAnimations animation; - private String username; - - public OffhandAnimationPacket(EnumAnimations animation, EntityPlayer user) { - this.animation = animation; - this.username = user.getCommandSenderName(); - } - - public OffhandAnimationPacket() {} - - @Override - public void process(ByteBuf in, EntityPlayer player) { - try { - animation = EnumAnimations.values()[in.readInt()]; - username = ByteBufUtils.readUTF8String(in); - } catch (Exception e) { - e.printStackTrace(); - return; - } - if (username != null && animation != null) { - EntityPlayer entity = player.worldObj.getPlayerEntityByName(username); - if (entity != null) { - if (entity.worldObj instanceof WorldServer) { - ((WorldServer) entity.worldObj).getEntityTracker() - .func_151247_a(entity, this.generatePacket()); - } - animation.processAnimation((IBackhandPlayer) entity); - } - } - } - - @Override - public String getChannel() { - return packetName; - } - - @Override - public void write(ByteBuf out) { - out.writeInt(animation.ordinal()); - ByteBufUtils.writeUTF8String(out, username); - } -} diff --git a/src/main/java/xonin/backhand/packet/OffhandAttackPacket.java b/src/main/java/xonin/backhand/packet/OffhandAttackPacket.java deleted file mode 100644 index be30c6c..0000000 --- a/src/main/java/xonin/backhand/packet/OffhandAttackPacket.java +++ /dev/null @@ -1,64 +0,0 @@ -package xonin.backhand.packet; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.item.EntityXPOrb; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.projectile.EntityArrow; - -import cpw.mods.fml.common.network.ByteBufUtils; -import io.netty.buffer.ByteBuf; -import xonin.backhand.Backhand; -import xonin.backhand.api.core.IBackhandPlayer; -import xonin.backhand.utils.BackhandConfig; -import xonin.backhand.utils.EnumAnimations; - -public class OffhandAttackPacket extends AbstractPacket { - - public static final String packetName = "MB2|Attack"; - private String user; - private int targetId; - - public OffhandAttackPacket(EntityPlayer player, Entity target) { - this.user = player.getCommandSenderName(); - this.targetId = target.getEntityId(); - } - - public OffhandAttackPacket() {} - - @Override - public String getChannel() { - return packetName; - } - - @Override - public void write(ByteBuf out) { - ByteBufUtils.writeUTF8String(out, user); - out.writeInt(targetId); - } - - @Override - public void process(ByteBuf inputStream, EntityPlayer sender) { - if (!BackhandConfig.OffhandAttack) { - return; - } - - this.user = ByteBufUtils.readUTF8String(inputStream); - this.targetId = inputStream.readInt(); - - EntityPlayer player = sender.worldObj.getPlayerEntityByName(user); - Entity target = sender.worldObj.getEntityByID(this.targetId); - if (player != null && target != null) { - if (target instanceof EntityItem || target instanceof EntityXPOrb - || target instanceof EntityArrow - || target == player) { - return; - } - ((IBackhandPlayer) player).attackTargetEntityWithCurrentOffItem(target); - Backhand.packetHandler.sendPacketAround( - player, - 120, - new OffhandAnimationPacket(EnumAnimations.OffHandSwing, player).generatePacket()); - } - } -} diff --git a/src/main/java/xonin/backhand/packet/OffhandConfigSyncPacket.java b/src/main/java/xonin/backhand/packet/OffhandConfigSyncPacket.java index ab4c84b..1250896 100644 --- a/src/main/java/xonin/backhand/packet/OffhandConfigSyncPacket.java +++ b/src/main/java/xonin/backhand/packet/OffhandConfigSyncPacket.java @@ -4,17 +4,11 @@ import net.minecraft.entity.player.EntityPlayer; import io.netty.buffer.ByteBuf; -import xonin.backhand.client.utils.BackhandClientUtils; import xonin.backhand.utils.BackhandConfig; public final class OffhandConfigSyncPacket extends AbstractPacket { public static final String packetName = "MB2|ConfigSync"; - private EntityPlayer player; - - public OffhandConfigSyncPacket(EntityPlayer player) { - this.player = player; - } public OffhandConfigSyncPacket() {} @@ -23,12 +17,6 @@ public void process(ByteBuf inputStream, EntityPlayer player) { BackhandConfig.OffhandAttack = inputStream.readBoolean(); BackhandConfig.EmptyOffhand = inputStream.readBoolean(); BackhandConfig.OffhandBreakBlocks = inputStream.readBoolean(); - BackhandConfig.UseOffhandArrows = inputStream.readBoolean(); - BackhandConfig.UseOffhandBow = inputStream.readBoolean(); - BackhandConfig.OffhandTickHotswap = inputStream.readBoolean(); - BackhandConfig.AlternateOffhandSlot = inputStream.readInt(); - BackhandConfig.UseInventorySlot = inputStream.readBoolean(); - BackhandClientUtils.receivedConfigs = true; } @Override @@ -41,10 +29,5 @@ public void write(ByteBuf out) { out.writeBoolean(BackhandConfig.OffhandAttack); out.writeBoolean(BackhandConfig.EmptyOffhand); out.writeBoolean(BackhandConfig.OffhandBreakBlocks); - out.writeBoolean(BackhandConfig.UseOffhandArrows); - out.writeBoolean(BackhandConfig.UseOffhandBow); - out.writeBoolean(BackhandConfig.OffhandTickHotswap); - out.writeInt(BackhandConfig.AlternateOffhandSlot); - out.writeBoolean(BackhandConfig.UseInventorySlot); } } diff --git a/src/main/java/xonin/backhand/packet/OffhandPlaceBlockPacket.java b/src/main/java/xonin/backhand/packet/OffhandPlaceBlockPacket.java deleted file mode 100644 index ccfe1a4..0000000 --- a/src/main/java/xonin/backhand/packet/OffhandPlaceBlockPacket.java +++ /dev/null @@ -1,207 +0,0 @@ -package xonin.backhand.packet; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.network.play.server.S02PacketChat; -import net.minecraft.network.play.server.S23PacketBlockChange; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; - -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.eventhandler.Event; -import cpw.mods.fml.common.network.ByteBufUtils; -import cpw.mods.fml.relauncher.Side; -import io.netty.buffer.ByteBuf; -import xonin.backhand.Backhand; -import xonin.backhand.HookContainerClass; -import xonin.backhand.api.PlayerEventChild; -import xonin.backhand.api.core.BackhandUtils; - -public final class OffhandPlaceBlockPacket extends AbstractPacket { - - public static final String packetName = "MB2|Place"; - private int xPosition; - private int yPosition; - private int zPosition; - /** The offset to use for block/item placement. */ - private int direction; - private ItemStack itemStack; - /** The offset from xPosition where the actual click took place */ - private float xOffset; - /** The offset from yPosition where the actual click took place */ - private float yOffset; - /** The offset from zPosition where the actual click took place */ - private float zOffset; - - public OffhandPlaceBlockPacket() {} - - public OffhandPlaceBlockPacket(int par1, int par2, int par3, int par4, ItemStack par5ItemStack, float par6, - float par7, float par8) { - this.xPosition = par1; - this.yPosition = par2; - this.zPosition = par3; - this.direction = par4; - this.itemStack = ItemStack.copyItemStack(par5ItemStack); - this.xOffset = par6; - this.yOffset = par7; - this.zOffset = par8; - } - - @Override - public String getChannel() { - return packetName; - } - - @Override - public void write(ByteBuf out) { - out.writeInt(this.xPosition); - out.writeByte(this.yPosition); - out.writeInt(this.zPosition); - out.writeByte(this.direction); - ByteBufUtils.writeItemStack(out, this.itemStack); - out.writeByte((int) (this.xOffset * 16.0F)); - out.writeByte((int) (this.yOffset * 16.0F)); - out.writeByte((int) (this.zOffset * 16.0F)); - } - - @Override - public void process(ByteBuf in, EntityPlayer player) { - try { - this.xPosition = in.readInt(); - this.yPosition = in.readUnsignedByte(); - this.zPosition = in.readInt(); - this.direction = in.readUnsignedByte(); - this.itemStack = ByteBufUtils.readItemStack(in); - this.xOffset = in.readUnsignedByte() / 16.0F; - this.yOffset = in.readUnsignedByte() / 16.0F; - this.zOffset = in.readUnsignedByte() / 16.0F; - } catch (Exception io) { - return; - } - if (!(player instanceof EntityPlayerMP playerMP)) return; - ItemStack offhandWeapon = BackhandUtils.getOffhandItem(playerMP); - if (offhandWeapon != null && !BackhandUtils.usagePriorAttack(offhandWeapon)) return; - boolean flag = true; - int i = xPosition; - int j = yPosition; - int k = zPosition; - int l = direction; - playerMP.func_143004_u(); - if (direction == 255) { - if (offhandWeapon == null) return; - PlayerInteractEvent event = new PlayerInteractEvent( - playerMP, - PlayerInteractEvent.Action.RIGHT_CLICK_AIR, - 0, - 0, - 0, - -1, - playerMP.getEntityWorld()); - MinecraftForge.EVENT_BUS.post(new PlayerEventChild.UseOffhandItemEvent(event, offhandWeapon)); - if (event.useItem != Event.Result.DENY) { - HookContainerClass.tryUseItem(playerMP, offhandWeapon, Side.SERVER); - } - flag = false; - } else { - MinecraftServer mcServer = FMLCommonHandler.instance() - .getMinecraftServerInstance(); - if (yPosition >= mcServer.getBuildLimit() - 1 - && (direction == 1 || yPosition >= mcServer.getBuildLimit())) { - ChatComponentTranslation chat = new ChatComponentTranslation("build.tooHigh", mcServer.getBuildLimit()); - chat.getChatStyle() - .setColor(EnumChatFormatting.RED); - playerMP.playerNetServerHandler.sendPacket(new S02PacketChat(chat)); - } else { - double dist = playerMP.theItemInWorldManager.getBlockReachDistance() + 1; - dist *= dist; - if (playerMP.getDistanceSq(i + 0.5D, j + 0.5D, k + 0.5D) < dist - && !mcServer.isBlockProtected(playerMP.getEntityWorld(), i, j, k, playerMP)) { - this.useItem(playerMP, offhandWeapon, i, j, k, l, xOffset, yOffset, zOffset); - } - } - } - if (flag) { - playerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(i, j, k, playerMP.getEntityWorld())); - if (l == 0) { - --j; - } - if (l == 1) { - ++j; - } - if (l == 2) { - --k; - } - if (l == 3) { - ++k; - } - if (l == 4) { - --i; - } - if (l == 5) { - ++i; - } - playerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(i, j, k, playerMP.getEntityWorld())); - } - offhandWeapon = BackhandUtils.getOffhandItem(playerMP); - if (offhandWeapon != null && HookContainerClass.isItemBlock(offhandWeapon.getItem())) { - if (offhandWeapon.stackSize <= 0) { - BackhandUtils.setPlayerOffhandItem(playerMP, null); - offhandWeapon = null; - } - if (offhandWeapon == null || offhandWeapon.getMaxItemUseDuration() == 0) { - playerMP.isChangingQuantityOnly = true; - BackhandUtils - .setPlayerOffhandItem(playerMP, ItemStack.copyItemStack(BackhandUtils.getOffhandItem(playerMP))); - playerMP.openContainer.detectAndSendChanges(); - playerMP.isChangingQuantityOnly = false; - } - } - - if (!ItemStack.areItemStacksEqual(itemStack, offhandWeapon)) { - Backhand.packetHandler.sendPacketToPlayer(new OffhandSyncItemPacket(playerMP).generatePacket(), playerMP); - } - } - - public boolean useItem(EntityPlayerMP playerMP, ItemStack itemStack, int x, int y, int z, int side, float xOffset, - float yOffset, float zOffset) { - World theWorld = playerMP.getEntityWorld(); - if (itemStack != null) { - final int meta = itemStack.getItemDamage(); - if (itemStack.getItem() - .onItemUseFirst(itemStack, playerMP, theWorld, x, y, z, side, xOffset, yOffset, zOffset)) { - if (itemStack.stackSize <= 0) { - ForgeEventFactory.onPlayerDestroyItem(playerMP, itemStack); - BackhandUtils.setPlayerOffhandItem(playerMP, null); - } else if (itemStack.getItemDamage() != meta) { - BackhandUtils.setPlayerOffhandItem(playerMP, BackhandUtils.getOffhandItem(playerMP)); - } - return true; - } - } - - boolean result = false; - if (itemStack != null) { - final int meta = itemStack.getItemDamage(); - final int size = itemStack.stackSize; - result = itemStack.tryPlaceItemIntoWorld(playerMP, theWorld, x, y, z, side, xOffset, yOffset, zOffset); - if (playerMP.theItemInWorldManager.isCreative()) { - itemStack.setItemDamage(meta); - itemStack.stackSize = size; - } - if (itemStack.stackSize <= 0) { - ForgeEventFactory.onPlayerDestroyItem(playerMP, itemStack); - BackhandUtils.setPlayerOffhandItem(playerMP, null); - } else if (itemStack.getItemDamage() != meta) { - BackhandUtils.setPlayerOffhandItem(playerMP, itemStack); - } - } - return result; - } - -} diff --git a/src/main/java/xonin/backhand/packet/OffhandSwapClientPacket.java b/src/main/java/xonin/backhand/packet/OffhandSwapClientPacket.java index 700652a..04cb8eb 100644 --- a/src/main/java/xonin/backhand/packet/OffhandSwapClientPacket.java +++ b/src/main/java/xonin/backhand/packet/OffhandSwapClientPacket.java @@ -6,8 +6,8 @@ import cpw.mods.fml.common.network.ByteBufUtils; import io.netty.buffer.ByteBuf; import xonin.backhand.api.core.BackhandUtils; -import xonin.backhand.api.core.InventoryPlayerBackhand; -import xonin.backhand.client.ClientTickHandler; +import xonin.backhand.api.core.IOffhandInventory; +import xonin.backhand.client.ClientEventHandler; /** * User: nerd-boy @@ -33,10 +33,10 @@ public void process(ByteBuf inputStream, EntityPlayer player) { this.player = player.worldObj.getPlayerEntityByName(user); if (this.player != null) { int slot = inputStream.readInt(); - if (InventoryPlayerBackhand.isValidSwitch(slot)) this.player.inventory.currentItem = slot; + if (IOffhandInventory.isValidSwitch(slot, this.player)) this.player.inventory.currentItem = slot; BackhandUtils.swapOffhandItem(player); } - ClientTickHandler.allowSwap = true; + ClientEventHandler.allowSwap = true; } @Override diff --git a/src/main/java/xonin/backhand/packet/OffhandSwapPacket.java b/src/main/java/xonin/backhand/packet/OffhandSwapPacket.java index 1021566..acaba55 100644 --- a/src/main/java/xonin/backhand/packet/OffhandSwapPacket.java +++ b/src/main/java/xonin/backhand/packet/OffhandSwapPacket.java @@ -43,7 +43,7 @@ public void process(ByteBuf inputStream, EntityPlayer player) { || Backhand.isOffhandBlacklisted(offhandItem)) return; BackhandUtils.setPlayerOffhandItem(this.player, this.player.getCurrentEquippedItem()); - BackhandUtils.setPlayerCurrentItem(this.player, offhandItem); + player.setCurrentItemOrArmor(0, offhandItem); Backhand.packetHandler .sendPacketToPlayer(new OffhandSwapClientPacket(this.player).generatePacket(), (EntityPlayerMP) player); } diff --git a/src/main/java/xonin/backhand/packet/OffhandSyncOffhandUse.java b/src/main/java/xonin/backhand/packet/OffhandSyncOffhandUse.java new file mode 100644 index 0000000..37c1734 --- /dev/null +++ b/src/main/java/xonin/backhand/packet/OffhandSyncOffhandUse.java @@ -0,0 +1,39 @@ +package xonin.backhand.packet; + +import net.minecraft.entity.player.EntityPlayer; + +import cpw.mods.fml.common.network.ByteBufUtils; +import io.netty.buffer.ByteBuf; +import xonin.backhand.api.core.IBackhandPlayer; + +public final class OffhandSyncOffhandUse extends AbstractPacket { + + public static final String packetName = "SyncItemUsage"; + private boolean isUsingOffhand; + private EntityPlayer player; + + public OffhandSyncOffhandUse(EntityPlayer player, boolean isUsingOffhand) { + this.player = player; + this.isUsingOffhand = isUsingOffhand; + } + + public OffhandSyncOffhandUse() {} + + @Override + public void process(ByteBuf inputStream, EntityPlayer player) { + this.player = player.worldObj.getPlayerEntityByName(ByteBufUtils.readUTF8String(inputStream)); + if (this.player == null) return; + ((IBackhandPlayer) this.player).setOffhandItemInUse(inputStream.readBoolean()); + } + + @Override + public String getChannel() { + return packetName; + } + + @Override + public void write(ByteBuf out) { + ByteBufUtils.writeUTF8String(out, player.getCommandSenderName()); + out.writeBoolean(isUsingOffhand); + } +} diff --git a/src/main/java/xonin/backhand/packet/OffhandToServerPacket.java b/src/main/java/xonin/backhand/packet/OffhandToServerPacket.java deleted file mode 100644 index e8314ee..0000000 --- a/src/main/java/xonin/backhand/packet/OffhandToServerPacket.java +++ /dev/null @@ -1,46 +0,0 @@ -package xonin.backhand.packet; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; - -import cpw.mods.fml.common.network.ByteBufUtils; -import io.netty.buffer.ByteBuf; -import xonin.backhand.api.core.BackhandUtils; - -public class OffhandToServerPacket extends AbstractPacket { - - public static final String packetName = "MB2|OffhandToServer"; - - private ItemStack offhandItem; - private String user; - EntityPlayer player; - - public OffhandToServerPacket(ItemStack offhandItem, EntityPlayer player) { - this.offhandItem = offhandItem; - this.player = player; - this.user = player.getCommandSenderName(); - } - - public OffhandToServerPacket() {} - - @Override - public String getChannel() { - return packetName; - } - - @Override - public void write(ByteBuf out) { - ByteBufUtils.writeUTF8String(out, player.getCommandSenderName()); - ByteBufUtils.writeItemStack(out, offhandItem); - } - - @Override - public void process(ByteBuf inputStream, EntityPlayer player) { - this.user = ByteBufUtils.readUTF8String(inputStream); - this.player = player.worldObj.getPlayerEntityByName(user); - if (this.player != null) { - ItemStack offhandItem = ByteBufUtils.readItemStack(inputStream); - BackhandUtils.setPlayerOffhandItem(this.player, offhandItem); - } - } -} diff --git a/src/main/java/xonin/backhand/utils/BackhandConfig.java b/src/main/java/xonin/backhand/utils/BackhandConfig.java index 0c3cee1..d503d98 100644 --- a/src/main/java/xonin/backhand/utils/BackhandConfig.java +++ b/src/main/java/xonin/backhand/utils/BackhandConfig.java @@ -20,29 +20,6 @@ public class BackhandConfig { @Config.DefaultBoolean(false) public static boolean OffhandBreakBlocks; - @Config.Comment("If enabled, arrows in the offhand will be used first when shooting a bow. Compatible with Et-Futurum's tipped arrows! True in vanilla.") - @Config.DefaultBoolean(true) - public static boolean UseOffhandArrows; - - @Config.Comment("If enabled, bows can be used in the offhand. True in vanilla.") - @Config.DefaultBoolean(true) - public static boolean UseOffhandBow; - - @Config.Comment("If the main offhand inventory can't be used, this slot in the main inventory will be used as the offhand instead. Slot 9 by default.") - @Config.DefaultInt(9) - public static int AlternateOffhandSlot; - - @Config.Comment("If enabled, the alternate offhand slot configured above will always be used for the offhand. False by default.") - @Config.DefaultBoolean(false) - public static boolean UseInventorySlot; - - @Config.Comment(""" - If enabled, a hotswap will be performed every tick if the main hand has no use or is empty. - This hotswap allows for many more items like fishing rods to be used in the offhand, but may be unstable. - """) - @Config.DefaultBoolean(false) - public static boolean OffhandTickHotswap; - @Config.Comment(""" These items will be unable to be swapped into the offhand. Formatting of an item should be: modid:itemname diff --git a/src/main/java/xonin/backhand/utils/EnumAnimations.java b/src/main/java/xonin/backhand/utils/EnumAnimations.java deleted file mode 100644 index 336f52e..0000000 --- a/src/main/java/xonin/backhand/utils/EnumAnimations.java +++ /dev/null @@ -1,17 +0,0 @@ -package xonin.backhand.utils; - -import xonin.backhand.api.core.IBackhandPlayer; - -public enum EnumAnimations { - - OffHandSwing { - - @Override - public void processAnimation(IBackhandPlayer entity) { - entity.swingOffItem(); - } - }; - - public abstract void processAnimation(IBackhandPlayer entity); - -} diff --git a/src/main/java/xonin/backhand/utils/Mods.java b/src/main/java/xonin/backhand/utils/Mods.java new file mode 100644 index 0000000..60b62d1 --- /dev/null +++ b/src/main/java/xonin/backhand/utils/Mods.java @@ -0,0 +1,24 @@ +package xonin.backhand.utils; + +import cpw.mods.fml.common.Loader; + +public enum Mods { + + INV_TWEAKS("inventorytweaks"), + DOUBLE_WIDE_SURPRISE("dws"), + TINKERS_CONSTRUCT("TConstruct"),; + + private final String modId; + private Boolean loaded; + + Mods(String modId) { + this.modId = modId; + } + + public boolean isLoaded() { + if (loaded == null) { + loaded = Loader.isModLoaded(modId); + } + return loaded; + } +} diff --git a/src/main/resources/META-INF/backhand_at.cfg b/src/main/resources/META-INF/backhand_at.cfg index 1ac515b..f74a6bf 100644 --- a/src/main/resources/META-INF/backhand_at.cfg +++ b/src/main/resources/META-INF/backhand_at.cfg @@ -1,52 +1,9 @@ -public net.minecraft.client.Minecraft.func_152340_a(Ljava/io/InputStream;)Ljava/nio/ByteBuffer -public net.minecraft.client.renderer.entity.RenderPlayer func_77029_c(Lnet/minecraft/client/entity/AbstractClientPlayer;F)V -#EntityArrow -public net.minecraft.entity.projectile.EntityArrow field_145791_d #xTile -public net.minecraft.entity.projectile.EntityArrow field_145792_e #yTile -public net.minecraft.entity.projectile.EntityArrow field_145789_f #zTile -public net.minecraft.client.renderer.ItemRenderer * #therearewaytoomanyfieldstomanuallyATthemall -public net.minecraft.client.gui.GuiIngame field_73841_b #itemRenderer -public net.minecraft.entity.projectile.EntityArrow field_70252_j #ticksInGround -#EntityLivingBase public net.minecraft.entity.EntityLivingBase func_82166_i()I #getArmSwingAnimationEnd -public net.minecraft.client.Minecraft func_147121_ag()V #rightClickMouse -#NetHandlerPlayServer -public net.minecraft.network.NetHandlerPlayServer field_147380_r #hasMoved -public net.minecraft.network.NetHandlerPlayServer field_147367_d #serverController -public net.minecraft.network.NetHandlerPlayServer field_147375_m #itemDropThreshold -#Client side -#GuiContainerCreative -public net.minecraft.client.gui.inventory.GuiContainerCreative func_147053_i()V # -public net.minecraft.client.gui.inventory.GuiContainerCreative func_147050_b(Lnet/minecraft/creativetab/CreativeTabs;)V # -public net.minecraft.client.gui.inventory.GuiContainerCreative field_147058_w # selectedTabIndex -public net.minecraft.client.gui.inventory.GuiContainerCreative * # -public net.minecraft.client.gui.inventory.GuiContainer field_147008_s # -#RendererLivingEntity -public net.minecraft.client.renderer.entity.RendererLivingEntity field_77045_g #mainModel -#PlayerControllerMP public net.minecraft.client.multiplayer.PlayerControllerMP func_78750_j()V #syncCurrentPlayItem -public net.minecraft.client.multiplayer.PlayerControllerMP * #therearewaytoomanyfieldstomanuallyATthemall -#Minecraft -public net.minecraft.client.Minecraft field_71467_ac #rightClickDelayTimer -public net.minecraft.client.Minecraft field_71429_W #leftClickCounter -public net.minecraft.client.Minecraft func_147112_ai()V #middle click -#NetHandlerPlayClient -public net.minecraft.client.network.NetHandlerPlayClient field_147299_f # gameController -#Item -public net.minecraft.item.Item field_77791_bV # itemIcon -#Render -public net.minecraft.client.renderer.entity.Render field_76990_c #renderManager -# SpecialSource needs to update to handle these. -public net.minecraft.client.gui.inventory.GuiContainerCreative$ContainerCreative -public net.minecraft.client.gui.inventory.GuiContainerCreative$CreativeSlot -public net.minecraft.client.gui.inventory.GuiContainerCreative$CreativeSlot field_148332_b # theSlot -public net.minecraft.client.settings.KeyBinding field_74512_d # keyCode public net.minecraft.client.gui.inventory.GuiContainer field_147003_i # guiLeft (1.6 field_74198_m) public net.minecraft.client.gui.inventory.GuiContainer field_147009_r # guiTop (1.6 field_74197_n) -public net.minecraft.client.gui.inventory.GuiContainer field_146999_f # xSize (1.6 field_74194_b) -public net.minecraft.client.gui.inventory.GuiContainer field_147000_g # ySize (1.6 field_74195_c) -public net.minecraft.client.gui.GuiScreen field_146292_n # buttonList (1.6 field_73887_h) -# S2FPacketSetSlot -public net.minecraft.network.play.server.S2FPacketSetSlot field_149179_a # field_149179_a / windowId -public net.minecraft.network.play.server.S2FPacketSetSlot field_149177_b # field_149177_b / slot -public net.minecraft.network.play.server.S2FPacketSetSlot field_149178_c # field_149178_c / itemStack +public net.minecraft.client.renderer.ItemRenderer field_78453_b # itemToRender +public net.minecraft.client.renderer.ItemRenderer field_78454_c # equippedProgress +public net.minecraft.client.renderer.ItemRenderer field_78451_d # prevEquippedProgress +public net.minecraft.client.gui.inventory.GuiContainerCreative$ContainerCreative +public net.minecraft.client.gui.inventory.GuiContainerCreative$CreativeSlot