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;
}
}
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);
});
}
});
});
}
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);
});
}
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));
});
}
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);
});
}
Aggregations