Search in sources :

Example 21 with LevelChunk

use of net.minecraft.world.level.chunk.LevelChunk in project SpongeCommon by SpongePowered.

the class LevelMixin_API method entityStream.

@SuppressWarnings("unchecked")
@Override
public VolumeStream<W, Entity> entityStream(final Vector3i min, final Vector3i max, final StreamOptions options) {
    VolumeStreamUtils.validateStreamArgs(Objects.requireNonNull(min, "min"), Objects.requireNonNull(max, "max"), Objects.requireNonNull(options, "options"));
    final boolean shouldCarbonCopy = options.carbonCopy();
    final Vector3i size = max.sub(min).add(1, 1, 1);
    @MonotonicNonNull final ObjectArrayMutableEntityBuffer backingVolume;
    if (shouldCarbonCopy) {
        backingVolume = new ObjectArrayMutableEntityBuffer(min, size);
    } else {
        backingVolume = null;
    }
    return VolumeStreamUtils.<W, Entity, net.minecraft.world.entity.Entity, ChunkAccess, UUID>generateStream(min, max, options, // Ref
    (W) this, // IdentityFunction
    VolumeStreamUtils.getOrCloneEntityWithVolume(shouldCarbonCopy, backingVolume, (Level) (Object) this), // ChunkAccessor
    VolumeStreamUtils.getChunkAccessorByStatus((LevelReader) (Object) this, options.loadingStyle().generateArea()), // Entity -> UniqueID
    (key, entity) -> entity.getUUID(), // Entity Accessor
    (chunk) -> chunk instanceof LevelChunk ? VolumeStreamUtils.getEntitiesFromChunk(min, max, (LevelChunk) chunk) : Stream.empty(), // Filtered Position Entity Accessor
    (entityUuid, world) -> {
        final net.minecraft.world.entity.@Nullable Entity entity = shouldCarbonCopy ? (net.minecraft.world.entity.Entity) backingVolume.entity(entityUuid).orElse(null) : (net.minecraft.world.entity.Entity) ((WorldLike) world).entity(entityUuid).orElse(null);
        if (entity == null) {
            return null;
        }
        return new Tuple<>(entity.blockPosition(), entity);
    });
}
Also used : HumanEntity(org.spongepowered.common.entity.living.human.HumanEntity) BlockEntity(org.spongepowered.api.block.entity.BlockEntity) Entity(org.spongepowered.api.entity.Entity) LevelReader(net.minecraft.world.level.LevelReader) ChunkAccess(net.minecraft.world.level.chunk.ChunkAccess) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) MonotonicNonNull(org.checkerframework.checker.nullness.qual.MonotonicNonNull) Vector3i(org.spongepowered.math.vector.Vector3i) ObjectArrayMutableEntityBuffer(org.spongepowered.common.world.volume.buffer.entity.ObjectArrayMutableEntityBuffer) Level(net.minecraft.world.level.Level) UUID(java.util.UUID) Nullable(org.checkerframework.checker.nullness.qual.Nullable) Tuple(net.minecraft.util.Tuple)

Example 22 with LevelChunk

use of net.minecraft.world.level.chunk.LevelChunk in project SpongeCommon by SpongePowered.

the class ChunkMapMixin method impl$onLoad.

@Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/chunk/LevelChunk;setLoaded(Z)V"), slice = @Slice(from = @At(value = "INVOKE", remap = false, target = "Lit/unimi/dsi/fastutil/longs/LongSet;add(J)Z"), to = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addAllPendingBlockEntities(Ljava/util/Collection;)V")))
private void impl$onLoad(final LevelChunk levelChunk, final boolean loaded) {
    levelChunk.setLoaded(true);
    final Vector3i chunkPos = new Vector3i(levelChunk.getPos().x, 0, levelChunk.getPos().z);
    if (ShouldFire.CHUNK_EVENT_LOAD) {
        final ChunkEvent.Load loadEvent = SpongeEventFactory.createChunkEventLoad(PhaseTracker.getInstance().currentCause(), ((WorldChunk) levelChunk), chunkPos, (ResourceKey) (Object) this.level.dimension().location());
        SpongeCommon.post(loadEvent);
    }
    for (final Direction dir : Constants.Chunk.CARDINAL_DIRECTIONS) {
        final Vector3i neighborPos = chunkPos.add(dir.asBlockOffset());
        ChunkAccess neighbor = this.level.getChunk(neighborPos.x(), neighborPos.z(), ChunkStatus.EMPTY, false);
        if (neighbor instanceof ImposterProtoChunk) {
            neighbor = ((ImposterProtoChunk) neighbor).getWrapped();
        }
        if (neighbor instanceof LevelChunk) {
            final int index = DirectionUtil.directionToIndex(dir);
            final int oppositeIndex = DirectionUtil.directionToIndex(dir.opposite());
            ((LevelChunkBridge) levelChunk).bridge$setNeighborChunk(index, (LevelChunk) neighbor);
            ((LevelChunkBridge) neighbor).bridge$setNeighborChunk(oppositeIndex, levelChunk);
        }
    }
}
Also used : ChunkAccess(net.minecraft.world.level.chunk.ChunkAccess) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) WorldChunk(org.spongepowered.api.world.chunk.WorldChunk) Vector3i(org.spongepowered.math.vector.Vector3i) ImposterProtoChunk(net.minecraft.world.level.chunk.ImposterProtoChunk) 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 23 with LevelChunk

use of net.minecraft.world.level.chunk.LevelChunk in project SpongeCommon by SpongePowered.

the class ChunkSerializerMixin_Tracker method impl$writeSpongeLevelData.

@Inject(method = "write", at = @At(value = "RETURN"))
private static void impl$writeSpongeLevelData(final ServerLevel param0, final ChunkAccess param1, final CallbackInfoReturnable<CompoundTag> cir) {
    if (!(param1 instanceof LevelChunk)) {
        return;
    }
    final LevelChunkBridge chunk = (LevelChunkBridge) param1;
    if (!chunk.bridge$getTrackedShortPlayerPositions().isEmpty() || !chunk.bridge$getTrackedIntPlayerPositions().isEmpty()) {
        final CompoundTag level = (CompoundTag) cir.getReturnValue().get("Level");
        final CompoundTag trackedNbt = new CompoundTag();
        final ListTag positions = new ListTag();
        trackedNbt.put(Constants.Sponge.SPONGE_BLOCK_POS_TABLE, positions);
        level.put(Constants.Sponge.Data.V2.SPONGE_DATA, trackedNbt);
        ChunkSerializerMixin_Tracker.impl$writeMap(positions, chunk.bridge$getTrackedShortPlayerPositions(), (nbt, pos) -> nbt.putShort("pos", pos));
        ChunkSerializerMixin_Tracker.impl$writeMap(positions, chunk.bridge$getTrackedIntPlayerPositions(), (nbt, pos) -> nbt.putInt("ipos", pos));
    }
}
Also used : LevelChunk(net.minecraft.world.level.chunk.LevelChunk) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) ListTag(net.minecraft.nbt.ListTag) CompoundTag(net.minecraft.nbt.CompoundTag) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 24 with LevelChunk

use of net.minecraft.world.level.chunk.LevelChunk in project SpongeCommon by SpongePowered.

the class ChunkSerializerMixin_Tracker method impl$readSpongeLevelData.

@Redirect(method = "read", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/chunk/ChunkAccess;setLightCorrect(Z)V"))
private static void impl$readSpongeLevelData(final ChunkAccess chunkAccess, final boolean var1, final ServerLevel param0, final StructureManager param1, final PoiManager param2, final ChunkPos param3, final CompoundTag param4) {
    if (!(chunkAccess instanceof LevelChunk)) {
        return;
    }
    final CompoundTag level = (CompoundTag) param4.get("Level");
    final CompoundTag spongeData = level.getCompound(Constants.Sponge.Data.V2.SPONGE_DATA);
    if (spongeData.isEmpty()) {
        return;
    }
    final Map<Integer, PlayerTracker> trackedIntPlayerPositions = new HashMap<>();
    final Map<Short, PlayerTracker> trackedShortPlayerPositions = new HashMap<>();
    final ListTag list = spongeData.getList(Constants.Sponge.SPONGE_BLOCK_POS_TABLE, 10);
    final LevelChunkBridge chunk = (LevelChunkBridge) chunkAccess;
    for (Tag tag : list) {
        final PlayerTracker tracker = new PlayerTracker();
        final CompoundTag data = (CompoundTag) tag;
        final boolean isShortPos = data.contains("pos");
        if (data.contains("owner")) {
            tracker.creatorindex = data.getInt("owner");
        }
        if (data.contains("notifier")) {
            tracker.notifierIndex = data.getInt("notifier");
        }
        if (tracker.notifierIndex != -1 || tracker.creatorindex != -1) {
            if (isShortPos) {
                trackedShortPlayerPositions.put(data.getShort("pos"), tracker);
            } else {
                trackedIntPlayerPositions.put(data.getInt("ipos"), tracker);
            }
        }
    }
    chunk.bridge$setTrackedIntPlayerPositions(trackedIntPlayerPositions);
    chunk.bridge$setTrackedShortPlayerPositions(trackedShortPlayerPositions);
}
Also used : LevelChunk(net.minecraft.world.level.chunk.LevelChunk) HashMap(java.util.HashMap) PlayerTracker(org.spongepowered.common.entity.PlayerTracker) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) Tag(net.minecraft.nbt.Tag) CompoundTag(net.minecraft.nbt.CompoundTag) ListTag(net.minecraft.nbt.ListTag) ListTag(net.minecraft.nbt.ListTag) CompoundTag(net.minecraft.nbt.CompoundTag) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 25 with LevelChunk

use of net.minecraft.world.level.chunk.LevelChunk in project SpongeCommon by SpongePowered.

the class IPhaseState method appendNotifierPreBlockTick.

/**
 * Appends additional information from the block's position in the world to provide notifier/owner
 * information. Overridden in world generation states to reduce chunk lookup costs and since
 * world generation does not track owners/notifiers.
 *  @param world The world reference
 * @param pos The position being updated
 * @param context The context
 * @param phaseContext the block tick context being entered
 */
default void appendNotifierPreBlockTick(final ServerLevel world, final BlockPos pos, final C context, final LocationBasedTickContext<@NonNull ?> phaseContext) {
    final LevelChunk chunk = world.getChunkAt(pos);
    final LevelChunkBridge mixinChunk = (LevelChunkBridge) chunk;
    if (chunk != null && !chunk.isEmpty()) {
        mixinChunk.bridge$getBlockCreatorUUID(pos).ifPresent(phaseContext::creator);
        mixinChunk.bridge$getBlockNotifierUUID(pos).ifPresent(phaseContext::notifier);
    }
}
Also used : LevelChunk(net.minecraft.world.level.chunk.LevelChunk) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge)

Aggregations

LevelChunk (net.minecraft.world.level.chunk.LevelChunk)36 BlockPos (net.minecraft.core.BlockPos)13 ChunkAccess (net.minecraft.world.level.chunk.ChunkAccess)10 ServerLevel (net.minecraft.server.level.ServerLevel)9 LevelChunkBridge (org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge)8 Vector3i (org.spongepowered.math.vector.Vector3i)7 BlockState (net.minecraft.world.level.block.state.BlockState)6 Nullable (org.checkerframework.checker.nullness.qual.Nullable)6 BlockEntity (org.spongepowered.api.block.entity.BlockEntity)5 BlockLight (com.denizenscript.denizen.nms.abstracts.BlockLight)4 ChunkCoordinate (com.denizenscript.denizen.utilities.blocks.ChunkCoordinate)4 UUID (java.util.UUID)4 Tuple (net.minecraft.util.Tuple)4 Level (net.minecraft.world.level.Level)4 MonotonicNonNull (org.checkerframework.checker.nullness.qual.MonotonicNonNull)4 CompoundTag (net.minecraft.nbt.CompoundTag)3 ChunkPos (net.minecraft.world.level.ChunkPos)3 PhaseTracker (org.spongepowered.common.event.tracking.PhaseTracker)3 SpongeBlockChangeFlag (org.spongepowered.common.world.SpongeBlockChangeFlag)3 BitSet (java.util.BitSet)2