Search in sources :

Example 11 with LevelChunkBridge

use of org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method handleCollideImpactEvent.

public static boolean handleCollideImpactEvent(final net.minecraft.world.entity.Entity projectile, @Nullable final ProjectileSource projectileSource, final HitResult movingObjectPosition) {
    final HitResult.Type movingObjectType = movingObjectPosition.getType();
    try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
        frame.pushCause(projectile);
        frame.addContext(EventContextKeys.PROJECTILE_SOURCE, projectileSource == null ? UnknownProjectileSource.UNKNOWN : projectileSource);
        final Optional<UUID> creator = PhaseTracker.getInstance().getPhaseContext().getCreator();
        creator.ifPresent(user -> frame.addContext(EventContextKeys.CREATOR, user));
        final ServerLocation impactPoint = ServerLocation.of((ServerWorld) projectile.level, VecHelper.toVector3d(movingObjectPosition.getLocation()));
        boolean cancelled = false;
        if (movingObjectType == HitResult.Type.BLOCK) {
            final BlockHitResult blockMovingObjectPosition = (BlockHitResult) movingObjectPosition;
            final BlockPos blockPos = blockMovingObjectPosition.getBlockPos();
            if (blockPos.getY() <= 0) {
                return false;
            }
            final BlockSnapshot targetBlock = ((ServerWorld) projectile.level).createSnapshot(blockPos.getX(), blockPos.getY(), blockPos.getZ());
            final Direction side = DirectionFacingProvider.INSTANCE.getKey(blockMovingObjectPosition.getDirection()).get();
            final CollideBlockEvent.Impact event = SpongeEventFactory.createCollideBlockEventImpact(frame.currentCause(), impactPoint, targetBlock.state(), targetBlock.location().get(), side);
            cancelled = SpongeCommon.post(event);
            // Track impact block if event is not cancelled
            if (!cancelled && creator.isPresent()) {
                final BlockPos targetPos = VecHelper.toBlockPos(impactPoint.blockPosition());
                final LevelChunkBridge spongeChunk = (LevelChunkBridge) projectile.level.getChunkAt(targetPos);
                spongeChunk.bridge$addTrackedBlockPosition((Block) targetBlock.state().type(), targetPos, creator.get(), PlayerTracker.Type.NOTIFIER);
            }
        } else if (movingObjectType == HitResult.Type.ENTITY) {
            // entity
            final EntityHitResult entityMovingObjectPosition = (EntityHitResult) movingObjectPosition;
            final ArrayList<Entity> entityList = new ArrayList<>();
            entityList.add((Entity) entityMovingObjectPosition.getEntity());
            final CollideEntityEvent.Impact event = SpongeEventFactory.createCollideEntityEventImpact(frame.currentCause(), entityList, impactPoint);
            cancelled = SpongeCommon.post(event);
        }
        return cancelled;
    }
}
Also used : JukeboxBlockEntity(net.minecraft.world.level.block.entity.JukeboxBlockEntity) Entity(org.spongepowered.api.entity.Entity) LivingEntity(net.minecraft.world.entity.LivingEntity) ServerLocation(org.spongepowered.api.world.server.ServerLocation) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) ArrayList(java.util.ArrayList) Direction(org.spongepowered.api.util.Direction) CollideBlockEvent(org.spongepowered.api.event.block.CollideBlockEvent) EntityHitResult(net.minecraft.world.phys.EntityHitResult) BlockHitResult(net.minecraft.world.phys.BlockHitResult) EntityHitResult(net.minecraft.world.phys.EntityHitResult) HitResult(net.minecraft.world.phys.HitResult) ServerWorld(org.spongepowered.api.world.server.ServerWorld) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockPos(net.minecraft.core.BlockPos) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) UUID(java.util.UUID) BlockHitResult(net.minecraft.world.phys.BlockHitResult)

Example 12 with LevelChunkBridge

use of org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge in project SpongeCommon by SpongePowered.

the class LocationBasedTickPhaseState method postBlockTransactionApplication.

@Override
public void postBlockTransactionApplication(final T context, final BlockChange blockChange, final BlockTransactionReceipt receipt) {
    // If we do not have a notifier at this point then there is no need to attempt to retrieve one from the chunk
    context.applyNotifierIfAvailable(user -> {
        final SpongeBlockSnapshot original = (SpongeBlockSnapshot) receipt.originalBlock();
        final Block block = (Block) original.state().type();
        final BlockPos changedBlockPos = original.getBlockPos();
        original.getServerWorld().ifPresent(worldServer -> {
            final LevelChunkBridge changedMixinChunk = (LevelChunkBridge) worldServer.getChunkAt(changedBlockPos);
            changedMixinChunk.bridge$addTrackedBlockPosition(block, changedBlockPos, user, PlayerTracker.Type.NOTIFIER);
            // to have new owners, which we can gather from the context.
            if (blockChange == BlockChange.PLACE) {
                context.applyOwnerIfAvailable(owner -> {
                    // We can do this when we check for notifiers because owners will always have a notifier set
                    // if not, well, file a bug report and find out the corner case that owners are set but not notifiers with block changes.
                    changedMixinChunk.bridge$addTrackedBlockPosition(block, changedBlockPos, owner, PlayerTracker.Type.CREATOR);
                });
            }
        });
    });
}
Also used : SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) LocatableBlock(org.spongepowered.api.world.LocatableBlock) Block(net.minecraft.world.level.block.Block) BlockPos(net.minecraft.core.BlockPos) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge)

Example 13 with LevelChunkBridge

use of org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge in project SpongeCommon by SpongePowered.

the class BlockEventTickPhaseState method associateNeighborStateNotifier.

@Override
public void associateNeighborStateNotifier(final BlockEventTickContext context, @Nullable final BlockPos sourcePos, final Block block, final BlockPos notifyPos, final ServerLevel minecraftWorld, final PlayerTracker.Type notifier) {
    // If we do not have a notifier at this point then there is no need to attempt to retrieve one from the chunk
    context.applyNotifierIfAvailable(user -> {
        final LevelChunkBridge mixinChunk = (LevelChunkBridge) minecraftWorld.getChunkAt(notifyPos);
        mixinChunk.bridge$addTrackedBlockPosition(block, notifyPos, user, PlayerTracker.Type.NOTIFIER);
    });
}
Also used : LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge)

Example 14 with LevelChunkBridge

use of org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge in project SpongeCommon by SpongePowered.

the class BlockEventTickPhaseState method postBlockTransactionApplication.

@Override
public void postBlockTransactionApplication(final BlockEventTickContext context, final BlockChange blockChange, final BlockTransactionReceipt receipt) {
    final Block block = (Block) receipt.originalBlock().state().type();
    final SpongeBlockSnapshot original = (SpongeBlockSnapshot) receipt.originalBlock();
    final BlockPos changedBlockPos = original.getBlockPos();
    original.getServerWorld().ifPresent(worldServer -> {
        final LevelChunkBridge changedMixinChunk = (LevelChunkBridge) worldServer.getChunkAt(changedBlockPos);
        changedMixinChunk.bridge$getBlockCreatorUUID(changedBlockPos).ifPresent(owner -> changedMixinChunk.bridge$addTrackedBlockPosition(block, changedBlockPos, owner, PlayerTracker.Type.CREATOR));
        changedMixinChunk.bridge$getBlockNotifierUUID(changedBlockPos).ifPresent(user -> changedMixinChunk.bridge$addTrackedBlockPosition(block, changedBlockPos, user, PlayerTracker.Type.NOTIFIER));
    });
}
Also used : SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) Block(net.minecraft.world.level.block.Block) BlockPos(net.minecraft.core.BlockPos) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge)

Example 15 with LevelChunkBridge

use of org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge in project SpongeCommon by SpongePowered.

the class SpongePacketHandler method init.

public static void init(final SpongeChannelManager registry) {
    SpongePacketHandler.channel = registry.createChannel(ResourceKey.sponge("default"), PacketChannel.class);
    SpongePacketHandler.channel.registerTransactional(RequestBlockTrackerDataPacket.class, TrackerDataResponsePacket.class, 0).setRequestHandler(EngineConnectionTypes.SERVER_PLAYER, (requestPacket, connection, response) -> {
        final ServerPlayer player = connection.player();
        if (!player.hasPermission("sponge.debug.block-tracking")) {
            return;
        }
        final net.minecraft.server.level.ServerPlayer sender = (net.minecraft.server.level.ServerPlayer) player;
        final BlockPos pos = new BlockPos(requestPacket.x, requestPacket.y, requestPacket.z);
        if (!sender.level.hasChunkAt(pos)) {
            return;
        }
        final LevelChunkBridge levelChunkBridge = (LevelChunkBridge) sender.level.getChunkAt(pos);
        final Optional<UUID> owner = levelChunkBridge.bridge$getBlockCreatorUUID(pos);
        final Optional<UUID> notifier = levelChunkBridge.bridge$getBlockNotifierUUID(pos);
        response.success(SpongePacketHandler.createTrackerDataResponse(owner, notifier));
    });
    SpongePacketHandler.channel.registerTransactional(RequestEntityTrackerDataPacket.class, TrackerDataResponsePacket.class, 1).setRequestHandler(EngineConnectionTypes.SERVER_PLAYER, (requestPacket, connection, response) -> {
        final ServerPlayer player = connection.player();
        if (!player.hasPermission("sponge.debug.entity-tracking")) {
            return;
        }
        final net.minecraft.server.level.ServerPlayer sender = (net.minecraft.server.level.ServerPlayer) player;
        final Entity entity = sender.level.getEntity(requestPacket.entityId);
        if (!(entity instanceof CreatorTrackedBridge)) {
            return;
        }
        final CreatorTrackedBridge creatorTrackedBridge = (CreatorTrackedBridge) entity;
        final Optional<UUID> owner = creatorTrackedBridge.tracker$getCreatorUUID();
        final Optional<UUID> notifier = creatorTrackedBridge.tracker$getNotifierUUID();
        response.success(SpongePacketHandler.createTrackerDataResponse(owner, notifier));
    });
    SpongePacketHandler.channel.register(ChangeViewerEnvironmentPacket.class, 3).addHandler(ClientSideConnection.class, (packet, connection) -> {
        final ClientLevel world = Minecraft.getInstance().level;
        if (world == null) {
            return;
        }
        final DimensionType dimensionType = SpongeCommon.server().registryAccess().dimensionTypes().get(packet.dimensionLogic);
        ((LevelBridge) world).bridge$adjustDimensionLogic(dimensionType);
    });
}
Also used : Entity(net.minecraft.world.entity.Entity) DimensionType(net.minecraft.world.level.dimension.DimensionType) CreatorTrackedBridge(org.spongepowered.common.bridge.CreatorTrackedBridge) ClientLevel(net.minecraft.client.multiplayer.ClientLevel) PacketChannel(org.spongepowered.api.network.channel.packet.PacketChannel) LevelBridge(org.spongepowered.common.bridge.world.level.LevelBridge) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) BlockPos(net.minecraft.core.BlockPos) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) UUID(java.util.UUID)

Aggregations

LevelChunkBridge (org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge)23 BlockPos (net.minecraft.core.BlockPos)9 LevelChunk (net.minecraft.world.level.chunk.LevelChunk)8 CreatorTrackedBridge (org.spongepowered.common.bridge.CreatorTrackedBridge)6 UUID (java.util.UUID)5 SpongeBlockSnapshot (org.spongepowered.common.block.SpongeBlockSnapshot)5 CompoundTag (net.minecraft.nbt.CompoundTag)4 ServerLocation (org.spongepowered.api.world.server.ServerLocation)4 ActiveChunkReferantBridge (org.spongepowered.common.bridge.world.level.chunk.ActiveChunkReferantBridge)4 TrackedLevelChunkBridge (org.spongepowered.common.bridge.world.level.chunk.TrackedLevelChunkBridge)4 ListTag (net.minecraft.nbt.ListTag)3 Block (net.minecraft.world.level.block.Block)3 CauseStackManager (org.spongepowered.api.event.CauseStackManager)3 Direction (org.spongepowered.api.util.Direction)3 Redirect (org.spongepowered.asm.mixin.injection.Redirect)3 Timing (co.aikar.timings.Timing)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Optional (java.util.Optional)2