better check for which terminal is allowed to talk to which server; added basic range check (range not yet configurable); some localization stuff

This commit is contained in:
Florian Nücke 2014-01-17 20:04:33 +01:00
parent 0f067e37c4
commit 0c464a7801
12 changed files with 101 additions and 46 deletions

View File

@ -54,6 +54,7 @@ oc:item.PrintedCircuitBoard.name=Gedruckte Leiterplatte (PCB)
oc:item.RawCircuitBoard.name=Leiterplattenrohling oc:item.RawCircuitBoard.name=Leiterplattenrohling
oc:item.RedstoneCard.name=Redstonekarte oc:item.RedstoneCard.name=Redstonekarte
oc:item.Server.name=Server oc:item.Server.name=Server
oc:item.Terminal.name=Fernbedienung
oc:item.Transistor.name=Transistor oc:item.Transistor.name=Transistor
oc:item.UpgradeCrafting.name=Fertigungs-Upgrade oc:item.UpgradeCrafting.name=Fertigungs-Upgrade
oc:item.UpgradeGenerator.name=Generator-Upgrade oc:item.UpgradeGenerator.name=Generator-Upgrade
@ -81,6 +82,8 @@ oc:gui.ServerRack.Bottom=Unten
oc:gui.ServerRack.Left=Links oc:gui.ServerRack.Left=Links
oc:gui.ServerRack.Right=Rechts oc:gui.ServerRack.Right=Rechts
oc:gui.ServerRack.Top=Oben oc:gui.ServerRack.Top=Oben
oc:gui.Terminal.InvalidKey=Ungültiger Schlüssel, vermutlich wurde eine andere Fernbedienung an den Server gebunden.
oc:gui.Terminal.OutOfRange=Kein Signal.
# Containers # Containers
oc:container.Adapter=Adapter oc:container.Adapter=Adapter
@ -134,6 +137,7 @@ oc:tooltip.Screen=Zeigt Text an, gesteuert von Grafikkarten in Computern.[nl] H
oc:tooltip.Server=Ein Server kann wie gewöhnlich Computergehäuse mit Komponenten verbessert werden. Um den Server zu starten muss er in einem Servergehäuse installiert werden. oc:tooltip.Server=Ein Server kann wie gewöhnlich Computergehäuse mit Komponenten verbessert werden. Um den Server zu starten muss er in einem Servergehäuse installiert werden.
oc:tooltip.Server.Components=Installierte Komponenten: oc:tooltip.Server.Components=Installierte Komponenten:
oc:tooltip.ServerRack=Erlaubt die Installation von bis zu vier Servern. oc:tooltip.ServerRack=Erlaubt die Installation von bis zu vier Servern.
oc:tooltip.Terminal=Erlaubt es einen Server aus der Ferne zu steuern, so lange man sich in Reichweite des Servers befindet. Verhält sich wie Bildschirm und Tastatur in einem.
oc:tooltip.TooLong=Shift gedrückt halten für mehr Infos. oc:tooltip.TooLong=Shift gedrückt halten für mehr Infos.
oc:tooltip.Transistor=Elementarer Baustein der meisten Computerkomponenten. Nicht zu verwechseln mit Steinelementaren. oc:tooltip.Transistor=Elementarer Baustein der meisten Computerkomponenten. Nicht zu verwechseln mit Steinelementaren.
oc:tooltip.UpgradeCrafting=Ermöglicht Robotern, in dem oberen linken Bereich ihres Inventars Dinge zu fertigen. Gegenstände müssen so angeordnet sein, wie sie es in einer Werkbank wären. oc:tooltip.UpgradeCrafting=Ermöglicht Robotern, in dem oberen linken Bereich ihres Inventars Dinge zu fertigen. Gegenstände müssen so angeordnet sein, wie sie es in einer Werkbank wären.

View File

@ -54,6 +54,7 @@ oc:item.PrintedCircuitBoard.name=Printed Circuit Board (PCB)
oc:item.RawCircuitBoard.name=Raw Circuit Board oc:item.RawCircuitBoard.name=Raw Circuit Board
oc:item.RedstoneCard.name=Redstone Card oc:item.RedstoneCard.name=Redstone Card
oc:item.Server.name=Server oc:item.Server.name=Server
oc:item.Terminal.name=Remote Terminal
oc:item.Transistor.name=Transistor oc:item.Transistor.name=Transistor
oc:item.UpgradeCrafting.name=Crafting Upgrade oc:item.UpgradeCrafting.name=Crafting Upgrade
oc:item.UpgradeGenerator.name=Generator Upgrade oc:item.UpgradeGenerator.name=Generator Upgrade
@ -81,6 +82,8 @@ oc:gui.ServerRack.Bottom=Bottom
oc:gui.ServerRack.Left=Left oc:gui.ServerRack.Left=Left
oc:gui.ServerRack.Right=Right oc:gui.ServerRack.Right=Right
oc:gui.ServerRack.Top=Top oc:gui.ServerRack.Top=Top
oc:gui.Terminal.InvalidKey=Invalid key, most likely another terminal has been bound to the server.
oc:gui.Terminal.OutOfRange=No signal.
# Containers # Containers
oc:container.Adapter=Adapter oc:container.Adapter=Adapter
@ -134,6 +137,7 @@ oc:tooltip.Screen=Display text, controlled by a Graphics Card in a Case.[nl] Max
oc:tooltip.Server=This is a server, there are many like it, but this one can be upgraded with components much like a computer case can be. It can be run by inserting it into a server rack. oc:tooltip.Server=This is a server, there are many like it, but this one can be upgraded with components much like a computer case can be. It can be run by inserting it into a server rack.
oc:tooltip.Server.Components=Installed components: oc:tooltip.Server.Components=Installed components:
oc:tooltip.ServerRack=Allows the installation of up to four servers. oc:tooltip.ServerRack=Allows the installation of up to four servers.
oc:tooltip.Terminal=Allows controlling a server remotely, as long as you are in range of it. Acts like a portable screen and keyboard.
oc:tooltip.TooLong=Hold shift for a detailed tooltip. oc:tooltip.TooLong=Hold shift for a detailed tooltip.
oc:tooltip.Transistor=A basic element in most other computer parts. It's a bit twisted, but it does the job. oc:tooltip.Transistor=A basic element in most other computer parts. It's a bit twisted, but it does the job.
oc:tooltip.UpgradeCrafting=Enables robots to use the top left area of their inventory for crafting objects. Items have to be aligned as they would be in a crafting table. oc:tooltip.UpgradeCrafting=Enables robots to use the top left area of their inventory for crafting objects. Items have to be aligned as they would be in a crafting table.

View File

@ -13,7 +13,6 @@ object Blocks {
var blockSpecial: SpecialDelegator = _ var blockSpecial: SpecialDelegator = _
var blockSpecialWithRedstone: SpecialDelegator = _ var blockSpecialWithRedstone: SpecialDelegator = _
var accessPoint: AccessPoint = _
var adapter: Adapter = _ var adapter: Adapter = _
var cable: Cable = _ var cable: Cable = _
var capacitor: Capacitor = _ var capacitor: Capacitor = _
@ -41,7 +40,6 @@ object Blocks {
GameRegistry.registerBlock(blockSpecial, classOf[Item], Settings.namespace + "special") GameRegistry.registerBlock(blockSpecial, classOf[Item], Settings.namespace + "special")
GameRegistry.registerBlock(blockSpecialWithRedstone, classOf[Item], Settings.namespace + "special_redstone") GameRegistry.registerBlock(blockSpecialWithRedstone, classOf[Item], Settings.namespace + "special_redstone")
GameRegistry.registerTileEntity(classOf[tileentity.AccessPoint], Settings.namespace + "accessPoint")
GameRegistry.registerTileEntity(classOf[tileentity.Adapter], Settings.namespace + "adapter") GameRegistry.registerTileEntity(classOf[tileentity.Adapter], Settings.namespace + "adapter")
GameRegistry.registerTileEntity(classOf[tileentity.Cable], Settings.namespace + "cable") GameRegistry.registerTileEntity(classOf[tileentity.Cable], Settings.namespace + "cable")
GameRegistry.registerTileEntity(classOf[tileentity.Capacitor], Settings.namespace + "capacitor") GameRegistry.registerTileEntity(classOf[tileentity.Capacitor], Settings.namespace + "capacitor")
@ -88,7 +86,6 @@ object Blocks {
// v1.2.0 // v1.2.0
serverRack = new Rack(blockSpecialWithRedstone) serverRack = new Rack(blockSpecialWithRedstone)
accessPoint = new AccessPoint(blockSimple)
register("oc:craftingCable", cable.createItemStack()) register("oc:craftingCable", cable.createItemStack())
register("oc:craftingCapacitor", capacitor.createItemStack()) register("oc:craftingCapacitor", capacitor.createItemStack())

View File

@ -110,8 +110,7 @@ object Recipes {
addRecipe(Items.card.createItemStack(), recipes, "card") addRecipe(Items.card.createItemStack(), recipes, "card")
// Try to keep this in the same order as the fields in the Blocks class // Try to keep this in the same order as the fields in the Blocks class
// to make it easier to match them and check if anything is missing. // to make it easier to match them and check if anything is missing.Point")
addRecipe(Blocks.accessPoint.createItemStack(), recipes, "accessPoint")
addRecipe(Blocks.adapter.createItemStack(), recipes, "adapter") addRecipe(Blocks.adapter.createItemStack(), recipes, "adapter")
addRecipe(Blocks.cable.createItemStack(), recipes, "cable") addRecipe(Blocks.cable.createItemStack(), recipes, "cable")
addRecipe(Blocks.capacitor.createItemStack(), recipes, "capacitor") addRecipe(Blocks.capacitor.createItemStack(), recipes, "capacitor")
@ -326,12 +325,6 @@ object Recipes {
Item.itemsList(index) Item.itemsList(index)
} }
private def cartesianProduct[T](xss: List[List[T]]): List[List[T]] = xss match {
case Nil => List(Nil)
case h :: t => for (xh <- h;
xt <- cartesianProduct(t)) yield xh :: xt
}
private class RecipeException(message: String) extends RuntimeException(message) private class RecipeException(message: String) extends RuntimeException(message)
} }

View File

@ -6,9 +6,11 @@ import li.cil.oc.{Settings, Items}
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.world.World import net.minecraft.world.World
import scala.collection.convert.WrapAsScala._ import scala.collection.convert.WrapAsScala._
import net.minecraft.util.StatCollector
import net.minecraft.client.Minecraft
object GuiHandler extends CommonGuiHandler { object GuiHandler extends CommonGuiHandler {
override def getClientGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int) = override def getClientGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef =
world.getBlockTileEntity(x, y, z) match { world.getBlockTileEntity(x, y, z) match {
case adapter: tileentity.Adapter if id == GuiType.Adapter.id => case adapter: tileentity.Adapter if id == GuiType.Adapter.id =>
new gui.Adapter(player.inventory, adapter) new gui.Adapter(player.inventory, adapter)
@ -33,24 +35,39 @@ object GuiHandler extends CommonGuiHandler {
val stack = player.getCurrentEquippedItem val stack = player.getCurrentEquippedItem
if (stack.hasTagCompound) { if (stack.hasTagCompound) {
val address = stack.getTagCompound.getString(Settings.namespace + "server") val address = stack.getTagCompound.getString(Settings.namespace + "server")
if (address != null && !address.isEmpty) { val key = stack.getTagCompound.getString(Settings.namespace + "key")
if (key != null && !key.isEmpty && address != null && !address.isEmpty) {
// Check if bound to server is loaded. TODO optimize this? // Check if bound to server is loaded. TODO optimize this?
world.loadedTileEntityList.flatMap { world.loadedTileEntityList.flatMap {
case rack: tileentity.Rack => rack.terminals case rack: tileentity.Rack => rack.terminals
case _ => Iterable.empty case _ => Iterable.empty
} find (_.rack.isPresent.exists { } find (term => term.rack.isPresent(term.number) match {
case Some(value) => value == address case Some(value) => value == address
case _ => false case _ => false
}) match { }) match {
case Some(term) => case Some(term) =>
// TODO check reachability // TODO check reachability
new gui.Screen(term.buffer, true, () => true) def inRange = player.isEntityAlive && term.rack.getDistanceFrom(player.posX, player.posY, player.posZ) < term.rack.range
if (inRange) {
if (term.key.isDefined && term.key.get == key) return new gui.Screen(term.buffer, true, () => {
// Check if someone else bound a term to our server.
if (stack.getTagCompound.getString(Settings.namespace + "key") != key) {
Minecraft.getMinecraft.displayGuiScreen(null)
}
// Check whether we're still in range.
if (!inRange) {
Minecraft.getMinecraft.displayGuiScreen(null)
}
true
})
else player.addChatMessage(StatCollector.translateToLocal(Settings.namespace + "gui.Terminal.InvalidKey"))
}
else player.addChatMessage(StatCollector.translateToLocal(Settings.namespace + "gui.Terminal.OutOfRange"))
case _ => null case _ => null
} }
} }
else null
} }
else null null
case _ => null case _ => null
} }
} }

View File

@ -86,6 +86,10 @@ class PacketHandler extends CommonPacketHandler {
val number = p.readInt() val number = p.readInt()
t.setRunning(number, p.readBoolean()) t.setRunning(number, p.readBoolean())
t.sides(number) = p.readDirection() t.sides(number) = p.readDirection()
val key = p.readUTF()
if (key != "") {
t.terminals(number).key = Option(key)
}
case _ => // Invalid packet. case _ => // Invalid packet.
} }

View File

@ -1,5 +0,0 @@
package li.cil.oc.common.block
class AccessPoint(val parent: SimpleDelegator) extends SimpleDelegate {
val unlocalizedName = "AccessPoint"
}

View File

@ -1,12 +1,14 @@
package li.cil.oc.common.component package li.cil.oc.common.component
import cpw.mods.fml.relauncher.{Side, SideOnly}
import li.cil.oc.api.network.{Node, Visibility} import li.cil.oc.api.network.{Node, Visibility}
import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity
import li.cil.oc.common.item
import li.cil.oc.server.component import li.cil.oc.server.component
import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.PackedColor.Depth import li.cil.oc.util.PackedColor.Depth
import li.cil.oc.{Settings, common} import li.cil.oc.{Items, Settings, common}
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
@ -15,11 +17,20 @@ class Terminal(val rack: tileentity.Rack, val number: Int) extends Buffer.Owner
val keyboard = if (buffer.node != null) { val keyboard = if (buffer.node != null) {
buffer.node.setVisibility(Visibility.Neighbors) buffer.node.setVisibility(Visibility.Neighbors)
new component.Keyboard { new component.Keyboard {
override def isUseableByPlayer(p: EntityPlayer) = true // TODO if player has bound terminal override def isUseableByPlayer(p: EntityPlayer) = {
val stack = p.getCurrentEquippedItem
Items.multi.subItem(stack) match {
case Some(t: item.Terminal) if key.isDefined && stack.hasTagCompound =>
key.get == stack.getTagCompound.getString(Settings.namespace + "key")
case _ => false
}
}
} }
} }
else null else null
var key: Option[String] = None
def isServer = rack.isServer def isServer = rack.isServer
def connect(node: Node) { def connect(node: Node) {
@ -35,11 +46,34 @@ class Terminal(val rack: tileentity.Rack, val number: Int) extends Buffer.Owner
def load(nbt: NBTTagCompound) { def load(nbt: NBTTagCompound) {
buffer.load(nbt.getCompoundTag(Settings.namespace + "buffer")) buffer.load(nbt.getCompoundTag(Settings.namespace + "buffer"))
keyboard.load(nbt.getCompoundTag(Settings.namespace + "keyboard")) keyboard.load(nbt.getCompoundTag(Settings.namespace + "keyboard"))
if (nbt.hasKey(Settings.namespace + "key")) {
key = Option(nbt.getString(Settings.namespace + "key"))
}
} }
def save(nbt: NBTTagCompound) { def save(nbt: NBTTagCompound) {
nbt.setNewCompoundTag(Settings.namespace + "buffer", buffer.save) nbt.setNewCompoundTag(Settings.namespace + "buffer", buffer.save)
nbt.setNewCompoundTag(Settings.namespace + "keyboard", keyboard.save) nbt.setNewCompoundTag(Settings.namespace + "keyboard", keyboard.save)
key match {
case Some(value) => nbt.setString(Settings.namespace + "key", value)
case _ =>
}
}
@SideOnly(Side.CLIENT)
def readFromNBTForClient(nbt: NBTTagCompound) {
buffer.buffer.load(nbt)
if (nbt.hasKey("key")) {
key = Option(nbt.getString("key"))
}
}
def writeToNBTForClient(nbt: NBTTagCompound) {
buffer.buffer.save(nbt)
key match {
case Some(value) => nbt.setString("key", value)
case _ =>
}
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //

View File

@ -2,8 +2,10 @@ package li.cil.oc.common.item
import cpw.mods.fml.relauncher.{SideOnly, Side} import cpw.mods.fml.relauncher.{SideOnly, Side}
import java.util import java.util
import java.util.UUID
import li.cil.oc.common.{GuiType, tileentity} import li.cil.oc.common.{GuiType, tileentity}
import li.cil.oc.util.Tooltip import li.cil.oc.util.Tooltip
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.{OpenComputers, Settings} import li.cil.oc.{OpenComputers, Settings}
import net.minecraft.client.renderer.texture.IconRegister import net.minecraft.client.renderer.texture.IconRegister
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
@ -35,14 +37,18 @@ class Terminal(val parent: Delegator) extends Delegate {
case rack: tileentity.Rack if side == rack.facing.ordinal() => case rack: tileentity.Rack if side == rack.facing.ordinal() =>
val l = 2 / 16.0 val l = 2 / 16.0
val h = 14 / 16.0 val h = 14 / 16.0
val s = (((1 - hitY) - l) / (h - l) * 4).toInt val slot = (((1 - hitY) - l) / (h - l) * 4).toInt
if (s >= 0 && s <= 3 && rack.items(s).isDefined) { if (slot >= 0 && slot <= 3 && rack.items(slot).isDefined) {
if (!world.isRemote) { if (!world.isRemote) {
rack.servers(s) match { rack.servers(slot) match {
case Some(server) => case Some(server) =>
if (!stack.hasTagCompound) { if (!stack.hasTagCompound) {
stack.setTagCompound(new NBTTagCompound("tag")) stack.setTagCompound(new NBTTagCompound("tag"))
} }
val key = UUID.randomUUID().toString
rack.terminals(slot).key = Some(key)
ServerPacketSender.sendServerState(rack, slot)
stack.getTagCompound.setString(Settings.namespace + "key", key)
stack.getTagCompound.setString(Settings.namespace + "server", server.machine.address) stack.getTagCompound.setString(Settings.namespace + "server", server.machine.address)
player.inventory.onInventoryChanged() player.inventory.onInventoryChanged()
case _ => // Huh? case _ => // Huh?
@ -57,8 +63,9 @@ class Terminal(val parent: Delegator) extends Delegate {
override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = { override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = {
if (!player.isSneaking && stack.hasTagCompound) { if (!player.isSneaking && stack.hasTagCompound) {
val address = stack.getTagCompound.getString(Settings.namespace + "server") val key = stack.getTagCompound.getString(Settings.namespace + "key")
if (address != null && !address.isEmpty) { val server = stack.getTagCompound.getString(Settings.namespace + "server")
if (key != null && !key.isEmpty && server != null && !server.isEmpty) {
if (world.isRemote) { if (world.isRemote) {
player.openGui(OpenComputers, GuiType.Terminal.id, world, 0, 0, 0) player.openGui(OpenComputers, GuiType.Terminal.id, world, 0, 0, 0)
} }

View File

@ -1,8 +0,0 @@
package li.cil.oc.common.tileentity
import li.cil.oc.api
import li.cil.oc.api.network.Visibility
class AccessPoint extends Environment {
val node = api.Network.newNode(this, Visibility.Network).create()
}

View File

@ -22,6 +22,8 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
val terminals = (0 until servers.length).map(new common.component.Terminal(this, _)).toArray val terminals = (0 until servers.length).map(new common.component.Terminal(this, _)).toArray
var range = 16 * 16
// For client side, where we don't create the component. // For client side, where we don't create the component.
private val _isRunning = new Array[Boolean](getSizeInventory) private val _isRunning = new Array[Boolean](getSizeInventory)
@ -102,15 +104,16 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = { def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = {
servers.collect { if (side == facing.ordinal) {
case Some(server) => server.machine.lastError match { val l = 2 / 16.0
case Some(value) => val h = 14 / 16.0
// TODO check if already in, expand value string with additional messages val slot = ((hitY - l) / (h - l) * 4).toInt
stats.setString(Settings.namespace + "gui.Analyzer.LastError", value) if (slot >= 0 && slot <= 3 && servers(slot).isDefined) {
case _ => servers(slot).get.machine.node
} }
else null
} }
null else sidedNode(ForgeDirection.getOrientation(side))
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@ -168,6 +171,7 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
for (i <- 0 until math.min(terminals.length, terminalsNbt.length)) { for (i <- 0 until math.min(terminals.length, terminalsNbt.length)) {
terminals(i).load(terminalsNbt(i)) terminals(i).load(terminalsNbt(i))
} }
range = nbt.getInteger(Settings.namespace + "range")
} }
override def writeToNBT(nbt: NBTTagCompound) { override def writeToNBT(nbt: NBTTagCompound) {
@ -185,6 +189,7 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
t.save(terminalNbt) t.save(terminalNbt)
terminalNbt terminalNbt
})) }))
nbt.setInteger(Settings.namespace + "range", range)
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@ -198,8 +203,9 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
Array.copy(sidesNbt, 0, sides, 0, math.min(sidesNbt.length, sides.length)) Array.copy(sidesNbt, 0, sides, 0, math.min(sidesNbt.length, sides.length))
val terminalsNbt = nbt.getTagList("terminals").iterator[NBTTagCompound].toArray val terminalsNbt = nbt.getTagList("terminals").iterator[NBTTagCompound].toArray
for (i <- 0 until math.min(terminals.length, terminalsNbt.length)) { for (i <- 0 until math.min(terminals.length, terminalsNbt.length)) {
terminals(i).buffer.buffer.load(terminalsNbt(i)) terminals(i).readFromNBTForClient(terminalsNbt(i))
} }
range = nbt.getInteger("range")
} }
override def writeToNBTForClient(nbt: NBTTagCompound) { override def writeToNBTForClient(nbt: NBTTagCompound) {
@ -209,9 +215,10 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
nbt.setByteArray("sides", sides.map(_.ordinal.toByte)) nbt.setByteArray("sides", sides.map(_.ordinal.toByte))
nbt.setNewTagList("terminals", terminals.map(t => { nbt.setNewTagList("terminals", terminals.map(t => {
val terminalNbt = new NBTTagCompound() val terminalNbt = new NBTTagCompound()
t.buffer.buffer.save(terminalNbt) t.writeToNBTForClient(terminalNbt)
terminalNbt terminalNbt
})) }))
nbt.setInteger("range", range)
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //

View File

@ -309,6 +309,7 @@ object PacketSender {
pb.writeInt(number) pb.writeInt(number)
pb.writeBoolean(t.isRunning(number)) pb.writeBoolean(t.isRunning(number))
pb.writeDirection(t.sides(number)) pb.writeDirection(t.sides(number))
pb.writeUTF(t.terminals(number).key.getOrElse(""))
pb.sendToNearbyPlayers(t) pb.sendToNearbyPlayers(t)
} }