From 13e1b22101689e3f924ccf5340ff1eb31d8ec6cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Thu, 14 May 2015 20:45:19 +0200 Subject: [PATCH 1/2] Added API entry to allow mods to register their own loot disks and EEPROMs. Reworked loot disk logic a bit, using factory callbacks producing file systems now. --- src/main/java/li/cil/oc/api/API.java | 2 +- src/main/java/li/cil/oc/api/Items.java | 50 ++++++++ .../java/li/cil/oc/api/detail/ItemAPI.java | 47 ++++++++ .../assets/opencomputers/loot/loot.properties | 2 +- .../opencomputers/recipes/default.recipes | 1 - src/main/scala/li/cil/oc/Constants.scala | 1 + .../scala/li/cil/oc/common/Achievement.scala | 2 +- src/main/scala/li/cil/oc/common/Loot.scala | 86 +++++++++----- .../scala/li/cil/oc/common/init/Items.scala | 109 ++++++++++++++---- .../cil/oc/common/recipe/ExtendedRecipe.scala | 5 +- .../li/cil/oc/common/recipe/Recipes.scala | 9 +- .../opencomputers/DriverFileSystem.scala | 35 ++++-- .../opencomputers/DriverLootDisk.scala | 3 + 13 files changed, 279 insertions(+), 73 deletions(-) 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..7a0d5657e 100644 --- a/src/main/java/li/cil/oc/api/Items.java +++ b/src/main/java/li/cil/oc/api/Items.java @@ -3,6 +3,8 @@ package li.cil.oc.api; import li.cil.oc.api.detail.ItemInfo; import net.minecraft.item.ItemStack; +import java.util.concurrent.Callable; + /** * Access to item definitions for all blocks and items provided by * OpenComputers. @@ -44,6 +46,54 @@ 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 (so 0-15, + * with 0 being black, 1 red and so on). + * @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, int 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..0de2b2f3d 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,10 @@ package li.cil.oc.api.detail; +import li.cil.oc.api.FileSystem; 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 +29,48 @@ 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 (so 0-15, + * with 0 being black, 1 red and so on). + * @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, int 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 b5399f3e0..9166abbe5 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -364,7 +364,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/Constants.scala b/src/main/scala/li/cil/oc/Constants.scala index cb00dea32..0eaa9d9ff 100644 --- a/src/main/scala/li/cil/oc/Constants.scala +++ b/src/main/scala/li/cil/oc/Constants.scala @@ -113,6 +113,7 @@ object Constants { final val NavigationUpgrade = "navigationUpgrade" final val NetworkCard = "lanCard" final val NumPad = "numPad" + final val OpenOS = "openOS" final val PistonUpgrade = "pistonUpgrade" final val Present = "present" final val PrintedCircuitBoard = "printedCircuitBoard" 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/Loot.scala b/src/main/scala/li/cil/oc/common/Loot.scala index 641769c5d..0a3c3a049 100644 --- a/src/main/scala/li/cil/oc/common/Loot.scala +++ b/src/main/scala/li/cil/oc/common/Loot.scala @@ -2,11 +2,15 @@ package li.cil.oc.common import java.io import java.util.Random +import java.util.concurrent.Callable +import cpw.mods.fml.common.Loader import cpw.mods.fml.common.eventhandler.SubscribeEvent 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 @@ -28,11 +32,38 @@ 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] + + def registerLootDisk(name: String, color: Int, 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 max 0 min 15) + + val stack = Items.get(Constants.ItemName.Floppy).createItemStack(1) + stack.setTagCompound(nbt) + + Loot.factories += modSpecificName -> factory + + stack.copy() + } def init() { for (container <- containers) { @@ -43,13 +74,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 = { worldDisks.clear() - disks.clear() + disksForSampling.clear() val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + "loot/") if (path.exists && path.isDirectory) { val listFile = new io.File(path, "loot.properties") @@ -59,33 +90,33 @@ 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.") } } } - 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, Some(Color.dyes.indexOf(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) @@ -93,29 +124,22 @@ 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[Int] = 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.LootDisk).createItemStack(1) - disk.setTagCompound(tag) - - disk + val stack = registerLootDisk(name, color.getOrElse(8), callable) + if (!external) { + Items.registerStack(stack, name) + } + stack } override def generateChestContent(random: Random, newInventory: IInventory) = - if (disks.length > 0) - ChestGenHooks.generateStacks(random, disks(random.nextInt(disks.length)), + if (disksForSampling.length > 0) + ChestGenHooks.generateStacks(random, disksForSampling(random.nextInt(disksForSampling.length)), theMinimumChanceToGenerateItem, theMaximumChanceToGenerateItem) else Array.empty[ItemStack] } 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 4b30ae26d..9f346874d 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -1,11 +1,14 @@ package li.cil.oc.common.init +import java.util.concurrent.Callable + import cpw.mods.fml.common.registry.GameRegistry 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 @@ -103,6 +106,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 { @@ -112,24 +133,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: Int, 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() = { @@ -204,8 +261,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( @@ -238,10 +295,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) @@ -255,20 +312,19 @@ object Items extends ItemAPI { def init() { val multi = new item.Delegator() { - def configuredItems = Array( - createLuaBios(), + def additionalItems = Array( createConfiguredDrone(), createConfiguredMicrocontroller(), createConfiguredRobot(), createConfiguredTablet() - ) + ) ++ registeredItems override def getSubItems(item: Item, tab: CreativeTabs, list: java.util.List[_]) { // Workaround for MC's untyped lists... 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)) - configuredItems.foreach(add(list, _)) + additionalItems.foreach(add(list, _)) } } @@ -369,7 +425,7 @@ object Items extends ItemAPI { new item.FloppyDisk(multi) { showInItemList = false - override def createItemStack(amount: Int) = createOpenOS(amount) + override def createItemStack(amount: Int) = get(Constants.ItemName.OpenOS).createItemStack(1) override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = { if (player.isSneaking) get(Constants.ItemName.Floppy).createItemStack(1) @@ -414,7 +470,13 @@ object Items extends ItemAPI { // 1.4.2 val eeprom = new item.EEPROM() Recipes.addItem(eeprom, Constants.ItemName.EEPROM, "oc:eeprom") - 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) + Recipes.addSubItem(new item.MicrocontrollerCase(multi, Tier.One), Constants.ItemName.MicrocontrollerCaseTier1, "oc:microcontrollerCase1") // 1.4.3 @@ -452,6 +514,5 @@ object Items extends ItemAPI { // 1.5.8 Recipes.addSubItem(new item.UpgradeHover(multi, Tier.One), Constants.ItemName.HoverUpgradeTier1, "oc:hoverUpgrade1") Recipes.addSubItem(new item.UpgradeHover(multi, Tier.Two), Constants.ItemName.HoverUpgradeTier2, "oc:hoverUpgrade2") - } } 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 c2fc0266f..a459acd10 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 3f5c764f2..a52c321c5 100644 --- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala +++ b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala @@ -68,6 +68,13 @@ object Recipes { instance } + 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 } @@ -149,7 +156,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/integration/opencomputers/DriverFileSystem.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala index 824d04533..9d8b9b966 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 @@ -41,17 +42,31 @@ object DriverFileSystem extends Item { } private def createEnvironment(stack: ItemStack, capacity: Int, host: EnvironmentHost, speed: Int) = { - // We have a bit of a chicken-egg problem here, because we want to use the - // node's address as the folder name... so we generate the address here, - // if necessary. No one will know, right? Right!? - val address = addressFromTag(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 } private def addressFromTag(tag: NBTTagCompound) = 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 ef00c1138..fe1cf718a 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.LootDisk)) From 39cf701c0fa57fad2e87df0183a77f6a83d480e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Thu, 14 May 2015 22:00:32 +0200 Subject: [PATCH 2/2] Removed now useless indirection for item stack loading (was for upgrading blocks to new format many versions back). Synching loot disks defined on dedicated servers via save directory to clients so that they show in their creative tabs. Yep, this was broken since the day it was added. --- src/main/scala/li/cil/oc/client/PacketHandler.scala | 9 +++++++++ src/main/scala/li/cil/oc/common/EventHandler.scala | 4 +++- src/main/scala/li/cil/oc/common/Loot.scala | 4 +++- src/main/scala/li/cil/oc/common/PacketHandler.scala | 4 ++-- src/main/scala/li/cil/oc/common/PacketType.scala | 1 + src/main/scala/li/cil/oc/common/init/Items.scala | 3 +-- .../scala/li/cil/oc/common/inventory/Inventory.scala | 3 +-- .../cil/oc/common/inventory/ItemStackInventory.scala | 3 +-- .../oc/common/item/data/MicrocontrollerData.scala | 3 +-- .../oc/common/item/data/NavigationUpgradeData.scala | 3 +-- .../scala/li/cil/oc/common/item/data/RaidData.scala | 3 +-- .../scala/li/cil/oc/common/item/data/RobotData.scala | 5 ++--- .../li/cil/oc/common/item/data/TabletData.scala | 5 ++--- .../li/cil/oc/common/tileentity/Assembler.scala | 5 ++--- .../li/cil/oc/common/tileentity/Disassembler.scala | 2 +- .../li/cil/oc/common/tileentity/DiskDrive.scala | 3 +-- .../scala/li/cil/oc/common/tileentity/Printer.scala | 3 +-- src/main/scala/li/cil/oc/server/PacketSender.scala | 12 ++++++++++++ .../cil/oc/server/component/UpgradeGenerator.scala | 3 +-- src/main/scala/li/cil/oc/util/ItemUtils.scala | 3 --- 20 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/main/scala/li/cil/oc/client/PacketHandler.scala b/src/main/scala/li/cil/oc/client/PacketHandler.scala index e9867fbb8..ae7ff3d01 100644 --- a/src/main/scala/li/cil/oc/client/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/client/PacketHandler.scala @@ -13,6 +13,7 @@ import li.cil.oc.common.PacketType import li.cil.oc.common.container import li.cil.oc.common.tileentity._ import li.cil.oc.common.tileentity.traits._ +import li.cil.oc.common.Loot import li.cil.oc.common.{PacketHandler => CommonPacketHandler} import li.cil.oc.util.Audio import li.cil.oc.util.ExtendedWorld._ @@ -54,6 +55,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) @@ -253,6 +255,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/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala index 18d341d2b..0b9b95482 100644 --- a/src/main/scala/li/cil/oc/common/EventHandler.scala +++ b/src/main/scala/li/cil/oc/common/EventHandler.scala @@ -174,6 +174,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.func_152596_g(player.getGameProfile))) { Future { @@ -190,6 +191,7 @@ object EventHandler { def clientLoggedIn(e: ClientConnectedToServerEvent) { PetRenderer.isInitialized = false PetRenderer.hidden.clear() + Loot.disksForClient.clear() } @SubscribeEvent @@ -254,7 +256,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 0a3c3a049..c12b88a99 100644 --- a/src/main/scala/li/cil/oc/common/Loot.scala +++ b/src/main/scala/li/cil/oc/common/Loot.scala @@ -40,6 +40,8 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1, val disksForSampling = mutable.ArrayBuffer.empty[ItemStack] + val disksForClient = mutable.ArrayBuffer.empty[ItemStack] + def registerLootDisk(name: String, color: Int, factory: Callable[FileSystem]): ItemStack = { val mod = Loader.instance.activeModContainer.getModId @@ -78,7 +80,7 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1, } @SubscribeEvent - def initForWorld(e: WorldEvent.Load): Unit = { + def initForWorld(e: WorldEvent.Load): Unit = if (!e.world.isRemote && e.world.provider.dimensionId == 0) { worldDisks.clear() disksForSampling.clear() val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + "loot/") diff --git a/src/main/scala/li/cil/oc/common/PacketHandler.scala b/src/main/scala/li/cil/oc/common/PacketHandler.scala index 5ef7ef4d0..5bb0f0f4d 100644 --- a/src/main/scala/li/cil/oc/common/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/common/PacketHandler.scala @@ -10,8 +10,8 @@ import li.cil.oc.Constants import li.cil.oc.OpenComputers import li.cil.oc.api import li.cil.oc.common.block.RobotAfterimage -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.world.World import net.minecraftforge.common.util.ForgeDirection @@ -106,7 +106,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 05033930d..b6eb1c0d4 100644 --- a/src/main/scala/li/cil/oc/common/PacketType.scala +++ b/src/main/scala/li/cil/oc/common/PacketType.scala @@ -20,6 +20,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 9f346874d..e045caa00 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -317,13 +317,12 @@ object Items extends ItemAPI { createConfiguredMicrocontroller(), createConfiguredRobot(), createConfiguredTablet() - ) ++ registeredItems + ) ++ Loot.disksForClient ++ registeredItems override def getSubItems(item: Item, tab: CreativeTabs, list: java.util.List[_]) { // Workaround for MC's untyped lists... 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)) additionalItems.foreach(add(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 a7cb503f2..5ab26b5d3 100644 --- a/src/main/scala/li/cil/oc/common/inventory/Inventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/Inventory.scala @@ -2,7 +2,6 @@ package li.cil.oc.common.inventory import li.cil.oc.Settings import li.cil.oc.util.ExtendedNBT._ -import li.cil.oc.util.ItemUtils import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound @@ -86,7 +85,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 b79b1f5b8..66bb5e625 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/tileentity/Assembler.scala b/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala index 378bbf604..e8a4331ec 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala @@ -13,7 +13,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.minecraftforge.common.util.ForgeDirection @@ -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 881bfd285..69afe5996 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 a3858d22f..595b5a06a 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala @@ -12,7 +12,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 @@ -79,7 +78,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 d4cfb1fe8..43c2b7373 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Printer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Printer.scala @@ -13,7 +13,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/server/PacketSender.scala b/src/main/scala/li/cil/oc/server/PacketSender.scala index fa082595a..3347c0b2d 100644 --- a/src/main/scala/li/cil/oc/server/PacketSender.scala +++ b/src/main/scala/li/cil/oc/server/PacketSender.scala @@ -222,6 +222,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, name: String, count: Int, velocity: Double, direction: Option[ForgeDirection] = 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 d0d07ef82..3767e5da3 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 309e8480a..c6819563c 100644 --- a/src/main/scala/li/cil/oc/util/ItemUtils.scala +++ b/src/main/scala/li/cil/oc/util/ItemUtils.scala @@ -12,7 +12,6 @@ import net.minecraft.item.crafting.CraftingManager import net.minecraft.item.crafting.IRecipe import net.minecraft.item.crafting.ShapedRecipes import net.minecraft.item.crafting.ShapelessRecipes -import net.minecraft.nbt.NBTTagCompound import net.minecraftforge.oredict.ShapedOreRecipe import net.minecraftforge.oredict.ShapelessOreRecipe @@ -44,8 +43,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 getIngredients(stack: ItemStack): Array[ItemStack] = try { def getFilteredInputs(inputs: Iterable[ItemStack], outputSize: Double) = inputs.filter(input => input != null &&