Skip to content

Commit c0690bb

Browse files
committedMar 11, 2015
Firing PlayerInteractEvent when agents (robots, drones) are interacting with in-world inventories and in the inventory driver. See #900.
Hopefully doesn't break anything...

File tree

5 files changed

+25
-11
lines changed

5 files changed

+25
-11
lines changed
 

Diff for: ‎src/main/scala/li/cil/oc/integration/vanilla/DriverInventory.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
package li.cil.oc.integration.vanilla;
22

3+
import cpw.mods.fml.common.eventhandler.Event;
34
import li.cil.oc.Settings;
45
import li.cil.oc.api.machine.Arguments;
56
import li.cil.oc.api.machine.Callback;
67
import li.cil.oc.api.machine.Context;
78
import li.cil.oc.api.network.ManagedEnvironment;
89
import li.cil.oc.api.prefab.DriverTileEntity;
910
import li.cil.oc.integration.ManagedTileEntityEnvironment;
11+
import li.cil.oc.util.BlockPosition;
1012
import net.minecraft.entity.player.EntityPlayer;
1113
import net.minecraft.inventory.IInventory;
1214
import net.minecraft.item.ItemStack;
1315
import net.minecraft.tileentity.TileEntity;
14-
import net.minecraft.util.Vec3;
1516
import net.minecraft.world.World;
1617
import net.minecraft.world.WorldServer;
1718
import net.minecraftforge.common.util.FakePlayerFactory;
19+
import net.minecraftforge.event.ForgeEventFactory;
20+
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
1821

1922
public final class DriverInventory extends DriverTileEntity {
2023
@Override
@@ -29,12 +32,12 @@ public ManagedEnvironment createEnvironment(final World world, final int x, fina
2932

3033
public static final class Environment extends ManagedTileEntityEnvironment<IInventory> {
3134
private final EntityPlayer fakePlayer;
32-
private final Vec3 position;
35+
private final BlockPosition position;
3336

3437
public Environment(final TileEntity tileEntity, final World world) {
3538
super((IInventory) tileEntity, "inventory");
3639
fakePlayer = FakePlayerFactory.get((WorldServer) world, Settings.get().fakePlayerProfile());
37-
position = Vec3.createVectorHelper(tileEntity.xCoord + 0.5, tileEntity.yCoord + 0.5, tileEntity.zCoord + 0.5);
40+
position = BlockPosition.apply(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord, world);
3841
}
3942

4043
@Callback(doc = "function():string -- Get the name of this inventory.")
@@ -172,8 +175,9 @@ private boolean itemEquals(final ItemStack stackA, final ItemStack stackB) {
172175

173176
private boolean notPermitted() {
174177
synchronized (fakePlayer) {
175-
fakePlayer.setPosition(position.xCoord, position.yCoord, position.zCoord);
176-
return !tileEntity.isUseableByPlayer(fakePlayer);
178+
fakePlayer.setPosition(position.toVec3().xCoord, position.toVec3().yCoord, position.toVec3().zCoord);
179+
final PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(fakePlayer, PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK, position.x(), position.y(), position.z(), 0, fakePlayer.getEntityWorld());
180+
return !event.isCanceled() && event.useBlock != Event.Result.DENY && !tileEntity.isUseableByPlayer(fakePlayer);
177181
}
178182
}
179183
}

Diff for: ‎src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala

+6-4
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest
3636
val count = args.optionalItemCount(1)
3737
val stack = inventory.getStackInSlot(selectedSlot)
3838
if (stack != null && stack.stackSize > 0) {
39-
InventoryUtils.inventoryAt(position.offset(facing)) match {
40-
case Some(inv) if inv.isUseableByPlayer(fakePlayer) =>
39+
val blockPos = position.offset(facing)
40+
InventoryUtils.inventoryAt(blockPos) match {
41+
case Some(inv) if inv.isUseableByPlayer(fakePlayer) && mayInteract(blockPos, facing.getOpposite) =>
4142
if (!InventoryUtils.insertIntoInventory(stack, inv, Option(facing.getOpposite), count)) {
4243
// Cannot drop into that inventory.
4344
return result(false, "inventory full")
@@ -70,8 +71,9 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest
7071
val facing = checkSideForAction(args, 0)
7172
val count = args.optionalItemCount(1)
7273

73-
if (InventoryUtils.inventoryAt(position.offset(facing)).exists(inventory => {
74-
inventory.isUseableByPlayer(fakePlayer) && InventoryUtils.extractFromInventory(InventoryUtils.insertIntoInventory(_, this.inventory, slots = Option(insertionSlots)), inventory, facing.getOpposite, count)
74+
val blockPos = position.offset(facing)
75+
if (InventoryUtils.inventoryAt(blockPos).exists(inventory => {
76+
inventory.isUseableByPlayer(fakePlayer) && mayInteract(blockPos, facing.getOpposite) && InventoryUtils.extractFromInventory(InventoryUtils.insertIntoInventory(_, this.inventory, slots = Option(insertionSlots)), inventory, facing.getOpposite, count)
7577
})) {
7678
context.pause(Settings.get.suckDelay)
7779
result(true)

Diff for: ‎src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ trait InventoryWorldControlMk2 extends InventoryAware with WorldAware with SideR
5656

5757
private def withInventory(side: ForgeDirection, f: IInventory => Array[AnyRef]) =
5858
InventoryUtils.inventoryAt(position.offset(side)) match {
59-
case Some(inventory) if inventory.isUseableByPlayer(fakePlayer) => f(inventory)
59+
case Some(inventory) if inventory.isUseableByPlayer(fakePlayer) && mayInteract(position.offset(side), side.getOpposite) => f(inventory)
6060
case _ => result(Unit, "no inventory")
6161
}
6262
}

Diff for: ‎src/main/scala/li/cil/oc/server/component/traits/WorldAware.scala

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package li.cil.oc.server.component.traits
22

3+
import cpw.mods.fml.common.eventhandler.Event.Result
34
import li.cil.oc.Settings
45
import li.cil.oc.util.BlockPosition
56
import li.cil.oc.util.ExtendedBlock._
@@ -13,6 +14,8 @@ import net.minecraft.world.WorldServer
1314
import net.minecraftforge.common.MinecraftForge
1415
import net.minecraftforge.common.util.FakePlayerFactory
1516
import net.minecraftforge.common.util.ForgeDirection
17+
import net.minecraftforge.event.ForgeEventFactory
18+
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action
1619
import net.minecraftforge.event.world.BlockEvent
1720
import net.minecraftforge.fluids.FluidRegistry
1821

@@ -33,6 +36,11 @@ trait WorldAware {
3336
player
3437
}
3538

39+
def mayInteract(blockPos: BlockPosition, face: ForgeDirection): Boolean = {
40+
val event = ForgeEventFactory.onPlayerInteract(fakePlayer, Action.RIGHT_CLICK_BLOCK, blockPos.x, blockPos.y, blockPos.z, face.ordinal(), world)
41+
!event.isCanceled && event.useBlock != Result.DENY
42+
}
43+
3644
def entitiesInBounds[Type <: Entity : ClassTag](bounds: AxisAlignedBB) = {
3745
world.getEntitiesWithinAABB(classTag[Type].runtimeClass, bounds).map(_.asInstanceOf[Type])
3846
}

Diff for: ‎src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ
6666

6767
private def withInventory(side: ForgeDirection, f: IInventory => Array[AnyRef]) =
6868
InventoryUtils.inventoryAt(position.offset(side)) match {
69-
case Some(inventory) if inventory.isUseableByPlayer(fakePlayer) => f(inventory)
69+
case Some(inventory) if inventory.isUseableByPlayer(fakePlayer) && mayInteract(position.offset(side), side.getOpposite) => f(inventory)
7070
case _ => result(null, "no inventory")
7171
}
7272
}

3 commit comments

Comments
 (3)

fnuecke commented on Mar 12, 2015

@fnuecke
MemberAuthor

Great.

As for the 'but', that's... very very unlikely to be related. The changes have nothing at all to do with how players interact with inventories; it's exclusively related to drone/robot/adapter interaction with inventories.

fnuecke commented on Mar 13, 2015

@fnuecke
MemberAuthor

I can't reproduce any such issue, so I have to guess it's some interaction with something else. Try if it happens with only OC present. If it still does, check your logs for warnings, give a step-by-step description of how to reproduce the issue, maybe even a short video capture of the issue. Thanks.

fnuecke commented on Mar 13, 2015

@fnuecke
MemberAuthor

Allrighty, thanks for the update.

Please sign in to comment.