Search in sources :

Example 16 with BlockSnapshot

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

the class InteractionPacketState method unwind.

@Override
public void unwind(BasicPacketContext phaseContext) {
    final EntityPlayerMP player = phaseContext.getPacketPlayer();
    final ItemStack usedStack = phaseContext.getItemUsed();
    final ItemStackSnapshot usedSnapshot = ItemStackUtil.snapshotOf(usedStack);
    final Entity spongePlayer = EntityUtil.fromNative(player);
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(spongePlayer);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
        final boolean hasBlocks = !phaseContext.getCapturedBlockSupplier().isEmpty();
        final List<BlockSnapshot> capturedBlcoks = phaseContext.getCapturedBlocks();
        @Nullable final BlockSnapshot firstBlockChange = hasBlocks ? capturedBlcoks.get(0) : null;
        if (hasBlocks) {
            if (!TrackingUtil.processBlockCaptures(capturedBlcoks, this, phaseContext)) {
                // Stop entities like XP from being spawned
                return;
            }
        } else {
            phaseContext.getBlockItemDropSupplier().acceptIfNotEmpty(map -> {
                if (ShouldFire.DROP_ITEM_EVENT_DESTRUCT) {
                    for (BlockSnapshot blockChange : capturedBlcoks) {
                        final Location<World> location = blockChange.getLocation().get();
                        final Vector3d position = location.getPosition();
                        final BlockPos blockPos = VecHelper.toBlockPos(position);
                        final Collection<EntityItem> entityItems = map.get(blockPos);
                        if (!entityItems.isEmpty()) {
                            final List<Entity> items = entityItems.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
                            final DropItemEvent.Destruct event = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), items);
                            SpongeImpl.postEvent(event);
                            if (!event.isCancelled()) {
                                processSpawnedEntities(player, event);
                            }
                        }
                    }
                } else {
                    for (BlockSnapshot blockChange : capturedBlcoks) {
                        final Location<World> location = blockChange.getLocation().get();
                        final Vector3d position = location.getPosition();
                        final BlockPos blockPos = VecHelper.toBlockPos(position);
                        final Collection<EntityItem> entityItems = map.get(blockPos);
                        if (!entityItems.isEmpty()) {
                            processEntities(player, (Collection<Entity>) (Collection<?>) entityItems);
                        }
                    }
                }
            });
        }
        phaseContext.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(items -> {
            final ArrayList<Entity> entities = new ArrayList<>();
            for (EntityItem item : items) {
                entities.add(EntityUtil.fromNative(item));
            }
            final DropItemEvent.Dispense dispense = SpongeEventFactory.createDropItemEventDispense(Sponge.getCauseStackManager().getCurrentCause(), entities);
            SpongeImpl.postEvent(dispense);
            if (!dispense.isCancelled()) {
                processSpawnedEntities(player, dispense);
            }
        });
        phaseContext.getCapturedEntityDropSupplier().acceptIfNotEmpty(map -> {
            if (map.isEmpty()) {
                return;
            }
            final PrettyPrinter printer = new PrettyPrinter(80);
            printer.add("Processing Interaction").centre().hr();
            printer.add("The item stacks captured are: ");
            for (Map.Entry<UUID, Collection<ItemDropData>> entry : map.asMap().entrySet()) {
                printer.add("  - Entity with UUID: %s", entry.getKey());
                for (ItemDropData stack : entry.getValue()) {
                    printer.add("    - %s", stack);
                }
            }
            printer.trace(System.err);
        });
        phaseContext.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
            final List<Entity> projectiles = new ArrayList<>(entities.size());
            final List<Entity> spawnEggs = new ArrayList<>(entities.size());
            final List<Entity> xpOrbs = new ArrayList<>(entities.size());
            final List<Entity> normalPlacement = new ArrayList<>(entities.size());
            final List<Entity> items = new ArrayList<>(entities.size());
            for (Entity entity : entities) {
                if (entity instanceof Projectile || entity instanceof EntityThrowable) {
                    projectiles.add(entity);
                } else if (usedSnapshot.getType() == ItemTypes.SPAWN_EGG) {
                    spawnEggs.add(entity);
                } else if (entity instanceof EntityItem) {
                    items.add(entity);
                } else if (entity instanceof EntityXPOrb) {
                    xpOrbs.add(entity);
                } else {
                    normalPlacement.add(entity);
                }
            }
            if (!projectiles.isEmpty()) {
                if (ShouldFire.SPAWN_ENTITY_EVENT) {
                    try (CauseStackManager.StackFrame frame2 = Sponge.getCauseStackManager().pushCauseFrame()) {
                        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PROJECTILE);
                        Sponge.getCauseStackManager().pushCause(usedSnapshot);
                        final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), projectiles);
                        if (!SpongeImpl.postEvent(event)) {
                            processSpawnedEntities(player, event);
                        }
                    }
                } else {
                    processEntities(player, projectiles);
                }
            }
            if (!spawnEggs.isEmpty()) {
                if (ShouldFire.SPAWN_ENTITY_EVENT) {
                    try (CauseStackManager.StackFrame frame2 = Sponge.getCauseStackManager().pushCauseFrame()) {
                        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PROJECTILE);
                        Sponge.getCauseStackManager().pushCause(usedSnapshot);
                        final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), spawnEggs);
                        if (!SpongeImpl.postEvent(event)) {
                            processSpawnedEntities(player, event);
                        }
                    }
                } else {
                    processEntities(player, spawnEggs);
                }
            }
            if (!items.isEmpty()) {
                if (ShouldFire.DROP_ITEM_EVENT_DISPENSE) {
                    final DropItemEvent.Dispense dispense = SpongeEventFactory.createDropItemEventDispense(Sponge.getCauseStackManager().getCurrentCause(), items);
                    if (!SpongeImpl.postEvent(dispense)) {
                        processSpawnedEntities(player, dispense);
                    }
                } else {
                    processEntities(player, items);
                }
            }
            if (!xpOrbs.isEmpty()) {
                if (ShouldFire.SPAWN_ENTITY_EVENT) {
                    try (final CauseStackManager.StackFrame stackFrame = Sponge.getCauseStackManager().pushCauseFrame()) {
                        if (firstBlockChange != null) {
                            stackFrame.pushCause(firstBlockChange);
                        }
                        stackFrame.addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.EXPERIENCE);
                        final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), xpOrbs);
                        if (!SpongeImpl.postEvent(event)) {
                            processSpawnedEntities(player, event);
                        }
                    }
                } else {
                    processEntities(player, xpOrbs);
                }
            }
            if (!normalPlacement.isEmpty()) {
                if (ShouldFire.SPAWN_ENTITY_EVENT) {
                    try (final CauseStackManager.StackFrame stackFrame = Sponge.getCauseStackManager().pushCauseFrame()) {
                        if (firstBlockChange != null) {
                            stackFrame.pushCause(firstBlockChange);
                        }
                        final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), normalPlacement);
                        if (!SpongeImpl.postEvent(event)) {
                            processSpawnedEntities(player, event);
                        }
                    }
                } else {
                    processEntities(player, normalPlacement);
                }
            }
        });
        final IMixinContainer mixinContainer = ContainerUtil.toMixin(player.openContainer);
        mixinContainer.setCaptureInventory(false);
        mixinContainer.getCapturedTransactions().clear();
    }
}
Also used : Entity(org.spongepowered.api.entity.Entity) ArrayList(java.util.ArrayList) World(org.spongepowered.api.world.World) PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockPos(net.minecraft.util.math.BlockPos) UUID(java.util.UUID) EntityItem(net.minecraft.entity.item.EntityItem) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) EntityThrowable(net.minecraft.entity.projectile.EntityThrowable) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) Projectile(org.spongepowered.api.entity.projectile.Projectile) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) Vector3d(com.flowpowered.math.vector.Vector3d) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) Collection(java.util.Collection) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) ItemStack(org.spongepowered.api.item.inventory.ItemStack) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) Map(java.util.Map) Nullable(javax.annotation.Nullable) EntityXPOrb(net.minecraft.entity.item.EntityXPOrb)

Example 17 with BlockSnapshot

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

the class BlockTypeRegistryModule method registerDefaults.

@Override
public void registerDefaults() {
    BlockSnapshot NONE_SNAPSHOT = new SpongeBlockSnapshotBuilder().worldId(BlockUtil.INVALID_WORLD_UUID).position(new Vector3i(0, 0, 0)).blockState((BlockState) Blocks.AIR.getDefaultState()).build();
    RegistryHelper.setFinalStatic(BlockSnapshot.class, "NONE", NONE_SNAPSHOT);
    this.blockTypeMappings.put("none", (BlockType) Blocks.AIR);
}
Also used : IMixinBlockState(org.spongepowered.common.interfaces.block.IMixinBlockState) BlockState(org.spongepowered.api.block.BlockState) IBlockState(net.minecraft.block.state.IBlockState) SpongeBlockSnapshotBuilder(org.spongepowered.common.block.SpongeBlockSnapshotBuilder) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) Vector3i(com.flowpowered.math.vector.Vector3i)

Example 18 with BlockSnapshot

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

the class MixinBlockDynamicLiquid method beforeSetBlockState.

// Capture Lava falling on Water forming Stone
@Inject(method = "updateTick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/state/IBlockState;)Z"))
private void beforeSetBlockState(net.minecraft.world.World worldIn, BlockPos sourcePos, IBlockState state, Random rand, CallbackInfo ci) {
    Location<org.spongepowered.api.world.World> loc = new Location<>(((org.spongepowered.api.world.World) worldIn), sourcePos.getX(), sourcePos.getY(), sourcePos.getZ());
    LocatableBlock source = LocatableBlock.builder().location(loc).build();
    IBlockState newState = Blocks.STONE.getDefaultState();
    ChangeBlockEvent.Modify event = SpongeCommonEventFactory.callChangeBlockEventModifyLiquidMix(worldIn, sourcePos, newState, source);
    Transaction<BlockSnapshot> transaction = event.getTransactions().get(0);
    if (event.isCancelled() || !transaction.isValid()) {
        ci.cancel();
        return;
    }
    if (!worldIn.setBlockState(sourcePos.down(), BlockUtil.toNative(transaction.getFinal().getState()))) {
        ci.cancel();
    }
}
Also used : ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) IBlockState(net.minecraft.block.state.IBlockState) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) LocatableBlock(org.spongepowered.api.world.LocatableBlock) Location(org.spongepowered.api.world.Location) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 19 with BlockSnapshot

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

the class MixinBlockDynamicLiquid method afterCanFlowInto.

// Capture Fluids flowing into other blocks
@Inject(method = "tryFlowInto", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/block/state/IBlockState;getMaterial()Lnet/minecraft/block/material/Material;"))
private void afterCanFlowInto(net.minecraft.world.World worldIn, BlockPos pos, IBlockState state, int level, CallbackInfo ci) {
    IBlockState defaultState = ((Block) (Object) this).getDefaultState();
    // Do not call events when just flowing into air or same liquid
    if (state.getMaterial() != Material.AIR && state.getMaterial() != defaultState.getMaterial()) {
        IBlockState newState = defaultState.withProperty(BlockLiquid.LEVEL, level);
        ChangeBlockEvent.Break event = SpongeCommonEventFactory.callChangeBlockEventModifyLiquidBreak(worldIn, pos, newState, 3);
        Transaction<BlockSnapshot> transaction = event.getTransactions().get(0);
        if (event.isCancelled() || !transaction.isValid()) {
            ci.cancel();
            return;
        }
        // Transaction modified?
        if (transaction.getDefault() != transaction.getFinal()) {
            worldIn.setBlockState(pos, BlockUtil.toNative(transaction.getFinal().getState()));
            ci.cancel();
        }
    // else do vanilla logic
    }
}
Also used : ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) IBlockState(net.minecraft.block.state.IBlockState) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) LocatableBlock(org.spongepowered.api.world.LocatableBlock) Block(net.minecraft.block.Block) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 20 with BlockSnapshot

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

the class SpongeCommonEventFactory method callInteractItemEventSecondary.

public static InteractItemEvent callInteractItemEventSecondary(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.Secondary event;
        if (hand == EnumHand.MAIN_HAND) {
            event = SpongeEventFactory.createInteractItemEventSecondaryMainHand(Sponge.getCauseStackManager().getCurrentCause(), HandTypes.MAIN_HAND, Optional.ofNullable(hitVec), ItemStackUtil.snapshotOf(stack));
        } else {
            event = SpongeEventFactory.createInteractItemEventSecondaryOffHand(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)

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