Fix inconsistent 3D print item stacking

Now prints that consist of the same set of shapes stack as they should.

Co-authored-by: Quant1um <spitfirexv22@gmail.com>
This commit is contained in:
Adrian Siekierka 2022-06-07 17:39:19 +02:00
parent 631ef13cab
commit 7d9d18c372

View File

@ -1,11 +1,11 @@
package li.cil.oc.common.item.data
import java.lang.reflect.Method
import li.cil.oc.Constants
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.common.IMC
import li.cil.oc.common.item.data.PrintData.Shape
import li.cil.oc.util.ExtendedAABB._
import li.cil.oc.util.ExtendedNBT._
import net.minecraft.item.ItemStack
@ -82,13 +82,35 @@ class PrintData extends ItemData(Constants.BlockName.Print) {
nbt.setBoolean("isButtonMode", isButtonMode)
nbt.setInteger("redstoneLevel", redstoneLevel)
nbt.setBoolean("pressurePlate", pressurePlate)
nbt.setNewTagList("stateOff", stateOff.map(PrintData.shapeToNBT))
nbt.setNewTagList("stateOn", stateOn.map(PrintData.shapeToNBT))
setNewShapeSet(nbt, "stateOff", stateOff)
setNewShapeSet(nbt, "stateOn", stateOn)
nbt.setBoolean("isBeaconBase", isBeaconBase)
nbt.setByte("lightLevel", lightLevel.toByte)
nbt.setBoolean("noclipOff", noclipOff)
nbt.setBoolean("noclipOn", noclipOn)
}
// Shapes are stored in a set and sets do not have an order, that means NBT shape lists may be in any order.
// Because NBT list comparison considers order of tags in a list, and prints may have arbitrarily ordered list of shapes,
// the comparison fails and minecraft considers two identical prints different.
// One possible solution is to sort the shapes before serializing them to NBT
private def setNewShapeSet(nbt: NBTTagCompound, name: String, values: Iterable[Shape]) = {
val seq = values.toSeq.sortWith(compareShape);
nbt.setNewTagList(name, seq.map(PrintData.shapeToNBT))
}
private def compareShape(a: Shape, b: Shape): Boolean = {
import scala.math.Ordering.Implicits._
if (a.bounds.minX != b.bounds.minX) return a.bounds.minX > b.bounds.minX;
if (a.bounds.minY != b.bounds.minY) return a.bounds.minY > b.bounds.minY;
if (a.bounds.minZ != b.bounds.minZ) return a.bounds.minZ > b.bounds.minZ;
if (a.bounds.maxX != b.bounds.maxX) return a.bounds.maxX > b.bounds.maxX;
if (a.bounds.maxY != b.bounds.maxY) return a.bounds.maxY > b.bounds.maxY;
if (a.bounds.maxZ != b.bounds.maxZ) return a.bounds.maxZ > b.bounds.maxZ;
if (a.tint != b.tint) return a.tint > b.tint;
if (a.texture != b.texture) return a.texture > b.texture;
false
}
}
object PrintData {