use of org.spongepowered.common.world.server.SpongeLocatableBlockBuilder in project SpongeCommon by SpongePowered.
the class PlaceBlockPacketState method appendNotifierToBlockEvent.
@Override
public void appendNotifierToBlockEvent(final BasicPacketContext context, final TrackedWorldBridge mixinWorldServer, final BlockPos pos, final TrackableBlockEventDataBridge blockEvent) {
final Player player = PhaseTracker.getCauseStackManager().currentCause().first(Player.class).get();
final BlockState state = ((ServerWorld) mixinWorldServer).block(pos.getX(), pos.getY(), pos.getZ());
final LocatableBlock locatable = new SpongeLocatableBlockBuilder().world((ServerWorld) mixinWorldServer).position(pos.getX(), pos.getY(), pos.getZ()).state(state).build();
blockEvent.bridge$setTickingLocatable(locatable);
blockEvent.bridge$setSourceUserUUID(player.uniqueId());
}
use of org.spongepowered.common.world.server.SpongeLocatableBlockBuilder in project SpongeCommon by SpongePowered.
the class ServerLevelMixin_Tracker method tracker$associatePhaseContextDataWithBlockEvent.
@Redirect(method = "blockEvent", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectLinkedOpenHashSet;add(Ljava/lang/Object;)Z", remap = false))
private boolean tracker$associatePhaseContextDataWithBlockEvent(final ObjectLinkedOpenHashSet<BlockEventData> list, final Object data, final BlockPos pos, final Block blockIn, final int eventID, final int eventParam) {
final PhaseContext<@NonNull ?> currentContext = PhaseTracker.getInstance().getPhaseContext();
final BlockEventData blockEventData = (BlockEventData) data;
final TrackableBlockEventDataBridge blockEvent = (TrackableBlockEventDataBridge) blockEventData;
// Short circuit phase states who do not track during block events
if (currentContext.ignoresBlockEvent()) {
return list.add(blockEventData);
}
final BlockState state = this.shadow$getBlockState(pos);
if (((TrackableBridge) blockIn).bridge$allowsBlockEventCreation()) {
blockEvent.bridge$setSourceUserUUID(currentContext.getActiveUserUUID());
if (((BlockStateBridge) state).bridge$hasTileEntity()) {
blockEvent.bridge$setTileEntity((BlockEntity) this.shadow$getBlockEntity(pos));
}
if (blockEvent.bridge$getTileEntity() == null) {
final LocatableBlock locatable = new SpongeLocatableBlockBuilder().world((org.spongepowered.api.world.server.ServerWorld) this).position(pos.getX(), pos.getY(), pos.getZ()).state((org.spongepowered.api.block.BlockState) state).build();
blockEvent.bridge$setTickingLocatable(locatable);
}
}
// allow tracking to take place for other/future phases
if (!((TrackableBridge) blockIn).bridge$allowsBlockEventCreation()) {
return list.add((BlockEventData) data);
}
// In pursuant with our block updates management, we chose to
// effectively allow the block event get added to the list, but
// we log the transaction so that we can call the change block event
// pre, and if needed, undo the add to the list.
currentContext.appendNotifierToBlockEvent(this, pos, blockEvent);
// This is very common with pistons as they add block events while blocks are being notified.
if (ShouldFire.CHANGE_BLOCK_EVENT_PRE) {
if (blockIn instanceof PistonBaseBlock) {
// We only fire pre events for pistons
if (SpongeCommonEventFactory.handlePistonEvent(this, pos, state, eventID)) {
return false;
}
} else {
if (SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) this, pos).isCancelled()) {
return false;
}
}
}
currentContext.getTransactor().logBlockEvent(state, this, pos, blockEvent);
return list.add(blockEventData);
}
use of org.spongepowered.common.world.server.SpongeLocatableBlockBuilder in project SpongeCommon by SpongePowered.
the class TrackingUtil method updateTickFluid.
public static void updateTickFluid(final TrackedWorldBridge mixinWorld, final FluidState fluidState, final BlockPos pos) {
final ServerLevel world = (ServerLevel) mixinWorld;
final org.spongepowered.api.world.server.ServerWorld apiWorld = (org.spongepowered.api.world.server.ServerWorld) world;
final net.minecraft.world.level.block.state.BlockState blockState = fluidState.createLegacyBlock();
if (ShouldFire.TICK_BLOCK_EVENT) {
final BlockSnapshot snapshot = mixinWorld.bridge$createSnapshot(blockState, pos, BlockChangeFlags.NONE);
final TickBlockEvent event = SpongeEventFactory.createTickBlockEventScheduled(PhaseTracker.getCauseStackManager().currentCause(), snapshot);
SpongeCommon.post(event);
if (event.isCancelled()) {
return;
}
}
final LocatableBlock locatable = new SpongeLocatableBlockBuilder().world(apiWorld).position(pos.getX(), pos.getY(), pos.getZ()).state((BlockState) blockState).build();
final FluidTickContext phaseContext = TickPhase.Tick.FLUID.createPhaseContext(PhaseTracker.SERVER).source(locatable).fluid(fluidState);
// We have to associate any notifiers in case of scheduled block updates from other sources
final PhaseContext<@NonNull ?> currentContext = PhaseTracker.getInstance().getPhaseContext();
currentContext.appendNotifierPreBlockTick(world, pos, phaseContext);
try (final PhaseContext<?> context = phaseContext;
final Timing timing = ((TimingBridge) blockState.getBlock()).bridge$timings()) {
timing.startTiming();
context.buildAndSwitch();
PhaseTracker.LOGGER.trace(TrackingUtil.FLUID_TICK, () -> "Wrapping Fluid Tick: " + fluidState.toString());
fluidState.tick(world, pos);
} catch (final Exception | NoClassDefFoundError e) {
PhasePrinter.printExceptionFromPhase(PhaseTracker.getInstance().stack, e, phaseContext);
}
}
use of org.spongepowered.common.world.server.SpongeLocatableBlockBuilder in project SpongeCommon by SpongePowered.
the class TrackingUtil method randomTickFluid.
@SuppressWarnings("rawtypes")
public static void randomTickFluid(final TrackedWorldBridge mixinWorld, final FluidState state, final BlockPos pos, final Random random) {
final ServerLevel world = (ServerLevel) mixinWorld;
final org.spongepowered.api.world.server.ServerWorld apiWorld = (org.spongepowered.api.world.server.ServerWorld) world;
if (ShouldFire.TICK_BLOCK_EVENT) {
final BlockSnapshot currentTickBlock = mixinWorld.bridge$createSnapshot(state.createLegacyBlock(), pos, BlockChangeFlags.NONE);
final TickBlockEvent event = SpongeEventFactory.createTickBlockEventRandom(PhaseTracker.getCauseStackManager().currentCause(), currentTickBlock);
SpongeCommon.post(event);
if (event.isCancelled()) {
return;
}
}
final LocatableBlock locatable = new SpongeLocatableBlockBuilder().world(apiWorld).position(pos.getX(), pos.getY(), pos.getZ()).state((BlockState) state.createLegacyBlock()).build();
final FluidTickContext phaseContext = TickPhase.Tick.RANDOM_FLUID.createPhaseContext(PhaseTracker.SERVER).source(locatable).fluid(state);
// We have to associate any notifiers in case of scheduled block updates from other sources
final PhaseContext<@NonNull ?> currentContext = PhaseTracker.getInstance().getPhaseContext();
currentContext.appendNotifierPreBlockTick(world, pos, phaseContext);
// Now actually switch to the new phase
try (final PhaseContext<@NonNull ?> context = phaseContext) {
context.buildAndSwitch();
PhaseTracker.LOGGER.trace(TrackingUtil.FLUID_TICK, () -> "Wrapping Random Fluid Tick: " + state.toString());
state.randomTick(world, pos, random);
} catch (final Exception | NoClassDefFoundError e) {
PhasePrinter.printExceptionFromPhase(PhaseTracker.getInstance().stack, e, phaseContext);
}
}
Aggregations