From f135d86b582833bfba4ccc5eb5f6cf9658c5f655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sun, 17 Nov 2013 12:54:58 +0100 Subject: [PATCH] made power distributor logic a component to be re-usable in robots; general shuffling for robot stuff, now building an "internal" network for each robot that is *not* connected to the outside world. this will limit some cards installed in the robot (e.g. gpus won't work with external screens) but makes it much easier to re-use components without having the issue that they interfere with external stuff (also, it makes robots less of a complete replacement for normal computers, which they should not be, they have a very specific role, after all); reworked how stuff gets saved a bit more, nodes are now generally saved by their host - in particular the base tile entity we use (Environment) will now only automatically save its `node` if it is that node's host --- assets/opencomputers/textures/gui/borders.png | Bin 215 -> 220 bytes li/cil/oc/api/driver/Slot.java | 5 + li/cil/oc/client/PacketHandler.scala | 4 +- .../renderer/tileentity/CableRenderer.scala | 1 - .../tileentity/PowerDistributorRenderer.scala | 6 +- li/cil/oc/common/component/Buffer.scala | 25 +-- li/cil/oc/common/container/Case.scala | 38 +--- li/cil/oc/common/container/DiskDrive.scala | 11 +- li/cil/oc/common/container/Player.scala | 13 ++ li/cil/oc/common/container/Robot.scala | 32 +--- .../tileentity/ComponentInventory.scala | 8 +- li/cil/oc/common/tileentity/Computer.scala | 9 +- li/cil/oc/common/tileentity/Environment.scala | 6 +- li/cil/oc/common/tileentity/Inventory.scala | 36 ++-- li/cil/oc/common/tileentity/Keyboard.scala | 6 +- .../oc/common/tileentity/PowerConverter.scala | 5 +- .../common/tileentity/PowerDistributor.scala | 172 ++---------------- .../common/tileentity/PowerInformation.scala | 5 + li/cil/oc/common/tileentity/Redstone.scala | 65 ++----- li/cil/oc/common/tileentity/Robot.scala | 85 ++++++--- li/cil/oc/common/tileentity/Rotatable.scala | 8 +- li/cil/oc/common/tileentity/Screen.scala | 4 +- li/cil/oc/server/PacketHandler.scala | 12 +- li/cil/oc/server/PacketSender.scala | 4 +- li/cil/oc/server/component/Computer.scala | 151 ++++++--------- li/cil/oc/server/component/Filesystem.scala | 7 +- li/cil/oc/server/component/GraphicsCard.scala | 8 +- li/cil/oc/server/component/Keyboard.scala | 9 +- .../server/component/ManagedComponent.scala | 5 +- li/cil/oc/server/component/NetworkCard.scala | 19 +- .../server/component/PowerDistributor.scala | 170 +++++++++++++++++ li/cil/oc/server/component/PowerSupply.scala | 9 +- .../component/WirelessNetworkCard.scala | 6 +- li/cil/oc/server/network/Connector.scala | 11 +- li/cil/oc/server/network/Network.scala | 2 + li/cil/oc/server/network/Node.scala | 8 +- li/cil/oc/util/ExtendedLuaState.scala | 2 +- li/cil/oc/util/ExtendedNBT.scala | 84 +++++++++ li/cil/oc/util/RenderState.scala | 14 ++ 39 files changed, 546 insertions(+), 519 deletions(-) create mode 100644 li/cil/oc/common/tileentity/PowerInformation.scala create mode 100644 li/cil/oc/server/component/PowerDistributor.scala create mode 100644 li/cil/oc/util/ExtendedNBT.scala diff --git a/assets/opencomputers/textures/gui/borders.png b/assets/opencomputers/textures/gui/borders.png index 0b852124268fefbfee5c4ad289e2a94efbe300a3..fd2a10da8c36cad3e7c1fa2fe1c6c99a06f77386 100644 GIT binary patch delta 155 zcmcc4c!zOPl)TWW5@pg{~sC}%D}+T-Q5jj|3AE~8OUKP3GxdDasM-H-oIo& zP{hyE#WAGfR>^rsz5@z8%#P|nokfLH6_mDCFPz6LI-%kcU(y_%9c2xyD~x_J*(n&a zzuBAQB+sj@rtoUn|NU3YI{v-jd9;`J^Uk)5$_E%k{;g+{TRZ>JXQ0sxp00i_>zopr E03iiNod5s; delta 150 zcmcb^c%5;AXFY#_Pl)TWW5+^6L;wH(&%nR{Bompww*XnJB|(0{K< t.average = p.readDouble() + p.readTileEntity[PowerInformation]() match { + case Some(t) => t.globalPower = p.readDouble() case _ => // Invalid packet. } diff --git a/li/cil/oc/client/renderer/tileentity/CableRenderer.scala b/li/cil/oc/client/renderer/tileentity/CableRenderer.scala index 4a77b96e0..ccd5d4eda 100644 --- a/li/cil/oc/client/renderer/tileentity/CableRenderer.scala +++ b/li/cil/oc/client/renderer/tileentity/CableRenderer.scala @@ -132,7 +132,6 @@ object CableRenderer extends TileEntitySpecialRenderer { GL11.glPushMatrix() GL11.glTranslated(x, y, z) - GL11.glColor3f(1, 1, 1) bindTexture(texture) GL11.glCallList(displayLists + cable.neighbors) diff --git a/li/cil/oc/client/renderer/tileentity/PowerDistributorRenderer.scala b/li/cil/oc/client/renderer/tileentity/PowerDistributorRenderer.scala index 844e19fdf..96fab6a12 100644 --- a/li/cil/oc/client/renderer/tileentity/PowerDistributorRenderer.scala +++ b/li/cil/oc/client/renderer/tileentity/PowerDistributorRenderer.scala @@ -13,13 +13,13 @@ object PowerDistributorRenderer extends TileEntitySpecialRenderer { private val sideOn = new ResourceLocation(Config.resourceDomain, "textures/blocks/power_distributor_on.png") override def renderTileEntityAt(tileEntity: TileEntity, x: Double, y: Double, z: Double, f: Float) = { - val balancer = tileEntity.asInstanceOf[tileentity.PowerDistributor] - if (balancer.average > 0) { + val distributor = tileEntity.asInstanceOf[tileentity.PowerDistributor] + if (distributor.globalPower > 0) { GL11.glPushAttrib(0xFFFFFF) RenderState.disableLighting() RenderState.makeItBlend() - RenderState.setBlendAlpha(balancer.average.toFloat) + RenderState.setBlendAlpha(distributor.globalPower.toFloat) GL11.glPushMatrix() diff --git a/li/cil/oc/common/component/Buffer.scala b/li/cil/oc/common/component/Buffer.scala index 7f62ac713..785f2acbf 100644 --- a/li/cil/oc/common/component/Buffer.scala +++ b/li/cil/oc/common/component/Buffer.scala @@ -4,6 +4,7 @@ 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 @@ -115,7 +116,8 @@ class Buffer(val owner: Buffer.Environment) extends api.network.Environment with // ----------------------------------------------------------------------- // override def load(nbt: NBTTagCompound) = { - buffer.load(nbt.getCompoundTag(Config.namespace + "buffer")) + node.load(nbt.getCompoundTag("node")) + buffer.load(nbt.getCompoundTag("buffer")) } override def save(nbt: NBTTagCompound) = { @@ -135,9 +137,8 @@ class Buffer(val owner: Buffer.Environment) extends api.network.Environment with } } - val screenNbt = new NBTTagCompound - buffer.save(screenNbt) - nbt.setCompoundTag(Config.namespace + "buffer", screenNbt) + nbt.setNewCompoundTag("node", node.save) + nbt.setNewCompoundTag("buffer", buffer.save) } } @@ -164,22 +165,6 @@ object Buffer { // ----------------------------------------------------------------------- // - override def onConnect(node: Node) { - super.onConnect(node) - if (node == this.node) { - node.connect(buffer.node) - } - } - - override def onDisconnect(node: Node) { - super.onDisconnect(node) - if (node == this.node) { - buffer.node.remove() - } - } - - // ----------------------------------------------------------------------- // - def onScreenColorChange(foreground: Int, background: Int) { if (isServer) { world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity]) diff --git a/li/cil/oc/common/container/Case.scala b/li/cil/oc/common/container/Case.scala index dc88980c6..c8826ee1f 100644 --- a/li/cil/oc/common/container/Case.scala +++ b/li/cil/oc/common/container/Case.scala @@ -1,52 +1,22 @@ package li.cil.oc.common.container import li.cil.oc.api -import li.cil.oc.client.gui.Icons import li.cil.oc.common.tileentity import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer} -import net.minecraft.inventory.Slot -import net.minecraft.item.ItemStack class Case(playerInventory: InventoryPlayer, `case`: tileentity.Case) extends Player(playerInventory, `case`) { - addSlotToContainer(new Slot(`case`, getInventory.size, 58, 17) { - setBackgroundIcon(Icons.get(api.driver.Slot.Power)) - - override def isItemValid(item: ItemStack) = { - `case`.isItemValidForSlot(0, item) - } - }) + addSlotToContainer(58, 17, api.driver.Slot.Power) for (i <- 0 to 2) { - val index = getInventory.size - addSlotToContainer(new Slot(`case`, index, 80, 17 + i * slotSize) { - setBackgroundIcon(Icons.get(api.driver.Slot.Card)) - - override def isItemValid(item: ItemStack) = { - `case`.isItemValidForSlot(index, item) - } - }) + addSlotToContainer(80, 17 + i * slotSize, api.driver.Slot.Card) } for (i <- 0 to 1) { - val index = getInventory.size - addSlotToContainer(new Slot(`case`, index, 102, 17 + i * slotSize) { - setBackgroundIcon(Icons.get(api.driver.Slot.Memory)) - - override def isItemValid(item: ItemStack) = { - `case`.isItemValidForSlot(index, item) - } - }) + addSlotToContainer(102, 17 + i * slotSize, api.driver.Slot.Memory) } for (i <- 0 to 1) { - val index = getInventory.size - addSlotToContainer(new Slot(`case`, index, 124, 17 + i * slotSize) { - setBackgroundIcon(Icons.get(api.driver.Slot.HardDiskDrive)) - - override def isItemValid(item: ItemStack) = { - `case`.isItemValidForSlot(index, item) - } - }) + addSlotToContainer(124, 17 + i * slotSize, api.driver.Slot.HardDiskDrive) } // Show the player's inventory. diff --git a/li/cil/oc/common/container/DiskDrive.scala b/li/cil/oc/common/container/DiskDrive.scala index ae08c80b0..a34739d6e 100644 --- a/li/cil/oc/common/container/DiskDrive.scala +++ b/li/cil/oc/common/container/DiskDrive.scala @@ -2,17 +2,8 @@ package li.cil.oc.common.container import li.cil.oc.common.tileentity import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.inventory.Slot -import net.minecraft.item.ItemStack class DiskDrive(playerInventory: InventoryPlayer, drive: tileentity.DiskDrive) extends Player(playerInventory, drive) { - // Floppy slot. - addSlotToContainer(new Slot(drive, 0, 80, 35) { - override def isItemValid(item: ItemStack) = { - drive.isItemValidForSlot(0, item) - } - }) - - // Show the player's inventory. + addSlotToContainer(80, 35) addPlayerInventorySlots(8, 84) } diff --git a/li/cil/oc/common/container/Player.scala b/li/cil/oc/common/container/Player.scala index b108bbdab..89b590826 100644 --- a/li/cil/oc/common/container/Player.scala +++ b/li/cil/oc/common/container/Player.scala @@ -1,5 +1,7 @@ package li.cil.oc.common.container +import li.cil.oc.api +import li.cil.oc.client.gui.Icons import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.InventoryPlayer import net.minecraft.inventory.Container @@ -103,6 +105,17 @@ abstract class Player(protected val playerInventory: InventoryPlayer, val otherI somethingChanged } + def addSlotToContainer(x: Int, y: Int, slot: api.driver.Slot = api.driver.Slot.None) { + val index = getInventory.size + addSlotToContainer(new Slot(otherInventory, index, x, y) { + setBackgroundIcon(Icons.get(slot)) + + override def isItemValid(item: ItemStack) = { + otherInventory.isItemValidForSlot(index, item) + } + }) + } + /** Render player inventory at the specified coordinates. */ protected def addPlayerInventorySlots(left: Int, top: Int) = { // Show the inventory proper. Start at plus one to skip hot bar. diff --git a/li/cil/oc/common/container/Robot.scala b/li/cil/oc/common/container/Robot.scala index 9641c0c30..09fad3ed4 100644 --- a/li/cil/oc/common/container/Robot.scala +++ b/li/cil/oc/common/container/Robot.scala @@ -1,46 +1,22 @@ package li.cil.oc.common.container import li.cil.oc.api -import li.cil.oc.client.gui.Icons import li.cil.oc.common.tileentity import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer} -import net.minecraft.inventory.Slot -import net.minecraft.item.ItemStack class Robot(playerInventory: InventoryPlayer, robot: tileentity.Robot) extends Player(playerInventory, robot) { - addSlotToContainer(new Slot(robot, getInventory.size, 176, 200) { - setBackgroundIcon(Icons.get(api.driver.Slot.Tool)) - - override def isItemValid(item: ItemStack) = { - robot.isItemValidForSlot(0, item) - } - }) - - for (i <- 0 to 1) { - val index = getInventory.size - addSlotToContainer(new Slot(robot, index, 194 + i * slotSize, 200) { - setBackgroundIcon(Icons.get(api.driver.Slot.Card)) - - override def isItemValid(item: ItemStack) = { - robot.isItemValidForSlot(index, item) - } - }) - } + 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) for (i <- 0 to 2) { val y = 142 + i * slotSize for (j <- 0 to 2) { val x = 176 + j * slotSize - val index = getInventory.size - addSlotToContainer(new Slot(robot, index, x, y) { - override def isItemValid(item: ItemStack) = { - robot.isItemValidForSlot(index, item) - } - }) + addSlotToContainer(x, y) } } - // Show the player's inventory. addPlayerInventorySlots(8, 142) override def canInteractWith(player: EntityPlayer) = diff --git a/li/cil/oc/common/tileentity/ComponentInventory.scala b/li/cil/oc/common/tileentity/ComponentInventory.scala index 4939a46f4..3bcd654ea 100644 --- a/li/cil/oc/common/tileentity/ComponentInventory.scala +++ b/li/cil/oc/common/tileentity/ComponentInventory.scala @@ -41,7 +41,7 @@ trait ComponentInventory extends Inventory with network.Environment with Persist } } components collect { - case Some(component) => node.connect(component.node) + case Some(component) => connectItemNode(component.node) } } } @@ -81,7 +81,7 @@ trait ComponentInventory extends Inventory with network.Environment with Persist case Some(component) => components(slot) = Some(component) component.load(driver.nbt(item)) - node.connect(component.node) + connectItemNode(component.node) case _ => // No environment (e.g. RAM). } case _ => // No driver. @@ -103,4 +103,8 @@ trait ComponentInventory extends Inventory with network.Environment with Persist case _ => // Nothing to do. } } + + protected def connectItemNode(node: Node) { + this.node.connect(node) + } } \ No newline at end of file diff --git a/li/cil/oc/common/tileentity/Computer.scala b/li/cil/oc/common/tileentity/Computer.scala index 1cc037f98..22abaa3c1 100644 --- a/li/cil/oc/common/tileentity/Computer.scala +++ b/li/cil/oc/common/tileentity/Computer.scala @@ -4,6 +4,7 @@ import li.cil.oc.Config import li.cil.oc.api.network._ import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.server.{PacketSender => ServerPacketSender, driver, component} +import li.cil.oc.util.ExtendedNBT._ import net.minecraft.entity.player.EntityPlayer import net.minecraft.nbt.NBTTagCompound import net.minecraftforge.common.ForgeDirection @@ -84,12 +85,16 @@ abstract class Computer(isRemote: Boolean) extends Environment with ComponentInv override def readFromNBT(nbt: NBTTagCompound) { super.readFromNBT(nbt) - if (computer != null) computer.load(nbt) + if (isServer) { + computer.load(nbt.getCompoundTag(Config.namespace + "computer")) + } } override def writeToNBT(nbt: NBTTagCompound) { super.writeToNBT(nbt) - if (computer != null) computer.save(nbt) + if (isServer) { + nbt.setNewCompoundTag(Config.namespace + "computer", computer.save) + } } // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/common/tileentity/Environment.scala b/li/cil/oc/common/tileentity/Environment.scala index 8ebd16d4f..801949813 100644 --- a/li/cil/oc/common/tileentity/Environment.scala +++ b/li/cil/oc/common/tileentity/Environment.scala @@ -1,6 +1,8 @@ package li.cil.oc.common.tileentity +import li.cil.oc.Config import li.cil.oc.api.{Network, network} +import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.Persistable import net.minecraft.nbt.NBTTagCompound import scala.math.ScalaNumber @@ -40,13 +42,13 @@ abstract class Environment extends net.minecraft.tileentity.TileEntity with Tile override def readFromNBT(nbt: NBTTagCompound) { super.readFromNBT(nbt) load(nbt) - if (node != null) node.load(nbt) + if (node != null && node.host == this) node.load(nbt.getCompoundTag(Config.namespace + "node")) } override def writeToNBT(nbt: NBTTagCompound) { super.writeToNBT(nbt) save(nbt) - if (node != null) node.save(nbt) + if (node != null && node.host == this) nbt.setNewCompoundTag(Config.namespace + "node", node.save) } // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/common/tileentity/Inventory.scala b/li/cil/oc/common/tileentity/Inventory.scala index 2f030b46f..acc6b6237 100644 --- a/li/cil/oc/common/tileentity/Inventory.scala +++ b/li/cil/oc/common/tileentity/Inventory.scala @@ -1,12 +1,13 @@ package li.cil.oc.common.tileentity import li.cil.oc.Config +import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.Persistable import net.minecraft.entity.item.EntityItem import net.minecraft.entity.player.EntityPlayer import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack -import net.minecraft.nbt.{NBTTagList, NBTTagCompound} +import net.minecraft.nbt.NBTTagCompound import net.minecraft.world.World trait Inventory extends TileEntity with IInventory with Persistable { @@ -82,34 +83,27 @@ trait Inventory extends TileEntity with IInventory with Persistable { override def load(nbt: NBTTagCompound) { super.load(nbt) - val inventoryNbt = nbt.getTagList(Config.namespace + "inventory.items") - for (i <- 0 until inventoryNbt.tagCount) { - val slotNbt = inventoryNbt.tagAt(i).asInstanceOf[NBTTagCompound] + nbt.getTagList(Config.namespace + "items").foreach[NBTTagCompound](slotNbt => { val slot = slotNbt.getByte("slot") if (slot >= 0 && slot < items.length) { - val item = ItemStack.loadItemStackFromNBT(slotNbt.getCompoundTag("item")) - items(slot) = Some(item) + items(slot) = Some(ItemStack.loadItemStackFromNBT(slotNbt.getCompoundTag("item"))) } - } + }) } override def save(nbt: NBTTagCompound) { super.save(nbt) - val inventoryNbt = new NBTTagList() - items.zipWithIndex collect { - case (Some(stack), slot) => (stack, slot) - } foreach { - case (stack, slot) => { - val slotNbt = new NBTTagCompound() - slotNbt.setByte("slot", slot.toByte) - val itemNbt = new NBTTagCompound() - stack.writeToNBT(itemNbt) - slotNbt.setCompoundTag("item", itemNbt) - inventoryNbt.appendTag(slotNbt) - } - } - nbt.setTag(Config.namespace + "inventory.items", inventoryNbt) + nbt.setNewTagList(Config.namespace + "items", + items.zipWithIndex collect { + case (Some(stack), slot) => (stack, slot) + } map { + case (stack, slot) => { + val slotNbt = new NBTTagCompound() + slotNbt.setByte("slot", slot.toByte) + slotNbt.setNewCompoundTag("item", stack.writeToNBT) + } + }) } // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/common/tileentity/Keyboard.scala b/li/cil/oc/common/tileentity/Keyboard.scala index a86309ea2..f441533a1 100644 --- a/li/cil/oc/common/tileentity/Keyboard.scala +++ b/li/cil/oc/common/tileentity/Keyboard.scala @@ -1,6 +1,8 @@ package li.cil.oc.common.tileentity +import li.cil.oc.Config import li.cil.oc.server.component +import li.cil.oc.util.ExtendedNBT._ import net.minecraft.nbt.NBTTagCompound class Keyboard(isRemote: Boolean) extends Environment with Rotatable { @@ -15,14 +17,14 @@ class Keyboard(isRemote: Boolean) extends Environment with Rotatable { override def readFromNBT(nbt: NBTTagCompound) { super.readFromNBT(nbt) if (isServer) { - keyboard.node.load(nbt) + keyboard.load(nbt.getCompoundTag(Config.namespace + "keyboard")) } } override def writeToNBT(nbt: NBTTagCompound) { super.writeToNBT(nbt) if (isServer) { - keyboard.node.save(nbt) + nbt.setNewCompoundTag(Config.namespace + "keyboard", keyboard.save) } } } diff --git a/li/cil/oc/common/tileentity/PowerConverter.scala b/li/cil/oc/common/tileentity/PowerConverter.scala index 9ea7f37c4..369c7abfe 100644 --- a/li/cil/oc/common/tileentity/PowerConverter.scala +++ b/li/cil/oc/common/tileentity/PowerConverter.scala @@ -5,6 +5,7 @@ import cpw.mods.fml.common.{Loader, Optional} import ic2.api.energy.event.{EnergyTileLoadEvent, EnergyTileUnloadEvent} import ic2.api.energy.tile.IEnergySink import li.cil.oc.api.network._ +import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.{Config, api} import net.minecraft.nbt.NBTTagCompound import net.minecraftforge.common.{ForgeDirection, MinecraftForge} @@ -63,14 +64,14 @@ class PowerConverter extends Environment with IEnergySink with IPowerReceptor wi override def readFromNBT(nbt: NBTTagCompound) { super.readFromNBT(nbt) if (Loader.isModLoaded("BuildCraft|Energy")) { - getPowerProvider.readFromNBT(nbt) + getPowerProvider.readFromNBT(nbt.getCompoundTag(Config.namespace + "bc")) } } override def writeToNBT(nbt: NBTTagCompound) { super.writeToNBT(nbt) if (Loader.isModLoaded("BuildCraft|Energy")) { - getPowerProvider.writeToNBT(nbt) + nbt.setNewCompoundTag(Config.namespace + "bc", getPowerProvider.writeToNBT) } } diff --git a/li/cil/oc/common/tileentity/PowerDistributor.scala b/li/cil/oc/common/tileentity/PowerDistributor.scala index 8901b7b86..cdea4c569 100644 --- a/li/cil/oc/common/tileentity/PowerDistributor.scala +++ b/li/cil/oc/common/tileentity/PowerDistributor.scala @@ -1,102 +1,44 @@ package li.cil.oc.common.tileentity +import li.cil.oc.Config import li.cil.oc.api.network._ import li.cil.oc.client.{PacketSender => ClientPacketSender} -import li.cil.oc.server.network.Connector -import li.cil.oc.server.{PacketSender => ServerPacketSender} -import li.cil.oc.{Config, api} +import li.cil.oc.server.component +import li.cil.oc.util.ExtendedNBT._ import net.minecraft.entity.player.EntityPlayer import net.minecraft.nbt.NBTTagCompound -import scala.collection.convert.WrapAsScala._ -import scala.collection.mutable -class PowerDistributor extends Environment with Analyzable { - val node = api.Network.newNode(this, Visibility.Network). - withComponent("power", Visibility.Network). - create() +class PowerDistributor extends Environment with PowerInformation with Analyzable { + val distributor = new component.PowerDistributor(this) - var globalBuffer = 0.0 - - var globalBufferSize = 0.0 - - var average = 0.0 - - private var lastSentAverage = 0.0 - - private val buffers = mutable.Set.empty[Connector] - - private val distributors = mutable.Set.empty[PowerDistributor] - - private var dirty = true - - // ----------------------------------------------------------------------- // - - @LuaCallback(value = "buffer", direct = true) - def buffer(context: Context, args: Arguments): Array[AnyRef] = result(globalBuffer) - - @LuaCallback(value = "bufferSize", direct = true) - def bufferSize(context: Context, args: Arguments): Array[AnyRef] = result(globalBufferSize) + def node = distributor.node // ----------------------------------------------------------------------- // override def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = { - stats.setString(Config.namespace + "text.Analyzer.TotalEnergy", "%.2f/%.2f".format(globalBuffer, globalBufferSize)) + stats.setString(Config.namespace + "text.Analyzer.TotalEnergy", "%.2f/%.2f".format(distributor.globalBuffer, distributor.globalBufferSize)) this } // ----------------------------------------------------------------------- // - def changeBuffer(delta: Double): Boolean = { - if (delta != 0) this.synchronized { - val oldBuffer = globalBuffer - globalBuffer = (globalBuffer + delta) max 0 min globalBufferSize - if (globalBuffer != oldBuffer) { - dirty = true - if (delta < 0) { - var remaining = -delta - for (connector <- buffers) { - connector.synchronized(if (connector.localBuffer > 0) { - connector.dirty = true - if (connector.localBuffer < remaining) { - remaining -= connector.localBuffer - connector.localBuffer = 0 - } - else { - connector.localBuffer -= remaining - return true - } - }) - } - } - else if (delta > 0) { - var remaining = delta - for (connector <- buffers) { - connector.synchronized(if (connector.localBuffer < connector.localBufferSize) { - connector.dirty = true - val space = connector.localBufferSize - connector.localBuffer - if (space < remaining) { - remaining -= space - connector.localBuffer = connector.localBufferSize - } - else { - connector.localBuffer += remaining - return true - } - }) - } - } - } - } - false + override def readFromNBT(nbt: NBTTagCompound) { + super.readFromNBT(nbt) + + distributor.load(nbt.getCompoundTag(Config.namespace + "distributor")) + } + + override def writeToNBT(nbt: NBTTagCompound) { + super.writeToNBT(nbt) + + nbt.setNewCompoundTag(Config.namespace + "distributor", distributor.save) } // ----------------------------------------------------------------------- // override def updateEntity() { super.updateEntity() - if (isServer && (dirty || buffers.exists(_.dirty))) { - updateCachedValues() - } + distributor.update() } override def validate() { @@ -105,82 +47,4 @@ class PowerDistributor extends Environment with Analyzable { ClientPacketSender.sendPowerStateRequest(this) } } - - // ----------------------------------------------------------------------- // - - override def onConnect(node: Node) { - super.onConnect(node) - if (node == this.node) { - for (node <- node.network.nodes) node match { - case connector: Connector if connector.localBufferSize > 0 => this.synchronized { - buffers += connector - globalBuffer += connector.localBuffer - globalBufferSize += connector.localBufferSize - } - case _ => node.host match { - case distributor: PowerDistributor => distributors += distributor - case _ => - } - } - dirty = true - } - else node match { - case connector: Connector => this.synchronized { - buffers += connector - globalBuffer += connector.localBuffer - globalBufferSize += connector.localBufferSize - dirty = true - } - case _ => node.host match { - case distributor: PowerDistributor => distributors += distributor - case _ => - } - } - } - - override def onDisconnect(node: Node) { - super.onDisconnect(node) - if (node == this.node) this.synchronized { - buffers.clear() - distributors.clear() - globalBuffer = 0 - globalBufferSize = 0 - average = -1 - } - else node match { - case connector: Connector => this.synchronized { - buffers -= connector - globalBuffer -= connector.localBuffer - globalBufferSize -= connector.localBufferSize - dirty = true - } - case _ => node.host match { - case distributor: PowerDistributor => distributors -= distributor - case _ => - } - } - } - - // ----------------------------------------------------------------------- // - - def updateCachedValues() { - // Computer average fill ratio of all buffers. - val (sumBuffer, sumBufferSize) = - buffers.foldRight((0.0, 0.0))((c, acc) => { - c.dirty = false // clear dirty flag for all connectors - (acc._1 + c.localBuffer, acc._2 + c.localBufferSize) - }) - average = if (globalBufferSize > 0) globalBuffer / globalBufferSize else 0 - val shouldSend = (lastSentAverage - average).abs > 0.05 - for (distributor <- distributors) distributor.synchronized { - distributor.dirty = false - distributor.globalBuffer = sumBuffer - distributor.globalBufferSize = sumBufferSize - distributor.average = average - if (shouldSend) { - distributor.lastSentAverage = lastSentAverage - ServerPacketSender.sendPowerState(distributor) - } - } - } } diff --git a/li/cil/oc/common/tileentity/PowerInformation.scala b/li/cil/oc/common/tileentity/PowerInformation.scala new file mode 100644 index 000000000..4eade5ec2 --- /dev/null +++ b/li/cil/oc/common/tileentity/PowerInformation.scala @@ -0,0 +1,5 @@ +package li.cil.oc.common.tileentity + +trait PowerInformation extends TileEntity { + var globalPower = 0.0 +} diff --git a/li/cil/oc/common/tileentity/Redstone.scala b/li/cil/oc/common/tileentity/Redstone.scala index 0a79e25b5..63fa18537 100644 --- a/li/cil/oc/common/tileentity/Redstone.scala +++ b/li/cil/oc/common/tileentity/Redstone.scala @@ -5,9 +5,10 @@ import cpw.mods.fml.common.{Loader, Optional} import li.cil.oc.Config import li.cil.oc.api.network import li.cil.oc.server.{PacketSender => ServerPacketSender} +import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.Persistable import mods.immibis.redlogic.api.wiring._ -import net.minecraft.nbt.{NBTTagByte, NBTTagList, NBTTagCompound} +import net.minecraft.nbt.{NBTTagByteArray, NBTTagCompound} import net.minecraftforge.common.ForgeDirection @Optional.InterfaceList(Array( @@ -104,67 +105,25 @@ with IConnectable with IBundledEmitter with IBundledUpdatable with IRedstoneEmit override def load(nbt: NBTTagCompound) = { super.load(nbt) - val inputNbt = nbt.getTagList(Config.namespace + "redstone.input") - for (i <- 0 until (_input.length min inputNbt.tagCount)) { - _input(i) = inputNbt.tagAt(i).asInstanceOf[NBTTagByte].data - } + nbt.getByteArray(Config.namespace + "rs.input").copyToArray(_input) + nbt.getByteArray(Config.namespace + "rs.output").copyToArray(_output) - val outputNbt = nbt.getTagList(Config.namespace + "redstone.output") - for (i <- 0 until (_output.length min outputNbt.tagCount)) { - _output(i) = outputNbt.tagAt(i).asInstanceOf[NBTTagByte].data + nbt.getTagList(Config.namespace + "rs.bundledInput").iterator[NBTTagByteArray].zipWithIndex.foreach { + case (input, side) => input.byteArray.copyToArray(_bundledInput(side)) } - - val bundledInputNbt = nbt.getTagList(Config.namespace + "redstone.bundledInput") - for (i <- 0 until (_bundledInput.length min bundledInputNbt.tagCount)) { - val bundleNbt = bundledInputNbt.tagAt(i).asInstanceOf[NBTTagList] - for (j <- 0 until (_bundledInput(i).length min bundleNbt.tagCount())) { - _bundledInput(i)(j) = bundleNbt.tagAt(j).asInstanceOf[NBTTagByte].data - } - } - - val bundledOutputNbt = nbt.getTagList(Config.namespace + "redstone.bundledOutput") - for (i <- 0 until (_bundledOutput.length min bundledOutputNbt.tagCount)) { - val bundleNbt = bundledOutputNbt.tagAt(i).asInstanceOf[NBTTagList] - for (j <- 0 until (_bundledOutput(i).length min bundleNbt.tagCount())) { - _bundledOutput(i)(j) = bundleNbt.tagAt(j).asInstanceOf[NBTTagByte].data - } + nbt.getTagList(Config.namespace + "rs.bundledOutput").iterator[NBTTagByteArray].zipWithIndex.foreach { + case (input, side) => input.byteArray.copyToArray(_bundledOutput(side)) } } override def save(nbt: NBTTagCompound) = { super.save(nbt) - val inputNbt = new NBTTagList() - for (i <- 0 until _input.length) { - inputNbt.appendTag(new NBTTagByte(null, _input(i))) - } - nbt.setTag(Config.namespace + "redstone.input", inputNbt) + nbt.setByteArray(Config.namespace + "rs.input", _input) + nbt.setByteArray(Config.namespace + "rs.output", _output) - val outputNbt = new NBTTagList() - for (i <- 0 until _output.length) { - outputNbt.appendTag(new NBTTagByte(null, _output(i))) - } - nbt.setTag(Config.namespace + "redstone.output", outputNbt) - - val bundledInputNbt = new NBTTagList() - for (i <- 0 until _bundledInput.length) { - val bundleNbt = new NBTTagList() - for (j <- 0 until _bundledInput(i).length) { - bundleNbt.appendTag(new NBTTagByte(null, _bundledInput(i)(j))) - } - bundledInputNbt.appendTag(bundleNbt) - } - nbt.setTag(Config.namespace + "redstone.bundledInput", bundledInputNbt) - - val bundledOutputNbt = new NBTTagList() - for (i <- 0 until _bundledOutput.length) { - val bundleNbt = new NBTTagList() - for (j <- 0 until _bundledOutput(i).length) { - bundleNbt.appendTag(new NBTTagByte(null, _bundledOutput(i)(j))) - } - bundledOutputNbt.appendTag(bundleNbt) - } - nbt.setTag(Config.namespace + "redstone.bundledOutput", bundledOutputNbt) + nbt.setNewTagList(Config.namespace + "rs.bundledInput", _bundledInput.view) + nbt.setNewTagList(Config.namespace + "rs.bundledOutput", _bundledOutput.view) } // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/common/tileentity/Robot.scala b/li/cil/oc/common/tileentity/Robot.scala index 8589edfe7..8d71a8d58 100644 --- a/li/cil/oc/common/tileentity/Robot.scala +++ b/li/cil/oc/common/tileentity/Robot.scala @@ -1,30 +1,44 @@ package li.cil.oc.common.tileentity 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.server.component import li.cil.oc.server.component.GraphicsCard import li.cil.oc.server.driver.Registry +import li.cil.oc.util.ExtendedNBT._ import net.minecraft.client.Minecraft import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound import scala.Some -class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer.Environment { +class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer.Environment with PowerInformation { def this() = this(false) // ----------------------------------------------------------------------- // - val gpu = new GraphicsCard.Tier1 { - override val maxResolution = (44, 14) - } - val keyboard = new component.Keyboard(this) - 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) + } + 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) + } + val keyboard = new component.Keyboard(this) + (battery, distributor, gpu, keyboard) + } + else (null, null, null, null) + // ----------------------------------------------------------------------- // def tier = 0 @@ -90,7 +104,11 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer.Environmen override def updateEntity() { super.updateEntity() - gpu.update() + if (isServer) { + distributor.changeBuffer(10) // just for testing + distributor.update() + gpu.update() + } } override def validate() { @@ -110,51 +128,63 @@ 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) { - super.onConnect(node) if (node == this.node) { - node.connect(gpu.node) - node.connect(buffer.node) - node.connect(keyboard.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) { - gpu.node.remove() + 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) { - buffer.node.load(nbt.getCompoundTag(Config.namespace + "buffer")) + battery.load(nbt.getCompoundTag(Config.namespace + "battery")) buffer.load(nbt.getCompoundTag(Config.namespace + "buffer")) gpu.load(nbt.getCompoundTag(Config.namespace + "gpu")) - keyboard.node.load(nbt.getCompoundTag(Config.namespace + "keyboard")) + keyboard.load(nbt.getCompoundTag(Config.namespace + "keyboard")) } } override def writeToNBT(nbt: NBTTagCompound) { super.writeToNBT(nbt) if (isServer) { - val bufferNbt = new NBTTagCompound() - buffer.node.save(bufferNbt) - buffer.save(bufferNbt) - nbt.setCompoundTag(Config.namespace + "buffer", bufferNbt) - - val gpuNbt = new NBTTagCompound() - gpu.save(gpuNbt) - nbt.setCompoundTag(Config.namespace + "gpu", gpuNbt) - - val keyboardNbt = new NBTTagCompound() - keyboard.node.save(keyboardNbt) - nbt.setCompoundTag(Config.namespace + "keyboard", keyboardNbt) + nbt.setNewCompoundTag(Config.namespace + "battery", battery.save) + nbt.setNewCompoundTag(Config.namespace + "buffer", buffer.save) + nbt.setNewCompoundTag(Config.namespace + "gpu", gpu.save) + nbt.setNewCompoundTag(Config.namespace + "keyboard", keyboard.save) } } @@ -173,7 +203,8 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer.Environmen def isItemValidForSlot(slot: Int, item: ItemStack) = (slot, Registry.driverFor(item)) match { case (0, Some(driver)) => driver.slot(item) == Slot.Tool - case (1 | 2, Some(driver)) => driver.slot(item) == Slot.Card + 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 _ => false // Invalid slot. } diff --git a/li/cil/oc/common/tileentity/Rotatable.scala b/li/cil/oc/common/tileentity/Rotatable.scala index 96eb4044a..840affdcf 100644 --- a/li/cil/oc/common/tileentity/Rotatable.scala +++ b/li/cil/oc/common/tileentity/Rotatable.scala @@ -154,16 +154,16 @@ trait Rotatable extends TileEntity with Persistable { override def load(nbt: NBTTagCompound) = { super.load(nbt) - _pitch = ForgeDirection.getOrientation(nbt.getInteger(Config.namespace + "rotatable.pitch")) - _yaw = ForgeDirection.getOrientation(nbt.getInteger(Config.namespace + "rotatable.yaw")) + _pitch = ForgeDirection.getOrientation(nbt.getInteger(Config.namespace + "pitch")) + _yaw = ForgeDirection.getOrientation(nbt.getInteger(Config.namespace + "yaw")) updateTranslation() } override def save(nbt: NBTTagCompound) = { super.save(nbt) - nbt.setInteger(Config.namespace + "rotatable.pitch", _pitch.ordinal) - nbt.setInteger(Config.namespace + "rotatable.yaw", _yaw.ordinal) + nbt.setInteger(Config.namespace + "pitch", _pitch.ordinal) + nbt.setInteger(Config.namespace + "yaw", _yaw.ordinal) } // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/common/tileentity/Screen.scala b/li/cil/oc/common/tileentity/Screen.scala index 170b33f52..d7da291c1 100644 --- a/li/cil/oc/common/tileentity/Screen.scala +++ b/li/cil/oc/common/tileentity/Screen.scala @@ -143,12 +143,12 @@ class Screen(var tier: Int) extends Buffer.Environment with Rotatable with Analy // ----------------------------------------------------------------------- // override def readFromNBT(nbt: NBTTagCompound) { - tier = nbt.getByte(Config.namespace + "screen.tier") + tier = nbt.getByte(Config.namespace + "tier") super.readFromNBT(nbt) } override def writeToNBT(nbt: NBTTagCompound) { - nbt.setByte(Config.namespace + "screen.tier", tier.toByte) + nbt.setByte(Config.namespace + "tier", tier.toByte) super.writeToNBT(nbt) } diff --git a/li/cil/oc/server/PacketHandler.scala b/li/cil/oc/server/PacketHandler.scala index c00ad28d7..79fe49bd5 100644 --- a/li/cil/oc/server/PacketHandler.scala +++ b/li/cil/oc/server/PacketHandler.scala @@ -57,31 +57,31 @@ class PacketHandler extends CommonPacketHandler { } def onKeyDown(p: PacketParser) = - p.readTileEntity[Environment]() match { + p.readTileEntity[Buffer.Environment]() match { case Some(s: Screen) => val char = Char.box(p.readChar()) val code = Int.box(p.readInt()) s.screens.foreach(_.node.sendToNeighbors("keyboard.keyDown", p.player, char, code)) - case Some(e) => e.node.sendToNeighbors("keyboard.keyDown", p.player, Char.box(p.readChar()), Int.box(p.readInt())) + case Some(e) => e.buffer.node.sendToNeighbors("keyboard.keyDown", p.player, Char.box(p.readChar()), Int.box(p.readInt())) case _ => // Invalid packet. } def onKeyUp(p: PacketParser) = - p.readTileEntity[Environment]() match { + p.readTileEntity[Buffer.Environment]() match { case Some(s: Screen) => val char = Char.box(p.readChar()) val code = Int.box(p.readInt()) s.screens.foreach(_.node.sendToNeighbors("keyboard.keyUp", p.player, char, code)) - case Some(e) => e.node.sendToNeighbors("keyboard.keyUp", p.player, Char.box(p.readChar()), Int.box(p.readInt())) + case Some(e) => e.buffer.node.sendToNeighbors("keyboard.keyUp", p.player, Char.box(p.readChar()), Int.box(p.readInt())) case _ => // Invalid packet. } def onClipboard(p: PacketParser) = - p.readTileEntity[Environment]() match { + p.readTileEntity[Buffer.Environment]() match { case Some(s: Screen) => val value = p.readUTF() s.screens.foreach(_.node.sendToNeighbors("keyboard.clipboard", p.player, value)) - case Some(e) => e.node.sendToNeighbors("keyboard.clipboard", p.player, p.readUTF()) + case Some(e) => e.buffer.node.sendToNeighbors("keyboard.clipboard", p.player, p.readUTF()) case _ => // Invalid packet. } } \ No newline at end of file diff --git a/li/cil/oc/server/PacketSender.scala b/li/cil/oc/server/PacketSender.scala index 333494440..204cedf68 100644 --- a/li/cil/oc/server/PacketSender.scala +++ b/li/cil/oc/server/PacketSender.scala @@ -33,11 +33,11 @@ object PacketSender { } } - def sendPowerState(t: PowerDistributor, player: Option[Player] = None) { + def sendPowerState(t: PowerInformation, player: Option[Player] = None) { val pb = new PacketBuilder(PacketType.PowerStateResponse) pb.writeTileEntity(t) - pb.writeDouble(t.average) + pb.writeDouble(t.globalPower) player match { case Some(p) => pb.sendToPlayer(p) diff --git a/li/cil/oc/server/component/Computer.scala b/li/cil/oc/server/component/Computer.scala index 2f357d9fb..176977674 100644 --- a/li/cil/oc/server/component/Computer.scala +++ b/li/cil/oc/server/component/Computer.scala @@ -7,11 +7,11 @@ import java.util.concurrent._ import java.util.concurrent.atomic.AtomicInteger import java.util.logging.Level import li.cil.oc.api -import li.cil.oc.api.Persistable import li.cil.oc.api.network._ import li.cil.oc.common.tileentity import li.cil.oc.server import li.cil.oc.util.ExtendedLuaState.extendLuaState +import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.{GameTimeFormatter, LuaStateFactory} import li.cil.oc.{OpenComputers, Config} import net.minecraft.entity.player.EntityPlayer @@ -24,7 +24,7 @@ import scala.collection.mutable import scala.math.ScalaNumber import scala.runtime.BoxedUnit -class Computer(val owner: tileentity.Computer) extends Environment with Context with Persistable with Runnable { +class Computer(val owner: tileentity.Computer) extends ManagedComponent with Context with Runnable { val node = api.Network.newNode(this, Visibility.Network). withComponent("computer", Visibility.Neighbors). withConnector(). @@ -156,7 +156,7 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context // ----------------------------------------------------------------------- // - def update() { + override def update() { // Add components that were added since the last update to the actual list // of components if we can see them. We use this delayed approach to avoid // issues with components that have a visibility lower than their @@ -279,7 +279,7 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context // ----------------------------------------------------------------------- // - def onConnect(node: Node) { + override def onConnect(node: Node) { if (node == this.node) { rom.foreach(rom => node.connect(rom.node)) tmp.foreach(tmp => node.connect(tmp.node)) @@ -293,7 +293,7 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context owner.onConnect(node) } - def onDisconnect(node: Node) { + override def onDisconnect(node: Node) { if (node == this.node) { stop() rom.foreach(_.node.remove()) @@ -308,7 +308,7 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context owner.onDisconnect(node) } - def onMessage(message: Message) { + override def onMessage(message: Message) { message.data match { case Array(name: String, args@_*) if message.name == "computer.signal" => signal(name, Seq(message.source.address) ++ args: _*) @@ -365,26 +365,19 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context // ----------------------------------------------------------------------- // - def load(nbt: NBTTagCompound) = this.synchronized { + override def load(nbt: NBTTagCompound) = this.synchronized { assert(state.top == Computer.State.Stopped) assert(future.isEmpty) - - val computerNbt = nbt.getCompoundTag(Config.namespace + "computer") - + assert(users.isEmpty) + assert(signals.isEmpty) state.clear() - val stateNbt = computerNbt.getTagList("state") - (0 until stateNbt.tagCount). - map(stateNbt.tagAt). - map(_.asInstanceOf[NBTTagInt]). - foreach(s => state.push(Computer.State(s.data))) - val usersNbt = computerNbt.getTagList("users") - (0 until usersNbt.tagCount). - map(usersNbt.tagAt). - map(_.asInstanceOf[NBTTagString]). - foreach(u => users += u.data) + super.load(nbt) - if (state.top != Computer.State.Stopped && init()) { + nbt.getTagList("state").foreach[NBTTagInt](s => state.push(Computer.State(s.data))) + nbt.getTagList("users").foreach[NBTTagString](u => users += u.data) + + if (state.size > 0 && state.top != Computer.State.Stopped && init()) { // Unlimit memory use while unpersisting. lua.setTotalMemory(Integer.MAX_VALUE) @@ -393,14 +386,14 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context // on. First, clear the stack, meaning the current kernel. lua.setTop(0) - unpersist(computerNbt.getByteArray("kernel")) + unpersist(nbt.getByteArray("kernel")) if (!lua.isThread(1)) { // This shouldn't really happen, but there's a chance it does if // the save was corrupt (maybe someone modified the Lua files). throw new IllegalArgumentException("Invalid kernel.") } if (state.contains(Computer.State.SynchronizedCall) || state.contains(Computer.State.SynchronizedReturn)) { - unpersist(computerNbt.getByteArray("stack")) + unpersist(nbt.getByteArray("stack")) if (!(if (state.contains(Computer.State.SynchronizedCall)) lua.isFunction(2) else lua.isTable(2))) { // Same as with the above, should not really happen normally, but // could for the same reasons. @@ -408,17 +401,11 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context } } - val componentsNbt = computerNbt.getTagList("components") - components ++= (0 until componentsNbt.tagCount). - map(componentsNbt.tagAt). - map(_.asInstanceOf[NBTTagCompound]). - map(c => c.getString("address") -> c.getString("name")) + val componentsNbt = nbt.getTagList("components") + components ++= componentsNbt.iterator[NBTTagCompound].map(c => + c.getString("address") -> c.getString("name")) - val signalsNbt = computerNbt.getTagList("signals") - signals ++= (0 until signalsNbt.tagCount). - map(signalsNbt.tagAt). - map(_.asInstanceOf[NBTTagCompound]). - map(signalNbt => { + signals ++= nbt.getTagList("signals").iterator[NBTTagCompound].map(signalNbt => { val argsNbt = signalNbt.getCompoundTag("args") val argsLength = argsNbt.getInteger("length") new Computer.Signal(signalNbt.getString("name"), @@ -432,21 +419,13 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context }.toArray) }) - rom.foreach(rom => { - val romNbt = computerNbt.getCompoundTag("rom") - rom.node.load(romNbt) - rom.load(romNbt) - }) - tmp.foreach(tmp => { - val tmpNbt = computerNbt.getCompoundTag("tmp") - tmp.node.load(tmpNbt) - tmp.load(tmpNbt) - }) - kernelMemory = computerNbt.getInteger("kernelMemory") - timeStarted = computerNbt.getLong("timeStarted") - cpuTime = computerNbt.getLong("cpuTime") - if (computerNbt.hasKey("message")) { - message = Some(computerNbt.getString("message")) + rom.foreach(rom => rom.load(nbt.getCompoundTag("rom"))) + tmp.foreach(tmp => tmp.load(nbt.getCompoundTag("tmp"))) + kernelMemory = nbt.getInteger("kernelMemory") + timeStarted = nbt.getLong("timeStarted") + cpuTime = nbt.getLong("cpuTime") + if (nbt.hasKey("message")) { + message = Some(nbt.getString("message")) } // Limit memory again. @@ -466,26 +445,17 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context else close() // Clean up in case we got a weird state stack. } - def save(nbt: NBTTagCompound): Unit = this.synchronized { + override def save(nbt: NBTTagCompound): Unit = this.synchronized { assert(state.top != Computer.State.Running) // Lock on 'this' should guarantee this. assert(state.top != Computer.State.Stopping) // Only set while executor is running. + super.save(nbt) + // Make sure the component list is up-to-date. processAddedComponents() - val computerNbt = new NBTTagCompound() - - val stateNbt = new NBTTagList() - for (state <- state) { - stateNbt.appendTag(new NBTTagInt(null, state.id)) - } - computerNbt.setTag("state", stateNbt) - - val usersNbt = new NBTTagList() - for (user <- users) { - usersNbt.appendTag(new NBTTagString(null, user)) - } - computerNbt.setTag("users", usersNbt) + nbt.setNewTagList("state", state.map(_.id)) + nbt.setNewTagList("users", users) if (state.top != Computer.State.Stopped) { // Unlimit memory while persisting. @@ -495,12 +465,12 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context // Try persisting Lua, because that's what all of the rest depends on. // Save the kernel state (which is always at stack index one). assert(lua.isThread(1)) - computerNbt.setByteArray("kernel", persist(1)) + nbt.setByteArray("kernel", persist(1)) // While in a driver call we have one object on the global stack: either // the function to call the driver with, or the result of the call. if (state.contains(Computer.State.SynchronizedCall) || state.contains(Computer.State.SynchronizedReturn)) { assert(if (state.contains(Computer.State.SynchronizedCall)) lua.isFunction(2) else lua.isTable(2)) - computerNbt.setByteArray("stack", persist(2)) + nbt.setByteArray("stack", persist(2)) } val componentsNbt = new NBTTagList() @@ -510,56 +480,43 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context componentNbt.setString("name", name) componentsNbt.appendTag(componentNbt) } - computerNbt.setTag("components", componentsNbt) + nbt.setTag("components", componentsNbt) val signalsNbt = new NBTTagList() for (s <- signals.iterator) { val signalNbt = new NBTTagCompound() signalNbt.setString("name", s.name) - val args = new NBTTagCompound() - args.setInteger("length", s.args.length) - s.args.zipWithIndex.foreach { - case (Unit, i) => args.setByte("arg" + i, -1) - case (arg: Boolean, i) => args.setByte("arg" + i, if (arg) 1 else 0) - case (arg: Double, i) => args.setDouble("arg" + i, arg) - case (arg: String, i) => args.setString("arg" + i, arg) - case (arg: Array[Byte], i) => args.setByteArray("arg" + i, arg) - } - signalNbt.setCompoundTag("args", args) + signalNbt.setNewCompoundTag("args", args => { + args.setInteger("length", s.args.length) + s.args.zipWithIndex.foreach { + case (Unit, i) => args.setByte("arg" + i, -1) + case (arg: Boolean, i) => args.setByte("arg" + i, if (arg) 1 else 0) + case (arg: Double, i) => args.setDouble("arg" + i, arg) + case (arg: String, i) => args.setString("arg" + i, arg) + case (arg: Array[Byte], i) => args.setByteArray("arg" + i, arg) + } + }) signalsNbt.appendTag(signalNbt) } - computerNbt.setTag("signals", signalsNbt) + nbt.setTag("signals", signalsNbt) - val romNbt = new NBTTagCompound() - rom.foreach(rom => { - rom.save(romNbt) - rom.node.save(romNbt) - }) - computerNbt.setCompoundTag("rom", romNbt) + rom.foreach(rom => nbt.setNewCompoundTag("rom", rom.save)) + tmp.foreach(tmp => nbt.setNewCompoundTag("tmp", tmp.save)) - val tmpNbt = new NBTTagCompound() - tmp.foreach(tmp => { - tmp.save(tmpNbt) - tmp.node.save(tmpNbt) - }) - computerNbt.setCompoundTag("tmp", tmpNbt) - - computerNbt.setInteger("kernelMemory", kernelMemory) - computerNbt.setLong("timeStarted", timeStarted) - computerNbt.setLong("cpuTime", cpuTime) - message.foreach(computerNbt.setString("message", _)) + nbt.setInteger("kernelMemory", kernelMemory) + nbt.setLong("timeStarted", timeStarted) + nbt.setLong("cpuTime", cpuTime) + message.foreach(nbt.setString("message", _)) } catch { case e: LuaRuntimeException => { OpenComputers.log.warning("Could not persist computer.\n" + e.toString + "\tat " + e.getLuaStackTrace.mkString("\n\tat ")) - computerNbt.setInteger("state", Computer.State.Stopped.id) + nbt.removeTag("state") } } // Limit memory again. recomputeMemory() } - - nbt.setCompoundTag(Config.namespace + "computer", computerNbt) } private def persist(index: Int): Array[Byte] = { @@ -1086,7 +1043,7 @@ class Computer(val owner: tileentity.Computer) extends Environment with Context } private def close() = state.synchronized( - if (state.top != Computer.State.Stopped) { + if (state.size == 0 || state.top != Computer.State.Stopped) { state.clear() state.push(Computer.State.Stopped) lua.setTotalMemory(Integer.MAX_VALUE) diff --git a/li/cil/oc/server/component/Filesystem.scala b/li/cil/oc/server/component/Filesystem.scala index 8b2d2b420..4491663fb 100644 --- a/li/cil/oc/server/component/Filesystem.scala +++ b/li/cil/oc/server/component/Filesystem.scala @@ -3,6 +3,7 @@ package li.cil.oc.server.component import java.io.{FileNotFoundException, IOException} import li.cil.oc.api.fs.{Label, Mode} import li.cil.oc.api.network._ +import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.{Config, api} import net.minecraft.nbt.{NBTTagInt, NBTTagList, NBTTagCompound} import scala.Some @@ -228,6 +229,7 @@ class FileSystem(val fileSystem: api.fs.FileSystem, var label: Label) extends Ma override def load(nbt: NBTTagCompound) { super.load(nbt) + val ownersNbt = nbt.getTagList("owners") (0 until ownersNbt.tagCount).map(ownersNbt.tagAt).map(_.asInstanceOf[NBTTagCompound]).foreach(ownerNbt => { val address = ownerNbt.getString("address") @@ -245,6 +247,7 @@ class FileSystem(val fileSystem: api.fs.FileSystem, var label: Label) extends Ma override def save(nbt: NBTTagCompound) { super.save(nbt) + val ownersNbt = new NBTTagList() for ((address, handles) <- owners) { val ownerNbt = new NBTTagCompound() @@ -258,9 +261,7 @@ class FileSystem(val fileSystem: api.fs.FileSystem, var label: Label) extends Ma } nbt.setTag("owners", ownersNbt) - val fsNbt = new NBTTagCompound() - fileSystem.save(fsNbt) - nbt.setCompoundTag("fs", fsNbt) + nbt.setNewCompoundTag("fs", fileSystem.save) } // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/server/component/GraphicsCard.scala b/li/cil/oc/server/component/GraphicsCard.scala index 32189ac7b..d6dd49ea2 100644 --- a/li/cil/oc/server/component/GraphicsCard.scala +++ b/li/cil/oc/server/component/GraphicsCard.scala @@ -207,16 +207,18 @@ abstract class GraphicsCard extends ManagedComponent { override def load(nbt: NBTTagCompound) { super.load(nbt) - if (nbt.hasKey(Config.namespace + "gpu.screen")) { - screenAddress = Some(nbt.getString(Config.namespace + "gpu.screen")) + + if (nbt.hasKey("screen")) { + screenAddress = Some(nbt.getString("screen")) screenInstance = None } } override def save(nbt: NBTTagCompound) { super.save(nbt) + if (screenAddress.isDefined) { - nbt.setString(Config.namespace + "gpu.screen", screenAddress.get) + nbt.setString("screen", screenAddress.get) } } } diff --git a/li/cil/oc/server/component/Keyboard.scala b/li/cil/oc/server/component/Keyboard.scala index 5e0d40b6c..e45620c8e 100644 --- a/li/cil/oc/server/component/Keyboard.scala +++ b/li/cil/oc/server/component/Keyboard.scala @@ -1,7 +1,6 @@ package li.cil.oc.server.component import cpw.mods.fml.common.IPlayerTracker -import li.cil.oc.api import li.cil.oc.api.Network import li.cil.oc.api.network.{Node, Visibility, Message} import li.cil.oc.common.tileentity.Environment @@ -13,7 +12,7 @@ import scala.collection.mutable // TODO key up when screen is disconnected from which the key down came // TODO key up after load for anything that was pressed -class Keyboard(owner: Environment) extends api.network.Environment { +class Keyboard(owner: Environment) extends ManagedComponent { val node = Network.newNode(this, Visibility.Network). withComponent("keyboard"). create() @@ -34,19 +33,19 @@ class Keyboard(owner: Environment) extends api.network.Environment { // ----------------------------------------------------------------------- // - def onConnect(node: Node) { + override def onConnect(node: Node) { if (node == this.node) { MinecraftForge.EVENT_BUS.register(this) } } - def onDisconnect(node: Node) { + override def onDisconnect(node: Node) { if (node == this.node) { MinecraftForge.EVENT_BUS.unregister(this) } } - def onMessage(message: Message) = { + override def onMessage(message: Message) = { message.data match { case Array(p: EntityPlayer, char: Character, code: Integer) if message.name == "keyboard.keyDown" => if (isUseableByPlayer(p)) { diff --git a/li/cil/oc/server/component/ManagedComponent.scala b/li/cil/oc/server/component/ManagedComponent.scala index 381edde11..98030d27f 100644 --- a/li/cil/oc/server/component/ManagedComponent.scala +++ b/li/cil/oc/server/component/ManagedComponent.scala @@ -1,6 +1,7 @@ package li.cil.oc.server.component import li.cil.oc.api.network.{ManagedEnvironment, Node, Message} +import li.cil.oc.util.ExtendedNBT._ import net.minecraft.nbt.NBTTagCompound import scala.math.ScalaNumber @@ -14,11 +15,11 @@ abstract class ManagedComponent extends ManagedEnvironment { def onConnect(node: Node) {} def load(nbt: NBTTagCompound) = { - if (node != null) node.load(nbt) + if (node != null) node.load(nbt.getCompoundTag("node")) } def save(nbt: NBTTagCompound) = { - if (node != null) node.save(nbt) + if (node != null) nbt.setNewCompoundTag("node", node.save) } /** diff --git a/li/cil/oc/server/component/NetworkCard.scala b/li/cil/oc/server/component/NetworkCard.scala index 878334a2f..af167e920 100644 --- a/li/cil/oc/server/component/NetworkCard.scala +++ b/li/cil/oc/server/component/NetworkCard.scala @@ -1,8 +1,9 @@ package li.cil.oc.server.component +import li.cil.oc.api import li.cil.oc.api.network._ -import li.cil.oc.{Config, api} -import net.minecraft.nbt.{NBTTagInt, NBTTagList, NBTTagCompound} +import li.cil.oc.util.ExtendedNBT._ +import net.minecraft.nbt.{NBTTagInt, NBTTagCompound} import scala.collection.convert.WrapAsScala._ import scala.collection.mutable @@ -81,19 +82,15 @@ class NetworkCard extends ManagedComponent { override def load(nbt: NBTTagCompound) { super.load(nbt) - val openPortsNbt = nbt.getTagList(Config.namespace + "modem.openPorts") - (0 until openPortsNbt.tagCount). - map(openPortsNbt.tagAt). - map(_.asInstanceOf[NBTTagInt]). - foreach(portNbt => openPorts.add(portNbt.data)) + + assert(openPorts.isEmpty) + openPorts ++ nbt.getTagList("openPorts").iterator[NBTTagInt].map(_.data) } override def save(nbt: NBTTagCompound) { super.save(nbt) - val openPortsNbt = new NBTTagList() - for (port <- openPorts) - openPortsNbt.appendTag(new NBTTagInt(null, port)) - nbt.setTag(Config.namespace + "modem.openPorts", openPortsNbt) + + nbt.setNewTagList("openPorts", openPorts) } // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/server/component/PowerDistributor.scala b/li/cil/oc/server/component/PowerDistributor.scala new file mode 100644 index 000000000..07fc69baa --- /dev/null +++ b/li/cil/oc/server/component/PowerDistributor.scala @@ -0,0 +1,170 @@ +package li.cil.oc.server.component + +import li.cil.oc.api +import li.cil.oc.api.network._ +import li.cil.oc.common.tileentity.PowerInformation +import li.cil.oc.server.network.Connector +import li.cil.oc.server.{PacketSender => ServerPacketSender} +import scala.collection.convert.WrapAsScala._ +import scala.collection.mutable + +class PowerDistributor(val owner: PowerInformation) extends ManagedComponent { + + val node = api.Network.newNode(this, Visibility.Network). + withComponent("power", Visibility.Network). + create() + + var globalBuffer = 0.0 + + var globalBufferSize = 0.0 + + private var lastSentState = 0.0 + + private val buffers = mutable.Set.empty[Connector] + + private val distributors = mutable.Set.empty[PowerDistributor] + + private var dirty = true + + // ----------------------------------------------------------------------- // + + @LuaCallback(value = "buffer", direct = true) + def buffer(context: Context, args: Arguments): Array[AnyRef] = result(globalBuffer) + + @LuaCallback(value = "bufferSize", direct = true) + def bufferSize(context: Context, args: Arguments): Array[AnyRef] = result(globalBufferSize) + + // ----------------------------------------------------------------------- // + + def changeBuffer(delta: Double): Boolean = { + if (delta != 0) this.synchronized { + val oldBuffer = globalBuffer + globalBuffer = (globalBuffer + delta) max 0 min globalBufferSize + if (globalBuffer != oldBuffer) { + dirty = true + if (delta < 0) { + var remaining = -delta + for (connector <- buffers) { + connector.synchronized(if (connector.localBuffer > 0) { + connector.dirty = true + if (connector.localBuffer < remaining) { + remaining -= connector.localBuffer + connector.localBuffer = 0 + } + else { + connector.localBuffer -= remaining + return true + } + }) + } + } + else if (delta > 0) { + var remaining = delta + for (connector <- buffers) { + connector.synchronized(if (connector.localBuffer < connector.localBufferSize) { + connector.dirty = true + val space = connector.localBufferSize - connector.localBuffer + if (space < remaining) { + remaining -= space + connector.localBuffer = connector.localBufferSize + } + else { + connector.localBuffer += remaining + return true + } + }) + } + } + } + } + false + } + + // ----------------------------------------------------------------------- // + + override def update() { + if (node != null && (dirty || buffers.exists(_.dirty))) { + updateCachedValues() + } + } + + // ----------------------------------------------------------------------- // + + override def onConnect(node: Node) { + super.onConnect(node) + if (node == this.node) { + for (node <- node.reachableNodes) node match { + case connector: Connector if connector.localBufferSize > 0 => this.synchronized { + buffers += connector + globalBuffer += connector.localBuffer + globalBufferSize += connector.localBufferSize + } + case _ => node.host match { + case distributor: PowerDistributor if distributor.node.canBeSeenFrom(this.node) => + distributors += distributor + case _ => + } + } + distributors += this + dirty = true + } + else node match { + case connector: Connector if connector.localBufferSize > 0 => this.synchronized { + buffers += connector + globalBuffer += connector.localBuffer + globalBufferSize += connector.localBufferSize + dirty = true + } + case _ => node.host match { + case distributor: PowerDistributor if distributor.node.canBeSeenFrom(this.node) => + distributors += distributor + case _ => + } + } + } + + override def onDisconnect(node: Node) { + super.onDisconnect(node) + if (node == this.node) this.synchronized { + buffers.clear() + distributors.clear() + globalBuffer = 0 + globalBufferSize = 0 + } + else node match { + case connector: Connector => this.synchronized { + buffers -= connector + globalBuffer -= connector.localBuffer + globalBufferSize -= connector.localBufferSize + dirty = true + } + case _ => node.host match { + case distributor: PowerDistributor => distributors -= distributor + case _ => + } + } + } + + // ----------------------------------------------------------------------- // + + def updateCachedValues() { + // Computer average fill ratio of all buffers. + val (sumBuffer, sumBufferSize) = + buffers.foldRight((0.0, 0.0))((c, acc) => { + c.dirty = false // clear dirty flag for all connectors + (acc._1 + c.localBuffer, acc._2 + c.localBufferSize) + }) + val globalPower = if (globalBufferSize > 0) globalBuffer / globalBufferSize else 0 + val shouldSend = (lastSentState - globalPower).abs > 0.05 + for (distributor <- distributors) distributor.synchronized { + distributor.dirty = false + distributor.globalBuffer = sumBuffer + distributor.globalBufferSize = sumBufferSize + distributor.owner.globalPower = globalPower + if (shouldSend) { + distributor.lastSentState = lastSentState + ServerPacketSender.sendPowerState(owner) + } + } + } +} diff --git a/li/cil/oc/server/component/PowerSupply.scala b/li/cil/oc/server/component/PowerSupply.scala index 3511c6d13..0a1eb87bb 100644 --- a/li/cil/oc/server/component/PowerSupply.scala +++ b/li/cil/oc/server/component/PowerSupply.scala @@ -1,11 +1,10 @@ package li.cil.oc.server.component -import li.cil.oc.api.network.{Context, Arguments, LuaCallback, Visibility} +import li.cil.oc.api.network.Visibility import li.cil.oc.{Config, api} class PowerSupply extends ManagedComponent { val node = api.Network.newNode(this, Visibility.Network). - withComponent("psu"). withConnector(Config.bufferPowerSupply). create() @@ -13,10 +12,4 @@ class PowerSupply extends ManagedComponent { super.update() node.changeBuffer(-Config.powerSupplyCost) } - - @LuaCallback(value = "localBufferSize", direct = true) - def bufferSize(context: Context, args: Arguments): Array[AnyRef] = result(node.localBufferSize) - - @LuaCallback(value = "localBuffer", direct = true) - def buffer(context: Context, args: Arguments): Array[AnyRef] = result(node.localBuffer) } diff --git a/li/cil/oc/server/component/WirelessNetworkCard.scala b/li/cil/oc/server/component/WirelessNetworkCard.scala index 9bbaacb86..177b674f0 100644 --- a/li/cil/oc/server/component/WirelessNetworkCard.scala +++ b/li/cil/oc/server/component/WirelessNetworkCard.scala @@ -86,13 +86,13 @@ class WirelessNetworkCard(val owner: TileEntity) extends NetworkCard { override def load(nbt: NBTTagCompound) { super.load(nbt) - if (nbt.hasKey(Config.namespace + "modem.strength")) { - strength = nbt.getDouble(Config.namespace + "modem.strength") + if (nbt.hasKey("modem")) { + strength = nbt.getDouble("strength") } } override def save(nbt: NBTTagCompound) { super.save(nbt) - nbt.setDouble(Config.namespace + "modem.strength", strength) + nbt.setDouble("strength", strength) } } diff --git a/li/cil/oc/server/network/Connector.scala b/li/cil/oc/server/network/Connector.scala index cf21b04f3..0d9875b54 100644 --- a/li/cil/oc/server/network/Connector.scala +++ b/li/cil/oc/server/network/Connector.scala @@ -3,7 +3,7 @@ package li.cil.oc.server.network import li.cil.oc.Config import li.cil.oc.api.network import li.cil.oc.api.network.{Node => ImmutableNode} -import li.cil.oc.common.tileentity.PowerDistributor +import li.cil.oc.server.component.PowerDistributor import li.cil.oc.util.Persistable import net.minecraft.nbt.NBTTagCompound import scala.collection.convert.WrapAsScala._ @@ -51,14 +51,15 @@ trait Connector extends Node with network.Connector with Persistable { override def onConnect(node: ImmutableNode) { if (node == this) findDistributor() else if (distributor.isEmpty) node.host match { - case distributor: PowerDistributor => this.distributor = Some(distributor) + case distributor: PowerDistributor => + this.distributor = Some(distributor) case _ => } super.onConnect(node) } override def onDisconnect(node: ImmutableNode) { - if (node != this && distributor.exists(_ == node.host)) findDistributor() + if (node != this && distributor.exists(_ == node)) findDistributor() super.onDisconnect(node) } @@ -70,12 +71,12 @@ trait Connector extends Node with network.Connector with Persistable { override def load(nbt: NBTTagCompound) { super.load(nbt) - localBuffer = nbt.getDouble(Config.namespace + "connector.buffer") max 0 min localBufferSize + localBuffer = nbt.getDouble("buffer") max 0 min localBufferSize dirty = true } override def save(nbt: NBTTagCompound) { super.save(nbt) - nbt.setDouble(Config.namespace + "connector.buffer", localBuffer) + nbt.setDouble("buffer", localBuffer) } } diff --git a/li/cil/oc/server/network/Network.scala b/li/cil/oc/server/network/Network.scala index 0e115ad18..9c13d5849 100644 --- a/li/cil/oc/server/network/Network.scala +++ b/li/cil/oc/server/network/Network.scala @@ -259,6 +259,8 @@ object Network extends api.detail.NetworkAPI { case _ => // Invalid block. } + def create(node: ImmutableNode): Unit = 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 { case Some(block) if block.hasTileEntity(world.getBlockMetadata(x, y, z)) => diff --git a/li/cil/oc/server/network/Node.scala b/li/cil/oc/server/network/Node.scala index 2d41f82b1..83bc82aa9 100644 --- a/li/cil/oc/server/network/Node.scala +++ b/li/cil/oc/server/network/Node.scala @@ -1,8 +1,8 @@ package li.cil.oc.server.network +import li.cil.oc.api import li.cil.oc.api.network.{Environment, Visibility, Node => ImmutableNode} import li.cil.oc.util.Persistable -import li.cil.oc.{Config, api} import net.minecraft.nbt.NBTTagCompound import scala.collection.convert.WrapAsJava._ import scala.collection.convert.WrapAsScala._ @@ -64,15 +64,15 @@ trait Node extends api.network.Node with Persistable { override def load(nbt: NBTTagCompound) = { super.load(nbt) - if (nbt.hasKey(Config.namespace + "node.address")) { - address = nbt.getString(Config.namespace + "node.address") + if (nbt.hasKey("address")) { + address = nbt.getString("address") } } override def save(nbt: NBTTagCompound) = { super.save(nbt) if (address != null) { - nbt.setString(Config.namespace + "node.address", address) + nbt.setString("address", address) } } } \ No newline at end of file diff --git a/li/cil/oc/util/ExtendedLuaState.scala b/li/cil/oc/util/ExtendedLuaState.scala index bc12e5c6b..653777a38 100644 --- a/li/cil/oc/util/ExtendedLuaState.scala +++ b/li/cil/oc/util/ExtendedLuaState.scala @@ -7,7 +7,7 @@ object ExtendedLuaState { implicit def extendLuaState(state: LuaState) = new ExtendedLuaState(state) - class ExtendedLuaState(state: LuaState) { + class ExtendedLuaState(val state: LuaState) { def pushScalaFunction(f: (LuaState) => Int) = state.pushJavaFunction(new JavaFunction { override def invoke(state: LuaState) = f(state) }) diff --git a/li/cil/oc/util/ExtendedNBT.scala b/li/cil/oc/util/ExtendedNBT.scala new file mode 100644 index 000000000..9b09512ae --- /dev/null +++ b/li/cil/oc/util/ExtendedNBT.scala @@ -0,0 +1,84 @@ +package li.cil.oc.util + +import net.minecraft.nbt._ +import scala.language.implicitConversions + +object ExtendedNBT { + + implicit def toNbt(value: Byte) = new NBTTagByte(null, value) + + implicit def toNbt(value: Short) = new NBTTagShort(null, value) + + implicit def toNbt(value: Int) = new NBTTagInt(null, value) + + implicit def toNbt(value: Long) = new NBTTagLong(null, value) + + implicit def toNbt(value: Float) = new NBTTagFloat(null, value) + + implicit def toNbt(value: Double) = new NBTTagDouble(null, value) + + implicit def toNbt(value: Array[Byte]) = new NBTTagByteArray(null, value) + + implicit def toNbt(value: String) = new NBTTagString(null, value) + + implicit def byteIterableToNbt(value: Iterable[Byte]) = value.map(toNbt) + + implicit def shortIterableToNbt(value: Iterable[Short]) = value.map(toNbt) + + implicit def intIterableToNbt(value: Iterable[Int]) = value.map(toNbt) + + implicit def longIterableToNbt(value: Iterable[Long]) = value.map(toNbt) + + implicit def floatIterableToNbt(value: Iterable[Float]) = value.map(toNbt) + + implicit def doubleIterableToNbt(value: Iterable[Double]) = value.map(toNbt) + + implicit def byteArrayIterableToNbt(value: Iterable[Array[Byte]]) = value.map(toNbt) + + implicit def stringIterableToNbt(value: Iterable[String]) = value.map(toNbt) + + implicit def extendNBTTagCompound(nbt: NBTTagCompound) = new ExtendedNBTTagCompound(nbt) + + implicit def extendNBTTagList(nbt: NBTTagList) = new ExtendedNBTTagList(nbt) + + class ExtendedNBTTagCompound(val nbt: NBTTagCompound) { + def setNewCompoundTag(name: String, f: (NBTTagCompound) => Any) = { + val t = new NBTTagCompound() + f(t) + nbt.setCompoundTag(name, t) + nbt + } + + def setNewTagList(name: String, values: Iterable[NBTBase]) = { + val t = new NBTTagList() + t.append(values) + nbt.setTag(name, t) + nbt + } + + def setNewTagList(name: String, values: NBTBase*): NBTTagCompound = setNewTagList(name, values) + } + + class ExtendedNBTTagList(val nbt: NBTTagList) { + def appendNewCompoundTag(f: (NBTTagCompound) => Unit) { + val t = new NBTTagCompound() + f(t) + nbt.appendTag(t) + } + + def append(values: Iterable[NBTBase]) { + for (value <- values) { + nbt.appendTag(value) + } + } + + def append(values: NBTBase*): Unit = append(values) + + def iterator[Tag <: NBTBase] = (0 until nbt.tagCount).map(nbt.tagAt).map(_.asInstanceOf[Tag]) + + def foreach[Tag <: NBTBase](f: (Tag) => Unit) = iterator[Tag].foreach(f) + + def map[Tag <: NBTBase, Value](f: (Tag) => Value) = iterator[Tag].map(f) + } + +} diff --git a/li/cil/oc/util/RenderState.scala b/li/cil/oc/util/RenderState.scala index e8a1b7576..ec3eaa74c 100644 --- a/li/cil/oc/util/RenderState.scala +++ b/li/cil/oc/util/RenderState.scala @@ -39,6 +39,20 @@ object RenderState { } } + def enableLighting() { + GL11.glEnable(GL11.GL_LIGHTING) + if (arb) { + ARBMultitexture.glActiveTextureARB(OpenGlHelper.lightmapTexUnit) + GL11.glEnable(GL11.GL_TEXTURE_2D) + ARBMultitexture.glActiveTextureARB(OpenGlHelper.defaultTexUnit) + } + else { + GL13.glActiveTexture(OpenGlHelper.lightmapTexUnit) + GL11.glEnable(GL11.GL_TEXTURE_2D) + GL13.glActiveTexture(OpenGlHelper.defaultTexUnit) + } + } + def makeItBlend() { GL11.glEnable(GL11.GL_BLEND) GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)