diff --git a/assets/opencomputers/textures/gui/robot.png b/assets/opencomputers/textures/gui/robot.png index f7c649975..3a61cbd98 100644 Binary files a/assets/opencomputers/textures/gui/robot.png and b/assets/opencomputers/textures/gui/robot.png differ diff --git a/li/cil/oc/api/Network.java b/li/cil/oc/api/Network.java index a79f096c1..3365eeb58 100644 --- a/li/cil/oc/api/Network.java +++ b/li/cil/oc/api/Network.java @@ -3,6 +3,7 @@ package li.cil.oc.api; import li.cil.oc.api.detail.Builder; import li.cil.oc.api.detail.NetworkAPI; import li.cil.oc.api.network.Environment; +import li.cil.oc.api.network.Node; import li.cil.oc.api.network.Visibility; import net.minecraft.world.World; @@ -29,6 +30,20 @@ public final class Network { if (instance != null) instance.joinOrCreateNetwork(world, x, y, z); } + /** + * Creates a new network with the specified node as its initial node. + *

+ * This can be used to create networks that are not bound to any tile + * entity. For example, this is used to create the internal networks of + * robots. + * + * @param node the node to create the network for. + * @throws IllegalArgumentException if the node already is in a network. + */ + public static void joinNewNetwork(Node node) { + if (instance != null) instance.joinNewNetwork(node); + } + /** * Factory function for creating new nodes. *

diff --git a/li/cil/oc/api/detail/NetworkAPI.java b/li/cil/oc/api/detail/NetworkAPI.java index 42635a052..3aa231aa5 100644 --- a/li/cil/oc/api/detail/NetworkAPI.java +++ b/li/cil/oc/api/detail/NetworkAPI.java @@ -1,11 +1,14 @@ package li.cil.oc.api.detail; import li.cil.oc.api.network.Environment; +import li.cil.oc.api.network.Node; import li.cil.oc.api.network.Visibility; import net.minecraft.world.World; public interface NetworkAPI { void joinOrCreateNetwork(World world, int x, int y, int z); + void joinNewNetwork(Node node); + Builder.NodeBuilder newNode(Environment host, Visibility visibility); } \ No newline at end of file diff --git a/li/cil/oc/client/PacketHandler.scala b/li/cil/oc/client/PacketHandler.scala index f5c4a2f8a..321b57cf4 100644 --- a/li/cil/oc/client/PacketHandler.scala +++ b/li/cil/oc/client/PacketHandler.scala @@ -2,7 +2,6 @@ package li.cil.oc.client import cpw.mods.fml.common.network.Player import li.cil.oc.common.PacketType -import li.cil.oc.common.component.Buffer import li.cil.oc.common.tileentity._ import li.cil.oc.common.{PacketHandler => CommonPacketHandler} import li.cil.oc.util.PackedColor @@ -87,7 +86,7 @@ class PacketHandler extends CommonPacketHandler { } def onScreenBufferResponse(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(t) => val screen = t.buffer val w = p.readInt() @@ -109,7 +108,7 @@ class PacketHandler extends CommonPacketHandler { } def onScreenColorChange(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(t) => t.buffer.foreground = p.readInt() t.buffer.background = p.readInt() @@ -117,7 +116,7 @@ class PacketHandler extends CommonPacketHandler { } def onScreenCopy(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(t) => val col = p.readInt() val row = p.readInt() @@ -130,13 +129,13 @@ class PacketHandler extends CommonPacketHandler { } def onScreenDepthChange(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(t) => t.buffer.depth = PackedColor.Depth(p.readInt()) case _ => // Invalid packet. } def onScreenFill(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(t) => val col = p.readInt() val row = p.readInt() @@ -154,7 +153,7 @@ class PacketHandler extends CommonPacketHandler { } def onScreenResolutionChange(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(t) => val w = p.readInt() val h = p.readInt() @@ -163,7 +162,7 @@ class PacketHandler extends CommonPacketHandler { } def onScreenSet(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(t) => val col = p.readInt() val row = p.readInt() diff --git a/li/cil/oc/client/PacketSender.scala b/li/cil/oc/client/PacketSender.scala index 382533cca..8d19e8ddb 100644 --- a/li/cil/oc/client/PacketSender.scala +++ b/li/cil/oc/client/PacketSender.scala @@ -2,7 +2,6 @@ package li.cil.oc.client import li.cil.oc.common.PacketBuilder import li.cil.oc.common.PacketType -import li.cil.oc.common.component.Buffer import li.cil.oc.common.tileentity._ object PacketSender { @@ -38,7 +37,7 @@ object PacketSender { pb.sendToServer() } - def sendScreenBufferRequest(t: Buffer.Environment) { + def sendScreenBufferRequest(t: Buffer) { val pb = new PacketBuilder(PacketType.ScreenBufferRequest) pb.writeTileEntity(t) @@ -46,7 +45,7 @@ object PacketSender { pb.sendToServer() } - def sendKeyDown[T <: Buffer.Environment](t: T, char: Char, code: Int) { + def sendKeyDown[T <: Buffer](t: T, char: Char, code: Int) { val pb = new PacketBuilder(PacketType.KeyDown) pb.writeTileEntity(t) @@ -56,7 +55,7 @@ object PacketSender { pb.sendToServer() } - def sendKeyUp[T <: Buffer.Environment](t: T, char: Char, code: Int) { + def sendKeyUp[T <: Buffer](t: T, char: Char, code: Int) { val pb = new PacketBuilder(PacketType.KeyUp) pb.writeTileEntity(t) @@ -66,7 +65,7 @@ object PacketSender { pb.sendToServer() } - def sendClipboard[T <: Buffer.Environment](t: T, value: String) = if (!value.isEmpty) { + def sendClipboard[T <: Buffer](t: T, value: String) = if (!value.isEmpty) { val pb = new PacketBuilder(PacketType.Clipboard) pb.writeTileEntity(t) diff --git a/li/cil/oc/client/gui/Buffer.scala b/li/cil/oc/client/gui/Buffer.scala index fa31808c5..9e77f579a 100644 --- a/li/cil/oc/client/gui/Buffer.scala +++ b/li/cil/oc/client/gui/Buffer.scala @@ -33,10 +33,12 @@ trait Buffer extends GuiScreen { MonospaceFontRenderer.init(Minecraft.getMinecraft.renderEngine) BufferRenderer.init(Minecraft.getMinecraft.renderEngine) Keyboard.enableRepeatEvents(true) + buffer.owner.currentGui = Some(this) } override def onGuiClosed() = { super.onGuiClosed() + buffer.owner.currentGui = None for ((code, char) <- pressedKeys) { PacketSender.sendKeyUp(buffer.owner, char, code) } diff --git a/li/cil/oc/client/gui/Robot.scala b/li/cil/oc/client/gui/Robot.scala index abaa9f15b..b8f082bce 100644 --- a/li/cil/oc/client/gui/Robot.scala +++ b/li/cil/oc/client/gui/Robot.scala @@ -14,27 +14,17 @@ import org.lwjgl.input.Keyboard import org.lwjgl.opengl.GL11 class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) extends GuiContainer(new container.Robot(playerInventory, robot)) with Buffer { - xSize = 236 - ySize = 222 + xSize = 256 + ySize = 242 protected val background = new ResourceLocation(Config.resourceDomain, "textures/gui/robot.png") protected val buffer = robot.buffer - private val bufferWidth = 222.0 + private val bufferWidth = 242.0 private val bufferHeight = 128.0 private val bufferMargin = BufferRenderer.innerMargin - override def initGui() { - super.initGui() - robot.currentGui = Some(this) - } - - override def onGuiClosed() = { - super.onGuiClosed() - robot.currentGui = None - } - override def drawSlotInventory(slot: Slot) { RenderState.makeItBlend() super.drawSlotInventory(slot) diff --git a/li/cil/oc/client/gui/Screen.scala b/li/cil/oc/client/gui/Screen.scala index 620d2e521..971ca27c8 100644 --- a/li/cil/oc/client/gui/Screen.scala +++ b/li/cil/oc/client/gui/Screen.scala @@ -13,16 +13,6 @@ class Screen(val screen: tileentity.Screen) extends Buffer { private var x, y = 0 - override def initGui() { - super.initGui() - screen.origin.currentGui = Some(this) - } - - override def onGuiClosed() = { - super.onGuiClosed() - screen.origin.currentGui = None - } - def drawBuffer() { GL11.glTranslatef(x, y, 0) BufferRenderer.drawBackground() diff --git a/li/cil/oc/common/component/Buffer.scala b/li/cil/oc/common/component/Buffer.scala index 785f2acbf..2357db919 100644 --- a/li/cil/oc/common/component/Buffer.scala +++ b/li/cil/oc/common/component/Buffer.scala @@ -1,16 +1,14 @@ package li.cil.oc.common.component import li.cil.oc.api.network.{Message, Node, Visibility} -import li.cil.oc.common.component import li.cil.oc.common.tileentity -import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.{Persistable, PackedColor, TextBuffer} import li.cil.oc.{api, Config} import net.minecraft.nbt.NBTTagCompound import scala.collection.convert.WrapAsScala._ -class Buffer(val owner: Buffer.Environment) extends api.network.Environment with Persistable { +class Buffer(val owner: tileentity.Buffer) extends api.network.Environment with Persistable { val node = api.Network.newNode(this, Visibility.Network). withComponent("screen"). withConnector(). @@ -141,80 +139,3 @@ class Buffer(val owner: Buffer.Environment) extends api.network.Environment with nbt.setNewCompoundTag("buffer", buffer.save) } } - -object Buffer { - - trait Environment extends tileentity.Environment with Persistable { - val buffer = new component.Buffer(this) - - var bufferIsDirty = false - - def tier: Int - - // ----------------------------------------------------------------------- // - - override def load(nbt: NBTTagCompound) = { - super.load(nbt) - buffer.load(nbt) - } - - override def save(nbt: NBTTagCompound) = { - super.save(nbt) - buffer.save(nbt) - } - - // ----------------------------------------------------------------------- // - - def onScreenColorChange(foreground: Int, background: Int) { - if (isServer) { - world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) - ServerPacketSender.sendScreenColorChange(this, foreground, background) - } - } - - def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) { - if (isServer) { - world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) - ServerPacketSender.sendScreenCopy(this, col, row, w, h, tx, ty) - } - else markForRenderUpdate() - } - - def onScreenDepthChange(depth: PackedColor.Depth.Value) { - if (isServer) { - world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) - ServerPacketSender.sendScreenDepthChange(this, depth) - } - else markForRenderUpdate() - } - - def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char) { - if (isServer) { - world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) - ServerPacketSender.sendScreenFill(this, col, row, w, h, c) - } - else markForRenderUpdate() - } - - def onScreenResolutionChange(w: Int, h: Int) { - if (isServer) { - world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) - ServerPacketSender.sendScreenResolutionChange(this, w, h) - } - else markForRenderUpdate() - } - - def onScreenSet(col: Int, row: Int, s: String) { - if (isServer) { - world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) - ServerPacketSender.sendScreenSet(this, col, row, s) - } - else markForRenderUpdate() - } - - protected def markForRenderUpdate() { - bufferIsDirty = true - } - } - -} \ No newline at end of file diff --git a/li/cil/oc/common/container/Robot.scala b/li/cil/oc/common/container/Robot.scala index 09fad3ed4..bc3cd7f54 100644 --- a/li/cil/oc/common/container/Robot.scala +++ b/li/cil/oc/common/container/Robot.scala @@ -5,19 +5,20 @@ import li.cil.oc.common.tileentity import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer} class Robot(playerInventory: InventoryPlayer, robot: tileentity.Robot) extends Player(playerInventory, robot) { - addSlotToContainer(176 + 0 * slotSize, 200, api.driver.Slot.Tool) - addSlotToContainer(176 + 1 * slotSize, 200, api.driver.Slot.Card) - addSlotToContainer(176 + 2 * slotSize, 200, api.driver.Slot.HardDiskDrive) + addSlotToContainer(178 + 0 * slotSize, 218, api.driver.Slot.Tool) + addSlotToContainer(178 + 1 * slotSize, 218, api.driver.Slot.Card) + addSlotToContainer(178 + 2 * slotSize, 218, api.driver.Slot.Card) + addSlotToContainer(178 + 3 * slotSize, 218, api.driver.Slot.HardDiskDrive) - for (i <- 0 to 2) { + for (i <- 0 to 3) { val y = 142 + i * slotSize - for (j <- 0 to 2) { - val x = 176 + j * slotSize + for (j <- 0 to 3) { + val x = 178 + j * slotSize addSlotToContainer(x, y) } } - addPlayerInventorySlots(8, 142) + addPlayerInventorySlots(8, 160) override def canInteractWith(player: EntityPlayer) = super.canInteractWith(player) && robot.computer.isUser(player.getCommandSenderName) diff --git a/li/cil/oc/common/tileentity/Buffer.scala b/li/cil/oc/common/tileentity/Buffer.scala new file mode 100644 index 000000000..8f9b92038 --- /dev/null +++ b/li/cil/oc/common/tileentity/Buffer.scala @@ -0,0 +1,87 @@ +package li.cil.oc.common.tileentity + +import cpw.mods.fml.relauncher.{Side, SideOnly} +import li.cil.oc.api.network.Node +import li.cil.oc.client.gui +import li.cil.oc.common.component +import li.cil.oc.server.{PacketSender => ServerPacketSender} +import li.cil.oc.util.{PackedColor, Persistable} +import net.minecraft.nbt.NBTTagCompound + +trait Buffer extends Environment with Persistable { + val buffer = new component.Buffer(this) + + var bufferIsDirty = false + + var currentGui: Option[gui.Buffer] = None + + def node: Node = buffer.node + + def tier: Int + + // ----------------------------------------------------------------------- // + + override def load(nbt: NBTTagCompound) = { + super.load(nbt) + buffer.load(nbt) + } + + override def save(nbt: NBTTagCompound) = { + super.save(nbt) + buffer.save(nbt) + } + + // ----------------------------------------------------------------------- // + + def onScreenColorChange(foreground: Int, background: Int) { + if (isServer) { + world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) + ServerPacketSender.sendScreenColorChange(this, foreground, background) + } + } + + def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) { + if (isServer) { + world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) + ServerPacketSender.sendScreenCopy(this, col, row, w, h, tx, ty) + } + else markForRenderUpdate() + } + + def onScreenDepthChange(depth: PackedColor.Depth.Value) { + if (isServer) { + world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) + ServerPacketSender.sendScreenDepthChange(this, depth) + } + else markForRenderUpdate() + } + + def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char) { + if (isServer) { + world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) + ServerPacketSender.sendScreenFill(this, col, row, w, h, c) + } + else markForRenderUpdate() + } + + def onScreenResolutionChange(w: Int, h: Int) { + if (isServer) { + world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) + ServerPacketSender.sendScreenResolutionChange(this, w, h) + } + else markForRenderUpdate() + } + + def onScreenSet(col: Int, row: Int, s: String) { + if (isServer) { + world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) + ServerPacketSender.sendScreenSet(this, col, row, s) + } + else markForRenderUpdate() + } + + @SideOnly(Side.CLIENT) + protected def markForRenderUpdate() { + bufferIsDirty = true + } +} diff --git a/li/cil/oc/common/tileentity/Robot.scala b/li/cil/oc/common/tileentity/Robot.scala index 8d71a8d58..4c5ec6000 100644 --- a/li/cil/oc/common/tileentity/Robot.scala +++ b/li/cil/oc/common/tileentity/Robot.scala @@ -1,12 +1,12 @@ package li.cil.oc.common.tileentity +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.network._ -import li.cil.oc.client.{PacketSender => ClientPacketSender, gui} -import li.cil.oc.common.component.Buffer -import li.cil.oc.server +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.driver.Registry @@ -16,23 +16,21 @@ import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound import scala.Some -class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer.Environment with PowerInformation { +class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with PowerInformation { def this() = this(false) // ----------------------------------------------------------------------- // - var currentGui: Option[gui.Robot] = None - override val node = api.Network.newNode(this, Visibility.None).create() - override val buffer = new Buffer(this) { - override def maxResolution = (44, 14) + override val buffer = new common.component.Buffer(this) { + override def maxResolution = (48, 14) } val (battery, distributor, gpu, keyboard) = if (isServer) { val battery = api.Network.newNode(this, Visibility.Network).withConnector(10000).create() val distributor = new component.PowerDistributor(this) val gpu = new GraphicsCard.Tier1 { - override val maxResolution = (44, 14) + override val maxResolution = (48, 14) } val keyboard = new component.Keyboard(this) (battery, distributor, gpu, keyboard) @@ -128,46 +126,6 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer.Environmen // ----------------------------------------------------------------------- // - // override def onMessage(message: Message) { - // if (message.source.network == node.network) { - // computer.node.network.sendToReachable(message.source, message.name, message.data: _*) - // } - // else { - // node.network.sendToReachable(message.source, message.name, message.data: _*) - // } - // } - - override def onConnect(node: Node) { - if (node == this.node) { - server.network.Network.create(computer.node) - - computer.node.connect(buffer.node) - computer.node.connect(distributor.node) - computer.node.connect(gpu.node) - distributor.node.connect(battery) - buffer.node.connect(keyboard.node) - } - super.onConnect(node) - } - - override def onDisconnect(node: Node) { - super.onDisconnect(node) - if (node == this.node) { - battery.remove() - buffer.node.remove() - computer.node.remove() - distributor.node.remove() - gpu.node.remove() - keyboard.node.remove() - } - } - - override protected def connectItemNode(node: Node) { - computer.node.connect(node) - } - - // ----------------------------------------------------------------------- // - override def readFromNBT(nbt: NBTTagCompound) { super.readFromNBT(nbt) if (isServer) { @@ -190,6 +148,47 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer.Environmen // ----------------------------------------------------------------------- // + // override def onMessage(message: Message) { + // if (message.source.network == node.network) { + // computer.node.network.sendToReachable(message.source, message.name, message.data: _*) + // } + // else { + // node.network.sendToReachable(message.source, message.name, message.data: _*) + // } + // } + + override def onConnect(node: Node) { + if (node == this.node) { + api.Network.joinNewNetwork(computer.node) + + computer.node.connect(buffer.node) + computer.node.connect(distributor.node) + computer.node.connect(gpu.node) + distributor.node.connect(battery) + buffer.node.connect(keyboard.node) + } + super.onConnect(node) + } + + override def onDisconnect(node: Node) { + super.onDisconnect(node) + if (node == this.node) { + battery.remove() + buffer.node.remove() + computer.node.remove() + distributor.node.remove() + gpu.node.remove() + keyboard.node.remove() + } + } + + // ----------------------------------------------------------------------- // + + override protected def connectItemNode(node: Node) { + computer.node.connect(node) + } + + @SideOnly(Side.CLIENT) override protected def markForRenderUpdate() { super.markForRenderUpdate() currentGui.foreach(_.recompileDisplayLists()) @@ -199,13 +198,13 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer.Environmen def getInvName = Config.namespace + "container.Robot" - def getSizeInventory = 12 + def getSizeInventory = 20 def isItemValidForSlot(slot: Int, item: ItemStack) = (slot, Registry.driverFor(item)) match { case (0, Some(driver)) => driver.slot(item) == Slot.Tool - case (1, Some(driver)) => driver.slot(item) == Slot.Card - case (2, Some(driver)) => driver.slot(item) == Slot.HardDiskDrive - case (3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11, _) => true // Normal inventory. + case (1 | 2, Some(driver)) => driver.slot(item) == Slot.Card + case (3, Some(driver)) => driver.slot(item) == Slot.HardDiskDrive + case (i, _) if 4 until 20 contains i => true // Normal inventory. case _ => false // Invalid slot. } } diff --git a/li/cil/oc/common/tileentity/Screen.scala b/li/cil/oc/common/tileentity/Screen.scala index d7da291c1..435eb2801 100644 --- a/li/cil/oc/common/tileentity/Screen.scala +++ b/li/cil/oc/common/tileentity/Screen.scala @@ -1,10 +1,9 @@ package li.cil.oc.common.tileentity +import cpw.mods.fml.relauncher.{Side, SideOnly} import li.cil.oc.Config import li.cil.oc.api.network.{Analyzable, Visibility} -import li.cil.oc.client.gui import li.cil.oc.client.{PacketSender => ClientPacketSender} -import li.cil.oc.common.component.Buffer import li.cil.oc.server.{PacketSender => ServerPacketSender} import net.minecraft.client.Minecraft import net.minecraft.entity.player.EntityPlayer @@ -13,15 +12,11 @@ import net.minecraft.util.AxisAlignedBB import net.minecraftforge.common.ForgeDirection import scala.collection.mutable -class Screen(var tier: Int) extends Buffer.Environment with Rotatable with Analyzable with Ordered[Screen] { +class Screen(var tier: Int) extends Buffer with Rotatable with Analyzable with Ordered[Screen] { def this() = this(0) // ----------------------------------------------------------------------- // - def node = buffer.node - - var currentGui: Option[gui.Screen] = None - /** * Check for multi-block screen option in next update. We do this in the * update to avoid unnecessary checks on chunk unload. @@ -38,6 +33,15 @@ class Screen(var tier: Int) extends Buffer.Environment with Rotatable with Analy // ----------------------------------------------------------------------- // + def checkMultiBlock() { + shouldCheckForMultiBlock = true + width = 1 + height = 1 + origin = this + screens.clear() + screens += this + } + def isOrigin = origin == this def localPosition = { @@ -48,15 +52,6 @@ class Screen(var tier: Int) extends Buffer.Environment with Rotatable with Analy // ----------------------------------------------------------------------- // - def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = origin - - def compare(that: Screen) = - if (x != that.x) x - that.x - else if (y != that.y) y - that.y - else z - that.z - - // ----------------------------------------------------------------------- // - override def updateEntity() { super.updateEntity() if (isServer) { @@ -154,15 +149,47 @@ class Screen(var tier: Int) extends Buffer.Environment with Rotatable with Analy // ----------------------------------------------------------------------- // - def checkMultiBlock() { - shouldCheckForMultiBlock = true - width = 1 - height = 1 - origin = this - screens.clear() - screens += this + @SideOnly(Side.CLIENT) + override def getRenderBoundingBox = + if ((width == 1 && height == 1) || !isOrigin) super.getRenderBoundingBox + else { + val (sx, sy, sz) = unproject(width, height, 1) + val ox = xCoord + (if (sx < 0) 1 else 0) + val oy = yCoord + (if (sy < 0) 1 else 0) + val oz = zCoord + (if (sz < 0) 1 else 0) + val b = AxisAlignedBB.getAABBPool.getAABB(ox, oy, oz, ox + sx, oy + sy, oz + sz) + b.setBounds(b.minX min b.maxX, b.minY min b.maxY, b.minZ min b.maxZ, + b.minX max b.maxX, b.minY max b.maxY, b.minZ max b.maxZ) + b + } + + @SideOnly(Side.CLIENT) + override def getMaxRenderDistanceSquared = if (isOrigin) super.getMaxRenderDistanceSquared else 0 + + // ----------------------------------------------------------------------- // + + def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = origin + + override def onRotationChanged() { + super.onRotationChanged() + screens.clone().foreach(_.checkMultiBlock()) } + @SideOnly(Side.CLIENT) + override protected def markForRenderUpdate() { + super.markForRenderUpdate() + currentGui.foreach(_.recompileDisplayLists()) + } + + // ----------------------------------------------------------------------- // + + def compare(that: Screen) = + if (x != that.x) x - that.x + else if (y != that.y) y - that.y + else z - that.z + + // ----------------------------------------------------------------------- // + private def tryMerge() = { val (x, y, z) = project(origin) def tryMergeTowards(dx: Int, dy: Int) = { @@ -208,33 +235,4 @@ class Screen(var tier: Int) extends Buffer.Environment with Rotatable with Analy def dot(f: ForgeDirection) = f.offsetX * x + f.offsetY * y + f.offsetZ * z (dot(toLocal(ForgeDirection.EAST)), dot(toLocal(ForgeDirection.UP)), dot(toLocal(ForgeDirection.SOUTH))) } - - // ----------------------------------------------------------------------- // - - override def getRenderBoundingBox = - if ((width == 1 && height == 1) || !isOrigin) super.getRenderBoundingBox - else { - val (sx, sy, sz) = unproject(width, height, 1) - val ox = xCoord + (if (sx < 0) 1 else 0) - val oy = yCoord + (if (sy < 0) 1 else 0) - val oz = zCoord + (if (sz < 0) 1 else 0) - val b = AxisAlignedBB.getAABBPool.getAABB(ox, oy, oz, ox + sx, oy + sy, oz + sz) - b.setBounds(b.minX min b.maxX, b.minY min b.maxY, b.minZ min b.maxZ, - b.minX max b.maxX, b.minY max b.maxY, b.minZ max b.maxZ) - b - } - - override def getMaxRenderDistanceSquared = if (isOrigin) super.getMaxRenderDistanceSquared else 0 - - // ----------------------------------------------------------------------- // - - override def onRotationChanged() { - super.onRotationChanged() - screens.clone().foreach(_.checkMultiBlock()) - } - - override protected def markForRenderUpdate() { - super.markForRenderUpdate() - currentGui.foreach(_.recompileDisplayLists()) - } } \ No newline at end of file diff --git a/li/cil/oc/server/PacketHandler.scala b/li/cil/oc/server/PacketHandler.scala index 79fe49bd5..b9bd0c1da 100644 --- a/li/cil/oc/server/PacketHandler.scala +++ b/li/cil/oc/server/PacketHandler.scala @@ -1,9 +1,7 @@ package li.cil.oc.server import cpw.mods.fml.common.network.Player -import li.cil.oc.api.network.Environment import li.cil.oc.common.PacketType -import li.cil.oc.common.component.Buffer import li.cil.oc.common.tileentity._ import li.cil.oc.common.{PacketHandler => CommonPacketHandler} import net.minecraftforge.common.DimensionManager @@ -51,13 +49,13 @@ class PacketHandler extends CommonPacketHandler { } def onScreenBufferRequest(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(t) => PacketSender.sendScreenBufferState(t, Option(p.player)) case _ => // Invalid packet. } def onKeyDown(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(s: Screen) => val char = Char.box(p.readChar()) val code = Int.box(p.readInt()) @@ -67,7 +65,7 @@ class PacketHandler extends CommonPacketHandler { } def onKeyUp(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(s: Screen) => val char = Char.box(p.readChar()) val code = Int.box(p.readInt()) @@ -77,7 +75,7 @@ class PacketHandler extends CommonPacketHandler { } def onClipboard(p: PacketParser) = - p.readTileEntity[Buffer.Environment]() match { + p.readTileEntity[Buffer]() match { case Some(s: Screen) => val value = p.readUTF() s.screens.foreach(_.node.sendToNeighbors("keyboard.clipboard", p.player, value)) diff --git a/li/cil/oc/server/PacketSender.scala b/li/cil/oc/server/PacketSender.scala index 204cedf68..6a436345a 100644 --- a/li/cil/oc/server/PacketSender.scala +++ b/li/cil/oc/server/PacketSender.scala @@ -3,7 +3,6 @@ package li.cil.oc.server import cpw.mods.fml.common.network.Player import li.cil.oc.common.PacketBuilder import li.cil.oc.common.PacketType -import li.cil.oc.common.component.Buffer import li.cil.oc.common.tileentity._ import li.cil.oc.util.PackedColor import net.minecraft.nbt.NBTTagCompound @@ -73,7 +72,7 @@ object PacketSender { } } - def sendScreenBufferState(t: Buffer.Environment, player: Option[Player] = None) { + def sendScreenBufferState(t: Buffer, player: Option[Player] = None) { val pb = new PacketBuilder(PacketType.ScreenBufferResponse) pb.writeTileEntity(t) @@ -94,7 +93,7 @@ object PacketSender { } } - def sendScreenColorChange(t: Buffer.Environment, foreground: Int, background: Int) { + def sendScreenColorChange(t: Buffer, foreground: Int, background: Int) { val pb = new PacketBuilder(PacketType.ScreenColorChange) pb.writeTileEntity(t) @@ -104,7 +103,7 @@ object PacketSender { pb.sendToAllPlayers() } - def sendScreenCopy(t: Buffer.Environment, col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) { + def sendScreenCopy(t: Buffer, col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) { val pb = new PacketBuilder(PacketType.ScreenCopy) pb.writeTileEntity(t) @@ -118,7 +117,7 @@ object PacketSender { pb.sendToAllPlayers() } - def sendScreenDepthChange(t: Buffer.Environment, value: PackedColor.Depth.Value) { + def sendScreenDepthChange(t: Buffer, value: PackedColor.Depth.Value) { val pb = new PacketBuilder(PacketType.ScreenDepthChange) pb.writeTileEntity(t) @@ -127,7 +126,7 @@ object PacketSender { pb.sendToAllPlayers() } - def sendScreenFill(t: Buffer.Environment, col: Int, row: Int, w: Int, h: Int, c: Char) { + def sendScreenFill(t: Buffer, col: Int, row: Int, w: Int, h: Int, c: Char) { val pb = new PacketBuilder(PacketType.ScreenFill) pb.writeTileEntity(t) @@ -140,7 +139,7 @@ object PacketSender { pb.sendToAllPlayers() } - def sendScreenPowerChange(t: Buffer.Environment, hasPower: Boolean) { + def sendScreenPowerChange(t: Buffer, hasPower: Boolean) { val pb = new PacketBuilder(PacketType.ScreenPowerChange) pb.writeTileEntity(t) @@ -149,7 +148,7 @@ object PacketSender { pb.sendToAllPlayers() } - def sendScreenResolutionChange(t: Buffer.Environment, w: Int, h: Int) { + def sendScreenResolutionChange(t: Buffer, w: Int, h: Int) { val pb = new PacketBuilder(PacketType.ScreenResolutionChange) pb.writeTileEntity(t) @@ -159,7 +158,7 @@ object PacketSender { pb.sendToAllPlayers() } - def sendScreenSet(t: Buffer.Environment, col: Int, row: Int, s: String) { + def sendScreenSet(t: Buffer, col: Int, row: Int, s: String) { val pb = new PacketBuilder(PacketType.ScreenSet) pb.writeTileEntity(t) diff --git a/li/cil/oc/server/network/Network.scala b/li/cil/oc/server/network/Network.scala index 9c13d5849..ecdb6b291 100644 --- a/li/cil/oc/server/network/Network.scala +++ b/li/cil/oc/server/network/Network.scala @@ -3,7 +3,7 @@ package li.cil.oc.server.network import cpw.mods.fml.common.FMLCommonHandler import cpw.mods.fml.relauncher.Side import li.cil.oc.api -import li.cil.oc.api.network.{Environment, Visibility, Node => ImmutableNode} +import li.cil.oc.api.network.{Node => ImmutableNode, Environment, Visibility} import li.cil.oc.server.network.{Node => MutableNode} import net.minecraft.block.Block import net.minecraft.world.{IBlockAccess, World} @@ -259,7 +259,14 @@ object Network extends api.detail.NetworkAPI { case _ => // Invalid block. } - def create(node: ImmutableNode): Unit = new Network(node.asInstanceOf[MutableNode]) + def joinNewNetwork(node: ImmutableNode): Unit = { + if (node != null) { + if (node.network != null) { + throw new IllegalArgumentException("Node must not be in a network.") + } + new Network(node.asInstanceOf[MutableNode]) + } + } private def getNetworkNode(world: IBlockAccess, x: Int, y: Int, z: Int) = Option(Block.blocksList(world.getBlockId(x, y, z))) match {