Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8

Conflicts:
	src/main/scala/li/cil/oc/common/EventHandler.scala
	src/main/scala/li/cil/oc/common/Loot.scala
	src/main/scala/li/cil/oc/common/PacketHandler.scala
	src/main/scala/li/cil/oc/common/init/Items.scala
	src/main/scala/li/cil/oc/common/inventory/Inventory.scala
	src/main/scala/li/cil/oc/common/recipe/Recipes.scala
	src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala
	src/main/scala/li/cil/oc/server/PacketSender.scala
	src/main/scala/li/cil/oc/util/ItemUtils.scala
This commit is contained in:
Florian Nücke 2015-05-14 22:19:45 +02:00
commit f0fc58d99c
30 changed files with 322 additions and 112 deletions

View File

@ -12,7 +12,7 @@ import li.cil.oc.api.detail.*;
*/ */
public class API { public class API {
public static final String ID_OWNER = "OpenComputers|Core"; 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 DriverAPI driver = null;
public static FileSystemAPI fileSystem = null; public static FileSystemAPI fileSystem = null;

View File

@ -1,8 +1,11 @@
package li.cil.oc.api; package li.cil.oc.api;
import li.cil.oc.api.detail.ItemInfo; import li.cil.oc.api.detail.ItemInfo;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import java.util.concurrent.Callable;
/** /**
* Access to item definitions for all blocks and items provided by * Access to item definitions for all blocks and items provided by
* OpenComputers. * OpenComputers.
@ -44,6 +47,53 @@ public final class Items {
return null; return null;
} }
/**
* Register a single loot floppy disk.
* <p/>
* The disk will be listed in the creative tab of OpenComputers.
* <p/>
* 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.
* <p/>
* 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<li.cil.oc.api.fs.FileSystem> factory) {
if (API.items != null)
return API.items.registerFloppy(name, color, factory);
return null;
}
/**
* Register a single custom EEPROM.
* <p/>
* The EEPROM will be listed in the creative tab of OpenComputers.
* <p/>
* The EEPROM will be initialized with the specified code and data byte
* arrays. For script code (e.g. a Lua script) use <tt>String.getBytes("UTF-8")</tt>.
* You can omit any of the arguments by passing <tt>null</tt>.
*
* @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() { private Items() {

View File

@ -1,7 +1,11 @@
package li.cil.oc.api.detail; package li.cil.oc.api.detail;
import li.cil.oc.api.FileSystem;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import java.util.concurrent.Callable;
public interface ItemAPI { public interface ItemAPI {
/** /**
* Get a descriptor object for the block or item with the specified name. * 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. * if the stack is not a valid OpenComputers item or block.
*/ */
ItemInfo get(ItemStack stack); ItemInfo get(ItemStack stack);
/**
* Register a single loot floppy disk.
* <p/>
* The disk will be listed in the creative tab of OpenComputers.
* <p/>
* 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.
* <p/>
* To use some directory in your mod JAR as the directory provided by the
* loot disk, use {@link FileSystem#fromClass} in your callable.
* <p/>
* Call this in the init phase or later, <em>not</em> 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<li.cil.oc.api.fs.FileSystem> factory);
/**
* Register a single custom EEPROM.
* <p/>
* The EEPROM will be listed in the creative tab of OpenComputers.
* <p/>
* The EEPROM will be initialized with the specified code and data byte
* arrays. For script code (e.g. a Lua script) use <tt>String.getBytes("UTF-8")</tt>.
* You can omit any of the arguments by passing <tt>null</tt>.
* <p/>
* Call this in the init phase or later, <em>not</em> 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);
} }

View File

@ -10,7 +10,7 @@ MazeGen=maze:1:dyeOrange
Network=network:1:dyeLime Network=network:1:dyeLime
OpenIRC=irc:1:dyeLightBlue OpenIRC=irc:1:dyeLightBlue
OpenLoader=openloader:1:dyeMagenta OpenLoader=openloader:1:dyeMagenta
OpenOS=openos:0:dyeGreen OpenOS=openOS:0:dyeGreen
OPPM=oppm:0:dyeCyan OPPM=oppm:0:dyeCyan
# Higher chance to find the dig program, because it has the most immediate # 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 # use - OpenOS is craftable and IRC can be downloaded once an internet card

View File

@ -365,7 +365,6 @@ chameliumBlock {
["oc:chamelium", "oc:chamelium", "oc:chamelium"], ["oc:chamelium", "oc:chamelium", "oc:chamelium"],
["oc:chamelium", "oc:chamelium", "oc:chamelium"]] ["oc:chamelium", "oc:chamelium", "oc:chamelium"]]
} }
endstone { endstone {
input: [[enderPearl, "oc:chameliumBlock", enderPearl] input: [[enderPearl, "oc:chameliumBlock", enderPearl]
["oc:chameliumBlock", enderPearl, "oc:chameliumBlock"] ["oc:chameliumBlock", enderPearl, "oc:chameliumBlock"]

View File

@ -7,6 +7,7 @@ import li.cil.oc.Settings
import li.cil.oc.api.component import li.cil.oc.api.component
import li.cil.oc.api.event.FileSystemAccessEvent import li.cil.oc.api.event.FileSystemAccessEvent
import li.cil.oc.client.renderer.PetRenderer import li.cil.oc.client.renderer.PetRenderer
import li.cil.oc.common.Loot
import li.cil.oc.common.PacketType import li.cil.oc.common.PacketType
import li.cil.oc.common.container import li.cil.oc.common.container
import li.cil.oc.common.tileentity._ import li.cil.oc.common.tileentity._
@ -56,6 +57,7 @@ object PacketHandler extends CommonPacketHandler {
case PacketType.HologramScale => onHologramScale(p) case PacketType.HologramScale => onHologramScale(p)
case PacketType.HologramTranslation => onHologramPositionOffsetY(p) case PacketType.HologramTranslation => onHologramPositionOffsetY(p)
case PacketType.HologramValues => onHologramValues(p) case PacketType.HologramValues => onHologramValues(p)
case PacketType.LootDisk => onLootDisk(p)
case PacketType.ParticleEffect => onParticleEffect(p) case PacketType.ParticleEffect => onParticleEffect(p)
case PacketType.PetVisibility => onPetVisibility(p) case PacketType.PetVisibility => onPetVisibility(p)
case PacketType.PowerState => onPowerState(p) case PacketType.PowerState => onPowerState(p)
@ -250,6 +252,13 @@ object PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet. case _ => // Invalid packet.
} }
def onLootDisk(p: PacketParser) = {
val stack = p.readItemStack()
if (stack != null) {
Loot.disksForClient += stack
}
}
def onParticleEffect(p: PacketParser) = { def onParticleEffect(p: PacketParser) = {
val dimension = p.readInt() val dimension = p.readInt()
world(p.player, dimension) match { world(p.player, dimension) match {

View File

@ -163,7 +163,7 @@ object Achievement {
val OpenOS = newAchievement("openOS"). val OpenOS = newAchievement("openOS").
at(10, 9). at(10, 9).
withParent(Floppy). withParent(Floppy).
whenCrafting(Items.createOpenOS()). whenCrafting(Constants.ItemName.OpenOS).
add() add()
val Raid = newAchievement("raid"). val Raid = newAchievement("raid").
at(8, 10). at(8, 10).

View File

@ -134,6 +134,7 @@ object EventHandler {
player.addChatMessage(Localization.Chat.WarningSimpleComponent) player.addChatMessage(Localization.Chat.WarningSimpleComponent)
} }
ServerPacketSender.sendPetVisibility(None, Some(player)) ServerPacketSender.sendPetVisibility(None, Some(player))
ServerPacketSender.sendLootDisks(player)
// Do update check in local games and for OPs. // Do update check in local games and for OPs.
if (!Mods.VersionChecker.isAvailable && (!MinecraftServer.getServer.isDedicatedServer || MinecraftServer.getServer.getConfigurationManager.canSendCommands(player.getGameProfile))) { if (!Mods.VersionChecker.isAvailable && (!MinecraftServer.getServer.isDedicatedServer || MinecraftServer.getServer.getConfigurationManager.canSendCommands(player.getGameProfile))) {
Future { Future {
@ -149,8 +150,9 @@ object EventHandler {
@SubscribeEvent @SubscribeEvent
def clientLoggedIn(e: ClientConnectedToServerEvent) { def clientLoggedIn(e: ClientConnectedToServerEvent) {
PetRenderer.isInitialized = false PetRenderer.isInitialized = false
PetRenderer.hidden.clear() PetRenderer.hidden.clear()
} Loot.disksForClient.clear()
}
@SubscribeEvent @SubscribeEvent
def onBlockBreak(e: BlockEvent.BreakEvent): Unit = { def onBlockBreak(e: BlockEvent.BreakEvent): Unit = {
@ -214,7 +216,7 @@ object EventHandler {
didRecraft = recraft(e, navigationUpgrade, stack => { didRecraft = recraft(e, navigationUpgrade, stack => {
// Restore the map currently used in the upgrade. // Restore the map currently used in the upgrade.
Option(api.Driver.driverFor(e.crafting)) match { 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 case _ => None
} }
}) || didRecraft }) || didRecraft

View File

@ -2,13 +2,17 @@ package li.cil.oc.common
import java.io import java.io
import java.util.Random import java.util.Random
import java.util.concurrent.Callable
import li.cil.oc.Constants import li.cil.oc.Constants
import li.cil.oc.OpenComputers import li.cil.oc.OpenComputers
import li.cil.oc.Settings 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.common.init.Items
import li.cil.oc.util.Color import li.cil.oc.util.Color
import net.minecraft.inventory.IInventory import net.minecraft.inventory.IInventory
import net.minecraft.item.EnumDyeColor
import net.minecraft.item.Item import net.minecraft.item.Item
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
@ -16,6 +20,7 @@ import net.minecraft.util.WeightedRandomChestContent
import net.minecraftforge.common.ChestGenHooks import net.minecraftforge.common.ChestGenHooks
import net.minecraftforge.common.DimensionManager import net.minecraftforge.common.DimensionManager
import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.event.world.WorldEvent
import net.minecraftforge.fml.common.Loader
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import scala.collection.convert.WrapAsScala._ import scala.collection.convert.WrapAsScala._
@ -28,16 +33,45 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
ChestGenHooks.PYRAMID_JUNGLE_CHEST, ChestGenHooks.PYRAMID_JUNGLE_CHEST,
ChestGenHooks.STRONGHOLD_LIBRARY) 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 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) = 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 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() { def init() {
for (container <- containers) { for (container <- containers) {
ChestGenHooks.addItem(container, Loot) 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") val listStream = getClass.getResourceAsStream("/assets/" + Settings.resourceDomain + "/loot/loot.properties")
list.load(listStream) list.load(listStream)
listStream.close() listStream.close()
parseLootDisks(list, builtInDisks) parseLootDisks(list, globalDisks, external = false)
} }
@SubscribeEvent @SubscribeEvent
def initForWorld(e: WorldEvent.Load) { def initForWorld(e: WorldEvent.Load): Unit = if (!e.world.isRemote && e.world.provider.getDimensionId == 0) {
worldDisks.clear() worldDisks.clear()
disks.clear() disksForSampling.clear()
if (!e.world.isRemote) { if (!e.world.isRemote) {
val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + "loot/") val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + "loot/")
if (path.exists && path.isDirectory) { 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() val list = new java.util.Properties()
list.load(listStream) list.load(listStream)
listStream.close() listStream.close()
parseLootDisks(list, worldDisks) parseLootDisks(list, worldDisks, external = true)
} }
catch { catch {
case t: Throwable => OpenComputers.log.warn("Failed opening loot descriptor file in saves folder.") 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 worldDisks += name -> entry
} }
for ((_, (stack, count)) <- worldDisks) { for ((_, (stack, count)) <- worldDisks) {
for (i <- 0 until count) { 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) { for (key <- list.stringPropertyNames) {
val value = list.getProperty(key) val value = list.getProperty(key)
try value.split(":") match { try value.split(":") match {
case Array(name, count, color) => 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) => case Array(name, count) =>
acc += key -> ((createLootDisk(name, key), count.toInt)) acc += key -> ((createLootDisk(name, key, external), count.toInt))
case _ => case _ =>
acc += key -> ((createLootDisk(value, key), 1)) acc += key -> ((createLootDisk(value, key, external), 1))
} }
catch { catch {
case t: Throwable => OpenComputers.log.warn("Bad loot descriptor: " + value, t) 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) = { def createLootDisk(name: String, path: String, external: Boolean, color: Option[EnumDyeColor] = None) = {
val data = new NBTTagCompound() val callable = if (external) new Callable[FileSystem] {
data.setString(Settings.namespace + "fs.label", name) override def call(): FileSystem = api.FileSystem.fromSaveDirectory("loot/" + path, 0, false)
} else new Callable[FileSystem] {
val tag = new NBTTagCompound() override def call(): FileSystem = api.FileSystem.fromClass(OpenComputers.getClass, Settings.resourceDomain, "loot/" + path)
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 _ =>
} }
val stack = registerLootDisk(name, color.getOrElse(EnumDyeColor.SILVER), callable)
val disk = Items.get(Constants.ItemName.Floppy).createItemStack(1) if (!external) {
disk.setTagCompound(tag) Items.registerStack(stack, name)
}
disk stack
} }
override def generateChestContent(random: Random, newInventory: IInventory) = override def generateChestContent(random: Random, newInventory: IInventory) =

View File

@ -12,8 +12,8 @@ import li.cil.oc.api
import li.cil.oc.common.block.RobotAfterimage import li.cil.oc.common.block.RobotAfterimage
import li.cil.oc.util.BlockPosition import li.cil.oc.util.BlockPosition
import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.ExtendedWorld._
import li.cil.oc.util.ItemUtils
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.CompressedStreamTools import net.minecraft.nbt.CompressedStreamTools
import net.minecraft.util.BlockPos import net.minecraft.util.BlockPos
import net.minecraft.util.EnumFacing import net.minecraft.util.EnumFacing
@ -109,7 +109,7 @@ abstract class PacketHandler {
def readItemStack() = { def readItemStack() = {
val haveStack = readBoolean() val haveStack = readBoolean()
if (haveStack) { if (haveStack) {
ItemUtils.loadStack(readNBT()) ItemStack.loadItemStackFromNBT(readNBT())
} }
else null else null
} }

View File

@ -19,6 +19,7 @@ object PacketType extends Enumeration {
HologramScale, HologramScale,
HologramTranslation, HologramTranslation,
HologramValues, HologramValues,
LootDisk,
ParticleEffect, ParticleEffect,
PetVisibility, // Goes both ways. PetVisibility, // Goes both ways.
PowerState, PowerState,

View File

@ -1,12 +1,14 @@
package li.cil.oc.common.init package li.cil.oc.common.init
import java.util import java.util
import java.util.concurrent.Callable
import li.cil.oc.Constants import li.cil.oc.Constants
import li.cil.oc.OpenComputers import li.cil.oc.OpenComputers
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.api.detail.ItemAPI import li.cil.oc.api.detail.ItemAPI
import li.cil.oc.api.detail.ItemInfo import li.cil.oc.api.detail.ItemInfo
import li.cil.oc.api.fs.FileSystem
import li.cil.oc.common import li.cil.oc.common
import li.cil.oc.common.Loot import li.cil.oc.common.Loot
import li.cil.oc.common.Tier import li.cil.oc.common.Tier
@ -22,6 +24,7 @@ import li.cil.oc.common.recipe.Recipes
import li.cil.oc.integration.Mods import li.cil.oc.integration.Mods
import net.minecraft.block.Block import net.minecraft.block.Block
import net.minecraft.creativetab.CreativeTabs import net.minecraft.creativetab.CreativeTabs
import net.minecraft.item.EnumDyeColor
import net.minecraft.item.Item import net.minecraft.item.Item
import net.minecraft.item.ItemBlock import net.minecraft.item.ItemBlock
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
@ -111,6 +114,24 @@ object Items extends ItemAPI {
instance 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 = private def getBlockOrItem(stack: ItemStack): Any =
if (stack == null) null if (stack == null) null
else Delegator.subItem(stack).getOrElse(stack.getItem match { else Delegator.subItem(stack).getOrElse(stack.getItem match {
@ -120,24 +141,60 @@ object Items extends ItemAPI {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
def createOpenOS(amount: Int = 1) = { val registeredItems = mutable.ArrayBuffer.empty[ItemStack]
Loot.builtInDisks.get("OpenOS").map(_._1.copy()).orNull
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) = { override def registerEEPROM(name: String, code: Array[Byte], data: Array[Byte], readonly: Boolean): ItemStack = {
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)")
val nbt = new NBTTagCompound() 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) val stackNbt = new NBTTagCompound()
stack.setTagCompound(nbt) 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 <tt>api.Items.get("openOS").createItemStack(amount)</tt> 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 <tt>api.Items.get("luaBios").createItemStack(amount)</tt> instead.
*/
@Deprecated
def createLuaBios(amount: Int = 1) = {
get(Constants.ItemName.LuaBios).createItemStack(amount)
} }
def createConfiguredDrone() = { def createConfiguredDrone() = {
@ -212,8 +269,8 @@ object Items extends ItemAPI {
get(Constants.ItemName.RAMTier6).createItemStack(1), get(Constants.ItemName.RAMTier6).createItemStack(1),
get(Constants.ItemName.RAMTier6).createItemStack(1), get(Constants.ItemName.RAMTier6).createItemStack(1),
createLuaBios(), get(Constants.ItemName.LuaBios).createItemStack(1),
createOpenOS(), get(Constants.ItemName.OpenOS).createItemStack(1),
get(Constants.ItemName.HDDTier3).createItemStack(1) get(Constants.ItemName.HDDTier3).createItemStack(1)
) )
data.containers = Array( 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(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)) Option(get(Constants.ItemName.HDDTier3).createItemStack(1))
).padTo(32, None) ).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)) data.container = Option(get(Constants.BlockName.DiskDrive).createItemStack(1))
val stack = get(Constants.ItemName.Tablet).createItemStack(1) val stack = get(Constants.ItemName.Tablet).createItemStack(1)
@ -401,14 +458,7 @@ object Items extends ItemAPI {
// Storage media of all kinds. // Storage media of all kinds.
private def initStorage(): Unit = { private def initStorage(): Unit = {
val storage = newItem(new item.Delegator() { val storage = newItem(new item.Delegator(), "storage")
// 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")
Recipes.addSubItem(new item.EEPROM(storage), Constants.ItemName.EEPROM, "oc:eeprom") Recipes.addSubItem(new item.EEPROM(storage), Constants.ItemName.EEPROM, "oc:eeprom")
Recipes.addSubItem(new item.FloppyDisk(storage), Constants.ItemName.Floppy, "oc:floppy") 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.Two), Constants.ItemName.HDDTier2, "oc:hdd2")
Recipes.addSubItem(new item.HardDiskDrive(storage, Tier.Three), Constants.ItemName.HDDTier3, "oc:hdd3") 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. // Special purpose items that don't fit into any other category.
@ -427,7 +483,7 @@ object Items extends ItemAPI {
Items.createConfiguredMicrocontroller(), Items.createConfiguredMicrocontroller(),
Items.createConfiguredRobot(), Items.createConfiguredRobot(),
Items.createConfiguredTablet() Items.createConfiguredTablet()
) ) ++ Loot.disksForClient ++ registeredItems
override def getSubItems(item: Item, tab: CreativeTabs, list: util.List[_]): Unit = { override def getSubItems(item: Item, tab: CreativeTabs, list: util.List[_]): Unit = {
super.getSubItems(item, tab, list) super.getSubItems(item, tab, list)

View File

@ -3,7 +3,6 @@ package li.cil.oc.common.inventory
import li.cil.oc.Localization import li.cil.oc.Localization
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.IInventory import net.minecraft.inventory.IInventory
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
@ -98,7 +97,7 @@ trait Inventory extends IInventory {
nbt.getTagList(Settings.namespace + "items", NBT.TAG_COMPOUND).foreach((slotNbt: NBTTagCompound) => { nbt.getTagList(Settings.namespace + "items", NBT.TAG_COMPOUND).foreach((slotNbt: NBTTagCompound) => {
val slot = slotNbt.getByte("slot") val slot = slotNbt.getByte("slot")
if (slot >= 0 && slot < items.length) { if (slot >= 0 && slot < items.length) {
updateItems(slot, ItemUtils.loadStack(slotNbt.getCompoundTag("item"))) updateItems(slot, ItemStack.loadItemStackFromNBT(slotNbt.getCompoundTag("item")))
} }
}) })
} }

View File

@ -1,7 +1,6 @@
package li.cil.oc.common.inventory package li.cil.oc.common.inventory
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraft.nbt.NBTTagList import net.minecraft.nbt.NBTTagList
@ -33,7 +32,7 @@ trait ItemStackInventory extends Inventory {
for (i <- 0 until (list.tagCount min items.length)) { for (i <- 0 until (list.tagCount min items.length)) {
val tag = list.getCompoundTagAt(i) val tag = list.getCompoundTagAt(i)
if (!tag.hasNoTags) { if (!tag.hasNoTags) {
updateItems(i, ItemUtils.loadStack(tag)) updateItems(i, ItemStack.loadItemStackFromNBT(tag))
} }
} }
} }

View File

@ -5,7 +5,6 @@ import li.cil.oc.Settings
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.common.Tier import li.cil.oc.common.Tier
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT import net.minecraftforge.common.util.Constants.NBT
@ -25,7 +24,7 @@ class MicrocontrollerData extends ItemData {
override def load(nbt: NBTTagCompound) { override def load(nbt: NBTTagCompound) {
tier = nbt.getByte(Settings.namespace + "tier") tier = nbt.getByte(Settings.namespace + "tier")
components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND). 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") storedEnergy = nbt.getInteger(Settings.namespace + "storedEnergy")
// Reserve slot for EEPROM if necessary, avoids having to resize the // Reserve slot for EEPROM if necessary, avoids having to resize the

View File

@ -2,7 +2,6 @@ package li.cil.oc.common.item.data
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemMap import net.minecraft.item.ItemMap
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
@ -35,7 +34,7 @@ class NavigationUpgradeData extends ItemData {
override def load(nbt: NBTTagCompound) { override def load(nbt: NBTTagCompound) {
if (nbt.hasKey(Settings.namespace + "map")) { if (nbt.hasKey(Settings.namespace + "map")) {
map = ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "map")) map = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "map"))
} }
} }

View File

@ -4,7 +4,6 @@ import li.cil.oc.Constants
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT import net.minecraftforge.common.util.Constants.NBT
@ -23,7 +22,7 @@ class RaidData extends ItemData {
override def load(nbt: NBTTagCompound): Unit = { override def load(nbt: NBTTagCompound): Unit = {
disks = nbt.getTagList(Settings.namespace + "disks", NBT.TAG_COMPOUND). 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") filesystem = nbt.getCompoundTag(Settings.namespace + "filesystem")
if (nbt.hasKey(Settings.namespace + "label")) { if (nbt.hasKey(Settings.namespace + "label")) {
label = Option(nbt.getString(Settings.namespace + "label")) label = Option(nbt.getString(Settings.namespace + "label"))

View File

@ -8,7 +8,6 @@ import li.cil.oc.Settings
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.integration.opencomputers.DriverScreen import li.cil.oc.integration.opencomputers.DriverScreen
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT import net.minecraftforge.common.util.Constants.NBT
@ -63,9 +62,9 @@ class RobotData extends ItemData {
robotEnergy = nbt.getInteger(Settings.namespace + "robotEnergy") robotEnergy = nbt.getInteger(Settings.namespace + "robotEnergy")
tier = nbt.getInteger(Settings.namespace + "tier") tier = nbt.getInteger(Settings.namespace + "tier")
components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND). 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). 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")) { if (nbt.hasKey(Settings.namespace + "lightColor")) {
lightColor = nbt.getInteger(Settings.namespace + "lightColor") lightColor = nbt.getInteger(Settings.namespace + "lightColor")
} }

View File

@ -3,7 +3,6 @@ package li.cil.oc.common.item.data
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.common.Tier import li.cil.oc.common.Tier
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.Constants.NBT 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) => { nbt.getTagList(Settings.namespace + "items", NBT.TAG_COMPOUND).foreach((slotNbt: NBTTagCompound) => {
val slot = slotNbt.getByte("slot") val slot = slotNbt.getByte("slot")
if (slot >= 0 && slot < items.length) { 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") isRunning = nbt.getBoolean(Settings.namespace + "isRunning")
@ -33,7 +32,7 @@ class TabletData extends ItemData {
maxEnergy = nbt.getDouble(Settings.namespace + "maxEnergy") maxEnergy = nbt.getDouble(Settings.namespace + "maxEnergy")
tier = nbt.getInteger(Settings.namespace + "tier") tier = nbt.getInteger(Settings.namespace + "tier")
if (nbt.hasKey(Settings.namespace + "container")) { if (nbt.hasKey(Settings.namespace + "container")) {
container = Option(ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "container"))) container = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "container")))
} }
} }

View File

@ -6,7 +6,6 @@ import li.cil.oc.Constants
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.api.detail.ItemInfo 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.DroneData
import li.cil.oc.common.item.data.MicrocontrollerData import li.cil.oc.common.item.data.MicrocontrollerData
import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.item.data.PrintData
@ -28,7 +27,7 @@ import scala.util.control.Breaks._
object ExtendedRecipe { object ExtendedRecipe {
private lazy val drone = api.Items.get(Constants.ItemName.Drone) private lazy val drone = api.Items.get(Constants.ItemName.Drone)
private lazy val eeprom = api.Items.get(Constants.ItemName.EEPROM) 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 mcu = api.Items.get(Constants.BlockName.Microcontroller)
private lazy val navigationUpgrade = api.Items.get(Constants.ItemName.NavigationUpgrade) private lazy val navigationUpgrade = api.Items.get(Constants.ItemName.NavigationUpgrade)
private lazy val linkedCard = api.Items.get(Constants.ItemName.LinkedCard) private lazy val linkedCard = api.Items.get(Constants.ItemName.LinkedCard)
@ -159,7 +158,7 @@ object ExtendedRecipe {
// EEPROM copying. // EEPROM copying.
if (api.Items.get(craftedStack) == eeprom && if (api.Items.get(craftedStack) == eeprom &&
!ItemStack.areItemStackTagsEqual(craftedStack, luaBios) && api.Items.get(craftedStack) != luaBios &&
recipe.isInstanceOf[ExtendedShapelessOreRecipe] && recipe.isInstanceOf[ExtendedShapelessOreRecipe] &&
recipe.asInstanceOf[ExtendedShapelessOreRecipe].getInput != null && recipe.asInstanceOf[ExtendedShapelessOreRecipe].getInput != null &&
recipe.asInstanceOf[ExtendedShapelessOreRecipe].getInput.size == 2) breakable { recipe.asInstanceOf[ExtendedShapelessOreRecipe].getInput.size == 2) breakable {

View File

@ -80,6 +80,13 @@ object Recipes {
delegate 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) { def addRecipe(stack: ItemStack, name: String) {
list += stack -> name list += stack -> name
} }
@ -161,7 +168,7 @@ object Recipes {
val lootRecipes = recipes.getConfigList("lootDisks") val lootRecipes = recipes.getConfigList("lootDisks")
for (recipe <- lootRecipes) { for (recipe <- lootRecipes) {
val name = recipe.getString("name") 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 Some((stack, _)) => addRecipe(stack, recipe, s"loot disk '$name'")
case _ => case _ =>
OpenComputers.log.warn(s"Failed adding recipe for loot disk '$name': No such global loot disk.") OpenComputers.log.warn(s"Failed adding recipe for loot disk '$name': No such global loot disk.")

View File

@ -11,7 +11,6 @@ import li.cil.oc.api.network._
import li.cil.oc.common.template.AssemblerTemplates import li.cil.oc.common.template.AssemblerTemplates
import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing import net.minecraft.util.EnumFacing
@ -127,11 +126,11 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits
override def readFromNBTForServer(nbt: NBTTagCompound) { override def readFromNBTForServer(nbt: NBTTagCompound) {
super.readFromNBTForServer(nbt) super.readFromNBTForServer(nbt)
if (nbt.hasKey(Settings.namespace + "output")) { 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")) { else if (nbt.hasKey(Settings.namespace + "robot")) {
// Backwards compatibility. // 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") totalRequiredEnergy = nbt.getDouble(Settings.namespace + "total")
requiredEnergy = nbt.getDouble(Settings.namespace + "remaining") requiredEnergy = nbt.getDouble(Settings.namespace + "remaining")

View File

@ -127,7 +127,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
super.readFromNBTForServer(nbt) super.readFromNBTForServer(nbt)
queue.clear() queue.clear()
queue ++= nbt.getTagList(Settings.namespace + "queue", NBT.TAG_COMPOUND). 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") buffer = nbt.getDouble(Settings.namespace + "buffer")
totalRequiredEnergy = nbt.getDouble(Settings.namespace + "total") totalRequiredEnergy = nbt.getDouble(Settings.namespace + "total")
isActive = queue.nonEmpty isActive = queue.nonEmpty

View File

@ -10,7 +10,6 @@ import li.cil.oc.common.Slot
import li.cil.oc.common.Sound import li.cil.oc.common.Sound
import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
@ -80,7 +79,7 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t
override def writeToNBTForClient(nbt: NBTTagCompound) { override def writeToNBTForClient(nbt: NBTTagCompound) {
super.writeToNBTForClient(nbt) super.writeToNBTForClient(nbt)
if (nbt.hasKey("disk")) { if (nbt.hasKey("disk")) {
setInventorySlotContents(0, ItemUtils.loadStack(nbt.getCompoundTag("disk"))) setInventorySlotContents(0, ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("disk")))
} }
} }
} }

View File

@ -11,7 +11,6 @@ import li.cil.oc.api.network._
import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.item.data.PrintData
import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.inventory.ISidedInventory import net.minecraft.inventory.ISidedInventory
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound 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") isActive = nbt.getBoolean(Settings.namespace + "active")
limit = nbt.getInteger(Settings.namespace + "limit") limit = nbt.getInteger(Settings.namespace + "limit")
if (nbt.hasKey(Settings.namespace + "output")) { 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") totalRequiredEnergy = nbt.getDouble(Settings.namespace + "total")
requiredEnergy = nbt.getDouble(Settings.namespace + "remaining") requiredEnergy = nbt.getDouble(Settings.namespace + "remaining")

View File

@ -5,6 +5,7 @@ import li.cil.oc.Constants
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.api.driver.EnvironmentHost import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.common.Loot
import li.cil.oc.common.Slot import li.cil.oc.common.Slot
import li.cil.oc.common.item.Delegator import li.cil.oc.common.item.Delegator
import li.cil.oc.common.item.FloppyDisk 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) { 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 if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "lootFactory")) {
// node's address as the folder name... so we generate the address here, // Loot disk, create file system using factory callback.
// if necessary. No one will know, right? Right!? Loot.factories.get(stack.getTagCompound.getString(Settings.namespace + "lootFactory")) match {
val address = addressFromTag(dataTag(stack)) case Some(factory) =>
val isFloppy = api.Items.get(stack) == api.Items.get(Constants.ItemName.Floppy) val label =
val fs = oc.api.FileSystem.fromSaveDirectory(address, capacity, Settings.get.bufferChanges) if (dataTag(stack).hasKey(Settings.namespace + "fs.label"))
val environment = oc.api.FileSystem.asManagedEnvironment(fs, new ReadWriteItemLabel(stack), host, Settings.resourceDomain + ":" + (if (isFloppy) "floppy_access" else "hdd_access"), speed) dataTag(stack).getString(Settings.namespace + "fs.label")
if (environment != null && environment.node != null) { else null
environment.node.asInstanceOf[oc.server.network.Node].address = address 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 else null

View File

@ -11,6 +11,9 @@ import li.cil.oc.common.Slot
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraftforge.common.DimensionManager 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 { object DriverLootDisk extends Item {
override def worksWith(stack: ItemStack) = isOneOf(stack, override def worksWith(stack: ItemStack) = isOneOf(stack,
api.Items.get(Constants.ItemName.Floppy)) && api.Items.get(Constants.ItemName.Floppy)) &&

View File

@ -215,6 +215,18 @@ object PacketSender {
pb.sendToPlayersNearTileEntity(t) 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) { def sendParticleEffect(position: BlockPosition, particleType: EnumParticleTypes, count: Int, velocity: Double, direction: Option[EnumFacing] = None): Unit = if (count > 0) {
val pb = new SimplePacketBuilder(PacketType.ParticleEffect) val pb = new SimplePacketBuilder(PacketType.ParticleEffect)

View File

@ -12,7 +12,6 @@ import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._ import li.cil.oc.api.network._
import li.cil.oc.api.prefab import li.cil.oc.api.prefab
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.entity.item.EntityItem import net.minecraft.entity.item.EntityItem
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
@ -149,7 +148,7 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr
super.load(nbt) super.load(nbt)
romGenerator.foreach(_.load(nbt.getCompoundTag("romGenerator"))) romGenerator.foreach(_.load(nbt.getCompoundTag("romGenerator")))
if (nbt.hasKey("inventory")) { if (nbt.hasKey("inventory")) {
inventory = Option(ItemUtils.loadStack(nbt.getCompoundTag("inventory"))) inventory = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("inventory")))
} }
remainingTicks = nbt.getInteger("remainingTicks") remainingTicks = nbt.getInteger("remainingTicks")
} }

View File

@ -47,12 +47,6 @@ object ItemUtils {
def caseNameWithTierSuffix(name: String, tier: Int) = name + (if (tier == Tier.Four) "Creative" else (tier + 1).toString) 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]) = { def loadTag(data: Array[Byte]) = {
val bais = new ByteArrayInputStream(data) val bais = new ByteArrayInputStream(data)
CompressedStreamTools.readCompressed(bais) CompressedStreamTools.readCompressed(bais)