Search in sources :

Example 6 with PhaseData

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();
    }
}
Also used : PhaseData(org.spongepowered.common.event.tracking.PhaseData) CollideEntityEvent(org.spongepowered.api.event.entity.CollideEntityEvent) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 7 with PhaseData

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;
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) IMixinTileEntity(org.spongepowered.common.interfaces.block.tile.IMixinTileEntity) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) PhaseData(org.spongepowered.common.event.tracking.PhaseData) IBlockState(net.minecraft.block.state.IBlockState) User(org.spongepowered.api.entity.living.player.User) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Block(net.minecraft.block.Block) EnumSkyBlock(net.minecraft.world.EnumSkyBlock) ExtendedBlockStorage(net.minecraft.world.chunk.storage.ExtendedBlockStorage) Nullable(javax.annotation.Nullable)

Example 8 with PhaseData

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;
}
Also used : PhaseData(org.spongepowered.common.event.tracking.PhaseData)

Example 9 with PhaseData

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
}
Also used : PhaseData(org.spongepowered.common.event.tracking.PhaseData) IPhaseState(org.spongepowered.common.event.tracking.IPhaseState) EntityList(net.minecraft.entity.EntityList) SPacketCombatEvent(net.minecraft.network.play.server.SPacketCombatEvent) Score(net.minecraft.scoreboard.Score) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) ScoreObjective(net.minecraft.scoreboard.ScoreObjective) DestructEntityEvent(org.spongepowered.api.event.entity.DestructEntityEvent) EntityLivingBase(net.minecraft.entity.EntityLivingBase) IInteractionObject(net.minecraft.world.IInteractionObject) IMixinTeam(org.spongepowered.common.interfaces.IMixinTeam) Team(net.minecraft.scoreboard.Team) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) IMixinEntityPlayerMP(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 10 with PhaseData

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);
    }
}
Also used : PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) PhaseData(org.spongepowered.common.event.tracking.PhaseData) IPhaseState(org.spongepowered.common.event.tracking.IPhaseState) Inject(org.spongepowered.asm.mixin.injection.Inject)

Aggregations

PhaseData (org.spongepowered.common.event.tracking.PhaseData)30 PhaseTracker (org.spongepowered.common.event.tracking.PhaseTracker)22 BlockPos (net.minecraft.util.math.BlockPos)13 IPhaseState (org.spongepowered.common.event.tracking.IPhaseState)10 User (org.spongepowered.api.entity.living.player.User)9 IBlockState (net.minecraft.block.state.IBlockState)8 EntityPlayer (net.minecraft.entity.player.EntityPlayer)8 World (org.spongepowered.api.world.World)8 Overwrite (org.spongepowered.asm.mixin.Overwrite)8 CauseStackManager (org.spongepowered.api.event.CauseStackManager)6 StackFrame (org.spongepowered.api.event.CauseStackManager.StackFrame)6 ItemStack (net.minecraft.item.ItemStack)5 BlockSnapshot (org.spongepowered.api.block.BlockSnapshot)5 Transaction (org.spongepowered.api.data.Transaction)5 BlockState (org.spongepowered.api.block.BlockState)4 Inject (org.spongepowered.asm.mixin.injection.Inject)4 Redirect (org.spongepowered.asm.mixin.injection.Redirect)4 IMixinChunk (org.spongepowered.common.interfaces.IMixinChunk)4 IMixinWorld (org.spongepowered.common.interfaces.world.IMixinWorld)4 Block (net.minecraft.block.Block)3