From 61ba86d4511d5d93046ff05d8d8b53bdeb07ec8c Mon Sep 17 00:00:00 2001 From: bdew Date: Wed, 25 Mar 2015 13:11:52 +0200 Subject: [PATCH] Added NBTHelper, changed OutputConfigFluid to use moving average --- src/net/bdew/lib/Misc.scala | 10 ++- src/net/bdew/lib/data/DataSlotInventory.scala | 6 +- .../inventory/InventoryItemAdapter.scala | 6 +- .../data/DataSlotBlockFaceMap.scala | 11 ++- .../lib/multiblock/data/DataSlotPosSet.scala | 11 ++- .../multiblock/data/OutputConfigFluid.scala | 22 +++-- src/net/bdew/lib/nbt/NBTHelper.scala | 32 +++++++ src/net/bdew/lib/nbt/NBTTypes.scala | 84 +++++++++++++++++++ .../inventory/PersistentInventoryTile.scala | 23 ++--- 9 files changed, 166 insertions(+), 39 deletions(-) create mode 100644 src/net/bdew/lib/nbt/NBTHelper.scala create mode 100644 src/net/bdew/lib/nbt/NBTTypes.scala diff --git a/src/net/bdew/lib/Misc.scala b/src/net/bdew/lib/Misc.scala index 06b56a4..84def2e 100644 --- a/src/net/bdew/lib/Misc.scala +++ b/src/net/bdew/lib/Misc.scala @@ -22,14 +22,16 @@ import net.minecraftforge.fluids.{Fluid, FluidStack} import net.minecraftforge.oredict.ShapedOreRecipe object Misc { + @deprecated("Use NBTImplicits instead", "bdlib 1.7.0") def iterNbtCompoundList(parent: NBTTagCompound, name: String): Iterable[NBTTagCompound] = { - val list = parent.getTagList(name, 10) - for (i <- 0 until list.tagCount()) yield list.getCompoundTagAt(i) + import net.bdew.lib.nbt.NBTHelper._ + parent.getList[NBTTagCompound](name) } + @deprecated("Use NBTImplicits instead", "bdlib 1.7.0") def iterNbtIntArray(parent: NBTTagCompound, name: String): Iterable[Array[Int]] = { - val list = parent.getTagList(name, 11) - for (i <- 0 until list.tagCount()) yield list.func_150306_c(i) + import net.bdew.lib.nbt.NBTHelper._ + parent.getList[Array[Int]](name) } def getActiveModId = Loader.instance().activeModContainer().getModId diff --git a/src/net/bdew/lib/data/DataSlotInventory.scala b/src/net/bdew/lib/data/DataSlotInventory.scala index bd5054a..337efaf 100644 --- a/src/net/bdew/lib/data/DataSlotInventory.scala +++ b/src/net/bdew/lib/data/DataSlotInventory.scala @@ -9,7 +9,6 @@ package net.bdew.lib.data -import net.bdew.lib.Misc import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind} import net.bdew.lib.tile.inventory.BaseInventory import net.minecraft.item.ItemStack @@ -23,9 +22,10 @@ case class DataSlotInventory(name: String, parent: DataSlotContainer, size: Int) override def load(t: NBTTagCompound, kind: UpdateKind.Value) { inv = new Array[ItemStack](getSizeInventory) - for (nbtItem <- Misc.iterNbtCompoundList(t, name)) { + import net.bdew.lib.nbt.NBTHelper._ + for (nbtItem <- t.getList[NBTTagCompound](name)) { val slot = nbtItem.getByte("Slot") - if (slot >= 0 && slot < inv.size) { + if (slot >= 0 && slot < inv.length) { inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem) } } diff --git a/src/net/bdew/lib/items/inventory/InventoryItemAdapter.scala b/src/net/bdew/lib/items/inventory/InventoryItemAdapter.scala index 8063a89..3dac250 100644 --- a/src/net/bdew/lib/items/inventory/InventoryItemAdapter.scala +++ b/src/net/bdew/lib/items/inventory/InventoryItemAdapter.scala @@ -9,7 +9,6 @@ package net.bdew.lib.items.inventory -import net.bdew.lib.Misc import net.bdew.lib.tile.inventory.BaseInventory import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack @@ -23,10 +22,11 @@ class InventoryItemAdapter(val player: EntityPlayer, val slot: Int, val size: In load() def load() { + import net.bdew.lib.nbt.NBTHelper._ val tag = getStack.getTagCompound - for (nbtItem <- Misc.iterNbtCompoundList(tag, tagName)) { + for (nbtItem <- tag.getList[NBTTagCompound](tagName)) { val slot = nbtItem.getByte("Slot") - if (slot >= 0 && slot < inv.size) { + if (slot >= 0 && slot < inv.length) { inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem) } } diff --git a/src/net/bdew/lib/multiblock/data/DataSlotBlockFaceMap.scala b/src/net/bdew/lib/multiblock/data/DataSlotBlockFaceMap.scala index 5b909c8..f6b3afc 100644 --- a/src/net/bdew/lib/multiblock/data/DataSlotBlockFaceMap.scala +++ b/src/net/bdew/lib/multiblock/data/DataSlotBlockFaceMap.scala @@ -9,10 +9,9 @@ package net.bdew.lib.multiblock.data -import net.bdew.lib.Misc import net.bdew.lib.block.BlockFace import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind} -import net.minecraft.nbt.{NBTTagCompound, NBTTagIntArray, NBTTagList} +import net.minecraft.nbt.NBTTagCompound import net.minecraftforge.common.util.ForgeDirection import scala.collection.mutable @@ -27,15 +26,15 @@ case class DataSlotBlockFaceMap(name: String, parent: DataSlotContainer) extends def ent2arr(x: (BlockFace, Int)) = Array(x._2, x._1.x, x._1.y, x._1.z, x._1.face.ordinal()) def arr2ent(x: Array[Int]) = BlockFace(x(1), x(2), x(3), ForgeDirection.values()(x(4))) -> x(0) + import net.bdew.lib.nbt.NBTHelper._ + def save(t: NBTTagCompound, kind: UpdateKind.Value) { - val lst = new NBTTagList() - for (x <- map) lst.appendTag(new NBTTagIntArray(ent2arr(x))) - t.setTag(name, lst) + t.setList(name, map.map(ent2arr)) } def load(t: NBTTagCompound, kind: UpdateKind.Value) { map.clear() - map ++= Misc.iterNbtIntArray(t, name) map arr2ent + map ++= t.getList[Array[Int]]("name") map arr2ent } def updated() = parent.dataSlotChanged(this) diff --git a/src/net/bdew/lib/multiblock/data/DataSlotPosSet.scala b/src/net/bdew/lib/multiblock/data/DataSlotPosSet.scala index d2bf67f..7e9c468 100644 --- a/src/net/bdew/lib/multiblock/data/DataSlotPosSet.scala +++ b/src/net/bdew/lib/multiblock/data/DataSlotPosSet.scala @@ -12,7 +12,7 @@ package net.bdew.lib.multiblock.data import net.bdew.lib.Misc import net.bdew.lib.block.BlockRef import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind} -import net.minecraft.nbt.{NBTTagCompound, NBTTagList} +import net.minecraft.nbt.NBTTagCompound import scala.collection.mutable @@ -21,19 +21,18 @@ case class DataSlotPosSet(name: String, parent: DataSlotContainer) extends DataS setUpdate(UpdateKind.SAVE, UpdateKind.WORLD) + import net.bdew.lib.nbt.NBTHelper._ + def save(t: NBTTagCompound, kind: UpdateKind.Value) { - val lst = new NBTTagList() - for (x <- set) lst.appendTag(Misc.applyMutator(x.writeToNBT, new NBTTagCompound)) - t.setTag(name, lst) + t.setList(name, set.map(x => Misc.applyMutator(x.writeToNBT, new NBTTagCompound))) } def load(t: NBTTagCompound, kind: UpdateKind.Value) { set.clear() - set ++= Misc.iterNbtCompoundList(t, name) map BlockRef.fromNBT + set ++= t.getList[NBTTagCompound](name) map BlockRef.fromNBT } def updated() = parent.dataSlotChanged(this) - } object DataSlotPosSet { diff --git a/src/net/bdew/lib/multiblock/data/OutputConfigFluid.scala b/src/net/bdew/lib/multiblock/data/OutputConfigFluid.scala index b524eae..196c28d 100644 --- a/src/net/bdew/lib/multiblock/data/OutputConfigFluid.scala +++ b/src/net/bdew/lib/multiblock/data/OutputConfigFluid.scala @@ -10,26 +10,36 @@ package net.bdew.lib.multiblock.data import net.bdew.lib.multiblock.network.MsgOutputCfg -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.{NBTTagCompound, NBTTagList} + +import scala.collection.mutable class OutputConfigFluid extends OutputConfig with OutputConfigRSControllable { override def id = "fluid" - var avg = 0.0 + val values = mutable.Queue.empty[Double] var rsMode = RSMode.ALWAYS - final val decay = 0.5 + final val ticks = 20 + + import net.bdew.lib.nbt.NBTHelper._ + + def avg = values.sum / values.size def updateAvg(v: Double) { - avg = avg * decay + (1 - decay) * v + values += v + if (values.size > ticks) + values.dequeue() } def read(t: NBTTagCompound) { - avg = t.getDouble("avg") + values.clear() + values ++= t.getList[Double]("values") rsMode = RSMode(t.getInteger("rsMode")) } def write(t: NBTTagCompound) { - t.setDouble("avg", avg) + val l = new NBTTagList + t.setList("values", values) t.setInteger("rsMode", rsMode.id) } diff --git a/src/net/bdew/lib/nbt/NBTHelper.scala b/src/net/bdew/lib/nbt/NBTHelper.scala new file mode 100644 index 0000000..9ea8a9b --- /dev/null +++ b/src/net/bdew/lib/nbt/NBTHelper.scala @@ -0,0 +1,32 @@ +/* + * Copyright (c) bdew, 2013 - 2015 + * https://github.com/bdew/bdlib + * + * This mod is distributed under the terms of the Minecraft Mod Public + * License 1.0, or MMPL. Please check the contents of the license located in + * http://bdew.net/minecraft-mod-public-license/ + */ + +package net.bdew.lib.nbt + +import net.minecraft.nbt.{NBTBase, NBTTagCompound, NBTTagList} + +import scala.language.implicitConversions + +object NBTHelper { + + import NBTTypes._ + + class RichNBTTagCompound(x: NBTTagCompound) { + def getList[T](name: String)(implicit ev: TypeInList[_, T]): Iterable[T] = { + val list = x.getTagList(name, ev.definition.id) + for (i <- 0 until list.tagCount()) yield ev.fromList(list, i) + } + def setList[T](name: String, v: Iterable[T])(implicit ev: Type[_ <: NBTBase, T]): Unit = { + val list = new NBTTagList + for (x <- v) list.appendTag(ev.toNBT(x)) + } + } + + implicit def compound2rich(p: NBTTagCompound): RichNBTTagCompound = new RichNBTTagCompound(p) +} diff --git a/src/net/bdew/lib/nbt/NBTTypes.scala b/src/net/bdew/lib/nbt/NBTTypes.scala new file mode 100644 index 0000000..b8f09d1 --- /dev/null +++ b/src/net/bdew/lib/nbt/NBTTypes.scala @@ -0,0 +1,84 @@ +/* + * Copyright (c) bdew, 2013 - 2015 + * https://github.com/bdew/bdlib + * + * This mod is distributed under the terms of the Minecraft Mod Public + * License 1.0, or MMPL. Please check the contents of the license located in + * http://bdew.net/minecraft-mod-public-license/ + */ + +package net.bdew.lib.nbt + +import net.minecraft.nbt._ + +object NBTTypes { + var map = Map.empty[Int, Type[_, _]] + + abstract class Type[T <: NBTBase, R](val id: Int, val cls: Class[T], val valueClass: Class[R]) { + map += id -> this + def toVal(p: T): R + def toNBT(p: R): T + } + + class TypeSimple[T <: NBTBase](id: Int, cls: Class[T]) extends Type[T, T](id, cls, cls) { + override def toVal(p: T): T = p + override def toNBT(p: T): T = p + } + + case class TypeInList[T <: NBTBase, R](definition: Type[T, R], fromList: (NBTTagList, Int) => R) + + implicit object TByte extends Type(1, classOf[NBTTagByte], classOf[Byte]) { + override def toVal(p: NBTTagByte): Byte = p.func_150290_f() + override def toNBT(p: Byte): NBTTagByte = new NBTTagByte(p) + } + + implicit object TShort extends Type(2, classOf[NBTTagShort], classOf[Short]) { + override def toVal(p: NBTTagShort): Short = p.func_150289_e() + override def toNBT(p: Short): NBTTagShort = new NBTTagShort(p) + } + + implicit object TInt extends Type(3, classOf[NBTTagInt], classOf[Int]) { + override def toVal(p: NBTTagInt): Int = p.func_150287_d() + override def toNBT(p: Int): NBTTagInt = new NBTTagInt(p) + } + + implicit object TLong extends Type(4, classOf[NBTTagLong], classOf[Long]) { + override def toVal(p: NBTTagLong): Long = p.func_150291_c() + override def toNBT(p: Long): NBTTagLong = new NBTTagLong(p) + } + + implicit object TFloat extends Type(5, classOf[NBTTagFloat], classOf[Float]) { + override def toVal(p: NBTTagFloat): Float = p.func_150288_h() + override def toNBT(p: Float): NBTTagFloat = new NBTTagFloat(p) + } + + implicit object TDouble extends Type(6, classOf[NBTTagDouble], classOf[Double]) { + override def toVal(p: NBTTagDouble): Double = p.func_150286_g() + override def toNBT(p: Double): NBTTagDouble = new NBTTagDouble(p) + } + + implicit object TByteArray extends Type(7, classOf[NBTTagByteArray], classOf[Array[Byte]]) { + override def toVal(p: NBTTagByteArray): Array[Byte] = p.func_150292_c() + override def toNBT(p: Array[Byte]): NBTTagByteArray = new NBTTagByteArray(p) + } + + implicit object TString extends Type(8, classOf[NBTTagString], classOf[String]) { + override def toVal(p: NBTTagString): String = p.func_150285_a_() + override def toNBT(p: String): NBTTagString = new NBTTagString(p) + } + + implicit object TList extends TypeSimple(9, classOf[NBTTagList]) + + implicit object TCompound extends TypeSimple(10, classOf[NBTTagCompound]) + + implicit object TIntArray extends Type(11, classOf[NBTTagIntArray], classOf[Array[Int]]) { + override def toVal(p: NBTTagIntArray): Array[Int] = p.func_150302_c() + override def toNBT(p: Array[Int]): NBTTagIntArray = new NBTTagIntArray(p) + } + + implicit val stringInList = TypeInList(TString, _.getStringTagAt(_)) + implicit val compoundInList = TypeInList(TCompound, _.getCompoundTagAt(_)) + implicit val intArrayInList = TypeInList(TIntArray, _.func_150306_c(_)) + implicit val doubleInList = TypeInList(TDouble, _.func_150309_d(_)) + implicit val floatInList = TypeInList(TFloat, _.func_150308_e(_)) +} diff --git a/src/net/bdew/lib/tile/inventory/PersistentInventoryTile.scala b/src/net/bdew/lib/tile/inventory/PersistentInventoryTile.scala index 400d12b..9e687a6 100644 --- a/src/net/bdew/lib/tile/inventory/PersistentInventoryTile.scala +++ b/src/net/bdew/lib/tile/inventory/PersistentInventoryTile.scala @@ -12,27 +12,28 @@ package net.bdew.lib.tile.inventory import net.bdew.lib.Misc import net.bdew.lib.tile.TileExtended import net.minecraft.item.ItemStack -import net.minecraft.nbt.{NBTTagCompound, NBTTagList} +import net.minecraft.nbt.NBTTagCompound trait PersistentInventoryTile extends TileExtended with BaseInventory { + + import net.bdew.lib.nbt.NBTHelper._ + persistLoad.listen((tag: NBTTagCompound) => { inv = new Array[ItemStack](getSizeInventory) - for (nbtItem <- Misc.iterNbtCompoundList(tag, "Items")) { + for (nbtItem <- tag.getList[NBTTagCompound]("Items")) { val slot = nbtItem.getByte("Slot") - if (slot >= 0 && slot < inv.size) { + if (slot >= 0 && slot < inv.length) { inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem) } } }) persistSave.listen((tag: NBTTagCompound) => { - val itemList = new NBTTagList - for ((item, i) <- inv.view.zipWithIndex if item != null) { - val itemNbt: NBTTagCompound = new NBTTagCompound - itemNbt.setByte("Slot", i.asInstanceOf[Byte]) - item.writeToNBT(itemNbt) - itemList.appendTag(itemNbt) - } - tag.setTag("Items", itemList) + tag.setList("name", + for ((item, i) <- inv.view.zipWithIndex if item != null) + yield Misc.applyMutator(new NBTTagCompound) { itemNbt => + itemNbt.setByte("Slot", i.asInstanceOf[Byte]) + item.writeToNBT(itemNbt) + }) }) }