disk drive and floppy disks (disk drives are mountable and act as a "proxy" for the item in them); minor refactoring;
@ -3,6 +3,8 @@ oc.block.Computer.name=Computer
|
||||
oc.block.Keyboard.name=Tastatur
|
||||
oc.block.Screen.name=Bildschirm
|
||||
oc.container.computer=Computer
|
||||
oc.container.disk_drive=Diskettenlaufwerk
|
||||
oc.item.Disk.name=Diskette
|
||||
oc.item.GraphicsCard.name=Grafikkarte
|
||||
oc.item.HardDiskDrive2m.name=Festplatte (2MB)
|
||||
oc.item.HardDiskDrive4m.name=Festplatte (4MB)
|
||||
|
@ -3,6 +3,8 @@ oc.block.Computer.name=Computer
|
||||
oc.block.Keyboard.name=Keyboard
|
||||
oc.block.Screen.name=Screen
|
||||
oc.container.computer=Computer
|
||||
oc.container.disk_drive=Disk Drive
|
||||
oc.item.Disk.name=Floppy Disk
|
||||
oc.item.GraphicsCard.name=Graphics Card
|
||||
oc.item.HardDiskDrive2m.name=Hard Disk Drive (2MB)
|
||||
oc.item.HardDiskDrive4m.name=Hard Disk Drive (4MB)
|
||||
|
@ -180,7 +180,9 @@ local function main(args)
|
||||
debug.sethook(co, checkDeadline, "", 10000)
|
||||
end
|
||||
local result = table.pack(coroutine.resume(co, table.unpack(args, 1, args.n)))
|
||||
if result[1] then
|
||||
if coroutine.status(co) == "dead" then
|
||||
error("computer stopped unexpectedly", 0)
|
||||
elseif result[1] then
|
||||
args = table.pack(coroutine.yield(result[2])) -- system yielded value
|
||||
else
|
||||
error(result[2], 0)
|
||||
|
@ -109,9 +109,10 @@ end
|
||||
function event.wait(seconds)
|
||||
seconds = seconds or 0/0
|
||||
checkArg(1, seconds, "number")
|
||||
local target = os.uptime() + (seconds == seconds and seconds or 0)
|
||||
local function isNaN(n) return n ~= n end
|
||||
local target = os.uptime() + (isNaN(seconds) and 0 or seconds)
|
||||
repeat
|
||||
local closest = seconds == seconds and target or math.huge
|
||||
local closest = isNaN(seconds) and math.huge or target
|
||||
for _, info in pairs(timers) do
|
||||
if info.after < closest then
|
||||
closest = info.after
|
||||
|
@ -23,7 +23,8 @@ end
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function onComponentAdded(_, address)
|
||||
if component.type(address) == "filesystem" and
|
||||
local componentType = component.type(address)
|
||||
if (componentType == "filesystem" or componentType == "disk_drive") and
|
||||
address ~= os.romAddress() and
|
||||
address ~= os.tmpAddress()
|
||||
then
|
||||
@ -44,7 +45,8 @@ local function onComponentAdded(_, address)
|
||||
end
|
||||
|
||||
local function onComponentRemoved(_, address)
|
||||
if component.type(address) == "filesystem" then
|
||||
local componentType = component.type(address)
|
||||
if componentType == "filesystem" or componentType == "disk_drive" then
|
||||
fs.umount(address)
|
||||
end
|
||||
end
|
||||
|
Before Width: | Height: | Size: 650 B After Width: | Height: | Size: 399 B |
BIN
assets/opencomputers/textures/blocks/disk_drive_front.png
Normal file
After Width: | Height: | Size: 592 B |
BIN
assets/opencomputers/textures/blocks/disk_drive_side.png
Normal file
After Width: | Height: | Size: 605 B |
BIN
assets/opencomputers/textures/gui/background.png
Normal file
After Width: | Height: | Size: 542 B |
Before Width: | Height: | Size: 583 B |
BIN
assets/opencomputers/textures/gui/slot.png
Normal file
After Width: | Height: | Size: 143 B |
BIN
assets/opencomputers/textures/items/disk.png
Normal file
After Width: | Height: | Size: 508 B |
@ -14,6 +14,7 @@ object Blocks {
|
||||
var powerDistributor: PowerDistributor = null
|
||||
|
||||
var adapter: Adapter = null
|
||||
var diskDrive: DiskDrive = null
|
||||
|
||||
def init() {
|
||||
// IMPORTANT: the multi block must come first, since the sub blocks will
|
||||
@ -30,5 +31,6 @@ object Blocks {
|
||||
powerDistributor = new PowerDistributor(blockSimple)
|
||||
|
||||
adapter = new Adapter(blockSimple)
|
||||
diskDrive = new DiskDrive(blockSimple)
|
||||
}
|
||||
}
|
@ -9,28 +9,29 @@ object Items {
|
||||
var rs: item.RedstoneCard = null
|
||||
var lan: item.NetworkCard = null
|
||||
|
||||
var ram32k: item.Memory = null
|
||||
var ram64k: item.Memory = null
|
||||
var ram128k: item.Memory = null
|
||||
var ram1: item.Memory = null
|
||||
var ram2: item.Memory = null
|
||||
var ram3: item.Memory = null
|
||||
|
||||
var hdd2: item.Hdd = null
|
||||
var hdd4: item.Hdd = null
|
||||
var hdd8: item.Hdd = null
|
||||
var hdd1: item.HardDiskDrive = null
|
||||
var hdd2: item.HardDiskDrive = null
|
||||
var hdd3: item.HardDiskDrive = null
|
||||
var disk: item.Disk = null
|
||||
|
||||
def init() {
|
||||
multi = new item.Delegator(Config.itemId)
|
||||
|
||||
gpu = new item.GraphicsCard(multi)
|
||||
rs = new item.RedstoneCard(multi)
|
||||
|
||||
ram32k = new item.Memory(multi, 32)
|
||||
ram64k = new item.Memory(multi, 64)
|
||||
ram128k = new item.Memory(multi, 128)
|
||||
|
||||
hdd2 = new item.Hdd(multi, 2)
|
||||
hdd4 = new item.Hdd(multi, 4)
|
||||
hdd8 = new item.Hdd(multi, 8)
|
||||
|
||||
lan = new item.NetworkCard(multi)
|
||||
|
||||
ram1 = new item.Memory(multi, 32)
|
||||
ram2 = new item.Memory(multi, 64)
|
||||
ram3 = new item.Memory(multi, 128)
|
||||
|
||||
hdd1 = new item.HardDiskDrive(multi, 2)
|
||||
hdd2 = new item.HardDiskDrive(multi, 4)
|
||||
hdd3 = new item.HardDiskDrive(multi, 8)
|
||||
disk = new item.Disk(multi)
|
||||
}
|
||||
}
|
@ -209,10 +209,12 @@ trait FileSystem extends Persistable {
|
||||
def file(handle: Int): Option[Handle]
|
||||
|
||||
/**
|
||||
* Called when the file system is deconstructed.
|
||||
* Called when the file system is close.
|
||||
* <p/>
|
||||
* This should close any open real file handles (e.g. all open I/O streams)
|
||||
* and clear any other internal state.
|
||||
* This should close any open real file handles (e.g. all open I/O streams),
|
||||
* but keep any internal state that may have to be persisted, for example
|
||||
* for floppy disks (which are removed before they are saved so they don't
|
||||
* save any open handles).
|
||||
* <p/>
|
||||
* When the filesystem is made available as a network node created via
|
||||
* `FileSystem.asNode` this will be called whenever the node is disconnected
|
||||
|
@ -44,6 +44,7 @@ trait Item extends Driver {
|
||||
* driver supports may go. This will only be called if a previous call to
|
||||
* `worksWith` with the same item type returned true.
|
||||
*
|
||||
* @param item the item to get the slot type for.
|
||||
* @return the component type of the specified item.
|
||||
*/
|
||||
def slot(item: ItemStack): Slot.Value
|
||||
|
20
li/cil/oc/api/driver/Memory.scala
Normal file
@ -0,0 +1,20 @@
|
||||
package li.cil.oc.api.driver
|
||||
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
/**
|
||||
* Use this trait to implement components extending the memory of a computer.
|
||||
* <p/>
|
||||
* Note that the item must be installed in the actual computer's inventory to
|
||||
* work. If it is installed in an external inventory the computer will not
|
||||
* recognize the memory.
|
||||
*/
|
||||
trait Memory extends Item {
|
||||
/**
|
||||
* The amount of RAM this component provides, in byte.
|
||||
*
|
||||
* @param item the item to get the provided memory for.
|
||||
* @return the amount of memory the specified component provides.
|
||||
*/
|
||||
def amount(item: ItemStack): Int
|
||||
}
|
@ -8,8 +8,18 @@ package li.cil.oc.api.driver
|
||||
* inside the computer, not next to it.
|
||||
*/
|
||||
object Slot extends Enumeration {
|
||||
val PSU = Value("PSU")
|
||||
val RAM = Value("RAM")
|
||||
val HDD = Value("HDD")
|
||||
val PCI = Value("PCI")
|
||||
/** Power generating components, such as generators. */
|
||||
val Power = Value("Power")
|
||||
|
||||
/** Memory extension components. */
|
||||
val Memory = Value("Memory")
|
||||
|
||||
/** Hard disk drives. */
|
||||
val HardDiskDrive = Value("HardDiskDrive")
|
||||
|
||||
/** Extension cards such as graphics or redstone cards. */
|
||||
val Card = Value("Card")
|
||||
|
||||
/** Floppy disks. */
|
||||
val Disk = Value("Disk")
|
||||
}
|
@ -76,7 +76,7 @@ trait Node extends Persistable {
|
||||
* they have is to *not* have an address, which can be useful for "dummy"
|
||||
* nodes, such as cables. In that case they may ignore the address being set.
|
||||
*/
|
||||
var address: Option[String] = None
|
||||
final var address: Option[String] = None
|
||||
|
||||
/**
|
||||
* The network this node is currently in.
|
||||
@ -88,7 +88,7 @@ trait Node extends Persistable {
|
||||
* This will always be set automatically by the network manager. Do not
|
||||
* change this value and do not return anything that it wasn't set to.
|
||||
*/
|
||||
var network: Option[Network] = None
|
||||
final var network: Option[Network] = None
|
||||
|
||||
/**
|
||||
* Makes the node handle a message.
|
||||
@ -183,7 +183,7 @@ trait Node extends Persistable {
|
||||
* @param args the values to return.
|
||||
* @return and array option as required by `receive`.
|
||||
*/
|
||||
protected def result(args: Any*): Option[Array[Any]] = {
|
||||
final protected def result(args: Any*): Option[Array[Any]] = {
|
||||
def unwrap(arg: Any): AnyRef = arg match {
|
||||
case x: ScalaNumber => x.underlying
|
||||
case x => x.asInstanceOf[AnyRef]
|
||||
|
@ -1,6 +1,6 @@
|
||||
package li.cil.oc.client
|
||||
|
||||
import li.cil.oc.common.tileentity.{Screen, Computer}
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.common.{GuiHandler => CommonGuiHandler, GuiType}
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.world.World
|
||||
@ -8,10 +8,12 @@ import net.minecraft.world.World
|
||||
object GuiHandler extends CommonGuiHandler {
|
||||
override def getClientGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int) =
|
||||
world.getBlockTileEntity(x, y, z) match {
|
||||
case tileEntity: Computer if id == GuiType.Computer.id =>
|
||||
new gui.Computer(player.inventory, tileEntity)
|
||||
case tileEntity: Screen if id == GuiType.Screen.id =>
|
||||
new gui.Screen(tileEntity)
|
||||
case computer: tileentity.Computer if id == GuiType.Computer.id =>
|
||||
new gui.Computer(player.inventory, computer)
|
||||
case screen: tileentity.Screen if id == GuiType.Screen.id =>
|
||||
new gui.Screen(screen)
|
||||
case drive: tileentity.DiskDrive if id == GuiType.DiskDrive.id =>
|
||||
new gui.DiskDrive(player.inventory, drive)
|
||||
case _ => null
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import cpw.mods.fml.relauncher.Side
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.common.{Proxy => CommonProxy}
|
||||
import li.cil.oc.client.renderer.tileentity.{PowerDistributorRenderer, ScreenRenderer, ComputerRenderer}
|
||||
|
||||
private[oc] class Proxy extends CommonProxy {
|
||||
override def init(e: FMLInitializationEvent) = {
|
||||
|
@ -3,17 +3,11 @@ package li.cil.oc.client.gui
|
||||
import li.cil.oc.Config
|
||||
import li.cil.oc.common.container
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.client.gui.inventory.GuiContainer
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
import net.minecraft.inventory.Slot
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraft.util.StatCollector
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
class Computer(inventory: InventoryPlayer, val tileEntity: tileentity.Computer) extends GuiContainer(new container.Computer(inventory, tileEntity)) {
|
||||
private val background = new ResourceLocation(Config.resourceDomain, "textures/gui/computer.png")
|
||||
import net.minecraft.util.{ResourceLocation, StatCollector}
|
||||
|
||||
class Computer(playerInventory: InventoryPlayer, val computer: tileentity.Computer) extends DynamicGuiContainer(new container.Computer(playerInventory, computer)) {
|
||||
private val iconPsu = new ResourceLocation(Config.resourceDomain, "textures/gui/icon_psu.png")
|
||||
private val iconPci = new ResourceLocation(Config.resourceDomain, "textures/gui/icon_pci.png")
|
||||
private val iconRam = new ResourceLocation(Config.resourceDomain, "textures/gui/icon_ram.png")
|
||||
@ -21,52 +15,18 @@ class Computer(inventory: InventoryPlayer, val tileEntity: tileentity.Computer)
|
||||
|
||||
private val icons = Array(iconPsu, iconPci, iconPci, iconPci, iconRam, iconRam, iconHdd, iconHdd)
|
||||
|
||||
private var (x, y) = (0, 0)
|
||||
|
||||
override def initGui() = {
|
||||
super.initGui()
|
||||
x = (width - xSize) / 2
|
||||
y = (height - ySize) / 2
|
||||
}
|
||||
|
||||
override def drawSlotInventory(slot: Slot) = {
|
||||
super.drawSlotInventory(slot)
|
||||
if (slot.slotNumber < 8 && !slot.getHasStack)
|
||||
drawSlotIcon(slot, icons(slot.slotNumber))
|
||||
}
|
||||
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
fontRenderer.drawString(
|
||||
StatCollector.translateToLocal("oc.container.computer"),
|
||||
8, 6, 0x404040)
|
||||
fontRenderer.drawString(
|
||||
StatCollector.translateToLocal("container.inventory"),
|
||||
8, ySize - 96 + 2, 0x404040)
|
||||
}
|
||||
|
||||
override def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) = {
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F)
|
||||
mc.renderEngine.bindTexture(background)
|
||||
drawTexturedModalRect(x, y, 0, 0, xSize, ySize)
|
||||
}
|
||||
override protected def bindIconBackground(slot: Slot) =
|
||||
if (slot.slotNumber < 8 && !slot.getHasStack) {
|
||||
mc.renderEngine.bindTexture(icons(slot.slotNumber))
|
||||
true
|
||||
}
|
||||
else false
|
||||
|
||||
override def doesGuiPauseGame = false
|
||||
|
||||
private def drawSlotIcon(slot: Slot, icon: ResourceLocation) = {
|
||||
GL11.glPushAttrib(0xFFFFFF)
|
||||
GL11.glDisable(GL11.GL_LIGHTING)
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST)
|
||||
GL11.glEnable(GL11.GL_BLEND)
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)
|
||||
GL11.glColor4f(1, 1, 1, 0.25f)
|
||||
mc.renderEngine.bindTexture(icon)
|
||||
val t = Tessellator.instance
|
||||
t.startDrawingQuads()
|
||||
t.addVertexWithUV(slot.xDisplayPosition, slot.yDisplayPosition + 16, zLevel, 0, 1)
|
||||
t.addVertexWithUV(slot.xDisplayPosition + 16, slot.yDisplayPosition + 16, zLevel, 1, 1)
|
||||
t.addVertexWithUV(slot.xDisplayPosition + 16, slot.yDisplayPosition, zLevel, 1, 0)
|
||||
t.addVertexWithUV(slot.xDisplayPosition, slot.yDisplayPosition, zLevel, 0, 0)
|
||||
t.draw()
|
||||
GL11.glPopAttrib()
|
||||
}
|
||||
}
|
14
li/cil/oc/client/gui/DiskDrive.scala
Normal file
@ -0,0 +1,14 @@
|
||||
package li.cil.oc.client.gui
|
||||
|
||||
import li.cil.oc.common.container
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
import net.minecraft.util.StatCollector
|
||||
|
||||
class DiskDrive(playerInventory: InventoryPlayer, val drive: tileentity.DiskDrive) extends DynamicGuiContainer(new container.DiskDrive(playerInventory, drive)) {
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
fontRenderer.drawString(
|
||||
StatCollector.translateToLocal("oc.container.disk_drive"),
|
||||
8, 6, 0x404040)
|
||||
}
|
||||
}
|
65
li/cil/oc/client/gui/DynamicGuiContainer.scala
Normal file
@ -0,0 +1,65 @@
|
||||
package li.cil.oc.client.gui
|
||||
|
||||
import li.cil.oc.Config
|
||||
import net.minecraft.client.gui.inventory.GuiContainer
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.inventory.{Container, Slot}
|
||||
import net.minecraft.util.{StatCollector, ResourceLocation}
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
abstract class DynamicGuiContainer(container: Container) extends GuiContainer(container) {
|
||||
protected val slotBackground = new ResourceLocation(Config.resourceDomain, "textures/gui/slot.png")
|
||||
protected val background = new ResourceLocation(Config.resourceDomain, "textures/gui/background.png")
|
||||
|
||||
protected var (x, y) = (0, 0)
|
||||
|
||||
override def initGui() = {
|
||||
super.initGui()
|
||||
x = (width - xSize) / 2
|
||||
y = (height - ySize) / 2
|
||||
}
|
||||
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
fontRenderer.drawString(
|
||||
StatCollector.translateToLocal("container.inventory"),
|
||||
8, ySize - 96 + 2, 0x404040)
|
||||
}
|
||||
|
||||
override def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) = {
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F)
|
||||
mc.renderEngine.bindTexture(background)
|
||||
drawTexturedModalRect(x, y, 0, 0, xSize, ySize)
|
||||
}
|
||||
|
||||
override def drawSlotInventory(slot: Slot) = {
|
||||
if (slot.slotNumber < container.inventorySlots.size() - 36) {
|
||||
mc.renderEngine.bindTexture(slotBackground)
|
||||
drawSlot(slot.xDisplayPosition - 1, slot.yDisplayPosition - 1, 18)
|
||||
}
|
||||
super.drawSlotInventory(slot)
|
||||
if (bindIconBackground(slot))
|
||||
drawSlot(slot.xDisplayPosition, slot.yDisplayPosition, 16, blend = true)
|
||||
}
|
||||
|
||||
protected def bindIconBackground(slot: Slot) = false
|
||||
|
||||
private def drawSlot(x: Int, y: Int, size: Int, blend: Boolean = false) {
|
||||
GL11.glPushAttrib(0xFFFFFF)
|
||||
GL11.glDisable(GL11.GL_LIGHTING)
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST)
|
||||
if (blend) {
|
||||
GL11.glEnable(GL11.GL_BLEND)
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)
|
||||
GL11.glColor4f(1, 1, 1, 0.25f)
|
||||
}
|
||||
else GL11.glColor4f(1, 1, 1, 1)
|
||||
val t = Tessellator.instance
|
||||
t.startDrawingQuads()
|
||||
t.addVertexWithUV(x, y + size, zLevel, 0, 1)
|
||||
t.addVertexWithUV(x + size, y + size, zLevel, 1, 1)
|
||||
t.addVertexWithUV(x + size, y, zLevel, 1, 0)
|
||||
t.addVertexWithUV(x, y, zLevel, 0, 0)
|
||||
t.draw()
|
||||
GL11.glPopAttrib()
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package li.cil.oc.client
|
||||
package li.cil.oc.client.renderer.tileentity
|
||||
|
||||
import li.cil.oc.Config
|
||||
import li.cil.oc.common.tileentity.Computer
|
||||
@ -8,6 +8,7 @@ import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
import org.lwjgl.opengl.GL11
|
||||
import li.cil.oc.util.RenderState
|
||||
|
||||
object ComputerRenderer extends TileEntitySpecialRenderer {
|
||||
private val frontOn = new ResourceLocation(Config.resourceDomain, "textures/blocks/computer_front_on.png")
|
||||
@ -17,8 +18,8 @@ object ComputerRenderer extends TileEntitySpecialRenderer {
|
||||
if (computer.isOn) {
|
||||
GL11.glPushAttrib(0xFFFFFF)
|
||||
|
||||
RenderUtil.disableLighting()
|
||||
RenderUtil.makeItBlend()
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
|
||||
GL11.glPushMatrix()
|
||||
|
@ -1,4 +1,4 @@
|
||||
package li.cil.oc.client
|
||||
package li.cil.oc.client.renderer.tileentity
|
||||
|
||||
import li.cil.oc.Config
|
||||
import li.cil.oc.common.tileentity
|
||||
@ -7,6 +7,7 @@ import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import org.lwjgl.opengl.GL11
|
||||
import li.cil.oc.util.RenderState
|
||||
|
||||
object PowerDistributorRenderer extends TileEntitySpecialRenderer {
|
||||
private val sideOn = new ResourceLocation(Config.resourceDomain, "textures/blocks/power_distributor_on.png")
|
||||
@ -16,8 +17,8 @@ object PowerDistributorRenderer extends TileEntitySpecialRenderer {
|
||||
if (distributor.isActive) {
|
||||
GL11.glPushAttrib(0xFFFFFF)
|
||||
|
||||
RenderUtil.disableLighting()
|
||||
RenderUtil.makeItBlend()
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
|
||||
GL11.glPushMatrix()
|
||||
|
@ -1,4 +1,4 @@
|
||||
package li.cil.oc.client
|
||||
package li.cil.oc.client.renderer.tileentity
|
||||
|
||||
import com.google.common.cache.{CacheBuilder, RemovalNotification, RemovalListener}
|
||||
import cpw.mods.fml.common.{TickType, ITickHandler}
|
||||
@ -12,6 +12,7 @@ import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
import org.lwjgl.opengl.{GL14, GL11}
|
||||
import li.cil.oc.util.RenderState
|
||||
|
||||
object ScreenRenderer extends TileEntitySpecialRenderer with Callable[Int] with RemovalListener[TileEntity, Int] with ITickHandler {
|
||||
|
||||
@ -52,8 +53,8 @@ object ScreenRenderer extends TileEntitySpecialRenderer with Callable[Int] with
|
||||
|
||||
GL11.glPushAttrib(0xFFFFFF)
|
||||
|
||||
RenderUtil.disableLighting()
|
||||
RenderUtil.makeItBlend()
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
|
||||
GL11.glPushMatrix()
|
||||
|
@ -1,15 +1,16 @@
|
||||
package li.cil.oc.common
|
||||
|
||||
import cpw.mods.fml.common.network.IGuiHandler
|
||||
import li.cil.oc.common.tileentity.Computer
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.world.World
|
||||
|
||||
abstract class GuiHandler extends IGuiHandler {
|
||||
override def getServerGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int) =
|
||||
world.getBlockTileEntity(x, y, z) match {
|
||||
case tileEntity: Computer =>
|
||||
new container.Computer(player.inventory, tileEntity)
|
||||
case computer: tileentity.Computer =>
|
||||
new container.Computer(player.inventory, computer)
|
||||
case drive: tileentity.DiskDrive =>
|
||||
new container.DiskDrive(player.inventory, drive)
|
||||
case _ => null
|
||||
}
|
||||
}
|
@ -3,4 +3,5 @@ package li.cil.oc.common
|
||||
object GuiType extends Enumeration {
|
||||
val Computer = Value("Computer")
|
||||
val Screen = Value("Screen")
|
||||
val DiskDrive = Value("DiskDrive")
|
||||
}
|
||||
|
@ -16,8 +16,6 @@ class Computer(val parent: Delegator) extends Delegate {
|
||||
|
||||
val unlocalizedName = "Computer"
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Rendering stuff
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
private object Icons {
|
||||
@ -55,16 +53,12 @@ class Computer(val parent: Delegator) extends Delegate {
|
||||
Icons.on(ForgeDirection.EAST.ordinal) = Icons.on(ForgeDirection.WEST.ordinal)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Tile entity
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def hasTileEntity = true
|
||||
|
||||
override def createTileEntity(world: World, metadata: Int) = Some(new tileentity.Computer(world.isRemote))
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Destruction / Interaction
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def canConnectRedstone(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) =
|
||||
@ -77,8 +71,12 @@ class Computer(val parent: Delegator) extends Delegate {
|
||||
world.getBlockTileEntity(x, y, z).asInstanceOf[tileentity.Computer].output(side)
|
||||
|
||||
override def breakBlock(world: World, x: Int, y: Int, z: Int, blockId: Int, metadata: Int) = {
|
||||
if (!world.isRemote)
|
||||
world.getBlockTileEntity(x, y, z).asInstanceOf[tileentity.Computer].turnOff()
|
||||
if (!world.isRemote) world.getBlockTileEntity(x, y, z) match {
|
||||
case computer: tileentity.Computer =>
|
||||
computer.turnOff()
|
||||
computer.dropContent(world, x, y, z)
|
||||
case _ => // Ignore.
|
||||
}
|
||||
super.breakBlock(world, x, y, z, blockId, metadata)
|
||||
}
|
||||
|
||||
|
@ -13,9 +13,9 @@ import net.minecraftforge.common.ForgeDirection
|
||||
|
||||
/** The base class on which all our blocks are built. */
|
||||
trait Delegate {
|
||||
def parent: Delegator
|
||||
val parent: Delegator
|
||||
|
||||
def unlocalizedName: String
|
||||
val unlocalizedName: String
|
||||
|
||||
val blockId = parent.add(this)
|
||||
|
||||
|
57
li/cil/oc/common/block/DiskDrive.scala
Normal file
@ -0,0 +1,57 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import cpw.mods.fml.common.registry.GameRegistry
|
||||
import li.cil.oc.common.{GuiType, tileentity}
|
||||
import li.cil.oc.{OpenComputers, Config}
|
||||
import net.minecraft.client.renderer.texture.IconRegister
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.util.Icon
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
|
||||
class DiskDrive(val parent: Delegator) extends Delegate {
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.DiskDrive], "oc.disk_drive")
|
||||
|
||||
val unlocalizedName = "DiskDrive"
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
private val icons = Array.fill[Icon](6)(null)
|
||||
|
||||
override def icon(side: ForgeDirection) = Some(icons(side.ordinal))
|
||||
|
||||
override def registerIcons(iconRegister: IconRegister) = {
|
||||
icons(ForgeDirection.DOWN.ordinal) = iconRegister.registerIcon(Config.resourceDomain + ":computer_top")
|
||||
icons(ForgeDirection.UP.ordinal) = icons(ForgeDirection.DOWN.ordinal)
|
||||
|
||||
icons(ForgeDirection.NORTH.ordinal) = iconRegister.registerIcon(Config.resourceDomain + ":disk_drive_side")
|
||||
icons(ForgeDirection.SOUTH.ordinal) = iconRegister.registerIcon(Config.resourceDomain + ":disk_drive_front")
|
||||
icons(ForgeDirection.WEST.ordinal) = icons(ForgeDirection.NORTH.ordinal)
|
||||
icons(ForgeDirection.EAST.ordinal) = icons(ForgeDirection.NORTH.ordinal)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def hasTileEntity = true
|
||||
|
||||
override def createTileEntity(world: World, metadata: Int) = Some(new tileentity.DiskDrive)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def breakBlock(world: World, x: Int, y: Int, z: Int, blockId: Int, metadata: Int) = {
|
||||
if (!world.isRemote) world.getBlockTileEntity(x, y, z) match {
|
||||
case drive: tileentity.DiskDrive => drive.dropContent(world, x, y, z)
|
||||
case _ => // Ignore.
|
||||
}
|
||||
super.breakBlock(world, x, y, z, blockId, metadata)
|
||||
}
|
||||
|
||||
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,
|
||||
side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
if (!player.isSneaking) {
|
||||
player.openGui(OpenComputers, GuiType.DiskDrive.id, world, x, y, z)
|
||||
true
|
||||
}
|
||||
else false
|
||||
}
|
||||
}
|
18
li/cil/oc/common/container/DiskDrive.scala
Normal file
@ -0,0 +1,18 @@
|
||||
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.
|
||||
addPlayerInventorySlots(8, 84)
|
||||
}
|
@ -7,9 +7,9 @@ import net.minecraft.util.Icon
|
||||
import net.minecraft.world.World
|
||||
|
||||
trait Delegate {
|
||||
def parent: Delegator
|
||||
val parent: Delegator
|
||||
|
||||
def unlocalizedName: String
|
||||
val unlocalizedName: String
|
||||
|
||||
val itemId = parent.add(this)
|
||||
|
||||
@ -23,7 +23,7 @@ trait Delegate {
|
||||
|
||||
def icon: Option[Icon] = _icon
|
||||
|
||||
protected def icon_=(value: Icon) = _icon = Some(value)
|
||||
protected def icon_=(value: Icon) = _icon = Option(value)
|
||||
|
||||
def onItemRightClick(item: ItemStack, world: World, player: EntityPlayer): ItemStack = item
|
||||
|
||||
|
14
li/cil/oc/common/item/Disk.scala
Normal file
@ -0,0 +1,14 @@
|
||||
package li.cil.oc.common.item
|
||||
|
||||
import li.cil.oc.Config
|
||||
import net.minecraft.client.renderer.texture.IconRegister
|
||||
|
||||
class Disk(val parent: Delegator) extends Delegate {
|
||||
val unlocalizedName = "Disk"
|
||||
|
||||
override def registerIcons(iconRegister: IconRegister) {
|
||||
super.registerIcons(iconRegister)
|
||||
|
||||
icon = iconRegister.registerIcon(Config.resourceDomain + ":disk")
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import li.cil.oc.Config
|
||||
import net.minecraft.client.renderer.texture.IconRegister
|
||||
|
||||
class GraphicsCard(val parent: Delegator) extends Delegate {
|
||||
def unlocalizedName = "GraphicsCard"
|
||||
val unlocalizedName = "GraphicsCard"
|
||||
|
||||
override def registerIcons(iconRegister: IconRegister) {
|
||||
super.registerIcons(iconRegister)
|
||||
|
@ -6,8 +6,8 @@ import net.minecraft.client.renderer.texture.IconRegister
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
class Hdd(val parent: Delegator, val megaBytes: Int) extends Delegate {
|
||||
def unlocalizedName = "HardDiskDrive" + megaBytes + "m"
|
||||
class HardDiskDrive(val parent: Delegator, val megaBytes: Int) extends Delegate {
|
||||
val unlocalizedName = "HardDiskDrive" + megaBytes + "m"
|
||||
|
||||
override def addInformation(item: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) = {
|
||||
super.addInformation(item, player, tooltip, advanced)
|
@ -4,7 +4,7 @@ import li.cil.oc.Config
|
||||
import net.minecraft.client.renderer.texture.IconRegister
|
||||
|
||||
class Memory(val parent: Delegator, val kiloBytes: Int) extends Delegate {
|
||||
def unlocalizedName = "Memory" + kiloBytes + "k"
|
||||
val unlocalizedName = "Memory" + kiloBytes + "k"
|
||||
|
||||
override def registerIcons(iconRegister: IconRegister) {
|
||||
super.registerIcons(iconRegister)
|
||||
|
@ -4,7 +4,7 @@ import li.cil.oc.Config
|
||||
import net.minecraft.client.renderer.texture.IconRegister
|
||||
|
||||
class NetworkCard(val parent: Delegator) extends Delegate {
|
||||
def unlocalizedName = "NetworkCard"
|
||||
val unlocalizedName = "NetworkCard"
|
||||
|
||||
override def registerIcons(iconRegister: IconRegister) = {
|
||||
super.registerIcons(iconRegister)
|
||||
|
@ -4,7 +4,7 @@ import li.cil.oc.Config
|
||||
import net.minecraft.client.renderer.texture.IconRegister
|
||||
|
||||
class RedstoneCard(val parent: Delegator) extends Delegate {
|
||||
def unlocalizedName = "RedstoneCard"
|
||||
val unlocalizedName = "RedstoneCard"
|
||||
|
||||
override def registerIcons(iconRegister: IconRegister) {
|
||||
super.registerIcons(iconRegister)
|
||||
|
@ -6,6 +6,7 @@ import li.cil.oc.api.network.{Message, Visibility, Node}
|
||||
import li.cil.oc.server.driver
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
import scala.collection.mutable
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class Adapter extends Rotatable with Node with IPeripheral {
|
||||
val name = "adapter"
|
||||
@ -71,6 +72,19 @@ class Adapter extends Rotatable with Node with IPeripheral {
|
||||
}
|
||||
}
|
||||
|
||||
override def readFromNBT(nbt: NBTTagCompound) {
|
||||
super.readFromNBT(nbt)
|
||||
load(nbt.getCompoundTag("node"))
|
||||
}
|
||||
|
||||
override def writeToNBT(nbt: NBTTagCompound) {
|
||||
super.writeToNBT(nbt)
|
||||
|
||||
val nodeNbt = new NBTTagCompound
|
||||
save(nodeNbt)
|
||||
nbt.setCompoundTag("node", nodeNbt)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def getType = "oc_adapter"
|
||||
|
@ -1,33 +1,23 @@
|
||||
package li.cil.oc.common.tileentity
|
||||
|
||||
import li.cil.oc.Items
|
||||
import li.cil.oc.api.driver.Slot
|
||||
import li.cil.oc.api.network.{PoweredNode, Node}
|
||||
import li.cil.oc.common.item
|
||||
import li.cil.oc.server.component
|
||||
import li.cil.oc.api.driver
|
||||
import li.cil.oc.api.network.Node
|
||||
import li.cil.oc.server.driver.Registry
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.nbt.NBTTagList
|
||||
import net.minecraft.world.World
|
||||
|
||||
trait ComponentInventory extends IInventory with PoweredNode {
|
||||
protected val inventory = new Array[ItemStack](inventorySize)
|
||||
|
||||
protected val itemComponents = Array.fill[Option[Node]](inventorySize)(None)
|
||||
|
||||
protected val computer: component.Computer
|
||||
trait ComponentInventory extends Inventory with Node {
|
||||
protected val components = Array.fill[Option[Node]](getSizeInventory)(None)
|
||||
|
||||
def world: World
|
||||
|
||||
def inventorySize = 8
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def installedMemory = inventory.foldLeft(0)((sum, stack) => sum + (Registry.driverFor(stack) match {
|
||||
case Some(driver) if driver.slot(stack) == Slot.RAM => Items.multi.subItem(stack) match {
|
||||
case Some(ram: item.Memory) => ram.kiloBytes * 1024
|
||||
def installedMemory = inventory.foldLeft(0)((sum, stack) => sum + (stack match {
|
||||
case Some(item) => Registry.driverFor(item) match {
|
||||
case Some(driver: driver.Memory) => driver.amount(item)
|
||||
case _ => 0
|
||||
}
|
||||
case _ => 0
|
||||
@ -37,14 +27,16 @@ trait ComponentInventory extends IInventory with PoweredNode {
|
||||
|
||||
override protected def onConnect() {
|
||||
super.onConnect()
|
||||
for (node <- itemComponents.filter(_.isDefined).map(_.get))
|
||||
network.foreach(_.connect(this, node))
|
||||
components collect {
|
||||
case Some(node) => network.foreach(_.connect(this, node))
|
||||
}
|
||||
}
|
||||
|
||||
override protected def onDisconnect() {
|
||||
super.onDisconnect()
|
||||
for (node <- itemComponents.filter(_.isDefined).map(_.get))
|
||||
node.network.foreach(_.remove(node))
|
||||
components collect {
|
||||
case Some(node) => node.network.foreach(_.remove(node))
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -56,32 +48,37 @@ trait ComponentInventory extends IInventory with PoweredNode {
|
||||
val slotNbt = list.tagAt(i).asInstanceOf[NBTTagCompound]
|
||||
val slot = slotNbt.getByte("slot")
|
||||
if (slot >= 0 && slot < inventory.length) {
|
||||
inventory(slot) = ItemStack.loadItemStackFromNBT(
|
||||
slotNbt.getCompoundTag("item"))
|
||||
itemComponents(slot) = Registry.driverFor(inventory(slot)) match {
|
||||
case None => None
|
||||
case Some(driver) => driver.node(inventory(slot))
|
||||
val item = ItemStack.loadItemStackFromNBT(slotNbt.getCompoundTag("item"))
|
||||
inventory(slot) = Some(item)
|
||||
components(slot) = Registry.driverFor(item) match {
|
||||
case Some(driver) =>
|
||||
driver.node(item) match {
|
||||
case Some(node) =>
|
||||
node.load(driver.nbt(item))
|
||||
Some(node)
|
||||
case _ => None
|
||||
}
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
computer.recomputeMemory()
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) = {
|
||||
super.save(nbt)
|
||||
val list = new NBTTagList
|
||||
inventory.zipWithIndex filter {
|
||||
case (stack, slot) => stack != null
|
||||
inventory.zipWithIndex collect {
|
||||
case (Some(stack), slot) => (stack, slot)
|
||||
} foreach {
|
||||
case (stack, slot) => {
|
||||
val slotNbt = new NBTTagCompound
|
||||
slotNbt.setByte("slot", slot.toByte)
|
||||
|
||||
itemComponents(slot) match {
|
||||
case None => // Nothing special to save.
|
||||
components(slot) match {
|
||||
case Some(node) =>
|
||||
// We're guaranteed to have a driver for entries.
|
||||
node.save(Registry.driverFor(stack).get.nbt(stack))
|
||||
case _ => // Nothing special to save.
|
||||
}
|
||||
|
||||
val itemNbt = new NBTTagCompound
|
||||
@ -97,75 +94,27 @@ trait ComponentInventory extends IInventory with PoweredNode {
|
||||
|
||||
def getInventoryStackLimit = 1
|
||||
|
||||
def getInvName = "oc.container.computer"
|
||||
|
||||
def getSizeInventory = inventory.length
|
||||
|
||||
def getStackInSlot(i: Int) = inventory(i)
|
||||
|
||||
def decrStackSize(slot: Int, amount: Int) = {
|
||||
val stack = getStackInSlot(slot)
|
||||
val result = if (stack == null)
|
||||
null
|
||||
else if (stack.stackSize <= amount) {
|
||||
setInventorySlotContents(slot, null)
|
||||
stack
|
||||
}
|
||||
else {
|
||||
val subStack = stack.splitStack(amount)
|
||||
if (stack.stackSize == 0) {
|
||||
setInventorySlotContents(slot, null)
|
||||
override protected def onItemAdded(slot: Int, item: ItemStack) = if (!world.isRemote) {
|
||||
Registry.driverFor(item) match {
|
||||
case None => // No driver.
|
||||
case Some(driver) => driver.node(item) match {
|
||||
case None => // No node.
|
||||
case Some(node) =>
|
||||
components(slot) = Some(node)
|
||||
node.load(driver.nbt(item))
|
||||
network.foreach(_.connect(this, node))
|
||||
}
|
||||
subStack
|
||||
}
|
||||
onInventoryChanged()
|
||||
result
|
||||
}
|
||||
|
||||
def getStackInSlotOnClosing(slot: Int) = null
|
||||
|
||||
def setInventorySlotContents(slot: Int, item: ItemStack) = {
|
||||
override protected def onItemRemoved(slot: Int, item: ItemStack) = if (!world.isRemote) {
|
||||
// Uninstall component previously in that slot.
|
||||
if (!world.isRemote) itemComponents(slot) match {
|
||||
case None => // Nothing to do.
|
||||
components(slot) match {
|
||||
case Some(node) =>
|
||||
itemComponents(slot) = None
|
||||
components(slot) = None
|
||||
node.network.foreach(_.remove(node))
|
||||
node.save(Registry.driverFor(inventory(slot)).get.nbt(inventory(slot)))
|
||||
Registry.driverFor(item).foreach(driver => node.save(driver.nbt(item)))
|
||||
case _ => // Nothing to do.
|
||||
}
|
||||
|
||||
inventory(slot) = item
|
||||
if (item != null && item.stackSize > getInventoryStackLimit)
|
||||
item.stackSize = getInventoryStackLimit
|
||||
|
||||
if (!world.isRemote) {
|
||||
Registry.driverFor(inventory(slot)) match {
|
||||
case None => // No driver.
|
||||
case Some(driver) =>
|
||||
driver.node(inventory(slot)) match {
|
||||
case None => // No node.
|
||||
case Some(node) =>
|
||||
itemComponents(slot) = Some(node)
|
||||
network.foreach(_.connect(this, node))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onInventoryChanged()
|
||||
}
|
||||
|
||||
def isItemValidForSlot(slot: Int, item: ItemStack) = (slot, Registry.driverFor(item)) match {
|
||||
case (_, None) => false // Invalid item.
|
||||
case (0, Some(driver)) => driver.slot(item) == Slot.PSU
|
||||
case (1 | 2 | 3, Some(driver)) => driver.slot(item) == Slot.PCI
|
||||
case (4 | 5, Some(driver)) => driver.slot(item) == Slot.RAM
|
||||
case (6 | 7, Some(driver)) => driver.slot(item) == Slot.HDD
|
||||
case _ => false // Invalid slot.
|
||||
}
|
||||
|
||||
def isInvNameLocalized = false
|
||||
|
||||
def openChest() {}
|
||||
|
||||
def closeChest() {}
|
||||
}
|
@ -1,16 +1,20 @@
|
||||
package li.cil.oc.common.tileentity
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import li.cil.oc.api.driver.Slot
|
||||
import li.cil.oc.api.network.PoweredNode
|
||||
import li.cil.oc.client.{PacketSender => ClientPacketSender}
|
||||
import li.cil.oc.server.component
|
||||
import li.cil.oc.server.component.Redstone
|
||||
import li.cil.oc.server.driver
|
||||
import li.cil.oc.server.driver.Registry
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
|
||||
class Computer(isClient: Boolean) extends Rotatable with component.Computer.Environment with ComponentInventory with Redstone {
|
||||
class Computer(isClient: Boolean) extends Rotatable with component.Computer.Environment with ComponentInventory with Redstone with PoweredNode {
|
||||
def this() = this(false)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -45,15 +49,16 @@ class Computer(isClient: Boolean) extends Rotatable with component.Computer.Envi
|
||||
|
||||
override def readFromNBT(nbt: NBTTagCompound) = {
|
||||
super.readFromNBT(nbt)
|
||||
load(nbt.getCompoundTag("data"))
|
||||
load(nbt.getCompoundTag("node"))
|
||||
computer.recomputeMemory()
|
||||
}
|
||||
|
||||
override def writeToNBT(nbt: NBTTagCompound) = {
|
||||
super.writeToNBT(nbt)
|
||||
|
||||
val dataNbt = new NBTTagCompound
|
||||
save(dataNbt)
|
||||
nbt.setCompoundTag("data", dataNbt)
|
||||
val nodeNbt = new NBTTagCompound
|
||||
save(nodeNbt)
|
||||
nbt.setCompoundTag("node", nodeNbt)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -67,7 +72,7 @@ class Computer(isClient: Boolean) extends Rotatable with component.Computer.Envi
|
||||
ServerPacketSender.sendComputerState(this, computer.isRunning)
|
||||
isRunning = computer.isRunning
|
||||
|
||||
for (component <- itemComponents) component match {
|
||||
for (component <- components) component match {
|
||||
case Some(node) => node.update()
|
||||
case _ => // Empty.
|
||||
}
|
||||
@ -83,6 +88,19 @@ class Computer(isClient: Boolean) extends Rotatable with component.Computer.Envi
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def getInvName = "oc.container.computer"
|
||||
|
||||
def getSizeInventory = 8
|
||||
|
||||
def isItemValidForSlot(slot: Int, item: ItemStack) = (slot, Registry.driverFor(item)) match {
|
||||
case (_, None) => false // Invalid item.
|
||||
case (0, Some(driver)) => driver.slot(item) == Slot.Power
|
||||
case (1 | 2 | 3, Some(driver)) => driver.slot(item) == Slot.Card
|
||||
case (4 | 5, Some(driver)) => driver.slot(item) == Slot.Memory
|
||||
case (6 | 7, Some(driver)) => driver.slot(item) == Slot.HardDiskDrive
|
||||
case _ => false // Invalid slot.
|
||||
}
|
||||
|
||||
override def isUseableByPlayer(player: EntityPlayer) =
|
||||
worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this &&
|
||||
player.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64
|
||||
@ -118,6 +136,8 @@ class Computer(isClient: Boolean) extends Rotatable with component.Computer.Envi
|
||||
else worldObj.markBlockForRenderUpdate(xCoord, yCoord, zCoord)
|
||||
}
|
||||
|
||||
private def hasRedstoneCard =
|
||||
!inventory.isEmpty && inventory.exists(item => item != null && driver.RedstoneCard.worksWith(item))
|
||||
private def hasRedstoneCard = inventory.exists {
|
||||
case Some(item) => driver.RedstoneCard.worksWith(item)
|
||||
case _ => false
|
||||
}
|
||||
}
|
57
li/cil/oc/common/tileentity/DiskDrive.scala
Normal file
@ -0,0 +1,57 @@
|
||||
package li.cil.oc.common.tileentity
|
||||
|
||||
import li.cil.oc.api.driver.Slot
|
||||
import li.cil.oc.api.network.{Message, Visibility, Node}
|
||||
import li.cil.oc.server.driver.Registry
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class DiskDrive extends Rotatable with Node with ComponentInventory {
|
||||
val name = "disk_drive"
|
||||
|
||||
val visibility = Visibility.Network
|
||||
|
||||
def world = worldObj
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def receive(message: Message) = super.receive(message) orElse {
|
||||
components(0) match {
|
||||
case Some(node) if node.address.isDefined =>
|
||||
node.receive(message)
|
||||
case _ if message.name.startsWith("fs.") => result(Unit, "no disk")
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def readFromNBT(nbt: NBTTagCompound) {
|
||||
super.readFromNBT(nbt)
|
||||
load(nbt.getCompoundTag("node"))
|
||||
}
|
||||
|
||||
override def writeToNBT(nbt: NBTTagCompound) {
|
||||
super.writeToNBT(nbt)
|
||||
|
||||
val nodeNbt = new NBTTagCompound
|
||||
save(nodeNbt)
|
||||
nbt.setCompoundTag("node", nodeNbt)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def getInvName = "oc.container.disk_drive"
|
||||
|
||||
def getSizeInventory = 1
|
||||
|
||||
def isItemValidForSlot(slot: Int, item: ItemStack) = (slot, Registry.driverFor(item)) match {
|
||||
case (0, Some(driver)) => driver.slot(item) == Slot.Disk
|
||||
case _ => false
|
||||
}
|
||||
|
||||
def isUseableByPlayer(player: EntityPlayer) =
|
||||
worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this &&
|
||||
player.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64
|
||||
}
|
66
li/cil/oc/common/tileentity/Inventory.scala
Normal file
@ -0,0 +1,66 @@
|
||||
package li.cil.oc.common.tileentity
|
||||
|
||||
import net.minecraft.entity.item.EntityItem
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.world.World
|
||||
|
||||
trait Inventory extends IInventory {
|
||||
protected val inventory = Array.fill[Option[ItemStack]](getSizeInventory)(None)
|
||||
|
||||
def getStackInSlot(i: Int) = inventory(i).orNull
|
||||
|
||||
def decrStackSize(slot: Int, amount: Int) = inventory(slot) match {
|
||||
case Some(stack) if stack.stackSize <= amount =>
|
||||
setInventorySlotContents(slot, null)
|
||||
stack
|
||||
case Some(stack) =>
|
||||
val result = stack.splitStack(amount)
|
||||
onInventoryChanged()
|
||||
result
|
||||
case _ => null
|
||||
}
|
||||
|
||||
def setInventorySlotContents(slot: Int, item: ItemStack) = {
|
||||
if (inventory(slot).isDefined)
|
||||
onItemRemoved(slot, inventory(slot).get)
|
||||
|
||||
inventory(slot) = Option(item)
|
||||
if (item != null && item.stackSize > getInventoryStackLimit)
|
||||
item.stackSize = getInventoryStackLimit
|
||||
|
||||
if (inventory(slot).isDefined)
|
||||
onItemAdded(slot, inventory(slot).get)
|
||||
|
||||
onInventoryChanged()
|
||||
}
|
||||
|
||||
def getStackInSlotOnClosing(slot: Int) = null
|
||||
|
||||
def isInvNameLocalized = false
|
||||
|
||||
def openChest() {}
|
||||
|
||||
def closeChest() {}
|
||||
|
||||
def dropContent(world: World, x: Int, y: Int, z: Int) {
|
||||
val rng = world.rand
|
||||
for (slot <- 0 until getSizeInventory) {
|
||||
inventory(slot) match {
|
||||
case Some(stack) if stack.stackSize > 0 =>
|
||||
setInventorySlotContents(slot, null)
|
||||
val (tx, ty, tz) = (0.25 + (rng.nextDouble() * 0.5), 0.25 + (rng.nextDouble() * 0.5), 0.25 + (rng.nextDouble() * 0.5))
|
||||
val (vx, vy, vz) = ((rng.nextDouble() - 0.3) * 0.5, (rng.nextDouble() - 0.5) * 0.3, (rng.nextDouble() - 0.5) * 0.3)
|
||||
val entity = new EntityItem(world, x + tx, y + ty, z + tz, stack.copy())
|
||||
entity.setVelocity(vx, vy, vz)
|
||||
entity.delayBeforeCanPickup = 20
|
||||
world.spawnEntityInWorld(entity)
|
||||
case _ => // Nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected def onItemAdded(slot: Int, item: ItemStack) {}
|
||||
|
||||
protected def onItemRemoved(slot: Int, item: ItemStack) {}
|
||||
}
|
@ -28,15 +28,15 @@ class Keyboard extends Rotatable with Node {
|
||||
|
||||
override def readFromNBT(nbt: NBTTagCompound) {
|
||||
super.readFromNBT(nbt)
|
||||
load(nbt.getCompoundTag("data"))
|
||||
load(nbt.getCompoundTag("node"))
|
||||
}
|
||||
|
||||
override def writeToNBT(nbt: NBTTagCompound) {
|
||||
super.writeToNBT(nbt)
|
||||
|
||||
val dataNbt = new NBTTagCompound
|
||||
save(dataNbt)
|
||||
nbt.setCompoundTag("data", dataNbt)
|
||||
val nodeNbt = new NBTTagCompound
|
||||
save(nodeNbt)
|
||||
nbt.setCompoundTag("node", nodeNbt)
|
||||
}
|
||||
|
||||
def isUseableByPlayer(p: Player) = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this &&
|
||||
|
@ -15,15 +15,15 @@ class Screen extends Rotatable with ScreenEnvironment with PoweredNode {
|
||||
|
||||
override def readFromNBT(nbt: NBTTagCompound) = {
|
||||
super.readFromNBT(nbt)
|
||||
load(nbt.getCompoundTag("data"))
|
||||
load(nbt.getCompoundTag("node"))
|
||||
}
|
||||
|
||||
override def writeToNBT(nbt: NBTTagCompound) = {
|
||||
super.writeToNBT(nbt)
|
||||
|
||||
val dataNbt = new NBTTagCompound
|
||||
save(dataNbt)
|
||||
nbt.setCompoundTag("data", dataNbt)
|
||||
val nodeNbt = new NBTTagCompound
|
||||
save(nodeNbt)
|
||||
nbt.setCompoundTag("node", nodeNbt)
|
||||
}
|
||||
|
||||
override def validate() = {
|
||||
|
@ -2,34 +2,43 @@ package li.cil.oc.server.driver
|
||||
|
||||
import li.cil.oc
|
||||
import li.cil.oc.api.driver.{Item, Slot}
|
||||
import li.cil.oc.common.item.Hdd
|
||||
import li.cil.oc.common.item.{Disk, HardDiskDrive}
|
||||
import li.cil.oc.{Config, Items}
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
object FileSystem extends Item {
|
||||
override def api = Option(getClass.getResourceAsStream(Config.driverPath + "filesystem.lua"))
|
||||
|
||||
override def worksWith(item: ItemStack) = WorksWith(Items.hdd2, Items.hdd4, Items.hdd8)(item)
|
||||
override def worksWith(item: ItemStack) = WorksWith(Items.hdd1, Items.hdd2, Items.hdd3, Items.disk)(item)
|
||||
|
||||
override def slot(item: ItemStack) = Slot.HDD
|
||||
override def slot(item: ItemStack) = Items.multi.subItem(item) match {
|
||||
case Some(hdd: HardDiskDrive) => Slot.HardDiskDrive
|
||||
case Some(disk: Disk) => Slot.Disk
|
||||
case _ => throw new IllegalArgumentException()
|
||||
}
|
||||
|
||||
override def node(item: ItemStack) = Items.multi.subItem(item) match {
|
||||
case Some(subItem: Hdd) =>
|
||||
// We have a bit of a chicken-egg problem here, because we want to use the
|
||||
// node's address as the folder name... so we generate the address here,
|
||||
// if necessary. No one will know, right? Right!?
|
||||
val tag = nbt(item)
|
||||
val address =
|
||||
if (tag.hasKey("address")) tag.getString("address")
|
||||
else java.util.UUID.randomUUID().toString
|
||||
oc.api.FileSystem.fromSaveDirectory(address, subItem.megaBytes * 1024 * 1024, Config.filesBuffered).
|
||||
flatMap(oc.api.FileSystem.asNode) match {
|
||||
case None => None
|
||||
case Some(node) =>
|
||||
node.address = Some(address)
|
||||
node.load(tag)
|
||||
Some(node)
|
||||
}
|
||||
case Some(hdd: HardDiskDrive) => createNode(item, hdd.megaBytes * 1024 * 1024)
|
||||
case Some(disk: Disk) => createNode(item, 512 * 1024)
|
||||
case _ => None
|
||||
}
|
||||
|
||||
private def createNode(item: ItemStack, capacity: Int) = {
|
||||
// We have a bit of a chicken-egg problem here, because we want to use the
|
||||
// node's address as the folder name... so we generate the address here,
|
||||
// if necessary. No one will know, right? Right!?
|
||||
val address = addressFromTag(nbt(item))
|
||||
oc.api.FileSystem.fromSaveDirectory(address, capacity, Config.filesBuffered).
|
||||
flatMap(oc.api.FileSystem.asNode) match {
|
||||
case Some(node) =>
|
||||
node.address = Some(address)
|
||||
Some(node)
|
||||
case None => None
|
||||
}
|
||||
}
|
||||
|
||||
private def addressFromTag(tag: NBTTagCompound) =
|
||||
if (tag.hasKey("address")) tag.getString("address")
|
||||
else java.util.UUID.randomUUID().toString
|
||||
}
|
@ -11,11 +11,7 @@ object GraphicsCard extends driver.Item {
|
||||
|
||||
override def worksWith(item: ItemStack) = WorksWith(Items.gpu)(item)
|
||||
|
||||
override def slot(item: ItemStack) = Slot.PCI
|
||||
override def slot(item: ItemStack) = Slot.Card
|
||||
|
||||
override def node(item: ItemStack) = {
|
||||
val instance = new component.GraphicsCard()
|
||||
instance.load(nbt(item))
|
||||
Some(instance)
|
||||
}
|
||||
override def node(item: ItemStack) = Some(new component.GraphicsCard())
|
||||
}
|
@ -5,8 +5,13 @@ import li.cil.oc.api.driver
|
||||
import li.cil.oc.api.driver.Slot
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
object Memory extends driver.Item {
|
||||
override def worksWith(item: ItemStack) = WorksWith(Items.ram128k, Items.ram32k, Items.ram64k)(item)
|
||||
object Memory extends driver.Memory {
|
||||
override def amount(item: ItemStack) = if (item.itemID == Items.multi.itemID) Items.multi.subItem(item) match {
|
||||
case Some(memory: li.cil.oc.common.item.Memory) => memory.kiloBytes * 1024
|
||||
case _ => 0
|
||||
} else 0
|
||||
|
||||
override def slot(item: ItemStack) = Slot.RAM
|
||||
override def worksWith(item: ItemStack) = WorksWith(Items.ram3, Items.ram1, Items.ram2)(item)
|
||||
|
||||
override def slot(item: ItemStack) = Slot.Memory
|
||||
}
|
||||
|
@ -11,11 +11,7 @@ object NetworkCard extends driver.Item {
|
||||
|
||||
def worksWith(item: ItemStack) = WorksWith(Items.lan)(item)
|
||||
|
||||
def slot(item: ItemStack) = Slot.PCI
|
||||
def slot(item: ItemStack) = Slot.Card
|
||||
|
||||
override def node(item: ItemStack) = {
|
||||
val instance = new component.NetworkCard()
|
||||
instance.load(nbt(item))
|
||||
Some(instance)
|
||||
}
|
||||
override def node(item: ItemStack) = Some(new component.NetworkCard())
|
||||
}
|
||||
|
@ -11,11 +11,7 @@ object RedstoneCard extends driver.Item {
|
||||
|
||||
override def worksWith(item: ItemStack) = WorksWith(Items.rs)(item)
|
||||
|
||||
override def slot(item: ItemStack) = Slot.PCI
|
||||
override def slot(item: ItemStack) = Slot.Card
|
||||
|
||||
override def node(item: ItemStack) = {
|
||||
val instance = new component.RedstoneCard()
|
||||
instance.load(nbt(item))
|
||||
Some(instance)
|
||||
}
|
||||
override def node(item: ItemStack) = Some(new component.RedstoneCard())
|
||||
}
|
||||
|
@ -95,13 +95,6 @@ trait VirtualFileSystem extends OutputStreamFileSystem {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def close() = {
|
||||
super.close()
|
||||
root.children.clear()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override protected def openInputStream(path: String) =
|
||||
root.get(segments(path)) match {
|
||||
case Some(obj: VirtualFile) => obj.openInputStream()
|
||||
|
@ -99,7 +99,7 @@ object LuaStateFactory {
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def createState(): Option[LuaState] = {
|
||||
val state = new LuaState(Integer.MAX_VALUE)
|
||||
val state = new LuaState(Int.MaxValue)
|
||||
try {
|
||||
// Load all libraries.
|
||||
state.openLib(LuaState.Library.BASE)
|
||||
|
@ -1,9 +1,9 @@
|
||||
package li.cil.oc.client
|
||||
package li.cil.oc.util
|
||||
|
||||
import net.minecraft.client.renderer.OpenGlHelper
|
||||
import org.lwjgl.opengl.{ARBMultitexture, GLContext, GL11, GL13}
|
||||
|
||||
object RenderUtil {
|
||||
object RenderState {
|
||||
val arb = GLContext.getCapabilities.GL_ARB_multitexture && !GLContext.getCapabilities.OpenGL13
|
||||
|
||||
def disableLighting() {
|