Search in sources :

Example 1 with StackFrame

use of org.spongepowered.api.event.CauseStackManager.StackFrame in project SpongeCommon by SpongePowered.

the class TrackingUtil method throwMultiEventsAndCreatePost.

public static ChangeBlockEvent.Post throwMultiEventsAndCreatePost(ImmutableList<Transaction<BlockSnapshot>>[] transactionArrays, List<ChangeBlockEvent> blockEvents, ChangeBlockEvent[] mainEvents) {
    if (!blockEvents.isEmpty()) {
        try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
            for (BlockChange blockChange : BlockChange.values()) {
                final ChangeBlockEvent mainEvent = mainEvents[blockChange.ordinal()];
                if (mainEvent != null) {
                    Sponge.getCauseStackManager().pushCause(mainEvent);
                }
            }
            final ImmutableList<Transaction<BlockSnapshot>> transactions = transactionArrays[MULTI_CHANGE_INDEX];
            final ChangeBlockEvent.Post post = SpongeEventFactory.createChangeBlockEventPost(Sponge.getCauseStackManager().getCurrentCause(), transactions);
            SpongeImpl.postEvent(post);
            return post;
        }
    }
    return null;
}
Also used : ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) BlockChange(org.spongepowered.common.world.BlockChange) Transaction(org.spongepowered.api.data.Transaction) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame)

Example 2 with StackFrame

use of org.spongepowered.api.event.CauseStackManager.StackFrame in project SpongeCommon by SpongePowered.

the class TrackingUtil method randomTickBlock.

public static void randomTickBlock(PhaseTracker phaseTracker, IMixinWorldServer mixinWorld, Block block, BlockPos pos, IBlockState state, Random random) {
    final WorldServer minecraftWorld = mixinWorld.asMinecraftWorld();
    try (@SuppressWarnings("unused") StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(minecraftWorld);
        if (ShouldFire.TICK_BLOCK_EVENT) {
            final BlockSnapshot currentTickBlock = mixinWorld.createSpongeBlockSnapshot(state, state, pos, BlockChangeFlags.NONE);
            final TickBlockEvent event = SpongeEventFactory.createTickBlockEventRandom(Sponge.getCauseStackManager().getCurrentCause(), currentTickBlock);
            SpongeImpl.postEvent(event);
            if (event.isCancelled()) {
                return;
            }
        }
        final LocatableBlock locatable = LocatableBlock.builder().location(new Location<>(mixinWorld.asSpongeWorld(), pos.getX(), pos.getY(), pos.getZ())).state((BlockState) state).build();
        Sponge.getCauseStackManager().pushCause(locatable);
        IPhaseState<BlockTickContext> phase = ((IMixinBlock) block).requiresBlockCapture() ? TickPhase.Tick.RANDOM_BLOCK : TickPhase.Tick.NO_CAPTURE_BLOCK;
        final BlockTickContext phaseContext = phase.createPhaseContext().source(locatable);
        checkAndAssignBlockTickConfig(block, minecraftWorld, phaseContext);
        // We have to associate any notifiers in case of scheduled block updates from other sources
        final PhaseData current = phaseTracker.getCurrentPhaseData();
        final IPhaseState<?> currentState = current.state;
        ((IPhaseState) currentState).appendNotifierPreBlockTick(mixinWorld, pos, current.context, phaseContext);
        // Now actually switch to the new phase
        try (PhaseContext<?> context = phaseContext.buildAndSwitch()) {
            block.randomTick(minecraftWorld, pos, state, random);
        } catch (Exception | NoClassDefFoundError e) {
            phaseTracker.printExceptionFromPhase(e, phaseContext);
        }
    }
}
Also used : SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) WorldServer(net.minecraft.world.WorldServer) TickBlockEvent(org.spongepowered.api.event.block.TickBlockEvent) BlockState(org.spongepowered.api.block.BlockState) IBlockState(net.minecraft.block.state.IBlockState) BlockTickContext(org.spongepowered.common.event.tracking.phase.tick.BlockTickContext) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) LocatableBlock(org.spongepowered.api.world.LocatableBlock)

Example 3 with StackFrame

use of org.spongepowered.api.event.CauseStackManager.StackFrame in project SpongeCommon by SpongePowered.

the class TrackingUtil method tickRidingEntity.

public static void tickRidingEntity(net.minecraft.entity.Entity entity) {
    checkArgument(entity instanceof Entity, "Entity %s is not an instance of SpongeAPI's Entity!", entity);
    checkNotNull(entity, "Cannot capture on a null ticking entity!");
    final IMixinEntity mixinEntity = EntityUtil.toMixin(entity);
    if (!mixinEntity.shouldTick()) {
        return;
    }
    final Optional<User> notifierUser = mixinEntity.getNotifierUser();
    final Optional<User> creatorUser = mixinEntity.getCreatorUser();
    final EntityTickContext tickContext = TickPhase.Tick.ENTITY.createPhaseContext().source(entity).notifier(() -> notifierUser).owner(() -> creatorUser);
    try (final StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
        final EntityTickContext context = tickContext.buildAndSwitch();
        final Timing entityTiming = mixinEntity.getTimingsHandler().startTiming()) {
        Sponge.getCauseStackManager().pushCause(entity);
        notifierUser.ifPresent(notifier -> frame.addContext(EventContextKeys.NOTIFIER, notifier));
        creatorUser.ifPresent(notifier -> frame.addContext(EventContextKeys.OWNER, notifier));
        entity.updateRidden();
    } catch (Exception | NoClassDefFoundError e) {
        PhaseTracker.getInstance().printExceptionFromPhase(e, tickContext);
    }
}
Also used : IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) IMixinTileEntity(org.spongepowered.common.interfaces.block.tile.IMixinTileEntity) Entity(org.spongepowered.api.entity.Entity) EntityTickContext(org.spongepowered.common.event.tracking.phase.tick.EntityTickContext) TileEntityTickContext(org.spongepowered.common.event.tracking.phase.tick.TileEntityTickContext) User(org.spongepowered.api.entity.living.player.User) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) Timing(co.aikar.timings.Timing)

Example 4 with StackFrame

use of org.spongepowered.api.event.CauseStackManager.StackFrame in project SpongeCommon by SpongePowered.

the class TrackingUtil method tickTileEntity.

@SuppressWarnings({ "unused", "try" })
public static void tickTileEntity(IMixinWorldServer mixinWorldServer, ITickable tile) {
    checkArgument(tile instanceof TileEntity, "ITickable %s is not a TileEntity!", tile);
    checkNotNull(tile, "Cannot capture on a null ticking tile entity!");
    final net.minecraft.tileentity.TileEntity tileEntity = (net.minecraft.tileentity.TileEntity) tile;
    final IMixinTileEntity mixinTileEntity = (IMixinTileEntity) tile;
    final BlockPos pos = tileEntity.getPos();
    final IMixinChunk chunk = ((IMixinTileEntity) tile).getActiveChunk();
    if (!mixinTileEntity.shouldTick()) {
        return;
    }
    final TileEntityTickContext context = TickPhase.Tick.TILE_ENTITY.createPhaseContext().source(tile);
    try (final StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
        final PhaseContext<?> phaseContext = context) {
        Sponge.getCauseStackManager().pushCause(tile);
        // Add notifier and owner so we don't have to perform lookups during the phases and other processing
        chunk.getBlockNotifier(pos).ifPresent(notifier -> {
            Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier);
            phaseContext.notifier(notifier);
        });
        User blockOwner = mixinTileEntity.getSpongeOwner();
        if (!mixinTileEntity.hasSetOwner()) {
            blockOwner = chunk.getBlockOwner(pos).orElse(null);
            mixinTileEntity.setSpongeOwner(blockOwner);
        }
        if (blockOwner != null) {
            Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, blockOwner);
            phaseContext.owner(blockOwner);
        }
        phaseContext.owner = blockOwner;
        // Add the block snapshot of the tile entity for caches to avoid creating multiple snapshots during processing
        // This is a lazy evaluating snapshot to avoid the overhead of snapshot creation
        // Finally, switch the context now that we have the owner and notifier
        phaseContext.buildAndSwitch();
        try (Timing timing = mixinTileEntity.getTimingsHandler().startTiming()) {
            tile.update();
        }
    } catch (Exception e) {
        PhaseTracker.getInstance().printExceptionFromPhase(e, context);
    }
}
Also used : User(org.spongepowered.api.entity.living.player.User) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) IMixinTileEntity(org.spongepowered.common.interfaces.block.tile.IMixinTileEntity) IMixinTileEntity(org.spongepowered.common.interfaces.block.tile.IMixinTileEntity) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) BlockPos(net.minecraft.util.math.BlockPos) Timing(co.aikar.timings.Timing) TileEntityTickContext(org.spongepowered.common.event.tracking.phase.tick.TileEntityTickContext)

Example 5 with StackFrame

use of org.spongepowered.api.event.CauseStackManager.StackFrame in project SpongeCommon by SpongePowered.

the class TrackingUtil method tickEntity.

public static void tickEntity(net.minecraft.entity.Entity entityIn) {
    checkArgument(entityIn instanceof Entity, "Entity %s is not an instance of SpongeAPI's Entity!", entityIn);
    checkNotNull(entityIn, "Cannot capture on a null ticking entity!");
    final IMixinEntity mixinEntity = EntityUtil.toMixin(entityIn);
    if (!mixinEntity.shouldTick()) {
        return;
    }
    final EntityTickContext tickContext = TickPhase.Tick.ENTITY.createPhaseContext().source(entityIn);
    try (final StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
        final EntityTickContext context = tickContext;
        final Timing entityTiming = mixinEntity.getTimingsHandler().startTiming()) {
        mixinEntity.getNotifierUser().ifPresent(notifier -> {
            frame.addContext(EventContextKeys.NOTIFIER, notifier);
            context.notifier(notifier);
        });
        mixinEntity.getCreatorUser().ifPresent(owner -> {
            if (mixinEntity instanceof EntityFallingBlock) {
                frame.pushCause(owner);
            }
            frame.addContext(EventContextKeys.OWNER, owner);
            context.owner(owner);
        });
        context.buildAndSwitch();
        entityIn.onUpdate();
    } catch (Exception | NoClassDefFoundError e) {
        PhaseTracker.getInstance().printExceptionFromPhase(e, tickContext);
    }
}
Also used : IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) IMixinTileEntity(org.spongepowered.common.interfaces.block.tile.IMixinTileEntity) Entity(org.spongepowered.api.entity.Entity) EntityTickContext(org.spongepowered.common.event.tracking.phase.tick.EntityTickContext) TileEntityTickContext(org.spongepowered.common.event.tracking.phase.tick.TileEntityTickContext) EntityFallingBlock(net.minecraft.entity.item.EntityFallingBlock) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) Timing(co.aikar.timings.Timing)

Aggregations

StackFrame (org.spongepowered.api.event.CauseStackManager.StackFrame)36 Entity (org.spongepowered.api.entity.Entity)18 ArrayList (java.util.ArrayList)15 SpawnEntityEvent (org.spongepowered.api.event.entity.SpawnEntityEvent)13 User (org.spongepowered.api.entity.living.player.User)12 EntityItem (net.minecraft.entity.item.EntityItem)11 EntityPlayer (net.minecraft.entity.player.EntityPlayer)8 TileEntity (org.spongepowered.api.block.tileentity.TileEntity)8 IMixinEntity (org.spongepowered.common.interfaces.entity.IMixinEntity)6 ItemStack (net.minecraft.item.ItemStack)5 BlockPos (net.minecraft.util.math.BlockPos)5 WorldServer (net.minecraft.world.WorldServer)5 LocatableBlock (org.spongepowered.api.world.LocatableBlock)5 IMixinTileEntity (org.spongepowered.common.interfaces.block.tile.IMixinTileEntity)5 List (java.util.List)4 UUID (java.util.UUID)4 Collectors (java.util.stream.Collectors)4 EntityLivingBase (net.minecraft.entity.EntityLivingBase)4 EntityPlayerMP (net.minecraft.entity.player.EntityPlayerMP)4 Sponge (org.spongepowered.api.Sponge)4