Made OpenOS loot disk a separate item to avoid confusing NEI and item costs.

Made loot disks to show up in NEI.
Validate inventory before starting assembly.
This commit is contained in:
Florian Nücke 2014-05-17 17:50:21 +02:00
parent 5c5e858c3d
commit 34c2fef670
5 changed files with 103 additions and 27 deletions

View File

@ -2,18 +2,11 @@ package li.cil.oc
import cpw.mods.fml.relauncher.Side
import cpw.mods.fml.relauncher.SideOnly
import li.cil.oc.common.Loot
import net.minecraft.creativetab.CreativeTabs
object CreativeTab extends CreativeTabs(CreativeTabs.getNextID, "OpenComputers") {
@SideOnly(Side.CLIENT)
override def getTabIconItemIndex = Settings.get.blockId2
override def displayAllReleventItems(list: java.util.List[_]) = {
def add[T](list: java.util.List[T], value: Any) = list.add(value.asInstanceOf[T])
super.displayAllReleventItems(list)
Loot.disks.foreach(add(list, _))
}
override def getTranslatedTabLabel = getTabLabel
}

View File

@ -1,13 +1,15 @@
package li.cil.oc
import cpw.mods.fml.common.registry.GameRegistry
import li.cil.oc.common.item
import li.cil.oc.common.{Loot, item}
import li.cil.oc.util.mods.Mods
import net.minecraft.item.{Item, ItemBlock, ItemStack}
import scala.collection.mutable
import li.cil.oc.api.detail.{ItemAPI, ItemInfo}
import net.minecraft.block.Block
import li.cil.oc.common.recipe.Recipes
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.creativetab.CreativeTabs
object Items extends ItemAPI {
private val descriptors = mutable.Map.empty[String, ItemInfo]
@ -69,7 +71,8 @@ object Items extends ItemAPI {
instance
}
private def getBlockOrItem(stack: ItemStack): Any = if (stack == null) null else {
private def getBlockOrItem(stack: ItemStack): Any = if (stack == null) null
else {
multi.subItem(stack).getOrElse(
Blocks.blockSimple.subBlock(stack).getOrElse(
Blocks.blockSimpleWithRedstone.subBlock(stack).getOrElse(
@ -93,7 +96,14 @@ object Items extends ItemAPI {
var ironNugget: item.IronNugget = _
def init() {
multi = new item.Delegator(Settings.get.itemId)
multi = new item.Delegator(Settings.get.itemId) {
override def getSubItems(itemId: Int, 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(itemId, tab, list)
Loot.worldDisks.values.foreach(entry => add(list, entry._1))
}
}
GameRegistry.registerItem(multi, Settings.namespace + "item")
@ -184,5 +194,23 @@ object Items extends ItemAPI {
Recipes.addItem(new item.UpgradeContainerCard(multi, 0), "cardContainer1", "oc:cardContainer1")
Recipes.addItem(new item.UpgradeContainerCard(multi, 1), "cardContainer2", "oc:cardContainer2")
Recipes.addItem(new item.UpgradeContainerCard(multi, 2), "cardContainer3", "oc:cardContainer3")
// Special case loot disk because this one's craftable and having it have
// the same item damage would confuse NEI and the item costs computation.
Recipes.addItem(new item.FloppyDisk(multi) {
override def createItemStack(amount: Int) = {
val data = new NBTTagCompound()
data.setString(Settings.namespace + "fs.label", "openos")
val nbt = new NBTTagCompound("tag")
nbt.setTag(Settings.namespace + "data", data)
nbt.setString(Settings.namespace + "lootPath", "OpenOS")
val stack = super.createItemStack(amount)
stack.setTagCompound(nbt)
stack
}
}, "openOS")
}
}

View File

@ -1,6 +1,6 @@
package li.cil.oc.common
import net.minecraftforge.common.ChestGenHooks
import net.minecraftforge.common.{DimensionManager, ChestGenHooks}
import net.minecraft.util.WeightedRandomChestContent
import net.minecraft.nbt.NBTTagCompound
import scala.collection.convert.WrapAsScala._
@ -8,8 +8,11 @@ import java.util.Random
import net.minecraft.inventory.IInventory
import net.minecraft.item.ItemStack
import scala.collection.mutable
import li.cil.oc.{Settings, api}
import li.cil.oc.{OpenComputers, Settings, api}
import li.cil.oc.common.recipe.Recipes
import java.io
import net.minecraftforge.event.ForgeSubscribe
import net.minecraftforge.event.world.WorldEvent
object Loot extends WeightedRandomChestContent(api.Items.get("lootDisk").createItemStack(1), 1, 1, Settings.get.lootProbability) {
val containers = Array(
@ -18,6 +21,10 @@ object Loot extends WeightedRandomChestContent(api.Items.get("lootDisk").createI
ChestGenHooks.PYRAMID_JUNGLE_CHEST,
ChestGenHooks.STRONGHOLD_LIBRARY)
val builtInDisks = mutable.Map.empty[String, (ItemStack, Int)]
val worldDisks = mutable.Map.empty[String, (ItemStack, Int)]
val disks = mutable.ArrayBuffer.empty[ItemStack]
def init() {
@ -26,16 +33,64 @@ object Loot extends WeightedRandomChestContent(api.Items.get("lootDisk").createI
}
val list = new java.util.Properties()
val listFile = getClass.getResourceAsStream("/assets/" + Settings.resourceDomain + "/loot/loot.properties")
list.load(listFile)
listFile.close()
val listStream = getClass.getResourceAsStream("/assets/" + Settings.resourceDomain + "/loot/loot.properties")
list.load(listStream)
listStream.close()
parseLootDisks(list, builtInDisks)
for (key <- list.stringPropertyNames) {
disks += createLootDisk(key, list.getProperty(key))
for ((name, (stack, _)) <- builtInDisks if name == "OpenOS") {
Recipes.list += stack -> "openOS"
}
}
def createLootDisk(name: String, path: String) = {
@ForgeSubscribe
def initForWorld(e: WorldEvent.Load) {
worldDisks.clear()
disks.clear()
val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + "loot/")
if (path.exists && path.isDirectory) {
val listFile = new io.File(path, "loot.properties")
if (listFile.exists && listFile.isFile) {
try {
val listStream = new io.FileInputStream(listFile)
val list = new java.util.Properties()
list.load(listStream)
listStream.close()
parseLootDisks(list, worldDisks)
}
catch {
case t: Throwable => OpenComputers.log.warning("Failed opening loot descriptor file in saves folder.")
}
}
}
for ((name, entry) <- builtInDisks if !worldDisks.contains(name)) {
worldDisks += name -> entry
}
for ((_, (stack, count)) <- worldDisks) {
for (i <- 0 until count) {
disks += stack
}
}
}
private def parseLootDisks(list: java.util.Properties, acc: mutable.Map[String, (ItemStack, Int)]) {
for (key <- list.stringPropertyNames if key != "OpenOS") {
val value = list.getProperty(key)
val splitAt = value.lastIndexOf(':')
if (splitAt >= 0) {
val (name, count) = value.splitAt(splitAt)
try {
acc += key -> (createLootDisk(name, key), count.toInt)
}
catch {
case _: Throwable => OpenComputers.log.warning("Bad loot descriptor: " + value)
}
}
else acc += key -> (createLootDisk(value, key), 1)
}
}
private def createLootDisk(name: String, path: String) = {
val data = new NBTTagCompound()
data.setString(Settings.namespace + "fs.label", name)
@ -47,10 +102,6 @@ object Loot extends WeightedRandomChestContent(api.Items.get("lootDisk").createI
val disk = api.Items.get("lootDisk").createItemStack(1)
disk.setTagCompound(tag)
if (name == "OpenOS") {
Recipes.list += disk -> "openOS"
}
disk
}

View File

@ -92,15 +92,16 @@ class Proxy {
api.Driver.add(driver.converter.FluidTankInfo)
api.Driver.add(driver.converter.ItemStack)
Loot.init()
Recipes.init()
GameRegistry.registerCraftingHandler(CraftingHandler)
MinecraftForge.EVENT_BUS.register(RobotCommonHandler)
MinecraftForge.EVENT_BUS.register(ExperienceUpgradeHandler)
if (Mods.UniversalElectricity.isAvailable) {
MinecraftForge.EVENT_BUS.register(UniversalElectricityToolHandler)
}
Loot.init()
Recipes.init()
GameRegistry.registerCraftingHandler(CraftingHandler)
MinecraftForge.EVENT_BUS.register(Loot)
FMLInterModComms.sendMessage("Waila", "register", "li.cil.oc.util.mods.Waila.init")
}

View File

@ -47,7 +47,10 @@ class RobotAssembler extends traits.Environment with traits.Inventory with trait
def start() {
if (!isAssembling && robot.isEmpty && complexity <= maxComplexity) {
// TODO validate all slots, just in case. never trust a client. never trust minecraft.
for (slot <- 0 until getSizeInventory) {
val stack = getStackInSlot(slot)
if (stack != null && !isItemValidForSlot(slot, stack)) return
}
val data = new ItemUtils.RobotData()
data.name = ItemUtils.RobotData.randomName
data.energy = 50000