use of org.spongepowered.common.event.tracking.PhaseData in project SpongeCommon by SpongePowered.
the class MixinChunk method onGetEntitiesWithinAABBForEntity.
@Inject(method = "getEntitiesWithinAABBForEntity", at = @At(value = "RETURN"))
public void onGetEntitiesWithinAABBForEntity(Entity entityIn, AxisAlignedBB aabb, List<Entity> listToFill, Predicate<Entity> p_177414_4_, CallbackInfo ci) {
if (this.world.isRemote || PhaseTracker.getInstance().getCurrentPhaseData().state.ignoresEntityCollisions()) {
return;
}
if (listToFill.size() == 0) {
return;
}
CollideEntityEvent event = SpongeCommonEventFactory.callCollideEntityEvent(this.world, entityIn, listToFill);
final PhaseData peek = PhaseTracker.getInstance().getCurrentPhaseData();
if (event == null || event.isCancelled()) {
if (event == null && !peek.state.isTicking()) {
return;
}
listToFill.clear();
}
}
use of org.spongepowered.common.event.tracking.PhaseData in project SpongeCommon by SpongePowered.
the class MixinChunk method setBlockState.
/**
* @author blood - November 2015
* @author gabizou - updated April 10th, 2016 - Add cause tracking refactor changes
*
* @param pos The position changing
* @param newState The new state
* @param currentState The current state - passed in from either chunk or world
* @param newBlockSnapshot The new snapshot. This can be null when calling {@link MixinChunk#setBlockState(BlockPos, IBlockState)} directly,
* as there's no block snapshot to change.
* @return The changed block state if not null
*/
@Override
@Nullable
public IBlockState setBlockState(BlockPos pos, IBlockState newState, IBlockState currentState, @Nullable BlockSnapshot newBlockSnapshot, BlockChangeFlag flag) {
int xPos = pos.getX() & 15;
int yPos = pos.getY();
int zPos = pos.getZ() & 15;
int combinedPos = zPos << 4 | xPos;
if (yPos >= this.precipitationHeightMap[combinedPos] - 1) {
this.precipitationHeightMap[combinedPos] = -999;
}
int currentHeight = this.heightMap[combinedPos];
// Sponge Start - remove blockstate check as we handle it in world.setBlockState
// IBlockState iblockstate = this.getBlockState(pos);
//
// if (iblockstate == state) {
// return null;
// } else {
Block newBlock = newState.getBlock();
Block currentBlock = currentState.getBlock();
// Sponge End
ExtendedBlockStorage extendedblockstorage = this.storageArrays[yPos >> 4];
// Sponge - make this final so we don't change it later
final boolean requiresNewLightCalculations;
// Sponge - Forge moves this from
int newBlockLightOpacity = SpongeImplHooks.getBlockLightOpacity(newState, this.world, pos);
if (extendedblockstorage == net.minecraft.world.chunk.Chunk.NULL_BLOCK_STORAGE) {
if (newBlock == Blocks.AIR) {
return null;
}
extendedblockstorage = this.storageArrays[yPos >> 4] = new ExtendedBlockStorage(yPos >> 4 << 4, this.world.provider.hasSkyLight());
requiresNewLightCalculations = yPos >= currentHeight;
// Sponge Start - properly initialize variable
} else {
requiresNewLightCalculations = false;
}
// Sponge end
// Sponge Start
final int modifiedY = yPos & 15;
extendedblockstorage.set(xPos, modifiedY, zPos, newState);
final PhaseTracker phaseTracker = PhaseTracker.getInstance();
final PhaseData peek = phaseTracker.getCurrentPhaseData();
final boolean requiresCapturing = peek.state.requiresBlockCapturing();
// if (block1 != block) // Sponge - Forge removes this change.
{
if (!this.world.isRemote) {
// Sponge - Forge adds this change for block changes to only fire events when necessary
if (currentState.getBlock() != newState.getBlock()) {
currentBlock.breakBlock(this.world, pos, currentState);
}
// Sponge - Add several tile entity hook checks. Mainly for forge added hooks, but these
// still work by themselves in vanilla.
TileEntity te = this.getTileEntity(pos, EnumCreateEntityType.CHECK);
if (te != null && SpongeImplHooks.shouldRefresh(te, this.world, pos, currentState, newState)) {
this.world.removeTileEntity(pos);
}
// } else if (currentBlock instanceof ITileEntityProvider) { // Sponge - remove since forge has a special hook we need to add here
} else if (SpongeImplHooks.hasBlockTileEntity(currentBlock, currentState)) {
TileEntity tileEntity = this.getTileEntity(pos, EnumCreateEntityType.CHECK);
// Sponge - Add hook for refreshing, because again, forge hooks.
if (tileEntity != null && SpongeImplHooks.shouldRefresh(tileEntity, this.world, pos, currentState, newState)) {
this.world.removeTileEntity(pos);
}
}
}
final IBlockState blockAfterSet = extendedblockstorage.get(xPos, modifiedY, zPos);
if (blockAfterSet.getBlock() != newBlock) {
return null;
}
// } else { // Sponge - remove unnecessary else
if (requiresNewLightCalculations) {
this.generateSkylightMap();
} else {
// int newBlockLightOpacity = state.getLightOpacity(); - Sponge Forge moves this all the way up before tile entities are removed.
// int postNewBlockLightOpacity = newState.getLightOpacity(this.worldObj, pos); - Sponge use the SpongeImplHooks for forge compatibility
int postNewBlockLightOpacity = SpongeImplHooks.getBlockLightOpacity(newState, this.world, pos);
if (newBlockLightOpacity > 0) {
if (yPos >= currentHeight) {
this.relightBlock(xPos, yPos + 1, zPos);
}
} else if (yPos == currentHeight - 1) {
this.relightBlock(xPos, yPos, zPos);
}
if (newBlockLightOpacity != postNewBlockLightOpacity && (newBlockLightOpacity < postNewBlockLightOpacity || this.getLightFor(EnumSkyBlock.SKY, pos) > 0 || this.getLightFor(EnumSkyBlock.BLOCK, pos) > 0)) {
this.propagateSkylightOcclusion(xPos, zPos);
}
}
if (!this.world.isRemote && currentBlock != newBlock) {
// a BlockContainer. Prevents blocks such as TNT from activating when cancelled.
if (!requiresCapturing || SpongeImplHooks.hasBlockTileEntity(newBlock, newState)) {
// If it is null, then directly call the onBlockAdded logic.
if (flag.performBlockPhysics()) {
newBlock.onBlockAdded(this.world, pos, newState);
}
}
// Sponge end
}
// if (block instanceof ITileEntityProvider) { // Sponge
if (SpongeImplHooks.hasBlockTileEntity(newBlock, newState)) {
// Sponge End
TileEntity tileentity = this.getTileEntity(pos, EnumCreateEntityType.CHECK);
if (tileentity == null) {
// Sponge Start - use SpongeImplHooks for forge compatibility
// tileentity = ((ITileEntityProvider)block).createNewTileEntity(this.worldObj, block.getMetaFromState(state)); // Sponge
tileentity = SpongeImplHooks.createTileEntity(newBlock, this.world, newState);
final User owner = peek.context.getOwner().orElse(null);
// This is required for TE's that get created during move such as pistons and ComputerCraft turtles.
if (owner != null) {
IMixinChunk spongeChunk = (IMixinChunk) this;
spongeChunk.addTrackedBlockPosition(newBlock, pos, owner, PlayerTracker.Type.OWNER);
}
// Sponge End
this.world.setTileEntity(pos, tileentity);
}
if (tileentity != null) {
tileentity.updateContainingBlockInfo();
}
}
this.dirty = true;
return currentState;
}
use of org.spongepowered.common.event.tracking.PhaseData in project SpongeCommon by SpongePowered.
the class MixinWorldServer method immediateBlockTick.
/**
* @author gabizou - March 12th, 2016
*
* Technically an overwrite to properly track on *server* worlds.
*/
@Override
public void immediateBlockTick(BlockPos pos, IBlockState state, Random random) {
this.scheduledUpdatesAreImmediate = true;
// Sponge start - Cause tracking
final PhaseData peek = PhaseTracker.getInstance().getCurrentPhaseData();
if (peek.state.ignoresBlockUpdateTick(peek)) {
state.getBlock().updateTick((WorldServer) (Object) this, pos, state, random);
// THIS NEEDS TO BE SET BACK TO FALSE OR ELSE ALL HELL BREAKS LOOSE!
// No seriously, if this is not set back to false, all future updates are processed immediately
// and various things get caught under the Unwinding Phase.
this.scheduledUpdatesAreImmediate = false;
return;
}
TrackingUtil.updateTickBlock(this, state.getBlock(), pos, state, random);
// Sponge end
this.scheduledUpdatesAreImmediate = false;
}
use of org.spongepowered.common.event.tracking.PhaseData in project SpongeCommon by SpongePowered.
the class MixinEntityPlayerMP method onDeath.
/**
* @author blood - May 12th, 2016
* @author gabizou - June 3rd, 2016
*
* @reason SpongeForge requires an overwrite so we do it here instead. This handles player death events.
*/
@Override
@Overwrite
public void onDeath(DamageSource cause) {
// Sponge start
DestructEntityEvent.Death event = SpongeCommonEventFactory.callDestructEntityEventDeath((EntityPlayerMP) (Object) this, cause);
// Double check that the PhaseTracker is already capturing the Death phase
final PhaseTracker phaseTracker;
final boolean tracksEntityDeaths;
if (!this.world.isRemote) {
phaseTracker = PhaseTracker.getInstance();
final PhaseData peek = phaseTracker.getCurrentPhaseData();
final IPhaseState state = peek.state;
tracksEntityDeaths = state.tracksEntityDeaths();
} else {
phaseTracker = null;
tracksEntityDeaths = false;
}
try (PhaseContext<?> context = !tracksEntityDeaths ? EntityPhase.State.DEATH.createPhaseContext().source(this).setDamageSource((org.spongepowered.api.event.cause.entity.damage.source.DamageSource) cause).buildAndSwitch() : null) {
// Sponge end
boolean flag = this.world.getGameRules().getBoolean("showDeathMessages");
this.connection.sendPacket(new SPacketCombatEvent(this.getCombatTracker(), SPacketCombatEvent.Event.ENTITY_DIED, flag));
if (flag) {
Team team = this.getTeam();
if (team != null && team.getDeathMessageVisibility() != Team.EnumVisible.ALWAYS) {
if (team.getDeathMessageVisibility() == Team.EnumVisible.HIDE_FOR_OTHER_TEAMS) {
this.mcServer.getPlayerList().sendMessageToAllTeamMembers((EntityPlayerMP) (Object) this, this.getCombatTracker().getDeathMessage());
} else if (team.getDeathMessageVisibility() == Team.EnumVisible.HIDE_FOR_OWN_TEAM) {
this.mcServer.getPlayerList().sendMessageToTeamOrAllPlayers((EntityPlayerMP) (Object) this, this.getCombatTracker().getDeathMessage());
}
} else {
this.mcServer.getPlayerList().sendMessage(this.getCombatTracker().getDeathMessage());
}
}
this.spawnShoulderEntities();
// Ignore keepInventory GameRule instead use keepInventory from Event
if (!event.getKeepInventory() && !this.isSpectator()) {
this.destroyVanishingCursedItems();
this.inventory.dropAllItems();
}
for (ScoreObjective scoreobjective : this.getWorldScoreboard().getObjectivesFromCriteria(IScoreCriteria.DEATH_COUNT)) {
Score score = this.getWorldScoreboard().getOrCreateScore(this.getName(), scoreobjective);
score.incrementScore();
}
EntityLivingBase entitylivingbase = this.getAttackingEntity();
if (entitylivingbase != null) {
EntityList.EntityEggInfo entitylist$entityegginfo = EntityList.ENTITY_EGGS.get(EntityList.getKey(entitylivingbase));
if (entitylist$entityegginfo != null) {
this.addStat(entitylist$entityegginfo.entityKilledByStat);
}
entitylivingbase.awardKillScore((EntityPlayerMP) (Object) this, this.scoreValue, cause);
}
this.addStat(StatList.DEATHS);
this.takeStat(StatList.TIME_SINCE_DEATH);
this.extinguish();
this.setFlag(0, false);
this.getCombatTracker().reset();
this.keepInventory = event.getKeepInventory();
}
// Sponge - brackets
}
use of org.spongepowered.common.event.tracking.PhaseData in project SpongeCommon by SpongePowered.
the class MixinItemStack method capturePlayerOnBlockDestroyed.
@SuppressWarnings("unchecked")
@Inject(method = "onBlockDestroyed", at = @At("HEAD"))
private void capturePlayerOnBlockDestroyed(World worldIn, IBlockState blockIn, BlockPos pos, EntityPlayer playerIn, CallbackInfo ci) {
if (!worldIn.isRemote) {
final PhaseTracker phaseTracker = PhaseTracker.getInstance();
final PhaseData peek = phaseTracker.getCurrentPhaseData();
final IPhaseState state = peek.state;
state.capturePlayerUsingStackToBreakBlock((ItemStack) this, (EntityPlayerMP) playerIn, peek.context);
}
}
Aggregations