From c6c07fe5240d7ae13e68580d52f6cd287501b764 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Fri, 29 Sep 2017 18:11:26 +0200 Subject: [PATCH 1/3] Backport of the fix for equipment slot actions. See commit 8066412830c5b7aeeb3bd46673ca37f2945e0d7b and f3490663efb7e7e376d225f083176cbdfb414590. --- .../scala/li/cil/oc/server/agent/Player.scala | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/agent/Player.scala b/src/main/scala/li/cil/oc/server/agent/Player.scala index 1f56985f7..13dabd689 100644 --- a/src/main/scala/li/cil/oc/server/agent/Player.scala +++ b/src/main/scala/li/cil/oc/server/agent/Player.scala @@ -23,6 +23,7 @@ import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer.SleepResult import net.minecraft.init.Blocks import net.minecraft.init.Items +import net.minecraft.inventory.EntityEquipmentSlot import net.minecraft.inventory.IInventory import net.minecraft.item.ItemBlock import net.minecraft.item.ItemStack @@ -218,9 +219,28 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc }) } + private var offHand: (IInventory, Int) = _ + + override def setItemStackToSlot(slotIn: EntityEquipmentSlot, stack: ItemStack): Unit = { + if (slotIn == EntityEquipmentSlot.MAINHAND) { + agent.equipmentInventory.setInventorySlotContents(0, stack) + } else if(slotIn == EntityEquipmentSlot.OFFHAND && offHand != null) { + offHand._1.setInventorySlotContents(offHand._2, stack) + } + super.setItemStackToSlot(slotIn, stack) + } + + override def getItemStackFromSlot(slotIn: EntityEquipmentSlot): ItemStack = { + if (slotIn == EntityEquipmentSlot.MAINHAND) + agent.equipmentInventory.getStackInSlot(0) + else if(slotIn == EntityEquipmentSlot.OFFHAND && offHand != null) + offHand._1.getStackInSlot(offHand._2) + else super.getItemStackFromSlot(slotIn) + } + def fireRightClickBlock(pos: BlockPos, side: EnumFacing): PlayerInteractEvent.RightClickBlock = { val hitVec = new Vec3d(0.5 + side.getDirectionVec.getX * 0.5, 0.5 + side.getDirectionVec.getY * 0.5, 0.5 + side.getDirectionVec.getZ * 0.5) - val event = new PlayerInteractEvent.RightClickBlock(this, EnumHand.MAIN_HAND, getHeldItemMainhand, pos, side, hitVec) + val event = new PlayerInteractEvent.RightClickBlock(this, EnumHand.OFF_HAND, getHeldItemMainhand, pos, side, hitVec) MinecraftForge.EVENT_BUS.post(event) event } @@ -434,6 +454,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc val stack = inventory.getStackInSlot(slot) val oldStack = if (stack != null) stack.copy() else null this.inventory.currentItem = if (inventory == agent.mainInventory) slot else ~slot + this.offHand = (inventory, slot) try { f(stack) } @@ -449,6 +470,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc else ForgeEventFactory.onPlayerDestroyItem(this, newStack, EnumHand.MAIN_HAND) } } + this.offHand = null collectDroppedItems(itemsBefore) } } @@ -472,7 +494,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc else { val fakeEyeHeight = if (rotationPitch < 0 && isSomeKindOfPiston(stack)) 1.82 else 0 setPosition(posX, posY - fakeEyeHeight, posZ) - val didPlace = stack.onItemUse(this, world, pos, EnumHand.MAIN_HAND, side, hitX, hitY, hitZ) + val didPlace = stack.onItemUse(this, world, pos, EnumHand.OFF_HAND, side, hitX, hitY, hitZ) setPosition(posX, posY + fakeEyeHeight, posZ) if (didPlace == EnumActionResult.SUCCESS) { MinecraftForge.EVENT_BUS.post(new RobotPlaceBlockEvent.Post(agent, stack, world, pos)) From 3c24a69d9685443cc3f2ab1d0e0e81cb31a4f9d8 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Fri, 29 Sep 2017 20:29:14 +0200 Subject: [PATCH 2/3] Fixed exception thrown when other code tries setting the equipment slot stack. --- src/main/scala/li/cil/oc/server/agent/Player.scala | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/scala/li/cil/oc/server/agent/Player.scala b/src/main/scala/li/cil/oc/server/agent/Player.scala index 13dabd689..5569adde8 100644 --- a/src/main/scala/li/cil/oc/server/agent/Player.scala +++ b/src/main/scala/li/cil/oc/server/agent/Player.scala @@ -222,12 +222,22 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc private var offHand: (IInventory, Int) = _ override def setItemStackToSlot(slotIn: EntityEquipmentSlot, stack: ItemStack): Unit = { + var superCall: () => Unit = () => super.setItemStackToSlot(slotIn, stack) if (slotIn == EntityEquipmentSlot.MAINHAND) { agent.equipmentInventory.setInventorySlotContents(0, stack) + superCall = () => { + val slot = inventory.currentItem + // So, if we're not in the main inventory, currentItem is set to -1 + // for compatibility with mods that try accessing the inv directly + // using inventory.currentItem. See li.cil.oc.server.agent.Inventory + if(inventory.currentItem < 0) inventory.currentItem = ~inventory.currentItem + super.setItemStackToSlot(slotIn, stack) + inventory.currentItem = slot + } } else if(slotIn == EntityEquipmentSlot.OFFHAND && offHand != null) { offHand._1.setInventorySlotContents(offHand._2, stack) } - super.setItemStackToSlot(slotIn, stack) + superCall() } override def getItemStackFromSlot(slotIn: EntityEquipmentSlot): ItemStack = { From d09a4a3ff4b6b04fc623ff5a424b7edc9ef44cab Mon Sep 17 00:00:00 2001 From: Vexatos Date: Tue, 3 Oct 2017 19:05:30 +0200 Subject: [PATCH 3/3] Fix yet another silly error related to null ItemStacks. --- .../li/cil/oc/common/inventory/ItemStackInventory.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala b/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala index 626afc3f1..1c04f22fd 100644 --- a/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala @@ -12,8 +12,11 @@ trait ItemStackInventory extends Inventory { override def items = inventory // Initialize the list automatically if we have a container. - if (!container.isEmpty) { - reinitialize() + { + val _container = container + if (_container != null && !_container.isEmpty) { + reinitialize() + } } // Load items from tag.