Search in sources :

Example 1 with MutableBlockVolume

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;
}
Also used : BlockPalette(org.spongepowered.api.world.schematic.BlockPalette) MutableBlockVolume(org.spongepowered.api.world.extent.MutableBlockVolume) BimapPalette(org.spongepowered.common.world.schematic.BimapPalette) ArrayMutableBlockBuffer(org.spongepowered.common.util.gen.ArrayMutableBlockBuffer) SpongeTileEntityArchetypeBuilder(org.spongepowered.common.block.SpongeTileEntityArchetypeBuilder) DataView(org.spongepowered.api.data.DataView) SpongeSchematic(org.spongepowered.common.world.schematic.SpongeSchematic) BlockState(org.spongepowered.api.block.BlockState) TileEntityType(org.spongepowered.api.block.tileentity.TileEntityType) ResourceLocation(net.minecraft.util.ResourceLocation) InvalidDataException(org.spongepowered.api.data.persistence.InvalidDataException) Vector3i(com.flowpowered.math.vector.Vector3i) DataQuery(org.spongepowered.api.data.DataQuery) TileEntityArchetype(org.spongepowered.api.block.tileentity.TileEntityArchetype) Schematic(org.spongepowered.api.world.schematic.Schematic) SpongeSchematic(org.spongepowered.common.world.schematic.SpongeSchematic)

Example 2 with MutableBlockVolume

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);
}
Also used : TileEntity(org.spongepowered.api.block.tileentity.TileEntity) MutableBlockVolume(org.spongepowered.api.world.extent.MutableBlockVolume) BlockState(org.spongepowered.api.block.BlockState) SpongeArchetypeVolume(org.spongepowered.common.world.schematic.SpongeArchetypeVolume) Extent(org.spongepowered.api.world.extent.Extent) Vector3i(com.flowpowered.math.vector.Vector3i) BimapPalette(org.spongepowered.common.world.schematic.BimapPalette) TileEntityArchetype(org.spongepowered.api.block.tileentity.TileEntityArchetype) ArrayMutableBlockBuffer(org.spongepowered.common.util.gen.ArrayMutableBlockBuffer)

Example 3 with MutableBlockVolume

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);
}
Also used : TileEntity(org.spongepowered.api.block.tileentity.TileEntity) MutableBlockVolume(org.spongepowered.api.world.extent.MutableBlockVolume) Vector3i(com.flowpowered.math.vector.Vector3i) TileEntityArchetype(org.spongepowered.api.block.tileentity.TileEntityArchetype) Map(java.util.Map) ArrayMutableBlockBuffer(org.spongepowered.common.util.gen.ArrayMutableBlockBuffer)

Example 4 with MutableBlockVolume

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;
}
Also used : ImmutableBiomeVolume(org.spongepowered.api.world.extent.ImmutableBiomeVolume) MutableBlockVolume(org.spongepowered.api.world.extent.MutableBlockVolume) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) ChunkPrimerBuffer(org.spongepowered.common.util.gen.ChunkPrimerBuffer) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Chunk(net.minecraft.world.chunk.Chunk) ChunkPrimer(net.minecraft.world.chunk.ChunkPrimer) BiomeType(org.spongepowered.api.world.biome.BiomeType) ChunkGeneratorOverworld(net.minecraft.world.gen.ChunkGeneratorOverworld) IChunkProviderOverworld(org.spongepowered.common.interfaces.world.gen.IChunkProviderOverworld) GenerationPopulator(org.spongepowered.api.world.gen.GenerationPopulator) IGenerationPopulator(org.spongepowered.common.interfaces.world.gen.IGenerationPopulator) Vector3i(com.flowpowered.math.vector.Vector3i) BiomeGenerationSettings(org.spongepowered.api.world.biome.BiomeGenerationSettings) SpongeBiomeGenerationSettings(org.spongepowered.common.world.biome.SpongeBiomeGenerationSettings)

Aggregations

Vector3i (com.flowpowered.math.vector.Vector3i)4 MutableBlockVolume (org.spongepowered.api.world.extent.MutableBlockVolume)4 TileEntityArchetype (org.spongepowered.api.block.tileentity.TileEntityArchetype)3 ArrayMutableBlockBuffer (org.spongepowered.common.util.gen.ArrayMutableBlockBuffer)3 BlockState (org.spongepowered.api.block.BlockState)2 TileEntity (org.spongepowered.api.block.tileentity.TileEntity)2 BimapPalette (org.spongepowered.common.world.schematic.BimapPalette)2 Map (java.util.Map)1 ResourceLocation (net.minecraft.util.ResourceLocation)1 Chunk (net.minecraft.world.chunk.Chunk)1 ChunkPrimer (net.minecraft.world.chunk.ChunkPrimer)1 ChunkGeneratorOverworld (net.minecraft.world.gen.ChunkGeneratorOverworld)1 TileEntityType (org.spongepowered.api.block.tileentity.TileEntityType)1 DataQuery (org.spongepowered.api.data.DataQuery)1 DataView (org.spongepowered.api.data.DataView)1 InvalidDataException (org.spongepowered.api.data.persistence.InvalidDataException)1 BiomeGenerationSettings (org.spongepowered.api.world.biome.BiomeGenerationSettings)1 BiomeType (org.spongepowered.api.world.biome.BiomeType)1 Extent (org.spongepowered.api.world.extent.Extent)1 ImmutableBiomeVolume (org.spongepowered.api.world.extent.ImmutableBiomeVolume)1