use of org.spongepowered.api.world.extent.MutableBlockVolume in project SpongeCommon by SpongePowered.
the class SchematicTranslator method translate.
@Override
public Schematic translate(DataView view) throws InvalidDataException {
int version = view.getInt(DataQueries.Schematic.VERSION).get();
// TODO version conversions
if (version != VERSION) {
throw new InvalidDataException(String.format("Unknown schematic version %d (current version is %d)", version, VERSION));
}
DataView metadata = view.getView(DataQueries.Schematic.METADATA).orElse(null);
if (metadata != null) {
Optional<DataView> dot_data = metadata.getView(DataQuery.of("."));
if (dot_data.isPresent()) {
DataView data = dot_data.get();
for (DataQuery key : data.getKeys(false)) {
if (!metadata.contains(key)) {
metadata.set(key, data.get(key).get());
}
}
}
}
// TODO error handling for these optionals
int width = view.getShort(DataQueries.Schematic.WIDTH).get();
int height = view.getShort(DataQueries.Schematic.HEIGHT).get();
int length = view.getShort(DataQueries.Schematic.LENGTH).get();
if (width > MAX_SIZE || height > MAX_SIZE || length > MAX_SIZE) {
throw new InvalidDataException(String.format("Schematic is larger than maximum allowable size (found: (%d, %d, %d) max: (%d, %<d, %<d)", width, height, length, MAX_SIZE));
}
int[] offset = (int[]) view.get(DataQueries.Schematic.OFFSET).orElse(null);
if (offset == null) {
offset = new int[3];
}
if (offset.length != 3) {
throw new InvalidDataException("Schematic offset was not of length 3");
}
BlockPalette palette;
Optional<DataView> paletteData = view.getView(DataQueries.Schematic.PALETTE);
int palette_max = view.getInt(DataQueries.Schematic.PALETTE_MAX).orElse(0xFFFF);
if (paletteData.isPresent()) {
// If we had a default palette_max we don't want to allocate all
// that space for nothing so we use a sensible default instead
palette = new BimapPalette(palette_max != 0xFFFF ? palette_max : 64);
DataView paletteMap = paletteData.get();
Set<DataQuery> paletteKeys = paletteMap.getKeys(false);
for (DataQuery key : paletteKeys) {
BlockState state = Sponge.getRegistry().getType(BlockState.class, key.getParts().get(0)).get();
((BimapPalette) palette).assign(state, paletteMap.getInt(key).get());
}
} else {
palette = GlobalPalette.instance;
}
MutableBlockVolume buffer = new ArrayMutableBlockBuffer(palette, new Vector3i(-offset[0], -offset[1], -offset[2]), new Vector3i(width, height, length));
byte[] blockdata = (byte[]) view.get(DataQueries.Schematic.BLOCK_DATA).get();
int index = 0;
int i = 0;
int value = 0;
int varint_length = 0;
while (i < blockdata.length) {
value = 0;
varint_length = 0;
while (true) {
value |= (blockdata[i] & 127) << (varint_length++ * 7);
if (varint_length > 5) {
throw new RuntimeException("VarInt too big (probably corrupted data)");
}
if ((blockdata[i] & 128) != 128) {
i++;
break;
}
i++;
}
// index = (y * length + z) * width + x
int y = index / (width * length);
int z = (index % (width * length)) / width;
int x = (index % (width * length)) % width;
BlockState state = palette.get(value).get();
buffer.setBlock(x - offset[0], y - offset[1], z - offset[2], state);
index++;
}
Map<Vector3i, TileEntityArchetype> tiles = Maps.newHashMap();
List<DataView> tiledata = view.getViewList(DataQueries.Schematic.TILEENTITY_DATA).orElse(null);
if (tiledata != null) {
for (DataView tile : tiledata) {
int[] pos = (int[]) tile.get(DataQueries.Schematic.TILEENTITY_POS).get();
if (offset.length != 3) {
throw new InvalidDataException("Schematic tileentity pos was not of length 3");
}
TileEntityType type = TileEntityTypeRegistryModule.getInstance().getForClass(TileEntity.REGISTRY.getObject(new ResourceLocation(tile.getString(DataQuery.of("id")).get())));
TileEntityArchetype archetype = new SpongeTileEntityArchetypeBuilder().state(buffer.getBlock(pos[0] - offset[0], pos[1] - offset[1], pos[2] - offset[2])).tileData(tile).tile(type).build();
tiles.put(new Vector3i(pos[0] - offset[0], pos[1] - offset[1], pos[2] - offset[2]), archetype);
}
}
Schematic schematic = new SpongeSchematic(buffer, tiles, metadata);
return schematic;
}
use of org.spongepowered.api.world.extent.MutableBlockVolume in project SpongeCommon by SpongePowered.
the class DefaultedExtent method createArchetypeVolume.
@Override
default ArchetypeVolume createArchetypeVolume(Vector3i min, Vector3i max, Vector3i origin) {
Vector3i tmin = min.min(max);
Vector3i tmax = max.max(min);
min = tmin;
max = tmax;
Extent volume = getExtentView(min, max);
BimapPalette palette = new BimapPalette();
volume.getBlockWorker().iterate((v, x, y, z) -> {
palette.getOrAssign(v.getBlock(x, y, z));
});
int ox = origin.getX();
int oy = origin.getY();
int oz = origin.getZ();
final MutableBlockVolume backing = new ArrayMutableBlockBuffer(min.sub(origin), max.sub(min).add(1, 1, 1));
Map<Vector3i, TileEntityArchetype> tiles = Maps.newHashMap();
volume.getBlockWorker().iterate((extent, x, y, z) -> {
BlockState state = extent.getBlock(x, y, z);
backing.setBlock(x - ox, y - oy, z - oz, state);
Optional<TileEntity> tile = extent.getTileEntity(x, y, z);
if (tile.isPresent()) {
tiles.put(new Vector3i(x - ox, y - oy, z - oz), tile.get().createArchetype());
}
});
return new SpongeArchetypeVolume(backing, tiles);
}
use of org.spongepowered.api.world.extent.MutableBlockVolume in project SpongeCommon by SpongePowered.
the class SpongeSchematicBuilder method build.
@Override
public Schematic build() throws IllegalArgumentException {
if (this.palette == null) {
this.palette = this.type.create();
}
checkArgument(this.volume != null || this.view != null);
Vector3i min;
Vector3i size;
if (this.volume != null) {
min = this.volume.getBlockMin();
size = this.volume.getBlockSize();
} else {
min = this.view.getBlockMin();
size = this.view.getBlockSize();
}
if (this.metadata == null) {
this.metadata = DataContainer.createNew();
}
for (Map.Entry<String, Object> entry : this.metaValues.entrySet()) {
this.metadata.set(DataQuery.of('.', entry.getKey()), entry.getValue());
}
if (this.volume == null) {
final MutableBlockVolume volume = new ArrayMutableBlockBuffer(this.palette, min, size);
Map<Vector3i, TileEntityArchetype> tiles = Maps.newHashMap();
this.view.getBlockWorker().iterate((v, x, y, z) -> {
volume.setBlock(x, y, z, v.getBlock(x, y, z));
Optional<TileEntity> tile = v.getTileEntity(x, y, z);
if (tile.isPresent()) {
tiles.put(new Vector3i(x, y, z), tile.get().createArchetype());
}
});
return new SpongeSchematic(volume, tiles, this.metadata);
}
return new SpongeSchematic((SpongeArchetypeVolume) this.volume, this.metadata);
}
use of org.spongepowered.api.world.extent.MutableBlockVolume in project SpongeCommon by SpongePowered.
the class SpongeChunkGenerator method generateChunk.
@Override
public Chunk generateChunk(int chunkX, int chunkZ) {
this.rand.setSeed(chunkX * 341873128712L + chunkZ * 132897987541L);
this.cachedBiomes.reuse(new Vector3i(chunkX * 16, 0, chunkZ * 16));
this.biomeGenerator.generateBiomes(this.cachedBiomes);
ImmutableBiomeVolume biomeBuffer = this.cachedBiomes.getImmutableBiomeCopy();
// Generate base terrain
ChunkPrimer chunkprimer = new ChunkPrimer();
MutableBlockVolume blockBuffer = new ChunkPrimerBuffer(chunkprimer, chunkX, chunkZ);
this.baseGenerator.populate((org.spongepowered.api.world.World) this.world, blockBuffer, biomeBuffer);
if (!(this.baseGenerator instanceof SpongeGenerationPopulator)) {
replaceBiomeBlocks(this.world, this.rand, chunkX, chunkZ, chunkprimer, biomeBuffer);
}
// Apply the generator populators to complete the blockBuffer
for (GenerationPopulator populator : this.genpop) {
populator.populate((org.spongepowered.api.world.World) this.world, blockBuffer, biomeBuffer);
}
// Get unique biomes to determine what generator populators to run
List<BiomeType> uniqueBiomes = Lists.newArrayList();
BiomeType biome;
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
biome = this.cachedBiomes.getBiome(chunkX * 16 + x, 0, chunkZ * 16 + z);
if (!uniqueBiomes.contains(biome)) {
uniqueBiomes.add(biome);
}
}
}
// run our generator populators
for (BiomeType type : uniqueBiomes) {
BiomeGenerationSettings settings = getBiomeSettings(type);
for (GenerationPopulator populator : settings.getGenerationPopulators()) {
populator.populate((org.spongepowered.api.world.World) this.world, blockBuffer, biomeBuffer);
}
}
// Assemble chunk
Chunk chunk;
if (this.baseGenerator instanceof SpongeGenerationPopulator && ((SpongeGenerationPopulator) this.baseGenerator).getCachedChunk() != null) {
chunk = ((SpongeGenerationPopulator) this.baseGenerator).getCachedChunk();
((IMixinChunk) chunk).fill(chunkprimer);
} else {
chunk = new Chunk(this.world, chunkprimer, chunkX, chunkZ);
this.cachedBiomes.fill(chunk.getBiomeArray());
}
chunk.generateSkylightMap();
return chunk;
}
Aggregations