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