finish MCAWriter

This commit is contained in:
Jesse Boyd 2019-04-10 22:04:22 +10:00
parent 808d32bc85
commit e03a43a1ab
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
5 changed files with 65 additions and 47 deletions

View File

@ -39,7 +39,7 @@ public class AsyncBlockState implements BlockState {
}
public int getTypeId() {
return combinedId & BlockTypes.BIT_MASK;
return BlockTypes.getFromStateId(combinedId).getInternalId();
}
public int getPropertyId() {
@ -160,7 +160,7 @@ public class AsyncBlockState implements BlockState {
@Override
public void setRawData(byte data) {
this.combinedId = (combinedId & BlockTypes.BIT_MASK) + (data << BlockTypes.BIT_OFFSET);
this.combinedId = getTypeId() + (data << BlockTypes.BIT_OFFSET);
this.blockData = BukkitAdapter.getBlockData(this.combinedId);
}

View File

@ -20,6 +20,7 @@ import com.boydti.fawe.util.image.ImageViewer;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.registry.state.PropertyKey;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
@ -80,7 +81,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
protected int worldThickness = 0;
protected boolean randomVariation = true;
protected int biomePriority = 0;
protected int waterId = BlockTypes.WATER.getInternalId();
protected int waterId = BlockID.WATER;
protected int bedrockId = BlockID.BEDROCK;
protected boolean modifiedMain = false;
@ -221,8 +222,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
floor = new DifferentialArray(new int[getArea()]);
main = new DifferentialArray(new int[getArea()]);
int stone = BlockTypes.STONE.getInternalId();
int grass = BlockTypes.GRASS_BLOCK.getInternalId();
int stone = BlockID.STONE;
int grass = BlockTypes.GRASS_BLOCK.getDefaultState().with(PropertyKey.SNOWY, false).getInternalId();
Arrays.fill(main.getIntArray(), stone);
Arrays.fill(floor.getIntArray(), grass);
}
@ -1684,7 +1685,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
chunk.hasSections[layer] = true;
}
if (primtives.waterHeight != 0) {
maxY = Math.max(maxY, primtives.waterHeight);
int maxIndex = (primtives.waterHeight) << 8;
Arrays.fill(chunk.blocks, 0, maxIndex, primtives.waterId);
}

View File

@ -647,11 +647,6 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
throw new UnsupportedOperationException("Not supported");
}
@Override
public IntFaweChunk getPrevious(IntFaweChunk fs, FaweChunk sections, Map<?, ?> tiles, Collection<?>[] entities, Set<UUID> createdEntities, boolean all) throws Exception {
throw new UnsupportedOperationException("Not supported");
}
@Override
public FaweQueue getImpWorld() {
return parent;

View File

@ -3,6 +3,7 @@ package com.boydti.fawe.jnbt.anvil;
import com.boydti.fawe.object.collection.IterableThreadLocal;
import com.boydti.fawe.object.io.BufferedRandomAccessFile;
import com.boydti.fawe.util.MainUtil;
import com.sk89q.worldedit.world.block.BlockID;
import java.io.File;
import java.io.IOException;
@ -82,6 +83,7 @@ public abstract class MCAWriter {
@Override
protected WritableMCAChunk initialValue() {
WritableMCAChunk chunk = new WritableMCAChunk();
Arrays.fill(chunk.blocks, BlockID.AIR);
Arrays.fill(chunk.skyLight, (byte) 255);
return chunk;
}

View File

@ -7,8 +7,10 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTConstants;
import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -73,11 +75,17 @@ public class WritableMCAChunk extends FaweChunk<Void> {
modified = 0;
deleted = false;
hasBiomes = false;
// TODO optimize
for (int i = 0; i < 65536; i++) {
blocks[i] = BlockID.AIR;
}
Arrays.fill(hasSections, false);
}
private transient final int[] blockToPalette = new int[BlockTypes.states.length];
private transient final boolean[] hasBlock = new boolean[BlockTypes.states.length];
{
Arrays.fill(blockToPalette, Integer.MAX_VALUE);
}
private transient final int[] paletteToBlock = new int[Character.MAX_VALUE];
private transient final long[] blockstates = new long[2048];
@ -105,51 +113,52 @@ public class WritableMCAChunk extends FaweChunk<Void> {
if (biomes != null) {
out.writeNamedTag("Biomes", biomes);
}
out.writeNamedTagName("Sections", NBTConstants.TYPE_LIST);
nbtOut.writeByte(NBTConstants.TYPE_COMPOUND);
int len = 0;
for (int layer = 0; layer < hasSections.length; layer++) {
if (hasSections[layer]) len++;
}
out.writeNamedTagName("Sections", NBTConstants.TYPE_LIST);
nbtOut.writeByte(NBTConstants.TYPE_COMPOUND);
nbtOut.writeInt(len);
for (int layer = 0; layer < hasSections.length; layer++) {
if (hasSections[layer]) {
continue;
}
if (!hasSections[layer]) continue;
out.writeNamedTag("Y", (byte) layer);
out.writeNamedTagName("BlockLight", NBTConstants.TYPE_BYTE_ARRAY);
out.writeInt(2048);
out.write(blockLight, layer << 11, 1 << 11);
out.writeNamedTagName("SkyLight", NBTConstants.TYPE_BYTE_ARRAY);
out.writeInt(2048);
out.write(skyLight, layer << 11, 1 << 11);
int blockIndexStart = layer << 8;
int blockIndexEnd = blockIndexStart << 1;
int blockIndexStart = layer << 12;
int blockIndexEnd = blockIndexStart + 4096;
int num_palette = 0;
try {
for (int i = blockIndexStart; i < blockIndexEnd; i++) {
int stateId = blocks[i];
int ordinal = BlockState.getFromInternalId(stateId).getOrdinal(); // TODO fixme Remove all use of BlockTypes.BIT_OFFSET so that this conversion isn't necessary
int palette = blockToPalette[ordinal];
if (palette == Integer.MAX_VALUE) {
BlockState state = BlockTypes.states[ordinal];
blockToPalette[ordinal] = palette = num_palette;
paletteToBlock[num_palette] = ordinal;
num_palette++;
}
blocks[i] = palette;
}
for (int i = 0; i < num_palette; i++) {
blockToPalette[paletteToBlock[i]] = Integer.MAX_VALUE;
}
out.writeNamedTagName("Palette", NBTConstants.TYPE_LIST);
out.writeByte(NBTConstants.TYPE_COMPOUND);
out.writeInt(num_palette);
for (int i = blockIndexStart; i < blockIndexEnd; i++) {
int stateId = blocks[i];
if (!hasBlock[stateId]) {
hasBlock[stateId] = true;
blockToPalette[stateId] = num_palette;
paletteToBlock[num_palette++] = stateId;
BlockState state = BlockTypes.states[stateId];
BlockType type = state.getBlockType();
out.writeNamedTag("Name", type.getId());
// Properties
if (type.getDefaultState() == state) continue;
for (int i = 0; i < num_palette; i++) {
int ordinal = paletteToBlock[i];
BlockState state = BlockTypes.states[ordinal];
BlockType type = state.getBlockType();
out.writeNamedTag("Name", type.getId());
// Has no properties
if (type.getDefaultState() != state) {
// Write properties
out.writeNamedTagName("Properties", NBTConstants.TYPE_COMPOUND);
for (Property<?> property : type.getProperties()) {
String key = property.getName();
@ -161,30 +170,42 @@ public class WritableMCAChunk extends FaweChunk<Void> {
}
out.writeNamedTag(key, valueStr);
}
out.writeByte(NBTConstants.TYPE_END);
out.writeEndTag();
}
out.writeEndTag();
}
// BlockStates
int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
int blockBitArrayEnd = (bitsPerEntry * 4096) >> 6;
if (num_palette == 1) {
Arrays.fill(blockstates, 0, blockBitArrayEnd, 0);
} else {
BitArray4096 bitArray = new BitArray4096(blockstates, bitsPerEntry);
bitArray.fromRaw(blocks, blockIndexStart);
}
BitArray4096 bitArray = new BitArray4096(blockstates, bitsPerEntry);
bitArray.fromRaw(blocks, blockIndexStart);
out.writeNamedTagName("BlockStates", NBTConstants.TYPE_LONG_ARRAY);
out.writeInt(blockBitArrayEnd);
for (int i = 0; i < blockBitArrayEnd; i++) out.writeLong(blockstates[i]);
out.writeNamedTagName("BlockLight", NBTConstants.TYPE_BYTE_ARRAY);
out.writeInt(2048);
out.write(blockLight, layer << 11, 1 << 11);
out.writeNamedTagName("SkyLight", NBTConstants.TYPE_BYTE_ARRAY);
out.writeInt(2048);
out.write(skyLight, layer << 11, 1 << 11);
out.writeEndTag();
// cleanup
} catch (Throwable e) {
for (int i = 0; i < num_palette; i++) {
hasBlock[i] = false;
}
Arrays.fill(blockToPalette, Integer.MAX_VALUE);
System.out.println("======================== exception e");
throw e;
}
}