blob: 52fff5377da9dd9e9fdcdb5a40e3260ba125bf18 [file] [log] [blame] [raw]
package li.cil.oc.server.component
import java.lang.reflect.InvocationTargetException
import li.cil.oc.api
import li.cil.oc.api.network._
import net.minecraft.nbt.NBTTagCompound
import scala.Some
import scala.language.existentials
class Carriage(controller: Object) extends ManagedComponent {
val node = api.Network.newNode(this, Visibility.Network).
withComponent("carriage").
create()
private val (directions, setup, move) = try {
val directions = Class.forName("JAKJ.RedstoneInMotion.Directions").getEnumConstants
val clazz = Class.forName("JAKJ.RedstoneInMotion.CarriageControllerEntity")
val methods = clazz.getDeclaredMethods
val setup = methods.find(_.getName == "SetupMotion").orNull
val move = methods.find(_.getName == "Move").orNull
(directions, setup, move)
} catch {
case _: Throwable => (null, null, null)
}
private var shouldMove = false
private var direction = 0
private var simulating = false
private var anchored = false
private var moving = false
// ----------------------------------------------------------------------- //
@LuaCallback("move")
def move(context: Context, args: Arguments): Array[Object] = {
if (directions == null || setup == null || move == null)
throw new Exception("Redstone in Motion not found")
if (shouldMove || moving)
throw new Exception("already moving")
direction = args.checkInteger(0)
if (direction < 0 || direction > directions.length)
throw new ArrayIndexOutOfBoundsException("invalid direction")
simulating = args.checkBoolean(1)
anchored = args.checkBoolean(2)
shouldMove = true
result(true)
}
// ----------------------------------------------------------------------- //
override def update() {
super.update()
if (shouldMove) {
shouldMove = false
moving = true
var error: Option[Throwable] = None
try {
setup.invoke(controller, directions(direction), Boolean.box(simulating), Boolean.box(anchored))
move.invoke(controller)
} catch {
case e: InvocationTargetException => error = Some(e.getCause)
case e: Throwable => error = Some(e)
}
moving = false
error match {
case Some(e) => node.sendToReachable("computer.signal", "carriage_moved", Unit, Option(e.getMessage).getOrElse(e.toString))
case _ => if (simulating || anchored) node.sendToReachable("computer.signal", "carriage_moved", Boolean.box(true))
}
}
}
// ----------------------------------------------------------------------- //
override def onConnect(node: Node) {
super.onConnect(node)
if (moving) {
moving = false
node.sendToReachable("computer.signal", "carriage_moved", Boolean.box(true))
}
}
// ----------------------------------------------------------------------- //
override def save(nbt: NBTTagCompound) {
super.save(nbt)
nbt.setBoolean("moving", moving)
}
override def load(nbt: NBTTagCompound) {
super.load(nbt)
moving = nbt.getBoolean("moving")
}
}