Search in sources :

Example 21 with BlockSnapshot

use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method callInteractItemEventPrimary.

public static InteractItemEvent callInteractItemEventPrimary(EntityPlayer player, ItemStack stack, EnumHand hand, @Nullable Vector3d hitVec, Object hitTarget) {
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        if (hitTarget instanceof Entity) {
            Sponge.getCauseStackManager().addContext(EventContextKeys.ENTITY_HIT, ((Entity) hitTarget));
        } else if (hitTarget instanceof BlockSnapshot) {
            Sponge.getCauseStackManager().addContext(EventContextKeys.BLOCK_HIT, (BlockSnapshot) hitTarget);
        }
        InteractItemEvent.Primary event;
        if (hand == EnumHand.MAIN_HAND) {
            event = SpongeEventFactory.createInteractItemEventPrimaryMainHand(Sponge.getCauseStackManager().getCurrentCause(), HandTypes.MAIN_HAND, Optional.ofNullable(hitVec), ItemStackUtil.snapshotOf(stack));
        } else {
            event = SpongeEventFactory.createInteractItemEventPrimaryOffHand(Sponge.getCauseStackManager().getCurrentCause(), HandTypes.OFF_HAND, Optional.ofNullable(hitVec), ItemStackUtil.snapshotOf(stack));
        }
        SpongeImpl.postEvent(event);
        return event;
    }
}
Also used : Entity(org.spongepowered.api.entity.Entity) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) InteractItemEvent(org.spongepowered.api.event.item.inventory.InteractItemEvent) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot)

Example 22 with BlockSnapshot

use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method callChangeBlockEventModifyLiquidMix.

public static ChangeBlockEvent.Modify callChangeBlockEventModifyLiquidMix(net.minecraft.world.World worldIn, BlockPos pos, IBlockState state, @Nullable Object source) {
    final PhaseTracker phaseTracker = PhaseTracker.getInstance();
    final PhaseData data = phaseTracker.getCurrentPhaseData();
    BlockState fromState = BlockUtil.fromNative(worldIn.getBlockState(pos));
    BlockState toState = BlockUtil.fromNative(state);
    User owner = data.context.getOwner().orElse(null);
    User notifier = data.context.getNotifier().orElse(null);
    if (source == null) {
        // If source is null the source is the block itself
        source = LocatableBlock.builder().state(fromState).world(((World) worldIn)).position(pos.getX(), pos.getY(), pos.getZ()).build();
    }
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(source);
        Sponge.getCauseStackManager().addContext(EventContextKeys.LIQUID_MIX, (World) worldIn);
        if (owner != null) {
            Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, owner);
        }
        if (notifier != null) {
            Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier);
        }
        WorldProperties world = ((World) worldIn).getProperties();
        Vector3i position = new Vector3i(pos.getX(), pos.getY(), pos.getZ());
        Transaction<BlockSnapshot> transaction = new Transaction<>(BlockSnapshot.builder().blockState(fromState).world(world).position(position).build(), BlockSnapshot.builder().blockState(toState).world(world).position(position).build());
        ChangeBlockEvent.Modify event = SpongeEventFactory.createChangeBlockEventModify(Sponge.getCauseStackManager().getCurrentCause(), Collections.singletonList(transaction));
        SpongeImpl.postEvent(event);
        return event;
    }
}
Also used : PhaseData(org.spongepowered.common.event.tracking.PhaseData) User(org.spongepowered.api.entity.living.player.User) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) World(org.spongepowered.api.world.World) ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) BlockState(org.spongepowered.api.block.BlockState) IBlockState(net.minecraft.block.state.IBlockState) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) Transaction(org.spongepowered.api.data.Transaction) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Vector3i(com.flowpowered.math.vector.Vector3i) WorldProperties(org.spongepowered.api.world.storage.WorldProperties)

Example 23 with BlockSnapshot

use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.

the class CustomExplosionState method processBlockCaptures.

@SuppressWarnings({ "unchecked" })
private void processBlockCaptures(List<BlockSnapshot> snapshots, Explosion explosion, Cause cause, PhaseContext<?> context) {
    if (snapshots.isEmpty()) {
        return;
    }
    ImmutableList<Transaction<BlockSnapshot>>[] transactionArrays = new ImmutableList[TrackingUtil.EVENT_COUNT];
    ImmutableList.Builder<Transaction<BlockSnapshot>>[] transactionBuilders = new ImmutableList.Builder[TrackingUtil.EVENT_COUNT];
    for (int i = 0; i < TrackingUtil.EVENT_COUNT; i++) {
        transactionBuilders[i] = new ImmutableList.Builder<>();
    }
    final List<ChangeBlockEvent> blockEvents = new ArrayList<>();
    for (BlockSnapshot snapshot : snapshots) {
        // This processes each snapshot to assign them to the correct event in the next area, with the
        // correct builder array entry.
        TrackingUtil.TRANSACTION_PROCESSOR.apply(transactionBuilders).accept(TrackingUtil.TRANSACTION_CREATION.apply(snapshot));
    }
    for (int i = 0; i < TrackingUtil.EVENT_COUNT; i++) {
        // Build each event array
        transactionArrays[i] = transactionBuilders[i].build();
    }
    // Clear captured snapshots after processing them
    context.getCapturedBlocksOrEmptyList().clear();
    final ChangeBlockEvent[] mainEvents = new ChangeBlockEvent[BlockChange.values().length];
    // case in point for WorldTick event listeners since the players are captured non-deterministically
    try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        if (context.getNotifier().isPresent()) {
            Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, context.getNotifier().get());
        }
        if (context.getOwner().isPresent()) {
            Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, context.getOwner().get());
        }
        try {
            this.associateAdditionalCauses(this, context);
        } catch (Exception e) {
        // TODO - this should be a thing to associate additional objects in the cause, or context, but for now it's just a simple
        // try catch to avoid bombing on performing block changes.
        }
        // Creates the block events accordingly to the transaction arrays
        // Needs to throw events
        iterateChangeBlockEvents(transactionArrays, blockEvents, mainEvents);
        // Copied from TrackingUtil#throwMultiEventsAndCreatePost
        for (BlockChange blockChange : BlockChange.values()) {
            final ChangeBlockEvent mainEvent = mainEvents[blockChange.ordinal()];
            if (mainEvent != null) {
                Sponge.getCauseStackManager().pushCause(mainEvent);
            }
        }
        final ImmutableList<Transaction<BlockSnapshot>> transactions = transactionArrays[TrackingUtil.MULTI_CHANGE_INDEX];
        final ExplosionEvent.Post postEvent = SpongeEventFactory.createExplosionEventPost(cause, explosion, transactions);
        if (postEvent == null) {
            // Means that we have had no actual block changes apparently?
            return;
        }
        SpongeImpl.postEvent(postEvent);
        final List<Transaction<BlockSnapshot>> invalid = new ArrayList<>();
        boolean noCancelledTransactions = true;
        // transactions of the preceeding block events)
        for (ChangeBlockEvent blockEvent : blockEvents) {
            // Need to only check if the event is cancelled, If it is, restore
            if (blockEvent.isCancelled()) {
                noCancelledTransactions = false;
                // Don't restore the transactions just yet, since we're just marking them as invalid for now
                for (Transaction<BlockSnapshot> transaction : Lists.reverse(blockEvent.getTransactions())) {
                    transaction.setValid(false);
                }
            }
        }
        // Finally check the post event
        if (postEvent.isCancelled()) {
            // Of course, if post is cancelled, just mark all transactions as invalid.
            noCancelledTransactions = false;
            for (Transaction<BlockSnapshot> transaction : postEvent.getTransactions()) {
                transaction.setValid(false);
            }
        }
        // Because after, we will restore all the invalid transactions in reverse order.
        for (Transaction<BlockSnapshot> transaction : postEvent.getTransactions()) {
            if (!transaction.isValid()) {
                invalid.add(transaction);
                // Cancel any block drops performed, avoids any item drops, regardless
                final Location<World> location = transaction.getOriginal().getLocation().orElse(null);
                if (location != null) {
                    final BlockPos pos = ((IMixinLocation) (Object) location).getBlockPos();
                    context.getBlockItemDropSupplier().removeAllIfNotEmpty(pos);
                }
            }
        }
        if (!invalid.isEmpty()) {
            // We need to set this value and return it to signify that some transactions were cancelled
            noCancelledTransactions = false;
            // or the events were cancelled), again in reverse order of which they were received.
            for (Transaction<BlockSnapshot> transaction : Lists.reverse(invalid)) {
                transaction.getOriginal().restore(true, BlockChangeFlags.NONE);
                // Cancel any block drops or harvests for the block change.
                // This prevents unnecessary spawns.
                final Location<World> location = transaction.getOriginal().getLocation().orElse(null);
                if (location != null) {
                    final BlockPos pos = ((IMixinLocation) (Object) location).getBlockPos();
                    context.getBlockDropSupplier().removeAllIfNotEmpty(pos);
                }
            }
        }
        TrackingUtil.performBlockAdditions(postEvent.getTransactions(), this, context, noCancelledTransactions);
    }
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) ExplosionEvent(org.spongepowered.api.event.world.ExplosionEvent) ArrayList(java.util.ArrayList) World(org.spongepowered.api.world.World) ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) BlockChange(org.spongepowered.common.world.BlockChange) BlockPos(net.minecraft.util.math.BlockPos) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) Transaction(org.spongepowered.api.data.Transaction) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame)

Example 24 with BlockSnapshot

use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.

the class MixinEntityLightningBolt method onStrikeBlock.

private boolean onStrikeBlock(net.minecraft.world.World world, BlockPos pos, IBlockState blockState) {
    if (!this.effect && ((World) world).containsBlock(pos.getX(), pos.getY(), pos.getZ())) {
        Vector3i pos3i = VecHelper.toVector3i(pos);
        Transaction<BlockSnapshot> transaction = new Transaction<BlockSnapshot>(new SpongeBlockSnapshotBuilder().blockState((BlockState) world.getBlockState(pos)).world(((World) world).getProperties()).position(pos3i).build(), new SpongeBlockSnapshotBuilder().blockState((BlockState) blockState).world(((World) world).getProperties()).position(pos3i).build());
        if (!this.struckBlocks.contains(transaction)) {
            this.struckBlocks.add(transaction);
        }
        return true;
    }
    return false;
}
Also used : Transaction(org.spongepowered.api.data.Transaction) SpongeBlockSnapshotBuilder(org.spongepowered.common.block.SpongeBlockSnapshotBuilder) Vector3i(com.flowpowered.math.vector.Vector3i) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) World(org.spongepowered.api.world.World)

Example 25 with BlockSnapshot

use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.

the class SpongeHooks method getFriendlyCauseName.

public static String getFriendlyCauseName(Cause cause) {
    String causedBy = "Unknown";
    Object rootCause = cause.root();
    if (rootCause instanceof User) {
        User user = (User) rootCause;
        causedBy = user.getName();
    } else if (rootCause instanceof EntityItem) {
        EntityItem item = (EntityItem) rootCause;
        causedBy = item.getItem().getDisplayName();
    } else if (rootCause instanceof Entity) {
        Entity causeEntity = (Entity) rootCause;
        causedBy = causeEntity.getName();
    } else if (rootCause instanceof BlockSnapshot) {
        BlockSnapshot snapshot = (BlockSnapshot) rootCause;
        causedBy = snapshot.getState().getType().getId();
    } else if (rootCause instanceof CatalogType) {
        CatalogType type = (CatalogType) rootCause;
        causedBy = type.getId();
    } else if (rootCause instanceof PluginContainer) {
        PluginContainer plugin = (PluginContainer) rootCause;
        causedBy = plugin.getId();
    } else {
        causedBy = rootCause.getClass().getName();
    }
    return causedBy;
}
Also used : Entity(net.minecraft.entity.Entity) TileEntity(net.minecraft.tileentity.TileEntity) CatalogType(org.spongepowered.api.CatalogType) User(org.spongepowered.api.entity.living.player.User) PluginContainer(org.spongepowered.api.plugin.PluginContainer) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) EntityItem(net.minecraft.entity.item.EntityItem)

Aggregations

BlockSnapshot (org.spongepowered.api.block.BlockSnapshot)144 World (org.spongepowered.api.world.World)64 Listener (org.spongepowered.api.event.Listener)61 Location (org.spongepowered.api.world.Location)27 BlockState (org.spongepowered.api.block.BlockState)21 BlockPos (net.minecraft.util.math.BlockPos)20 Entity (org.spongepowered.api.entity.Entity)20 CauseStackManager (org.spongepowered.api.event.CauseStackManager)19 Region (br.net.fabiozumbi12.RedProtect.Sponge.Region)18 IBlockState (net.minecraft.block.state.IBlockState)18 Transaction (org.spongepowered.api.data.Transaction)17 BlockType (org.spongepowered.api.block.BlockType)15 Direction (org.spongepowered.api.util.Direction)15 SpongeBlockSnapshot (org.spongepowered.common.block.SpongeBlockSnapshot)14 Vector3d (com.flowpowered.math.vector.Vector3d)13 ArrayList (java.util.ArrayList)13 ChangeBlockEvent (org.spongepowered.api.event.block.ChangeBlockEvent)13 Player (org.spongepowered.api.entity.living.player.Player)12 User (org.spongepowered.api.entity.living.player.User)11 LocatableBlock (org.spongepowered.api.world.LocatableBlock)11