mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-16 02:39:48 -04:00
get a move on. robots can now move. there's no animation yet and accordingly collision bounds aren't interpolated either, but movement basically works. in a very... simple manner, I must say (re-uses existing tile entity, on both server and client); cleaned up delegate class a bit (the node.remove in block break should be redundant since we do this in the environment tile entity base class)
This commit is contained in:
parent
827344b543
commit
3324371ec6
@ -85,6 +85,18 @@ object Config {
|
|||||||
var canPlaceInAir = false
|
var canPlaceInAir = false
|
||||||
var itemDamageRate = 0.05
|
var itemDamageRate = 0.05
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
// robot.delays
|
||||||
|
|
||||||
|
var dropDelay = 0.1
|
||||||
|
var moveDelay = 0.4
|
||||||
|
var placeDelay = 0.3
|
||||||
|
var suckDelay = 0.1
|
||||||
|
var swingDelay = 0.4
|
||||||
|
var turnDelay = 0.4
|
||||||
|
var useDelay = 0.4
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
def load(file: File) = {
|
def load(file: File) = {
|
||||||
|
@ -27,6 +27,7 @@ class PacketHandler extends CommonPacketHandler {
|
|||||||
case PacketType.ComputerStateResponse => onComputerStateResponse(p)
|
case PacketType.ComputerStateResponse => onComputerStateResponse(p)
|
||||||
case PacketType.PowerStateResponse => onPowerStateResponse(p)
|
case PacketType.PowerStateResponse => onPowerStateResponse(p)
|
||||||
case PacketType.RedstoneStateResponse => onRedstoneStateResponse(p)
|
case PacketType.RedstoneStateResponse => onRedstoneStateResponse(p)
|
||||||
|
case PacketType.RobotMove => onRobotMove(p)
|
||||||
case PacketType.RobotSelectedSlotResponse => onRobotSelectedSlotResponse(p)
|
case PacketType.RobotSelectedSlotResponse => onRobotSelectedSlotResponse(p)
|
||||||
case PacketType.RotatableStateResponse => onRotatableStateResponse(p)
|
case PacketType.RotatableStateResponse => onRotatableStateResponse(p)
|
||||||
case PacketType.ScreenBufferResponse => onScreenBufferResponse(p)
|
case PacketType.ScreenBufferResponse => onScreenBufferResponse(p)
|
||||||
@ -78,6 +79,12 @@ class PacketHandler extends CommonPacketHandler {
|
|||||||
case _ => // Invalid packet.
|
case _ => // Invalid packet.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def onRobotMove(p: PacketParser) =
|
||||||
|
p.readTileEntity[Robot]() match {
|
||||||
|
case Some(t) => t.move(p.readInt(), p.readInt(), p.readInt())
|
||||||
|
case _ => // Invalid packet.
|
||||||
|
}
|
||||||
|
|
||||||
def onRobotSelectedSlotResponse(p: PacketParser) =
|
def onRobotSelectedSlotResponse(p: PacketParser) =
|
||||||
p.readTileEntity[Robot]() match {
|
p.readTileEntity[Robot]() match {
|
||||||
case Some(t) => t.selectedSlot = p.readInt()
|
case Some(t) => t.selectedSlot = p.readInt()
|
||||||
|
@ -10,6 +10,7 @@ object PacketType extends Enumeration {
|
|||||||
val RedstoneStateRequest = Value("RedstoneStateRequest")
|
val RedstoneStateRequest = Value("RedstoneStateRequest")
|
||||||
val RedstoneStateResponse = Value("RedstoneStateResponse")
|
val RedstoneStateResponse = Value("RedstoneStateResponse")
|
||||||
|
|
||||||
|
val RobotMove = Value("RobotMove")
|
||||||
val RobotSelectedSlotRequest = Value("RobotSelectedSlotRequest")
|
val RobotSelectedSlotRequest = Value("RobotSelectedSlotRequest")
|
||||||
val RobotSelectedSlotResponse = Value("RobotSelectedSlotResponse")
|
val RobotSelectedSlotResponse = Value("RobotSelectedSlotResponse")
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package li.cil.oc.common.block
|
package li.cil.oc.common.block
|
||||||
|
|
||||||
import li.cil.oc.common.tileentity
|
import li.cil.oc.common.tileentity
|
||||||
import net.minecraft.block.Block
|
|
||||||
import net.minecraft.client.renderer.texture.IconRegister
|
import net.minecraft.client.renderer.texture.IconRegister
|
||||||
import net.minecraft.entity.EntityLivingBase
|
import net.minecraft.entity.EntityLivingBase
|
||||||
import net.minecraft.entity.player.EntityPlayer
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package li.cil.oc.common.block
|
package li.cil.oc.common.block
|
||||||
|
|
||||||
import java.util
|
import java.util
|
||||||
import li.cil.oc.api.network.Environment
|
|
||||||
import li.cil.oc.common.tileentity.Rotatable
|
import li.cil.oc.common.tileentity.Rotatable
|
||||||
import li.cil.oc.{Config, CreativeTab}
|
import li.cil.oc.{Config, CreativeTab}
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
@ -95,14 +94,7 @@ class Delegator[Child <: Delegate](id: Int, name: String) extends Block(id, Mate
|
|||||||
|
|
||||||
override def breakBlock(world: World, x: Int, y: Int, z: Int, blockId: Int, metadata: Int) = {
|
override def breakBlock(world: World, x: Int, y: Int, z: Int, blockId: Int, metadata: Int) = {
|
||||||
subBlock(metadata) match {
|
subBlock(metadata) match {
|
||||||
case Some(subBlock) => {
|
case Some(subBlock) => subBlock.breakBlock(world, x, y, z, blockId)
|
||||||
world.getBlockTileEntity(x, y, z) match {
|
|
||||||
case environment: Environment if environment.node != null =>
|
|
||||||
environment.node.remove()
|
|
||||||
case _ => // Nothing special to do.
|
|
||||||
}
|
|
||||||
subBlock.breakBlock(world, x, y, z, blockId)
|
|
||||||
}
|
|
||||||
case _ => // Invalid but avoid match error.
|
case _ => // Invalid but avoid match error.
|
||||||
}
|
}
|
||||||
super.breakBlock(world, x, y, z, blockId, metadata)
|
super.breakBlock(world, x, y, z, blockId, metadata)
|
||||||
|
@ -10,7 +10,16 @@ import net.minecraftforge.common.ForgeDirection
|
|||||||
class Robot(val parent: SpecialDelegator) extends Computer with SpecialDelegate {
|
class Robot(val parent: SpecialDelegator) extends Computer with SpecialDelegate {
|
||||||
val unlocalizedName = "Robot"
|
val unlocalizedName = "Robot"
|
||||||
|
|
||||||
override def createTileEntity(world: World) = Some(new tileentity.Robot(world.isRemote))
|
var moving = new ThreadLocal[Option[tileentity.Robot]] {
|
||||||
|
override protected def initialValue = None
|
||||||
|
}
|
||||||
|
|
||||||
|
override def createTileEntity(world: World) = {
|
||||||
|
moving.get match {
|
||||||
|
case Some(robot) => Some(robot)
|
||||||
|
case _ => Some(new tileentity.Robot(world.isRemote))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
@ -47,4 +56,10 @@ class Robot(val parent: SpecialDelegator) extends Computer with SpecialDelegate
|
|||||||
}
|
}
|
||||||
else false
|
else false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def onBlockPreDestroy(world: World, x: Int, y: Int, z: Int) {
|
||||||
|
if (moving.get.isEmpty) {
|
||||||
|
super.onBlockPreDestroy(world, x, y, z)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
package li.cil.oc.common.tileentity
|
package li.cil.oc.common.tileentity
|
||||||
|
|
||||||
import cpw.mods.fml.relauncher.{SideOnly, Side}
|
import cpw.mods.fml.relauncher.{SideOnly, Side}
|
||||||
import li.cil.oc.Config
|
|
||||||
import li.cil.oc.api
|
|
||||||
import li.cil.oc.api.driver.Slot
|
import li.cil.oc.api.driver.Slot
|
||||||
import li.cil.oc.api.network._
|
import li.cil.oc.api.network._
|
||||||
import li.cil.oc.client.{PacketSender => ClientPacketSender}
|
import li.cil.oc.client.{PacketSender => ClientPacketSender}
|
||||||
import li.cil.oc.common
|
|
||||||
import li.cil.oc.server.component
|
|
||||||
import li.cil.oc.server.component.GraphicsCard
|
import li.cil.oc.server.component.GraphicsCard
|
||||||
import li.cil.oc.server.component.robot.Player
|
import li.cil.oc.server.component.robot.Player
|
||||||
import li.cil.oc.server.driver.Registry
|
import li.cil.oc.server.driver.Registry
|
||||||
|
import li.cil.oc.server.{PacketSender => ServerPacketSender, component}
|
||||||
import li.cil.oc.util.ExtendedNBT._
|
import li.cil.oc.util.ExtendedNBT._
|
||||||
|
import li.cil.oc.{Blocks, Config, api, common}
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
import net.minecraftforge.common.ForgeDirection
|
import net.minecraftforge.common.ForgeDirection
|
||||||
import scala.Some
|
import scala.Some
|
||||||
|
import scala.collection.convert.WrapAsScala._
|
||||||
|
|
||||||
class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with PowerInformation {
|
class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with PowerInformation {
|
||||||
def this() = this(false)
|
def this() = this(false)
|
||||||
@ -42,43 +41,83 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
}
|
}
|
||||||
else (null, null, null, null)
|
else (null, null, null, null)
|
||||||
|
|
||||||
|
var selectedSlot = 0
|
||||||
|
|
||||||
private lazy val player_ = new Player(this)
|
private lazy val player_ = new Player(this)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
def player(facing: ForgeDirection = facing, side: ForgeDirection = facing) = {
|
def player(facing: ForgeDirection = facing, side: ForgeDirection = facing) = {
|
||||||
assert(isServer)
|
assert(isServer)
|
||||||
player_.updatePositionAndRotation(facing, side)
|
player_.updatePositionAndRotation(facing, side)
|
||||||
player_
|
player_
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedSlot = 0
|
def actualSlot(n: Int) = n + 3
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
def move(nx: Int, ny: Int, nz: Int) = {
|
||||||
|
val (ox, oy, oz) = (x, y, z)
|
||||||
|
// Setting this will make the tile entity created via the following call
|
||||||
|
// to setBlock to re-use our "real" instance as the inner object, instead
|
||||||
|
// of creating a new one.
|
||||||
|
Blocks.robot.moving.set(Some(this))
|
||||||
|
// Do *not* immediately send the change to clients to allow checking if it
|
||||||
|
// worked before the client is notified so that we can use the same trick on
|
||||||
|
// the client by sending a corresponding packet. This also saves us from
|
||||||
|
// having to send the complete state again (e.g. screen buffer) each move.
|
||||||
|
val blockId = world.getBlockId(nx, ny, nz)
|
||||||
|
val metadata = world.getBlockMetadata(nx, ny, nz)
|
||||||
|
val created = world.setBlock(nx, ny, nz, getBlockType.blockID, getBlockMetadata, 1)
|
||||||
|
if (created) {
|
||||||
|
assert(world.getBlockTileEntity(nx, ny, nz) == this)
|
||||||
|
assert(x == nx && y == ny && z == nz)
|
||||||
|
if (isServer) {
|
||||||
|
ServerPacketSender.sendRobotMove(this, ox, oy, oz)
|
||||||
|
world.setBlock(ox, oy, oz, 0, 0, 1)
|
||||||
|
for (neighbor <- node.neighbors) {
|
||||||
|
node.disconnect(neighbor)
|
||||||
|
}
|
||||||
|
api.Network.joinOrCreateNetwork(world, nx, ny, nz)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (blockId > 0) {
|
||||||
|
world.playAuxSFX(2001, nx, ny, nz, blockId + (metadata << 12))
|
||||||
|
}
|
||||||
|
world.markBlockForUpdate(x, y, z)
|
||||||
|
world.setBlockToAir(ox, oy, oz)
|
||||||
|
}
|
||||||
|
assert(!isInvalid)
|
||||||
|
}
|
||||||
|
Blocks.robot.moving.set(None)
|
||||||
|
if (created) {
|
||||||
|
checkRedstoneInputChanged()
|
||||||
|
}
|
||||||
|
created
|
||||||
|
}
|
||||||
|
|
||||||
|
def animateMove(direction: ForgeDirection, duration: Double) {}
|
||||||
|
|
||||||
|
def animateTurn(oldFacing: ForgeDirection, duration: Double) {}
|
||||||
|
|
||||||
|
override def installedMemory = 64 * 1024
|
||||||
|
|
||||||
def tier = 0
|
def tier = 0
|
||||||
|
|
||||||
//def bounds =
|
//def bounds =
|
||||||
|
|
||||||
override def installedMemory = 64 * 1024
|
|
||||||
|
|
||||||
def actualSlot(n: Int) = n + 3
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
@LuaCallback("start")
|
@LuaCallback("start")
|
||||||
def start(context: Context, args: Arguments): Array[AnyRef] =
|
def start(context: Context, args: Arguments): Array[AnyRef] =
|
||||||
Array(Boolean.box(computer.start()))
|
result(computer.start())
|
||||||
|
|
||||||
@LuaCallback("stop")
|
@LuaCallback("stop")
|
||||||
def stop(context: Context, args: Arguments): Array[AnyRef] =
|
def stop(context: Context, args: Arguments): Array[AnyRef] =
|
||||||
Array(Boolean.box(computer.stop()))
|
result(computer.stop())
|
||||||
|
|
||||||
@LuaCallback(value = "isRunning", direct = true)
|
@LuaCallback(value = "isRunning", direct = true)
|
||||||
def isRunning(context: Context, args: Arguments): Array[AnyRef] =
|
def isRunning(context: Context, args: Arguments): Array[AnyRef] =
|
||||||
Array(Boolean.box(computer.isRunning))
|
result(computer.isRunning)
|
||||||
|
|
||||||
@LuaCallback(value = "isRobot", direct = true)
|
|
||||||
def isRobot(context: Context, args: Arguments): Array[AnyRef] =
|
|
||||||
Array(java.lang.Boolean.TRUE)
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
@ -92,24 +131,27 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
}
|
}
|
||||||
|
|
||||||
override def validate() {
|
override def validate() {
|
||||||
super.validate()
|
if (Blocks.robot.moving.get.isEmpty) {
|
||||||
if (isServer) {
|
super.validate()
|
||||||
items(0) match {
|
if (isServer) {
|
||||||
case Some(item) => player_.getAttributeMap.applyAttributeModifiers(item.getAttributeModifiers)
|
items(0) match {
|
||||||
case _ =>
|
case Some(item) => player_.getAttributeMap.applyAttributeModifiers(item.getAttributeModifiers)
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ClientPacketSender.sendScreenBufferRequest(this)
|
||||||
|
ClientPacketSender.sendRobotSelectedSlotRequest(this)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
ClientPacketSender.sendRotatableStateRequest(this)
|
|
||||||
ClientPacketSender.sendScreenBufferRequest(this)
|
|
||||||
ClientPacketSender.sendRobotSelectedSlotRequest(this)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def invalidate() {
|
override def invalidate() {
|
||||||
super.invalidate()
|
if (Blocks.robot.moving.get.isEmpty) {
|
||||||
if (currentGui.isDefined) {
|
super.invalidate()
|
||||||
Minecraft.getMinecraft.displayGuiScreen(null)
|
if (currentGui.isDefined) {
|
||||||
|
Minecraft.getMinecraft.displayGuiScreen(null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,16 +183,6 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
override def onMessage(message: Message) {
|
|
||||||
if (message.source.network == node.network) {
|
|
||||||
//computer.node.network.sendToReachable(message.source, message.name, message.data: _*)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(message.source.network == computer.node.network)
|
|
||||||
//node.network.sendToReachable(message.source, message.name, message.data: _*)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override def onConnect(node: Node) {
|
override def onConnect(node: Node) {
|
||||||
if (node == this.node) {
|
if (node == this.node) {
|
||||||
api.Network.joinNewNetwork(computer.node)
|
api.Network.joinNewNetwork(computer.node)
|
||||||
|
@ -59,6 +59,22 @@ object PacketSender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def sendRobotMove(t: Robot, ox: Int, oy: Int, oz: Int) {
|
||||||
|
val pb = new PacketBuilder(PacketType.RobotMove)
|
||||||
|
|
||||||
|
// Custom pb.writeTileEntity() with fake coordinates (valid for the client).
|
||||||
|
pb.writeInt(t.world.provider.dimensionId)
|
||||||
|
pb.writeInt(ox)
|
||||||
|
pb.writeInt(oy)
|
||||||
|
pb.writeInt(oz)
|
||||||
|
|
||||||
|
pb.writeInt(t.x)
|
||||||
|
pb.writeInt(t.y)
|
||||||
|
pb.writeInt(t.z)
|
||||||
|
|
||||||
|
pb.sendToAllPlayers()
|
||||||
|
}
|
||||||
|
|
||||||
def sendRobotSelectedSlotState(t: Robot, player: Option[Player] = None) {
|
def sendRobotSelectedSlotState(t: Robot, player: Option[Player] = None) {
|
||||||
val pb = new PacketBuilder(PacketType.RobotSelectedSlotResponse)
|
val pb = new PacketBuilder(PacketType.RobotSelectedSlotResponse)
|
||||||
|
|
||||||
|
@ -127,9 +127,12 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
val count = checkOptionalItemCount(args, 1)
|
val count = checkOptionalItemCount(args, 1)
|
||||||
// TODO inventory, if available
|
// TODO inventory, if available
|
||||||
|
|
||||||
result(robot.dropSlot(actualSlot(selectedSlot), count, facing))
|
// Don't drop using the fake player because he throws too far.
|
||||||
// This also works, but throws the items a little too far.
|
if (robot.dropSlot(actualSlot(selectedSlot), count, facing)) {
|
||||||
// result(robot.player().dropPlayerItemWithRandomChoice(robot.decrStackSize(actualSlot(selectedSlot), count), false) != null)
|
context.pause(Config.dropDelay)
|
||||||
|
result(true)
|
||||||
|
}
|
||||||
|
else result(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@LuaCallback("place")
|
@LuaCallback("place")
|
||||||
@ -160,6 +163,9 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
if (stack.stackSize <= 0) {
|
if (stack.stackSize <= 0) {
|
||||||
robot.setInventorySlotContents(player.robotInventory.selectedSlot, null)
|
robot.setInventorySlotContents(player.robotInventory.selectedSlot, null)
|
||||||
}
|
}
|
||||||
|
if (what) {
|
||||||
|
context.pause(Config.placeDelay)
|
||||||
|
}
|
||||||
result(what)
|
result(what)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +179,10 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
val stack = entity.getEntityItem
|
val stack = entity.getEntityItem
|
||||||
val size = stack.stackSize
|
val size = stack.stackSize
|
||||||
entity.onCollideWithPlayer(robot.player())
|
entity.onCollideWithPlayer(robot.player())
|
||||||
if (stack.stackSize < size || entity.isDead) return result(true)
|
if (stack.stackSize < size || entity.isDead) {
|
||||||
|
context.pause(Config.suckDelay)
|
||||||
|
return result(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result(false)
|
result(false)
|
||||||
}
|
}
|
||||||
@ -183,24 +192,8 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
@LuaCallback("detect")
|
@LuaCallback("detect")
|
||||||
def detect(context: Context, args: Arguments): Array[AnyRef] = {
|
def detect(context: Context, args: Arguments): Array[AnyRef] = {
|
||||||
val side = checkSideForAction(args, 0)
|
val side = checkSideForAction(args, 0)
|
||||||
val (bx, by, bz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
|
val (something, what) = blockContent(side)
|
||||||
val id = world.getBlockId(bx, by, bz)
|
result(something, what)
|
||||||
val block = Block.blocksList(id)
|
|
||||||
if (id == 0 || block == null || block.isAirBlock(world, bx, by, bz)) {
|
|
||||||
robot.player().closestLivingEntity(side) match {
|
|
||||||
case Some(entity) => result(true, "entity")
|
|
||||||
case _ => result(false, "air")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (FluidRegistry.lookupFluidForBlock(block) != null || block.isInstanceOf[BlockFluid]) {
|
|
||||||
result(false, "liquid")
|
|
||||||
}
|
|
||||||
else if (block.isBlockReplaceable(world, bx, by, bz)) {
|
|
||||||
result(false, "replaceable")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result(true, "solid")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
@ -219,9 +212,13 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
val what = hit.typeOfHit match {
|
val what = hit.typeOfHit match {
|
||||||
case EnumMovingObjectType.ENTITY =>
|
case EnumMovingObjectType.ENTITY =>
|
||||||
player.attackTargetEntityWithCurrentItem(hit.entityHit)
|
player.attackTargetEntityWithCurrentItem(hit.entityHit)
|
||||||
|
context.pause(Config.swingDelay)
|
||||||
result(true, "entity")
|
result(true, "entity")
|
||||||
case EnumMovingObjectType.TILE =>
|
case EnumMovingObjectType.TILE =>
|
||||||
val broke = player.clickBlock(hit.blockX, hit.blockY, hit.blockZ, hit.sideHit)
|
val broke = player.clickBlock(hit.blockX, hit.blockY, hit.blockZ, hit.sideHit)
|
||||||
|
if (broke) {
|
||||||
|
context.pause(Config.swingDelay)
|
||||||
|
}
|
||||||
result(broke, "block")
|
result(broke, "block")
|
||||||
}
|
}
|
||||||
what
|
what
|
||||||
@ -229,6 +226,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
player.closestLivingEntity(facing) match {
|
player.closestLivingEntity(facing) match {
|
||||||
case Some(entity) =>
|
case Some(entity) =>
|
||||||
player.attackTargetEntityWithCurrentItem(entity)
|
player.attackTargetEntityWithCurrentItem(entity)
|
||||||
|
context.pause(Config.swingDelay)
|
||||||
result(true, "entity")
|
result(true, "entity")
|
||||||
case _ =>
|
case _ =>
|
||||||
result(false)
|
result(false)
|
||||||
@ -247,9 +245,15 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
val player = robot.player(facing, side)
|
val player = robot.player(facing, side)
|
||||||
def activationResult(activationType: ActivationType.Value): Array[AnyRef] =
|
def activationResult(activationType: ActivationType.Value): Array[AnyRef] =
|
||||||
activationType match {
|
activationType match {
|
||||||
case ActivationType.BlockActivated => result(true, "block_activated")
|
case ActivationType.BlockActivated =>
|
||||||
case ActivationType.ItemPlaced => result(true, "item_placed")
|
context.pause(Config.useDelay)
|
||||||
case ActivationType.ItemUsed => result(true, "item_used")
|
result(true, "block_activated")
|
||||||
|
case ActivationType.ItemPlaced =>
|
||||||
|
context.pause(Config.useDelay)
|
||||||
|
result(true, "item_placed")
|
||||||
|
case ActivationType.ItemUsed =>
|
||||||
|
context.pause(Config.useDelay)
|
||||||
|
result(true, "item_used")
|
||||||
case _ => result(false)
|
case _ => result(false)
|
||||||
}
|
}
|
||||||
player.setSneaking(sneaky)
|
player.setSneaking(sneaky)
|
||||||
@ -269,7 +273,10 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
player.activateBlockOrUseItem(bx, by, bz, side.getOpposite.ordinal, hx, hy, hz)
|
player.activateBlockOrUseItem(bx, by, bz, side.getOpposite.ordinal, hx, hy, hz)
|
||||||
} else ActivationType.None) match {
|
} else ActivationType.None) match {
|
||||||
case ActivationType.None =>
|
case ActivationType.None =>
|
||||||
if (player.useEquippedItem()) result(true, "item_used")
|
if (player.useEquippedItem()) {
|
||||||
|
context.pause(Config.useDelay)
|
||||||
|
result(true, "item_used")
|
||||||
|
}
|
||||||
else result(false)
|
else result(false)
|
||||||
case activationType => activationResult(activationType)
|
case activationType => activationResult(activationType)
|
||||||
}
|
}
|
||||||
@ -290,44 +297,60 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def pick(facing: ForgeDirection, side: ForgeDirection, range: Double) = {
|
|
||||||
val (bx, by, bz) = (x + facing.offsetX, y + facing.offsetY, z + facing.offsetZ)
|
|
||||||
val (hx, hy, hz) = (0.5 + side.offsetX * range, 0.5 + side.offsetY * range, 0.5 + side.offsetZ * range)
|
|
||||||
val origin = Vec3.createVectorHelper(x + 0.5, y + 0.5, z + 0.5)
|
|
||||||
val target = Vec3.createVectorHelper(bx + hx, by + hy, bz + hz)
|
|
||||||
world.clip(origin, target)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
@LuaCallback("move")
|
@LuaCallback("move")
|
||||||
def move(context: Context, args: Arguments): Array[AnyRef] = {
|
def move(context: Context, args: Arguments): Array[AnyRef] = {
|
||||||
// Try to move in the specified direction.
|
val direction = checkSideForMovement(args, 0)
|
||||||
val side = checkSideForMovement(args, 0)
|
val (something, what) = blockContent(direction)
|
||||||
null
|
if (something) {
|
||||||
|
result(false, what)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val (nx, ny, nz) = (x + direction.offsetX, y + direction.offsetY, z + direction.offsetZ)
|
||||||
|
if (robot.move(nx, ny, nz)) {
|
||||||
|
robot.animateMove(direction, Config.moveDelay)
|
||||||
|
context.pause(Config.moveDelay)
|
||||||
|
result(true)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LuaCallback("turn")
|
@LuaCallback("turn")
|
||||||
def turn(context: Context, args: Arguments): Array[AnyRef] = {
|
def turn(context: Context, args: Arguments): Array[AnyRef] = {
|
||||||
val clockwise = args.checkBoolean(0)
|
val clockwise = args.checkBoolean(0)
|
||||||
|
val oldFacing = robot.facing
|
||||||
if (clockwise) robot.rotate(ForgeDirection.UP)
|
if (clockwise) robot.rotate(ForgeDirection.UP)
|
||||||
else robot.rotate(ForgeDirection.DOWN)
|
else robot.rotate(ForgeDirection.DOWN)
|
||||||
|
robot.animateTurn(oldFacing, 0.4)
|
||||||
|
context.pause(Config.turnDelay)
|
||||||
result(true)
|
result(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
private def haveSameItemType(stackA: ItemStack, stackB: ItemStack) =
|
private def blockContent(side: ForgeDirection) = {
|
||||||
stackA.itemID == stackB.itemID &&
|
val (bx, by, bz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
|
||||||
(!stackA.getHasSubtypes || stackA.getItemDamage == stackB.getItemDamage)
|
val id = world.getBlockId(bx, by, bz)
|
||||||
|
val block = Block.blocksList(id)
|
||||||
private def stackInSlot(slot: Int) = Option(robot.getStackInSlot(actualSlot(slot)))
|
if (id == 0 || block == null || block.isAirBlock(world, bx, by, bz)) {
|
||||||
|
robot.player().closestLivingEntity(side) match {
|
||||||
private def clickParamsFromHit(hit: MovingObjectPosition) = {
|
case Some(entity) => (true, "entity")
|
||||||
(hit.blockX, hit.blockY, hit.blockZ,
|
case _ => (false, "air")
|
||||||
(hit.hitVec.xCoord - hit.blockX).toFloat,
|
}
|
||||||
(hit.hitVec.yCoord - hit.blockY).toFloat,
|
}
|
||||||
(hit.hitVec.zCoord - hit.blockZ).toFloat)
|
else if (FluidRegistry.lookupFluidForBlock(block) != null || block.isInstanceOf[BlockFluid]) {
|
||||||
|
(false, "liquid")
|
||||||
|
}
|
||||||
|
else if (block.isBlockReplaceable(world, bx, by, bz)) {
|
||||||
|
(false, "replaceable")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(true, "solid")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private def clickParamsFromFacing(facing: ForgeDirection, side: ForgeDirection) = {
|
private def clickParamsFromFacing(facing: ForgeDirection, side: ForgeDirection) = {
|
||||||
@ -339,6 +362,29 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
0.5f - side.offsetZ * 0.5f)
|
0.5f - side.offsetZ * 0.5f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def pick(facing: ForgeDirection, side: ForgeDirection, range: Double) = {
|
||||||
|
val (bx, by, bz) = (x + facing.offsetX, y + facing.offsetY, z + facing.offsetZ)
|
||||||
|
val (hx, hy, hz) = (0.5 + side.offsetX * range, 0.5 + side.offsetY * range, 0.5 + side.offsetZ * range)
|
||||||
|
val origin = Vec3.createVectorHelper(x + 0.5, y + 0.5, z + 0.5)
|
||||||
|
val target = Vec3.createVectorHelper(bx + hx, by + hy, bz + hz)
|
||||||
|
world.clip(origin, target)
|
||||||
|
}
|
||||||
|
|
||||||
|
private def clickParamsFromHit(hit: MovingObjectPosition) = {
|
||||||
|
(hit.blockX, hit.blockY, hit.blockZ,
|
||||||
|
(hit.hitVec.xCoord - hit.blockX).toFloat,
|
||||||
|
(hit.hitVec.yCoord - hit.blockY).toFloat,
|
||||||
|
(hit.hitVec.zCoord - hit.blockZ).toFloat)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
private def haveSameItemType(stackA: ItemStack, stackB: ItemStack) =
|
||||||
|
stackA.itemID == stackB.itemID &&
|
||||||
|
(!stackA.getHasSubtypes || stackA.getItemDamage == stackB.getItemDamage)
|
||||||
|
|
||||||
|
private def stackInSlot(slot: Int) = Option(robot.getStackInSlot(actualSlot(slot)))
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
private def checkOptionalItemCount(args: Arguments, n: Int) =
|
private def checkOptionalItemCount(args: Arguments, n: Int) =
|
||||||
@ -357,7 +403,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
|
|
||||||
private def checkSideForAction(args: Arguments, n: Int) = checkSide(args, n, ForgeDirection.SOUTH, ForgeDirection.UP, ForgeDirection.DOWN)
|
private def checkSideForAction(args: Arguments, n: Int) = checkSide(args, n, ForgeDirection.SOUTH, ForgeDirection.UP, ForgeDirection.DOWN)
|
||||||
|
|
||||||
private def checkSideForMovement(args: Arguments, n: Int) = checkSide(args, n, ForgeDirection.SOUTH, ForgeDirection.NORTH)
|
private def checkSideForMovement(args: Arguments, n: Int) = checkSide(args, n, ForgeDirection.SOUTH, ForgeDirection.NORTH, ForgeDirection.UP, ForgeDirection.DOWN)
|
||||||
|
|
||||||
private def checkSide(args: Arguments, n: Int, allowed: ForgeDirection*) = {
|
private def checkSide(args: Arguments, n: Int, allowed: ForgeDirection*) = {
|
||||||
val side = args.checkInteger(n)
|
val side = args.checkInteger(n)
|
||||||
|
@ -247,7 +247,7 @@ object Network extends api.detail.NetworkAPI {
|
|||||||
case Some(node: MutableNode) => {
|
case Some(node: MutableNode) => {
|
||||||
for (side <- ForgeDirection.VALID_DIRECTIONS) {
|
for (side <- ForgeDirection.VALID_DIRECTIONS) {
|
||||||
getNetworkNode(world, x + side.offsetX, y + side.offsetY, z + side.offsetZ) match {
|
getNetworkNode(world, x + side.offsetX, y + side.offsetY, z + side.offsetZ) match {
|
||||||
case Some(neighbor) =>
|
case Some(neighbor: MutableNode) if neighbor != node =>
|
||||||
if (neighbor.network != null) {
|
if (neighbor.network != null) {
|
||||||
neighbor.connect(node)
|
neighbor.connect(node)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user