mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-15 18:30:27 -04:00
robots can now interact with *living* entities (i.e. use items on entities, such as shears on sheep)
This commit is contained in:
parent
763054bb7d
commit
ed7ab6b535
@ -6,7 +6,7 @@ import li.cil.oc.common.tileentity
|
|||||||
import li.cil.oc.server.component.robot.{Player, ActivationType}
|
import li.cil.oc.server.component.robot.{Player, ActivationType}
|
||||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||||
import net.minecraft.block.{BlockFluid, Block}
|
import net.minecraft.block.{BlockFluid, Block}
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.{EntityLivingBase, Entity}
|
||||||
import net.minecraft.entity.item.EntityItem
|
import net.minecraft.entity.item.EntityItem
|
||||||
import net.minecraft.inventory.{IInventory, ISidedInventory}
|
import net.minecraft.inventory.{IInventory, ISidedInventory}
|
||||||
import net.minecraft.item.{ItemStack, ItemBlock}
|
import net.minecraft.item.{ItemStack, ItemBlock}
|
||||||
@ -14,6 +14,7 @@ import net.minecraft.util.{MovingObjectPosition, EnumMovingObjectType}
|
|||||||
import net.minecraftforge.common.ForgeDirection
|
import net.minecraftforge.common.ForgeDirection
|
||||||
import net.minecraftforge.fluids.FluidRegistry
|
import net.minecraftforge.fluids.FluidRegistry
|
||||||
import scala.Some
|
import scala.Some
|
||||||
|
import scala.collection.convert.WrapAsScala._
|
||||||
|
|
||||||
class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
||||||
|
|
||||||
@ -306,27 +307,33 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
context.pause(Settings.get.swingDelay)
|
context.pause(Settings.get.swingDelay)
|
||||||
robot.animateSwing(Settings.get.swingDelay)
|
robot.animateSwing(Settings.get.swingDelay)
|
||||||
}
|
}
|
||||||
|
def attack(entity: Entity) = {
|
||||||
|
beginConsumeDrops(entity)
|
||||||
|
player.attackTargetEntityWithCurrentItem(entity)
|
||||||
|
endConsumeDrops(entity)
|
||||||
|
triggerDelay()
|
||||||
|
result(true, "entity")
|
||||||
|
}
|
||||||
|
def click(x: Int, y: Int, z: Int, side: Int) = {
|
||||||
|
val broke = player.clickBlock(x, y, z, side)
|
||||||
|
if (broke) {
|
||||||
|
triggerDelay()
|
||||||
|
}
|
||||||
|
result(broke, "block")
|
||||||
|
}
|
||||||
Option(pick(player, Settings.get.swingRange)) match {
|
Option(pick(player, Settings.get.swingRange)) match {
|
||||||
case Some(hit) =>
|
case Some(hit) =>
|
||||||
val what = hit.typeOfHit match {
|
val what = hit.typeOfHit match {
|
||||||
case EnumMovingObjectType.ENTITY =>
|
case EnumMovingObjectType.ENTITY =>
|
||||||
player.attackTargetEntityWithCurrentItem(hit.entityHit)
|
attack(hit.entityHit)
|
||||||
triggerDelay()
|
|
||||||
result(true, "entity")
|
|
||||||
case EnumMovingObjectType.TILE =>
|
case EnumMovingObjectType.TILE =>
|
||||||
val broke = player.clickBlock(hit.blockX, hit.blockY, hit.blockZ, hit.sideHit)
|
click(hit.blockX, hit.blockY, hit.blockZ, hit.sideHit)
|
||||||
if (broke) {
|
|
||||||
triggerDelay()
|
|
||||||
}
|
|
||||||
result(broke, "block")
|
|
||||||
}
|
}
|
||||||
what
|
what
|
||||||
case _ =>
|
case _ => // Retry with full block bounds, disregarding swing range.
|
||||||
player.closestEntity[Entity]() match {
|
player.closestEntity[EntityLivingBase]() match {
|
||||||
case Some(entity) =>
|
case Some(entity) =>
|
||||||
player.attackTargetEntityWithCurrentItem(entity)
|
attack(entity)
|
||||||
triggerDelay()
|
|
||||||
result(true, "entity")
|
|
||||||
case _ =>
|
case _ =>
|
||||||
result(false)
|
result(false)
|
||||||
}
|
}
|
||||||
@ -363,17 +370,19 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
case _ => result(false)
|
case _ => result(false)
|
||||||
}
|
}
|
||||||
player.setSneaking(sneaky)
|
player.setSneaking(sneaky)
|
||||||
|
def interact(entity: Entity) = {
|
||||||
|
beginConsumeDrops(entity)
|
||||||
|
val result = player.interactWith(entity)
|
||||||
|
endConsumeDrops(entity)
|
||||||
|
result
|
||||||
|
}
|
||||||
val what = Option(pick(player, Settings.get.useAndPlaceRange)) match {
|
val what = Option(pick(player, Settings.get.useAndPlaceRange)) match {
|
||||||
case Some(hit) =>
|
case Some(hit) if hit.typeOfHit == EnumMovingObjectType.ENTITY && interact(hit.entityHit) =>
|
||||||
hit.typeOfHit match {
|
triggerDelay()
|
||||||
case EnumMovingObjectType.ENTITY =>
|
result(true, "item_interacted")
|
||||||
// TODO Is there any practical use for this? Most of the stuff related to this is still 'obfuscated'...
|
case Some(hit) if hit.typeOfHit == EnumMovingObjectType.TILE =>
|
||||||
// TODO I think this is used for shearing sheep, for example... needs looking into.
|
val (bx, by, bz, hx, hy, hz) = clickParamsFromHit(hit)
|
||||||
result(false, "entity")
|
activationResult(player.activateBlockOrUseItem(bx, by, bz, hit.sideHit, hx, hy, hz, duration))
|
||||||
case EnumMovingObjectType.TILE =>
|
|
||||||
val (bx, by, bz, hx, hy, hz) = clickParamsFromHit(hit)
|
|
||||||
activationResult(player.activateBlockOrUseItem(bx, by, bz, hit.sideHit, hx, hy, hz, duration))
|
|
||||||
}
|
|
||||||
case _ =>
|
case _ =>
|
||||||
(if (Settings.get.canPlaceInAir) {
|
(if (Settings.get.canPlaceInAir) {
|
||||||
val (bx, by, bz, hx, hy, hz) = clickParamsFromFacing(facing, side)
|
val (bx, by, bz, hx, hy, hz) = clickParamsFromFacing(facing, side)
|
||||||
@ -445,6 +454,25 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
private def beginConsumeDrops(entity: Entity) {
|
||||||
|
entity.captureDrops = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private def endConsumeDrops(entity: Entity) {
|
||||||
|
val player = robot.player()
|
||||||
|
entity.captureDrops = false
|
||||||
|
for (drop <- entity.capturedDrops) {
|
||||||
|
val stack = drop.getEntityItem
|
||||||
|
player.inventory.addItemStackToInventory(stack)
|
||||||
|
if (stack.stackSize > 0) {
|
||||||
|
player.dropPlayerItemWithRandomChoice(stack, inPlace = false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entity.capturedDrops.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
private def blockContent(side: ForgeDirection) = {
|
private def blockContent(side: ForgeDirection) = {
|
||||||
val (bx, by, bz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
|
val (bx, by, bz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
|
||||||
val id = world.getBlockId(bx, by, bz)
|
val id = world.getBlockId(bx, by, bz)
|
||||||
@ -477,7 +505,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
|
|
||||||
private def pick(player: Player, range: Double) = {
|
private def pick(player: Player, range: Double) = {
|
||||||
val hit = player.rayTrace(range, 1)
|
val hit = player.rayTrace(range, 1)
|
||||||
player.closestEntity[Entity]() match {
|
player.closestEntity[EntityLivingBase]() match {
|
||||||
case Some(entity) if hit == null || player.getPosition(1).distanceTo(hit.hitVec) > player.getDistanceToEntity(entity) => new MovingObjectPosition(entity)
|
case Some(entity) if hit == null || player.getPosition(1).distanceTo(hit.hitVec) > player.getDistanceToEntity(entity) => new MovingObjectPosition(entity)
|
||||||
case _ => hit
|
case _ => hit
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,16 @@ class Player(val robot: Robot) extends EntityPlayer(robot.world, Settings.get.na
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def interactWith(entity: Entity) = {
|
||||||
|
val stack = getCurrentEquippedItem
|
||||||
|
val oldDamage = if (stack != null) getCurrentEquippedItem.getItemDamage else 0
|
||||||
|
val result = super.interactWith(entity)
|
||||||
|
if (stack != null && stack.stackSize > 0) {
|
||||||
|
tryRepair(stack, oldDamage)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
def activateBlockOrUseItem(x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float, duration: Double): ActivationType.Value = {
|
def activateBlockOrUseItem(x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float, duration: Double): ActivationType.Value = {
|
||||||
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side)
|
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side)
|
||||||
if (event.isCanceled || event.useBlock == Event.Result.DENY) {
|
if (event.isCanceled || event.useBlock == Event.Result.DENY) {
|
||||||
@ -330,8 +340,6 @@ class Player(val robot: Robot) extends EntityPlayer(robot.world, Settings.get.na
|
|||||||
|
|
||||||
override def sleepInBedAt(x: Int, y: Int, z: Int) = EnumStatus.OTHER_PROBLEM
|
override def sleepInBedAt(x: Int, y: Int, z: Int) = EnumStatus.OTHER_PROBLEM
|
||||||
|
|
||||||
override def interactWith(entity: Entity) = false // TODO Or do we want this?
|
|
||||||
|
|
||||||
def canCommandSenderUseCommand(i: Int, s: String) = false
|
def canCommandSenderUseCommand(i: Int, s: String) = false
|
||||||
|
|
||||||
def sendChatToPlayer(message: ChatMessageComponent) {}
|
def sendChatToPlayer(message: ChatMessageComponent) {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user