From 4641bfc701415c80edb3b74bba5dbbdd1dbdb6d0 Mon Sep 17 00:00:00 2001 From: mezz Date: Sun, 30 Jul 2017 18:03:53 -0700 Subject: [PATCH] Allow the server to handle item-block interaction if onItemUse does not return PASS (#3951) --- .../multiplayer/PlayerControllerMP.java.patch | 19 ++-- .../debug/OnItemUseFirstTest.java | 100 ++++++++++++++++++ .../models/item/test_item.json | 6 ++ 3 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 src/test/java/net/minecraftforge/debug/OnItemUseFirstTest.java create mode 100644 src/test/resources/assets/onitemusefirsttest/models/item/test_item.json diff --git a/patches/minecraft/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch index b3c2fccec9..3cee96bc5b 100644 --- a/patches/minecraft/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch +++ b/patches/minecraft/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch @@ -103,7 +103,7 @@ } return p_178893_1_.equals(this.field_178895_c) && flag; -@@ -373,13 +384,29 @@ +@@ -373,13 +384,34 @@ } else { @@ -120,7 +120,12 @@ if (this.field_78779_k != GameType.SPECTATOR) { + EnumActionResult ret = itemstack.onItemUseFirst(p_187099_1_, p_187099_2_, p_187099_3_, p_187099_6_, p_187099_4_, f, f1, f2); -+ if (ret != EnumActionResult.PASS) return ret; ++ if (ret != EnumActionResult.PASS) ++ { ++ // The server needs to process the item use as well. Otherwise onItemUseFirst won't ever be called on the server without causing weird bugs ++ this.field_78774_b.func_147297_a(new CPacketPlayerTryUseItemOnBlock(p_187099_3_, p_187099_4_, p_187099_6_, f, f1, f2)); ++ return ret; ++ } + IBlockState iblockstate = p_187099_2_.func_180495_p(p_187099_3_); + boolean bypass = itemstack.func_190926_b() || itemstack.func_77973_b().doesSneakBypassUse(itemstack, p_187099_2_, p_187099_3_, p_187099_1_); @@ -135,7 +140,7 @@ } if (!flag && itemstack.func_77973_b() instanceof ItemBlock) -@@ -395,7 +422,7 @@ +@@ -395,7 +427,7 @@ this.field_78774_b.func_147297_a(new CPacketPlayerTryUseItemOnBlock(p_187099_3_, p_187099_4_, p_187099_6_, f, f1, f2)); @@ -144,7 +149,7 @@ { if (itemstack.func_190926_b()) { -@@ -421,14 +448,20 @@ +@@ -421,14 +453,20 @@ { int i = itemstack.func_77960_j(); int j = itemstack.func_190916_E(); @@ -166,7 +171,7 @@ } } } -@@ -457,6 +490,8 @@ +@@ -457,6 +495,8 @@ } else { @@ -175,7 +180,7 @@ int i = itemstack.func_190916_E(); ActionResult actionresult = itemstack.func_77957_a(p_187101_2_, p_187101_1_, p_187101_3_); ItemStack itemstack1 = (ItemStack)actionresult.func_188398_b(); -@@ -464,6 +499,10 @@ +@@ -464,6 +504,10 @@ if (itemstack1 != itemstack || itemstack1.func_190916_E() != i) { p_187101_1_.func_184611_a(p_187101_3_, itemstack1); @@ -186,7 +191,7 @@ } return actionresult.func_188397_a(); -@@ -500,6 +539,9 @@ +@@ -500,6 +544,9 @@ this.func_78750_j(); Vec3d vec3d = new Vec3d(p_187102_3_.field_72307_f.field_72450_a - p_187102_2_.field_70165_t, p_187102_3_.field_72307_f.field_72448_b - p_187102_2_.field_70163_u, p_187102_3_.field_72307_f.field_72449_c - p_187102_2_.field_70161_v); this.field_78774_b.func_147297_a(new CPacketUseEntity(p_187102_2_, p_187102_4_, vec3d)); diff --git a/src/test/java/net/minecraftforge/debug/OnItemUseFirstTest.java b/src/test/java/net/minecraftforge/debug/OnItemUseFirstTest.java new file mode 100644 index 0000000000..ec76cc8b58 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/OnItemUseFirstTest.java @@ -0,0 +1,100 @@ +package net.minecraftforge.debug; + +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.SidedProxy; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import javax.annotation.Nonnull; + +@Mod(modid = OnItemUseFirstTest.MODID, name = "OnItemUseFirstTest", version = "0.0.0", acceptableRemoteVersions = "*") +@Mod.EventBusSubscriber +public class OnItemUseFirstTest +{ + public static final boolean ENABLE = true; + public static final String MODID = "onitemusefirsttest"; + @SidedProxy + public static CommonProxy proxy = null; + + public static abstract class CommonProxy + { + public void registerItem(RegistryEvent.Register event) + { + ItemTest.instance = new ItemTest().setCreativeTab(CreativeTabs.MISC); + event.getRegistry().register(ItemTest.instance); + } + } + + public static final class ServerProxy extends CommonProxy + { + } + + public static final class ClientProxy extends CommonProxy + { + @Override + public void registerItem(RegistryEvent.Register event) + { + super.registerItem(event); + for (int i = 0; i < EnumActionResult.values().length; i++) + { + ModelLoader.setCustomModelResourceLocation(ItemTest.instance, i, new ModelResourceLocation(new ResourceLocation(MODID, "test_item"), "inventory")); + } + } + } + + @SubscribeEvent + public static void registerItem(RegistryEvent.Register event) + { + if (ENABLE) + { + proxy.registerItem(event); + } + } + + public static class ItemTest extends Item + { + static Item instance; + public ItemTest() + { + setRegistryName(MODID, "test_item"); + setHasSubtypes(true); + } + @Nonnull + @Override + public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) + { + ItemStack stack = player.getHeldItem(hand); + EnumActionResult ret = EnumActionResult.values()[stack.getMetadata()]; + player.sendMessage(new TextComponentString("Called onItemUseFirst in thread " + Thread.currentThread().getName() + ", returns " + ret + " in hand " + hand.name())); + return ret; + } + + @Override + public void getSubItems(@Nonnull Item itemIn, CreativeTabs tab, NonNullList subItems) + { + subItems.add(new ItemStack(itemIn, 1, 0)); + subItems.add(new ItemStack(itemIn, 1, 1)); + } + + @Override + public String getItemStackDisplayName(ItemStack stack) + { + return "OnItemUseFirst Returns: " + EnumActionResult.values()[stack.getMetadata()]; + } + } +} + diff --git a/src/test/resources/assets/onitemusefirsttest/models/item/test_item.json b/src/test/resources/assets/onitemusefirsttest/models/item/test_item.json new file mode 100644 index 0000000000..900fa81498 --- /dev/null +++ b/src/test/resources/assets/onitemusefirsttest/models/item/test_item.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "items/shulker_shell" + } +}