mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 10:12:53 +00:00
Forcefully integrate a mangled DataPalette from NMS into a NBTMCA API
This commit is contained in:
parent
861e11a713
commit
d5da8e4e2b
@ -688,14 +688,4 @@ public class Chunk {
|
||||
public int sectionCount() {
|
||||
return sections.length();
|
||||
}
|
||||
|
||||
public void runLighting() {
|
||||
for (int s = 15; s >= 0; s--) {
|
||||
Section section = getSection(s);
|
||||
|
||||
if (section != null) {
|
||||
section.runLighting();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,12 +20,13 @@ package com.volmit.iris.util.nbt.mca;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.nbt.mca.palettes.DataPaletteBlock;
|
||||
import com.volmit.iris.util.nbt.tag.ByteArrayTag;
|
||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||
import com.volmit.iris.util.nbt.tag.ListTag;
|
||||
import com.volmit.iris.util.nbt.tag.LongArrayTag;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import net.minecraft.world.level.chunk.DataPaletteGlobal;
|
||||
import net.minecraft.world.level.chunk.Chunk;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -35,10 +36,8 @@ import java.util.concurrent.atomic.AtomicLongArray;
|
||||
|
||||
public class Section {
|
||||
private CompoundTag data;
|
||||
private Map<String, List<PaletteIndex>> valueIndexedPalette = new KMap<>();
|
||||
private ListTag<CompoundTag> palette;
|
||||
private DataPaletteBlock<CompoundTag> palette;
|
||||
private byte[] blockLight;
|
||||
private AtomicLongArray blockStates;
|
||||
private byte[] skyLight;
|
||||
private int dataVersion;
|
||||
|
||||
@ -53,72 +52,18 @@ public class Section {
|
||||
if (rawPalette == null) {
|
||||
return;
|
||||
}
|
||||
palette = rawPalette.asCompoundTagList();
|
||||
for (int i = 0; i < palette.size(); i++) {
|
||||
CompoundTag data = palette.get(i);
|
||||
putValueIndexedPalette(data, i);
|
||||
}
|
||||
|
||||
palette.makeAtomic();
|
||||
ByteArrayTag blockLight = sectionRoot.getByteArrayTag("BlockLight");
|
||||
palette = new DataPaletteBlock<>();
|
||||
LongArrayTag blockStates = sectionRoot.getLongArrayTag("BlockStates");
|
||||
palette.a((ListTag<CompoundTag>) rawPalette, blockStates.getValue());
|
||||
ByteArrayTag blockLight = sectionRoot.getByteArrayTag("BlockLight");
|
||||
ByteArrayTag skyLight = sectionRoot.getByteArrayTag("SkyLight");
|
||||
|
||||
if ((loadFlags & LoadFlags.BLOCK_LIGHTS) != 0) {
|
||||
this.blockLight = blockLight != null ? blockLight.getValue() : null;
|
||||
}
|
||||
if ((loadFlags & LoadFlags.BLOCK_STATES) != 0) {
|
||||
this.blockStates = blockStates != null ? new AtomicLongArray(blockStates.getValue()) : null;
|
||||
}
|
||||
if ((loadFlags & LoadFlags.SKY_LIGHT) != 0) {
|
||||
this.skyLight = skyLight != null ? skyLight.getValue() : null;
|
||||
}
|
||||
this.blockLight = blockLight != null ? blockLight.getValue() : null;
|
||||
this.skyLight = skyLight != null ? skyLight.getValue() : null;
|
||||
}
|
||||
|
||||
Section() {
|
||||
}
|
||||
|
||||
void putValueIndexedPalette(CompoundTag data, int index) {
|
||||
PaletteIndex leaf = new PaletteIndex(data, index);
|
||||
String name = data.getString("Name");
|
||||
List<PaletteIndex> leaves = valueIndexedPalette.get(name);
|
||||
if (leaves == null) {
|
||||
leaves = new ArrayList<>(1);
|
||||
leaves.add(leaf);
|
||||
valueIndexedPalette.put(name, leaves);
|
||||
} else {
|
||||
for (PaletteIndex pal : leaves) {
|
||||
if (pal.data.equals(data)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
leaves.add(leaf);
|
||||
}
|
||||
}
|
||||
|
||||
PaletteIndex getValueIndexedPalette(CompoundTag data) {
|
||||
List<PaletteIndex> leaves = valueIndexedPalette.get(data.getString("Name"));
|
||||
if (leaves == null) {
|
||||
return null;
|
||||
}
|
||||
for (PaletteIndex leaf : leaves) {
|
||||
if (leaf.data.equals(data)) {
|
||||
return leaf;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void runLighting() {
|
||||
for (int x = 1; x < 14; x++) {
|
||||
for (int z = 1; z < 14; z++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ClassCanBeRecord")
|
||||
private static class PaletteIndex {
|
||||
|
||||
@ -150,16 +95,7 @@ public class Section {
|
||||
* @return The block state data of this block.
|
||||
*/
|
||||
public synchronized CompoundTag getBlockStateAt(int blockX, int blockY, int blockZ) {
|
||||
try {
|
||||
int index = getBlockIndex(blockX, blockY, blockZ);
|
||||
int paletteIndex = getPaletteIndex(index);
|
||||
return palette.get(paletteIndex);
|
||||
} catch (Throwable ignored) {
|
||||
Iris.reportError(ignored);
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
return palette.a(blockX, blockY, blockZ);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,52 +105,17 @@ public class Section {
|
||||
* @param blockY The y-coordinate of the block in this Section
|
||||
* @param blockZ The z-coordinate of the block in this Section
|
||||
* @param state The block state to be set
|
||||
* @param cleanup When <code>true</code>, it will cleanup the palette of this section.
|
||||
* This option should only be used moderately to avoid unnecessary recalculation of the palette indices.
|
||||
* Recalculating the Palette should only be executed once right before saving the Section to file.
|
||||
*/
|
||||
public synchronized void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) {
|
||||
int paletteIndex = addToPalette(state);
|
||||
int paletteSizeBefore = palette.size();
|
||||
//power of 2 --> bits must increase, but only if the palette size changed
|
||||
//otherwise we would attempt to update all blockstates and the entire palette
|
||||
//every time an existing blockstate was added while having 2^x blockstates in the palette
|
||||
if (paletteSizeBefore != palette.size() && (paletteIndex & (paletteIndex - 1)) == 0) {
|
||||
adjustBlockStateBits(null, blockStates);
|
||||
cleanup = true;
|
||||
|
||||
if(cleanup)
|
||||
{
|
||||
palette.setBlock(blockX, blockY, blockZ, state);
|
||||
}
|
||||
|
||||
setPaletteIndex(getBlockIndex(blockX, blockY, blockZ), paletteIndex, blockStates);
|
||||
if (cleanup) {
|
||||
cleanupPaletteAndBlockStates();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the block data in the palette.
|
||||
*
|
||||
* @param blockStateIndex The index of the block in this section, ranging from 0-4095.
|
||||
* @return The index of the block data in the palette.
|
||||
*/
|
||||
public synchronized int getPaletteIndex(int blockStateIndex) {
|
||||
int bits = blockStates.length() >> 6;
|
||||
|
||||
if (dataVersion < 2527) {
|
||||
double blockStatesIndex = blockStateIndex / (4096D / blockStates.length());
|
||||
int longIndex = (int) blockStatesIndex;
|
||||
int startBit = (int) ((blockStatesIndex - Math.floor(blockStatesIndex)) * 64D);
|
||||
if (startBit + bits > 64) {
|
||||
long prev = bitRange(blockStates.get(longIndex), startBit, 64);
|
||||
long next = bitRange(blockStates.get(longIndex + 1), 0, startBit + bits - 64);
|
||||
return (int) ((next << 64 - startBit) + prev);
|
||||
} else {
|
||||
return (int) bitRange(blockStates.get(longIndex), startBit, startBit + bits);
|
||||
}
|
||||
} else {
|
||||
int indicesPerLong = (int) (64D / bits);
|
||||
int blockStatesIndex = blockStateIndex / indicesPerLong;
|
||||
int startBit = (blockStateIndex % indicesPerLong) * bits;
|
||||
return (int) bitRange(blockStates.get(blockStatesIndex), startBit, startBit + bits);
|
||||
else
|
||||
{
|
||||
palette.b(blockX, blockY, blockZ, state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,25 +147,6 @@ public class Section {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the palette of this Section.
|
||||
*
|
||||
* @return The palette of this Section.
|
||||
*/
|
||||
public synchronized ListTag<CompoundTag> getPalette() {
|
||||
return palette;
|
||||
}
|
||||
|
||||
synchronized int addToPalette(CompoundTag data) {
|
||||
PaletteIndex index;
|
||||
if ((index = getValueIndexedPalette(data)) != null) {
|
||||
return index.index;
|
||||
}
|
||||
palette.add(data);
|
||||
putValueIndexedPalette(data, palette.size() - 1);
|
||||
return palette.size() - 1;
|
||||
}
|
||||
|
||||
int getBlockIndex(int blockX, int blockY, int blockZ) {
|
||||
return (blockY & 0xF) * 256 + (blockZ & 0xF) * 16 + (blockX & 0xF);
|
||||
}
|
||||
@ -285,63 +167,8 @@ public class Section {
|
||||
* This should only be used moderately to avoid unnecessary recalculation of the palette indices.
|
||||
* Recalculating the Palette should only be executed once right before saving the Section to file.
|
||||
*/
|
||||
public synchronized void cleanupPaletteAndBlockStates() {
|
||||
Map<Integer, Integer> oldToNewMapping = cleanupPalette();
|
||||
adjustBlockStateBits(oldToNewMapping, blockStates);
|
||||
}
|
||||
public void cleanupPaletteAndBlockStates() {
|
||||
|
||||
private synchronized Map<Integer, Integer> cleanupPalette() {
|
||||
//create index - palette mapping
|
||||
Map<Integer, Integer> allIndices = new Int2IntOpenHashMap();
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
int paletteIndex = getPaletteIndex(i);
|
||||
allIndices.put(paletteIndex, paletteIndex);
|
||||
}
|
||||
//delete unused blocks from palette
|
||||
//start at index 1 because we need to keep minecraft:air
|
||||
int index = 1;
|
||||
valueIndexedPalette = new HashMap<>(valueIndexedPalette.size());
|
||||
putValueIndexedPalette(palette.get(0), 0);
|
||||
for (int i = 1; i < palette.size(); i++) {
|
||||
if (!allIndices.containsKey(index)) {
|
||||
palette.remove(i);
|
||||
i--;
|
||||
} else {
|
||||
putValueIndexedPalette(palette.get(i), i);
|
||||
allIndices.put(index, i);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return allIndices;
|
||||
}
|
||||
|
||||
synchronized void adjustBlockStateBits(Map<Integer, Integer> oldToNewMapping, AtomicLongArray blockStates) {
|
||||
//increases or decreases the amount of bits used per BlockState
|
||||
//based on the size of the palette. oldToNewMapping can be used to update indices
|
||||
//if the palette had been cleaned up before using MCAFile#cleanupPalette().
|
||||
|
||||
int newBits = 32 - Integer.numberOfLeadingZeros(palette.size() - 1);
|
||||
newBits = Math.max(newBits, 4);
|
||||
|
||||
AtomicLongArray newBlockStates;
|
||||
|
||||
if (dataVersion < 2527) {
|
||||
newBlockStates = newBits == blockStates.length() / 64 ? blockStates : new AtomicLongArray(newBits * 64);
|
||||
} else {
|
||||
int newLength = (int) Math.ceil(4096D / (64D / newBits));
|
||||
newBlockStates = newBits == blockStates.length() / 64 ? blockStates : new AtomicLongArray(newLength);
|
||||
}
|
||||
if (oldToNewMapping != null) {
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
setPaletteIndex(i, oldToNewMapping.get(getPaletteIndex(i)), newBlockStates);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
setPaletteIndex(i, getPaletteIndex(i), newBlockStates);
|
||||
}
|
||||
}
|
||||
this.blockStates = newBlockStates;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -364,29 +191,6 @@ public class Section {
|
||||
this.blockLight = blockLight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The indices of the block states of this Section.
|
||||
*/
|
||||
public synchronized AtomicLongArray getBlockStates() {
|
||||
return blockStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block state indices to a custom value.
|
||||
*
|
||||
* @param blockStates The block state indices.
|
||||
* @throws NullPointerException If <code>blockStates</code> is <code>null</code>
|
||||
* @throws IllegalArgumentException When <code>blockStates</code>' length is < 256 or > 4096 and is not a multiple of 64
|
||||
*/
|
||||
public void setBlockStates(AtomicLongArray blockStates) {
|
||||
if (blockStates == null) {
|
||||
throw new NullPointerException("BlockStates cannot be null");
|
||||
} else if (blockStates.length() % 64 != 0 || blockStates.length() < 256 || blockStates.length() > 4096) {
|
||||
throw new IllegalArgumentException("BlockStates must have a length > 255 and < 4097 and must be divisible by 64");
|
||||
}
|
||||
this.blockStates = blockStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The sky light values of this Section
|
||||
*/
|
||||
@ -414,11 +218,7 @@ public class Section {
|
||||
*/
|
||||
public static Section newSection() {
|
||||
Section s = new Section();
|
||||
s.blockStates = new AtomicLongArray(256);
|
||||
s.palette = new ListTag<>(CompoundTag.class);
|
||||
CompoundTag air = new CompoundTag();
|
||||
air.putString("Name", "minecraft:air");
|
||||
s.palette.add(air);
|
||||
s.palette = new DataPaletteBlock<>();
|
||||
s.data = new CompoundTag();
|
||||
return s;
|
||||
}
|
||||
@ -434,20 +234,12 @@ public class Section {
|
||||
public synchronized CompoundTag updateHandle(int y) {
|
||||
data.putByte("Y", (byte) y);
|
||||
if (palette != null) {
|
||||
data.put("Palette", palette);
|
||||
data.put("Palette", palette.getK().getPalette());
|
||||
data.putLongArray("BlockStates", palette.getC().a());
|
||||
}
|
||||
if (blockLight != null) {
|
||||
data.putByteArray("BlockLight", blockLight);
|
||||
}
|
||||
if (blockStates != null) {
|
||||
long[] c = new long[blockStates.length()];
|
||||
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
c[i] = blockStates.get(i);
|
||||
}
|
||||
|
||||
data.putLongArray("BlockStates", c);
|
||||
}
|
||||
if (skyLight != null) {
|
||||
data.putByteArray("SkyLight", skyLight);
|
||||
}
|
||||
|
@ -35,4 +35,6 @@ public interface DataPalette<T> {
|
||||
int b();
|
||||
|
||||
void a(ListTag<CompoundTag> t);
|
||||
|
||||
ListTag<CompoundTag> getPalette();
|
||||
}
|
||||
|
@ -19,16 +19,20 @@
|
||||
package com.volmit.iris.util.nbt.mca.palettes;
|
||||
|
||||
import com.volmit.iris.util.math.MathHelper;
|
||||
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||
import com.volmit.iris.util.nbt.tag.ListTag;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.network.PacketDataSerializer;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Getter
|
||||
public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
|
||||
private static final int d = 4096;
|
||||
public static final int a = 9;
|
||||
@ -41,16 +45,26 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
|
||||
private final Function<CompoundTag, T> h;
|
||||
private final Function<T, CompoundTag> i;
|
||||
private final T j;
|
||||
private static final RegistryBlockID<CompoundTag> registry = new RegistryBlockID<>();
|
||||
private static final CompoundTag air = NBTWorld.getCompound(Material.AIR.createBlockData());
|
||||
protected DataBits c;
|
||||
private DataPalette<T> k;
|
||||
private int l;
|
||||
private int bits;
|
||||
private final Semaphore m = new Semaphore(1);
|
||||
|
||||
public void b() {
|
||||
this.m.release();
|
||||
}
|
||||
|
||||
public DataPaletteBlock(DataPalette<T> var0, RegistryBlockID<T> var1, Function<CompoundTag, T> var2, Function<T, CompoundTag> var3, T var4) {
|
||||
public DataPaletteBlock() {
|
||||
this(null, (RegistryBlockID<T>) registry, (i) -> (T) i, (i) -> (CompoundTag) i, (T) air);
|
||||
}
|
||||
|
||||
public DataPaletteBlock(DataPalette<T> var0,
|
||||
RegistryBlockID<T> var1,
|
||||
Function<CompoundTag, T> var2,
|
||||
Function<T, CompoundTag> var3,
|
||||
T var4) {
|
||||
this.e = var0;
|
||||
this.g = var1;
|
||||
this.h = var2;
|
||||
@ -64,20 +78,20 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
|
||||
}
|
||||
|
||||
private void b(int var0) {
|
||||
if (var0 != this.l) {
|
||||
this.l = var0;
|
||||
if (this.l <= 4) {
|
||||
this.l = 4;
|
||||
this.k = new DataPaletteLinear<T>(this.g, this.l, this, this.h);
|
||||
} else if (this.l < 9) {
|
||||
this.k = new DataPaletteHash<T>(this.g, this.l, this, this.h, this.i);
|
||||
if (var0 != this.bits) {
|
||||
this.bits = var0;
|
||||
if (this.bits <= 4) {
|
||||
this.bits = 4;
|
||||
this.k = new DataPaletteLinear<T>(this.g, this.bits, this, this.h);
|
||||
} else if (this.bits < 9) {
|
||||
this.k = new DataPaletteHash<T>(this.g, this.bits, this, this.h, this.i);
|
||||
} else {
|
||||
this.k = this.e;
|
||||
this.l = MathHelper.e(this.g.a());
|
||||
this.bits = MathHelper.e(this.g.a());
|
||||
}
|
||||
|
||||
this.k.a(this.j);
|
||||
this.c = new DataBits(this.l, 4096);
|
||||
this.c = new DataBits(this.bits, 4096);
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,27 +154,27 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
|
||||
return var1 == null ? this.j : var1;
|
||||
}
|
||||
|
||||
public void a(ListTag<CompoundTag> var0, long[] var1) {
|
||||
public void a(ListTag<CompoundTag> palettedata, long[] databits) {
|
||||
try {
|
||||
int var2 = Math.max(4, MathHelper.e(var0.size()));
|
||||
if (var2 != this.l) {
|
||||
int var2 = Math.max(4, MathHelper.e(palettedata.size()));
|
||||
if (var2 != this.bits) {
|
||||
this.b(var2);
|
||||
}
|
||||
|
||||
this.k.a(var0);
|
||||
int var3 = var1.length * 64 / 4096;
|
||||
this.k.a(palettedata);
|
||||
int var3 = databits.length * 64 / 4096;
|
||||
if (this.k == this.e) {
|
||||
DataPalette<T> var4 = new DataPaletteHash(this.g, var2, this.f, this.h, this.i);
|
||||
var4.a(var0);
|
||||
DataBits var5 = new DataBits(var2, 4096, var1);
|
||||
DataPalette<T> var4 = new DataPaletteHash<T>(this.g, var2, this.f, this.h, this.i);
|
||||
var4.a(palettedata);
|
||||
DataBits var5 = new DataBits(var2, 4096, databits);
|
||||
|
||||
for (int var6 = 0; var6 < 4096; ++var6) {
|
||||
this.c.b(var6, this.e.a(var4.a(var5.a(var6))));
|
||||
}
|
||||
} else if (var3 == this.l) {
|
||||
System.arraycopy(var1, 0, this.c.a(), 0, var1.length);
|
||||
} else if (var3 == this.bits) {
|
||||
System.arraycopy(databits, 0, this.c.a(), 0, databits.length);
|
||||
} else {
|
||||
DataBits var4 = new DataBits(var3, 4096, var1);
|
||||
DataBits var4 = new DataBits(var3, 4096, databits);
|
||||
|
||||
for (int var5 = 0; var5 < 4096; ++var5) {
|
||||
this.c.b(var5, var4.a(var5));
|
||||
@ -169,12 +183,11 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
|
||||
} finally {
|
||||
this.b();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void a(CompoundTag var0, String var1, String var2) {
|
||||
try {
|
||||
DataPaletteHash<T> var3 = new DataPaletteHash(this.g, this.l, this.f, this.h, this.i);
|
||||
DataPaletteHash<T> var3 = new DataPaletteHash(this.g, this.bits, this.f, this.h, this.i);
|
||||
T var4 = this.j;
|
||||
int var5 = var3.a(this.j);
|
||||
int[] var6 = new int[4096];
|
||||
@ -215,12 +228,8 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
|
||||
|
||||
public void a(DataPaletteBlock.a<T> var0) {
|
||||
Int2IntMap var1 = new Int2IntOpenHashMap();
|
||||
this.c.a((var1x) -> {
|
||||
var1.put(var1x, var1.get(var1x) + 1);
|
||||
});
|
||||
var1.int2IntEntrySet().forEach((var1x) -> {
|
||||
var0.accept(this.k.a(var1x.getIntKey()), var1x.getIntValue());
|
||||
});
|
||||
this.c.a((var1x) -> var1.put(var1x, var1.get(var1x) + 1));
|
||||
var1.int2IntEntrySet().forEach((var1x) -> var0.accept(this.k.a(var1x.getIntKey()), var1x.getIntValue()));
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
|
@ -110,6 +110,11 @@ public class DataPaletteHash<T> implements DataPalette<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListTag<CompoundTag> getPalette() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void b(ListTag<CompoundTag> var0) {
|
||||
for (int var1 = 0; var1 < this.b(); ++var1) {
|
||||
var0.add(this.e.apply(this.b.fromId(var1)));
|
||||
|
@ -112,4 +112,15 @@ public class DataPaletteLinear<T> implements DataPalette<T> {
|
||||
|
||||
this.f = var0.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListTag<CompoundTag> getPalette() {
|
||||
ListTag<CompoundTag> c = (ListTag<CompoundTag>) ListTag.createUnchecked(CompoundTag.class);
|
||||
for(T i : b)
|
||||
{
|
||||
c.add((CompoundTag) i);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user