diff --git a/assets/items.psd b/assets/items.psd index ad2ca3c3f..f2eaafd96 100644 Binary files a/assets/items.psd and b/assets/items.psd differ diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index 3139f13a2..b8ab313c5 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -37,7 +37,7 @@ item.oc.AbstractBusCard.name=Abstract Bus Card item.oc.Acid.name=Grog item.oc.ALU.name=Arithmetic Logic Unit (ALU) item.oc.Analyzer.name=Analyzer -item.oc.AppengTunnel.name=P2P Tunnel - OpenComputers +item.oc.appengTunnel.name=P2P Tunnel - OpenComputers item.oc.ArrowKeys.name=Arrow Keys item.oc.ButtonGroup.name=Button Group item.oc.CardBase.name=Card Base @@ -53,6 +53,7 @@ item.oc.CuttingWire.name=Cutting Wire item.oc.DebugCard.name=Debug Card item.oc.Debugger.name=Network Debugger item.oc.Disk.name=Disk Platter +item.oc.eeprom.name=EEPROM item.oc.FloppyDisk.name=Floppy Disk item.oc.GraphicsCard0.name=Graphics Card (Tier 1) item.oc.GraphicsCard1.name=Graphics Card (Tier 2) @@ -137,6 +138,7 @@ oc:gui.Assembler.InsertRAM=Insert some RAM oc:gui.Assembler.Progress=Progress: %s%% (%s) oc:gui.Assembler.Run=Assemble oc:gui.Assembler.Warnings=§eWarning§7: Recommended components are missing. +oc:gui.Assembler.Warning.BIOS=BIOS oc:gui.Assembler.Warning.GraphicsCard=Graphics Card oc:gui.Assembler.Warning.Inventory=Inventory Upgrade oc:gui.Assembler.Warning.Keyboard=Keyboard @@ -213,6 +215,7 @@ oc:tooltip.Disassembler=Separates items into their original components. §lWarni oc:tooltip.Disk=Primitive medium that can be used to build persistent storage devices. oc:tooltip.DiskDrive.CC=ComputerCraft floppies are §asupported§7. oc:tooltip.DiskDrive=Allows reading and writing floppies. Can be installed in robots to allow inserting floppies later on. +oc:tooltip.EEPROM=Small, programmable storage that contains the BIOS computers use to boot. oc:tooltip.Geolyzer=Allows scanning the surrounding area's blocks' hardness. This information can be useful for generating holograms of the area or for detecting ores. oc:tooltip.GraphicsCard=Used to change what's displayed on screens.[nl] Maximum resolution: §f%sx%s§7[nl] Maximum color depth: §f%s§7[nl] Operations/tick: §f%s§7 oc:tooltip.InternetCard=This card allows making HTTP requests and using real TCP sockets. @@ -289,6 +292,7 @@ item.oc.Analyzer.usage=The §oAnalyzer§r is a handy tool for getting some infor item.oc.ComponentBus.usage=A §oComponent Bus§r is a server-specific upgrade that allows the server to communicate with more components at the same time, without shutting down. Like with CPUs, higher tier buses provide higher component limits. item.oc.CPU.usage=The §oCentral Processing Unit§r is a core part for each computer. It defines the architecture of the computer, and the number of components that can be connected to the computer before it stops working. Higher tier CPUs also provide a higher per-tick direct call limit to the computer - in simpler terms: better CPUs run faster. item.oc.DebugCard.usage=The §oDebug Card§r is a non-craftable item that was originally only intended to make debugging things easier, by automating some processes. It has since gotten a bunch more functionality, making it quite useful for custom map-making. +item.oc.eeprom.usage=The §oEEPROM§r is what contains the code used to initialize a computer when it is being booted. This data is stored as a plain byte array, and may mean different things to different CPU architectures. For example, for Lua it is usually a small script that searches for file systems with an init script, for other architectures it may be actual machine code. item.oc.FloppyDisk.usage=The §oFloppy Disk§r is the cheapest and smallest type of storage medium in OpenComputers. It is a handy early game way of storing data and transferring it between computers and robots. You may also find floppy disks with useful programs on them in dungeon chests.[nl][nl]Beware: shift-rightclicking while holding a floppy disk in your hand will wipe the floppy disk! item.oc.GraphicsCard.usage=The §oGraphics Card§r is an essential part for most computers and allows the computer to display text on a connected §oScreen§r. Graphics cards come in several tiers, and like screens, support different resolutions and color depths.[nl][nl]Another noteworthy difference for the different graphics card tiers is the number of operations a graphics card can perform per tick. The values listed in the graphics cards' tooltip is representative for a computer with a tier two CPU. Tier one CPUs perform slightly slower, tier three CPUs slightly faster. The numbers listed are for the different operations provided by a GPU: copy, fill, set, setBackground and setForeground, respectively. item.oc.HardDiskDrive.usage=The §oHard Disk Drives§r are the higher tier storage medium in OpenComputers. There are no speed differences in the storage media provided by OpenComputers, they only differ in the amount of disk space they provide. There are also some devices that can only use disk drives, no floppies (although servers could use an external disk drive, for example).[nl][nl]Beware: shift-rightclicking while holding a hard disk in your hand will wipe the disk! diff --git a/src/main/resources/assets/opencomputers/lua/eeprom.lua b/src/main/resources/assets/opencomputers/lua/eeprom.lua new file mode 100644 index 000000000..83db021ae --- /dev/null +++ b/src/main/resources/assets/opencomputers/lua/eeprom.lua @@ -0,0 +1,50 @@ +function boot_invoke(address, method, ...) + local result = table.pack(pcall(component.invoke, address, method, ...)) + if not result[1] then + return nil, result[2] + else + return table.unpack(result, 2, result.n) + end +end +do + local screen = component.list("screen")() + local gpu = component.list("gpu")() + if gpu and screen then + boot_invoke(gpu, "bind", screen) + end +end +local function tryLoadFrom(address) + local handle, reason = boot_invoke(address, "open", "/init.lua") + if not handle then + return nil, reason + end + local buffer = "" + repeat + local data, reason = boot_invoke(address, "read", handle, math.huge) + if not data and reason then + return nil, reason + end + buffer = buffer .. (data or "") + until not data + boot_invoke(address, "close", handle) + return load(buffer, "=init", "t", sandbox) +end +local init, reason +if computer.getBootAddress() then + init, reason = tryLoadFrom(computer.getBootAddress()) +end +if not init then + computer.setBootAddress() + for address in component.list("filesystem") do + init, reason = tryLoadFrom(address) + if init then + computer.setBootAddress(address) + break + end + end +end +if not init then + error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or ""), 0) +end +computer.beep(1000, 0.2) +init() \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/lua/kernel.lua b/src/main/resources/assets/opencomputers/lua/machine.lua similarity index 96% rename from src/main/resources/assets/opencomputers/lua/kernel.lua rename to src/main/resources/assets/opencomputers/lua/machine.lua index 52f669baf..603d5e7b5 100644 --- a/src/main/resources/assets/opencomputers/lua/kernel.lua +++ b/src/main/resources/assets/opencomputers/lua/machine.lua @@ -1303,57 +1303,18 @@ sandbox.unicode = libunicode ------------------------------------------------------------------------------- local function bootstrap() - function boot_invoke(address, method, ...) - local result = table.pack(pcall(libcomponent.invoke, address, method, ...)) - if not result[1] then - return nil, result[2] - else - return table.unpack(result, 2, result.n) - end - end - do - local screen = libcomponent.list("screen")() - local gpu = libcomponent.list("gpu")() - if gpu and screen then - boot_invoke(gpu, "bind", screen) - end - end - local function tryLoadFrom(address) - local handle, reason = boot_invoke(address, "open", "/init.lua") - if not handle then - return nil, reason - end - local buffer = "" - repeat - local data, reason = boot_invoke(address, "read", handle, math.huge) - if not data and reason then - return nil, reason - end - buffer = buffer .. (data or "") - until not data - boot_invoke(address, "close", handle) - return load(buffer, "=init", "t", sandbox) - end - local init, reason - if computer.getBootAddress() then - init, reason = tryLoadFrom(computer.getBootAddress()) - end - if not init then - computer.setBootAddress() - for address in libcomponent.list("filesystem") do - init, reason = tryLoadFrom(address) - if init then - computer.setBootAddress(address) - break + local eeprom = libcomponent.list("eeprom")() + if eeprom then + local code = libcomponent.invoke(eeprom, "get") + if code and #code > 0 then + local bios, reason = load(code, "=bios", "t", sandbox) + if bios then + return coroutine.create(bios), {n=0} end + error("failed loading bios: " .. reason, 0) end end - if not init then - error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or ""), 0) - end - libcomputer.beep(1000, 0.2) - - return coroutine.create(init), {n=0} + error("no bios found; install a configured EEPROM", 0) end ------------------------------------------------------------------------------- @@ -1385,7 +1346,7 @@ local function main() if not result[1] then error(tostring(result[2]), 0) elseif coroutine.status(co) == "dead" then - error("computer stopped unexpectedly", 0) + error("computer halted", 0) else args = table.pack(coroutine.yield(result[2])) -- system yielded value wrapUserdata(args) diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes index 388cd2a96..e6f6c0e8a 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -58,6 +58,11 @@ ram6 { ["oc:circuitChip2", "oc:materialCircuitBoardPrinted", "oc:circuitChip2"]] } +eeprom { + input: [[nuggetGold, "oc:materialTransistor", nuggetGold] + [paper, "oc:circuitChip1", paper] + [nuggetGold, torchRedstoneActive, nuggetGold]] +} floppy { input: [[nuggetIron, lever, nuggetIron] [paper, "oc:materialDisk", paper] @@ -82,6 +87,10 @@ openOS { type: shapeless input: ["oc:floppy", book] } +luaBios { + type: shapeless + input: ["oc:eeprom", book] +} abstractBusCard { input: [[{block="StargateTech2:block.busCable"}, {item="StargateTech2:naquadah", subID=3}, ""] diff --git a/src/main/resources/assets/opencomputers/textures/items/EEPROM.png b/src/main/resources/assets/opencomputers/textures/items/EEPROM.png new file mode 100644 index 000000000..7dbd82185 Binary files /dev/null and b/src/main/resources/assets/opencomputers/textures/items/EEPROM.png differ diff --git a/src/main/resources/assets/opencomputers/textures/items/icons/eeprom.png b/src/main/resources/assets/opencomputers/textures/items/icons/eeprom.png new file mode 100644 index 000000000..57b633410 Binary files /dev/null and b/src/main/resources/assets/opencomputers/textures/items/icons/eeprom.png differ diff --git a/src/main/scala/li/cil/oc/common/InventorySlots.scala b/src/main/scala/li/cil/oc/common/InventorySlots.scala index 5098ba48b..6961b5bd4 100644 --- a/src/main/scala/li/cil/oc/common/InventorySlots.scala +++ b/src/main/scala/li/cil/oc/common/InventorySlots.scala @@ -8,7 +8,8 @@ object InventorySlots { InventorySlot(Slot.Memory, Tier.One), InventorySlot(Slot.HDD, Tier.One), InventorySlot(Slot.CPU, Tier.One), - InventorySlot(Slot.Memory, Tier.One) + InventorySlot(Slot.Memory, Tier.One), + InventorySlot(Slot.EEPROM, Tier.Any) ), Array( @@ -18,7 +19,8 @@ object InventorySlots { InventorySlot(Slot.Memory, Tier.Two), InventorySlot(Slot.HDD, Tier.Two), InventorySlot(Slot.HDD, Tier.One), - InventorySlot(Slot.CPU, Tier.Two) + InventorySlot(Slot.CPU, Tier.Two), + InventorySlot(Slot.EEPROM, Tier.Any) ), Array( @@ -30,7 +32,8 @@ object InventorySlots { InventorySlot(Slot.HDD, Tier.Three), InventorySlot(Slot.HDD, Tier.Two), InventorySlot(Slot.Floppy, Tier.One), - InventorySlot(Slot.CPU, Tier.Three) + InventorySlot(Slot.CPU, Tier.Three), + InventorySlot(Slot.EEPROM, Tier.Any) ), Array( @@ -42,7 +45,8 @@ object InventorySlots { InventorySlot(Slot.HDD, Tier.Three), InventorySlot(Slot.HDD, Tier.Three), InventorySlot(Slot.Floppy, Tier.One), - InventorySlot(Slot.CPU, Tier.Three) + InventorySlot(Slot.CPU, Tier.Three), + InventorySlot(Slot.EEPROM, Tier.Any) ) ) @@ -55,7 +59,8 @@ object InventorySlots { InventorySlot(Slot.Memory, Tier.Two), InventorySlot(Slot.Memory, Tier.Two), InventorySlot(Slot.HDD, Tier.Two), - InventorySlot(Slot.HDD, Tier.Two) + InventorySlot(Slot.HDD, Tier.Two), + InventorySlot(Slot.EEPROM, Tier.Any) ), Array( @@ -70,7 +75,8 @@ object InventorySlots { InventorySlot(Slot.HDD, Tier.Three), InventorySlot(Slot.HDD, Tier.Three), InventorySlot(Slot.HDD, Tier.Three), - InventorySlot(Slot.Card, Tier.Two) + InventorySlot(Slot.Card, Tier.Two), + InventorySlot(Slot.EEPROM, Tier.Any) ), Array( @@ -89,7 +95,8 @@ object InventorySlots { InventorySlot(Slot.HDD, Tier.Three), InventorySlot(Slot.HDD, Tier.Three), InventorySlot(Slot.Card, Tier.Two), - InventorySlot(Slot.Card, Tier.Two) + InventorySlot(Slot.Card, Tier.Two), + InventorySlot(Slot.EEPROM, Tier.Any) ), Array( @@ -108,7 +115,8 @@ object InventorySlots { InventorySlot(Slot.HDD, Tier.Three), InventorySlot(Slot.HDD, Tier.Three), InventorySlot(Slot.Card, Tier.Three), - InventorySlot(Slot.Card, Tier.Three) + InventorySlot(Slot.Card, Tier.Three), + InventorySlot(Slot.EEPROM, Tier.Any) ) ) diff --git a/src/main/scala/li/cil/oc/common/Loot.scala b/src/main/scala/li/cil/oc/common/Loot.scala index 44d946785..cc7cab4dc 100644 --- a/src/main/scala/li/cil/oc/common/Loot.scala +++ b/src/main/scala/li/cil/oc/common/Loot.scala @@ -45,7 +45,7 @@ object Loot extends WeightedRandomChestContent(api.Items.get("openOS").createIte parseLootDisks(list, builtInDisks) for ((name, (stack, _)) <- builtInDisks if name == "OpenOS") { - Recipes.list += stack -> "openOS" + Recipes.addRecipe(stack, "openOS") } } diff --git a/src/main/scala/li/cil/oc/common/Proxy.scala b/src/main/scala/li/cil/oc/common/Proxy.scala index 9d2a696bd..a31ff344b 100644 --- a/src/main/scala/li/cil/oc/common/Proxy.scala +++ b/src/main/scala/li/cil/oc/common/Proxy.scala @@ -34,7 +34,7 @@ class Proxy { registerExclusive("nuggetIron", Items.ironNugget.createItemStack()) if (OreDictionary.getOres("nuggetIron").exists(Items.ironNugget.createItemStack().isItemEqual)) { - Recipes.addItem(Items.ironNugget, "nuggetIron") + Recipes.addMultiItem(Items.ironNugget, "nuggetIron") Recipes.addItem(net.minecraft.init.Items.iron_ingot, "ingotIron") } @@ -100,7 +100,8 @@ class Proxy { OpenComputers.ID + ":" + Settings.namespace + "special" -> "special", OpenComputers.ID + ":" + Settings.namespace + "special_redstone" -> "special_redstone", OpenComputers.ID + ":" + Settings.namespace + "keyboard" -> "keyboard", - OpenComputers.ID + ":rack" -> "serverRack" + OpenComputers.ID + ":rack" -> "serverRack", + OpenComputers.ID + ":appengTunnel" -> "oc.appenTunnel" ) def missingMappings(e: FMLMissingMappingsEvent) { @@ -108,16 +109,16 @@ class Proxy { if (missing.`type` == GameRegistry.Type.BLOCK) { blockRenames.get(missing.name) match { case Some(name) => missing.remap(GameRegistry.findBlock(OpenComputers.ID, name)) - case _ => missing.fail() + case _ => missing.warn() } } else if (missing.`type` == GameRegistry.Type.ITEM) { itemRenames.get(missing.name) match { case Some(name) => missing.remap(GameRegistry.findItem(OpenComputers.ID, name)) - case _ => missing.fail() + case _ => missing.warn() } } - else missing.fail() + else missing.warn() } } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/Slot.scala b/src/main/scala/li/cil/oc/common/Slot.scala index 9e628dc5e..4cbb05bd6 100644 --- a/src/main/scala/li/cil/oc/common/Slot.scala +++ b/src/main/scala/li/cil/oc/common/Slot.scala @@ -10,6 +10,7 @@ object Slot { val ComponentBus = driver.item.Slot.ComponentBus val Container = driver.item.Slot.Container val CPU = driver.item.Slot.CPU + val EEPROM = "eeprom" val Floppy = driver.item.Slot.Floppy val HDD = driver.item.Slot.HDD val Memory = driver.item.Slot.Memory @@ -17,5 +18,5 @@ object Slot { val Tool = "tool" val Upgrade = driver.item.Slot.Upgrade - val All = Array(Card, ComponentBus, Container, CPU, Floppy, HDD, Memory, Tablet, Tool, Upgrade) + val All = Array(Card, ComponentBus, Container, CPU, EEPROM, Floppy, HDD, Memory, Tablet, Tool, Upgrade) } diff --git a/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala b/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala index 34b4e5459..cbd71ad41 100644 --- a/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala +++ b/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala @@ -33,6 +33,8 @@ class SimpleBlock(material: Material = Material.iron) extends Block(material) { protected val validRotations_ = Array(ForgeDirection.UP, ForgeDirection.DOWN) + def createItemStack(amount: Int = 1) = new ItemStack(this, amount) + // ----------------------------------------------------------------------- // // Rendering // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/common/container/Assembler.scala b/src/main/scala/li/cil/oc/common/container/Assembler.scala index 513543644..1169d56ea 100644 --- a/src/main/scala/li/cil/oc/common/container/Assembler.scala +++ b/src/main/scala/li/cil/oc/common/container/Assembler.scala @@ -60,7 +60,7 @@ class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Asse addSlotToContainer(126, 30 + i * slotSize, slotInfo _) } - // Floppy + HDDs. + // Floppy/EEPROM + HDDs. for (i <- 0 until 3) { addSlotToContainer(148, 12 + i * slotSize, slotInfo _) } diff --git a/src/main/scala/li/cil/oc/common/container/Case.scala b/src/main/scala/li/cil/oc/common/container/Case.scala index 872a90159..326323791 100644 --- a/src/main/scala/li/cil/oc/common/container/Case.scala +++ b/src/main/scala/li/cil/oc/common/container/Case.scala @@ -1,29 +1,30 @@ package li.cil.oc.common.container import li.cil.oc.common.InventorySlots +import li.cil.oc.common.Tier import li.cil.oc.common.tileentity import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.InventoryPlayer class Case(playerInventory: InventoryPlayer, computer: tileentity.Case) extends Player(playerInventory, computer) { - for (i <- 0 to (if (computer.tier >= 2) 2 else 1)) { + for (i <- 0 to (if (computer.tier >= Tier.Three) 2 else 1)) { val slot = InventorySlots.computer(computer.tier)(getInventory.size) addSlotToContainer(98, 16 + i * slotSize, slot.slot, slot.tier) } - for (i <- 0 to (if (computer.tier == 0) 0 else 1)) { + for (i <- 0 to (if (computer.tier == Tier.One) 0 else 1)) { val slot = InventorySlots.computer(computer.tier)(getInventory.size) addSlotToContainer(120, 16 + (i + 1) * slotSize, slot.slot, slot.tier) } - for (i <- 0 to (if (computer.tier == 0) 0 else 1)) { + for (i <- 0 to (if (computer.tier == Tier.One) 0 else 1)) { val slot = InventorySlots.computer(computer.tier)(getInventory.size) addSlotToContainer(142, 16 + i * slotSize, slot.slot, slot.tier) } - if (computer.tier >= 2) { + if (computer.tier >= Tier.Three) { val slot = InventorySlots.computer(computer.tier)(getInventory.size) - addSlotToContainer(142, 16 + 2 * slotSize, slot.slot) + addSlotToContainer(142, 16 + 2 * slotSize, slot.slot, slot.tier) } { @@ -31,11 +32,16 @@ class Case(playerInventory: InventoryPlayer, computer: tileentity.Case) extends addSlotToContainer(120, 16, slot.slot, slot.tier) } - if (computer.tier == 0) { + if (computer.tier == Tier.One) { val slot = InventorySlots.computer(computer.tier)(getInventory.size) addSlotToContainer(120, 16 + 2 * slotSize, slot.slot, slot.tier) } + { + val slot = InventorySlots.computer(computer.tier)(getInventory.size) + addSlotToContainer(48, 34, slot.slot, slot.tier) + } + // Show the player's inventory. addPlayerInventorySlots(8, 84) diff --git a/src/main/scala/li/cil/oc/common/container/Server.scala b/src/main/scala/li/cil/oc/common/container/Server.scala index f503ea139..d991efbe2 100644 --- a/src/main/scala/li/cil/oc/common/container/Server.scala +++ b/src/main/scala/li/cil/oc/common/container/Server.scala @@ -32,6 +32,11 @@ class Server(playerInventory: InventoryPlayer, serverInventory: ServerInventory) addSlotToContainer(76, 7 + i * slotSize, slot.slot, slot.tier) } + { + val slot = InventorySlots.server(serverInventory.tier)(getInventory.size) + addSlotToContainer(48, 34, slot.slot, slot.tier) + } + // Show the player's inventory. addPlayerInventorySlots(8, 84) diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index 80e1da5c4..490a2b3d8 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -1,13 +1,16 @@ package li.cil.oc.common.init import cpw.mods.fml.common.registry.GameRegistry +import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api.detail.ItemAPI import li.cil.oc.api.detail.ItemInfo import li.cil.oc.common import li.cil.oc.common.Loot import li.cil.oc.common.Tier +import li.cil.oc.common.block.SimpleBlock import li.cil.oc.common.item +import li.cil.oc.common.item.SimpleItem import li.cil.oc.common.recipe.Recipes import li.cil.oc.integration.Mods import li.cil.oc.util.Color @@ -35,9 +38,11 @@ object Items extends ItemAPI { } def registerBlock[T <: Block](instance: T, id: String) = { - if (instance.getClass.getName.startsWith("li.cil.oc.")) { - instance.setBlockName("oc." + id) - GameRegistry.registerBlock(instance, classOf[common.block.Item], id) + instance match { + case simple: SimpleBlock => + instance.setBlockName("oc." + id) + GameRegistry.registerBlock(simple, classOf[common.block.Item], id) + case _ => } descriptors += id -> new ItemInfo { override def name = id @@ -46,7 +51,10 @@ object Items extends ItemAPI { override def item = null - override def createItemStack(size: Int) = new ItemStack(instance, size) + override def createItemStack(size: Int) = instance match { + case simple: SimpleBlock => simple.createItemStack(size) + case _ => new ItemStack(instance, size) + } } names += instance -> id instance @@ -67,9 +75,11 @@ object Items extends ItemAPI { } def registerItem(instance: Item, id: String) = { - if (instance.getClass.getName.startsWith("li.cil.oc.")) { - instance.setUnlocalizedName("oc." + id.capitalize) - GameRegistry.registerItem(instance, id) + instance match { + case simple: SimpleItem => + simple.setUnlocalizedName("oc." + id) + GameRegistry.registerItem(simple, id) + case _ => } descriptors += id -> new ItemInfo { override def name = id @@ -78,7 +88,10 @@ object Items extends ItemAPI { override def item = instance - override def createItemStack(size: Int) = new ItemStack(instance, size) + override def createItemStack(size: Int) = instance match { + case simple: SimpleItem => simple.createItemStack(size) + case _ => new ItemStack(instance, size) + } } names += instance -> id instance @@ -107,77 +120,79 @@ object Items extends ItemAPI { def add[T](list: java.util.List[T], value: Any) = list.add(value.asInstanceOf[T]) super.getSubItems(item, tab, list) Loot.worldDisks.values.foreach(entry => add(list, entry._1)) + add(list, createOpenOS()) + add(list, createLuaBios()) } } GameRegistry.registerItem(multi, "item") - Recipes.addItem(new item.Analyzer(multi), "analyzer", "oc:analyzer") + Recipes.addMultiItem(new item.Analyzer(multi), "analyzer", "oc:analyzer") - Recipes.addItem(new item.Memory(multi, Tier.One), "ram1", "oc:ram1") - Recipes.addItem(new item.Memory(multi, Tier.Three), "ram3", "oc:ram3") - Recipes.addItem(new item.Memory(multi, Tier.Four), "ram4", "oc:ram4") + Recipes.addMultiItem(new item.Memory(multi, Tier.One), "ram1", "oc:ram1") + Recipes.addMultiItem(new item.Memory(multi, Tier.Three), "ram3", "oc:ram3") + Recipes.addMultiItem(new item.Memory(multi, Tier.Four), "ram4", "oc:ram4") - Recipes.addItem(new item.FloppyDisk(multi), "floppy", "oc:floppy") - Recipes.addItem(new item.HardDiskDrive(multi, Tier.One), "hdd1", "oc:hdd1") - Recipes.addItem(new item.HardDiskDrive(multi, Tier.Two), "hdd2", "oc:hdd2") - Recipes.addItem(new item.HardDiskDrive(multi, Tier.Three), "hdd3", "oc:hdd3") + Recipes.addMultiItem(new item.FloppyDisk(multi), "floppy", "oc:floppy") + Recipes.addMultiItem(new item.HardDiskDrive(multi, Tier.One), "hdd1", "oc:hdd1") + Recipes.addMultiItem(new item.HardDiskDrive(multi, Tier.Two), "hdd2", "oc:hdd2") + Recipes.addMultiItem(new item.HardDiskDrive(multi, Tier.Three), "hdd3", "oc:hdd3") - Recipes.addItem(new item.GraphicsCard(multi, Tier.One), "graphicsCard1", "oc:graphicsCard1") - Recipes.addItem(new item.GraphicsCard(multi, Tier.Two), "graphicsCard2", "oc:graphicsCard2") - Recipes.addItem(new item.GraphicsCard(multi, Tier.Three), "graphicsCard3", "oc:graphicsCard3") - Recipes.addItem(new item.NetworkCard(multi), "lanCard", "oc:lanCard") - Recipes.addItem(new item.RedstoneCard(multi, Tier.Two), "redstoneCard2", "oc:redstoneCard2") - Recipes.addItem(new item.WirelessNetworkCard(multi), "wlanCard", "oc:wlanCard") + Recipes.addMultiItem(new item.GraphicsCard(multi, Tier.One), "graphicsCard1", "oc:graphicsCard1") + Recipes.addMultiItem(new item.GraphicsCard(multi, Tier.Two), "graphicsCard2", "oc:graphicsCard2") + Recipes.addMultiItem(new item.GraphicsCard(multi, Tier.Three), "graphicsCard3", "oc:graphicsCard3") + Recipes.addMultiItem(new item.NetworkCard(multi), "lanCard", "oc:lanCard") + Recipes.addMultiItem(new item.RedstoneCard(multi, Tier.Two), "redstoneCard2", "oc:redstoneCard2") + Recipes.addMultiItem(new item.WirelessNetworkCard(multi), "wlanCard", "oc:wlanCard") - Recipes.addItem(new item.UpgradeCrafting(multi), "craftingUpgrade", "oc:craftingUpgrade") - Recipes.addItem(new item.UpgradeGenerator(multi), "generatorUpgrade", "oc:generatorUpgrade") + Recipes.addMultiItem(new item.UpgradeCrafting(multi), "craftingUpgrade", "oc:craftingUpgrade") + Recipes.addMultiItem(new item.UpgradeGenerator(multi), "generatorUpgrade", "oc:generatorUpgrade") ironNugget = new item.IronNugget(multi) - Recipes.addItem(new item.CuttingWire(multi), "cuttingWire", "oc:materialCuttingWire") - Recipes.addItem(new item.Acid(multi), "acid", "oc:materialAcid") - Recipes.addItem(new item.Disk(multi), "disk", "oc:materialDisk") + Recipes.addMultiItem(new item.CuttingWire(multi), "cuttingWire", "oc:materialCuttingWire") + Recipes.addMultiItem(new item.Acid(multi), "acid", "oc:materialAcid") + Recipes.addMultiItem(new item.Disk(multi), "disk", "oc:materialDisk") - Recipes.addItem(new item.ButtonGroup(multi), "buttonGroup", "oc:materialButtonGroup") - Recipes.addItem(new item.ArrowKeys(multi), "arrowKeys", "oc:materialArrowKey") - Recipes.addItem(new item.NumPad(multi), "numPad", "oc:materialNumPad") + Recipes.addMultiItem(new item.ButtonGroup(multi), "buttonGroup", "oc:materialButtonGroup") + Recipes.addMultiItem(new item.ArrowKeys(multi), "arrowKeys", "oc:materialArrowKey") + Recipes.addMultiItem(new item.NumPad(multi), "numPad", "oc:materialNumPad") - Recipes.addItem(new item.Transistor(multi), "transistor", "oc:materialTransistor") - Recipes.addItem(new item.Microchip(multi, Tier.One), "chip1", "oc:circuitChip1") - Recipes.addItem(new item.Microchip(multi, Tier.Two), "chip2", "oc:circuitChip2") - Recipes.addItem(new item.Microchip(multi, Tier.Three), "chip3", "oc:circuitChip3") - Recipes.addItem(new item.ALU(multi), "alu", "oc:materialALU") - Recipes.addItem(new item.ControlUnit(multi), "cu", "oc:materialCU") - Recipes.addItem(new item.CPU(multi, Tier.One), "cpu1", "oc:cpu1") + Recipes.addMultiItem(new item.Transistor(multi), "transistor", "oc:materialTransistor") + Recipes.addMultiItem(new item.Microchip(multi, Tier.One), "chip1", "oc:circuitChip1") + Recipes.addMultiItem(new item.Microchip(multi, Tier.Two), "chip2", "oc:circuitChip2") + Recipes.addMultiItem(new item.Microchip(multi, Tier.Three), "chip3", "oc:circuitChip3") + Recipes.addMultiItem(new item.ALU(multi), "alu", "oc:materialALU") + Recipes.addMultiItem(new item.ControlUnit(multi), "cu", "oc:materialCU") + Recipes.addMultiItem(new item.CPU(multi, Tier.One), "cpu1", "oc:cpu1") - Recipes.addItem(new item.RawCircuitBoard(multi), "rawCircuitBoard", "oc:materialCircuitBoardRaw") - Recipes.addItem(new item.CircuitBoard(multi), "circuitBoard", "oc:materialCircuitBoard") - Recipes.addItem(new item.PrintedCircuitBoard(multi), "printedCircuitBoard", "oc:materialCircuitBoardPrinted") - Recipes.addItem(new item.CardBase(multi), "card", "oc:materialCard") + Recipes.addMultiItem(new item.RawCircuitBoard(multi), "rawCircuitBoard", "oc:materialCircuitBoardRaw") + Recipes.addMultiItem(new item.CircuitBoard(multi), "circuitBoard", "oc:materialCircuitBoard") + Recipes.addMultiItem(new item.PrintedCircuitBoard(multi), "printedCircuitBoard", "oc:materialCircuitBoardPrinted") + Recipes.addMultiItem(new item.CardBase(multi), "card", "oc:materialCard") // v1.1.0 - Recipes.addItem(new item.UpgradeSolarGenerator(multi), "solarGeneratorUpgrade", "oc:solarGeneratorUpgrade") - Recipes.addItem(new item.UpgradeSign(multi), "signUpgrade", "oc:signUpgrade") - Recipes.addItem(new item.UpgradeNavigation(multi), "navigationUpgrade", "oc:navigationUpgrade") + Recipes.addMultiItem(new item.UpgradeSolarGenerator(multi), "solarGeneratorUpgrade", "oc:solarGeneratorUpgrade") + Recipes.addMultiItem(new item.UpgradeSign(multi), "signUpgrade", "oc:signUpgrade") + Recipes.addMultiItem(new item.UpgradeNavigation(multi), "navigationUpgrade", "oc:navigationUpgrade") // Always create, to avoid shifting IDs. val abstractBus = new item.AbstractBusCard(multi) if (Mods.StargateTech2.isAvailable) { - Recipes.addItem(abstractBus, "abstractBusCard", "oc:abstractBusCard") + Recipes.addMultiItem(abstractBus, "abstractBusCard", "oc:abstractBusCard") } - Recipes.addItem(new item.Memory(multi, Tier.Five), "ram5", "oc:ram5") - Recipes.addItem(new item.Memory(multi, Tier.Six), "ram6", "oc:ram6") + Recipes.addMultiItem(new item.Memory(multi, Tier.Five), "ram5", "oc:ram5") + Recipes.addMultiItem(new item.Memory(multi, Tier.Six), "ram6", "oc:ram6") // v1.2.0 - Recipes.addItem(new item.Server(multi, Tier.Three), "server3", "oc:server3") - Recipes.addItem(new item.Terminal(multi), "terminal", "oc:terminal") - Recipes.addItem(new item.CPU(multi, Tier.Two), "cpu2", "oc:cpu2") - Recipes.addItem(new item.CPU(multi, Tier.Three), "cpu3", "oc:cpu3") - Recipes.addItem(new item.InternetCard(multi), "internetCard", "oc:internetCard") - Recipes.addItem(new item.Server(multi, Tier.One), "server1", "oc:server1") - Recipes.addItem(new item.Server(multi, Tier.Two), "server2", "oc:server2") + Recipes.addMultiItem(new item.Server(multi, Tier.Three), "server3", "oc:server3") + Recipes.addMultiItem(new item.Terminal(multi), "terminal", "oc:terminal") + Recipes.addMultiItem(new item.CPU(multi, Tier.Two), "cpu2", "oc:cpu2") + Recipes.addMultiItem(new item.CPU(multi, Tier.Three), "cpu3", "oc:cpu3") + Recipes.addMultiItem(new item.InternetCard(multi), "internetCard", "oc:internetCard") + Recipes.addMultiItem(new item.Server(multi, Tier.One), "server1", "oc:server1") + Recipes.addMultiItem(new item.Server(multi, Tier.Two), "server2", "oc:server2") // v1.2.3 registerItem(new item.FloppyDisk(multi) { @@ -190,54 +205,46 @@ object Items extends ItemAPI { }, "lootDisk") // v1.2.6 - Recipes.addItem(new item.Interweb(multi), "interweb", "oc:materialInterweb") - Recipes.addItem(new item.UpgradeAngel(multi), "angelUpgrade", "oc:angelUpgrade") - Recipes.addItem(new item.Memory(multi, Tier.Two), "ram2", "oc:ram2") + Recipes.addMultiItem(new item.Interweb(multi), "interweb", "oc:materialInterweb") + Recipes.addMultiItem(new item.UpgradeAngel(multi), "angelUpgrade", "oc:angelUpgrade") + Recipes.addMultiItem(new item.Memory(multi, Tier.Two), "ram2", "oc:ram2") // v1.3.0 - Recipes.addItem(new item.LinkedCard(multi), "linkedCard", "oc:linkedCard") - Recipes.addItem(new item.UpgradeExperience(multi), "experienceUpgrade", "oc:experienceUpgrade") - Recipes.addItem(new item.UpgradeInventory(multi), "inventoryUpgrade", "oc:inventoryUpgrade") - Recipes.addItem(new item.UpgradeContainerUpgrade(multi, Tier.One), "upgradeContainer1", "oc:upgradeContainer1") - Recipes.addItem(new item.UpgradeContainerUpgrade(multi, Tier.Two), "upgradeContainer2", "oc:upgradeContainer2") - Recipes.addItem(new item.UpgradeContainerUpgrade(multi, Tier.Three), "upgradeContainer3", "oc:upgradeContainer3") - Recipes.addItem(new item.UpgradeContainerCard(multi, Tier.One), "cardContainer1", "oc:cardContainer1") - Recipes.addItem(new item.UpgradeContainerCard(multi, Tier.Two), "cardContainer2", "oc:cardContainer2") - Recipes.addItem(new item.UpgradeContainerCard(multi, Tier.Three), "cardContainer3", "oc:cardContainer3") + Recipes.addMultiItem(new item.LinkedCard(multi), "linkedCard", "oc:linkedCard") + Recipes.addMultiItem(new item.UpgradeExperience(multi), "experienceUpgrade", "oc:experienceUpgrade") + Recipes.addMultiItem(new item.UpgradeInventory(multi), "inventoryUpgrade", "oc:inventoryUpgrade") + Recipes.addMultiItem(new item.UpgradeContainerUpgrade(multi, Tier.One), "upgradeContainer1", "oc:upgradeContainer1") + Recipes.addMultiItem(new item.UpgradeContainerUpgrade(multi, Tier.Two), "upgradeContainer2", "oc:upgradeContainer2") + Recipes.addMultiItem(new item.UpgradeContainerUpgrade(multi, Tier.Three), "upgradeContainer3", "oc:upgradeContainer3") + Recipes.addMultiItem(new item.UpgradeContainerCard(multi, Tier.One), "cardContainer1", "oc:cardContainer1") + Recipes.addMultiItem(new item.UpgradeContainerCard(multi, Tier.Two), "cardContainer2", "oc:cardContainer2") + Recipes.addMultiItem(new item.UpgradeContainerCard(multi, Tier.Three), "cardContainer3", "oc:cardContainer3") // Special case loot disk because this one's craftable and having it have // the same item damage would confuse NEI and the item costs computation. - Recipes.addItem(new item.FloppyDisk(multi) { - override def createItemStack(amount: Int) = { - val data = new NBTTagCompound() - data.setString(Settings.namespace + "fs.label", "openos") + // UPDATE: screw that, keeping it for compatibility for now, but using recipe + // below now (creating "normal" loot disk). + registerItem(new item.FloppyDisk(multi) { + showInItemList = false - val nbt = new NBTTagCompound() - nbt.setTag(Settings.namespace + "data", data) - nbt.setString(Settings.namespace + "lootPath", "OpenOS") - nbt.setInteger(Settings.namespace + "color", Color.dyes.indexOf("dyeGreen")) - - val stack = super.createItemStack(amount) - stack.setTagCompound(nbt) - - stack - } + override def createItemStack(amount: Int) = createOpenOS(amount) override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = { if (player.isSneaking) get("floppy").createItemStack(1) else super.onItemRightClick(stack, world, player) } }, "openOS") + Recipes.addRecipe(createOpenOS(), "openOS") - Recipes.addItem(new item.UpgradeInventoryController(multi), "inventoryControllerUpgrade", "oc:inventoryControllerUpgrade") - Recipes.addItem(new item.UpgradeChunkloader(multi), "chunkloaderUpgrade", "oc:chunkloaderUpgrade") - Recipes.addItem(new item.UpgradeBattery(multi, Tier.One), "batteryUpgrade1", "oc:batteryUpgrade1") - Recipes.addItem(new item.UpgradeBattery(multi, Tier.Two), "batteryUpgrade2", "oc:batteryUpgrade2") - Recipes.addItem(new item.UpgradeBattery(multi, Tier.Three), "batteryUpgrade3", "oc:batteryUpgrade3") - Recipes.addItem(new item.RedstoneCard(multi, Tier.One), "redstoneCard1", "oc:redstoneCard1") + Recipes.addMultiItem(new item.UpgradeInventoryController(multi), "inventoryControllerUpgrade", "oc:inventoryControllerUpgrade") + Recipes.addMultiItem(new item.UpgradeChunkloader(multi), "chunkloaderUpgrade", "oc:chunkloaderUpgrade") + Recipes.addMultiItem(new item.UpgradeBattery(multi, Tier.One), "batteryUpgrade1", "oc:batteryUpgrade1") + Recipes.addMultiItem(new item.UpgradeBattery(multi, Tier.Two), "batteryUpgrade2", "oc:batteryUpgrade2") + Recipes.addMultiItem(new item.UpgradeBattery(multi, Tier.Three), "batteryUpgrade3", "oc:batteryUpgrade3") + Recipes.addMultiItem(new item.RedstoneCard(multi, Tier.One), "redstoneCard1", "oc:redstoneCard1") // 1.3.2 - Recipes.addItem(new item.UpgradeTractorBeam(multi), "tractorBeamUpgrade", "oc:tractorBeamUpgrade") + Recipes.addMultiItem(new item.UpgradeTractorBeam(multi), "tractorBeamUpgrade", "oc:tractorBeamUpgrade") // 1.3.? registerItem(new item.Tablet(multi), "tablet") @@ -246,26 +253,61 @@ object Items extends ItemAPI { registerItem(new item.Server(multi, Tier.Four), "serverCreative") // 1.3.3 - Recipes.addItem(new item.ComponentBus(multi, Tier.One), "componentBus1", "oc:componentBus1") - Recipes.addItem(new item.ComponentBus(multi, Tier.Two), "componentBus2", "oc:componentBus2") - Recipes.addItem(new item.ComponentBus(multi, Tier.Three), "componentBus3", "oc:componentBus3") + Recipes.addMultiItem(new item.ComponentBus(multi, Tier.One), "componentBus1", "oc:componentBus1") + Recipes.addMultiItem(new item.ComponentBus(multi, Tier.Two), "componentBus2", "oc:componentBus2") + Recipes.addMultiItem(new item.ComponentBus(multi, Tier.Three), "componentBus3", "oc:componentBus3") registerItem(new item.DebugCard(multi), "debugCard") // 1.3.5 - Recipes.addItem(new item.TabletCase(multi), "tabletCase", "oc:tabletCase") - Recipes.addItem(new item.UpgradePiston(multi), "pistonUpgrade", "oc:pistonUpgrade") - Recipes.addItem(new item.UpgradeTank(multi), "tankUpgrade", "oc:tankUpgrade") - Recipes.addItem(new item.UpgradeTankController(multi), "tankControllerUpgrade", "oc:tankControllerUpgrade") + Recipes.addMultiItem(new item.TabletCase(multi), "tabletCase", "oc:tabletCase") + Recipes.addMultiItem(new item.UpgradePiston(multi), "pistonUpgrade", "oc:pistonUpgrade") + Recipes.addMultiItem(new item.UpgradeTank(multi), "tankUpgrade", "oc:tankUpgrade") + Recipes.addMultiItem(new item.UpgradeTankController(multi), "tankControllerUpgrade", "oc:tankControllerUpgrade") // 1.4.0 - Recipes.addItem(new item.UpgradeDatabase(multi, Tier.One), "databaseUpgrade1", "oc:databaseUpgrade1") - Recipes.addItem(new item.UpgradeDatabase(multi, Tier.Two), "databaseUpgrade2", "oc:databaseUpgrade2") - Recipes.addItem(new item.UpgradeDatabase(multi, Tier.Three), "databaseUpgrade3", "oc:databaseUpgrade3") + Recipes.addMultiItem(new item.UpgradeDatabase(multi, Tier.One), "databaseUpgrade1", "oc:databaseUpgrade1") + Recipes.addMultiItem(new item.UpgradeDatabase(multi, Tier.Two), "databaseUpgrade2", "oc:databaseUpgrade2") + Recipes.addMultiItem(new item.UpgradeDatabase(multi, Tier.Three), "databaseUpgrade3", "oc:databaseUpgrade3") registerItem(new item.Debugger(multi), "debugger") // 1.4.2 if (Mods.AppliedEnergistics2.isAvailable) { Recipes.addItem(new item.AppliedEnergisticsP2PTunnel(), "appengTunnel") } + + val eeprom = new item.EEPROM() + Recipes.addItem(eeprom, "eeprom", "oc:eeprom") + Recipes.addRecipe(createLuaBios(), "luaBios") + } + + def createOpenOS(amount: Int = 1) = { + val data = new NBTTagCompound() + data.setString(Settings.namespace + "fs.label", "openos") + + val nbt = new NBTTagCompound() + nbt.setTag(Settings.namespace + "data", data) + nbt.setString(Settings.namespace + "lootPath", "OpenOS") + nbt.setInteger(Settings.namespace + "color", Color.dyes.indexOf("dyeGreen")) + + val stack = get("lootDisk").createItemStack(amount) + stack.setTagCompound(nbt) + + stack + } + + def createLuaBios(amount: Int = 1) = { + val data = new NBTTagCompound() + val code = new Array[Byte](4 * 1024) + val count = OpenComputers.getClass.getResourceAsStream(Settings.scriptPath + "eeprom.lua").read(code) + data.setByteArray(Settings.namespace + "eeprom", code.take(count)) + data.setString(Settings.namespace + "label", "Lua BIOS") + + val nbt = new NBTTagCompound() + nbt.setTag(Settings.namespace + "data", data) + + val stack = get("eeprom").createItemStack(amount) + stack.setTagCompound(nbt) + + stack } } diff --git a/src/main/scala/li/cil/oc/common/item/AppliedEnergisticsP2PTunnel.scala b/src/main/scala/li/cil/oc/common/item/AppliedEnergisticsP2PTunnel.scala index b7cfb3704..de69c9f1c 100644 --- a/src/main/scala/li/cil/oc/common/item/AppliedEnergisticsP2PTunnel.scala +++ b/src/main/scala/li/cil/oc/common/item/AppliedEnergisticsP2PTunnel.scala @@ -12,7 +12,7 @@ import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.world.World -class AppliedEnergisticsP2PTunnel extends Item with IPartItem { +class AppliedEnergisticsP2PTunnel extends SimpleItem with IPartItem { override def createPartFromItemStack(stack: ItemStack) = new PartP2POCNode(stack) override def onItemUse(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float) = diff --git a/src/main/scala/li/cil/oc/common/item/Delegator.scala b/src/main/scala/li/cil/oc/common/item/Delegator.scala index a37d5cf14..565a6a1de 100644 --- a/src/main/scala/li/cil/oc/common/item/Delegator.scala +++ b/src/main/scala/li/cil/oc/common/item/Delegator.scala @@ -5,6 +5,7 @@ import java.util.Random import cpw.mods.fml.relauncher.Side import cpw.mods.fml.relauncher.SideOnly +import li.cil.oc.Settings import li.cil.oc.common.tileentity import li.cil.oc.CreativeTab import li.cil.oc.OpenComputers @@ -26,6 +27,7 @@ class Delegator extends Item { setHasSubtypes(true) setCreativeTab(CreativeTab) setUnlocalizedName("oc.multi") + iconString = Settings.resourceDomain + ":Microchip0" // ----------------------------------------------------------------------- // // SubItem diff --git a/src/main/scala/li/cil/oc/common/item/EEPROM.scala b/src/main/scala/li/cil/oc/common/item/EEPROM.scala new file mode 100644 index 000000000..e9959db44 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/item/EEPROM.scala @@ -0,0 +1,19 @@ +package li.cil.oc.common.item + +import li.cil.oc.Settings +import net.minecraft.item.ItemStack + +class EEPROM extends SimpleItem { + override def getItemStackDisplayName(stack: ItemStack): String = { + if (stack.hasTagCompound) { + val tag = stack.getTagCompound + if (tag.hasKey(Settings.namespace + "data")) { + val data = tag.getCompoundTag(Settings.namespace + "data") + if (data.hasKey(Settings.namespace + "label")) { + return data.getString(Settings.namespace + "label") + } + } + } + super.getItemStackDisplayName(stack) + } +} diff --git a/src/main/scala/li/cil/oc/common/item/SimpleItem.scala b/src/main/scala/li/cil/oc/common/item/SimpleItem.scala new file mode 100644 index 000000000..b04576970 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/item/SimpleItem.scala @@ -0,0 +1,62 @@ +package li.cil.oc.common.item + +import java.util +import java.util.Random + +import cpw.mods.fml.relauncher.Side +import cpw.mods.fml.relauncher.SideOnly +import li.cil.oc.CreativeTab +import li.cil.oc.Localization +import li.cil.oc.Settings +import li.cil.oc.client.KeyBindings +import li.cil.oc.common.tileentity +import li.cil.oc.util.ItemCosts +import li.cil.oc.util.Tooltip +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraft.util.WeightedRandomChestContent +import net.minecraft.world.World +import net.minecraftforge.common.ChestGenHooks +import org.lwjgl.input + +class SimpleItem extends Item { + setCreativeTab(CreativeTab) + iconString = Settings.resourceDomain + ":" + getClass.getSimpleName + + def createItemStack(amount: Int = 1) = new ItemStack(this, amount) + + override def isBookEnchantable(stack: ItemStack, book: ItemStack) = false + + override def getChestGenBase(chest: ChestGenHooks, rnd: Random, original: WeightedRandomChestContent) = original + + override def doesSneakBypassUse(world: World, x: Int, y: Int, z: Int, player: EntityPlayer) = { + world.getTileEntity(x, y, z) match { + case drive: tileentity.DiskDrive => true + case _ => super.doesSneakBypassUse(world, x, y, z, player) + } + } + + @SideOnly(Side.CLIENT) + override def addInformation(stack: ItemStack, player: EntityPlayer, tooltip: util.List[_], advanced: Boolean): Unit = { + val tt = tooltip.asInstanceOf[util.List[String]] + tt.addAll(Tooltip.get(getClass.getSimpleName)) + + if (ItemCosts.hasCosts(stack)) { + if (KeyBindings.showMaterialCosts) { + ItemCosts.addTooltip(stack, tt) + } + else { + tt.add(Localization.localizeImmediately( + Settings.namespace + "tooltip.MaterialCosts", + input.Keyboard.getKeyName(KeyBindings.materialCosts.getKeyCode))) + } + } + if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "data")) { + val data = stack.getTagCompound.getCompoundTag(Settings.namespace + "data") + if (data.hasKey("node") && data.getCompoundTag("node").hasKey("address")) { + tt.add("§8" + data.getCompoundTag("node").getString("address").substring(0, 13) + "...§7") + } + } + } +} diff --git a/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala index 7f3e5d378..62bb84589 100644 --- a/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala +++ b/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala @@ -58,11 +58,6 @@ object ExtendedRecipe { for (i <- 0 until inventory.getSizeInventory) { val stack = inventory.getStackInSlot(i) if (stack != null) { - Color.findDye(stack) match { - case Some(oreDictName) => - nbt.setInteger(Settings.namespace + "color", Color.dyes.indexOf(oreDictName)) - case _ => - } if (api.Items.get(stack) == floppy && stack.hasTagCompound) { val oldData = stack.getTagCompound for (oldTagName <- oldData.func_150296_c().map(_.asInstanceOf[String])) { diff --git a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala index e207ecb15..6e0030965 100644 --- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala +++ b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala @@ -9,6 +9,7 @@ import cpw.mods.fml.common.registry.GameRegistry import li.cil.oc._ import li.cil.oc.common.block.SimpleBlock import li.cil.oc.common.init.Items +import li.cil.oc.common.item.SimpleItem import li.cil.oc.integration.Mods import li.cil.oc.integration.util.NEI import li.cil.oc.util.Color @@ -17,6 +18,7 @@ import net.minecraft.item.Item import net.minecraft.item.ItemBlock import net.minecraft.item.ItemStack import net.minecraft.item.crafting.FurnaceRecipes +import net.minecraft.nbt.NBTTagCompound import net.minecraft.util.RegistryNamespaced import net.minecraftforge.oredict.OreDictionary import net.minecraftforge.oredict.RecipeSorter @@ -32,24 +34,35 @@ object Recipes { def addBlock(instance: Block, name: String, oreDict: String = null) = { Items.registerBlock(instance, name) - list += new ItemStack(instance) -> name - register(oreDict, new ItemStack(instance)) + addRecipe(new ItemStack(instance), name) + register(oreDict, instance match { + case simple: SimpleBlock => simple.createItemStack() + case _ => new ItemStack(instance) + }) instance } - def addItem[T <: common.item.Delegate](delegate: T, name: String, oreDict: String = null) = { + def addMultiItem[T <: common.item.Delegate](delegate: T, name: String, oreDict: String = null) = { Items.registerItem(delegate, name) - list += delegate.createItemStack() -> name + addRecipe(delegate.createItemStack(), name) register(oreDict, delegate.createItemStack()) delegate } - def addItem(instance: Item, name: String) = { + def addItem(instance: Item, name: String, oreDict: String = null) = { Items.registerItem(instance, name) - list += new ItemStack(instance) -> name + addRecipe(new ItemStack(instance), name) + register(oreDict, instance match { + case simple: SimpleItem => simple.createItemStack() + case _ => new ItemStack(instance) + }) instance } + def addRecipe(stack: ItemStack, name: String) { + list += stack -> name + } + private def register(name: String, item: ItemStack) { if (name != null) { oreDictEntries += name -> item @@ -113,7 +126,11 @@ object Recipes { // Floppy disk coloring. val floppy = api.Items.get("floppy").createItemStack(1) for (dye <- Color.dyes) { - GameRegistry.addRecipe(new ExtendedShapelessOreRecipe(floppy, floppy, dye)) + val result = api.Items.get("floppy").createItemStack(1) + val tag = new NBTTagCompound() + tag.setInteger(Settings.namespace + "color", Color.dyes.indexOf(dye)) + result.setTagCompound(tag) + GameRegistry.addRecipe(new ExtendedShapelessOreRecipe(result, floppy, dye)) } } catch { diff --git a/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala b/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala index 982a229d5..d576e37ef 100644 --- a/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala +++ b/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala @@ -71,7 +71,7 @@ object RobotTemplate extends Template { componentSlots.appendTag(Map("type" -> Slot.CPU, "tier" -> Tier.One)) componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.One)) componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.One)) - componentSlots.appendTag(Map("type" -> Slot.Floppy, "tier" -> Tier.Any)) + componentSlots.appendTag(Map("type" -> Slot.EEPROM, "tier" -> Tier.Any)) componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.One)) nbt.setTag("componentSlots", componentSlots) @@ -109,7 +109,7 @@ object RobotTemplate extends Template { componentSlots.appendTag(Map("type" -> Slot.CPU, "tier" -> Tier.Two)) componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Two)) componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Two)) - componentSlots.appendTag(Map("type" -> Slot.Floppy, "tier" -> Tier.Any)) + componentSlots.appendTag(Map("type" -> Slot.EEPROM, "tier" -> Tier.Any)) componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Two)) nbt.setTag("componentSlots", componentSlots) @@ -150,7 +150,7 @@ object RobotTemplate extends Template { componentSlots.appendTag(Map("type" -> Slot.CPU, "tier" -> Tier.Three)) componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Three)) componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Three)) - componentSlots.appendTag(Map("type" -> Slot.Floppy, "tier" -> Tier.Any)) + componentSlots.appendTag(Map("type" -> Slot.EEPROM, "tier" -> Tier.Any)) componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Three)) componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Two)) nbt.setTag("componentSlots", componentSlots) @@ -192,7 +192,7 @@ object RobotTemplate extends Template { componentSlots.appendTag(Map("type" -> Slot.CPU, "tier" -> Tier.Three)) componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Three)) componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Three)) - componentSlots.appendTag(Map("type" -> Slot.Floppy, "tier" -> Tier.Any)) + componentSlots.appendTag(Map("type" -> Slot.EEPROM, "tier" -> Tier.Any)) componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Three)) componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Three)) nbt.setTag("componentSlots", componentSlots) diff --git a/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala b/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala index 5144336c9..425c6467c 100644 --- a/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala +++ b/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala @@ -17,6 +17,7 @@ import scala.collection.mutable object TabletTemplate extends Template { override protected val suggestedComponents = Array( + "BIOS" -> hasComponent("eeprom") _, "GraphicsCard" -> ((inventory: IInventory) => Array("graphicsCard1", "graphicsCard2", "graphicsCard3").exists(name => hasComponent(name)(inventory))), "OS" -> hasFileSystem _) @@ -62,6 +63,7 @@ object TabletTemplate extends Template { componentSlots.appendTag(Map("type" -> Slot.CPU, "tier" -> Tier.Two)) componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Two)) componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.Two)) + componentSlots.appendTag(Map("type" -> Slot.EEPROM, "tier" -> Tier.Any)) componentSlots.appendTag(Map("type" -> Slot.HDD, "tier" -> Tier.Two)) nbt.setTag("componentSlots", componentSlots) diff --git a/src/main/scala/li/cil/oc/common/template/Template.scala b/src/main/scala/li/cil/oc/common/template/Template.scala index 540810d71..f9ac618a4 100644 --- a/src/main/scala/li/cil/oc/common/template/Template.scala +++ b/src/main/scala/li/cil/oc/common/template/Template.scala @@ -18,6 +18,7 @@ import scala.collection.mutable abstract class Template { protected val suggestedComponents = Array( + "BIOS" -> hasComponent("eeprom") _, "Screen" -> hasComponent("screen1") _, "Keyboard" -> hasComponent("keyboard") _, "GraphicsCard" -> ((inventory: IInventory) => Array("graphicsCard1", "graphicsCard2", "graphicsCard3").exists(name => hasComponent(name)(inventory))), diff --git a/src/main/scala/li/cil/oc/common/tileentity/Case.scala b/src/main/scala/li/cil/oc/common/tileentity/Case.scala index 1e6fa64d9..0b386a467 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Case.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Case.scala @@ -12,6 +12,7 @@ import li.cil.oc.common import li.cil.oc.common.InventorySlots import li.cil.oc.common.Slot import li.cil.oc.common.Tier +import li.cil.oc.common.init.Items import li.cil.oc.util.Color import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack @@ -90,11 +91,20 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with color = Color.byTier(tier) super.readFromNBT(nbt) recomputeMaxComponents() + + // Code for migrating from 1.4.1 -> 1.4.2, add EEPROM. + // TODO Remove in 1.5 + if (!nbt.hasKey(Settings.namespace + "biosFlag")) { + items(items.length - 1) = Option(Items.createLuaBios()) + } } override def writeToNBT(nbt: NBTTagCompound) { nbt.setByte(Settings.namespace + "tier", tier.toByte) super.writeToNBT(nbt) + + // TODO Remove in 1.5 + nbt.setBoolean(Settings.namespace + "biosFlag", true) } // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala b/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala index 8f0922481..9edf884bc 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala @@ -12,6 +12,7 @@ import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network._ import li.cil.oc.client.Sound import li.cil.oc.common.Tier +import li.cil.oc.common.init.Items import li.cil.oc.integration.Mods import li.cil.oc.integration.opencomputers.DriverRedstoneCard import li.cil.oc.integration.stargatetech2.DriverAbstractBusCard @@ -294,7 +295,8 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB super.readFromNBT(nbt) for (slot <- 0 until getSizeInventory) { if (getStackInSlot(slot) != null) { - servers(slot) = Some(new component.Server(this, slot)) + val server = new component.Server(this, slot) + servers(slot) = Option(server) } } nbt.getTagList(Settings.namespace + "servers", NBT.TAG_COMPOUND).toArray[NBTTagCompound]. @@ -305,6 +307,12 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB try server.load(tag) catch { case t: Throwable => OpenComputers.log.warn("Failed restoring server state. Please report this!", t) } + + // Code for migrating from 1.4.1 -> 1.4.2, add EEPROM. + // TODO Remove in 1.5 + if (!nbt.hasKey(Settings.namespace + "biosFlag")) { + server.inventory.items(server.inventory.items.length - 1) = Option(Items.createLuaBios()) + } case _ => } case _ => @@ -347,6 +355,9 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB })) nbt.setInteger(Settings.namespace + "range", range) nbt.setBoolean(Settings.namespace + "internalSwitch", internalSwitch) + + // TODO Remove in 1.5 + nbt.setBoolean(Settings.namespace + "biosFlag", true) } @SideOnly(Side.CLIENT) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverEEPROM.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverEEPROM.scala new file mode 100644 index 000000000..9f562a7b8 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverEEPROM.scala @@ -0,0 +1,26 @@ +package li.cil.oc.integration.opencomputers + +import li.cil.oc.api +import li.cil.oc.api.driver.EnvironmentAware +import li.cil.oc.api.driver.EnvironmentHost +import li.cil.oc.api.driver.item.HostAware +import li.cil.oc.common.Slot +import li.cil.oc.common.Tier +import li.cil.oc.server.component +import net.minecraft.item.ItemStack + +object DriverEEPROM extends Item with HostAware with EnvironmentAware { + override def worksWith(stack: ItemStack) = + isOneOf(stack, api.Items.get("eeprom")) + + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) = + worksWith(stack) && (isComputer(host) || isRobot(host) || isServer(host) || isTablet(host)) + + override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.EEPROM() + + override def slot(stack: ItemStack) = Slot.EEPROM + + override def tier(stack: ItemStack) = Tier.One + + override def providedEnvironment(stack: ItemStack) = classOf[component.EEPROM] +} diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala index e14b452fc..66e7c9dee 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala @@ -54,6 +54,7 @@ object ModOpenComputers extends ModProxy { api.Driver.add(DriverComponentBus) api.Driver.add(DriverCPU) api.Driver.add(DriverDebugCard) + api.Driver.add(DriverEEPROM) api.Driver.add(DriverFileSystem) api.Driver.add(DriverGeolyzer) api.Driver.add(DriverGraphicsCard) diff --git a/src/main/scala/li/cil/oc/server/component/EEPROM.scala b/src/main/scala/li/cil/oc/server/component/EEPROM.scala new file mode 100644 index 000000000..fe7225049 --- /dev/null +++ b/src/main/scala/li/cil/oc/server/component/EEPROM.scala @@ -0,0 +1,60 @@ +package li.cil.oc.server.component + +import li.cil.oc.Settings +import li.cil.oc.api.Network +import li.cil.oc.api.machine.Arguments +import li.cil.oc.api.machine.Callback +import li.cil.oc.api.machine.Context +import li.cil.oc.api.network._ +import li.cil.oc.api.prefab +import net.minecraft.nbt.NBTTagCompound + +class EEPROM extends prefab.ManagedEnvironment { + override val node = Network.newNode(this, Visibility.Network). + withComponent("eeprom", Visibility.Network). + withConnector(). + create() + + var data = Array.empty[Byte] + + var label = "EEPROM" + + // ----------------------------------------------------------------------- // + + @Callback(direct = true, doc = """function():string -- Get the currently stored byte array.""") + def get(context: Context, args: Arguments): Array[AnyRef] = result(data) + + @Callback(doc = """function(data:string) -- Overwrite the currently stored byte array.""") + def set(context: Context, args: Arguments): Array[AnyRef] = { + val newData = args.checkByteArray(0) + if (newData.length > 4 * 1024) throw new IllegalArgumentException("not enough space") + data = newData + context.pause(2) // deliberately slow to discourage use as normal storage medium + null + } + + @Callback(direct = true, doc = """function():string -- Get the label of the EEPROM.""") + def getLabel(context: Context, args: Arguments): Array[AnyRef] = result(label) + + @Callback(doc = """function(data:string) -- Set the label of the EEPROM.""") + def setLabel(context: Context, args: Arguments): Array[AnyRef] = { + label = args.checkString(0).take(16) + null + } + + // ----------------------------------------------------------------------- // + + override def load(nbt: NBTTagCompound) { + super.load(nbt) + data = nbt.getByteArray(Settings.namespace + "eeprom") + if (nbt.hasKey(Settings.namespace + "label")) { + label = nbt.getString(Settings.namespace + "label") + } + } + + override def save(nbt: NBTTagCompound) { + super.save(nbt) + nbt.setByteArray(Settings.namespace + "eeprom", data) + nbt.setString(Settings.namespace + "label", label) + } +} diff --git a/src/main/scala/li/cil/oc/server/machine/luac/NativeLuaArchitecture.scala b/src/main/scala/li/cil/oc/server/machine/luac/NativeLuaArchitecture.scala index 5d246ca2f..9eeababe8 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/NativeLuaArchitecture.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/NativeLuaArchitecture.scala @@ -287,7 +287,7 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu apis.foreach(_.initialize()) - lua.load(classOf[Machine].getResourceAsStream(Settings.scriptPath + "kernel.lua"), "=kernel", "t") + lua.load(classOf[Machine].getResourceAsStream(Settings.scriptPath + "machine.lua"), "=kernel", "t") lua.newThread() // Left as the first value on the stack. true diff --git a/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala b/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala index ee6a5e77d..9692cc0f4 100644 --- a/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala +++ b/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala @@ -218,7 +218,7 @@ class LuaJLuaArchitecture(val machine: api.machine.Machine) extends Architecture recomputeMemory() - val kernel = lua.load(classOf[Machine].getResourceAsStream(Settings.scriptPath + "kernel.lua"), "=kernel", "t", lua) + val kernel = lua.load(classOf[Machine].getResourceAsStream(Settings.scriptPath + "machine.lua"), "=kernel", "t", lua) thread = new LuaThread(lua, kernel) // Left as the first value on the stack. true diff --git a/src/main/scala/li/cil/oc/util/ItemUtils.scala b/src/main/scala/li/cil/oc/util/ItemUtils.scala index eaa3a1740..2acacb50e 100644 --- a/src/main/scala/li/cil/oc/util/ItemUtils.scala +++ b/src/main/scala/li/cil/oc/util/ItemUtils.scala @@ -8,6 +8,7 @@ import li.cil.oc.api import li.cil.oc.api.Persistable import li.cil.oc.common.Tier import li.cil.oc.common.block.DelegatorConverter +import li.cil.oc.common.init.Items import li.cil.oc.integration.opencomputers.DriverScreen import li.cil.oc.integration.opencomputers.DriverUpgradeExperience import li.cil.oc.util.ExtendedNBT._ @@ -77,34 +78,16 @@ object ItemUtils { } totalEnergy = nbt.getInteger(Settings.namespace + "storedEnergy") robotEnergy = nbt.getInteger(Settings.namespace + "robotEnergy") - if (nbt.hasKey(Settings.namespace + "components")) { - tier = nbt.getInteger(Settings.namespace + "tier") - components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND). - toArray[NBTTagCompound].map(loadStack) - containers = nbt.getTagList(Settings.namespace + "containers", NBT.TAG_COMPOUND). - toArray[NBTTagCompound].map(loadStack) - } - else { - // Old robot, upgrade to new modular model. - tier = 0 - val experienceUpgrade = api.Items.get("experienceUpgrade").createItemStack(1) - DriverUpgradeExperience.dataTag(experienceUpgrade).setDouble(Settings.namespace + "xp", nbt.getDouble(Settings.namespace + "xp")) - components = Array( - api.Items.get("screen1").createItemStack(1), - api.Items.get("keyboard").createItemStack(1), - api.Items.get("inventoryUpgrade").createItemStack(1), - experienceUpgrade, - api.Items.get("openOS").createItemStack(1), - api.Items.get("graphicsCard1").createItemStack(1), - api.Items.get("cpu1").createItemStack(1), - api.Items.get("ram2").createItemStack(1) - ) - containers = Array( - api.Items.get("cardContainer2").createItemStack(1), - api.Items.get("diskDrive").createItemStack(1), - api.Items.get("upgradeContainer3").createItemStack(1) - ) - robotEnergy = totalEnergy + tier = nbt.getInteger(Settings.namespace + "tier") + components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND). + toArray[NBTTagCompound].map(loadStack) + containers = nbt.getTagList(Settings.namespace + "containers", NBT.TAG_COMPOUND). + toArray[NBTTagCompound].map(loadStack) + + // Code for migrating from 1.4.1 -> 1.4.2, add EEPROM. + // TODO Remove in 1.5 + if (!nbt.hasKey(Settings.namespace + "biosFlag")) { + components :+= Items.createLuaBios() } } @@ -120,6 +103,9 @@ object ItemUtils { nbt.setInteger(Settings.namespace + "tier", tier) nbt.setNewTagList(Settings.namespace + "components", components.toIterable) nbt.setNewTagList(Settings.namespace + "containers", containers.toIterable) + + // TODO Remove in 1.5 + nbt.setBoolean(Settings.namespace + "biosFlag", true) } def createItemStack() = { @@ -224,6 +210,13 @@ object ItemUtils { isRunning = nbt.getBoolean(Settings.namespace + "isRunning") energy = nbt.getDouble(Settings.namespace + "energy") maxEnergy = nbt.getDouble(Settings.namespace + "maxEnergy") + + // Code for migrating from 1.4.1 -> 1.4.2, add EEPROM. + // TODO Remove in 1.5 + if (!nbt.hasKey(Settings.namespace + "biosFlag")) { + val firstEmpty = items.indexWhere(_.isEmpty) + items(firstEmpty) = Option(Items.createLuaBios()) + } } override def save(nbt: NBTTagCompound) { @@ -239,6 +232,9 @@ object ItemUtils { nbt.setBoolean(Settings.namespace + "isRunning", isRunning) nbt.setDouble(Settings.namespace + "energy", energy) nbt.setDouble(Settings.namespace + "maxEnergy", maxEnergy) + + // TODO Remove in 1.5 + nbt.setBoolean(Settings.namespace + "biosFlag", true) } } diff --git a/src/main/scala/li/cil/oc/util/Tooltip.scala b/src/main/scala/li/cil/oc/util/Tooltip.scala index 755b58a47..89dca660e 100644 --- a/src/main/scala/li/cil/oc/util/Tooltip.scala +++ b/src/main/scala/li/cil/oc/util/Tooltip.scala @@ -1,6 +1,7 @@ package li.cil.oc.util import li.cil.oc.Localization +import li.cil.oc.Settings import li.cil.oc.client.KeyBindings import net.minecraft.client.Minecraft import org.lwjgl.input.Keyboard @@ -14,6 +15,7 @@ object Tooltip { private def font = Minecraft.getMinecraft.fontRenderer def get(name: String, args: Any*): java.util.List[String] = { + if (!Localization.canLocalize(Settings.namespace + "tooltip." + name)) return Seq.empty[String] val tooltip = Localization.localizeImmediately("tooltip." + name). format(args.map(_.toString): _*) val isSubTooltip = name.contains(".")