Search in sources :

Example 31 with StackFrame

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

the class BlockTickPhaseState method unwind.

@Override
public void unwind(BlockTickContext context) {
    final LocatableBlock locatableBlock = context.requireSource(LocatableBlock.class);
    try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(locatableBlock);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
        final User entityCreator = context.getNotifier().orElseGet(() -> context.getOwner().orElse(null));
        context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blockSnapshots -> TrackingUtil.processBlockCaptures(blockSnapshots, this, context));
        context.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(items -> {
            final ArrayList<Entity> capturedEntities = new ArrayList<>();
            for (EntityItem entity : items) {
                capturedEntities.add(EntityUtil.fromNative(entity));
            }
            final SpawnEntityEvent spawnEntityEvent = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), capturedEntities);
            SpongeImpl.postEvent(spawnEntityEvent);
            for (Entity entity : spawnEntityEvent.getEntities()) {
                if (entityCreator != null) {
                    EntityUtil.toMixin(entity).setCreator(entityCreator.getUniqueId());
                }
                EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
            }
        });
    }
}
Also used : Entity(org.spongepowered.api.entity.Entity) User(org.spongepowered.api.entity.living.player.User) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) ArrayList(java.util.ArrayList) LocatableBlock(org.spongepowered.api.world.LocatableBlock) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) EntityItem(net.minecraft.entity.item.EntityItem)

Example 32 with StackFrame

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

the class DimensionTickPhaseState method spawnEntityOrCapture.

/*
    @author - gabizou
    non-javadoc
    This is a stopgap to get dragon respawns working. Since there's 4 classes that interweave themselves
    between various states including but not withstanding: respawning endercrystals, respawning the dragon,
    locating the crystals, etc. it's best to not capture the spawns and simply spawn them in directly.
    This is a todo until the dragon phases are completely configured and correctly managed (should be able to at some point restore
    traditional ai logic to the dragon without the necessity for the dragon being summoned the manual way).

     */
@Override
public boolean spawnEntityOrCapture(DimensionContext context, Entity entity, int chunkX, int chunkZ) {
    final User user = context.getNotifier().orElseGet(() -> context.getOwner().orElse(null));
    if (user != null) {
        entity.setCreator(user.getUniqueId());
    }
    final ArrayList<Entity> entities = new ArrayList<>(1);
    entities.add(entity);
    try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.PLACEMENT);
        final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
        SpongeImpl.postEvent(event);
        if (!event.isCancelled() && event.getEntities().size() > 0) {
            for (Entity item : event.getEntities()) {
                EntityUtil.getMixinWorld(entity).forceSpawnEntity(item);
            }
            return true;
        }
    }
    return false;
}
Also used : Entity(org.spongepowered.api.entity.Entity) User(org.spongepowered.api.entity.living.player.User) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) ArrayList(java.util.ArrayList) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent)

Example 33 with StackFrame

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

the class MixinWorldServer method updateBlocks.

/**
 * @author blood - July 1st, 2016
 * @author gabizou - July 1st, 2016 - Update to 1.10 and cause tracking
 *
 * @reason Added chunk and block tick optimizations, timings, cause tracking, and pre-construction events.
 */
@SuppressWarnings("unchecked")
@Override
@Overwrite
protected void updateBlocks() {
    this.playerCheckLight();
    if (this.worldInfo.getTerrainType() == WorldType.DEBUG_ALL_BLOCK_STATES) {
        Iterator<net.minecraft.world.chunk.Chunk> iterator1 = this.playerChunkMap.getChunkIterator();
        while (iterator1.hasNext()) {
            iterator1.next().onTick(false);
        }
        // Sponge: Add return
        return;
    }
    // else // Sponge - Remove unnecessary else
    // { //
    int i = this.shadow$getGameRules().getInt("randomTickSpeed");
    boolean flag = this.isRaining();
    boolean flag1 = this.isThundering();
    // this.profiler.startSection("pollingChunks"); // Sponge - Don't use the profiler
    // Sponge - get the cause tracker
    final PhaseTracker phaseTracker = PhaseTracker.getInstance();
    // Sponge: Use SpongeImplHooks for Forge
    for (Iterator<net.minecraft.world.chunk.Chunk> iterator = // this.profiler.endSection()) // Sponge - don't use the profiler
    SpongeImplHooks.getChunkIterator((WorldServer) (Object) this); // this.profiler.endSection()) // Sponge - don't use the profiler
    iterator.hasNext(); ) {
        // this.profiler.startSection("getChunk"); // Sponge - Don't use the profiler
        net.minecraft.world.chunk.Chunk chunk = iterator.next();
        final net.minecraft.world.World world = chunk.getWorld();
        int j = chunk.x * 16;
        int k = chunk.z * 16;
        // this.profiler.endStartSection("checkNextLight"); // Sponge - Don't use the profiler
        // Sponge - Timings
        this.timings.updateBlocksCheckNextLight.startTiming();
        chunk.enqueueRelightChecks();
        // Sponge - Timings
        this.timings.updateBlocksCheckNextLight.stopTiming();
        // this.profiler.endStartSection("tickChunk"); // Sponge - Don't use the profiler
        // Sponge - Timings
        this.timings.updateBlocksChunkTick.startTiming();
        chunk.onTick(false);
        // Sponge - Timings
        this.timings.updateBlocksChunkTick.stopTiming();
        // Sponge start - if surrounding neighbors are not loaded, skip
        if (!((IMixinChunk) chunk).areNeighborsLoaded()) {
            continue;
        }
        // Sponge end
        // this.profiler.endStartSection("thunder"); // Sponge - Don't use the profiler
        // Sponge start
        this.timings.updateBlocksThunder.startTiming();
        // if (this.provider.canDoLightning(chunk) && flag && flag1 && this.rand.nextInt(100000) == 0) // Sponge - Add SpongeImplHooks for forge
        if (this.weatherThunderEnabled && SpongeImplHooks.canDoLightning(this.provider, chunk) && flag && flag1 && this.rand.nextInt(100000) == 0) {
            try (final PhaseContext<?> context = TickPhase.Tick.WEATHER.createPhaseContext().source(this).buildAndSwitch()) {
                // Sponge end
                this.updateLCG = this.updateLCG * 3 + 1013904223;
                int l = this.updateLCG >> 2;
                BlockPos blockpos = this.adjustPosToNearbyEntity(new BlockPos(j + (l & 15), 0, k + (l >> 8 & 15)));
                if (this.isRainingAt(blockpos)) {
                    DifficultyInstance difficultyinstance = this.getDifficultyForLocation(blockpos);
                    // Sponge - create a transform to be used for events
                    final Transform<org.spongepowered.api.world.World> transform = new Transform<>(this, VecHelper.toVector3d(blockpos).toDouble());
                    if (world.getGameRules().getBoolean("doMobSpawning") && this.rand.nextDouble() < (double) difficultyinstance.getAdditionalDifficulty() * 0.01D) {
                        // Sponge Start - Throw construction events
                        try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
                            Sponge.getCauseStackManager().pushCause(this.getWeather());
                            Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.WEATHER);
                            ConstructEntityEvent.Pre constructEntityEvent = SpongeEventFactory.createConstructEntityEventPre(Sponge.getCauseStackManager().getCurrentCause(), EntityTypes.HORSE, transform);
                            SpongeImpl.postEvent(constructEntityEvent);
                            if (!constructEntityEvent.isCancelled()) {
                                // Sponge End
                                EntitySkeletonHorse entityhorse = new EntitySkeletonHorse((WorldServer) (Object) this);
                                entityhorse.setTrap(true);
                                entityhorse.setGrowingAge(0);
                                entityhorse.setPosition(blockpos.getX(), blockpos.getY(), blockpos.getZ());
                                this.spawnEntity(entityhorse);
                            // Sponge Start - Throw a construct event for the lightning
                            }
                            ConstructEntityEvent.Pre lightning = SpongeEventFactory.createConstructEntityEventPre(Sponge.getCauseStackManager().getCurrentCause(), EntityTypes.LIGHTNING, transform);
                            SpongeImpl.postEvent(lightning);
                            if (!lightning.isCancelled()) {
                                LightningEvent.Pre lightningPre = SpongeEventFactory.createLightningEventPre(frame.getCurrentCause());
                                if (!SpongeImpl.postEvent(lightningPre)) {
                                    // Sponge End
                                    this.addWeatherEffect(new EntityLightningBolt(world, (double) blockpos.getX(), (double) blockpos.getY(), (double) blockpos.getZ(), true));
                                }
                            }
                        // Sponge - Brackets.
                        }
                    } else {
                        // Sponge start - Throw construction event for lightningbolts
                        try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
                            Sponge.getCauseStackManager().pushCause(this.getWeather());
                            Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.WEATHER);
                            ConstructEntityEvent.Pre event = SpongeEventFactory.createConstructEntityEventPre(Sponge.getCauseStackManager().getCurrentCause(), EntityTypes.LIGHTNING, transform);
                            SpongeImpl.postEvent(event);
                            if (!event.isCancelled()) {
                                LightningEvent.Pre lightningPre = SpongeEventFactory.createLightningEventPre(frame.getCurrentCause());
                                if (!SpongeImpl.postEvent(lightningPre)) {
                                    // Sponge End
                                    this.addWeatherEffect(new EntityLightningBolt(world, (double) blockpos.getX(), (double) blockpos.getY(), (double) blockpos.getZ(), true));
                                }
                            }
                        // Sponge - Brackets.
                        }
                    }
                }
            }
        // Sponge - brackets
        // Sponge End
        }
        // Sponge - Stop thunder timing
        this.timings.updateBlocksThunder.stopTiming();
        // Sponge - Start thunder timing
        this.timings.updateBlocksIceAndSnow.startTiming();
        // if (this.rand.nextInt(16) == 0) // Sponge - Rewrite to use our boolean, and forge hook
        if (this.weatherIceAndSnowEnabled && SpongeImplHooks.canDoRainSnowIce(this.provider, chunk) && this.rand.nextInt(16) == 0) {
            // Sponge Start - Enter weather phase for snow and ice and flooding.
            try (final PhaseContext<?> context = TickPhase.Tick.WEATHER.createPhaseContext().source(this).buildAndSwitch()) {
                // Sponge End
                this.updateLCG = this.updateLCG * 3 + 1013904223;
                int j2 = this.updateLCG >> 2;
                BlockPos blockpos1 = this.getPrecipitationHeight(new BlockPos(j + (j2 & 15), 0, k + (j2 >> 8 & 15)));
                BlockPos blockpos2 = blockpos1.down();
                if (this.canBlockFreezeNoWater(blockpos2)) {
                    this.setBlockState(blockpos2, Blocks.ICE.getDefaultState());
                }
                if (flag && this.canSnowAt(blockpos1, true)) {
                    this.setBlockState(blockpos1, Blocks.SNOW_LAYER.getDefaultState());
                }
                if (flag && this.getBiome(blockpos2).canRain()) {
                    this.getBlockState(blockpos2).getBlock().fillWithRain((WorldServer) (Object) this, blockpos2);
                }
            }
        // Sponge - brackets
        }
        // Sponge - Stop ice and snow timing
        this.timings.updateBlocksIceAndSnow.stopTiming();
        // Sponge - Start random block tick timing
        this.timings.updateBlocksRandomTick.startTiming();
        if (i > 0) {
            for (ExtendedBlockStorage extendedblockstorage : chunk.getBlockStorageArray()) {
                if (extendedblockstorage != net.minecraft.world.chunk.Chunk.NULL_BLOCK_STORAGE && extendedblockstorage.needsRandomTick()) {
                    for (int i1 = 0; i1 < i; ++i1) {
                        this.updateLCG = this.updateLCG * 3 + 1013904223;
                        int j1 = this.updateLCG >> 2;
                        int k1 = j1 & 15;
                        int l1 = j1 >> 8 & 15;
                        int i2 = j1 >> 16 & 15;
                        IBlockState iblockstate = extendedblockstorage.get(k1, i2, l1);
                        Block block = iblockstate.getBlock();
                        if (block.getTickRandomly()) {
                            // Sponge start - capture random tick
                            // Remove the random tick for cause tracking
                            // block.randomTick(this, new BlockPos(k1 + j, i2 + extendedblockstorage.getYLocation(), l1 + k), iblockstate, this.rand);
                            BlockPos pos = new BlockPos(k1 + j, i2 + extendedblockstorage.getYLocation(), l1 + k);
                            IMixinBlock spongeBlock = (IMixinBlock) block;
                            spongeBlock.getTimingsHandler().startTiming();
                            final PhaseData currentTuple = phaseTracker.getCurrentPhaseData();
                            final IPhaseState phaseState = currentTuple.state;
                            if (phaseState.alreadyCapturingBlockTicks(currentTuple.context)) {
                                block.randomTick(world, pos, iblockstate, this.rand);
                            } else {
                                TrackingUtil.randomTickBlock(phaseTracker, this, block, pos, iblockstate, this.rand);
                            }
                            spongeBlock.getTimingsHandler().stopTiming();
                        // Sponge end
                        }
                    // this.profiler.endSection(); // Sponge - Don't use the profiler
                    }
                }
            }
        }
    }
    // Sponge - Stop random block timing
    this.timings.updateBlocksRandomTick.stopTiming();
// this.profiler.endSection(); // Sponge - Don't use the profiler
// } // Sponge- Remove unecessary else
}
Also used : DifficultyInstance(net.minecraft.world.DifficultyInstance) EntityLightningBolt(net.minecraft.entity.effect.EntityLightningBolt) World(net.minecraft.world.World) IMixinBlock(org.spongepowered.common.interfaces.block.IMixinBlock) CauseStackManager(org.spongepowered.api.event.CauseStackManager) EntitySkeletonHorse(net.minecraft.entity.passive.EntitySkeletonHorse) BlockPos(net.minecraft.util.math.BlockPos) IMixinBlockPos(org.spongepowered.common.interfaces.util.math.IMixinBlockPos) Chunk(net.minecraft.world.chunk.Chunk) IBlockState(net.minecraft.block.state.IBlockState) PhaseData(org.spongepowered.common.event.tracking.PhaseData) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) World(net.minecraft.world.World) LightningEvent(org.spongepowered.api.event.action.LightningEvent) IPhaseState(org.spongepowered.common.event.tracking.IPhaseState) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Chunk(net.minecraft.world.chunk.Chunk) ExtendedBlockStorage(net.minecraft.world.chunk.storage.ExtendedBlockStorage) ConstructEntityEvent(org.spongepowered.api.event.entity.ConstructEntityEvent) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) Block(net.minecraft.block.Block) EnumSkyBlock(net.minecraft.world.EnumSkyBlock) IMixinBlock(org.spongepowered.common.interfaces.block.IMixinBlock) LocatableBlock(org.spongepowered.api.world.LocatableBlock) Transform(org.spongepowered.api.entity.Transform) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 34 with StackFrame

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

the class MixinAnvilChunkLoader method onReadChunkEntity.

/**
 * @author gabizou - January 30th, 2016
 *
 *         Attempts to redirect EntityList spawning an entity. Forge
 *         rewrites this method to handle it in a different method, so this
 *         will not actually inject in SpongeForge.
 *
 * @param compound
 * @param world
 * @return
 */
@Redirect(method = "readChunkEntity", at = @At(value = "INVOKE", target = ENTITY_LIST_CREATE_FROM_NBT), require = 0, expect = 0)
private static Entity onReadChunkEntity(NBTTagCompound compound, World world, Chunk chunk) {
    if ("Minecart".equals(compound.getString(NbtDataUtil.ENTITY_TYPE_ID))) {
        compound.setString(NbtDataUtil.ENTITY_TYPE_ID, EntityMinecart.Type.values()[compound.getInteger(NbtDataUtil.MINECART_TYPE)].getName());
        compound.removeTag(NbtDataUtil.MINECART_TYPE);
    }
    Class<? extends Entity> entityClass = SpongeImplHooks.getEntityClass(new ResourceLocation(compound.getString(NbtDataUtil.ENTITY_TYPE_ID)));
    if (entityClass == null) {
        return null;
    }
    EntityType type = EntityTypeRegistryModule.getInstance().getForClass(entityClass);
    if (type == null) {
        return null;
    }
    NBTTagList positionList = compound.getTagList(NbtDataUtil.ENTITY_POSITION, NbtDataUtil.TAG_DOUBLE);
    NBTTagList rotationList = compound.getTagList(NbtDataUtil.ENTITY_ROTATION, NbtDataUtil.TAG_FLOAT);
    Vector3d position = new Vector3d(positionList.getDoubleAt(0), positionList.getDoubleAt(1), positionList.getDoubleAt(2));
    Vector3d rotation = new Vector3d(rotationList.getFloatAt(0), rotationList.getFloatAt(1), 0);
    Transform<org.spongepowered.api.world.World> transform = new Transform<>((org.spongepowered.api.world.World) world, position, rotation);
    try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.CHUNK_LOAD);
        ConstructEntityEvent.Pre event = SpongeEventFactory.createConstructEntityEventPre(Sponge.getCauseStackManager().getCurrentCause(), type, transform);
        SpongeImpl.postEvent(event);
        if (event.isCancelled()) {
            return null;
        }
        return EntityList.createEntityFromNBT(compound, world);
    }
}
Also used : World(net.minecraft.world.World) EntityType(org.spongepowered.api.entity.EntityType) NBTTagList(net.minecraft.nbt.NBTTagList) ConstructEntityEvent(org.spongepowered.api.event.entity.ConstructEntityEvent) Vector3d(com.flowpowered.math.vector.Vector3d) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) ResourceLocation(net.minecraft.util.ResourceLocation) Transform(org.spongepowered.api.entity.Transform) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 35 with StackFrame

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

the class MixinWorldServer method onUpdateWeatherReturn.

@Inject(method = "updateWeather", at = @At(value = "RETURN"))
private void onUpdateWeatherReturn(CallbackInfo ci) {
    final Weather weather = getWeather();
    int duration = (int) getRemainingDuration();
    if (this.prevWeather != weather && duration > 0) {
        try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
            frame.pushCause(this);
            final ChangeWorldWeatherEvent event = SpongeEventFactory.createChangeWorldWeatherEvent(frame.getCurrentCause(), duration, duration, weather, weather, this.prevWeather, this);
            if (Sponge.getEventManager().post(event)) {
                this.setWeather(this.prevWeather);
            } else {
                if (!weather.equals(event.getWeather()) || duration != event.getDuration()) {
                    this.setWeather(event.getWeather(), event.getDuration());
                    this.prevWeather = event.getWeather();
                    this.weatherStartTime = this.worldInfo.getWorldTotalTime();
                }
            }
        }
    }
}
Also used : Weather(org.spongepowered.api.world.weather.Weather) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) ChangeWorldWeatherEvent(org.spongepowered.api.event.world.ChangeWorldWeatherEvent) Inject(org.spongepowered.asm.mixin.injection.Inject)

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