Search in sources :

Example 1 with Palette

use of org.spongepowered.api.world.schematic.Palette in project SpongeCommon by SpongePowered.

the class SchematicTranslator method addTo.

@Override
public DataView addTo(final Schematic schematic, final DataView data) {
    final int xMin = schematic.min().x();
    final int yMin = schematic.min().y();
    final int zMin = schematic.min().z();
    final int width = schematic.size().x();
    final int height = schematic.size().y();
    final int length = schematic.size().z();
    if (width > Constants.Sponge.Schematic.MAX_SIZE || height > Constants.Sponge.Schematic.MAX_SIZE || length > Constants.Sponge.Schematic.MAX_SIZE) {
        throw new IllegalArgumentException(String.format("Schematic is larger than maximum allowable size (found: (%d, %d, %d) max: (%d, %<d, %<d)", width, height, length, Constants.Sponge.Schematic.MAX_SIZE));
    }
    data.set(Constants.Sponge.Schematic.WIDTH, (short) width);
    data.set(Constants.Sponge.Schematic.HEIGHT, (short) height);
    data.set(Constants.Sponge.Schematic.LENGTH, (short) length);
    data.set(Constants.Sponge.Schematic.VERSION, Constants.Sponge.Schematic.CURRENT_VERSION);
    data.set(Constants.Sponge.Schematic.DATA_VERSION, SharedConstants.getCurrentVersion().getWorldVersion());
    for (final DataQuery metaKey : schematic.metadata().keys(false)) {
        data.set(Constants.Sponge.Schematic.METADATA.then(metaKey), schematic.metadata().get(metaKey).get());
    }
    final Set<String> requiredMods = new HashSet<>();
    final int[] offset = new int[] { xMin, yMin, zMin };
    data.set(Constants.Sponge.Schematic.OFFSET, offset);
    // Check if we have blocks to store
    if (schematic.blockPalette().highestId() != 0) {
        final DataView blockData = data.createView(Constants.Sponge.Schematic.BLOCK_CONTAINER);
        final Palette.Mutable<BlockState, BlockType> palette = schematic.blockPalette().asMutable(Sponge.server());
        try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length)) {
            for (int y = 0; y < height; y++) {
                final int y0 = yMin + y;
                for (int z = 0; z < length; z++) {
                    final int z0 = zMin + z;
                    for (int x = 0; x < width; x++) {
                        final int x0 = xMin + x;
                        final BlockState state = schematic.block(x0, y0, z0);
                        SchematicTranslator.writeIdToBuffer(buffer, palette.orAssign(state));
                    }
                }
            }
            blockData.set(Constants.Sponge.Schematic.BLOCK_DATA, buffer.toByteArray());
        } catch (final IOException e) {
        // should never reach here
        }
        final Registry<BlockType> blockRegistry = VolumeStreamUtils.nativeToSpongeRegistry(net.minecraft.core.Registry.BLOCK);
        SchematicTranslator.writePaletteToView(blockData, palette, blockRegistry, Constants.Sponge.Schematic.BLOCK_PALETTE, BlockState::type, requiredMods);
        final List<DataView> blockEntities = schematic.blockEntityArchetypes().entrySet().stream().map(entry -> {
            final DataContainer container = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
            final Vector3i pos = entry.getKey();
            final BlockEntityArchetype archetype = entry.getValue();
            final DataContainer entityData = archetype.blockEntityData();
            final int[] apos = new int[] { pos.x() - xMin, pos.y() - yMin, pos.z() - zMin };
            container.set(Constants.Sponge.Schematic.BLOCKENTITY_POS, apos);
            container.set(Constants.Sponge.Schematic.BLOCKENTITY_DATA, entityData);
            final ResourceKey key = archetype.blockEntityType().key(RegistryTypes.BLOCK_ENTITY_TYPE);
            container.set(Constants.Sponge.Schematic.ENTITIES_ID, key.asString());
            final String namespace = key.namespace();
            if (!ResourceKey.MINECRAFT_NAMESPACE.equals(namespace)) {
                requiredMods.add(namespace);
            }
            return container;
        }).collect(Collectors.toList());
        blockData.set(Constants.Sponge.Schematic.BLOCKENTITY_CONTAINER, blockEntities);
    }
    if (schematic.biomePalette().highestId() != 0) {
        final DataView biomeContainer = data.createView(Constants.Sponge.Schematic.BIOME_CONTAINER);
        final Palette.Mutable<Biome, Biome> biomePalette = schematic.biomePalette().asMutable(Sponge.game());
        try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length)) {
            for (int y = 0; y < height; y++) {
                final int y0 = yMin + y;
                for (int z = 0; z < length; z++) {
                    final int z0 = zMin + z;
                    for (int x = 0; x < width; x++) {
                        final int x0 = xMin + x;
                        final Biome state = schematic.biome(x0, y0, z0);
                        SchematicTranslator.writeIdToBuffer(buffer, biomePalette.orAssign(state));
                    }
                }
            }
            biomeContainer.set(Constants.Sponge.Schematic.BIOME_DATA, buffer.toByteArray());
        } catch (final IOException e) {
        // Should never reach here.
        }
        final Registry<Biome> biomeRegistry = VolumeStreamUtils.nativeToSpongeRegistry(BuiltinRegistries.BIOME);
        SchematicTranslator.writePaletteToView(biomeContainer, biomePalette, biomeRegistry, Constants.Sponge.Schematic.BIOME_PALETTE, Function.identity(), requiredMods);
    }
    final List<DataView> entities = schematic.entityArchetypesByPosition().stream().map(entry -> {
        final DataContainer container = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
        final List<Double> entityPosition = new ArrayList<>();
        entityPosition.add(entry.position().x());
        entityPosition.add(entry.position().y());
        entityPosition.add(entry.position().z());
        container.set(Constants.Sponge.Schematic.ENTITIES_POS, entityPosition);
        final ResourceKey key = entry.archetype().type().key(RegistryTypes.ENTITY_TYPE);
        if (!ResourceKey.MINECRAFT_NAMESPACE.equals(key.namespace())) {
            requiredMods.add(key.namespace());
        }
        container.set(Constants.Sponge.Schematic.ENTITIES_ID, key.toString());
        final DataContainer entityData = entry.archetype().entityData();
        container.set(Constants.Sponge.Schematic.BLOCKENTITY_DATA, entityData);
        return container;
    }).collect(Collectors.toList());
    data.set(Constants.Sponge.Schematic.ENTITIES, entities);
    if (!requiredMods.isEmpty()) {
        data.set(Constants.Sponge.Schematic.METADATA.then(Constants.Sponge.Schematic.REQUIRED_MODS), requiredMods);
    }
    return data;
}
Also used : DataFixTypes(net.minecraft.util.datafix.DataFixTypes) SpongeEntityArchetypeBuilder(org.spongepowered.common.entity.SpongeEntityArchetypeBuilder) Biome(org.spongepowered.api.world.biome.Biome) PaletteTypes(org.spongepowered.api.world.schematic.PaletteTypes) DataQuery(org.spongepowered.api.data.persistence.DataQuery) BlockEntityArchetype(org.spongepowered.api.block.entity.BlockEntityArchetype) BuiltinRegistries(net.minecraft.data.BuiltinRegistries) BiomeVolume(org.spongepowered.api.world.volume.biome.BiomeVolume) NbtUtils(net.minecraft.nbt.NbtUtils) BlockTypes(org.spongepowered.api.block.BlockTypes) Sponge(org.spongepowered.api.Sponge) Set(java.util.Set) TypeToken(io.leangen.geantyref.TypeToken) Collectors(java.util.stream.Collectors) BlockState(org.spongepowered.api.block.BlockState) SpongeBlockEntityArchetypeBuilder(org.spongepowered.common.block.entity.SpongeBlockEntityArchetypeBuilder) List(java.util.List) CompoundTag(net.minecraft.nbt.CompoundTag) Stream(java.util.stream.Stream) SpongeArchetypeVolume(org.spongepowered.common.world.volume.buffer.archetype.SpongeArchetypeVolume) VolumeStreamUtils(org.spongepowered.common.world.volume.VolumeStreamUtils) BlockType(org.spongepowered.api.block.BlockType) DataTranslator(org.spongepowered.api.data.persistence.DataTranslator) EntityArchetypeEntry(org.spongepowered.api.world.volume.archetype.entity.EntityArchetypeEntry) Optional(java.util.Optional) NotNull(org.jetbrains.annotations.NotNull) NonNull(org.checkerframework.checker.nullness.qual.NonNull) DataContainer(org.spongepowered.api.data.persistence.DataContainer) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Schematic(org.spongepowered.api.world.schematic.Schematic) Constants(org.spongepowered.common.util.Constants) Registry(org.spongepowered.api.registry.Registry) DataView(org.spongepowered.api.data.persistence.DataView) Function(java.util.function.Function) NBTTranslator(org.spongepowered.common.data.persistence.NBTTranslator) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SharedConstants(net.minecraft.SharedConstants) ResourceKey(org.spongepowered.api.ResourceKey) BlockStateSerializerDeserializer(org.spongepowered.common.block.BlockStateSerializerDeserializer) Nullable(org.checkerframework.checker.nullness.qual.Nullable) SchematicUpdater2_to_3(org.spongepowered.common.data.persistence.schematic.SchematicUpdater2_to_3) DataContentUpdater(org.spongepowered.api.data.persistence.DataContentUpdater) SchematicUpdater1_to_2(org.spongepowered.common.data.persistence.schematic.SchematicUpdater1_to_2) InvalidDataException(org.spongepowered.api.data.persistence.InvalidDataException) IOException(java.io.IOException) Palette(org.spongepowered.api.world.schematic.Palette) SpongeCommon(org.spongepowered.common.SpongeCommon) DataFixer(com.mojang.datafixers.DataFixer) RegistryTypes(org.spongepowered.api.registry.RegistryTypes) Consumer(java.util.function.Consumer) Vector3d(org.spongepowered.math.vector.Vector3d) ConcurrentSkipListSet(java.util.concurrent.ConcurrentSkipListSet) EntityType(org.spongepowered.api.entity.EntityType) BlockVolume(org.spongepowered.api.world.volume.block.BlockVolume) EntityArchetype(org.spongepowered.api.entity.EntityArchetype) Vector3i(org.spongepowered.math.vector.Vector3i) Palette(org.spongepowered.api.world.schematic.Palette) BlockEntityArchetype(org.spongepowered.api.block.entity.BlockEntityArchetype) DataContainer(org.spongepowered.api.data.persistence.DataContainer) Biome(org.spongepowered.api.world.biome.Biome) DataQuery(org.spongepowered.api.data.persistence.DataQuery) List(java.util.List) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ResourceKey(org.spongepowered.api.ResourceKey) DataView(org.spongepowered.api.data.persistence.DataView) BlockState(org.spongepowered.api.block.BlockState) BlockType(org.spongepowered.api.block.BlockType) Vector3i(org.spongepowered.math.vector.Vector3i)

Aggregations

DataFixer (com.mojang.datafixers.DataFixer)1 TypeToken (io.leangen.geantyref.TypeToken)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Optional (java.util.Optional)1 Set (java.util.Set)1 ConcurrentSkipListSet (java.util.concurrent.ConcurrentSkipListSet)1 Consumer (java.util.function.Consumer)1 Function (java.util.function.Function)1 Collectors (java.util.stream.Collectors)1 Stream (java.util.stream.Stream)1 SharedConstants (net.minecraft.SharedConstants)1 BuiltinRegistries (net.minecraft.data.BuiltinRegistries)1 CompoundTag (net.minecraft.nbt.CompoundTag)1 NbtUtils (net.minecraft.nbt.NbtUtils)1 DataFixTypes (net.minecraft.util.datafix.DataFixTypes)1 NonNull (org.checkerframework.checker.nullness.qual.NonNull)1