diff --git a/src/main/java/li/cil/oc/api/API.java b/src/main/java/li/cil/oc/api/API.java
index 5e277005b..3497915e9 100644
--- a/src/main/java/li/cil/oc/api/API.java
+++ b/src/main/java/li/cil/oc/api/API.java
@@ -12,7 +12,7 @@ import li.cil.oc.api.detail.*;
*/
public class API {
public static final String ID_OWNER = "OpenComputers|Core";
- public static final String VERSION = "5.4.0";
+ public static final String VERSION = "5.5.0";
public static DriverAPI driver = null;
public static FileSystemAPI fileSystem = null;
diff --git a/src/main/java/li/cil/oc/api/Items.java b/src/main/java/li/cil/oc/api/Items.java
index a10182d6c..81a10bc2f 100644
--- a/src/main/java/li/cil/oc/api/Items.java
+++ b/src/main/java/li/cil/oc/api/Items.java
@@ -1,8 +1,11 @@
package li.cil.oc.api;
import li.cil.oc.api.detail.ItemInfo;
+import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack;
+import java.util.concurrent.Callable;
+
/**
* Access to item definitions for all blocks and items provided by
* OpenComputers.
@@ -44,6 +47,53 @@ public final class Items {
return null;
}
+ /**
+ * Register a single loot floppy disk.
+ *
+ * The disk will be listed in the creative tab of OpenComputers.
+ *
+ * The specified factory callable will be used to generate a new file
+ * system when the loot disk is used as a component. The specified name
+ * will be used as the label for the loot disk, as well as the identifier
+ * to select the corresponding factory method, so choose wisely.
+ *
+ * To use some directory in your mod JAR as the directory provided by the
+ * loot disk, use {@link FileSystem#fromClass} in your callable.
+ *
+ * @param name the label and identifier to use for the loot disk.
+ * @param color the color of the disk, as a Minecraft color.
+ * @param factory the callable to call for creating file system instances.
+ * @return an item stack representing the registered loot disk, to allow
+ * adding a recipe for your loot disk, for example.
+ */
+ public static ItemStack registerFloppy(String name, EnumDyeColor color, Callable factory) {
+ if (API.items != null)
+ return API.items.registerFloppy(name, color, factory);
+ return null;
+ }
+
+ /**
+ * Register a single custom EEPROM.
+ *
+ * The EEPROM will be listed in the creative tab of OpenComputers.
+ *
+ * The EEPROM will be initialized with the specified code and data byte
+ * arrays. For script code (e.g. a Lua script) use String.getBytes("UTF-8").
+ * You can omit any of the arguments by passing null.
+ *
+ * @param name the label of the EEPROM.
+ * @param code the code section of the EEPROM.
+ * @param data the data section of the EEPROM.
+ * @param readonly whether the code section is read-only.
+ * @return an item stack representing the registered EEPROM, to allow
+ * adding a recipe for your custom BIOS, for example.
+ */
+ public static ItemStack registerEEPROM(String name, byte[] code, byte[] data, boolean readonly) {
+ if (API.items != null)
+ return API.items.registerEEPROM(name, code, data, readonly);
+ return null;
+ }
+
// ----------------------------------------------------------------------- //
private Items() {
diff --git a/src/main/java/li/cil/oc/api/detail/ItemAPI.java b/src/main/java/li/cil/oc/api/detail/ItemAPI.java
index 8ae9f334d..358472c48 100644
--- a/src/main/java/li/cil/oc/api/detail/ItemAPI.java
+++ b/src/main/java/li/cil/oc/api/detail/ItemAPI.java
@@ -1,7 +1,11 @@
package li.cil.oc.api.detail;
+import li.cil.oc.api.FileSystem;
+import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack;
+import java.util.concurrent.Callable;
+
public interface ItemAPI {
/**
* Get a descriptor object for the block or item with the specified name.
@@ -26,4 +30,47 @@ public interface ItemAPI {
* if the stack is not a valid OpenComputers item or block.
*/
ItemInfo get(ItemStack stack);
+
+ /**
+ * Register a single loot floppy disk.
+ *
+ * The disk will be listed in the creative tab of OpenComputers.
+ *
+ * The specified factory callable will be used to generate a new file
+ * system when the loot disk is used as a component. The specified name
+ * will be used as the label for the loot disk, as well as the identifier
+ * to select the corresponding factory method, so choose wisely.
+ *
+ * To use some directory in your mod JAR as the directory provided by the
+ * loot disk, use {@link FileSystem#fromClass} in your callable.
+ *
+ * Call this in the init phase or later, not in pre-init.
+ *
+ * @param name the label and identifier to use for the loot disk.
+ * @param color the color of the disk, as a Minecraft color.
+ * @param factory the callable to call for creating file system instances.
+ * @return an item stack representing the registered loot disk, to allow
+ * adding a recipe for your loot disk, for example.
+ */
+ ItemStack registerFloppy(String name, EnumDyeColor color, Callable factory);
+
+ /**
+ * Register a single custom EEPROM.
+ *
+ * The EEPROM will be listed in the creative tab of OpenComputers.
+ *
+ * The EEPROM will be initialized with the specified code and data byte
+ * arrays. For script code (e.g. a Lua script) use String.getBytes("UTF-8").
+ * You can omit any of the arguments by passing null.
+ *
+ * Call this in the init phase or later, not in pre-init.
+ *
+ * @param name the label of the EEPROM.
+ * @param code the code section of the EEPROM.
+ * @param data the data section of the EEPROM.
+ * @param readonly whether the code section is read-only.
+ * @return an item stack representing the registered EEPROM, to allow
+ * adding a recipe for your custom BIOS, for example.
+ */
+ ItemStack registerEEPROM(String name, byte[] code, byte[] data, boolean readonly);
}
diff --git a/src/main/resources/assets/opencomputers/loot/loot.properties b/src/main/resources/assets/opencomputers/loot/loot.properties
index 95e955686..b7f6a3b68 100644
--- a/src/main/resources/assets/opencomputers/loot/loot.properties
+++ b/src/main/resources/assets/opencomputers/loot/loot.properties
@@ -10,7 +10,7 @@ MazeGen=maze:1:dyeOrange
Network=network:1:dyeLime
OpenIRC=irc:1:dyeLightBlue
OpenLoader=openloader:1:dyeMagenta
-OpenOS=openos:0:dyeGreen
+OpenOS=openOS:0:dyeGreen
OPPM=oppm:0:dyeCyan
# Higher chance to find the dig program, because it has the most immediate
# use - OpenOS is craftable and IRC can be downloaded once an internet card
diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes
index b3d54f0fa..d1e29ac97 100644
--- a/src/main/resources/assets/opencomputers/recipes/default.recipes
+++ b/src/main/resources/assets/opencomputers/recipes/default.recipes
@@ -365,7 +365,6 @@ chameliumBlock {
["oc:chamelium", "oc:chamelium", "oc:chamelium"],
["oc:chamelium", "oc:chamelium", "oc:chamelium"]]
}
-
endstone {
input: [[enderPearl, "oc:chameliumBlock", enderPearl]
["oc:chameliumBlock", enderPearl, "oc:chameliumBlock"]
diff --git a/src/main/scala/li/cil/oc/client/PacketHandler.scala b/src/main/scala/li/cil/oc/client/PacketHandler.scala
index 72c02299a..44ac676af 100644
--- a/src/main/scala/li/cil/oc/client/PacketHandler.scala
+++ b/src/main/scala/li/cil/oc/client/PacketHandler.scala
@@ -7,6 +7,7 @@ import li.cil.oc.Settings
import li.cil.oc.api.component
import li.cil.oc.api.event.FileSystemAccessEvent
import li.cil.oc.client.renderer.PetRenderer
+import li.cil.oc.common.Loot
import li.cil.oc.common.PacketType
import li.cil.oc.common.container
import li.cil.oc.common.tileentity._
@@ -56,6 +57,7 @@ object PacketHandler extends CommonPacketHandler {
case PacketType.HologramScale => onHologramScale(p)
case PacketType.HologramTranslation => onHologramPositionOffsetY(p)
case PacketType.HologramValues => onHologramValues(p)
+ case PacketType.LootDisk => onLootDisk(p)
case PacketType.ParticleEffect => onParticleEffect(p)
case PacketType.PetVisibility => onPetVisibility(p)
case PacketType.PowerState => onPowerState(p)
@@ -250,6 +252,13 @@ object PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet.
}
+ def onLootDisk(p: PacketParser) = {
+ val stack = p.readItemStack()
+ if (stack != null) {
+ Loot.disksForClient += stack
+ }
+ }
+
def onParticleEffect(p: PacketParser) = {
val dimension = p.readInt()
world(p.player, dimension) match {
diff --git a/src/main/scala/li/cil/oc/common/Achievement.scala b/src/main/scala/li/cil/oc/common/Achievement.scala
index 1fd7c6a93..d4fe9c3c7 100644
--- a/src/main/scala/li/cil/oc/common/Achievement.scala
+++ b/src/main/scala/li/cil/oc/common/Achievement.scala
@@ -163,7 +163,7 @@ object Achievement {
val OpenOS = newAchievement("openOS").
at(10, 9).
withParent(Floppy).
- whenCrafting(Items.createOpenOS()).
+ whenCrafting(Constants.ItemName.OpenOS).
add()
val Raid = newAchievement("raid").
at(8, 10).
diff --git a/src/main/scala/li/cil/oc/common/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala
index 253688948..32929fa49 100644
--- a/src/main/scala/li/cil/oc/common/EventHandler.scala
+++ b/src/main/scala/li/cil/oc/common/EventHandler.scala
@@ -134,6 +134,7 @@ object EventHandler {
player.addChatMessage(Localization.Chat.WarningSimpleComponent)
}
ServerPacketSender.sendPetVisibility(None, Some(player))
+ ServerPacketSender.sendLootDisks(player)
// Do update check in local games and for OPs.
if (!Mods.VersionChecker.isAvailable && (!MinecraftServer.getServer.isDedicatedServer || MinecraftServer.getServer.getConfigurationManager.canSendCommands(player.getGameProfile))) {
Future {
@@ -149,8 +150,9 @@ object EventHandler {
@SubscribeEvent
def clientLoggedIn(e: ClientConnectedToServerEvent) {
PetRenderer.isInitialized = false
- PetRenderer.hidden.clear()
- }
+ PetRenderer.hidden.clear()
+ Loot.disksForClient.clear()
+ }
@SubscribeEvent
def onBlockBreak(e: BlockEvent.BreakEvent): Unit = {
@@ -214,7 +216,7 @@ object EventHandler {
didRecraft = recraft(e, navigationUpgrade, stack => {
// Restore the map currently used in the upgrade.
Option(api.Driver.driverFor(e.crafting)) match {
- case Some(driver) => Option(ItemUtils.loadStack(driver.dataTag(stack).getCompoundTag(Settings.namespace + "map")))
+ case Some(driver) => Option(ItemStack.loadItemStackFromNBT(driver.dataTag(stack).getCompoundTag(Settings.namespace + "map")))
case _ => None
}
}) || didRecraft
diff --git a/src/main/scala/li/cil/oc/common/Loot.scala b/src/main/scala/li/cil/oc/common/Loot.scala
index 9e23d9a56..d3bb5b64d 100644
--- a/src/main/scala/li/cil/oc/common/Loot.scala
+++ b/src/main/scala/li/cil/oc/common/Loot.scala
@@ -2,13 +2,17 @@ package li.cil.oc.common
import java.io
import java.util.Random
+import java.util.concurrent.Callable
import li.cil.oc.Constants
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
+import li.cil.oc.api
+import li.cil.oc.api.fs.FileSystem
import li.cil.oc.common.init.Items
import li.cil.oc.util.Color
import net.minecraft.inventory.IInventory
+import net.minecraft.item.EnumDyeColor
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
@@ -16,6 +20,7 @@ import net.minecraft.util.WeightedRandomChestContent
import net.minecraftforge.common.ChestGenHooks
import net.minecraftforge.common.DimensionManager
import net.minecraftforge.event.world.WorldEvent
+import net.minecraftforge.fml.common.Loader
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import scala.collection.convert.WrapAsScala._
@@ -28,16 +33,45 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
ChestGenHooks.PYRAMID_JUNGLE_CHEST,
ChestGenHooks.STRONGHOLD_LIBRARY)
- val builtInDisks = mutable.Map.empty[String, (ItemStack, Int)]
+ val factories = mutable.Map.empty[String, Callable[FileSystem]]
+
+ val globalDisks = mutable.Map.empty[String, (ItemStack, Int)]
val worldDisks = mutable.Map.empty[String, (ItemStack, Int)]
- val disks = mutable.ArrayBuffer.empty[ItemStack]
+ val disksForSampling = mutable.ArrayBuffer.empty[ItemStack]
+
+ val disksForClient = mutable.ArrayBuffer.empty[ItemStack]
def randomDisk(rng: Random) =
- if (disks.length > 0) Some(disks(rng.nextInt(disks.length)))
+ if (disksForSampling.length > 0) Some(disksForSampling(rng.nextInt(disksForSampling.length)))
else None
+ def registerLootDisk(name: String, color: EnumDyeColor, factory: Callable[FileSystem]): ItemStack = {
+ val mod = Loader.instance.activeModContainer.getModId
+
+ OpenComputers.log.info(s"Registering loot disk '$name' from mod $mod.")
+
+ val modSpecificName = mod + ":" + name
+
+ val data = new NBTTagCompound()
+ data.setString(Settings.namespace + "fs.label", name)
+
+ val nbt = new NBTTagCompound()
+ nbt.setTag(Settings.namespace + "data", data)
+
+ // Store this top level, so it won't get wiped on save.
+ nbt.setString(Settings.namespace + "lootFactory", modSpecificName)
+ nbt.setInteger(Settings.namespace + "color", color.getDyeDamage)
+
+ val stack = Items.get(Constants.ItemName.Floppy).createItemStack(1)
+ stack.setTagCompound(nbt)
+
+ Loot.factories += modSpecificName -> factory
+
+ stack.copy()
+ }
+
def init() {
for (container <- containers) {
ChestGenHooks.addItem(container, Loot)
@@ -47,13 +81,13 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
val listStream = getClass.getResourceAsStream("/assets/" + Settings.resourceDomain + "/loot/loot.properties")
list.load(listStream)
listStream.close()
- parseLootDisks(list, builtInDisks)
+ parseLootDisks(list, globalDisks, external = false)
}
@SubscribeEvent
- def initForWorld(e: WorldEvent.Load) {
+ def initForWorld(e: WorldEvent.Load): Unit = if (!e.world.isRemote && e.world.provider.getDimensionId == 0) {
worldDisks.clear()
- disks.clear()
+ disksForSampling.clear()
if (!e.world.isRemote) {
val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + "loot/")
if (path.exists && path.isDirectory) {
@@ -64,7 +98,7 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
val list = new java.util.Properties()
list.load(listStream)
listStream.close()
- parseLootDisks(list, worldDisks)
+ parseLootDisks(list, worldDisks, external = true)
}
catch {
case t: Throwable => OpenComputers.log.warn("Failed opening loot descriptor file in saves folder.")
@@ -72,26 +106,26 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
}
}
}
- for ((name, entry) <- builtInDisks if !worldDisks.contains(name)) {
+ for ((name, entry) <- globalDisks if !worldDisks.contains(name)) {
worldDisks += name -> entry
}
for ((_, (stack, count)) <- worldDisks) {
for (i <- 0 until count) {
- disks += stack
+ disksForSampling += stack
}
}
}
- private def parseLootDisks(list: java.util.Properties, acc: mutable.Map[String, (ItemStack, Int)]) {
+ private def parseLootDisks(list: java.util.Properties, acc: mutable.Map[String, (ItemStack, Int)], external: Boolean) {
for (key <- list.stringPropertyNames) {
val value = list.getProperty(key)
try value.split(":") match {
case Array(name, count, color) =>
- acc += key -> ((createLootDisk(name, key, Some(color)), count.toInt))
+ acc += key -> ((createLootDisk(name, key, external, Color.byOreName.get(color)), count.toInt))
case Array(name, count) =>
- acc += key -> ((createLootDisk(name, key), count.toInt))
+ acc += key -> ((createLootDisk(name, key, external), count.toInt))
case _ =>
- acc += key -> ((createLootDisk(value, key), 1))
+ acc += key -> ((createLootDisk(value, key, external), 1))
}
catch {
case t: Throwable => OpenComputers.log.warn("Bad loot descriptor: " + value, t)
@@ -99,24 +133,17 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
}
}
- def createLootDisk(name: String, path: String, color: Option[String] = None) = {
- val data = new NBTTagCompound()
- data.setString(Settings.namespace + "fs.label", name)
-
- val tag = new NBTTagCompound()
- tag.setTag(Settings.namespace + "data", data)
- // Store this top level, so it won't get wiped on save.
- tag.setString(Settings.namespace + "lootPath", path)
- color match {
- case Some(oreDictName) =>
- tag.setInteger(Settings.namespace + "color", Color.dyes.indexOf(oreDictName))
- case _ =>
+ def createLootDisk(name: String, path: String, external: Boolean, color: Option[EnumDyeColor] = None) = {
+ val callable = if (external) new Callable[FileSystem] {
+ override def call(): FileSystem = api.FileSystem.fromSaveDirectory("loot/" + path, 0, false)
+ } else new Callable[FileSystem] {
+ override def call(): FileSystem = api.FileSystem.fromClass(OpenComputers.getClass, Settings.resourceDomain, "loot/" + path)
}
-
- val disk = Items.get(Constants.ItemName.Floppy).createItemStack(1)
- disk.setTagCompound(tag)
-
- disk
+ val stack = registerLootDisk(name, color.getOrElse(EnumDyeColor.SILVER), callable)
+ if (!external) {
+ Items.registerStack(stack, name)
+ }
+ stack
}
override def generateChestContent(random: Random, newInventory: IInventory) =
diff --git a/src/main/scala/li/cil/oc/common/PacketHandler.scala b/src/main/scala/li/cil/oc/common/PacketHandler.scala
index 0584dd893..6e8ba78c3 100644
--- a/src/main/scala/li/cil/oc/common/PacketHandler.scala
+++ b/src/main/scala/li/cil/oc/common/PacketHandler.scala
@@ -12,8 +12,8 @@ import li.cil.oc.api
import li.cil.oc.common.block.RobotAfterimage
import li.cil.oc.util.BlockPosition
import li.cil.oc.util.ExtendedWorld._
-import li.cil.oc.util.ItemUtils
import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.item.ItemStack
import net.minecraft.nbt.CompressedStreamTools
import net.minecraft.util.BlockPos
import net.minecraft.util.EnumFacing
@@ -109,7 +109,7 @@ abstract class PacketHandler {
def readItemStack() = {
val haveStack = readBoolean()
if (haveStack) {
- ItemUtils.loadStack(readNBT())
+ ItemStack.loadItemStackFromNBT(readNBT())
}
else null
}
diff --git a/src/main/scala/li/cil/oc/common/PacketType.scala b/src/main/scala/li/cil/oc/common/PacketType.scala
index 24bcd360e..94c6a744f 100644
--- a/src/main/scala/li/cil/oc/common/PacketType.scala
+++ b/src/main/scala/li/cil/oc/common/PacketType.scala
@@ -19,6 +19,7 @@ object PacketType extends Enumeration {
HologramScale,
HologramTranslation,
HologramValues,
+ LootDisk,
ParticleEffect,
PetVisibility, // Goes both ways.
PowerState,
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 713262c74..0aa0ef649 100644
--- a/src/main/scala/li/cil/oc/common/init/Items.scala
+++ b/src/main/scala/li/cil/oc/common/init/Items.scala
@@ -1,12 +1,14 @@
package li.cil.oc.common.init
import java.util
+import java.util.concurrent.Callable
import li.cil.oc.Constants
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.api.fs.FileSystem
import li.cil.oc.common
import li.cil.oc.common.Loot
import li.cil.oc.common.Tier
@@ -22,6 +24,7 @@ import li.cil.oc.common.recipe.Recipes
import li.cil.oc.integration.Mods
import net.minecraft.block.Block
import net.minecraft.creativetab.CreativeTabs
+import net.minecraft.item.EnumDyeColor
import net.minecraft.item.Item
import net.minecraft.item.ItemBlock
import net.minecraft.item.ItemStack
@@ -111,6 +114,24 @@ object Items extends ItemAPI {
instance
}
+ def registerStack(stack: ItemStack, id: String) = {
+ val immutableStack = stack.copy()
+ descriptors += id -> new ItemInfo {
+ override def name = id
+
+ override def block = null
+
+ override def createItemStack(size: Int): ItemStack = {
+ val copy = immutableStack.copy()
+ copy.stackSize = size
+ copy
+ }
+
+ override def item = immutableStack.getItem
+ }
+ stack
+ }
+
private def getBlockOrItem(stack: ItemStack): Any =
if (stack == null) null
else Delegator.subItem(stack).getOrElse(stack.getItem match {
@@ -120,24 +141,60 @@ object Items extends ItemAPI {
// ----------------------------------------------------------------------- //
- def createOpenOS(amount: Int = 1) = {
- Loot.builtInDisks.get("OpenOS").map(_._1.copy()).orNull
+ val registeredItems = mutable.ArrayBuffer.empty[ItemStack]
+
+ override def registerFloppy(name: String, color: EnumDyeColor, factory: Callable[FileSystem]): ItemStack = {
+ val stack = Loot.registerLootDisk(name, color, factory)
+
+ registeredItems += stack
+
+ stack.copy()
}
- def createLuaBios(amount: Int = 1) = {
- val data = new NBTTagCompound()
- val code = new Array[Byte](4 * 1024)
- val count = OpenComputers.getClass.getResourceAsStream(Settings.scriptPath + "bios.lua").read(code)
- data.setByteArray(Settings.namespace + "eeprom", code.take(count))
- data.setString(Settings.namespace + "label", "EEPROM (Lua BIOS)")
-
+ override def registerEEPROM(name: String, code: Array[Byte], data: Array[Byte], readonly: Boolean): ItemStack = {
val nbt = new NBTTagCompound()
- nbt.setTag(Settings.namespace + "data", data)
+ if (name != null) {
+ nbt.setString(Settings.namespace + "label", name.trim.take(16))
+ }
+ if (code != null) {
+ nbt.setByteArray(Settings.namespace + "eeprom", code.take(Settings.get.eepromSize))
+ }
+ if (data != null) {
+ nbt.setByteArray(Settings.namespace + "userdata", data.take(Settings.get.eepromDataSize))
+ }
+ nbt.setBoolean(Settings.namespace + "readonly", readonly)
- val stack = get(Constants.ItemName.EEPROM).createItemStack(amount)
- stack.setTagCompound(nbt)
+ val stackNbt = new NBTTagCompound()
+ stackNbt.setTag(Settings.namespace + "data", nbt)
- stack
+ val stack = get(Constants.ItemName.EEPROM).createItemStack(1)
+ stack.setTagCompound(stackNbt)
+
+ registeredItems += stack
+
+ stack.copy()
+ }
+
+ // ----------------------------------------------------------------------- //
+
+ // Nobody should use this anyway, since it's internal, but IIRC some people do, so let's be nice...
+ // TODO remove in OC 1.6
+ /**
+ * @deprecated use api.Items.get("openOS").createItemStack(amount) instead.
+ */
+ @Deprecated
+ def createOpenOS(amount: Int = 1) = {
+ get(Constants.ItemName.OpenOS).createItemStack(amount)
+ }
+
+ // Nobody should use this anyway, since it's internal, but IIRC some people do, so let's be nice...
+ // TODO remove in OC 1.6
+ /**
+ * @deprecated use api.Items.get("luaBios").createItemStack(amount) instead.
+ */
+ @Deprecated
+ def createLuaBios(amount: Int = 1) = {
+ get(Constants.ItemName.LuaBios).createItemStack(amount)
}
def createConfiguredDrone() = {
@@ -212,8 +269,8 @@ object Items extends ItemAPI {
get(Constants.ItemName.RAMTier6).createItemStack(1),
get(Constants.ItemName.RAMTier6).createItemStack(1),
- createLuaBios(),
- createOpenOS(),
+ get(Constants.ItemName.LuaBios).createItemStack(1),
+ get(Constants.ItemName.OpenOS).createItemStack(1),
get(Constants.ItemName.HDDTier3).createItemStack(1)
)
data.containers = Array(
@@ -246,10 +303,10 @@ object Items extends ItemAPI {
Option(get(Constants.ItemName.RAMTier6).createItemStack(1)),
Option(get(Constants.ItemName.RAMTier6).createItemStack(1)),
- Option(createLuaBios()),
+ Option(get(Constants.ItemName.LuaBios).createItemStack(1)),
Option(get(Constants.ItemName.HDDTier3).createItemStack(1))
).padTo(32, None)
- data.items(31) = Option(createOpenOS())
+ data.items(31) = Option(get(Constants.ItemName.OpenOS).createItemStack(1))
data.container = Option(get(Constants.BlockName.DiskDrive).createItemStack(1))
val stack = get(Constants.ItemName.Tablet).createItemStack(1)
@@ -401,14 +458,7 @@ object Items extends ItemAPI {
// Storage media of all kinds.
private def initStorage(): Unit = {
- val storage = newItem(new item.Delegator() {
- // Override to inject loot disks.
- override def getSubItems(item: Item, tab: CreativeTabs, list: java.util.List[_]) {
- super.getSubItems(item, tab, list)
- Items.add(list, createLuaBios())
- Loot.worldDisks.values.foreach(entry => Items.add(list, entry._1))
- }
- }, "storage")
+ val storage = newItem(new item.Delegator(), "storage")
Recipes.addSubItem(new item.EEPROM(storage), Constants.ItemName.EEPROM, "oc:eeprom")
Recipes.addSubItem(new item.FloppyDisk(storage), Constants.ItemName.Floppy, "oc:floppy")
@@ -416,7 +466,13 @@ object Items extends ItemAPI {
Recipes.addSubItem(new item.HardDiskDrive(storage, Tier.Two), Constants.ItemName.HDDTier2, "oc:hdd2")
Recipes.addSubItem(new item.HardDiskDrive(storage, Tier.Three), Constants.ItemName.HDDTier3, "oc:hdd3")
- Recipes.addRecipe(createLuaBios(), Constants.ItemName.LuaBios)
+ val luaBios = {
+ val code = new Array[Byte](4 * 1024)
+ val count = OpenComputers.getClass.getResourceAsStream(Settings.scriptPath + "bios.lua").read(code)
+ registerEEPROM("EEPROM (Lua BIOS)", code.take(count), null, readonly = false)
+ }
+ Recipes.addStack(luaBios, Constants.ItemName.LuaBios)
+
}
// Special purpose items that don't fit into any other category.
@@ -427,7 +483,7 @@ object Items extends ItemAPI {
Items.createConfiguredMicrocontroller(),
Items.createConfiguredRobot(),
Items.createConfiguredTablet()
- )
+ ) ++ Loot.disksForClient ++ registeredItems
override def getSubItems(item: Item, tab: CreativeTabs, list: util.List[_]): Unit = {
super.getSubItems(item, tab, list)
diff --git a/src/main/scala/li/cil/oc/common/inventory/Inventory.scala b/src/main/scala/li/cil/oc/common/inventory/Inventory.scala
index 1f62f27b8..b1c42f3a3 100644
--- a/src/main/scala/li/cil/oc/common/inventory/Inventory.scala
+++ b/src/main/scala/li/cil/oc/common/inventory/Inventory.scala
@@ -3,7 +3,6 @@ package li.cil.oc.common.inventory
import li.cil.oc.Localization
import li.cil.oc.Settings
import li.cil.oc.util.ExtendedNBT._
-import li.cil.oc.util.ItemUtils
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.IInventory
import net.minecraft.item.ItemStack
@@ -98,7 +97,7 @@ trait Inventory extends IInventory {
nbt.getTagList(Settings.namespace + "items", NBT.TAG_COMPOUND).foreach((slotNbt: NBTTagCompound) => {
val slot = slotNbt.getByte("slot")
if (slot >= 0 && slot < items.length) {
- updateItems(slot, ItemUtils.loadStack(slotNbt.getCompoundTag("item")))
+ updateItems(slot, ItemStack.loadItemStackFromNBT(slotNbt.getCompoundTag("item")))
}
})
}
diff --git a/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala b/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala
index bff8b9b74..9505eea54 100644
--- a/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala
+++ b/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala
@@ -1,7 +1,6 @@
package li.cil.oc.common.inventory
import li.cil.oc.Settings
-import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.nbt.NBTTagList
@@ -33,7 +32,7 @@ trait ItemStackInventory extends Inventory {
for (i <- 0 until (list.tagCount min items.length)) {
val tag = list.getCompoundTagAt(i)
if (!tag.hasNoTags) {
- updateItems(i, ItemUtils.loadStack(tag))
+ updateItems(i, ItemStack.loadItemStackFromNBT(tag))
}
}
}
diff --git a/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala b/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala
index 67303f58d..73f690633 100644
--- a/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala
+++ b/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala
@@ -5,7 +5,6 @@ import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.common.Tier
import li.cil.oc.util.ExtendedNBT._
-import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT
@@ -25,7 +24,7 @@ class MicrocontrollerData extends ItemData {
override def load(nbt: NBTTagCompound) {
tier = nbt.getByte(Settings.namespace + "tier")
components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND).
- toArray[NBTTagCompound].map(ItemUtils.loadStack).filter(_ != null)
+ toArray[NBTTagCompound].map(ItemStack.loadItemStackFromNBT).filter(_ != null)
storedEnergy = nbt.getInteger(Settings.namespace + "storedEnergy")
// Reserve slot for EEPROM if necessary, avoids having to resize the
diff --git a/src/main/scala/li/cil/oc/common/item/data/NavigationUpgradeData.scala b/src/main/scala/li/cil/oc/common/item/data/NavigationUpgradeData.scala
index 0173c41de..8ace83029 100644
--- a/src/main/scala/li/cil/oc/common/item/data/NavigationUpgradeData.scala
+++ b/src/main/scala/li/cil/oc/common/item/data/NavigationUpgradeData.scala
@@ -2,7 +2,6 @@ package li.cil.oc.common.item.data
import li.cil.oc.Settings
import li.cil.oc.util.ExtendedNBT._
-import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemMap
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
@@ -35,7 +34,7 @@ class NavigationUpgradeData extends ItemData {
override def load(nbt: NBTTagCompound) {
if (nbt.hasKey(Settings.namespace + "map")) {
- map = ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "map"))
+ map = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "map"))
}
}
diff --git a/src/main/scala/li/cil/oc/common/item/data/RaidData.scala b/src/main/scala/li/cil/oc/common/item/data/RaidData.scala
index ec222f4c8..e9a9290e5 100644
--- a/src/main/scala/li/cil/oc/common/item/data/RaidData.scala
+++ b/src/main/scala/li/cil/oc/common/item/data/RaidData.scala
@@ -4,7 +4,6 @@ import li.cil.oc.Constants
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.util.ExtendedNBT._
-import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT
@@ -23,7 +22,7 @@ class RaidData extends ItemData {
override def load(nbt: NBTTagCompound): Unit = {
disks = nbt.getTagList(Settings.namespace + "disks", NBT.TAG_COMPOUND).
- toArray[NBTTagCompound].map(ItemUtils.loadStack)
+ toArray[NBTTagCompound].map(ItemStack.loadItemStackFromNBT)
filesystem = nbt.getCompoundTag(Settings.namespace + "filesystem")
if (nbt.hasKey(Settings.namespace + "label")) {
label = Option(nbt.getString(Settings.namespace + "label"))
diff --git a/src/main/scala/li/cil/oc/common/item/data/RobotData.scala b/src/main/scala/li/cil/oc/common/item/data/RobotData.scala
index 1f7f9d7fd..ef587ac7e 100644
--- a/src/main/scala/li/cil/oc/common/item/data/RobotData.scala
+++ b/src/main/scala/li/cil/oc/common/item/data/RobotData.scala
@@ -8,7 +8,6 @@ import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.integration.opencomputers.DriverScreen
import li.cil.oc.util.ExtendedNBT._
-import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT
@@ -63,9 +62,9 @@ class RobotData extends ItemData {
robotEnergy = nbt.getInteger(Settings.namespace + "robotEnergy")
tier = nbt.getInteger(Settings.namespace + "tier")
components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND).
- toArray[NBTTagCompound].map(ItemUtils.loadStack)
+ toArray[NBTTagCompound].map(ItemStack.loadItemStackFromNBT)
containers = nbt.getTagList(Settings.namespace + "containers", NBT.TAG_COMPOUND).
- toArray[NBTTagCompound].map(ItemUtils.loadStack)
+ toArray[NBTTagCompound].map(ItemStack.loadItemStackFromNBT)
if (nbt.hasKey(Settings.namespace + "lightColor")) {
lightColor = nbt.getInteger(Settings.namespace + "lightColor")
}
diff --git a/src/main/scala/li/cil/oc/common/item/data/TabletData.scala b/src/main/scala/li/cil/oc/common/item/data/TabletData.scala
index 65b0faa4f..1f8629350 100644
--- a/src/main/scala/li/cil/oc/common/item/data/TabletData.scala
+++ b/src/main/scala/li/cil/oc/common/item/data/TabletData.scala
@@ -3,7 +3,6 @@ package li.cil.oc.common.item.data
import li.cil.oc.Settings
import li.cil.oc.common.Tier
import li.cil.oc.util.ExtendedNBT._
-import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT
@@ -25,7 +24,7 @@ class TabletData extends ItemData {
nbt.getTagList(Settings.namespace + "items", NBT.TAG_COMPOUND).foreach((slotNbt: NBTTagCompound) => {
val slot = slotNbt.getByte("slot")
if (slot >= 0 && slot < items.length) {
- items(slot) = Option(ItemUtils.loadStack(slotNbt.getCompoundTag("item")))
+ items(slot) = Option(ItemStack.loadItemStackFromNBT(slotNbt.getCompoundTag("item")))
}
})
isRunning = nbt.getBoolean(Settings.namespace + "isRunning")
@@ -33,7 +32,7 @@ class TabletData extends ItemData {
maxEnergy = nbt.getDouble(Settings.namespace + "maxEnergy")
tier = nbt.getInteger(Settings.namespace + "tier")
if (nbt.hasKey(Settings.namespace + "container")) {
- container = Option(ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "container")))
+ container = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "container")))
}
}
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 1b51a9d43..c3e68d05c 100644
--- a/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala
+++ b/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala
@@ -6,7 +6,6 @@ import li.cil.oc.Constants
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.detail.ItemInfo
-import li.cil.oc.common.init.Items
import li.cil.oc.common.item.data.DroneData
import li.cil.oc.common.item.data.MicrocontrollerData
import li.cil.oc.common.item.data.PrintData
@@ -28,7 +27,7 @@ import scala.util.control.Breaks._
object ExtendedRecipe {
private lazy val drone = api.Items.get(Constants.ItemName.Drone)
private lazy val eeprom = api.Items.get(Constants.ItemName.EEPROM)
- private lazy val luaBios = Items.createLuaBios()
+ private lazy val luaBios = api.Items.get(Constants.ItemName.LuaBios)
private lazy val mcu = api.Items.get(Constants.BlockName.Microcontroller)
private lazy val navigationUpgrade = api.Items.get(Constants.ItemName.NavigationUpgrade)
private lazy val linkedCard = api.Items.get(Constants.ItemName.LinkedCard)
@@ -159,7 +158,7 @@ object ExtendedRecipe {
// EEPROM copying.
if (api.Items.get(craftedStack) == eeprom &&
- !ItemStack.areItemStackTagsEqual(craftedStack, luaBios) &&
+ api.Items.get(craftedStack) != luaBios &&
recipe.isInstanceOf[ExtendedShapelessOreRecipe] &&
recipe.asInstanceOf[ExtendedShapelessOreRecipe].getInput != null &&
recipe.asInstanceOf[ExtendedShapelessOreRecipe].getInput.size == 2) breakable {
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 82a5fd70b..e2bf111de 100644
--- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala
+++ b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala
@@ -80,6 +80,13 @@ object Recipes {
delegate
}
+ def addStack(stack: ItemStack, name: String, oreDict: String*) = {
+ Items.registerStack(stack, name)
+ addRecipe(stack, name)
+ register(stack, oreDict: _*)
+ stack
+ }
+
def addRecipe(stack: ItemStack, name: String) {
list += stack -> name
}
@@ -161,7 +168,7 @@ object Recipes {
val lootRecipes = recipes.getConfigList("lootDisks")
for (recipe <- lootRecipes) {
val name = recipe.getString("name")
- Loot.builtInDisks.get(name) match {
+ Loot.globalDisks.get(name) match {
case Some((stack, _)) => addRecipe(stack, recipe, s"loot disk '$name'")
case _ =>
OpenComputers.log.warn(s"Failed adding recipe for loot disk '$name': No such global loot disk.")
diff --git a/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala b/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala
index 2046e2d7f..f28c3acb0 100644
--- a/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala
+++ b/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala
@@ -11,7 +11,6 @@ import li.cil.oc.api.network._
import li.cil.oc.common.template.AssemblerTemplates
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._
-import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing
@@ -127,11 +126,11 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits
override def readFromNBTForServer(nbt: NBTTagCompound) {
super.readFromNBTForServer(nbt)
if (nbt.hasKey(Settings.namespace + "output")) {
- output = Option(ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "output")))
+ output = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "output")))
}
else if (nbt.hasKey(Settings.namespace + "robot")) {
// Backwards compatibility.
- output = Option(ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "robot")))
+ output = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "robot")))
}
totalRequiredEnergy = nbt.getDouble(Settings.namespace + "total")
requiredEnergy = nbt.getDouble(Settings.namespace + "remaining")
diff --git a/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala b/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala
index e8ed3acc5..12835a3a5 100644
--- a/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala
+++ b/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala
@@ -127,7 +127,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
super.readFromNBTForServer(nbt)
queue.clear()
queue ++= nbt.getTagList(Settings.namespace + "queue", NBT.TAG_COMPOUND).
- map((tag: NBTTagCompound) => ItemUtils.loadStack(tag))
+ map((tag: NBTTagCompound) => ItemStack.loadItemStackFromNBT(tag))
buffer = nbt.getDouble(Settings.namespace + "buffer")
totalRequiredEnergy = nbt.getDouble(Settings.namespace + "total")
isActive = queue.nonEmpty
diff --git a/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala b/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala
index 556f567a5..e995b17e1 100644
--- a/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala
+++ b/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala
@@ -10,7 +10,6 @@ import li.cil.oc.common.Slot
import li.cil.oc.common.Sound
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._
-import li.cil.oc.util.ItemUtils
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
@@ -80,7 +79,7 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t
override def writeToNBTForClient(nbt: NBTTagCompound) {
super.writeToNBTForClient(nbt)
if (nbt.hasKey("disk")) {
- setInventorySlotContents(0, ItemUtils.loadStack(nbt.getCompoundTag("disk")))
+ setInventorySlotContents(0, ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("disk")))
}
}
}
diff --git a/src/main/scala/li/cil/oc/common/tileentity/Printer.scala b/src/main/scala/li/cil/oc/common/tileentity/Printer.scala
index 1e8b70d0d..2b7c5a577 100644
--- a/src/main/scala/li/cil/oc/common/tileentity/Printer.scala
+++ b/src/main/scala/li/cil/oc/common/tileentity/Printer.scala
@@ -11,7 +11,6 @@ import li.cil.oc.api.network._
import li.cil.oc.common.item.data.PrintData
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._
-import li.cil.oc.util.ItemUtils
import net.minecraft.inventory.ISidedInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
@@ -278,7 +277,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
isActive = nbt.getBoolean(Settings.namespace + "active")
limit = nbt.getInteger(Settings.namespace + "limit")
if (nbt.hasKey(Settings.namespace + "output")) {
- output = Option(ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "output")))
+ output = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "output")))
}
totalRequiredEnergy = nbt.getDouble(Settings.namespace + "total")
requiredEnergy = nbt.getDouble(Settings.namespace + "remaining")
diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala
index e1903ac4c..ebc84ea1f 100644
--- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala
+++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala
@@ -5,6 +5,7 @@ import li.cil.oc.Constants
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.driver.EnvironmentHost
+import li.cil.oc.common.Loot
import li.cil.oc.common.Slot
import li.cil.oc.common.item.Delegator
import li.cil.oc.common.item.FloppyDisk
@@ -43,17 +44,31 @@ object DriverFileSystem extends Item {
}
private def createEnvironment(stack: ItemStack, capacity: Int, host: EnvironmentHost, speed: Int) = if (DimensionManager.getWorld(0) != null) {
- // 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(dataTag(stack))
- val isFloppy = api.Items.get(stack) == api.Items.get(Constants.ItemName.Floppy)
- val fs = oc.api.FileSystem.fromSaveDirectory(address, capacity, Settings.get.bufferChanges)
- val environment = oc.api.FileSystem.asManagedEnvironment(fs, new ReadWriteItemLabel(stack), host, Settings.resourceDomain + ":" + (if (isFloppy) "floppy_access" else "hdd_access"), speed)
- if (environment != null && environment.node != null) {
- environment.node.asInstanceOf[oc.server.network.Node].address = address
+ if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "lootFactory")) {
+ // Loot disk, create file system using factory callback.
+ Loot.factories.get(stack.getTagCompound.getString(Settings.namespace + "lootFactory")) match {
+ case Some(factory) =>
+ val label =
+ if (dataTag(stack).hasKey(Settings.namespace + "fs.label"))
+ dataTag(stack).getString(Settings.namespace + "fs.label")
+ else null
+ api.FileSystem.asManagedEnvironment(factory.call(), label, host, Settings.resourceDomain + ":floppy_access")
+ case _ => null // Invalid loot disk.
+ }
+ }
+ else {
+ // 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(dataTag(stack))
+ val isFloppy = api.Items.get(stack) == api.Items.get(Constants.ItemName.Floppy)
+ val fs = oc.api.FileSystem.fromSaveDirectory(address, capacity, Settings.get.bufferChanges)
+ val environment = oc.api.FileSystem.asManagedEnvironment(fs, new ReadWriteItemLabel(stack), host, Settings.resourceDomain + ":" + (if (isFloppy) "floppy_access" else "hdd_access"), speed)
+ if (environment != null && environment.node != null) {
+ environment.node.asInstanceOf[oc.server.network.Node].address = address
+ }
+ environment
}
- environment
}
else null
diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverLootDisk.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverLootDisk.scala
index 16156961b..fa463b563 100644
--- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverLootDisk.scala
+++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverLootDisk.scala
@@ -11,6 +11,9 @@ import li.cil.oc.common.Slot
import net.minecraft.item.ItemStack
import net.minecraftforge.common.DimensionManager
+// This is deprecated and kept for compatibility with old saves.
+// As of OC 1.5.10, loot disks are generated using normal floppies, and using
+// a factory system that allows third-party mods to register loot disks.
object DriverLootDisk extends Item {
override def worksWith(stack: ItemStack) = isOneOf(stack,
api.Items.get(Constants.ItemName.Floppy)) &&
diff --git a/src/main/scala/li/cil/oc/server/PacketSender.scala b/src/main/scala/li/cil/oc/server/PacketSender.scala
index f0d5e61ef..f0d639768 100644
--- a/src/main/scala/li/cil/oc/server/PacketSender.scala
+++ b/src/main/scala/li/cil/oc/server/PacketSender.scala
@@ -215,6 +215,18 @@ object PacketSender {
pb.sendToPlayersNearTileEntity(t)
}
+ def sendLootDisks(p: EntityPlayerMP): Unit = {
+ // Sending as separate packets, because CompressedStreamTools hiccups otherwise...
+ val stacks = Loot.worldDisks.values.map(_._1)
+ for (stack <- stacks) {
+ val pb = new SimplePacketBuilder(PacketType.LootDisk)
+
+ pb.writeItemStack(stack)
+
+ pb.sendToPlayer(p)
+ }
+ }
+
def sendParticleEffect(position: BlockPosition, particleType: EnumParticleTypes, count: Int, velocity: Double, direction: Option[EnumFacing] = None): Unit = if (count > 0) {
val pb = new SimplePacketBuilder(PacketType.ParticleEffect)
diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala b/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala
index b7f2d9655..73a0f791c 100644
--- a/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala
+++ b/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala
@@ -12,7 +12,6 @@ import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._
import li.cil.oc.api.prefab
import li.cil.oc.util.ExtendedNBT._
-import li.cil.oc.util.ItemUtils
import net.minecraft.entity.item.EntityItem
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
@@ -149,7 +148,7 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr
super.load(nbt)
romGenerator.foreach(_.load(nbt.getCompoundTag("romGenerator")))
if (nbt.hasKey("inventory")) {
- inventory = Option(ItemUtils.loadStack(nbt.getCompoundTag("inventory")))
+ inventory = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("inventory")))
}
remainingTicks = nbt.getInteger("remainingTicks")
}
diff --git a/src/main/scala/li/cil/oc/util/ItemUtils.scala b/src/main/scala/li/cil/oc/util/ItemUtils.scala
index 0da7adf79..669967573 100644
--- a/src/main/scala/li/cil/oc/util/ItemUtils.scala
+++ b/src/main/scala/li/cil/oc/util/ItemUtils.scala
@@ -47,12 +47,6 @@ object ItemUtils {
def caseNameWithTierSuffix(name: String, tier: Int) = name + (if (tier == Tier.Four) "Creative" else (tier + 1).toString)
- def loadStack(nbt: NBTTagCompound) = ItemStack.loadItemStackFromNBT(nbt)
-
- def loadStack(data: Array[Byte]) = {
- ItemStack.loadItemStackFromNBT(loadTag(data))
- }
-
def loadTag(data: Array[Byte]) = {
val bais = new ByteArrayInputStream(data)
CompressedStreamTools.readCompressed(bais)