Search in sources :

Example 1 with UnwindingPhaseContext

use of org.spongepowered.common.event.tracking.phase.general.UnwindingPhaseContext in project SpongeForge by SpongePowered.

the class SpongeForgeEventFactory method callBlockPlaceEvent.

public static ChangeBlockEvent.Place callBlockPlaceEvent(Event event) {
    ChangeBlockEvent.Place spongeEvent = (ChangeBlockEvent.Place) event;
    if (spongeEvent.getCause().root() instanceof Player) {
        EntityPlayer player = (EntityPlayer) spongeEvent.getCause().first(Player.class).get();
        net.minecraft.world.World world = player.world;
        final PhaseTracker phaseTracker = PhaseTracker.getInstance();
        final PhaseContext<?> currentContext = phaseTracker.getCurrentContext();
        PhaseContext<?> target = currentContext;
        if (currentContext instanceof UnwindingPhaseContext) {
            target = ((UnwindingPhaseContext) currentContext).getUnwindingContext();
        }
        PacketContext<?> context = target instanceof PacketContext<?> ? (PacketContext<?>) target : null;
        Packet<?> contextPacket = context != null ? context.getPacket() : null;
        if (contextPacket == null) {
            return spongeEvent;
        }
        if (spongeEvent.getTransactions().size() == 1) {
            BlockPos pos = VecHelper.toBlockPos(spongeEvent.getTransactions().get(0).getOriginal().getPosition());
            IBlockState state = (IBlockState) spongeEvent.getTransactions().get(0).getOriginal().getState();
            net.minecraftforge.common.util.BlockSnapshot blockSnapshot = new net.minecraftforge.common.util.BlockSnapshot(world, pos, state);
            IBlockState placedAgainst = Blocks.AIR.getDefaultState();
            EnumHand hand = EnumHand.MAIN_HAND;
            if (contextPacket instanceof CPacketPlayerTryUseItemOnBlock) {
                CPacketPlayerTryUseItemOnBlock packet = (CPacketPlayerTryUseItemOnBlock) contextPacket;
                EnumFacing facing = packet.getDirection();
                placedAgainst = blockSnapshot.getWorld().getBlockState(blockSnapshot.getPos().offset(facing.getOpposite()));
                hand = packet.getHand();
            }
            BlockEvent.PlaceEvent forgeEvent = new BlockEvent.PlaceEvent(blockSnapshot, placedAgainst, player, hand);
            ((IMixinEventBus) MinecraftForge.EVENT_BUS).post(forgeEvent, true);
            if (forgeEvent.isCanceled()) {
                spongeEvent.setCancelled(true);
            }
        } else {
            // multi
            Iterator<Transaction<BlockSnapshot>> iterator = spongeEvent.getTransactions().iterator();
            List<net.minecraftforge.common.util.BlockSnapshot> blockSnapshots = new ArrayList<>();
            while (iterator.hasNext()) {
                Transaction<BlockSnapshot> transaction = iterator.next();
                Location<World> location = transaction.getOriginal().getLocation().get();
                IBlockState state = (IBlockState) transaction.getOriginal().getState();
                BlockPos pos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
                net.minecraftforge.common.util.BlockSnapshot blockSnapshot = new net.minecraftforge.common.util.BlockSnapshot(world, pos, state);
                blockSnapshots.add(blockSnapshot);
            }
            IBlockState placedAgainst = Blocks.AIR.getDefaultState();
            EnumHand hand = EnumHand.MAIN_HAND;
            if (contextPacket instanceof CPacketPlayerTryUseItemOnBlock) {
                CPacketPlayerTryUseItemOnBlock packet = (CPacketPlayerTryUseItemOnBlock) contextPacket;
                EnumFacing facing = packet.getDirection();
                placedAgainst = blockSnapshots.get(0).getWorld().getBlockState(blockSnapshots.get(0).getPos().offset(facing.getOpposite()));
                hand = packet.getHand();
            }
            BlockEvent.MultiPlaceEvent forgeEvent = new BlockEvent.MultiPlaceEvent(blockSnapshots, placedAgainst, player, hand);
            ((IMixinEventBus) MinecraftForge.EVENT_BUS).post(forgeEvent, true);
            if (forgeEvent.isCanceled()) {
                spongeEvent.setCancelled(true);
            }
        }
    }
    return spongeEvent;
}
Also used : EnumFacing(net.minecraft.util.EnumFacing) ArrayList(java.util.ArrayList) UnwindingPhaseContext(org.spongepowered.common.event.tracking.phase.general.UnwindingPhaseContext) World(org.spongepowered.api.world.World) IMixinWorld(org.spongepowered.common.interfaces.world.IMixinWorld) ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) EnumHand(net.minecraft.util.EnumHand) BlockPos(net.minecraft.util.math.BlockPos) Player(org.spongepowered.api.entity.living.player.Player) EntityPlayer(net.minecraft.entity.player.EntityPlayer) IBlockState(net.minecraft.block.state.IBlockState) IMixinBlockSnapshot(org.spongepowered.mod.interfaces.IMixinBlockSnapshot) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) CPacketPlayerTryUseItemOnBlock(net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock) IMixinEventBus(org.spongepowered.mod.interfaces.IMixinEventBus) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) Transaction(org.spongepowered.api.data.Transaction) EntityPlayer(net.minecraft.entity.player.EntityPlayer) ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) BlockEvent(net.minecraftforge.event.world.BlockEvent) InteractBlockEvent(org.spongepowered.api.event.block.InteractBlockEvent) NotifyNeighborBlockEvent(org.spongepowered.api.event.block.NotifyNeighborBlockEvent)

Example 2 with UnwindingPhaseContext

use of org.spongepowered.common.event.tracking.phase.general.UnwindingPhaseContext in project SpongeCommon by SpongePowered.

the class PhaseTracker method completePhase.

@SuppressWarnings({ "rawtypes", "unused", "try" })
public void completePhase(IPhaseState<?> prevState) {
    final PhaseData currentPhaseData = this.stack.peek();
    final IPhaseState<?> state = currentPhaseData.state;
    final boolean isEmpty = this.stack.isEmpty();
    if (isEmpty) {
        // The random occurrence that we're told to complete a phase
        // while a world is being changed unknowingly.
        this.printEmptyStackOnCompletion();
        return;
    }
    if (prevState != state) {
        this.printIncorrectPhaseCompletion(prevState, state);
        // The phase on the top of the stack was most likely never completed.
        // Since we don't know when and where completePhase was intended to be called for it,
        // we simply pop it to allow processing to continue (somewhat) as normal
        this.stack.pop();
    }
    if (SpongeImpl.getGlobalConfig().getConfig().getPhaseTracker().isVerbose() && this.stack.size() > 6 && state != GeneralPhase.Post.UNWINDING && !state.isExpectedForReEntrance()) {
        // This printing is to detect possibilities of a phase not being cleared properly
        // and resulting in a "runaway" phase state accumulation.
        this.printRunnawayPhaseCompletion(state);
    }
    this.stack.pop();
    // If pop is called, the Deque will already throw an exception if there is no element
    // so it's an error properly handled.
    final TrackingPhase phase = state.getPhase();
    final PhaseContext<?> context = currentPhaseData.context;
    try (final UnwindingPhaseContext unwinding = UnwindingPhaseContext.unwind(state, context)) {
        // a new list of capture lists
        try {
            // Yes this is a nested try, but in the event the current phase cannot be unwound, at least unwind UNWINDING
            ((IPhaseState) state).unwind(context);
        } catch (Exception e) {
            this.printMessageWithCaughtException("Exception Exiting Phase", "Something happened when trying to unwind", state, context, e);
        }
    } catch (Exception e) {
        this.printMessageWithCaughtException("Exception Post Dispatching Phase", "Something happened when trying to post dispatch state", state, context, e);
    }
}
Also used : TrackingPhase(org.spongepowered.common.event.tracking.phase.TrackingPhase) UnwindingPhaseContext(org.spongepowered.common.event.tracking.phase.general.UnwindingPhaseContext) ReportedException(net.minecraft.util.ReportedException)

Aggregations

UnwindingPhaseContext (org.spongepowered.common.event.tracking.phase.general.UnwindingPhaseContext)2 ArrayList (java.util.ArrayList)1 IBlockState (net.minecraft.block.state.IBlockState)1 EntityPlayer (net.minecraft.entity.player.EntityPlayer)1 CPacketPlayerTryUseItemOnBlock (net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock)1 EnumFacing (net.minecraft.util.EnumFacing)1 EnumHand (net.minecraft.util.EnumHand)1 ReportedException (net.minecraft.util.ReportedException)1 BlockPos (net.minecraft.util.math.BlockPos)1 BlockEvent (net.minecraftforge.event.world.BlockEvent)1 BlockSnapshot (org.spongepowered.api.block.BlockSnapshot)1 Transaction (org.spongepowered.api.data.Transaction)1 Player (org.spongepowered.api.entity.living.player.Player)1 ChangeBlockEvent (org.spongepowered.api.event.block.ChangeBlockEvent)1 InteractBlockEvent (org.spongepowered.api.event.block.InteractBlockEvent)1 NotifyNeighborBlockEvent (org.spongepowered.api.event.block.NotifyNeighborBlockEvent)1 World (org.spongepowered.api.world.World)1 PhaseTracker (org.spongepowered.common.event.tracking.PhaseTracker)1 TrackingPhase (org.spongepowered.common.event.tracking.phase.TrackingPhase)1 IMixinWorld (org.spongepowered.common.interfaces.world.IMixinWorld)1