blob: 3dd08bc55d79091a7d6746a334badacfce708e84 [file] [log] [blame] [raw]
package li.cil.oc.util
import li.cil.oc.common.tileentity.Robot
import net.minecraft.block.Block
import net.minecraft.item.ItemStack
import net.minecraft.util.ChunkCoordinates
import net.minecraftforge.common.{ForgeDirection, FakePlayer}
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action
import net.minecraftforge.event.{Event, ForgeEventFactory}
class RobotPlayer(val robot: Robot) extends FakePlayer(robot.world, "OpenComputers") {
capabilities.allowFlying = true
capabilities.disableDamage = true
capabilities.isFlying = true
val robotInventory = new InventoryRobot(this)
inventory = robotInventory
yOffset = 1f
// TODO override def getBoundingBox = super.getBoundingBox
override def getPlayerCoordinates = new ChunkCoordinates(robot.x, robot.y, robot.z)
def activateBlockOrUseItem(x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side)
if (event.isCanceled) {
return false
}
val world = robot.world
val stack = inventory.getCurrentItem
val item = if (stack != null) stack.getItem else null
if (item != null && item.onItemUseFirst(stack, this, world, x, y, z, side, hitX, hitY, hitZ)) {
if (stack.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(this, stack)
if (stack.stackSize <= 0) inventory.setInventorySlotContents(0, null)
return true
}
val blockId = world.getBlockId(x, y, z)
val block = Block.blocksList(blockId)
val shouldActivate = block != null && (!isSneaking || (item == null || item.shouldPassSneakingClickToBlock(world, x, y, z)))
val activated = shouldActivate && (event.useBlock == Event.Result.DENY ||
block.onBlockActivated(world, x, y, z, this, side, hitX, hitY, hitZ))
activated || (stack != null && ({
val direction = ForgeDirection.getOrientation(side).getOpposite
val (onX, onY, onZ) = (x + direction.offsetX, y + direction.offsetY, z + direction.offsetZ)
val result = stack.tryPlaceItemIntoWorld(this, world, onX, onY, onZ, side, hitX, hitY, hitZ)
if (stack.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(this, stack)
if (stack.stackSize <= 0) inventory.setInventorySlotContents(0, null)
result
} || stack.getMaxItemUseDuration <= 0 && {
val oldSize = stack.stackSize
val oldDamage = stack.getItemDamage
val newStack = stack.useItemRightClick(world, this)
val stackChanged = newStack != stack || (newStack != null && (newStack.stackSize != oldSize || newStack.getItemDamage != oldDamage))
stackChanged && {
if (newStack.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(this, newStack)
if (newStack.stackSize > 0) inventory.setInventorySlotContents(0, newStack)
else inventory.setInventorySlotContents(0, null)
true
}
}))
}
def placeBlock(stack: ItemStack, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side)
if (event.isCanceled) {
return false
}
event.useBlock == Event.Result.DENY || {
val world = robot.world
val direction = ForgeDirection.getOrientation(side).getOpposite
val (onX, onY, onZ) = (x + direction.offsetX, y + direction.offsetY, z + direction.offsetZ)
val result = stack.tryPlaceItemIntoWorld(this, world, onX, onY, onZ, side, hitX, hitY, hitZ)
if (stack.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(this, stack)
result
}
}
def updatePositionAndRotation(pitch: ForgeDirection) {
val offsetToGetPistonsToBePlacedProperly = pitch.offsetY * 0.83
posX = robot.x + 0.5
posY = robot.y + yOffset - offsetToGetPistonsToBePlacedProperly
posZ = robot.z + 0.5
rotationPitch = pitch.offsetY * -90
rotationYaw = robot.yaw match {
case ForgeDirection.WEST => 90
case ForgeDirection.NORTH => 180
case ForgeDirection.EAST => 270
case _ => 0
}
prevPosX = posZ
prevPosY = posY
prevPosZ = posZ
prevRotationPitch = rotationPitch
cameraPitch = rotationPitch
prevCameraPitch = rotationPitch
prevRotationYaw = rotationYaw
cameraYaw = rotationYaw
prevCameraYaw = rotationYaw
}
}