fix #3182 by passing inventory source to transposer.getInventoryName

This commit is contained in:
Adrian Siekierka 2022-06-12 13:13:24 +02:00 committed by payonel
parent b2831fc2e0
commit 352e75603c
2 changed files with 51 additions and 17 deletions

View File

@ -6,12 +6,12 @@ import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context import li.cil.oc.api.machine.Context
import li.cil.oc.api.prefab.ItemStackArrayValue import li.cil.oc.api.prefab.ItemStackArrayValue
import li.cil.oc.server.component.result import li.cil.oc.server.component.result
import li.cil.oc.util.{BlockPosition, DatabaseAccess, InventoryUtils} import li.cil.oc.util.{BlockInventorySource, BlockPosition, DatabaseAccess, EntityInventorySource, InventorySource, InventoryUtils}
import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.ExtendedWorld._
import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedArguments._
import li.cil.oc.util.InventoryUtils
import net.minecraft.inventory.IInventory import net.minecraft.inventory.IInventory
import net.minecraft.block.Block import net.minecraft.block.Block
import net.minecraft.entity.EntityList
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
import net.minecraftforge.oredict.OreDictionary import net.minecraftforge.oredict.OreDictionary
@ -102,9 +102,13 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ
} }
case _ => None case _ => None
} }
withInventory(facing, inventory => blockAt(position.offset(facing)) match { withInventorySource(facing, {
case BlockInventorySource(position, _) => blockAt(position) match {
case Some(block) => result(block.getUnlocalizedName) case Some(block) => result(block.getUnlocalizedName)
case _ => result(Unit, "Unknown") case _ => result(Unit, "Unknown")
}
case EntityInventorySource(entity, _) => result(EntityList.getEntityString(entity))
case _ => result(Unit, "Unknown")
}) })
} }
else result(Unit, "not enabled in config") else result(Unit, "not enabled in config")
@ -122,9 +126,20 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ
withInventory(facing, inventory => store(inventory.getStackInSlot(args.checkSlot(inventory, 1)))) withInventory(facing, inventory => store(inventory.getStackInSlot(args.checkSlot(inventory, 1))))
} }
private def withInventory(side: ForgeDirection, f: IInventory => Array[AnyRef]) = private def mayInteract(side: ForgeDirection, f: InventorySource): Boolean = {
InventoryUtils.inventoryAt(position.offset(side)) match { if (!f.inventory.isUseableByPlayer(fakePlayer)) false
case Some(inventory) if inventory.isUseableByPlayer(fakePlayer) && mayInteract(position.offset(side), side.getOpposite) => f(inventory) else f match {
case BlockInventorySource(pos, _) => mayInteract(pos, side.getOpposite)
case _ => true
}
}
private def withInventorySource(side: ForgeDirection, f: InventorySource => Array[AnyRef]) =
InventoryUtils.inventorySourceAt(position.offset(side)) match {
case Some(is) if mayInteract(side, is) => f(is)
case _ => result(Unit, "no inventory") case _ => result(Unit, "no inventory")
} }
private def withInventory(side: ForgeDirection, f: IInventory => Array[AnyRef]) =
withInventorySource(side, is => f(is.inventory))
} }

View File

@ -2,6 +2,7 @@ package li.cil.oc.util
import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.ExtendedWorld._
import net.minecraft.block.BlockChest import net.minecraft.block.BlockChest
import net.minecraft.entity.Entity
import net.minecraft.entity.item.EntityItem import net.minecraft.entity.item.EntityItem
import net.minecraft.entity.item.EntityMinecartContainer import net.minecraft.entity.item.EntityMinecartContainer
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
@ -25,22 +26,34 @@ object InventoryUtils {
(!stackA.getHasSubtypes || stackA.getItemDamage == stackB.getItemDamage) && (!stackA.getHasSubtypes || stackA.getItemDamage == stackB.getItemDamage) &&
(!checkNBT || ItemStack.areItemStackTagsEqual(stackA, stackB)) (!checkNBT || ItemStack.areItemStackTagsEqual(stackA, stackB))
/**
* Retrieves an actual inventory implementation for a specified world coordinate,
* complete with a reference to the source of said implementation.
* <br>
* This performs special handling for (double-)chests and also checks for
* mine carts with chests.
*/
def inventorySourceAt(position: BlockPosition): Option[InventorySource] = position.world match {
case Some(world) if world.blockExists(position) => (world.getBlock(position), world.getTileEntity(position)) match {
case (block: BlockChest, chest: TileEntityChest) => Option(block.func_149951_m(world, chest.xCoord, chest.yCoord, chest.zCoord)).
map(a => BlockInventorySource(position, a))
case (_, inventory: IInventory) => Some(BlockInventorySource(position, inventory))
case _ => world.getEntitiesWithinAABB(classOf[EntityMinecartContainer], position.bounds).
map(_.asInstanceOf[EntityMinecartContainer]).
find(!_.isDead).
map(a => EntityInventorySource(a, a))
}
case _ => None
}
/** /**
* Retrieves an actual inventory implementation for a specified world coordinate. * Retrieves an actual inventory implementation for a specified world coordinate.
* <br> * <br>
* This performs special handling for (double-)chests and also checks for * This performs special handling for (double-)chests and also checks for
* mine carts with chests. * mine carts with chests.
*/ */
def inventoryAt(position: BlockPosition): Option[IInventory] = position.world match { def inventoryAt(position: BlockPosition): Option[IInventory] = inventorySourceAt(position).
case Some(world) if world.blockExists(position) => (world.getBlock(position), world.getTileEntity(position)) match { map(a => a.inventory)
case (block: BlockChest, chest: TileEntityChest) => Option(block.func_149951_m(world, chest.xCoord, chest.yCoord, chest.zCoord))
case (_, inventory: IInventory) => Some(inventory)
case _ => world.getEntitiesWithinAABB(classOf[EntityMinecartContainer], position.bounds).
map(_.asInstanceOf[EntityMinecartContainer]).
find(!_.isDead)
}
case _ => None
}
/** /**
* Inserts a stack into an inventory. * Inserts a stack into an inventory.
@ -408,3 +421,9 @@ object InventoryUtils {
case _ => null case _ => null
} }
} }
sealed trait InventorySource {
def inventory: IInventory
}
final case class BlockInventorySource(position: BlockPosition, inventory: IInventory) extends InventorySource
final case class EntityInventorySource(entity: Entity, inventory: IInventory) extends InventorySource