mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-16 02:39:48 -04:00
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
This commit is contained in:
parent
6e1ba98ecf
commit
f135d86b58
Binary file not shown.
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 220 B |
@ -7,6 +7,11 @@ package li.cil.oc.api.driver;
|
||||
* a computer's inventory.
|
||||
*/
|
||||
public enum Slot {
|
||||
/**
|
||||
* Invalid slot type.
|
||||
*/
|
||||
None,
|
||||
|
||||
/**
|
||||
* Extension cards such as graphics cards or redstone cards.
|
||||
*/
|
||||
|
@ -63,8 +63,8 @@ class PacketHandler extends CommonPacketHandler {
|
||||
}
|
||||
|
||||
def onPowerStateResponse(p: PacketParser) =
|
||||
p.readTileEntity[PowerDistributor]() match {
|
||||
case Some(t) => t.average = p.readDouble()
|
||||
p.readTileEntity[PowerInformation]() match {
|
||||
case Some(t) => t.globalPower = p.readDouble()
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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])
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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) =
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
5
li/cil/oc/common/tileentity/PowerInformation.scala
Normal file
5
li/cil/oc/common/tileentity/PowerInformation.scala
Normal file
@ -0,0 +1,5 @@
|
||||
package li.cil.oc.common.tileentity
|
||||
|
||||
trait PowerInformation extends TileEntity {
|
||||
var globalPower = 0.0
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -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.
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
170
li/cil/oc/server/component/PowerDistributor.scala
Normal file
170
li/cil/oc/server/component/PowerDistributor.scala
Normal file
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)) =>
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
})
|
||||
|
84
li/cil/oc/util/ExtendedNBT.scala
Normal file
84
li/cil/oc/util/ExtendedNBT.scala
Normal file
@ -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)
|
||||
}
|
||||
|
||||
}
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user