use of org.spongepowered.common.event.tracking.IPhaseState in project SpongeCommon by SpongePowered.
the class PlayerPhase method unwind.
@SuppressWarnings("unchecked")
public void unwind(IPhaseState<?> state, PhaseContext<?> phaseContext) {
// Since currently all we have is PLAYER_LOGOUT, don't care about
// states.
final Player player = phaseContext.getSource(Player.class).orElseThrow(TrackingUtil.throwWithContext("Expected to be processing a player leaving, but we're not!", phaseContext));
try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
Sponge.getCauseStackManager().pushCause(player);
Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.DISPENSE);
phaseContext.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(items -> {
final ArrayList<Entity> entities = new ArrayList<>();
for (EntityItem item : items) {
entities.add(EntityUtil.fromNative(item));
}
final DropItemEvent.Dispense dispense = SpongeEventFactory.createDropItemEventDispense(Sponge.getCauseStackManager().getCurrentCause(), entities);
SpongeImpl.postEvent(dispense);
if (!dispense.isCancelled()) {
for (Entity entity : dispense.getEntities()) {
EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
}
}
});
Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.DROPPED_ITEM);
phaseContext.getCapturedItemStackSupplier().acceptAndClearIfNotEmpty(items -> {
final List<EntityItem> drops = items.stream().map(drop -> drop.create(EntityUtil.getMinecraftWorld(player))).collect(Collectors.toList());
final List<Entity> entities = (List<Entity>) (List<?>) drops;
if (!entities.isEmpty()) {
DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
SpongeImpl.postEvent(event);
if (!event.isCancelled()) {
for (Entity droppedItem : event.getEntities()) {
EntityUtil.getMixinWorld(droppedItem).forceSpawnEntity(droppedItem);
}
}
}
});
phaseContext.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blocks -> TrackingUtil.processBlockCaptures(blocks, state, phaseContext));
}
}
use of org.spongepowered.common.event.tracking.IPhaseState in project SpongeCommon by SpongePowered.
the class MixinWorldServer method onUpdateTick.
// This ticks pending updates to blocks, Requires mixin for NextTickListEntry so we use the correct tracking
@SuppressWarnings("unchecked")
@Redirect(method = "tickUpdates", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/Block;updateTick(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/state/IBlockState;Ljava/util/Random;)V"))
private void onUpdateTick(Block block, net.minecraft.world.World worldIn, BlockPos pos, IBlockState state, Random rand) {
final PhaseTracker phaseTracker = PhaseTracker.getInstance();
final PhaseData phaseData = phaseTracker.getCurrentPhaseData();
final IPhaseState phaseState = phaseData.state;
if (phaseState.alreadyCapturingBlockTicks(phaseData.context) || phaseState.ignoresBlockUpdateTick(phaseData)) {
block.updateTick(worldIn, pos, state, rand);
return;
}
IMixinBlock spongeBlock = (IMixinBlock) block;
spongeBlock.getTimingsHandler().startTiming();
TrackingUtil.updateTickBlock(this, block, pos, state, rand);
spongeBlock.getTimingsHandler().stopTiming();
}
use of org.spongepowered.common.event.tracking.IPhaseState in project SpongeCommon by SpongePowered.
the class MixinWorldServer method onCreateScheduledBlockUpdate.
/*@Redirect(method = "updateBlockTick",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/NextTickListEntry;setPriority(I)V"))
private void onUpdateScheduledBlock(NextTickListEntry sbu, int priority) {
this.onCreateScheduledBlockUpdate(sbu, priority);
}*/
@// really scheduleUpdate
Redirect(// really scheduleUpdate
method = "updateBlockTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/NextTickListEntry;setPriority(I)V"))
private void onCreateScheduledBlockUpdate(NextTickListEntry sbu, int priority) {
final PhaseTracker phaseTracker = PhaseTracker.getInstance();
final IPhaseState phaseState = phaseTracker.getCurrentState();
if (phaseState.ignoresScheduledUpdates()) {
this.tmpScheduledObj = sbu;
return;
}
sbu.setPriority(priority);
((IMixinNextTickListEntry) sbu).setWorld((WorldServer) (Object) this);
this.tmpScheduledObj = sbu;
}
use of org.spongepowered.common.event.tracking.IPhaseState in project SpongeCommon by SpongePowered.
the class MixinWorldServer method onAddBlockEvent.
@Redirect(method = "addBlockEvent", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/WorldServer$ServerBlockEventList;add(Ljava/lang/Object;)Z", remap = false))
private boolean onAddBlockEvent(WorldServer.ServerBlockEventList list, Object obj, BlockPos pos, Block blockIn, int eventId, int eventParam) {
final BlockEventData blockEventData = (BlockEventData) obj;
IMixinBlockEventData blockEvent = (IMixinBlockEventData) blockEventData;
// This is very common with pistons as they add block events while blocks are being notified.
if (blockIn instanceof BlockPistonBase) {
// We only fire pre events for pistons
if (SpongeCommonEventFactory.handlePistonEvent(this, list, obj, pos, blockIn, eventId, eventParam)) {
return false;
}
blockEvent.setCaptureBlocks(false);
// TODO BLOCK_EVENT flag
} else if (SpongeCommonEventFactory.callChangeBlockEventPre(this, pos).isCancelled()) {
return false;
}
final PhaseTracker phaseTracker = PhaseTracker.getInstance();
final PhaseData currentPhase = phaseTracker.getCurrentPhaseData();
final IPhaseState phaseState = currentPhase.state;
if (phaseState.ignoresBlockEvent()) {
return list.add((BlockEventData) obj);
}
final PhaseContext<?> context = currentPhase.context;
final LocatableBlock locatable = LocatableBlock.builder().location(new Location<>(this, pos.getX(), pos.getY(), pos.getZ())).state(this.getBlock(pos.getX(), pos.getY(), pos.getZ())).build();
blockEvent.setTickBlock(locatable);
phaseState.addNotifierToBlockEvent(context, this, pos, blockEvent);
return list.add((BlockEventData) obj);
}
use of org.spongepowered.common.event.tracking.IPhaseState in project SpongeCommon by SpongePowered.
the class MixinChunkProviderServer method canDenyChunkRequest.
private boolean canDenyChunkRequest() {
if (!SpongeImpl.getServer().isCallingFromMinecraftThread()) {
return true;
}
if (this.forceChunkRequests) {
return false;
}
final PhaseTracker phaseTracker = PhaseTracker.getInstance();
final IPhaseState currentState = phaseTracker.getCurrentState();
// States that cannot deny chunks
if (currentState == TickPhase.Tick.PLAYER || currentState == TickPhase.Tick.DIMENSION || currentState == EntityPhase.State.CHANGING_DIMENSION || currentState == EntityPhase.State.LEAVING_DIMENSION) {
return false;
}
// States that can deny chunks
if (currentState == GenerationPhase.State.WORLD_SPAWNER_SPAWNING || currentState == PluginPhase.Listener.PRE_SERVER_TICK_LISTENER || currentState == PluginPhase.Listener.POST_SERVER_TICK_LISTENER) {
return true;
}
// Phases that can deny chunks
if (currentState.getPhase() == TrackingPhases.BLOCK || currentState.getPhase() == TrackingPhases.ENTITY || currentState.getPhase() == TrackingPhases.TICK) {
return true;
}
return false;
}
Aggregations