mirror of
https://github.com/Minestom/Minestom.git
synced 2025-03-02 11:21:15 +01:00
Added support for item CustomModelData
This commit is contained in:
parent
3e9194b5ec
commit
433703c0af
@ -35,6 +35,7 @@ public class ItemStack implements DataContainer {
|
||||
private Set<PotionType> potionTypes;
|
||||
|
||||
private int hideFlag;
|
||||
private int customModelData;
|
||||
|
||||
private StackingRule stackingRule;
|
||||
private Data data;
|
||||
@ -388,6 +389,24 @@ public class ItemStack implements DataContainer {
|
||||
this.hideFlag = hideFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item custom model data
|
||||
*
|
||||
* @return the item custom model data
|
||||
*/
|
||||
public int getCustomModelData() {
|
||||
return customModelData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the item custom model data
|
||||
*
|
||||
* @param customModelData the new item custom data model
|
||||
*/
|
||||
public void setCustomModelData(int customModelData) {
|
||||
this.customModelData = customModelData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add flags to the item
|
||||
*
|
||||
@ -464,7 +483,7 @@ public class ItemStack implements DataContainer {
|
||||
public boolean hasNbtTag() {
|
||||
return hasDisplayName() || hasLore() || isUnbreakable() ||
|
||||
!enchantmentMap.isEmpty() || !storedEnchantmentMap.isEmpty() ||
|
||||
!attributes.isEmpty() || !potionTypes.isEmpty();
|
||||
!attributes.isEmpty() || !potionTypes.isEmpty() || customModelData != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,6 +88,118 @@ public class Utils {
|
||||
} while (value != 0);
|
||||
}
|
||||
|
||||
private static final int[] MAGIC = {
|
||||
-1, -1, 0, Integer.MIN_VALUE, 0, 0, 1431655765, 1431655765, 0, Integer.MIN_VALUE,
|
||||
0, 1, 858993459, 858993459, 0, 715827882, 715827882, 0, 613566756, 613566756,
|
||||
0, Integer.MIN_VALUE, 0, 2, 477218588, 477218588, 0, 429496729, 429496729, 0,
|
||||
390451572, 390451572, 0, 357913941, 357913941, 0, 330382099, 330382099, 0, 306783378,
|
||||
306783378, 0, 286331153, 286331153, 0, Integer.MIN_VALUE, 0, 3, 252645135, 252645135,
|
||||
0, 238609294, 238609294, 0, 226050910, 226050910, 0, 214748364, 214748364, 0,
|
||||
204522252, 204522252, 0, 195225786, 195225786, 0, 186737708, 186737708, 0, 178956970,
|
||||
178956970, 0, 171798691, 171798691, 0, 165191049, 165191049, 0, 159072862, 159072862,
|
||||
0, 153391689, 153391689, 0, 148102320, 148102320, 0, 143165576, 143165576, 0,
|
||||
138547332, 138547332, 0, Integer.MIN_VALUE, 0, 4, 130150524, 130150524, 0, 126322567,
|
||||
126322567, 0, 122713351, 122713351, 0, 119304647, 119304647, 0, 116080197, 116080197,
|
||||
0, 113025455, 113025455, 0, 110127366, 110127366, 0, 107374182, 107374182, 0,
|
||||
104755299, 104755299, 0, 102261126, 102261126, 0, 99882960, 99882960, 0, 97612893,
|
||||
97612893, 0, 95443717, 95443717, 0, 93368854, 93368854, 0, 91382282, 91382282,
|
||||
0, 89478485, 89478485, 0, 87652393, 87652393, 0, 85899345, 85899345, 0,
|
||||
84215045, 84215045, 0, 82595524, 82595524, 0, 81037118, 81037118, 0, 79536431,
|
||||
79536431, 0, 78090314, 78090314, 0, 76695844, 76695844, 0, 75350303, 75350303,
|
||||
0, 74051160, 74051160, 0, 72796055, 72796055, 0, 71582788, 71582788, 0,
|
||||
70409299, 70409299, 0, 69273666, 69273666, 0, 68174084, 68174084, 0, Integer.MIN_VALUE,
|
||||
0, 5};
|
||||
|
||||
private static void writeEnchant(NbtWriter writer, String listName, Map<Enchantment, Short> enchantmentMap) {
|
||||
writer.writeList(listName, NBT.NBT_COMPOUND, enchantmentMap.size(), () -> {
|
||||
for (Map.Entry<Enchantment, Short> entry : enchantmentMap.entrySet()) {
|
||||
Enchantment enchantment = entry.getKey();
|
||||
short level = entry.getValue();
|
||||
|
||||
writer.writeShort("lvl", level);
|
||||
|
||||
writer.writeString("id", "minecraft:" + enchantment.name().toLowerCase());
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static ItemStack readItemStack(PacketReader reader) {
|
||||
boolean present = reader.readBoolean();
|
||||
|
||||
if (!present) {
|
||||
return ItemStack.getAirItem();
|
||||
}
|
||||
|
||||
int id = reader.readVarInt();
|
||||
if (id == -1) {
|
||||
// Drop mode
|
||||
return ItemStack.getAirItem();
|
||||
}
|
||||
|
||||
byte count = reader.readByte();
|
||||
|
||||
ItemStack item = new ItemStack((short) id, count);
|
||||
|
||||
byte nbt = reader.readByte(); // Should be compound start (0x0A) or 0 if there isn't NBT data
|
||||
|
||||
if (nbt == 0x00) {
|
||||
return item;
|
||||
} else if (nbt == 0x0A) {
|
||||
reader.readShort(); // Ignored, should be empty (main compound name)
|
||||
NbtReaderUtils.readItemStackNBT(reader, item);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static void writeBlocks(BufferWrapper buffer, short[] blocksId, int bitsPerEntry) {
|
||||
short count = 0;
|
||||
for (short id : blocksId)
|
||||
if (id != 0)
|
||||
count++;
|
||||
|
||||
buffer.putShort(count);
|
||||
buffer.putByte((byte) bitsPerEntry);
|
||||
int[] blocksData = new int[Chunk.CHUNK_SIZE_X * Chunk.CHUNK_SECTION_SIZE * Chunk.CHUNK_SIZE_Z];
|
||||
for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) {
|
||||
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
|
||||
for (int z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
|
||||
int sectionIndex = (((y * 16) + x) * 16) + z;
|
||||
int index = y << 8 | z << 4 | x;
|
||||
blocksData[index] = blocksId[sectionIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
long[] data = encodeBlocks(blocksData, bitsPerEntry);
|
||||
buffer.putVarInt(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
buffer.putLong(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*public static long[] encodeBlocks(int[] blocks, int bitsPerEntry) {
|
||||
long maxEntryValue = (1L << bitsPerEntry) - 1;
|
||||
|
||||
int length = (int) Math.ceil(blocks.length * bitsPerEntry / 64.0);
|
||||
long[] data = new long[length];
|
||||
|
||||
for (int index = 0; index < blocks.length; index++) {
|
||||
int value = blocks[index];
|
||||
int bitIndex = index * bitsPerEntry;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((index + 1) * bitsPerEntry - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex;
|
||||
if (startIndex != endIndex) {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}*/
|
||||
|
||||
public static void writeItemStack(PacketWriter packet, ItemStack itemStack) {
|
||||
if (itemStack == null || itemStack.isAir()) {
|
||||
packet.writeBoolean(false);
|
||||
@ -206,122 +318,20 @@ public class Utils {
|
||||
writer.writeInt("HideFlags", hideFlag);
|
||||
}
|
||||
}
|
||||
// End hide flags
|
||||
|
||||
// Start custom model data
|
||||
{
|
||||
int customModelData = itemStack.getCustomModelData();
|
||||
if (customModelData != 0) {
|
||||
writer.writeInt("CustomModelData", customModelData);
|
||||
}
|
||||
}
|
||||
// End custom model data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeEnchant(NbtWriter writer, String listName, Map<Enchantment, Short> enchantmentMap) {
|
||||
writer.writeList(listName, NBT.NBT_COMPOUND, enchantmentMap.size(), () -> {
|
||||
for (Map.Entry<Enchantment, Short> entry : enchantmentMap.entrySet()) {
|
||||
Enchantment enchantment = entry.getKey();
|
||||
short level = entry.getValue();
|
||||
|
||||
writer.writeShort("lvl", level);
|
||||
|
||||
writer.writeString("id", "minecraft:" + enchantment.name().toLowerCase());
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static ItemStack readItemStack(PacketReader reader) {
|
||||
boolean present = reader.readBoolean();
|
||||
|
||||
if (!present) {
|
||||
return ItemStack.getAirItem();
|
||||
}
|
||||
|
||||
int id = reader.readVarInt();
|
||||
if (id == -1) {
|
||||
// Drop mode
|
||||
return ItemStack.getAirItem();
|
||||
}
|
||||
|
||||
byte count = reader.readByte();
|
||||
|
||||
ItemStack item = new ItemStack((short) id, count);
|
||||
|
||||
byte nbt = reader.readByte(); // Should be compound start (0x0A) or 0 if there isn't NBT data
|
||||
|
||||
if (nbt == 0x00) {
|
||||
return item;
|
||||
} else if (nbt == 0x0A) {
|
||||
reader.readShort(); // Ignored, should be empty (main compound name)
|
||||
NbtReaderUtils.readItemStackNBT(reader, item);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static void writeBlocks(BufferWrapper buffer, short[] blocksId, int bitsPerEntry) {
|
||||
short count = 0;
|
||||
for (short id : blocksId)
|
||||
if (id != 0)
|
||||
count++;
|
||||
|
||||
buffer.putShort(count);
|
||||
buffer.putByte((byte) bitsPerEntry);
|
||||
int[] blocksData = new int[Chunk.CHUNK_SIZE_X * Chunk.CHUNK_SECTION_SIZE * Chunk.CHUNK_SIZE_Z];
|
||||
for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) {
|
||||
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
|
||||
for (int z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
|
||||
int sectionIndex = (((y * 16) + x) * 16) + z;
|
||||
int index = y << 8 | z << 4 | x;
|
||||
blocksData[index] = blocksId[sectionIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
long[] data = encodeBlocks(blocksData, bitsPerEntry);
|
||||
buffer.putVarInt(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
buffer.putLong(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*public static long[] encodeBlocks(int[] blocks, int bitsPerEntry) {
|
||||
long maxEntryValue = (1L << bitsPerEntry) - 1;
|
||||
|
||||
int length = (int) Math.ceil(blocks.length * bitsPerEntry / 64.0);
|
||||
long[] data = new long[length];
|
||||
|
||||
for (int index = 0; index < blocks.length; index++) {
|
||||
int value = blocks[index];
|
||||
int bitIndex = index * bitsPerEntry;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((index + 1) * bitsPerEntry - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex;
|
||||
if (startIndex != endIndex) {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}*/
|
||||
|
||||
private static final int[] MAGIC = {
|
||||
-1, -1, 0, Integer.MIN_VALUE, 0, 0, 1431655765, 1431655765, 0, Integer.MIN_VALUE,
|
||||
0, 1, 858993459, 858993459, 0, 715827882, 715827882, 0, 613566756, 613566756,
|
||||
0, Integer.MIN_VALUE, 0, 2, 477218588, 477218588, 0, 429496729, 429496729, 0,
|
||||
390451572, 390451572, 0, 357913941, 357913941, 0, 330382099, 330382099, 0, 306783378,
|
||||
306783378, 0, 286331153, 286331153, 0, Integer.MIN_VALUE, 0, 3, 252645135, 252645135,
|
||||
0, 238609294, 238609294, 0, 226050910, 226050910, 0, 214748364, 214748364, 0,
|
||||
204522252, 204522252, 0, 195225786, 195225786, 0, 186737708, 186737708, 0, 178956970,
|
||||
178956970, 0, 171798691, 171798691, 0, 165191049, 165191049, 0, 159072862, 159072862,
|
||||
0, 153391689, 153391689, 0, 148102320, 148102320, 0, 143165576, 143165576, 0,
|
||||
138547332, 138547332, 0, Integer.MIN_VALUE, 0, 4, 130150524, 130150524, 0, 126322567,
|
||||
126322567, 0, 122713351, 122713351, 0, 119304647, 119304647, 0, 116080197, 116080197,
|
||||
0, 113025455, 113025455, 0, 110127366, 110127366, 0, 107374182, 107374182, 0,
|
||||
104755299, 104755299, 0, 102261126, 102261126, 0, 99882960, 99882960, 0, 97612893,
|
||||
97612893, 0, 95443717, 95443717, 0, 93368854, 93368854, 0, 91382282, 91382282,
|
||||
0, 89478485, 89478485, 0, 87652393, 87652393, 0, 85899345, 85899345, 0,
|
||||
84215045, 84215045, 0, 82595524, 82595524, 0, 81037118, 81037118, 0, 79536431,
|
||||
79536431, 0, 78090314, 78090314, 0, 76695844, 76695844, 0, 75350303, 75350303,
|
||||
0, 74051160, 74051160, 0, 72796055, 72796055, 0, 71582788, 71582788, 0,
|
||||
70409299, 70409299, 0, 69273666, 69273666, 0, 68174084, 68174084, 0, Integer.MIN_VALUE,
|
||||
0, 5 };
|
||||
|
||||
public static long[] encodeBlocks(int[] blocks, int bitsPerEntry) {
|
||||
long maxEntryValue = (1L << bitsPerEntry) - 1;
|
||||
char valuesPerLong = (char) (64 / bitsPerEntry);
|
||||
|
Loading…
Reference in New Issue
Block a user