mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-16 10:51:55 -04:00
add a AgentContainer to improve item use detection
This new AgentContainer provides slots for all agent inventory items so that proper change detection can occur for using items properly closes #2327
This commit is contained in:
parent
4ff26e91a0
commit
89c8885624
43
src/main/scala/li/cil/oc/server/agent/AgentContainer.scala
Normal file
43
src/main/scala/li/cil/oc/server/agent/AgentContainer.scala
Normal file
@ -0,0 +1,43 @@
|
||||
package li.cil.oc.server.agent
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.{Container, IContainerListener, IInventory, Slot}
|
||||
import li.cil.oc.server.agent
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.NonNullList
|
||||
|
||||
class AgentContainer(player: agent.Player) extends Container {
|
||||
{
|
||||
for (slot <- 0 until player.agent.equipmentInventory.getSizeInventory) {
|
||||
this.addSlotToContainer(new Slot(player.inventory, -1 - slot, 0, 0))
|
||||
}
|
||||
for (slot <- 0 until player.agent.mainInventory.getSizeInventory) {
|
||||
this.addSlotToContainer(new Slot(player.inventory, slot, 0, 0))
|
||||
}
|
||||
|
||||
this.addListener(new IContainerListener {
|
||||
override def sendAllContents(containerToSend: Container, itemsList: NonNullList[ItemStack]): Unit = {}
|
||||
|
||||
override def sendWindowProperty(containerIn: Container, varToUpdate: Int, newValue: Int): Unit = {}
|
||||
|
||||
override def sendAllWindowProperties(containerIn: Container, inventory: IInventory): Unit = {}
|
||||
|
||||
override def sendSlotContents(containerToSend: Container, index: Int, stack: ItemStack): Unit = {
|
||||
// an action has updated the agent.inventory via slots
|
||||
// thus the player.inventory is outdated in this regard
|
||||
val relativeIndex: Int = containerToSend.inventorySlots.get(index).getSlotIndex
|
||||
|
||||
if (relativeIndex < 0) {
|
||||
if (~relativeIndex < player.inventory.armorInventory.size) {
|
||||
player.inventory.armorInventory.set(~relativeIndex, stack)
|
||||
}
|
||||
}
|
||||
else if (relativeIndex < player.inventory.mainInventory.size) {
|
||||
player.inventory.mainInventory.set(relativeIndex, stack)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override def canInteractWith(player: EntityPlayer): Boolean = true
|
||||
}
|
@ -43,17 +43,6 @@ class Inventory(playerEntity: EntityPlayer, val agent: internal.Agent) extends I
|
||||
}
|
||||
}
|
||||
|
||||
// override def consumeInventoryItem(item: Item): Boolean = {
|
||||
// for ((slot, stack) <- inventorySlots.map(slot => (slot, getStackInSlot(slot))) if !stack.isEmpty && stack.getItem == item && stack.stackSize > 0) {
|
||||
// stack.stackSize -= 1
|
||||
// if (stack.stackSize <= 0) {
|
||||
// setInventorySlotContents(slot, ItemStack.EMPTY)
|
||||
// }
|
||||
// return true
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
|
||||
override def addItemStackToInventory(stack: ItemStack): Boolean = {
|
||||
val slots = this.indices.drop(agent.selectedSlot) ++ this.indices.take(agent.selectedSlot)
|
||||
InventoryUtils.insertIntoInventory(stack, InventoryUtils.asItemHandler(this), slots = Option(slots))
|
||||
@ -67,7 +56,7 @@ class Inventory(playerEntity: EntityPlayer, val agent: internal.Agent) extends I
|
||||
|
||||
override def readFromNBT(nbt: NBTTagList) {}
|
||||
|
||||
override def armorItemInSlot(slot: Int) = ItemStack.EMPTY
|
||||
override def armorItemInSlot(slot: Int): ItemStack = ItemStack.EMPTY
|
||||
|
||||
override def damageArmor(damage: Float) {}
|
||||
|
||||
|
@ -145,7 +145,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
this.inventory = new Inventory(this, agent)
|
||||
this.inventory.player = this
|
||||
// because the inventory was just overwritten, the container is now detached
|
||||
this.inventoryContainer = new ContainerPlayer(this.inventory, !world.isRemote, this)
|
||||
this.inventoryContainer = new AgentContainer(this)
|
||||
this.openContainer = this.inventoryContainer
|
||||
|
||||
def setItemHandler(fieldName: String, handler: IItemHandler): Unit = {
|
||||
@ -158,29 +158,6 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
setItemHandler("playerMainHandler", new PlayerMainInvWrapper(inventory))
|
||||
setItemHandler("playerEquipmentHandler", new CombinedInvWrapper(new PlayerArmorInvWrapper(inventory), new PlayerOffhandInvWrapper(inventory)))
|
||||
setItemHandler("playerJoinedHandler", new PlayerInvWrapper(inventory))
|
||||
|
||||
this.inventoryContainer.addListener(new IContainerListener{
|
||||
override def sendAllContents(containerToSend: Container, itemsList: NonNullList[ItemStack]): Unit = {}
|
||||
override def sendWindowProperty(containerIn: Container, varToUpdate: Int, newValue: Int): Unit = {}
|
||||
override def sendAllWindowProperties(containerIn: Container, inventory: IInventory): Unit = {}
|
||||
override def sendSlotContents(containerToSend: Container, index: Int, stack: ItemStack): Unit = {
|
||||
// an action has updated the agent.inventory via slots
|
||||
// thus the player.inventory is outdated in this regard
|
||||
var relativeIndex: Int = containerToSend.inventorySlots.get(index).getSlotIndex
|
||||
def tryInv(inv: NonNullList[ItemStack]): Boolean = {
|
||||
if (relativeIndex >= 0 && relativeIndex < inv.size) {
|
||||
inv.set(relativeIndex, stack)
|
||||
true
|
||||
} else {
|
||||
relativeIndex -= inv.size
|
||||
false
|
||||
}
|
||||
}
|
||||
if (!tryInv(Player.this.inventory.mainInventory))
|
||||
if (!tryInv(Player.this.inventory.armorInventory))
|
||||
tryInv(Player.this.inventory.offHandInventory)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var facing, side = EnumFacing.SOUTH
|
||||
@ -279,7 +256,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
ActivationType.BlockActivated
|
||||
else if (duration <= Double.MinPositiveValue && isItemUseAllowed(stack) && tryPlaceBlockWhileHandlingFunnySpecialCases(stack, pos, side, hitX, hitY, hitZ))
|
||||
ActivationType.ItemPlaced
|
||||
else if (useEquippedItem(duration))
|
||||
else if (useEquippedItem(duration, Option(stack)))
|
||||
ActivationType.ItemUsed
|
||||
else
|
||||
ActivationType.None
|
||||
@ -355,54 +332,59 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
}
|
||||
}
|
||||
|
||||
def useEquippedItem(duration: Double): Boolean = {
|
||||
callUsingItemInSlot(agent.equipmentInventory, 0, stack => {
|
||||
if (shouldCancel(() => fireRightClickAir())) {
|
||||
def useEquippedItem(duration: Double, stackOption: Option[ItemStack] = None): Boolean = {
|
||||
if (stackOption.isEmpty) {
|
||||
return callUsingItemInSlot(agent.equipmentInventory, 0, {
|
||||
case item: ItemStack if item != null => useEquippedItem(duration, Option(item))
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
|
||||
if (shouldCancel(() => fireRightClickAir())) {
|
||||
return false
|
||||
}
|
||||
|
||||
// setting the active hand will also set its initial duration
|
||||
var hand: EnumHand = EnumHand.MAIN_HAND
|
||||
if (!trySetActiveHand(hand, duration)) {
|
||||
hand = EnumHand.OFF_HAND
|
||||
if (!trySetActiveHand(hand, duration)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// setting the active hand will also set its initial duration
|
||||
var hand: EnumHand = EnumHand.MAIN_HAND
|
||||
if (!trySetActiveHand(hand, duration)) {
|
||||
hand = EnumHand.OFF_HAND
|
||||
if (!trySetActiveHand(hand, duration)) {
|
||||
return false
|
||||
}
|
||||
// Change the offset at which items are used, to avoid hitting
|
||||
// the robot itself (e.g. with bows, potions, mining laser, ...).
|
||||
posX += facing.getFrontOffsetX / 2.0
|
||||
posZ += facing.getFrontOffsetZ / 2.0
|
||||
|
||||
try {
|
||||
val stack = getActiveItemStack
|
||||
val oldStack = stack.copy
|
||||
var newStack = stack.copy
|
||||
if (isItemUseAllowed(stack)) {
|
||||
|
||||
val maxDuration = stack.getMaxItemUseDuration
|
||||
val heldTicks = Math.max(0, Math.min(maxDuration, (duration * 20).toInt))
|
||||
agent.machine.pause(heldTicks / 20.0)
|
||||
|
||||
newStack = stack.useItemRightClick(world, this, hand).getResult
|
||||
}
|
||||
stopActiveHand()
|
||||
|
||||
// Change the offset at which items are used, to avoid hitting
|
||||
// the robot itself (e.g. with bows, potions, mining laser, ...).
|
||||
posX += facing.getFrontOffsetX / 2.0
|
||||
posZ += facing.getFrontOffsetZ / 2.0
|
||||
val stackChanged: Boolean =
|
||||
!ItemStack.areItemStacksEqual(oldStack, newStack) ||
|
||||
!ItemStack.areItemStacksEqual(oldStack, stack)
|
||||
|
||||
try {
|
||||
val stack = getActiveItemStack
|
||||
val oldStack = stack.copy
|
||||
var newStack = stack.copy
|
||||
if (isItemUseAllowed(stack)) {
|
||||
|
||||
val maxDuration = stack.getMaxItemUseDuration
|
||||
val heldTicks = Math.max(0, Math.min(maxDuration, (duration * 20).toInt))
|
||||
agent.machine.pause(heldTicks / 20.0)
|
||||
|
||||
newStack = stack.useItemRightClick(world, this, hand).getResult
|
||||
}
|
||||
stopActiveHand()
|
||||
|
||||
val stackChanged: Boolean =
|
||||
!ItemStack.areItemStacksEqual(oldStack, newStack) ||
|
||||
!ItemStack.areItemStacksEqual(oldStack, stack)
|
||||
|
||||
if (stackChanged) {
|
||||
agent.equipmentInventory.setInventorySlotContents(0, newStack)
|
||||
}
|
||||
stackChanged
|
||||
if (stackChanged) {
|
||||
agent.equipmentInventory.setInventorySlotContents(0, newStack)
|
||||
}
|
||||
finally {
|
||||
posX -= facing.getFrontOffsetX / 2.0
|
||||
posZ -= facing.getFrontOffsetZ / 2.0
|
||||
}
|
||||
})
|
||||
stackChanged
|
||||
}
|
||||
finally {
|
||||
posX -= facing.getFrontOffsetX / 2.0
|
||||
posZ -= facing.getFrontOffsetZ / 2.0
|
||||
}
|
||||
}
|
||||
|
||||
def placeBlock(slot: Int, pos: BlockPos, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user