Search in sources :

Example 26 with Vector3i

use of org.spongepowered.math.vector.Vector3i in project SpongeCommon by SpongePowered.

the class SpongeAABBTest method testExpandVector3i.

@Test
void testExpandVector3i() {
    final AABB aabb1 = new SpongeAABB(new Vector3d(1, 2, 3), new Vector3d(7, 10, 13));
    final AABB aabb2 = new SpongeAABB(new Vector3d(-4, 3, 2.5), new Vector3d(12, 9, 13.5));
    Assertions.assertEquals(aabb2, aabb1.expand(new Vector3i(10, -2, 1)));
}
Also used : Vector3d(org.spongepowered.math.vector.Vector3d) Vector3i(org.spongepowered.math.vector.Vector3i) AABB(org.spongepowered.api.util.AABB) Test(org.junit.jupiter.api.Test)

Example 27 with Vector3i

use of org.spongepowered.math.vector.Vector3i in project SpongeCommon by SpongePowered.

the class SchematicUpdater2_to_3 method update.

@Override
public DataView update(final DataView content) {
    // Move BlockData, BlockPalette, BlockEntities -> Blocks.Data, Blocks.Palette, and Blocks.BlockEntities
    content.getView(Constants.Sponge.Schematic.Versions.V2_BLOCK_PALETTE).ifPresent(dataView -> {
        content.remove(Constants.Sponge.Schematic.Versions.V2_BLOCK_PALETTE);
        final byte[] blockData = (byte[]) content.get(Constants.Sponge.Schematic.BLOCK_DATA).orElseThrow(() -> new InvalidDataException("Missing BlockData for Schematic"));
        content.remove(Constants.Sponge.Schematic.Versions.V2_BLOCK_DATA);
        final List<DataView> blockEntities = content.getViewList(Constants.Sponge.Schematic.BLOCKENTITY_CONTAINER).orElse(Collections.emptyList());
        content.remove(Constants.Sponge.Schematic.BLOCKENTITY_CONTAINER);
        final DataView blockContainer = content.createView(Constants.Sponge.Schematic.BLOCK_CONTAINER);
        blockContainer.set(Constants.Sponge.Schematic.BLOCK_DATA, blockData);
        blockContainer.set(Constants.Sponge.Schematic.BLOCK_PALETTE, dataView);
        blockContainer.set(Constants.Sponge.Schematic.BLOCKENTITY_CONTAINER, blockEntities);
    });
    // Move BiomeData, BiomePalette -> Biomes.Data and Biomes.Palette
    content.get(Constants.Sponge.Schematic.Versions.V2_BIOME_DATA).ifPresent(biomeData -> {
        content.remove(Constants.Sponge.Schematic.Versions.V2_BIOME_DATA);
        // But first, convert from a 2D array to a 3D array, which basically means almost fully deserializing
        // the entirety of the biome into a new buffer.
        final int[] offset = (int[]) content.get(Constants.Sponge.Schematic.OFFSET).orElse(new int[3]);
        if (offset.length != 3) {
            throw new InvalidDataException("Schematic offset was not of length 3");
        }
        final int xOffset = offset[0];
        final int yOffset = offset[1];
        final int zOffset = offset[2];
        final DataView palette = content.getView(Constants.Sponge.Schematic.Versions.V2_BIOME_PALETTE).orElseThrow(() -> new InvalidDataException("Missing Biome Palette for schematic"));
        final int width = content.getShort(Constants.Sponge.Schematic.WIDTH).orElseThrow(() -> new InvalidDataException("Missing value for: " + Constants.Sponge.Schematic.WIDTH));
        final int height = content.getShort(Constants.Sponge.Schematic.HEIGHT).orElseThrow(() -> new InvalidDataException("Missing value for: " + Constants.Sponge.Schematic.HEIGHT));
        final int length = content.getShort(Constants.Sponge.Schematic.LENGTH).orElseThrow(() -> new InvalidDataException("Missing value for: " + Constants.Sponge.Schematic.LENGTH));
        final Set<DataQuery> biomeKeys = palette.keys(false);
        final Registry<Biome> biomeRegistry = VolumeStreamUtils.nativeToSpongeRegistry(BuiltinRegistries.BIOME);
        final MutableBimapPalette<Biome, Biome> biomePalette = new MutableBimapPalette<>(PaletteTypes.BIOME_PALETTE.get(), biomeRegistry, RegistryTypes.BIOME, biomeKeys.size());
        final ByteArrayMutableBiomeBuffer biomeBuffer = new ByteArrayMutableBiomeBuffer(biomePalette, new Vector3i(-xOffset, -yOffset, -zOffset), new Vector3i(width, height, length));
        final DataView biomeView = content.createView(Constants.Sponge.Schematic.BIOME_CONTAINER);
        biomeView.set(Constants.Sponge.Schematic.BLOCK_PALETTE, palette);
        final byte[] biomes = (byte[]) biomeData;
        int biomeIndex = 0;
        int biomeJ = 0;
        int bVal = 0;
        int varIntLength = 0;
        final int yMin = biomeBuffer.min().y();
        final int yMax = biomeBuffer.max().y();
        while (biomeJ < biomes.length) {
            bVal = 0;
            varIntLength = 0;
            while (true) {
                bVal |= (biomes[biomeJ] & 127) << (varIntLength++ * 7);
                if (varIntLength > 5) {
                    throw new RuntimeException("VarInt too big (probably corrupted data)");
                }
                if (((biomes[biomeJ] & 128) != 128)) {
                    biomeJ++;
                    break;
                }
                biomeJ++;
            }
            final int z = (biomeIndex % (width * length)) / width;
            final int x = (biomeIndex % (width * length)) % width;
            final Biome type = biomePalette.get(bVal, Sponge.server()).get();
            for (int y = yMin; y <= yMax; y++) {
                biomeBuffer.setBiome(x - xOffset, y, z - zOffset, type);
            }
            biomeIndex++;
        }
        try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length)) {
            final int xMin = biomeBuffer.min().x();
            final int zMin = biomeBuffer.min().z();
            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 biome = biomeBuffer.biome(x0, y0, z0);
                        SchematicTranslator.writeIdToBuffer(buffer, biomePalette.orAssign(biome));
                    }
                }
            }
            content.set(Constants.Sponge.Schematic.BIOME_DATA, buffer.toByteArray());
        } catch (final IOException e) {
        // Should never reach here.
        }
        content.remove(Constants.Sponge.Schematic.Versions.V2_BIOME_PALETTE);
    });
    content.set(Constants.Sponge.Schematic.VERSION, 3);
    return content;
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) DataView(org.spongepowered.api.data.persistence.DataView) Biome(org.spongepowered.api.world.biome.Biome) InvalidDataException(org.spongepowered.api.data.persistence.InvalidDataException) Vector3i(org.spongepowered.math.vector.Vector3i) MutableBimapPalette(org.spongepowered.common.world.schematic.MutableBimapPalette) DataQuery(org.spongepowered.api.data.persistence.DataQuery) ByteArrayMutableBiomeBuffer(org.spongepowered.common.world.volume.buffer.biome.ByteArrayMutableBiomeBuffer)

Example 28 with Vector3i

use of org.spongepowered.math.vector.Vector3i in project SpongeCommon by SpongePowered.

the class ChunkMapMixin method impl$onSetUnloaded.

@Redirect(method = "lambda$scheduleUnload$10", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;unload(Lnet/minecraft/world/level/chunk/LevelChunk;)V"), slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ChunkMap;save(Lnet/minecraft/world/level/chunk/ChunkAccess;)Z")))
private void impl$onSetUnloaded(final ServerLevel level, final LevelChunk chunk) {
    final Vector3i chunkPos = new Vector3i(chunk.getPos().x, 0, chunk.getPos().z);
    if (ShouldFire.CHUNK_EVENT_UNLOAD_PRE) {
        final ChunkEvent.Unload event = SpongeEventFactory.createChunkEventUnloadPre(PhaseTracker.getInstance().currentCause(), (WorldChunk) chunk, chunkPos, (ResourceKey) (Object) this.level.dimension().location());
        SpongeCommon.post(event);
    }
    level.unload(chunk);
    for (final Direction dir : Constants.Chunk.CARDINAL_DIRECTIONS) {
        final Vector3i neighborPos = chunkPos.add(dir.asBlockOffset());
        final ChunkAccess neighbor = this.level.getChunk(neighborPos.x(), neighborPos.z(), ChunkStatus.EMPTY, false);
        if (neighbor instanceof LevelChunk) {
            final int index = DirectionUtil.directionToIndex(dir);
            final int oppositeIndex = DirectionUtil.directionToIndex(dir.opposite());
            ((LevelChunkBridge) chunk).bridge$setNeighborChunk(index, null);
            ((LevelChunkBridge) neighbor).bridge$setNeighborChunk(oppositeIndex, null);
        }
    }
    if (ShouldFire.CHUNK_EVENT_UNLOAD_POST) {
        final ChunkEvent.Unload event = SpongeEventFactory.createChunkEventUnloadPost(PhaseTracker.getInstance().currentCause(), chunkPos, (ResourceKey) (Object) this.level.dimension().location());
        SpongeCommon.post(event);
    }
}
Also used : ChunkAccess(net.minecraft.world.level.chunk.ChunkAccess) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) Vector3i(org.spongepowered.math.vector.Vector3i) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) ChunkEvent(org.spongepowered.api.event.world.chunk.ChunkEvent) Direction(org.spongepowered.api.util.Direction) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 29 with Vector3i

use of org.spongepowered.math.vector.Vector3i in project SpongeCommon by SpongePowered.

the class ChunkMapMixin method impl$onSaved.

@Inject(method = "save", at = @At(value = "RETURN"))
private void impl$onSaved(final ChunkAccess var1, final CallbackInfoReturnable<Boolean> cir) {
    if (ShouldFire.CHUNK_EVENT_SAVE_POST) {
        final Vector3i chunkPos = new Vector3i(var1.getPos().x, 0, var1.getPos().z);
        final ChunkEvent.Save.Post postSave = SpongeEventFactory.createChunkEventSavePost(PhaseTracker.getInstance().currentCause(), chunkPos, (ResourceKey) (Object) this.level.dimension().location());
        SpongeCommon.post(postSave);
    }
}
Also used : Vector3i(org.spongepowered.math.vector.Vector3i) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 30 with Vector3i

use of org.spongepowered.math.vector.Vector3i in project SpongeCommon by SpongePowered.

the class ChunkHolderMixin method impl$throwChunkGeneratedEvent.

@Inject(method = "replaceProtoChunk(Lnet/minecraft/world/level/chunk/ImposterProtoChunk;)V", at = @At("TAIL"))
private void impl$throwChunkGeneratedEvent(final ImposterProtoChunk imposter, final CallbackInfo ci) {
    if (!ShouldFire.CHUNK_EVENT_GENERATED) {
        return;
    }
    final LevelChunk chunk = imposter.getWrapped();
    final Vector3i chunkPos = VecHelper.toVector3i(chunk.getPos());
    final ChunkEvent.Generated event = SpongeEventFactory.createChunkEventGenerated(PhaseTracker.getInstance().currentCause(), chunkPos, (ResourceKey) (Object) chunk.getLevel().dimension().location());
    SpongeCommon.post(event);
}
Also used : LevelChunk(net.minecraft.world.level.chunk.LevelChunk) Vector3i(org.spongepowered.math.vector.Vector3i) ChunkEvent(org.spongepowered.api.event.world.chunk.ChunkEvent) Inject(org.spongepowered.asm.mixin.injection.Inject)

Aggregations

Vector3i (org.spongepowered.math.vector.Vector3i)59 Vector3d (org.spongepowered.math.vector.Vector3d)22 Nullable (org.checkerframework.checker.nullness.qual.Nullable)15 BlockPos (net.minecraft.core.BlockPos)14 BlockState (org.spongepowered.api.block.BlockState)14 Stream (java.util.stream.Stream)13 ChunkAccess (net.minecraft.world.level.chunk.ChunkAccess)12 StreamOptions (org.spongepowered.api.world.volume.stream.StreamOptions)12 MonotonicNonNull (org.checkerframework.checker.nullness.qual.MonotonicNonNull)11 VolumeElement (org.spongepowered.api.world.volume.stream.VolumeElement)11 Tuple (net.minecraft.util.Tuple)10 LevelChunk (net.minecraft.world.level.chunk.LevelChunk)10 VolumeStream (org.spongepowered.api.world.volume.stream.VolumeStream)10 Function (java.util.function.Function)9 Biome (org.spongepowered.api.world.biome.Biome)9 Collection (java.util.Collection)8 Objects (java.util.Objects)8 Optional (java.util.Optional)8 UUID (java.util.UUID)8 Entity (org.spongepowered.api.entity.Entity)8