mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-13 17:28:52 -04:00
Firing PlayerInteractEvent
when agents (robots, drones) are interacting with in-world inventories and in the inventory driver. See #900.
Hopefully doesn't break anything...
This commit is contained in:
parent
ffd38e59ff
commit
c0690bb07f
@ -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<IInventory> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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])
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user