Search in sources :

Example 81 with BlockSnapshot

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

the class InteractEntityPacketState method unwind.

@Override
public void unwind(BasicPacketContext phaseContext) {
    final EntityPlayerMP player = phaseContext.getPacketPlayer();
    final CPacketUseEntity useEntityPacket = phaseContext.getPacket();
    final net.minecraft.entity.Entity entity = useEntityPacket.getEntityFromWorld(player.world);
    if (entity == null) {
        // Something happened?
        return;
    }
    final World spongeWorld = EntityUtil.getSpongeWorld(player);
    EntityUtil.toMixin(entity).setNotifier(player.getUniqueID());
    phaseContext.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blocks -> {
        final PrettyPrinter printer = new PrettyPrinter(80);
        printer.add("Processing Interact Entity").centre().hr();
        printer.add("The blocks captured are:");
        for (BlockSnapshot blockSnapshot : blocks) {
            printer.add("  Block: %s", blockSnapshot);
        }
        printer.trace(System.err);
    });
    phaseContext.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
        final PrettyPrinter printer = new PrettyPrinter(80);
        printer.add("Processing Interact Entity").centre().hr();
        printer.add("The entities captured are:");
        for (Entity capturedEntity : entities) {
            printer.add("  Entity: %s", capturedEntity);
        }
        printer.trace(System.err);
    });
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(player);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PLACEMENT);
        phaseContext.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(entities -> {
            final List<Entity> items = entities.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
            SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), items);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                processSpawnedEntities(player, event);
            }
        });
    }
    phaseContext.getCapturedEntityDropSupplier().acceptIfNotEmpty(map -> {
        final PrettyPrinter printer = new PrettyPrinter(80);
        printer.add("Processing Interact Entity").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.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(snapshots -> TrackingUtil.processBlockCaptures(snapshots, this, phaseContext));
}
Also used : CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) Entity(org.spongepowered.api.entity.Entity) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) World(org.spongepowered.api.world.World) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Collection(java.util.Collection) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) UUID(java.util.UUID) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) Map(java.util.Map)

Example 82 with BlockSnapshot

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

the class MixinPlayerInteractionManager method processRightClickBlock.

/**
 * @author Aaron1011
 * @author gabizou - May 28th, 2016 - Rewritten for 1.9.4
 *
 * @reason Fire interact block event.
 */
@Overwrite
public EnumActionResult processRightClickBlock(EntityPlayer player, net.minecraft.world.World worldIn, ItemStack stack, EnumHand hand, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ) {
    if (this.gameType == GameType.SPECTATOR) {
        TileEntity tileentity = worldIn.getTileEntity(pos);
        if (tileentity instanceof ILockableContainer) {
            Block block = worldIn.getBlockState(pos).getBlock();
            ILockableContainer ilockablecontainer = (ILockableContainer) tileentity;
            if (ilockablecontainer instanceof TileEntityChest && block instanceof BlockChest) {
                ilockablecontainer = ((BlockChest) block).getLockableContainer(worldIn, pos);
            }
            if (ilockablecontainer != null) {
                // TODO - fire event
                player.displayGUIChest(ilockablecontainer);
                return EnumActionResult.SUCCESS;
            }
        } else if (tileentity instanceof IInventory) {
            // TODO - fire event
            player.displayGUIChest((IInventory) tileentity);
            return EnumActionResult.SUCCESS;
        }
        return EnumActionResult.PASS;
    }
    // else { // Sponge - Remove unecessary else
    // Sponge Start - Create an interact block event before something happens.
    final ItemStack oldStack = stack.copy();
    final BlockSnapshot currentSnapshot = ((World) worldIn).createSnapshot(pos.getX(), pos.getY(), pos.getZ());
    final InteractBlockEvent.Secondary event = SpongeCommonEventFactory.callInteractBlockEventSecondary(player, oldStack, new Vector3d(pos.getX() + hitX, pos.getY() + hitY, pos.getZ() + hitZ), currentSnapshot, DirectionFacingProvider.getInstance().getKey(facing).get(), hand);
    if (!ItemStack.areItemStacksEqual(oldStack, this.player.getHeldItem(hand))) {
        SpongeCommonEventFactory.playerInteractItemChanged = true;
    }
    if (event.isCancelled()) {
        final IBlockState state = (IBlockState) currentSnapshot.getState();
        if (state.getBlock() == Blocks.COMMAND_BLOCK) {
            // CommandBlock GUI opens solely on the client, we need to force it close on cancellation
            this.player.connection.sendPacket(new SPacketCloseWindow(0));
        } else if (state.getProperties().containsKey(BlockDoor.HALF)) {
            // client to resolve this
            if (state.getValue(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER) {
                this.player.connection.sendPacket(new SPacketBlockChange(worldIn, pos.up()));
            } else {
                this.player.connection.sendPacket(new SPacketBlockChange(worldIn, pos.down()));
            }
        } else if (!oldStack.isEmpty()) {
            // Stopping the placement of a door or double plant causes artifacts (ghosts) on the top-side of the block. We need to remove it
            final Item item = oldStack.getItem();
            if (item instanceof ItemDoor || (item instanceof ItemBlock && ((ItemBlock) item).getBlock().equals(Blocks.DOUBLE_PLANT))) {
                this.player.connection.sendPacket(new SPacketBlockChange(worldIn, pos.up(2)));
            }
        }
        SpongeCommonEventFactory.interactBlockEventCancelled = true;
        return EnumActionResult.FAIL;
    }
    if (!player.isSneaking() || player.getHeldItemMainhand().isEmpty() && player.getHeldItemOffhand().isEmpty()) {
        // Also, store the result instead of returning immediately
        if (event.getUseBlockResult() != Tristate.FALSE) {
            IBlockState iblockstate = (IBlockState) currentSnapshot.getState();
            Container lastOpenContainer = player.openContainer;
            EnumActionResult result = iblockstate.getBlock().onBlockActivated(worldIn, pos, iblockstate, player, hand, facing, hitX, hitY, hitZ) ? EnumActionResult.SUCCESS : EnumActionResult.PASS;
            // if itemstack changed, avoid restore
            if (!ItemStack.areItemStacksEqual(oldStack, this.player.getHeldItem(hand))) {
                SpongeCommonEventFactory.playerInteractItemChanged = true;
            }
            result = this.handleOpenEvent(lastOpenContainer, this.player, currentSnapshot, result);
            if (result != EnumActionResult.PASS) {
                return result;
            }
        } else {
            // Need to send a block change to the client, because otherwise, they are not
            // going to be told about the block change.
            this.player.connection.sendPacket(new SPacketBlockChange(this.world, pos));
            // it wasn't cancelled, but perform no further processing.
            return EnumActionResult.FAIL;
        }
    // Sponge End
    }
    if (stack.isEmpty()) {
        return EnumActionResult.PASS;
    } else if (player.getCooldownTracker().hasCooldown(stack.getItem())) {
        return EnumActionResult.PASS;
    } else if (stack.getItem() instanceof ItemBlock) {
        Block block = ((ItemBlock) stack.getItem()).getBlock();
        if ((block instanceof BlockCommandBlock || block instanceof BlockStructure) && !player.canUseCommandBlock()) {
            return EnumActionResult.FAIL;
        }
    }
    // else if (this.isCreative()) { // Sponge - Rewrite this to handle an isCreative check after the result, since we have a copied stack at the top of this method.
    // int j = stack.getMetadata();
    // int i = stack.stackSize;
    // EnumActionResult enumactionresult = stack.onItemUse(player, worldIn, pos, hand, facing, offsetX, offsetY, offsetZ);
    // stack.setItemDamage(j);
    // stack.stackSize = i;
    // return enumactionresult;
    // } else {
    // return stack.onItemUse(player, worldIn, pos, hand, facing, offsetX, offsetY, offsetZ);
    // }
    // } // Sponge - Remove unecessary else bracket
    // Sponge Start - complete the method with the micro change of resetting item damage and quantity from the copied stack.
    final EnumActionResult result = stack.onItemUse(player, worldIn, pos, hand, facing, hitX, hitY, hitZ);
    if (this.isCreative()) {
        stack.setItemDamage(oldStack.getItemDamage());
        stack.setCount(oldStack.getCount());
    }
    if (!ItemStack.areItemStacksEqual(player.getHeldItem(hand), oldStack) || result != EnumActionResult.SUCCESS) {
        player.openContainer.detectAndSendChanges();
    }
    return result;
// Sponge end
// } // Sponge - Remove unecessary else bracket
}
Also used : IInventory(net.minecraft.inventory.IInventory) TileEntityChest(net.minecraft.tileentity.TileEntityChest) IBlockState(net.minecraft.block.state.IBlockState) ItemDoor(net.minecraft.item.ItemDoor) BlockChest(net.minecraft.block.BlockChest) BlockCommandBlock(net.minecraft.block.BlockCommandBlock) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) BlockStructure(net.minecraft.block.BlockStructure) World(org.spongepowered.api.world.World) ItemBlock(net.minecraft.item.ItemBlock) SPacketBlockChange(net.minecraft.network.play.server.SPacketBlockChange) TileEntity(net.minecraft.tileentity.TileEntity) ILockableContainer(net.minecraft.world.ILockableContainer) Item(net.minecraft.item.Item) ILockableContainer(net.minecraft.world.ILockableContainer) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) Container(net.minecraft.inventory.Container) EnumActionResult(net.minecraft.util.EnumActionResult) InteractBlockEvent(org.spongepowered.api.event.block.InteractBlockEvent) Vector3d(com.flowpowered.math.vector.Vector3d) Block(net.minecraft.block.Block) BlockCommandBlock(net.minecraft.block.BlockCommandBlock) ItemBlock(net.minecraft.item.ItemBlock) SPacketCloseWindow(net.minecraft.network.play.server.SPacketCloseWindow) ItemStack(net.minecraft.item.ItemStack) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 83 with BlockSnapshot

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

the class SpongeCommonEventFactory method handleCollideImpactEvent.

public static boolean handleCollideImpactEvent(net.minecraft.entity.Entity projectile, @Nullable ProjectileSource projectileSource, RayTraceResult movingObjectPosition) {
    final PhaseTracker phaseTracker = PhaseTracker.getInstance();
    RayTraceResult.Type movingObjectType = movingObjectPosition.typeOfHit;
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(projectile);
        Sponge.getCauseStackManager().addContext(EventContextKeys.PROJECTILE_SOURCE, projectileSource == null ? ProjectileSource.UNKNOWN : projectileSource);
        final Optional<User> owner = phaseTracker.getCurrentPhaseData().context.getOwner();
        owner.ifPresent(user -> Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, user));
        Location<World> impactPoint = new Location<>((World) projectile.world, VecHelper.toVector3d(movingObjectPosition.hitVec));
        boolean cancelled = false;
        if (movingObjectType == RayTraceResult.Type.BLOCK) {
            final BlockPos blockPos = movingObjectPosition.getBlockPos();
            if (blockPos.getY() <= 0) {
                return false;
            }
            BlockSnapshot targetBlock = ((World) projectile.world).createSnapshot(VecHelper.toVector3i(movingObjectPosition.getBlockPos()));
            Direction side = Direction.NONE;
            if (movingObjectPosition.sideHit != null) {
                side = DirectionFacingProvider.getInstance().getKey(movingObjectPosition.sideHit).get();
            }
            CollideBlockEvent.Impact event = SpongeEventFactory.createCollideBlockEventImpact(Sponge.getCauseStackManager().getCurrentCause(), impactPoint, targetBlock.getState(), targetBlock.getLocation().get(), side);
            cancelled = SpongeImpl.postEvent(event);
            // Track impact block if event is not cancelled
            if (!cancelled && owner.isPresent()) {
                BlockPos targetPos = VecHelper.toBlockPos(impactPoint.getBlockPosition());
                IMixinChunk spongeChunk = (IMixinChunk) projectile.world.getChunkFromBlockCoords(targetPos);
                spongeChunk.addTrackedBlockPosition((Block) targetBlock.getState().getType(), targetPos, owner.get(), PlayerTracker.Type.NOTIFIER);
            }
        } else if (movingObjectPosition.entityHit != null) {
            // entity
            ArrayList<Entity> entityList = new ArrayList<>();
            entityList.add((Entity) movingObjectPosition.entityHit);
            CollideEntityEvent.Impact event = SpongeEventFactory.createCollideEntityEventImpact(Sponge.getCauseStackManager().getCurrentCause(), entityList, impactPoint);
            cancelled = SpongeImpl.postEvent(event);
        }
        if (cancelled) {
            // Entities such as EnderPearls call setDead during onImpact. However, if the event is cancelled
            // setDead will never be called resulting in a bad state such as falling through world.
            projectile.setDead();
        }
        return cancelled;
    }
}
Also used : Entity(org.spongepowered.api.entity.Entity) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) User(org.spongepowered.api.entity.living.player.User) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) RayTraceResult(net.minecraft.util.math.RayTraceResult) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) ArrayList(java.util.ArrayList) World(org.spongepowered.api.world.World) Direction(org.spongepowered.api.util.Direction) CollideBlockEvent(org.spongepowered.api.event.block.CollideBlockEvent) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockPos(net.minecraft.util.math.BlockPos) Location(org.spongepowered.api.world.Location)

Example 84 with BlockSnapshot

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

the class SpongeCommonEventFactory method callChangeBlockEventModifyLiquidBreak.

public static ChangeBlockEvent.Break callChangeBlockEventModifyLiquidBreak(net.minecraft.world.World worldIn, BlockPos pos, IBlockState state, int flags) {
    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);
    Object source = data.context.getSource(LocatableBlock.class).orElse(null);
    if (source == null) {
        // Fallback
        source = worldIn;
    }
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(source);
        Sponge.getCauseStackManager().addContext(EventContextKeys.LIQUID_BREAK, (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.Break event = SpongeEventFactory.createChangeBlockEventBreak(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) IInteractionObject(net.minecraft.world.IInteractionObject) LocatableBlock(org.spongepowered.api.world.LocatableBlock) WorldProperties(org.spongepowered.api.world.storage.WorldProperties)

Example 85 with BlockSnapshot

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

the class MixinBlockFalling method onIsAreaLoadedCheck.

@Redirect(method = "checkFallable", at = @At(value = "INVOKE", target = WORLD_IS_AREA_LOADED))
private boolean onIsAreaLoadedCheck(World world, BlockPos pos, BlockPos to) {
    if (world.isAreaLoaded(pos, to)) {
        if (!world.isRemote) {
            BlockPos actualPos = pos.add(32, 32, 32);
            EntityType fallingBlock = EntityTypes.FALLING_BLOCK;
            Vector3d position = new Vector3d(actualPos.getX() + 0.5D, actualPos.getY(), actualPos.getZ() + 0.5D);
            BlockSnapshot snapshot = ((org.spongepowered.api.world.World) world).createSnapshot(actualPos.getX(), actualPos.getY(), actualPos.getZ());
            try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
                Sponge.getCauseStackManager().pushCause(snapshot);
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.FALLING_BLOCK);
                Transform<org.spongepowered.api.world.World> worldTransform = new Transform<>((org.spongepowered.api.world.World) world, position);
                ConstructEntityEvent.Pre event = SpongeEventFactory.createConstructEntityEventPre(Sponge.getCauseStackManager().getCurrentCause(), fallingBlock, worldTransform);
                SpongeImpl.postEvent(event);
                return !event.isCancelled();
            }
        }
    }
    return false;
}
Also used : BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) World(net.minecraft.world.World) EntityType(org.spongepowered.api.entity.EntityType) ConstructEntityEvent(org.spongepowered.api.event.entity.ConstructEntityEvent) Vector3d(com.flowpowered.math.vector.Vector3d) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockPos(net.minecraft.util.math.BlockPos) Transform(org.spongepowered.api.entity.Transform) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Aggregations

BlockSnapshot (org.spongepowered.api.block.BlockSnapshot)150 World (org.spongepowered.api.world.World)67 Listener (org.spongepowered.api.event.Listener)66 Location (org.spongepowered.api.world.Location)26 BlockState (org.spongepowered.api.block.BlockState)22 Entity (org.spongepowered.api.entity.Entity)21 BlockPos (net.minecraft.util.math.BlockPos)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)18 BlockType (org.spongepowered.api.block.BlockType)15 Player (org.spongepowered.api.entity.living.player.Player)15 Direction (org.spongepowered.api.util.Direction)15 ChangeBlockEvent (org.spongepowered.api.event.block.ChangeBlockEvent)14 SpongeBlockSnapshot (org.spongepowered.common.block.SpongeBlockSnapshot)14 Vector3d (com.flowpowered.math.vector.Vector3d)13 ArrayList (java.util.ArrayList)13 User (org.spongepowered.api.entity.living.player.User)11 ItemStack (org.spongepowered.api.item.inventory.ItemStack)11