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 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;

View File

@ -1,8 +1,11 @@
package li.cil.oc.api;
import li.cil.oc.api.detail.ItemInfo;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack;
import java.util.concurrent.Callable;
/**
* Access to item definitions for all blocks and items provided by
* OpenComputers.
@ -44,6 +47,53 @@ public final class Items {
return null;
}
/**
* Register a single loot floppy disk.
* <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() {

View File

@ -1,7 +1,11 @@
package li.cil.oc.api.detail;
import li.cil.oc.api.FileSystem;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack;
import java.util.concurrent.Callable;
public interface ItemAPI {
/**
* Get a descriptor object for the block or item with the specified name.
@ -26,4 +30,47 @@ public interface ItemAPI {
* if the stack is not a valid OpenComputers item or block.
*/
ItemInfo get(ItemStack stack);
/**
* Register a single loot floppy disk.
* <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
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

View File

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

View File

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

View File

@ -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).

View File

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

View File

@ -2,13 +2,17 @@ package li.cil.oc.common
import java.io
import java.util.Random
import java.util.concurrent.Callable
import li.cil.oc.Constants
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.fs.FileSystem
import li.cil.oc.common.init.Items
import li.cil.oc.util.Color
import net.minecraft.inventory.IInventory
import net.minecraft.item.EnumDyeColor
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
@ -16,6 +20,7 @@ import net.minecraft.util.WeightedRandomChestContent
import net.minecraftforge.common.ChestGenHooks
import net.minecraftforge.common.DimensionManager
import net.minecraftforge.event.world.WorldEvent
import net.minecraftforge.fml.common.Loader
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import scala.collection.convert.WrapAsScala._
@ -28,16 +33,45 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
ChestGenHooks.PYRAMID_JUNGLE_CHEST,
ChestGenHooks.STRONGHOLD_LIBRARY)
val builtInDisks = mutable.Map.empty[String, (ItemStack, Int)]
val factories = mutable.Map.empty[String, Callable[FileSystem]]
val globalDisks = mutable.Map.empty[String, (ItemStack, Int)]
val worldDisks = mutable.Map.empty[String, (ItemStack, Int)]
val disks = mutable.ArrayBuffer.empty[ItemStack]
val disksForSampling = mutable.ArrayBuffer.empty[ItemStack]
val disksForClient = mutable.ArrayBuffer.empty[ItemStack]
def randomDisk(rng: Random) =
if (disks.length > 0) Some(disks(rng.nextInt(disks.length)))
if (disksForSampling.length > 0) Some(disksForSampling(rng.nextInt(disksForSampling.length)))
else None
def registerLootDisk(name: String, color: EnumDyeColor, factory: Callable[FileSystem]): ItemStack = {
val mod = Loader.instance.activeModContainer.getModId
OpenComputers.log.info(s"Registering loot disk '$name' from mod $mod.")
val modSpecificName = mod + ":" + name
val data = new NBTTagCompound()
data.setString(Settings.namespace + "fs.label", name)
val nbt = new NBTTagCompound()
nbt.setTag(Settings.namespace + "data", data)
// Store this top level, so it won't get wiped on save.
nbt.setString(Settings.namespace + "lootFactory", modSpecificName)
nbt.setInteger(Settings.namespace + "color", color.getDyeDamage)
val stack = Items.get(Constants.ItemName.Floppy).createItemStack(1)
stack.setTagCompound(nbt)
Loot.factories += modSpecificName -> factory
stack.copy()
}
def init() {
for (container <- containers) {
ChestGenHooks.addItem(container, Loot)
@ -47,13 +81,13 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
val listStream = getClass.getResourceAsStream("/assets/" + Settings.resourceDomain + "/loot/loot.properties")
list.load(listStream)
listStream.close()
parseLootDisks(list, builtInDisks)
parseLootDisks(list, globalDisks, external = false)
}
@SubscribeEvent
def initForWorld(e: WorldEvent.Load) {
def initForWorld(e: WorldEvent.Load): Unit = if (!e.world.isRemote && e.world.provider.getDimensionId == 0) {
worldDisks.clear()
disks.clear()
disksForSampling.clear()
if (!e.world.isRemote) {
val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + "loot/")
if (path.exists && path.isDirectory) {
@ -64,7 +98,7 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
val list = new java.util.Properties()
list.load(listStream)
listStream.close()
parseLootDisks(list, worldDisks)
parseLootDisks(list, worldDisks, external = true)
}
catch {
case t: Throwable => OpenComputers.log.warn("Failed opening loot descriptor file in saves folder.")
@ -72,26 +106,26 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
}
}
}
for ((name, entry) <- builtInDisks if !worldDisks.contains(name)) {
for ((name, entry) <- globalDisks if !worldDisks.contains(name)) {
worldDisks += name -> entry
}
for ((_, (stack, count)) <- worldDisks) {
for (i <- 0 until count) {
disks += stack
disksForSampling += stack
}
}
}
private def parseLootDisks(list: java.util.Properties, acc: mutable.Map[String, (ItemStack, Int)]) {
private def parseLootDisks(list: java.util.Properties, acc: mutable.Map[String, (ItemStack, Int)], external: Boolean) {
for (key <- list.stringPropertyNames) {
val value = list.getProperty(key)
try value.split(":") match {
case Array(name, count, color) =>
acc += key -> ((createLootDisk(name, key, Some(color)), count.toInt))
acc += key -> ((createLootDisk(name, key, external, Color.byOreName.get(color)), count.toInt))
case Array(name, count) =>
acc += key -> ((createLootDisk(name, key), count.toInt))
acc += key -> ((createLootDisk(name, key, external), count.toInt))
case _ =>
acc += key -> ((createLootDisk(value, key), 1))
acc += key -> ((createLootDisk(value, key, external), 1))
}
catch {
case t: Throwable => OpenComputers.log.warn("Bad loot descriptor: " + value, t)
@ -99,24 +133,17 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
}
}
def createLootDisk(name: String, path: String, color: Option[String] = None) = {
val data = new NBTTagCompound()
data.setString(Settings.namespace + "fs.label", name)
val tag = new NBTTagCompound()
tag.setTag(Settings.namespace + "data", data)
// Store this top level, so it won't get wiped on save.
tag.setString(Settings.namespace + "lootPath", path)
color match {
case Some(oreDictName) =>
tag.setInteger(Settings.namespace + "color", Color.dyes.indexOf(oreDictName))
case _ =>
def createLootDisk(name: String, path: String, external: Boolean, color: Option[EnumDyeColor] = None) = {
val callable = if (external) new Callable[FileSystem] {
override def call(): FileSystem = api.FileSystem.fromSaveDirectory("loot/" + path, 0, false)
} else new Callable[FileSystem] {
override def call(): FileSystem = api.FileSystem.fromClass(OpenComputers.getClass, Settings.resourceDomain, "loot/" + path)
}
val disk = Items.get(Constants.ItemName.Floppy).createItemStack(1)
disk.setTagCompound(tag)
disk
val stack = registerLootDisk(name, color.getOrElse(EnumDyeColor.SILVER), callable)
if (!external) {
Items.registerStack(stack, name)
}
stack
}
override def generateChestContent(random: Random, newInventory: IInventory) =

View File

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

View File

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

View File

@ -1,12 +1,14 @@
package li.cil.oc.common.init
import java.util
import java.util.concurrent.Callable
import li.cil.oc.Constants
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.api.detail.ItemAPI
import li.cil.oc.api.detail.ItemInfo
import li.cil.oc.api.fs.FileSystem
import li.cil.oc.common
import li.cil.oc.common.Loot
import li.cil.oc.common.Tier
@ -22,6 +24,7 @@ import li.cil.oc.common.recipe.Recipes
import li.cil.oc.integration.Mods
import net.minecraft.block.Block
import net.minecraft.creativetab.CreativeTabs
import net.minecraft.item.EnumDyeColor
import net.minecraft.item.Item
import net.minecraft.item.ItemBlock
import net.minecraft.item.ItemStack
@ -111,6 +114,24 @@ object Items extends ItemAPI {
instance
}
def registerStack(stack: ItemStack, id: String) = {
val immutableStack = stack.copy()
descriptors += id -> new ItemInfo {
override def name = id
override def block = null
override def createItemStack(size: Int): ItemStack = {
val copy = immutableStack.copy()
copy.stackSize = size
copy
}
override def item = immutableStack.getItem
}
stack
}
private def getBlockOrItem(stack: ItemStack): Any =
if (stack == null) null
else Delegator.subItem(stack).getOrElse(stack.getItem match {
@ -120,24 +141,60 @@ object Items extends ItemAPI {
// ----------------------------------------------------------------------- //
def createOpenOS(amount: Int = 1) = {
Loot.builtInDisks.get("OpenOS").map(_._1.copy()).orNull
val registeredItems = mutable.ArrayBuffer.empty[ItemStack]
override def registerFloppy(name: String, color: EnumDyeColor, factory: Callable[FileSystem]): ItemStack = {
val stack = Loot.registerLootDisk(name, color, factory)
registeredItems += stack
stack.copy()
}
def createLuaBios(amount: Int = 1) = {
val data = new NBTTagCompound()
val code = new Array[Byte](4 * 1024)
val count = OpenComputers.getClass.getResourceAsStream(Settings.scriptPath + "bios.lua").read(code)
data.setByteArray(Settings.namespace + "eeprom", code.take(count))
data.setString(Settings.namespace + "label", "EEPROM (Lua BIOS)")
override def registerEEPROM(name: String, code: Array[Byte], data: Array[Byte], readonly: Boolean): ItemStack = {
val nbt = new NBTTagCompound()
nbt.setTag(Settings.namespace + "data", data)
if (name != null) {
nbt.setString(Settings.namespace + "label", name.trim.take(16))
}
if (code != null) {
nbt.setByteArray(Settings.namespace + "eeprom", code.take(Settings.get.eepromSize))
}
if (data != null) {
nbt.setByteArray(Settings.namespace + "userdata", data.take(Settings.get.eepromDataSize))
}
nbt.setBoolean(Settings.namespace + "readonly", readonly)
val stack = get(Constants.ItemName.EEPROM).createItemStack(amount)
stack.setTagCompound(nbt)
val stackNbt = new NBTTagCompound()
stackNbt.setTag(Settings.namespace + "data", nbt)
stack
val stack = get(Constants.ItemName.EEPROM).createItemStack(1)
stack.setTagCompound(stackNbt)
registeredItems += stack
stack.copy()
}
// ----------------------------------------------------------------------- //
// Nobody should use this anyway, since it's internal, but IIRC some people do, so let's be nice...
// TODO remove in OC 1.6
/**
* @deprecated use <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() = {
@ -212,8 +269,8 @@ object Items extends ItemAPI {
get(Constants.ItemName.RAMTier6).createItemStack(1),
get(Constants.ItemName.RAMTier6).createItemStack(1),
createLuaBios(),
createOpenOS(),
get(Constants.ItemName.LuaBios).createItemStack(1),
get(Constants.ItemName.OpenOS).createItemStack(1),
get(Constants.ItemName.HDDTier3).createItemStack(1)
)
data.containers = Array(
@ -246,10 +303,10 @@ object Items extends ItemAPI {
Option(get(Constants.ItemName.RAMTier6).createItemStack(1)),
Option(get(Constants.ItemName.RAMTier6).createItemStack(1)),
Option(createLuaBios()),
Option(get(Constants.ItemName.LuaBios).createItemStack(1)),
Option(get(Constants.ItemName.HDDTier3).createItemStack(1))
).padTo(32, None)
data.items(31) = Option(createOpenOS())
data.items(31) = Option(get(Constants.ItemName.OpenOS).createItemStack(1))
data.container = Option(get(Constants.BlockName.DiskDrive).createItemStack(1))
val stack = get(Constants.ItemName.Tablet).createItemStack(1)
@ -401,14 +458,7 @@ object Items extends ItemAPI {
// Storage media of all kinds.
private def initStorage(): Unit = {
val storage = newItem(new item.Delegator() {
// Override to inject loot disks.
override def getSubItems(item: Item, tab: CreativeTabs, list: java.util.List[_]) {
super.getSubItems(item, tab, list)
Items.add(list, createLuaBios())
Loot.worldDisks.values.foreach(entry => Items.add(list, entry._1))
}
}, "storage")
val storage = newItem(new item.Delegator(), "storage")
Recipes.addSubItem(new item.EEPROM(storage), Constants.ItemName.EEPROM, "oc:eeprom")
Recipes.addSubItem(new item.FloppyDisk(storage), Constants.ItemName.Floppy, "oc:floppy")
@ -416,7 +466,13 @@ object Items extends ItemAPI {
Recipes.addSubItem(new item.HardDiskDrive(storage, Tier.Two), Constants.ItemName.HDDTier2, "oc:hdd2")
Recipes.addSubItem(new item.HardDiskDrive(storage, Tier.Three), Constants.ItemName.HDDTier3, "oc:hdd3")
Recipes.addRecipe(createLuaBios(), Constants.ItemName.LuaBios)
val luaBios = {
val code = new Array[Byte](4 * 1024)
val count = OpenComputers.getClass.getResourceAsStream(Settings.scriptPath + "bios.lua").read(code)
registerEEPROM("EEPROM (Lua BIOS)", code.take(count), null, readonly = false)
}
Recipes.addStack(luaBios, Constants.ItemName.LuaBios)
}
// Special purpose items that don't fit into any other category.
@ -427,7 +483,7 @@ object Items extends ItemAPI {
Items.createConfiguredMicrocontroller(),
Items.createConfiguredRobot(),
Items.createConfiguredTablet()
)
) ++ Loot.disksForClient ++ registeredItems
override def getSubItems(item: Item, tab: CreativeTabs, list: util.List[_]): Unit = {
super.getSubItems(item, tab, list)

View File

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

View File

@ -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))
}
}
}

View File

@ -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

View File

@ -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"))
}
}

View File

@ -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"))

View File

@ -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")
}

View File

@ -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")))
}
}

View File

@ -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 {

View File

@ -80,6 +80,13 @@ object Recipes {
delegate
}
def addStack(stack: ItemStack, name: String, oreDict: String*) = {
Items.registerStack(stack, name)
addRecipe(stack, name)
register(stack, oreDict: _*)
stack
}
def addRecipe(stack: ItemStack, name: String) {
list += stack -> name
}
@ -161,7 +168,7 @@ object Recipes {
val lootRecipes = recipes.getConfigList("lootDisks")
for (recipe <- lootRecipes) {
val name = recipe.getString("name")
Loot.builtInDisks.get(name) match {
Loot.globalDisks.get(name) match {
case Some((stack, _)) => addRecipe(stack, recipe, s"loot disk '$name'")
case _ =>
OpenComputers.log.warn(s"Failed adding recipe for loot disk '$name': No such global loot disk.")

View File

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

View File

@ -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

View File

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

View File

@ -11,7 +11,6 @@ import li.cil.oc.api.network._
import li.cil.oc.common.item.data.PrintData
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ItemUtils
import net.minecraft.inventory.ISidedInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
@ -278,7 +277,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
isActive = nbt.getBoolean(Settings.namespace + "active")
limit = nbt.getInteger(Settings.namespace + "limit")
if (nbt.hasKey(Settings.namespace + "output")) {
output = Option(ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "output")))
output = Option(ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(Settings.namespace + "output")))
}
totalRequiredEnergy = nbt.getDouble(Settings.namespace + "total")
requiredEnergy = nbt.getDouble(Settings.namespace + "remaining")

View File

@ -5,6 +5,7 @@ import li.cil.oc.Constants
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.common.Loot
import li.cil.oc.common.Slot
import li.cil.oc.common.item.Delegator
import li.cil.oc.common.item.FloppyDisk
@ -43,17 +44,31 @@ object DriverFileSystem extends Item {
}
private def createEnvironment(stack: ItemStack, capacity: Int, host: EnvironmentHost, speed: Int) = if (DimensionManager.getWorld(0) != null) {
// We have a bit of a chicken-egg problem here, because we want to use the
// node's address as the folder name... so we generate the address here,
// if necessary. No one will know, right? Right!?
val address = addressFromTag(dataTag(stack))
val isFloppy = api.Items.get(stack) == api.Items.get(Constants.ItemName.Floppy)
val fs = oc.api.FileSystem.fromSaveDirectory(address, capacity, Settings.get.bufferChanges)
val environment = oc.api.FileSystem.asManagedEnvironment(fs, new ReadWriteItemLabel(stack), host, Settings.resourceDomain + ":" + (if (isFloppy) "floppy_access" else "hdd_access"), speed)
if (environment != null && environment.node != null) {
environment.node.asInstanceOf[oc.server.network.Node].address = address
if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "lootFactory")) {
// Loot disk, create file system using factory callback.
Loot.factories.get(stack.getTagCompound.getString(Settings.namespace + "lootFactory")) match {
case Some(factory) =>
val label =
if (dataTag(stack).hasKey(Settings.namespace + "fs.label"))
dataTag(stack).getString(Settings.namespace + "fs.label")
else null
api.FileSystem.asManagedEnvironment(factory.call(), label, host, Settings.resourceDomain + ":floppy_access")
case _ => null // Invalid loot disk.
}
}
else {
// We have a bit of a chicken-egg problem here, because we want to use the
// node's address as the folder name... so we generate the address here,
// if necessary. No one will know, right? Right!?
val address = addressFromTag(dataTag(stack))
val isFloppy = api.Items.get(stack) == api.Items.get(Constants.ItemName.Floppy)
val fs = oc.api.FileSystem.fromSaveDirectory(address, capacity, Settings.get.bufferChanges)
val environment = oc.api.FileSystem.asManagedEnvironment(fs, new ReadWriteItemLabel(stack), host, Settings.resourceDomain + ":" + (if (isFloppy) "floppy_access" else "hdd_access"), speed)
if (environment != null && environment.node != null) {
environment.node.asInstanceOf[oc.server.network.Node].address = address
}
environment
}
environment
}
else null

View File

@ -11,6 +11,9 @@ import li.cil.oc.common.Slot
import net.minecraft.item.ItemStack
import net.minecraftforge.common.DimensionManager
// This is deprecated and kept for compatibility with old saves.
// As of OC 1.5.10, loot disks are generated using normal floppies, and using
// a factory system that allows third-party mods to register loot disks.
object DriverLootDisk extends Item {
override def worksWith(stack: ItemStack) = isOneOf(stack,
api.Items.get(Constants.ItemName.Floppy)) &&

View File

@ -215,6 +215,18 @@ object PacketSender {
pb.sendToPlayersNearTileEntity(t)
}
def sendLootDisks(p: EntityPlayerMP): Unit = {
// Sending as separate packets, because CompressedStreamTools hiccups otherwise...
val stacks = Loot.worldDisks.values.map(_._1)
for (stack <- stacks) {
val pb = new SimplePacketBuilder(PacketType.LootDisk)
pb.writeItemStack(stack)
pb.sendToPlayer(p)
}
}
def sendParticleEffect(position: BlockPosition, particleType: EnumParticleTypes, count: Int, velocity: Double, direction: Option[EnumFacing] = None): Unit = if (count > 0) {
val pb = new SimplePacketBuilder(PacketType.ParticleEffect)

View File

@ -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")
}

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 loadStack(nbt: NBTTagCompound) = ItemStack.loadItemStackFromNBT(nbt)
def loadStack(data: Array[Byte]) = {
ItemStack.loadItemStackFromNBT(loadTag(data))
}
def loadTag(data: Array[Byte]) = {
val bais = new ByteArrayInputStream(data)
CompressedStreamTools.readCompressed(bais)