diff --git a/src/main/scala/li/cil/oc/integration/vanilla/DriverInventory.java b/src/main/scala/li/cil/oc/integration/vanilla/DriverInventory.java index 4431fc8b6..cde412eeb 100644 --- a/src/main/scala/li/cil/oc/integration/vanilla/DriverInventory.java +++ b/src/main/scala/li/cil/oc/integration/vanilla/DriverInventory.java @@ -1,5 +1,6 @@ package li.cil.oc.integration.vanilla; +import cpw.mods.fml.common.eventhandler.Event; import li.cil.oc.Settings; import li.cil.oc.api.machine.Arguments; import li.cil.oc.api.machine.Callback; @@ -7,14 +8,16 @@ import li.cil.oc.api.machine.Context; import li.cil.oc.api.network.ManagedEnvironment; import li.cil.oc.api.prefab.DriverTileEntity; import li.cil.oc.integration.ManagedTileEntityEnvironment; +import li.cil.oc.util.BlockPosition; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.common.util.FakePlayerFactory; +import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; public final class DriverInventory extends DriverTileEntity { @Override @@ -29,12 +32,12 @@ public final class DriverInventory extends DriverTileEntity { public static final class Environment extends ManagedTileEntityEnvironment { private final EntityPlayer fakePlayer; - private final Vec3 position; + private final BlockPosition position; public Environment(final TileEntity tileEntity, final World world) { super((IInventory) tileEntity, "inventory"); fakePlayer = FakePlayerFactory.get((WorldServer) world, Settings.get().fakePlayerProfile()); - position = Vec3.createVectorHelper(tileEntity.xCoord + 0.5, tileEntity.yCoord + 0.5, tileEntity.zCoord + 0.5); + position = BlockPosition.apply(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord, world); } @Callback(doc = "function():string -- Get the name of this inventory.") @@ -172,8 +175,9 @@ public final class DriverInventory extends DriverTileEntity { private boolean notPermitted() { synchronized (fakePlayer) { - fakePlayer.setPosition(position.xCoord, position.yCoord, position.zCoord); - return !tileEntity.isUseableByPlayer(fakePlayer); + fakePlayer.setPosition(position.toVec3().xCoord, position.toVec3().yCoord, position.toVec3().zCoord); + final PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(fakePlayer, PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK, position.x(), position.y(), position.z(), 0, fakePlayer.getEntityWorld()); + return !event.isCanceled() && event.useBlock != Event.Result.DENY && !tileEntity.isUseableByPlayer(fakePlayer); } } } diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala index c6497f971..3627b8b32 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala @@ -36,8 +36,9 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest val count = args.optionalItemCount(1) val stack = inventory.getStackInSlot(selectedSlot) if (stack != null && stack.stackSize > 0) { - InventoryUtils.inventoryAt(position.offset(facing)) match { - case Some(inv) if inv.isUseableByPlayer(fakePlayer) => + val blockPos = position.offset(facing) + InventoryUtils.inventoryAt(blockPos) match { + case Some(inv) if inv.isUseableByPlayer(fakePlayer) && mayInteract(blockPos, facing.getOpposite) => if (!InventoryUtils.insertIntoInventory(stack, inv, Option(facing.getOpposite), count)) { // Cannot drop into that inventory. return result(false, "inventory full") @@ -70,8 +71,9 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest val facing = checkSideForAction(args, 0) val count = args.optionalItemCount(1) - if (InventoryUtils.inventoryAt(position.offset(facing)).exists(inventory => { - inventory.isUseableByPlayer(fakePlayer) && InventoryUtils.extractFromInventory(InventoryUtils.insertIntoInventory(_, this.inventory, slots = Option(insertionSlots)), inventory, facing.getOpposite, count) + val blockPos = position.offset(facing) + if (InventoryUtils.inventoryAt(blockPos).exists(inventory => { + inventory.isUseableByPlayer(fakePlayer) && mayInteract(blockPos, facing.getOpposite) && InventoryUtils.extractFromInventory(InventoryUtils.insertIntoInventory(_, this.inventory, slots = Option(insertionSlots)), inventory, facing.getOpposite, count) })) { context.pause(Settings.get.suckDelay) result(true) diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala index 55083b348..814ed4706 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala @@ -56,7 +56,7 @@ trait InventoryWorldControlMk2 extends InventoryAware with WorldAware with SideR private def withInventory(side: ForgeDirection, f: IInventory => Array[AnyRef]) = InventoryUtils.inventoryAt(position.offset(side)) match { - case Some(inventory) if inventory.isUseableByPlayer(fakePlayer) => f(inventory) + case Some(inventory) if inventory.isUseableByPlayer(fakePlayer) && mayInteract(position.offset(side), side.getOpposite) => f(inventory) case _ => result(Unit, "no inventory") } } diff --git a/src/main/scala/li/cil/oc/server/component/traits/WorldAware.scala b/src/main/scala/li/cil/oc/server/component/traits/WorldAware.scala index 95df7a722..56bc16711 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/WorldAware.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/WorldAware.scala @@ -1,5 +1,6 @@ package li.cil.oc.server.component.traits +import cpw.mods.fml.common.eventhandler.Event.Result import li.cil.oc.Settings import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedBlock._ @@ -13,6 +14,8 @@ import net.minecraft.world.WorldServer import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.util.FakePlayerFactory import net.minecraftforge.common.util.ForgeDirection +import net.minecraftforge.event.ForgeEventFactory +import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action import net.minecraftforge.event.world.BlockEvent import net.minecraftforge.fluids.FluidRegistry @@ -33,6 +36,11 @@ trait WorldAware { player } + def mayInteract(blockPos: BlockPosition, face: ForgeDirection): Boolean = { + val event = ForgeEventFactory.onPlayerInteract(fakePlayer, Action.RIGHT_CLICK_BLOCK, blockPos.x, blockPos.y, blockPos.z, face.ordinal(), world) + !event.isCanceled && event.useBlock != Result.DENY + } + def entitiesInBounds[Type <: Entity : ClassTag](bounds: AxisAlignedBB) = { world.getEntitiesWithinAABB(classTag[Type].runtimeClass, bounds).map(_.asInstanceOf[Type]) } diff --git a/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala b/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala index f03e9ae2d..f59e36129 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala @@ -66,7 +66,7 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ private def withInventory(side: ForgeDirection, f: IInventory => Array[AnyRef]) = InventoryUtils.inventoryAt(position.offset(side)) match { - case Some(inventory) if inventory.isUseableByPlayer(fakePlayer) => f(inventory) + case Some(inventory) if inventory.isUseableByPlayer(fakePlayer) && mayInteract(position.offset(side), side.getOpposite) => f(inventory) case _ => result(null, "no inventory") } }