cleaned up the robot implementation, removing some ugly cross-references, inheritance and dependencies, will require to be rebooted if they already loaded the robot module

This commit is contained in:
Florian Nücke 2014-03-05 00:44:55 +01:00
parent 28a12d08b6
commit c00233023b
19 changed files with 213 additions and 125 deletions

View File

@ -57,6 +57,22 @@ public interface Machine extends ManagedEnvironment, Context {
*/
int componentCount();
/**
* Gets the amount of energy this machine consumes per tick when it is
* running.
*
* @return the energy consumed per tick by the machine.
*/
double getCostPerTick();
/**
* Sets the amount of energy this machine consumes per tick when it is
* running.
*
* @param value the energy consumed per tick by the machine.
*/
void setCostPerTick(double value);
/**
* The address of the file system that holds the machine's file system for
* temporary files (tmpfs). This may return <tt>null</tt> if either the
@ -203,11 +219,4 @@ public interface Machine extends ManagedEnvironment, Context {
* @return whether the player was removed from the user list.
*/
boolean removeUser(String name);
/**
* This is only here because of some sub-optimal design decisions for the
* internal robot implementation, it will go away. Do not use.
*/
@Deprecated
boolean isRobot();
}

View File

@ -0,0 +1,55 @@
package li.cil.oc.api.machine;
import net.minecraft.entity.player.EntityPlayer;
/**
* This interface allows interaction with robots.
* <p/>
* It is intended to be used by components when installed in a robot. In that
* case, the robot in question is the tile entity passed to item driver when
* asked to create the component's environment.
*/
public interface Robot {
/**
* Returns the fake player used to represent the robot as an entity for
* certain actions that require one.
* <p/>
* This will automatically be positioned and rotated to represent the
* robot's current position and rotation in the world. Use this to trigger
* events involving the robot that require a player entity, and for
* interacting with the robots' inventory.
* <p/>
* Note that the inventory of each robot is structured such that the first
* four slots are the "equipment" slots, from left to right, i.e. slot one
* is the tool slot, slot two is the card slot, three the disk slot and
* slot four is for upgrades. The inventory proper starts after that.
*
* @return the fake player for the robot.
*/
EntityPlayer player();
/**
* Gets the index of the currently selected slot in the robot's inventory.
*
* @return the index of the currently selected slot.
*/
int selectedSlot();
/**
* Causes the currently installed upgrade to be saved and synchronized.
* <p/>
* If no upgrade is installed in the robot this does nothing.
* <p/>
* This is intended for upgrade components, to allow them to update their
* client side representation for rendering purposes. The component will be
* saved to its item's NBT tag compound, as it would be when the game is
* saved, and then re-sent to the client. Keep the number of calls to this
* function low, since each call causes a network packet to be sent.
* <p/>
* This is somewhat of a 'meh, it works' approach that I'm not really happy
* with and plan to replace with something cleaner. Don't use unless you
* absolutely really have to.
*/
@Deprecated
void saveUpgrade();
}

View File

@ -1,7 +1,15 @@
package li.cil.oc.api.network;
import li.cil.oc.api.machine.Robot;
import net.minecraft.entity.player.EntityPlayer;
/**
* This is no longer used nor provided to callbacks. The context in a callback
* will always be the one of a machine. To get access to a robot either use
* its tile entity where possible (which implements {@link Robot}) or use
* <tt>(Robot)((Machine)context).owner()</tt>.
*/
@Deprecated
public interface RobotContext extends Context {
/**
* Gets the index of the currently selected slot in the robot's inventory.

View File

@ -37,5 +37,5 @@
@cpw.mods.fml.common.API(
owner = "OpenComputers|Core",
provides = "OpenComputersAPI",
apiVersion = "1.4.1")
apiVersion = "1.4.2")
package li.cil.oc.api;

View File

@ -34,7 +34,7 @@ class Charger extends Environment with RedstoneAware with Analyzable {
val charge = Settings.get.chargeRate * chargeSpeed
robots.collect {
case Some(proxy) => node.changeBuffer(proxy.robot.node.changeBuffer(charge + node.changeBuffer(-charge)))
case Some(proxy) => node.changeBuffer(proxy.robot.bot.node.changeBuffer(charge + node.changeBuffer(-charge)))
}
}
else if (chargeSpeed > 0 && world.getWorldInfo.getWorldTotalTime % 10 == 0) {

View File

@ -18,11 +18,11 @@ import stargatetech2.api.bus.IBusDevice
// See AbstractBusAware as to why we have to define the IBusDevice here.
@Optional.Interface(iface = "stargatetech2.api.bus.IBusDevice", modid = "StargateTech2")
abstract class Computer(isRemote: Boolean) extends Environment with ComponentInventory with Rotatable with BundledRedstoneAware with AbstractBusAware with IBusDevice with Analyzable with Owner {
protected val _computer = if (isRemote) null else Machine.create(this)
private lazy val _computer = if (isRemote) null else Machine.create(this)
def computer = _computer
override def node = if (isClient) null else computer.node
override def node = if (isServer) computer.node else null
override lazy val isClient = computer == null

View File

@ -24,8 +24,11 @@ import net.minecraftforge.common.ForgeDirection
// robot moves we only create a new proxy tile entity, hook the instance of this
// class that was held by the old proxy to it and can then safely forget the
// old proxy, which will be cleaned up by Minecraft like any other tile entity.
class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory with Buffer with PowerInformation with RobotContext {
class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory with Buffer with PowerInformation with api.machine.Robot {
def this() = this(false)
if (isServer) {
computer.setCostPerTick(Settings.get.robotCost)
}
var proxy: RobotProxy = _
@ -51,13 +54,13 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
// ----------------------------------------------------------------------- //
override def node: ComponentConnector = if (isClient) null else computer.node.asInstanceOf[ComponentConnector]
override def node = if (isServer) computer.node else null
override val _buffer = new common.component.Buffer(this) {
override def maxResolution = (48, 14)
}
override val _computer = if (isRemote) null else new robot.Robot(this)
val (gpu, keyboard) = if (isServer) {
val (bot, gpu, keyboard) = if (isServer) {
val bot = new robot.Robot(this)
val gpu = new GraphicsCard.Tier1 {
override val maxResolution = (48, 14)
}
@ -66,9 +69,9 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
world.getBlockTileEntity(x, y, z) == proxy &&
p.getDistanceSq(x + 0.5, y + 0.5, z + 0.5) <= 64
}
(gpu, keyboard)
(bot, gpu, keyboard)
}
else (null, null)
else (null, null, null)
var owner = "OpenComputers"
@ -115,7 +118,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
// pow(xp(level) - base, 1/exp) / const = level
level = math.min((Math.pow(xp - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt, 30)
if (isServer) {
node.setLocalBufferSize(Settings.get.bufferRobot + Settings.get.bufferPerLevel * level)
bot.node.setLocalBufferSize(Settings.get.bufferRobot + Settings.get.bufferPerLevel * level)
}
}
@ -209,7 +212,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
if (stack.hasTagCompound) {
xp = stack.getTagCompound.getDouble(Settings.namespace + "xp")
updateXpInfo()
node.changeBuffer(stack.getTagCompound.getInteger(Settings.namespace + "storedEnergy"))
bot.node.changeBuffer(stack.getTagCompound.getInteger(Settings.namespace + "storedEnergy"))
}
}
@ -270,9 +273,11 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
// ----------------------------------------------------------------------- //
override def updateEntity() {
if (!addedToNetwork) {
if (isServer && !addedToNetwork) {
addedToNetwork = true
api.Network.joinNewNetwork(node)
// For upgrading from when the energy was stored by the machine's node.
node.asInstanceOf[Connector].setLocalBufferSize(0)
}
if (animationTicksLeft > 0) {
animationTicksLeft -= 1
@ -287,8 +292,8 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
super.updateEntity()
if (isServer) {
gpu.update()
globalBuffer = node.globalBuffer
globalBufferSize = node.globalBufferSize
globalBuffer = bot.node.globalBuffer
globalBufferSize = bot.node.globalBufferSize
updatePowerInformation()
if (xpChanged && world.getWorldInfo.getWorldTotalTime % 200 == 0) {
xpChanged = false
@ -321,6 +326,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
buffer.load(nbt.getCompoundTag(Settings.namespace + "buffer"))
gpu.load(nbt.getCompoundTag(Settings.namespace + "gpu"))
keyboard.load(nbt.getCompoundTag(Settings.namespace + "keyboard"))
bot.load(nbt.getCompoundTag(Settings.namespace + "robot"))
if (nbt.hasKey(Settings.namespace + "owner")) {
owner = nbt.getString(Settings.namespace + "owner")
}
@ -345,6 +351,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
nbt.setNewCompoundTag(Settings.namespace + "buffer", buffer.save)
nbt.setNewCompoundTag(Settings.namespace + "gpu", gpu.save)
nbt.setNewCompoundTag(Settings.namespace + "keyboard", keyboard.save)
nbt.setNewCompoundTag(Settings.namespace + "robot", bot.save)
nbt.setString(Settings.namespace + "owner", owner)
nbt.setDouble(Settings.namespace + "xp", xp)
nbt.setInteger(Settings.namespace + "selectedSlot", selectedSlot)
@ -418,6 +425,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
override def onMachineConnect(node: Node) {
super.onConnect(node)
if (node == this.node) {
node.connect(bot.node)
node.connect(buffer.node)
node.connect(gpu.node)
buffer.node.connect(keyboard.node)
@ -441,6 +449,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
node.remove()
gpu.node.remove()
keyboard.node.remove()
bot.node.remove()
}
}

View File

@ -14,7 +14,7 @@ import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.ForgeDirection
class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with ISidedInventory with Buffer with PowerInformation with RobotContext {
class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with ISidedInventory with Buffer with PowerInformation with api.machine.Robot {
def this() = this(new Robot(false))
// ----------------------------------------------------------------------- //
@ -23,8 +23,6 @@ class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with ISidedI
withComponent("robot", Visibility.Neighbors).
create()
override protected val _computer = null
override def computer = robot.computer
override def maxComponents = robot.maxComponents

View File

@ -2,25 +2,26 @@ package li.cil.oc.server.component
import cpw.mods.fml.common.registry.GameRegistry
import li.cil.oc.api.Network
import li.cil.oc.api.machine.Robot
import li.cil.oc.api.network._
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.{Container, InventoryCrafting}
import net.minecraft.item.ItemStack
import net.minecraft.item.crafting.CraftingManager
import net.minecraft.tileentity.{TileEntity => MCTileEntity}
import net.minecraft.tileentity.TileEntity
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent
import scala.collection.mutable
class UpgradeCrafting(val owner: MCTileEntity) extends ManagedComponent {
class UpgradeCrafting(val owner: TileEntity with Robot) extends ManagedComponent {
val node = Network.newNode(this, Visibility.Network).
withComponent("crafting").
create()
@Callback(doc = """function([count:number]):number -- Tries to craft the specified number of items in the top left area of the inventory.""")
def craft(context: RobotContext, args: Arguments): Array[AnyRef] = {
def craft(context: Context, args: Arguments): Array[AnyRef] = {
val count = if (args.count > 0) args.checkInteger(0) else Int.MaxValue
result(CraftingInventory.craft(context, count))
result(CraftingInventory.craft(count))
}
private object CraftingInventory extends InventoryCrafting(new Container {
@ -28,15 +29,15 @@ class UpgradeCrafting(val owner: MCTileEntity) extends ManagedComponent {
}, 3, 3) {
var amountPossible = 0
def craft(context: RobotContext, wantedCount: Int): Boolean = {
load(context)
def craft(wantedCount: Int): Boolean = {
load()
val manager = CraftingManager.getInstance
val result = manager.findMatchingRecipe(CraftingInventory, owner.getWorldObj)
if (result == null) return false
val targetStackSize = if (result.isStackable) math.min(wantedCount, result.getMaxStackSize) else result.stackSize
val timesCrafted = math.min(targetStackSize / result.stackSize, amountPossible)
if (timesCrafted <= 0) return true
GameRegistry.onItemCrafted(context.player, result, this)
GameRegistry.onItemCrafted(owner.player, result, this)
val surplus = mutable.ArrayBuffer.empty[ItemStack]
for (slot <- 0 until getSizeInventory) {
val stack = getStackInSlot(slot)
@ -46,7 +47,7 @@ class UpgradeCrafting(val owner: MCTileEntity) extends ManagedComponent {
if (item.hasContainerItem) {
val container = item.getContainerItemStack(stack)
if (container.isItemStackDamageable && container.getItemDamage > container.getMaxDamage) {
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(context.player, container))
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(owner.player, container))
}
else if (container.getItem.doesContainerItemLeaveCraftingGrid(container) || getStackInSlot(slot) != null) {
surplus += container
@ -58,9 +59,9 @@ class UpgradeCrafting(val owner: MCTileEntity) extends ManagedComponent {
}
}
}
save(context)
save()
result.stackSize *= timesCrafted
val inventory = context.player.inventory
val inventory = owner.player.inventory
inventory.addItemStackToInventory(result)
for (stack <- surplus) {
inventory.addItemStackToInventory(stack)
@ -68,8 +69,8 @@ class UpgradeCrafting(val owner: MCTileEntity) extends ManagedComponent {
true
}
def load(context: RobotContext) {
val inventory = context.player.inventory
def load() {
val inventory = owner.player.inventory
amountPossible = Int.MaxValue
for (slot <- 0 until getSizeInventory) {
val stack = inventory.getStackInSlot(toParentSlot(slot))
@ -80,8 +81,8 @@ class UpgradeCrafting(val owner: MCTileEntity) extends ManagedComponent {
}
}
def save(context: RobotContext) {
val inventory = context.player.inventory
def save() {
val inventory = owner.player.inventory
for (slot <- 0 until getSizeInventory) {
inventory.setInventorySlotContents(toParentSlot(slot), getStackInSlot(slot))
}

View File

@ -1,6 +1,7 @@
package li.cil.oc.server.component
import li.cil.oc.api.Network
import li.cil.oc.api.machine.Robot
import li.cil.oc.api.network._
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.{OpenComputers, api, Settings}
@ -9,7 +10,7 @@ import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.{TileEntity, TileEntityFurnace}
class UpgradeGenerator(val owner: TileEntity) extends ManagedComponent {
class UpgradeGenerator(val owner: TileEntity with Robot) extends ManagedComponent {
val node = Network.newNode(this, Visibility.Network).
withComponent("generator", Visibility.Neighbors).
withConnector().
@ -25,10 +26,10 @@ class UpgradeGenerator(val owner: TileEntity) extends ManagedComponent {
// ----------------------------------------------------------------------- //
@Callback(doc = """function([count:number]):boolean -- Tries to insert fuel from the selected slot into the generator's queue.""")
def insert(context: RobotContext, args: Arguments): Array[AnyRef] = {
def insert(context: Context, args: Arguments): Array[AnyRef] = {
val count = if (args.count > 0) args.checkInteger(0) else 64
val player = context.player
val stack = player.inventory.getStackInSlot(context.selectedSlot)
val player = owner.player
val stack = player.inventory.getStackInSlot(owner.selectedSlot)
if (stack == null) return result(Unit, "selected slot is empty")
if (!TileEntityFurnace.isItemFuel(stack)) {
return result(Unit, "selected slot does not contain fuel")
@ -49,7 +50,7 @@ class UpgradeGenerator(val owner: TileEntity) extends ManagedComponent {
case _ =>
inventory = Some(stack.splitStack(math.min(stack.stackSize, count)))
}
player.inventory.setInventorySlotContents(context.selectedSlot, stack)
player.inventory.setInventorySlotContents(owner.selectedSlot, stack)
result(true)
}
@ -62,12 +63,12 @@ class UpgradeGenerator(val owner: TileEntity) extends ManagedComponent {
}
@Callback(doc = """function([count:number]):boolean -- Tries to remove items from the generator's queue.""")
def remove(context: RobotContext, args: Arguments): Array[AnyRef] = {
def remove(context: Context, args: Arguments): Array[AnyRef] = {
val count = if (args.count > 0) args.checkInteger(0) else Int.MaxValue
inventory match {
case Some(stack) =>
val removedStack = stack.splitStack(math.min(count, stack.stackSize))
val success = context.player.inventory.addItemStackToInventory(removedStack)
val success = owner.player.inventory.addItemStackToInventory(removedStack)
stack.stackSize += removedStack.stackSize
if (success && stack.stackSize <= 0) {
inventory = None
@ -101,10 +102,7 @@ class UpgradeGenerator(val owner: TileEntity) extends ManagedComponent {
}
}
private def updateClient() = owner match {
case robot: RobotContext => robot.saveUpgrade()
case _ =>
}
private def updateClient() = owner.saveUpgrade()
// ----------------------------------------------------------------------- //

View File

@ -248,7 +248,8 @@ class LuaJLuaArchitecture(machine: api.machine.Machine) extends LuaArchitecture(
})
// Are we a robot? (No this is not a CAPTCHA.)
computer.set("isRobot", (_: Varargs) => LuaValue.valueOf(machine.isRobot))
// TODO deprecate this
computer.set("isRobot", (_: Varargs) => LuaValue.valueOf(machine.components.contains("robot")))
computer.set("freeMemory", (_: Varargs) => LuaValue.valueOf(memory / 2))

View File

@ -24,7 +24,7 @@ import scala.collection.mutable
class Machine(val owner: Owner, constructor: Constructor[_ <: Architecture]) extends ManagedComponent with machine.Machine with Runnable {
val node = Network.newNode(this, Visibility.Network).
withComponent("computer", Visibility.Neighbors).
withConnector(if (isRobot) Settings.get.bufferRobot + 30 * Settings.get.bufferPerLevel else Settings.get.bufferComputer).
withConnector(Settings.get.bufferComputer).
create()
val tmp = if (Settings.get.tmpSize > 0) {
@ -48,13 +48,13 @@ class Machine(val owner: Owner, constructor: Constructor[_ <: Architecture]) ext
// ----------------------------------------------------------------------- //
private[component] var timeStarted = 0L // Game-world time [ms] for os.uptime().
private var timeStarted = 0L // Game-world time [ms] for os.uptime().
var worldTime = 0L // Game-world time for os.time().
private[component] var cpuTotal = 0L // Pseudo-real-world time [ns] for os.clock().
private var cpuTotal = 0L // Pseudo-real-world time [ns] for os.clock().
private[component] var cpuStart = 0L // Pseudo-real-world time [ns] for os.clock().
private var cpuStart = 0L // Pseudo-real-world time [ns] for os.clock().
private var remainIdle = 0 // Ticks left to sleep before resuming.
@ -62,30 +62,32 @@ class Machine(val owner: Owner, constructor: Constructor[_ <: Architecture]) ext
private var usersChanged = false // Send updated users list to clients?
private[component] var message: Option[String] = None // For error messages.
private var message: Option[String] = None // For error messages.
private var cost = Settings.get.computerCost * Settings.get.tickFrequency
// ----------------------------------------------------------------------- //
def lastError = message.orNull
override def components = scala.collection.convert.WrapAsJava.mapAsJavaMap(_components)
override def users = _users.synchronized(_users.toArray)
override def tmpAddress = tmp.fold(null: String)(_.node.address)
override def upTime() = (worldTime - timeStarted) / 20.0
override def cpuTime = (cpuTotal + (System.nanoTime() - cpuStart)) * 10e-10
def isRobot = false
private val cost = (if (isRobot) Settings.get.robotCost else Settings.get.computerCost) * Settings.get.tickFrequency
def componentCount = _components.count {
case (_, name) => name != "filesystem"
} + addedComponents.count(_.name != "filesystem") - 1 // -1 = this computer
override def tmpAddress = tmp.fold(null: String)(_.node.address)
def lastError = message.orNull
override def setCostPerTick(value: Double) = cost = value * Settings.get.tickFrequency
override def getCostPerTick = cost / Settings.get.tickFrequency
override def users = _users.synchronized(_users.toArray)
override def upTime() = (worldTime - timeStarted) / 20.0
override def cpuTime = (cpuTotal + (System.nanoTime() - cpuStart)) * 10e-10
// ----------------------------------------------------------------------- //
override def address = node.address

View File

@ -295,8 +295,9 @@ class NativeLuaArchitecture(machine: api.machine.Machine) extends LuaArchitectur
lua.setField(-2, "address")
// Are we a robot? (No this is not a CAPTCHA.)
// TODO deprecate this
lua.pushScalaFunction(lua => {
lua.pushBoolean(machine.isRobot)
lua.pushBoolean(machine.components.contains("robot"))
1
})
lua.setField(-2, "isRobot")

View File

@ -368,7 +368,7 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Sett
override def addExhaustion(amount: Float) {
if (Settings.get.robotExhaustionCost > 0) {
robot.node.changeBuffer(-Settings.get.robotExhaustionCost * amount)
robot.bot.node.changeBuffer(-Settings.get.robotExhaustionCost * amount)
}
robot.addXp(Settings.get.robotExhaustionXpRate * amount)
}

View File

@ -3,7 +3,7 @@ package li.cil.oc.server.component.robot
import li.cil.oc.api
import li.cil.oc.api.network._
import li.cil.oc.common.tileentity
import li.cil.oc.server.component.machine.Machine
import li.cil.oc.server.component.ManagedComponent
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.{OpenComputers, Settings}
@ -19,8 +19,12 @@ import net.minecraftforge.common.ForgeDirection
import net.minecraftforge.fluids.FluidRegistry
import scala.collection.convert.WrapAsScala._
// TODO rework this so as not to extend machine but be an extra component instead
class Robot(val robot: tileentity.Robot) extends Machine(robot, api.Machine.LuaArchitecture.getConstructor(classOf[api.machine.Machine])) with RobotContext {
class Robot(val robot: tileentity.Robot) extends ManagedComponent {
val node = api.Network.newNode(this, Visibility.Neighbors).
withComponent("robot").
withConnector(Settings.get.bufferRobot + 30 * Settings.get.bufferPerLevel).
create()
def actualSlot(n: Int) = robot.actualSlot(n)
def world = robot.world
@ -36,8 +40,6 @@ class Robot(val robot: tileentity.Robot) extends Machine(robot, api.Machine.LuaA
val romRobot = Option(api.FileSystem.asManagedEnvironment(api.FileSystem.
fromClass(OpenComputers.getClass, Settings.resourceDomain, "lua/component/robot"), "robot"))
override def isRobot = true
def selectedSlot = robot.selectedSlot
def player = robot.player()
@ -501,7 +503,7 @@ class Robot(val robot: tileentity.Robot) extends Machine(robot, api.Machine.LuaA
result(Unit, what)
}
else {
if (!robot.node.tryChangeBuffer(-Settings.get.robotMoveCost)) {
if (!node.tryChangeBuffer(-Settings.get.robotMoveCost)) {
result(Unit, "not enough energy")
}
else if (robot.move(direction)) {
@ -510,7 +512,7 @@ class Robot(val robot: tileentity.Robot) extends Machine(robot, api.Machine.LuaA
result(true)
}
else {
robot.node.changeBuffer(Settings.get.robotMoveCost)
node.changeBuffer(Settings.get.robotMoveCost)
result(Unit, "impossible move")
}
}
@ -520,7 +522,7 @@ class Robot(val robot: tileentity.Robot) extends Machine(robot, api.Machine.LuaA
@Callback
def turn(context: Context, args: Arguments): Array[AnyRef] = {
val clockwise = args.checkBoolean(0)
if (robot.node.tryChangeBuffer(-Settings.get.robotTurnCost)) {
if (node.tryChangeBuffer(-Settings.get.robotTurnCost)) {
if (clockwise) robot.rotate(ForgeDirection.UP)
else robot.rotate(ForgeDirection.DOWN)
robot.animateTurn(clockwise, Settings.get.turnDelay)
@ -537,7 +539,10 @@ class Robot(val robot: tileentity.Robot) extends Machine(robot, api.Machine.LuaA
override def onConnect(node: Node) {
super.onConnect(node)
if (node == this.node) {
romRobot.foreach(rom => node.connect(rom.node))
romRobot.foreach(fs => {
fs.node.asInstanceOf[Component].setVisibility(Visibility.Network)
node.connect(fs.node)
})
}
}
@ -550,7 +555,7 @@ class Robot(val robot: tileentity.Robot) extends Machine(robot, api.Machine.LuaA
override def save(nbt: NBTTagCompound) {
super.save(nbt)
romRobot.foreach(rom => nbt.setNewCompoundTag("romRobot", rom.save))
romRobot.foreach(fs => nbt.setNewCompoundTag("romRobot", fs.save))
}
// ----------------------------------------------------------------------- //

View File

@ -2,14 +2,19 @@ package li.cil.oc.server.driver.item
import li.cil.oc.Items
import li.cil.oc.api.driver.Slot
import li.cil.oc.api.machine.Robot
import li.cil.oc.server.component
import net.minecraft.item.ItemStack
import net.minecraft.tileentity.{TileEntity => MCTileEntity}
import net.minecraft.tileentity.TileEntity
object UpgradeCrafting extends Item {
override def worksWith(stack: ItemStack) = isOneOf(stack, Items.upgradeCrafting)
override def createEnvironment(stack: ItemStack, container: MCTileEntity) = new component.UpgradeCrafting(container)
override def createEnvironment(stack: ItemStack, container: TileEntity) =
container match {
case robot: Robot => new component.UpgradeCrafting(robot)
case _ => null
}
override def slot(stack: ItemStack) = Slot.Upgrade
}

View File

@ -4,6 +4,7 @@ import cpw.mods.fml.common.FMLCommonHandler
import cpw.mods.fml.relauncher.Side
import java.lang.reflect.{Modifier, Method, InvocationTargetException}
import li.cil.oc.OpenComputers
import li.cil.oc.api.machine.Robot
import li.cil.oc.api.network
import li.cil.oc.api.network.{Node => ImmutableNode, _}
import li.cil.oc.server.component.machine.Machine
@ -164,7 +165,7 @@ object Component {
ms.filter(_.isAnnotationPresent(classOf[network.Callback])).foreach(m =>
if (m.getParameterTypes.size != 2 ||
(m.getParameterTypes()(0) != classOf[Context] && m.getParameterTypes()(0) != classOf[RobotContext]) ||
(m.getParameterTypes()(0) != classOf[Context] && m.getParameterTypes()(0) != classOf[Robot]) ||
m.getParameterTypes()(1) != classOf[Arguments]) {
OpenComputers.log.severe("Invalid use of Callback annotation on %s.%s: invalid argument types or count.".format(m.getDeclaringClass.getName, m.getName))
}

View File

@ -113,7 +113,7 @@ trait Connector extends network.Connector with Node {
override def load(nbt: NBTTagCompound) {
super.load(nbt)
localBuffer = math.min(nbt.getDouble("buffer"), math.max(0, localBufferSize))
localBuffer = nbt.getDouble("buffer")
}
override def save(nbt: NBTTagCompound) {

View File

@ -1,185 +1,180 @@
local component = require("component")
local computer = require("computer")
local sides = require("sides")
if not computer.isRobot() then
error("not a robot")
end
local robot = {}
-------------------------------------------------------------------------------
-- General
function robot.level()
return component.computer.level()
return component.robot.level()
end
-------------------------------------------------------------------------------
-- World
function robot.detect()
return component.computer.detect(sides.front)
return component.robot.detect(sides.front)
end
function robot.detectUp()
return component.computer.detect(sides.up)
return component.robot.detect(sides.up)
end
function robot.detectDown()
return component.computer.detect(sides.down)
return component.robot.detect(sides.down)
end
-------------------------------------------------------------------------------
-- Inventory
function robot.select(slot)
return component.computer.select(slot)
return component.robot.select(slot)
end
function robot.count(slot)
return component.computer.count(slot)
return component.robot.count(slot)
end
function robot.space(slot)
return component.computer.space(slot)
return component.robot.space(slot)
end
function robot.compareTo(slot)
return component.computer.compareTo(slot)
return component.robot.compareTo(slot)
end
function robot.transferTo(slot, count)
return component.computer.transferTo(slot, count)
return component.robot.transferTo(slot, count)
end
-------------------------------------------------------------------------------
-- Inventory + World
function robot.compare()
return component.computer.compare(sides.front)
return component.robot.compare(sides.front)
end
function robot.compareUp()
return component.computer.compare(sides.up)
return component.robot.compare(sides.up)
end
function robot.compareDown()
return component.computer.compare(sides.down)
return component.robot.compare(sides.down)
end
function robot.drop(count)
checkArg(1, count, "nil", "number")
return component.computer.drop(sides.front, count)
return component.robot.drop(sides.front, count)
end
function robot.dropUp(count)
checkArg(1, count, "nil", "number")
return component.computer.drop(sides.up, count)
return component.robot.drop(sides.up, count)
end
function robot.dropDown(count)
checkArg(1, count, "nil", "number")
return component.computer.drop(sides.down, count)
return component.robot.drop(sides.down, count)
end
function robot.place(side, sneaky)
checkArg(1, side, "nil", "number")
return component.computer.place(sides.front, side, sneaky ~= nil and sneaky ~= false)
return component.robot.place(sides.front, side, sneaky ~= nil and sneaky ~= false)
end
function robot.placeUp(side, sneaky)
checkArg(1, side, "nil", "number")
return component.computer.place(sides.up, side, sneaky ~= nil and sneaky ~= false)
return component.robot.place(sides.up, side, sneaky ~= nil and sneaky ~= false)
end
function robot.placeDown(side, sneaky)
checkArg(1, side, "nil", "number")
return component.computer.place(sides.down, side, sneaky ~= nil and sneaky ~= false)
return component.robot.place(sides.down, side, sneaky ~= nil and sneaky ~= false)
end
function robot.suck(count)
checkArg(1, count, "nil", "number")
return component.computer.suck(sides.front, count)
return component.robot.suck(sides.front, count)
end
function robot.suckUp(count)
checkArg(1, count, "nil", "number")
return component.computer.suck(sides.up, count)
return component.robot.suck(sides.up, count)
end
function robot.suckDown(count)
checkArg(1, count, "nil", "number")
return component.computer.suck(sides.down, count)
return component.robot.suck(sides.down, count)
end
-------------------------------------------------------------------------------
-- Tool
function robot.durability()
return component.computer.durability()
return component.robot.durability()
end
function robot.swing(side, sneaky)
checkArg(1, side, "nil", "number")
return component.computer.swing(sides.front, side, sneaky ~= nil and sneaky ~= false)
return component.robot.swing(sides.front, side, sneaky ~= nil and sneaky ~= false)
end
function robot.swingUp(side, sneaky)
checkArg(1, side, "nil", "number")
return component.computer.swing(sides.up, side, sneaky ~= nil and sneaky ~= false)
return component.robot.swing(sides.up, side, sneaky ~= nil and sneaky ~= false)
end
function robot.swingDown(side, sneaky)
checkArg(1, side, "nil", "number")
return component.computer.swing(sides.down, side, sneaky ~= nil and sneaky ~= false)
return component.robot.swing(sides.down, side, sneaky ~= nil and sneaky ~= false)
end
function robot.use(side, sneaky, duration)
checkArg(1, side, "nil", "number")
checkArg(3, duration, "nil", "number")
return component.computer.use(sides.front, side, sneaky ~= nil and sneaky ~= false, duration)
return component.robot.use(sides.front, side, sneaky ~= nil and sneaky ~= false, duration)
end
function robot.useUp(side, sneaky, duration)
checkArg(1, side, "nil", "number")
checkArg(3, duration, "nil", "number")
return component.computer.use(sides.up, side, sneaky ~= nil and sneaky ~= false, duration)
return component.robot.use(sides.up, side, sneaky ~= nil and sneaky ~= false, duration)
end
function robot.useDown(side, sneaky, duration)
checkArg(1, side, "nil", "number")
checkArg(3, duration, "nil", "number")
return component.computer.use(sides.down, side, sneaky ~= nil and sneaky ~= false, duration)
return component.robot.use(sides.down, side, sneaky ~= nil and sneaky ~= false, duration)
end
-------------------------------------------------------------------------------
-- Movement
function robot.forward()
return component.computer.move(sides.front)
return component.robot.move(sides.front)
end
function robot.back()
return component.computer.move(sides.back)
return component.robot.move(sides.back)
end
function robot.up()
return component.computer.move(sides.up)
return component.robot.move(sides.up)
end
function robot.down()
return component.computer.move(sides.down)
return component.robot.move(sides.down)
end
function robot.turnLeft()
return component.computer.turn(false)
return component.robot.turn(false)
end
function robot.turnRight()
return component.computer.turn(true)
return component.robot.turn(true)
end
function robot.turnAround()