Implement support for 1.16+ chunks
This commit is contained in:
parent
62f382313d
commit
24c4fda89d
|
@ -115,7 +115,7 @@ public class Key implements Keyed {
|
|||
/**
|
||||
* Using our own function instead of {@link String#intern()} since the ConcurrentHashMap is much faster.
|
||||
*/
|
||||
private static String intern(String string) {
|
||||
protected static String intern(String string) {
|
||||
String interned = STRING_INTERN_POOL.putIfAbsent(string, string);
|
||||
return interned != null ? interned : string;
|
||||
}
|
||||
|
|
|
@ -197,8 +197,8 @@ public class BlockState extends Key {
|
|||
private final String key, value;
|
||||
|
||||
public Property(String key, String value) {
|
||||
this.key = key.intern();
|
||||
this.value = value.intern();
|
||||
this.key = intern(key);
|
||||
this.value = intern(value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("StringEquality")
|
||||
|
|
|
@ -18,7 +18,10 @@ public class ChunkLoader {
|
|||
|
||||
// sorted list of chunk-versions, loaders at the start of the list are preferred over loaders at the end
|
||||
private static final List<ChunkVersionLoader<?>> CHUNK_VERSION_LOADERS = List.of(
|
||||
new ChunkVersionLoader<>(Chunk_1_18.Data.class, Chunk_1_18::new, 0)
|
||||
//new ChunkVersionLoader<>(Chunk_1_13.Data.class, Chunk_1_13::new, 0),
|
||||
//new ChunkVersionLoader<>(Chunk_1_15.Data.class, Chunk_1_15::new, 2200),
|
||||
new ChunkVersionLoader<>(Chunk_1_16.Data.class, Chunk_1_16::new, 2500),
|
||||
new ChunkVersionLoader<>(Chunk_1_18.Data.class, Chunk_1_18::new, 2844)
|
||||
);
|
||||
|
||||
private ChunkVersionLoader<?> lastUsedLoader = CHUNK_VERSION_LOADERS.get(0);
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
package de.bluecolored.bluemap.core.world.mca.chunk;
|
||||
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
import de.bluecolored.bluemap.core.util.Key;
|
||||
import de.bluecolored.bluemap.core.world.Biome;
|
||||
import de.bluecolored.bluemap.core.world.BlockState;
|
||||
import de.bluecolored.bluemap.core.world.DimensionType;
|
||||
import de.bluecolored.bluemap.core.world.LightData;
|
||||
import de.bluecolored.bluemap.core.world.mca.MCAUtil;
|
||||
import de.bluecolored.bluemap.core.world.mca.PackedIntArrayAccess;
|
||||
import de.bluecolored.bluemap.core.world.mca.region.MCARegion;
|
||||
import de.bluecolored.bluenbt.NBTName;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class Chunk_1_16 extends MCAChunk {
|
||||
|
||||
private static final Level EMPTY_LEVEL = new Level();
|
||||
private static final HeightmapsData EMPTY_HEIGHTMAPS_DATA = new HeightmapsData();
|
||||
|
||||
private static final Key STATUS_EMPTY = new Key("minecraft", "empty");
|
||||
private static final Key STATUS_FULL = new Key("minecraft", "full");
|
||||
|
||||
private final boolean generated;
|
||||
private final boolean hasLightData;
|
||||
private final long inhabitedTime;
|
||||
|
||||
private final int skyLight;
|
||||
|
||||
private final boolean hasWorldSurfaceHeights;
|
||||
private final PackedIntArrayAccess worldSurfaceHeights;
|
||||
private final boolean hasOceanFloorHeights;
|
||||
private final PackedIntArrayAccess oceanFloorHeights;
|
||||
|
||||
private final Section[] sections;
|
||||
private final int sectionMin, sectionMax;
|
||||
|
||||
private final int[] biomes;
|
||||
|
||||
public Chunk_1_16(MCARegion region, Data data) {
|
||||
super(region, data);
|
||||
|
||||
Level level = data.level;
|
||||
|
||||
this.generated = !STATUS_EMPTY.equals(level.status);
|
||||
this.hasLightData = STATUS_FULL.equals(level.status);
|
||||
this.inhabitedTime = level.inhabitedTime;
|
||||
|
||||
DimensionType dimensionType = getRegion().getWorld().getDimensionType();
|
||||
this.skyLight = dimensionType.hasSkylight() ? 16 : 0;
|
||||
|
||||
int worldHeight = dimensionType.getHeight();
|
||||
int bitsPerHeightmapElement = MCAUtil.ceilLog2(worldHeight + 1);
|
||||
|
||||
this.worldSurfaceHeights = new PackedIntArrayAccess(bitsPerHeightmapElement, level.heightmaps.worldSurface);
|
||||
this.oceanFloorHeights = new PackedIntArrayAccess(bitsPerHeightmapElement, level.heightmaps.oceanFloor);
|
||||
|
||||
this.hasWorldSurfaceHeights = this.worldSurfaceHeights.isCorrectSize(VALUES_PER_HEIGHTMAP);
|
||||
this.hasOceanFloorHeights = this.oceanFloorHeights.isCorrectSize(VALUES_PER_HEIGHTMAP);
|
||||
|
||||
this.biomes = level.biomes;
|
||||
|
||||
SectionData[] sectionsData = level.sections;
|
||||
if (sectionsData != null && sectionsData.length > 0) {
|
||||
int min = Integer.MAX_VALUE;
|
||||
int max = Integer.MIN_VALUE;
|
||||
|
||||
// find section min/max y
|
||||
for (SectionData sectionData : sectionsData) {
|
||||
int y = sectionData.getY();
|
||||
if (min > y) min = y;
|
||||
if (max < y) max = y;
|
||||
}
|
||||
|
||||
// load sections into ordered array
|
||||
this.sections = new Section[1 + max - min];
|
||||
for (SectionData sectionData : sectionsData) {
|
||||
Section section = new Section(sectionData);
|
||||
int y = section.getSectionY();
|
||||
|
||||
if (min > y) min = y;
|
||||
if (max < y) max = y;
|
||||
|
||||
this.sections[section.sectionY - min] = section;
|
||||
}
|
||||
|
||||
this.sectionMin = min;
|
||||
this.sectionMax = max;
|
||||
} else {
|
||||
this.sections = new Section[0];
|
||||
this.sectionMin = 0;
|
||||
this.sectionMax = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGenerated() {
|
||||
return generated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLightData() {
|
||||
return hasLightData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInhabitedTime() {
|
||||
return inhabitedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
Section section = getSection(y >> 4);
|
||||
if (section == null) return BlockState.AIR;
|
||||
|
||||
return section.getBlockState(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBiome(int x, int y, int z) {
|
||||
if (this.biomes.length < 16) return Biome.DEFAULT.getFormatted();
|
||||
|
||||
int biomeIntIndex = (y & 0b1100) << 2 | z & 0b1100 | (x & 0b1100) >> 2;
|
||||
|
||||
// shift y up/down if not in range
|
||||
if (biomeIntIndex >= biomes.length) biomeIntIndex -= (((biomeIntIndex - biomes.length) >> 4) + 1) * 16;
|
||||
if (biomeIntIndex < 0) biomeIntIndex -= (biomeIntIndex >> 4) * 16;
|
||||
|
||||
return LegacyBiomes.idFor(biomes[biomeIntIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LightData getLightData(int x, int y, int z, LightData target) {
|
||||
if (!hasLightData) return target.set(skyLight, 0);
|
||||
|
||||
int sectionY = y >> 4;
|
||||
Section section = getSection(sectionY);
|
||||
if (section == null) return (sectionY < sectionMin) ? target.set(0, 0) : target.set(skyLight, 0);
|
||||
|
||||
return section.getLightData(x, y, z, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinY(int x, int z) {
|
||||
return sectionMin * 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY(int x, int z) {
|
||||
return sectionMax * 16 + 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasWorldSurfaceHeights() {
|
||||
return hasWorldSurfaceHeights;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWorldSurfaceY(int x, int z) {
|
||||
return worldSurfaceHeights.get((z & 0xF) << 4 | x & 0xF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOceanFloorHeights() {
|
||||
return hasOceanFloorHeights;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOceanFloorY(int x, int z) {
|
||||
return oceanFloorHeights.get((z & 0xF) << 4 | x & 0xF);
|
||||
}
|
||||
|
||||
private @Nullable Section getSection(int y) {
|
||||
y -= sectionMin;
|
||||
if (y < 0 || y >= this.sections.length) return null;
|
||||
return this.sections[y];
|
||||
}
|
||||
|
||||
protected static class Section {
|
||||
|
||||
private final int sectionY;
|
||||
private final BlockState[] blockPalette;
|
||||
private final PackedIntArrayAccess blocks;
|
||||
private final byte[] blockLight;
|
||||
private final byte[] skyLight;
|
||||
|
||||
public Section(SectionData sectionData) {
|
||||
this.sectionY = sectionData.y;
|
||||
|
||||
this.blockPalette = sectionData.palette;
|
||||
this.blocks = new PackedIntArrayAccess(sectionData.blockStates, BLOCKS_PER_SECTION);
|
||||
|
||||
this.blockLight = sectionData.getBlockLight();
|
||||
this.skyLight = sectionData.getSkyLight();
|
||||
}
|
||||
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
if (blockPalette.length == 1) return blockPalette[0];
|
||||
if (blockPalette.length == 0) return BlockState.AIR;
|
||||
|
||||
int id = blocks.get((y & 0xF) << 8 | (z & 0xF) << 4 | x & 0xF);
|
||||
if (id >= blockPalette.length) {
|
||||
Logger.global.noFloodWarning("palette-warning", "Got block-palette id " + id + " but palette has size of " + blockPalette.length + "! (Future occasions of this error will not be logged)");
|
||||
return BlockState.MISSING;
|
||||
}
|
||||
|
||||
return blockPalette[id];
|
||||
}
|
||||
|
||||
public LightData getLightData(int x, int y, int z, LightData target) {
|
||||
if (blockLight.length == 0 && skyLight.length == 0) return target.set(0, 0);
|
||||
|
||||
int blockByteIndex = (y & 0xF) << 8 | (z & 0xF) << 4 | x & 0xF;
|
||||
int blockHalfByteIndex = blockByteIndex >> 1; // blockByteIndex / 2
|
||||
boolean largeHalf = (blockByteIndex & 0x1) != 0; // (blockByteIndex % 2) == 0
|
||||
|
||||
return target.set(
|
||||
this.skyLight.length > blockHalfByteIndex ? MCAUtil.getByteHalf(this.skyLight[blockHalfByteIndex], largeHalf) : 0,
|
||||
this.blockLight.length > blockHalfByteIndex ? MCAUtil.getByteHalf(this.blockLight[blockHalfByteIndex], largeHalf) : 0
|
||||
);
|
||||
}
|
||||
|
||||
public int getSectionY() {
|
||||
return sectionY;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Getter
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public static class Data extends MCAChunk.Data {
|
||||
private Level level = EMPTY_LEVEL;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public static class Level {
|
||||
private Key status = STATUS_EMPTY;
|
||||
private long inhabitedTime = 0;
|
||||
private HeightmapsData heightmaps = EMPTY_HEIGHTMAPS_DATA;
|
||||
private SectionData @Nullable [] sections = null;
|
||||
private int[] biomes = EMPTY_INT_ARRAY;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
protected static class HeightmapsData {
|
||||
@NBTName("WORLD_SURFACE") private long[] worldSurface = EMPTY_LONG_ARRAY;
|
||||
@NBTName("OCEAN_FLOOR") private long[] oceanFloor = EMPTY_LONG_ARRAY;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
protected static class SectionData {
|
||||
private int y = 0;
|
||||
private byte[] blockLight = EMPTY_BYTE_ARRAY;
|
||||
private byte[] skyLight = EMPTY_BYTE_ARRAY;
|
||||
private BlockState[] palette = EMPTY_BLOCKSTATE_ARRAY;
|
||||
private long[] blockStates = EMPTY_LONG_ARRAY;
|
||||
}
|
||||
|
||||
}
|
|
@ -51,13 +51,13 @@ public class Chunk_1_18 extends MCAChunk {
|
|||
int worldHeight = dimensionType.getHeight();
|
||||
int bitsPerHeightmapElement = MCAUtil.ceilLog2(worldHeight + 1);
|
||||
|
||||
this.worldSurfaceHeights = new PackedIntArrayAccess(bitsPerHeightmapElement, data.getHeightmaps().getWorldSurface());
|
||||
this.oceanFloorHeights = new PackedIntArrayAccess(bitsPerHeightmapElement, data.getHeightmaps().getOceanFloor());
|
||||
this.worldSurfaceHeights = new PackedIntArrayAccess(bitsPerHeightmapElement, data.heightmaps.worldSurface);
|
||||
this.oceanFloorHeights = new PackedIntArrayAccess(bitsPerHeightmapElement, data.heightmaps.oceanFloor);
|
||||
|
||||
this.hasWorldSurfaceHeights = this.worldSurfaceHeights.isCorrectSize(VALUES_PER_HEIGHTMAP);
|
||||
this.hasOceanFloorHeights = this.oceanFloorHeights.isCorrectSize(VALUES_PER_HEIGHTMAP);
|
||||
|
||||
SectionData[] sectionsData = data.getSections();
|
||||
SectionData[] sectionsData = data.sections;
|
||||
if (sectionsData != null && sectionsData.length > 0) {
|
||||
int min = Integer.MAX_VALUE;
|
||||
int max = Integer.MIN_VALUE;
|
||||
|
@ -162,7 +162,7 @@ public class Chunk_1_18 extends MCAChunk {
|
|||
return oceanFloorHeights.get((z & 0xF) << 4 | x & 0xF) + worldMinY;
|
||||
}
|
||||
|
||||
private Section getSection(int y) {
|
||||
private @Nullable Section getSection(int y) {
|
||||
y -= sectionMin;
|
||||
if (y < 0 || y >= this.sections.length) return null;
|
||||
return this.sections[y];
|
||||
|
@ -179,16 +179,16 @@ public class Chunk_1_18 extends MCAChunk {
|
|||
private final byte[] skyLight;
|
||||
|
||||
public Section(SectionData sectionData) {
|
||||
this.sectionY = sectionData.getY();
|
||||
this.sectionY = sectionData.y;
|
||||
|
||||
this.blockPalette = sectionData.getBlockStates().getPalette();
|
||||
this.biomePalette = sectionData.getBiomes().getPalette();
|
||||
this.blockPalette = sectionData.blockStates.palette;
|
||||
this.biomePalette = sectionData.biomes.palette;
|
||||
|
||||
this.blocks = new PackedIntArrayAccess(sectionData.getBlockStates().getData(), BLOCKS_PER_SECTION);
|
||||
this.biomes = new PackedIntArrayAccess(sectionData.getBiomes().getData(), BIOMES_PER_SECTION);
|
||||
this.blocks = new PackedIntArrayAccess(sectionData.blockStates.data, BLOCKS_PER_SECTION);
|
||||
this.biomes = new PackedIntArrayAccess(sectionData.biomes.data, BIOMES_PER_SECTION);
|
||||
|
||||
this.blockLight = sectionData.getBlockLight();
|
||||
this.skyLight = sectionData.getSkyLight();
|
||||
this.blockLight = sectionData.blockLight;
|
||||
this.skyLight = sectionData.skyLight;
|
||||
}
|
||||
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
|
@ -233,6 +233,7 @@ public class Chunk_1_18 extends MCAChunk {
|
|||
public int getSectionY() {
|
||||
return sectionY;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Getter
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* This file is part of BlueMap, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package de.bluecolored.bluemap.core.world.mca.chunk;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class LegacyBiomes {
|
||||
|
||||
private static final String[] BIOME_IDS = new String[170];
|
||||
static {
|
||||
Arrays.fill(BIOME_IDS, "minecraft:ocean");
|
||||
BIOME_IDS[0] = "minecraft:ocean";
|
||||
BIOME_IDS[1] = "minecraft:plains";
|
||||
BIOME_IDS[2] = "minecraft:desert";
|
||||
BIOME_IDS[3] = "minecraft:mountains";
|
||||
BIOME_IDS[4] = "minecraft:forest";
|
||||
BIOME_IDS[5] = "minecraft:taiga";
|
||||
BIOME_IDS[6] = "minecraft:swamp";
|
||||
BIOME_IDS[7] = "minecraft:river";
|
||||
BIOME_IDS[8] = "minecraft:nether";
|
||||
BIOME_IDS[9] = "minecraft:the_end";
|
||||
BIOME_IDS[10] = "minecraft:frozen_ocean";
|
||||
BIOME_IDS[11] = "minecraft:frozen_river";
|
||||
BIOME_IDS[12] = "minecraft:snowy_tundra";
|
||||
BIOME_IDS[13] = "minecraft:snowy_mountains";
|
||||
BIOME_IDS[14] = "minecraft:mushroom_fields";
|
||||
BIOME_IDS[15] = "minecraft:mushroom_field_shore";
|
||||
BIOME_IDS[16] = "minecraft:beach";
|
||||
BIOME_IDS[17] = "minecraft:desert_hills";
|
||||
BIOME_IDS[18] = "minecraft:wooded_hills";
|
||||
BIOME_IDS[19] = "minecraft:taiga_hills";
|
||||
BIOME_IDS[20] = "minecraft:mountain_edge";
|
||||
BIOME_IDS[21] = "minecraft:jungle";
|
||||
BIOME_IDS[22] = "minecraft:jungle_hills";
|
||||
BIOME_IDS[23] = "minecraft:jungle_edge";
|
||||
BIOME_IDS[24] = "minecraft:deep_ocean";
|
||||
BIOME_IDS[25] = "minecraft:stone_shore";
|
||||
BIOME_IDS[26] = "minecraft:snowy_beach";
|
||||
BIOME_IDS[27] = "minecraft:birch_forest";
|
||||
BIOME_IDS[28] = "minecraft:birch_forest_hills";
|
||||
BIOME_IDS[29] = "minecraft:dark_forest";
|
||||
BIOME_IDS[30] = "minecraft:snowy_taiga";
|
||||
BIOME_IDS[31] = "minecraft:snowy_taiga_hills";
|
||||
BIOME_IDS[32] = "minecraft:giant_tree_taiga";
|
||||
BIOME_IDS[33] = "minecraft:giant_tree_taiga_hills";
|
||||
BIOME_IDS[34] = "minecraft:wooded_mountains";
|
||||
BIOME_IDS[35] = "minecraft:savanna";
|
||||
BIOME_IDS[36] = "minecraft:savanna_plateau";
|
||||
BIOME_IDS[37] = "minecraft:badlands";
|
||||
BIOME_IDS[38] = "minecraft:wooded_badlands_plateau";
|
||||
BIOME_IDS[39] = "minecraft:badlands_plateau";
|
||||
BIOME_IDS[40] = "minecraft:small_end_islands";
|
||||
BIOME_IDS[41] = "minecraft:end_midlands";
|
||||
BIOME_IDS[42] = "minecraft:end_highlands";
|
||||
BIOME_IDS[43] = "minecraft:end_barrens";
|
||||
BIOME_IDS[44] = "minecraft:warm_ocean";
|
||||
BIOME_IDS[45] = "minecraft:lukewarm_ocean";
|
||||
BIOME_IDS[46] = "minecraft:cold_ocean";
|
||||
BIOME_IDS[47] = "minecraft:deep_warm_ocean";
|
||||
BIOME_IDS[48] = "minecraft:deep_lukewarm_ocean";
|
||||
BIOME_IDS[49] = "minecraft:deep_cold_ocean";
|
||||
BIOME_IDS[50] = "minecraft:deep_frozen_ocean";
|
||||
BIOME_IDS[127] = "minecraft:the_void";
|
||||
BIOME_IDS[129] = "minecraft:sunflower_plains";
|
||||
BIOME_IDS[130] = "minecraft:desert_lakes";
|
||||
BIOME_IDS[131] = "minecraft:gravelly_mountains";
|
||||
BIOME_IDS[132] = "minecraft:flower_forest";
|
||||
BIOME_IDS[133] = "minecraft:taiga_mountains";
|
||||
BIOME_IDS[134] = "minecraft:swamp_hills";
|
||||
BIOME_IDS[140] = "minecraft:ice_spikes";
|
||||
BIOME_IDS[149] = "minecraft:modified_jungle";
|
||||
BIOME_IDS[151] = "minecraft:modified_jungle_edge";
|
||||
BIOME_IDS[155] = "minecraft:tall_birch_forest";
|
||||
BIOME_IDS[156] = "minecraft:tall_birch_hills";
|
||||
BIOME_IDS[157] = "minecraft:dark_forest_hills";
|
||||
BIOME_IDS[158] = "minecraft:snowy_taiga_mountains";
|
||||
BIOME_IDS[160] = "minecraft:giant_spruce_taiga";
|
||||
BIOME_IDS[161] = "minecraft:giant_spruce_taiga_hills";
|
||||
BIOME_IDS[162] = "minecraft:modified_gravelly_mountains";
|
||||
BIOME_IDS[163] = "minecraft:shattered_savanna";
|
||||
BIOME_IDS[164] = "minecraft:shattered_savanna_plateau";
|
||||
BIOME_IDS[165] = "minecraft:eroded_badlands";
|
||||
BIOME_IDS[166] = "minecraft:modified_wooded_badlands_plateau";
|
||||
BIOME_IDS[167] = "minecraft:modified_badlands_plateau";
|
||||
BIOME_IDS[168] = "minecraft:bamboo_jungle";
|
||||
BIOME_IDS[169] = "minecraft:bamboo_jungle_hills";
|
||||
}
|
||||
|
||||
public static String idFor(int legacyId) {
|
||||
if (legacyId < 0 || legacyId >= BIOME_IDS.length) legacyId = 0;
|
||||
return BIOME_IDS[legacyId];
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,7 @@ public abstract class MCAChunk implements Chunk {
|
|||
protected static final int VALUES_PER_HEIGHTMAP = 16 * 16;
|
||||
|
||||
protected static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
|
||||
protected static final int[] EMPTY_INT_ARRAY = new int[0];
|
||||
protected static final long[] EMPTY_LONG_ARRAY = new long[0];
|
||||
protected static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
protected static final BlockState[] EMPTY_BLOCKSTATE_ARRAY = new BlockState[0];
|
||||
|
|
Loading…
Reference in New Issue