ChunkHeightAndBiomeFix.java
net.minecraft.util.datafix.fixes.ChunkHeightAndBiomeFix
信息
- 全限定名:net.minecraft.util.datafix.fixes.ChunkHeightAndBiomeFix
- 类型:public class
- 包:net.minecraft.util.datafix.fixes
- 源码路径:src/main/java/net/minecraft/util/datafix/fixes/ChunkHeightAndBiomeFix.java
- 起始行号:L42
- 继承:DataFix
- 职责:
TODO
字段/常量
-
DATAFIXER_CONTEXT_TAG- 类型:
String - 修饰符:
public static final - 源码定位:
L43 - 说明:
TODO
- 类型:
-
NAME- 类型:
String - 修饰符:
private static final - 源码定位:
L44 - 说明:
TODO
- 类型:
-
OLD_SECTION_COUNT- 类型:
int - 修饰符:
private static final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
NEW_SECTION_COUNT- 类型:
int - 修饰符:
private static final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
NEW_MIN_SECTION_Y- 类型:
int - 修饰符:
private static final - 源码定位:
L47 - 说明:
TODO
- 类型:
-
BLOCKS_PER_SECTION- 类型:
int - 修饰符:
public static final - 源码定位:
L48 - 说明:
TODO
- 类型:
-
LONGS_PER_SECTION- 类型:
int - 修饰符:
private static final - 源码定位:
L49 - 说明:
TODO
- 类型:
-
HEIGHTMAP_BITS- 类型:
int - 修饰符:
private static final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
HEIGHTMAP_MASK- 类型:
long - 修饰符:
private static final - 源码定位:
L51 - 说明:
TODO
- 类型:
-
HEIGHTMAP_OFFSET- 类型:
int - 修饰符:
private static final - 源码定位:
L52 - 说明:
TODO
- 类型:
-
HEIGHTMAP_TYPES- 类型:
String[] - 修饰符:
private static final - 源码定位:
L53 - 说明:
TODO
- 类型:
-
STATUS_IS_OR_AFTER_SURFACE- 类型:
Set<String> - 修饰符:
private static final - 源码定位:
L56 - 说明:
TODO
- 类型:
-
STATUS_IS_OR_AFTER_NOISE- 类型:
Set<String> - 修饰符:
private static final - 源码定位:
L59 - 说明:
TODO
- 类型:
-
BLOCKS_BEFORE_FEATURE_STATUS- 类型:
Set<String> - 修饰符:
private static final - 源码定位:
L62 - 说明:
TODO
- 类型:
-
BIOME_CONTAINER_LAYER_SIZE- 类型:
int - 修饰符:
private static final - 源码定位:
L98 - 说明:
TODO
- 类型:
-
BIOME_CONTAINER_SIZE- 类型:
int - 修饰符:
private static final - 源码定位:
L99 - 说明:
TODO
- 类型:
-
BIOME_CONTAINER_TOP_LAYER_OFFSET- 类型:
int - 修饰符:
private static final - 源码定位:
L100 - 说明:
TODO
- 类型:
-
DEFAULT_BIOME- 类型:
String - 修饰符:
public static final - 源码定位:
L101 - 说明:
TODO
- 类型:
-
BIOMES_BY_ID- 类型:
Int2ObjectMap<String> - 修饰符:
private static final - 源码定位:
L102 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
public ChunkHeightAndBiomeFix(Schema outputSchema) @ L104
- 构造器名:ChunkHeightAndBiomeFix
- 源码定位:L104
- 修饰符:public
参数:
- outputSchema: Schema
说明:
TODO
方法
下面的方法块按源码顺序生成。
protected TypeRewriteRule makeRule() @ L108
- 方法名:makeRule
- 源码定位:L108
- 返回类型:TypeRewriteRule
- 修饰符:protected
参数:
- 无
说明:
TODO
private Dynamic<?> predictChunkStatusBeforeSurface(Dynamic<?> chunkTag, Set<String> blocksInChunk) @ L198
- 方法名:predictChunkStatusBeforeSurface
- 源码定位:L198
- 返回类型:Dynamic<?>
- 修饰符:private
参数:
- chunkTag: Dynamic<?>
- blocksInChunk: Set
说明:
TODO
private static Dynamic<?>[] getBiomeContainers(Dynamic<?> tag, boolean increaseHeight, int minSection, MutableBoolean wasIncreasedHeight) @ L219
- 方法名:getBiomeContainers
- 源码定位:L219
- 返回类型:Dynamic<?>[]
- 修饰符:private static
参数:
- tag: Dynamic<?>
- increaseHeight: boolean
- minSection: int
- wasIncreasedHeight: MutableBoolean
说明:
TODO
private static int getOldBiome(int[] oldBiomes, int index) @ L255
- 方法名:getOldBiome
- 源码定位:L255
- 返回类型:int
- 修饰符:private static
参数:
- oldBiomes: int[]
- index: int
说明:
TODO
private static Dynamic<?> updateChunkTag(Dynamic<?> chunkTag, boolean isOverworld, boolean wasIncreasedHeight, boolean needsBlendingAndUpgrade, Supplier<ChunkProtoTickListFix.PoorMansPalettedContainer> bedrockSectionBlocks) @ L259
- 方法名:updateChunkTag
- 源码定位:L259
- 返回类型:Dynamic<?>
- 修饰符:private static
参数:
- chunkTag: Dynamic<?>
- isOverworld: boolean
- wasIncreasedHeight: boolean
- needsBlendingAndUpgrade: boolean
- bedrockSectionBlocks: Supplier<ChunkProtoTickListFix.PoorMansPalettedContainer>
说明:
TODO
private static <T> Dynamic<T> shiftUpgradeData(Dynamic<T> upgradeData) @ L338
- 方法名:shiftUpgradeData
- 源码定位:L338
- 返回类型:
Dynamic - 修饰符:private static
参数:
- upgradeData: Dynamic
说明:
TODO
private static Dynamic<?> updateCarvingMasks(Dynamic<?> chunkTag, int sectionCount, int addedSectionsBelow) @ L354
- 方法名:updateCarvingMasks
- 源码定位:L354
- 返回类型:Dynamic<?>
- 修饰符:private static
参数:
- chunkTag: Dynamic<?>
- sectionCount: int
- addedSectionsBelow: int
说明:
TODO
private static Dynamic<?> addPaddingEntries(Dynamic<?> chunkTag, String key) @ L365
- 方法名:addPaddingEntries
- 源码定位:L365
- 返回类型:Dynamic<?>
- 修饰符:private static
参数:
- chunkTag: Dynamic<?>
- key: String
说明:
TODO
private static Dynamic<?> updateHeightmaps(Dynamic<?> chunkTag) @ L381
- 方法名:updateHeightmaps
- 源码定位:L381
- 返回类型:Dynamic<?>
- 修饰符:private static
参数:
- chunkTag: Dynamic<?>
说明:
TODO
private static Dynamic<?> getFixedHeightmap(Dynamic<?> tag) @ L391
- 方法名:getFixedHeightmap
- 源码定位:L391
- 返回类型:Dynamic<?>
- 修饰符:private static
参数:
- tag: Dynamic<?>
说明:
TODO
private static Dynamic<?> makeBiomeContainer(Dynamic<?> tag, Int2IntFunction sourceStorage) @ L411
- 方法名:makeBiomeContainer
- 源码定位:L411
- 返回类型:Dynamic<?>
- 修饰符:private static
参数:
- tag: Dynamic<?>
- sourceStorage: Int2IntFunction
说明:
TODO
private static Dynamic<?> makePalettedContainer(Dynamic<?> palette) @ L449
- 方法名:makePalettedContainer
- 源码定位:L449
- 返回类型:Dynamic<?>
- 修饰符:private static
参数:
- palette: Dynamic<?>
说明:
TODO
private static Dynamic<?> makePalettedContainer(Dynamic<?> palette, Dynamic<?> storage) @ L453
- 方法名:makePalettedContainer
- 源码定位:L453
- 返回类型:Dynamic<?>
- 修饰符:private static
参数:
- palette: Dynamic<?>
- storage: Dynamic<?>
说明:
TODO
private static Dynamic<?> makeOptimizedPalettedContainer(Dynamic<?> palette, Dynamic<?> data) @ L457
- 方法名:makeOptimizedPalettedContainer
- 源码定位:L457
- 返回类型:Dynamic<?>
- 修饰符:private static
参数:
- palette: Dynamic<?>
- data: Dynamic<?>
说明:
TODO
private static Dynamic<?> padPaletteEntries(Dynamic<?> palette, Dynamic<?> data, List<Dynamic<?>> paletteList) @ L467
- 方法名:padPaletteEntries
- 源码定位:L467
- 返回类型:Dynamic<?>
- 修饰符:private static
参数:
- palette: Dynamic<?>
- data: Dynamic<?>
- paletteList: List<Dynamic<?>>
说明:
TODO
public static int ceillog2(int input) @ L487
- 方法名:ceillog2
- 源码定位:L487
- 返回类型:int
- 修饰符:public static
参数:
- input: int
说明:
TODO
代码
public class ChunkHeightAndBiomeFix extends DataFix {
public static final String DATAFIXER_CONTEXT_TAG = "__context";
private static final String NAME = "ChunkHeightAndBiomeFix";
private static final int OLD_SECTION_COUNT = 16;
private static final int NEW_SECTION_COUNT = 24;
private static final int NEW_MIN_SECTION_Y = -4;
public static final int BLOCKS_PER_SECTION = 4096;
private static final int LONGS_PER_SECTION = 64;
private static final int HEIGHTMAP_BITS = 9;
private static final long HEIGHTMAP_MASK = 511L;
private static final int HEIGHTMAP_OFFSET = 64;
private static final String[] HEIGHTMAP_TYPES = new String[]{
"WORLD_SURFACE_WG", "WORLD_SURFACE", "WORLD_SURFACE_IGNORE_SNOW", "OCEAN_FLOOR_WG", "OCEAN_FLOOR", "MOTION_BLOCKING", "MOTION_BLOCKING_NO_LEAVES"
};
private static final Set<String> STATUS_IS_OR_AFTER_SURFACE = Set.of(
"surface", "carvers", "liquid_carvers", "features", "light", "spawn", "heightmaps", "full"
);
private static final Set<String> STATUS_IS_OR_AFTER_NOISE = Set.of(
"noise", "surface", "carvers", "liquid_carvers", "features", "light", "spawn", "heightmaps", "full"
);
private static final Set<String> BLOCKS_BEFORE_FEATURE_STATUS = Set.of(
"minecraft:air",
"minecraft:basalt",
"minecraft:bedrock",
"minecraft:blackstone",
"minecraft:calcite",
"minecraft:cave_air",
"minecraft:coarse_dirt",
"minecraft:crimson_nylium",
"minecraft:dirt",
"minecraft:end_stone",
"minecraft:grass_block",
"minecraft:gravel",
"minecraft:ice",
"minecraft:lava",
"minecraft:mycelium",
"minecraft:nether_wart_block",
"minecraft:netherrack",
"minecraft:orange_terracotta",
"minecraft:packed_ice",
"minecraft:podzol",
"minecraft:powder_snow",
"minecraft:red_sand",
"minecraft:red_sandstone",
"minecraft:sand",
"minecraft:sandstone",
"minecraft:snow_block",
"minecraft:soul_sand",
"minecraft:soul_soil",
"minecraft:stone",
"minecraft:terracotta",
"minecraft:warped_nylium",
"minecraft:warped_wart_block",
"minecraft:water",
"minecraft:white_terracotta"
);
private static final int BIOME_CONTAINER_LAYER_SIZE = 16;
private static final int BIOME_CONTAINER_SIZE = 64;
private static final int BIOME_CONTAINER_TOP_LAYER_OFFSET = 1008;
public static final String DEFAULT_BIOME = "minecraft:plains";
private static final Int2ObjectMap<String> BIOMES_BY_ID = new Int2ObjectOpenHashMap<>();
public ChunkHeightAndBiomeFix(Schema outputSchema) {
super(outputSchema, true);
}
@Override
protected TypeRewriteRule makeRule() {
Type<?> oldChunkType = this.getInputSchema().getType(References.CHUNK);
OpticFinder<?> levelFinder = oldChunkType.findField("Level");
OpticFinder<?> sectionsFinder = levelFinder.type().findField("Sections");
Schema outputSchema = this.getOutputSchema();
Type<?> chunkType = outputSchema.getType(References.CHUNK);
Type<?> levelType = chunkType.findField("Level").type();
Type<?> sectionsType = levelType.findField("Sections").type();
return this.fixTypeEverywhereTyped(
"ChunkHeightAndBiomeFix",
oldChunkType,
chunkType,
chunk -> chunk.updateTyped(
levelFinder,
levelType,
level -> {
Dynamic<?> tag = level.get(DSL.remainderFinder());
OptionalDynamic<?> contextTag = chunk.get(DSL.remainderFinder()).get("__context");
String dimension = contextTag.get("dimension").asString().result().orElse("");
String generator = contextTag.get("generator").asString().result().orElse("");
boolean isOverworld = "minecraft:overworld".equals(dimension);
MutableBoolean wasIncreasedHeight = new MutableBoolean();
int minSection = isOverworld ? -4 : 0;
Dynamic<?>[] biomeContainers = getBiomeContainers(tag, isOverworld, minSection, wasIncreasedHeight);
Dynamic<?> airContainer = makePalettedContainer(
tag.createList(Stream.of(tag.createMap(ImmutableMap.of(tag.createString("Name"), tag.createString("minecraft:air")))))
);
Set<String> blocksInChunk = Sets.newHashSet();
MutableObject<Supplier<ChunkProtoTickListFix.PoorMansPalettedContainer>> bedrockSectionBlocks = new MutableObject<>(() -> null);
level = level.updateTyped(sectionsFinder, sectionsType, sections -> {
IntSet doneSections = new IntOpenHashSet();
Dynamic<?> dynamic = (Dynamic<?>)sections.write()
.result()
.orElseThrow(() -> new IllegalStateException("Malformed Chunk.Level.Sections"));
List<Dynamic<?>> sectionsList = dynamic.asStream().map(sectionx -> {
int sectionYx = sectionx.get("Y").asInt(0);
Dynamic<?> blockStatesContainer = DataFixUtils.orElse(sectionx.get("Palette").result().flatMap(palette -> {
palette.asStream().map(blockState -> blockState.get("Name").asString("minecraft:air")).forEach(blocksInChunk::add);
return sectionx.get("BlockStates")
.result()
.map(blockStates -> makeOptimizedPalettedContainer(palette, (Dynamic<?>)blockStates));
}), airContainer);
Dynamic<?> result = sectionx;
int sectionYIndex = sectionYx - minSection;
if (sectionYIndex >= 0 && sectionYIndex < biomeContainers.length) {
result = sectionx.set("biomes", biomeContainers[sectionYIndex]);
}
doneSections.add(sectionYx);
if (sectionx.get("Y").asInt(Integer.MAX_VALUE) == 0) {
bedrockSectionBlocks.setValue(() -> {
List<? extends Dynamic<?>> palette = blockStatesContainer.get("palette").asList(Function.identity());
long[] data = blockStatesContainer.get("data").asLongStream().toArray();
return new ChunkProtoTickListFix.PoorMansPalettedContainer(palette, data);
});
}
return result.set("block_states", blockStatesContainer).remove("Palette").remove("BlockStates");
}).collect(Collectors.toCollection(ArrayList::new));
for (int sectionIndex = 0; sectionIndex < biomeContainers.length; sectionIndex++) {
int sectionY = sectionIndex + minSection;
if (doneSections.add(sectionY)) {
Dynamic<?> section = tag.createMap(Map.of(tag.createString("Y"), tag.createInt(sectionY)));
section = section.set("block_states", airContainer);
section = section.set("biomes", biomeContainers[sectionIndex]);
sectionsList.add(section);
}
}
return Util.readTypedOrThrow(sectionsType, tag.createList(sectionsList.stream()));
});
return level.update(
DSL.remainderFinder(),
chunkTag -> {
if (isOverworld) {
chunkTag = this.predictChunkStatusBeforeSurface(chunkTag, blocksInChunk);
}
return updateChunkTag(
chunkTag, isOverworld, wasIncreasedHeight.booleanValue(), "minecraft:noise".equals(generator), bedrockSectionBlocks.get()
);
}
);
}
)
);
}
private Dynamic<?> predictChunkStatusBeforeSurface(Dynamic<?> chunkTag, Set<String> blocksInChunk) {
return chunkTag.update("Status", statusDynamic -> {
String status = statusDynamic.asString("empty");
if (STATUS_IS_OR_AFTER_SURFACE.contains(status)) {
return statusDynamic;
} else {
blocksInChunk.remove("minecraft:air");
boolean hasNonAirBlocks = !blocksInChunk.isEmpty();
blocksInChunk.removeAll(BLOCKS_BEFORE_FEATURE_STATUS);
boolean hasFeatureBlocks = !blocksInChunk.isEmpty();
if (hasFeatureBlocks) {
return statusDynamic.createString("liquid_carvers");
} else if ("noise".equals(status) || hasNonAirBlocks) {
return statusDynamic.createString("noise");
} else {
return "biomes".equals(status) ? statusDynamic.createString("structure_references") : statusDynamic;
}
}
});
}
private static Dynamic<?>[] getBiomeContainers(Dynamic<?> tag, boolean increaseHeight, int minSection, MutableBoolean wasIncreasedHeight) {
Dynamic<?>[] biomeContainers = new Dynamic[increaseHeight ? 24 : 16];
int[] oldBiomes = tag.get("Biomes").asIntStreamOpt().result().map(IntStream::toArray).orElse(null);
if (oldBiomes != null && oldBiomes.length == 1536) {
wasIncreasedHeight.setValue(true);
for (int sectionYIndex = 0; sectionYIndex < 24; sectionYIndex++) {
int finalSectionYIndex = sectionYIndex;
biomeContainers[sectionYIndex] = makeBiomeContainer(tag, ix -> getOldBiome(oldBiomes, finalSectionYIndex * 64 + ix));
}
} else if (oldBiomes != null && oldBiomes.length == 1024) {
for (int sectionY = 0; sectionY < 16; sectionY++) {
int sectionYIndex = sectionY - minSection;
int finalSectionY = sectionY;
biomeContainers[sectionYIndex] = makeBiomeContainer(tag, ix -> getOldBiome(oldBiomes, finalSectionY * 64 + ix));
}
if (increaseHeight) {
Dynamic<?> belowWorldBiomes = makeBiomeContainer(tag, ix -> getOldBiome(oldBiomes, ix % 16));
Dynamic<?> aboveWorldBiomes = makeBiomeContainer(tag, ix -> getOldBiome(oldBiomes, ix % 16 + 1008));
for (int i = 0; i < 4; i++) {
biomeContainers[i] = belowWorldBiomes;
}
for (int i = 20; i < 24; i++) {
biomeContainers[i] = aboveWorldBiomes;
}
}
} else {
Arrays.fill(biomeContainers, makePalettedContainer(tag.createList(Stream.of(tag.createString("minecraft:plains")))));
}
return biomeContainers;
}
private static int getOldBiome(int[] oldBiomes, int index) {
return oldBiomes[index] & 0xFF;
}
private static Dynamic<?> updateChunkTag(
Dynamic<?> chunkTag,
boolean isOverworld,
boolean wasIncreasedHeight,
boolean needsBlendingAndUpgrade,
Supplier<ChunkProtoTickListFix.@Nullable PoorMansPalettedContainer> bedrockSectionBlocks
) {
chunkTag = chunkTag.remove("Biomes");
if (!isOverworld) {
return updateCarvingMasks(chunkTag, 16, 0);
} else if (wasIncreasedHeight) {
return updateCarvingMasks(chunkTag, 24, 0);
} else {
chunkTag = updateHeightmaps(chunkTag);
chunkTag = addPaddingEntries(chunkTag, "LiquidsToBeTicked");
chunkTag = addPaddingEntries(chunkTag, "PostProcessing");
chunkTag = addPaddingEntries(chunkTag, "ToBeTicked");
chunkTag = updateCarvingMasks(chunkTag, 24, 4);
chunkTag = chunkTag.update("UpgradeData", ChunkHeightAndBiomeFix::shiftUpgradeData);
if (!needsBlendingAndUpgrade) {
return chunkTag;
} else {
Optional<? extends Dynamic<?>> statusOpt = chunkTag.get("Status").result();
if (statusOpt.isPresent()) {
Dynamic<?> status = (Dynamic<?>)statusOpt.get();
String lastStatus = status.asString("");
if (!"empty".equals(lastStatus)) {
chunkTag = chunkTag.set(
"blending_data",
chunkTag.createMap(
ImmutableMap.of(chunkTag.createString("old_noise"), chunkTag.createBoolean(STATUS_IS_OR_AFTER_NOISE.contains(lastStatus)))
)
);
if (!SharedConstants.DEBUG_DISABLE_BELOW_ZERO_RETROGENERATION) {
ChunkProtoTickListFix.PoorMansPalettedContainer poorMansPalettedContainer = bedrockSectionBlocks.get();
if (poorMansPalettedContainer != null) {
BitSet missingBedrock = new BitSet(256);
boolean hasAnyBedrock = lastStatus.equals("noise");
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
Dynamic<?> blockState = poorMansPalettedContainer.get(x, 0, z);
boolean isBedrock = blockState != null && "minecraft:bedrock".equals(blockState.get("Name").asString(""));
boolean isAir = blockState != null && "minecraft:air".equals(blockState.get("Name").asString(""));
if (isAir) {
missingBedrock.set(z * 16 + x);
}
hasAnyBedrock |= isBedrock;
}
}
if (hasAnyBedrock && missingBedrock.cardinality() != missingBedrock.size()) {
Dynamic<?> targetStatus = "full".equals(lastStatus) ? chunkTag.createString("heightmaps") : status;
chunkTag = chunkTag.set(
"below_zero_retrogen",
chunkTag.createMap(
ImmutableMap.of(
chunkTag.createString("target_status"),
targetStatus,
chunkTag.createString("missing_bedrock"),
chunkTag.createLongList(LongStream.of(missingBedrock.toLongArray()))
)
)
);
chunkTag = chunkTag.set("Status", chunkTag.createString("empty"));
}
chunkTag = chunkTag.set("isLightOn", chunkTag.createBoolean(false));
}
}
}
}
return chunkTag;
}
}
}
private static <T> Dynamic<T> shiftUpgradeData(Dynamic<T> upgradeData) {
return upgradeData.update("Indices", indices -> {
Map<Dynamic<?>, Dynamic<?>> shiftedIndices = new HashMap<>();
indices.getMapValues().ifSuccess(entries -> entries.forEach((index, data) -> {
try {
index.asString().result().map(Integer::parseInt).ifPresent(i -> {
int shiftedIndex = i - -4;
shiftedIndices.put(index.createString(Integer.toString(shiftedIndex)), (Dynamic<?>)data);
});
} catch (NumberFormatException var4) {
}
}));
return indices.createMap(shiftedIndices);
});
}
private static Dynamic<?> updateCarvingMasks(Dynamic<?> chunkTag, int sectionCount, int addedSectionsBelow) {
Dynamic<?> carvingMasks = chunkTag.get("CarvingMasks").orElseEmptyMap();
carvingMasks = carvingMasks.updateMapValues(pair -> {
long[] oldValues = BitSet.valueOf(pair.getSecond().asByteBuffer().array()).toLongArray();
long[] newValues = new long[64 * sectionCount];
System.arraycopy(oldValues, 0, newValues, 64 * addedSectionsBelow, oldValues.length);
return Pair.of(pair.getFirst(), chunkTag.createLongList(LongStream.of(newValues)));
});
return chunkTag.set("CarvingMasks", carvingMasks);
}
private static Dynamic<?> addPaddingEntries(Dynamic<?> chunkTag, String key) {
List<Dynamic<?>> list = chunkTag.get(key).orElseEmptyList().asStream().collect(Collectors.toCollection(ArrayList::new));
if (list.size() == 24) {
return chunkTag;
} else {
Dynamic<?> emptyList = chunkTag.emptyList();
for (int i = 0; i < 4; i++) {
list.add(0, emptyList);
list.add(emptyList);
}
return chunkTag.set(key, chunkTag.createList(list.stream()));
}
}
private static Dynamic<?> updateHeightmaps(Dynamic<?> chunkTag) {
return chunkTag.update("Heightmaps", heightmapTag -> {
for (String heightmapType : HEIGHTMAP_TYPES) {
heightmapTag = heightmapTag.update(heightmapType, ChunkHeightAndBiomeFix::getFixedHeightmap);
}
return heightmapTag;
});
}
private static Dynamic<?> getFixedHeightmap(Dynamic<?> tag) {
return tag.createLongList(tag.asLongStream().map(value -> {
long newValue = 0L;
for (int bitIndex = 0; bitIndex + 9 <= 64; bitIndex += 9) {
long oldHeight = value >> bitIndex & 511L;
long newHeight;
if (oldHeight == 0L) {
newHeight = 0L;
} else {
newHeight = Math.min(oldHeight + 64L, 511L);
}
newValue |= newHeight << bitIndex;
}
return newValue;
}));
}
private static Dynamic<?> makeBiomeContainer(Dynamic<?> tag, Int2IntFunction sourceStorage) {
Int2IntMap idMap = new Int2IntLinkedOpenHashMap();
for (int i = 0; i < 64; i++) {
int biomeId = sourceStorage.applyAsInt(i);
if (!idMap.containsKey(biomeId)) {
idMap.put(biomeId, idMap.size());
}
}
Dynamic<?> palette = tag.createList(
idMap.keySet().stream().map(biomeId1 -> tag.createString(BIOMES_BY_ID.getOrDefault(biomeId1.intValue(), "minecraft:plains")))
);
int bits = ceillog2(idMap.size());
if (bits == 0) {
return makePalettedContainer(palette);
} else {
int valuesPerLong = 64 / bits;
int requiredLength = (64 + valuesPerLong - 1) / valuesPerLong;
long[] bitStorage = new long[requiredLength];
int cellIndex = 0;
int bitIndex = 0;
for (int ix = 0; ix < 64; ix++) {
int biomeId = sourceStorage.applyAsInt(ix);
bitStorage[cellIndex] |= (long)idMap.get(biomeId) << bitIndex;
bitIndex += bits;
if (bitIndex + bits > 64) {
cellIndex++;
bitIndex = 0;
}
}
Dynamic<?> storage = tag.createLongList(Arrays.stream(bitStorage));
return makePalettedContainer(palette, storage);
}
}
private static Dynamic<?> makePalettedContainer(Dynamic<?> palette) {
return palette.createMap(ImmutableMap.of(palette.createString("palette"), palette));
}
private static Dynamic<?> makePalettedContainer(Dynamic<?> palette, Dynamic<?> storage) {
return palette.createMap(ImmutableMap.of(palette.createString("palette"), palette, palette.createString("data"), storage));
}
private static Dynamic<?> makeOptimizedPalettedContainer(Dynamic<?> palette, Dynamic<?> data) {
List<Dynamic<?>> paletteList = palette.asStream().collect(Collectors.toCollection(ArrayList::new));
if (paletteList.size() == 1) {
return makePalettedContainer(palette);
} else {
palette = padPaletteEntries(palette, data, paletteList);
return makePalettedContainer(palette, data);
}
}
private static Dynamic<?> padPaletteEntries(Dynamic<?> palette, Dynamic<?> data, List<Dynamic<?>> paletteList) {
long dataSizeInBits = data.asLongStream().count() * 64L;
long estimatedBitsPerBlock = dataSizeInBits / 4096L;
int paletteSize = paletteList.size();
int expectedBitsPerBlock = ceillog2(paletteSize);
if (estimatedBitsPerBlock <= expectedBitsPerBlock) {
return palette;
} else {
Dynamic<?> airPalleteEntry = palette.createMap(ImmutableMap.of(palette.createString("Name"), palette.createString("minecraft:air")));
int minimumPaletteSizeToMatchData = (1 << (int)(estimatedBitsPerBlock - 1L)) + 1;
int additionalPaletteEntries = minimumPaletteSizeToMatchData - paletteSize;
for (int i = 0; i < additionalPaletteEntries; i++) {
paletteList.add(airPalleteEntry);
}
return palette.createList(paletteList.stream());
}
}
public static int ceillog2(int input) {
return input == 0 ? 0 : (int)Math.ceil(Math.log(input) / Math.log(2.0));
}
static {
BIOMES_BY_ID.put(0, "minecraft:ocean");
BIOMES_BY_ID.put(1, "minecraft:plains");
BIOMES_BY_ID.put(2, "minecraft:desert");
BIOMES_BY_ID.put(3, "minecraft:mountains");
BIOMES_BY_ID.put(4, "minecraft:forest");
BIOMES_BY_ID.put(5, "minecraft:taiga");
BIOMES_BY_ID.put(6, "minecraft:swamp");
BIOMES_BY_ID.put(7, "minecraft:river");
BIOMES_BY_ID.put(8, "minecraft:nether_wastes");
BIOMES_BY_ID.put(9, "minecraft:the_end");
BIOMES_BY_ID.put(10, "minecraft:frozen_ocean");
BIOMES_BY_ID.put(11, "minecraft:frozen_river");
BIOMES_BY_ID.put(12, "minecraft:snowy_tundra");
BIOMES_BY_ID.put(13, "minecraft:snowy_mountains");
BIOMES_BY_ID.put(14, "minecraft:mushroom_fields");
BIOMES_BY_ID.put(15, "minecraft:mushroom_field_shore");
BIOMES_BY_ID.put(16, "minecraft:beach");
BIOMES_BY_ID.put(17, "minecraft:desert_hills");
BIOMES_BY_ID.put(18, "minecraft:wooded_hills");
BIOMES_BY_ID.put(19, "minecraft:taiga_hills");
BIOMES_BY_ID.put(20, "minecraft:mountain_edge");
BIOMES_BY_ID.put(21, "minecraft:jungle");
BIOMES_BY_ID.put(22, "minecraft:jungle_hills");
BIOMES_BY_ID.put(23, "minecraft:jungle_edge");
BIOMES_BY_ID.put(24, "minecraft:deep_ocean");
BIOMES_BY_ID.put(25, "minecraft:stone_shore");
BIOMES_BY_ID.put(26, "minecraft:snowy_beach");
BIOMES_BY_ID.put(27, "minecraft:birch_forest");
BIOMES_BY_ID.put(28, "minecraft:birch_forest_hills");
BIOMES_BY_ID.put(29, "minecraft:dark_forest");
BIOMES_BY_ID.put(30, "minecraft:snowy_taiga");
BIOMES_BY_ID.put(31, "minecraft:snowy_taiga_hills");
BIOMES_BY_ID.put(32, "minecraft:giant_tree_taiga");
BIOMES_BY_ID.put(33, "minecraft:giant_tree_taiga_hills");
BIOMES_BY_ID.put(34, "minecraft:wooded_mountains");
BIOMES_BY_ID.put(35, "minecraft:savanna");
BIOMES_BY_ID.put(36, "minecraft:savanna_plateau");
BIOMES_BY_ID.put(37, "minecraft:badlands");
BIOMES_BY_ID.put(38, "minecraft:wooded_badlands_plateau");
BIOMES_BY_ID.put(39, "minecraft:badlands_plateau");
BIOMES_BY_ID.put(40, "minecraft:small_end_islands");
BIOMES_BY_ID.put(41, "minecraft:end_midlands");
BIOMES_BY_ID.put(42, "minecraft:end_highlands");
BIOMES_BY_ID.put(43, "minecraft:end_barrens");
BIOMES_BY_ID.put(44, "minecraft:warm_ocean");
BIOMES_BY_ID.put(45, "minecraft:lukewarm_ocean");
BIOMES_BY_ID.put(46, "minecraft:cold_ocean");
BIOMES_BY_ID.put(47, "minecraft:deep_warm_ocean");
BIOMES_BY_ID.put(48, "minecraft:deep_lukewarm_ocean");
BIOMES_BY_ID.put(49, "minecraft:deep_cold_ocean");
BIOMES_BY_ID.put(50, "minecraft:deep_frozen_ocean");
BIOMES_BY_ID.put(127, "minecraft:the_void");
BIOMES_BY_ID.put(129, "minecraft:sunflower_plains");
BIOMES_BY_ID.put(130, "minecraft:desert_lakes");
BIOMES_BY_ID.put(131, "minecraft:gravelly_mountains");
BIOMES_BY_ID.put(132, "minecraft:flower_forest");
BIOMES_BY_ID.put(133, "minecraft:taiga_mountains");
BIOMES_BY_ID.put(134, "minecraft:swamp_hills");
BIOMES_BY_ID.put(140, "minecraft:ice_spikes");
BIOMES_BY_ID.put(149, "minecraft:modified_jungle");
BIOMES_BY_ID.put(151, "minecraft:modified_jungle_edge");
BIOMES_BY_ID.put(155, "minecraft:tall_birch_forest");
BIOMES_BY_ID.put(156, "minecraft:tall_birch_hills");
BIOMES_BY_ID.put(157, "minecraft:dark_forest_hills");
BIOMES_BY_ID.put(158, "minecraft:snowy_taiga_mountains");
BIOMES_BY_ID.put(160, "minecraft:giant_spruce_taiga");
BIOMES_BY_ID.put(161, "minecraft:giant_spruce_taiga_hills");
BIOMES_BY_ID.put(162, "minecraft:modified_gravelly_mountains");
BIOMES_BY_ID.put(163, "minecraft:shattered_savanna");
BIOMES_BY_ID.put(164, "minecraft:shattered_savanna_plateau");
BIOMES_BY_ID.put(165, "minecraft:eroded_badlands");
BIOMES_BY_ID.put(166, "minecraft:modified_wooded_badlands_plateau");
BIOMES_BY_ID.put(167, "minecraft:modified_badlands_plateau");
BIOMES_BY_ID.put(168, "minecraft:bamboo_jungle");
BIOMES_BY_ID.put(169, "minecraft:bamboo_jungle_hills");
BIOMES_BY_ID.put(170, "minecraft:soul_sand_valley");
BIOMES_BY_ID.put(171, "minecraft:crimson_forest");
BIOMES_BY_ID.put(172, "minecraft:warped_forest");
BIOMES_BY_ID.put(173, "minecraft:basalt_deltas");
BIOMES_BY_ID.put(174, "minecraft:dripstone_caves");
BIOMES_BY_ID.put(175, "minecraft:lush_caves");
BIOMES_BY_ID.put(177, "minecraft:meadow");
BIOMES_BY_ID.put(178, "minecraft:grove");
BIOMES_BY_ID.put(179, "minecraft:snowy_slopes");
BIOMES_BY_ID.put(180, "minecraft:snowcapped_peaks");
BIOMES_BY_ID.put(181, "minecraft:lofty_peaks");
BIOMES_BY_ID.put(182, "minecraft:stony_peaks");
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
System.arraycopy()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.readTypedOrThrow()
- 引用位置:
-
- 引用位置:
参数/方法调用/构造调用 - 关联成员:
ChunkProtoTickListFix.PoorMansPalettedContainer(), PoorMansPalettedContainer()
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置: