Search in sources :

Example 11 with Jukebox

use of org.bukkit.block.Jukebox in project Prism-Bukkit by prism.

the class PrismBlockEvents method logItemRemoveFromDestroyedContainer.

/**
     * If this is a container we need to trigger item removal for everything in
     * it. It's important we record this *after* the block break so the log
     * shows what really happened.
     * 
     * @param player_name
     * @param block
     */
public void logItemRemoveFromDestroyedContainer(String player_name, Block block) {
    if (block.getType().equals(Material.JUKEBOX)) {
        final Jukebox jukebox = (Jukebox) block.getState();
        final Material playing = jukebox.getPlaying();
        if (playing == null || playing.equals(Material.AIR))
            return;
        final ItemStack i = new ItemStack(jukebox.getPlaying(), 1);
        RecordingQueue.addToQueue(ActionFactory.createItemStack("item-remove", i, i.getAmount(), 0, null, block.getLocation(), player_name));
        return;
    }
    if (block.getState() instanceof InventoryHolder) {
        final InventoryHolder container = (InventoryHolder) block.getState();
        int slot = 0;
        for (final ItemStack i : container.getInventory().getContents()) {
            // even though only half of the chest breaks.
            if ((block.getType().equals(Material.CHEST) || block.getType().equals(Material.TRAPPED_CHEST)) && slot > 26)
                break;
            // record item
            if (i != null) {
                RecordingQueue.addToQueue(ActionFactory.createItemStack("item-remove", i, i.getAmount(), slot, null, block.getLocation(), player_name));
            }
            slot++;
        }
    }
}
Also used : Jukebox(org.bukkit.block.Jukebox) Material(org.bukkit.Material) ItemStack(org.bukkit.inventory.ItemStack) InventoryHolder(org.bukkit.inventory.InventoryHolder)

Example 12 with Jukebox

use of org.bukkit.block.Jukebox in project Prism-Bukkit by prism.

the class ItemStackAction method placeItems.

protected ChangeResult placeItems(Player player, PrismParameters parameters, boolean isPreview) {
    if (actionData == null) {
        return new ChangeResultImpl(ChangeResultType.SKIPPED, null);
    }
    ChangeResultType result = ChangeResultType.SKIPPED;
    if (isPreview) {
        return new ChangeResultImpl(ChangeResultType.PLANNED, null);
    }
    if (Prism.config.getBoolean("prism.appliers.allow-rollback-items-removed-from-container")) {
        final Block block = getWorld().getBlockAt(getLoc());
        Inventory inventory = null;
        // Item drop/pickup from player inventories
        if (getActionType().getName().equals("item-drop") || getActionType().getName().equals("item-pickup")) {
            // Is player online?
            final Player onlinePlayer = Bukkit.getServer().getPlayer(getUuid());
            if (onlinePlayer != null) {
                inventory = onlinePlayer.getInventory();
            } else {
                // Skip if the player isn't online
                Prism.debug("Skipping inventory process because player is offline");
                return new ChangeResultImpl(ChangeResultType.SKIPPED, null);
            }
        } else {
            if (block.getType().equals(Material.JUKEBOX)) {
                final Jukebox jukebox = (Jukebox) block.getState();
                jukebox.setPlaying(item.getType());
                jukebox.update();
            } else if (block.getState() instanceof InventoryHolder) {
                final InventoryHolder ih = (InventoryHolder) block.getState();
                inventory = ih.getInventory();
            } else {
                String slot = getActionData().slot.toUpperCase(Locale.ENGLISH);
                EquipmentSlot eSlot = null;
                // Prism.log("Slot found: " + slot);
                try {
                    eSlot = EquipmentSlot.valueOf(slot);
                } catch (IllegalArgumentException ignored) {
                // ignored
                }
                // Prism.log("   eSlot: " + eSlot);
                BlockFace fSlot = null;
                try {
                    fSlot = BlockFace.valueOf(slot);
                } catch (IllegalArgumentException ignored) {
                // ignored
                }
                // Prism.log("   fSlot: " + fSlot);
                Entity[] foundEntities = block.getChunk().getEntities();
                for (Entity e : foundEntities) {
                    // Get the block location for better comparisons
                    Location loc = e.getLocation();
                    loc.setX(loc.getBlockX());
                    loc.setY(loc.getBlockY());
                    loc.setZ(loc.getBlockZ());
                    Prism.debug(block.getLocation());
                    Prism.debug(loc);
                    if (!block.getWorld().equals(e.getWorld())) {
                        continue;
                    }
                    if (block.getLocation().distanceSquared(loc) < 0.25) {
                        if (e instanceof ItemFrame) {
                            final ItemFrame frame = (ItemFrame) e;
                            // if we have a pseudo-slot try to use that
                            if (fSlot != null && fSlot != frame.getAttachedFace()) {
                                // Prism.log("Skipping frame: " + frame.getFacing());
                                continue;
                            }
                            if ((getActionType().getName().equals("item-remove") && parameters.getProcessType().equals(PrismProcessType.ROLLBACK)) || (getActionType().getName().equals("item-insert") && parameters.getProcessType().equals(PrismProcessType.RESTORE))) {
                                if (frame.getItem().getType() == Material.AIR) {
                                    frame.setItem(item);
                                    result = ChangeResultType.APPLIED;
                                    break;
                                }
                            } else if (frame.getItem().getType() != Material.AIR) {
                                frame.setItem(null);
                                result = ChangeResultType.APPLIED;
                                break;
                            }
                        } else if (e instanceof ArmorStand) {
                            final LivingEntity stand = (ArmorStand) e;
                            EquipmentSlot actualSlot = eSlot;
                            if (actualSlot == null) {
                                actualSlot = InventoryUtils.getTargetArmorSlot(item.getType());
                            }
                            ItemStack atPoint = InventoryUtils.getEquipment(stand.getEquipment(), eSlot);
                            if ((getActionType().getName().equals("item-remove") && parameters.getProcessType().equals(PrismProcessType.ROLLBACK)) || (getActionType().getName().equals("item-insert") && parameters.getProcessType().equals(PrismProcessType.RESTORE))) {
                                if (atPoint.getType() == Material.AIR) {
                                    InventoryUtils.setEquipment(stand.getEquipment(), actualSlot, item);
                                    result = ChangeResultType.APPLIED;
                                    break;
                                }
                            } else if (atPoint.getType() != Material.AIR) {
                                InventoryUtils.setEquipment(stand.getEquipment(), actualSlot, null);
                                result = ChangeResultType.APPLIED;
                                break;
                            }
                        }
                    }
                }
            }
        }
        if (inventory != null) {
            final PrismProcessType pt = parameters.getProcessType();
            final String n = getActionType().getName();
            int iSlot = -1;
            try {
                iSlot = Integer.parseInt(getActionData().slot);
            } catch (IllegalArgumentException ignored) {
            // ignored
            }
            // inventory
            if ((pt.equals(PrismProcessType.ROLLBACK) && (n.equals("item-remove") || n.equals("item-drop"))) || (pt.equals(PrismProcessType.RESTORE) && (n.equals("item-insert") || n.equals("item-pickup")))) {
                boolean added = false;
                // We'll attempt to put it back in the same slot
                if (iSlot >= 0) {
                    // https://snowy-evening.com/botsko/prism/450/
                    if (iSlot < inventory.getSize()) {
                        final ItemStack currentSlotItem = inventory.getItem(iSlot);
                        int amount = 0;
                        ItemStack item = getItem().clone();
                        int max = item.getType().getMaxStackSize();
                        if (currentSlotItem == null || currentSlotItem.getType() == Material.AIR) {
                            amount = item.getAmount();
                        } else if (currentSlotItem.isSimilar(item)) {
                            amount = Math.min(currentSlotItem.getAmount() + item.getAmount(), max);
                        }
                        if (amount > 0) {
                            result = ChangeResultType.APPLIED;
                            item.setAmount(amount);
                            added = true;
                            inventory.setItem(iSlot, item);
                        }
                    }
                }
                // If that failed we'll attempt to put it anywhere
                if (!added) {
                    // TODO: Skip is actually "partially applied"
                    final HashMap<Integer, ItemStack> leftovers = InventoryUtils.addItemToInventory(inventory, getItem());
                    if (leftovers.size() > 0) {
                        Prism.debug("Skipping adding items because there are leftovers");
                        result = ChangeResultType.SKIPPED;
                    } else {
                        result = ChangeResultType.APPLIED;
                        added = true;
                    }
                }
                // Item was added to the inv, we need to remove the entity
                if (added && (n.equals("item-drop") || n.equals("item-pickup"))) {
                    final Entity[] entities = getLoc().getChunk().getEntities();
                    for (final Entity entity : entities) {
                        if (entity instanceof Item) {
                            final ItemStack stack = ((Item) entity).getItemStack();
                            if (stack.isSimilar(getItem())) {
                                // Remove the event's number of items from
                                // the stack
                                stack.setAmount(stack.getAmount() - getItem().getAmount());
                                if (stack.getAmount() == 0) {
                                    entity.remove();
                                }
                                break;
                            }
                        }
                    }
                }
            }
            // inventory
            if ((pt.equals(PrismProcessType.ROLLBACK) && (n.equals("item-insert") || n.equals("item-pickup"))) || (pt.equals(PrismProcessType.RESTORE) && (n.equals("item-remove") || n.equals("item-drop")))) {
                // does inventory have item?
                boolean removed = false;
                // We'll attempt to take it from the same slot
                if (iSlot >= 0) {
                    if (iSlot >= inventory.getContents().length) {
                        inventory.addItem(getItem());
                    } else {
                        final ItemStack currentSlotItem = inventory.getItem(iSlot);
                        ItemStack item = getItem().clone();
                        if (item.isSimilar(currentSlotItem)) {
                            int amount = 0;
                            if (currentSlotItem != null) {
                                amount = Math.max(currentSlotItem.getAmount() - item.getAmount(), 0);
                            }
                            item.setAmount(amount);
                            result = ChangeResultType.APPLIED;
                            removed = true;
                            inventory.setItem(iSlot, amount > 0 ? item : null);
                        }
                    }
                }
                if (removed && (n.equals("item-drop") || n.equals("item-pickup"))) {
                    ItemUtils.dropItem(getLoc(), getItem());
                }
            }
        }
    }
    return new ChangeResultImpl(result, null);
}
Also used : Jukebox(org.bukkit.block.Jukebox) Entity(org.bukkit.entity.Entity) LivingEntity(org.bukkit.entity.LivingEntity) Player(org.bukkit.entity.Player) BlockFace(org.bukkit.block.BlockFace) EquipmentSlot(org.bukkit.inventory.EquipmentSlot) ItemFrame(org.bukkit.entity.ItemFrame) LivingEntity(org.bukkit.entity.LivingEntity) ChangeResultType(me.botsko.prism.api.ChangeResultType) Item(org.bukkit.entity.Item) ArmorStand(org.bukkit.entity.ArmorStand) PrismProcessType(me.botsko.prism.api.actions.PrismProcessType) Block(org.bukkit.block.Block) ChangeResultImpl(me.botsko.prism.appliers.ChangeResultImpl) ItemStack(org.bukkit.inventory.ItemStack) InventoryHolder(org.bukkit.inventory.InventoryHolder) Inventory(org.bukkit.inventory.Inventory) Location(org.bukkit.Location)

Example 13 with Jukebox

use of org.bukkit.block.Jukebox in project Prism-Bukkit by prism.

the class PrismBlockEvents method forEachItem.

/**
 * Process over each item.
 * @param block Block
 * @param callback callback that consumes items/integer pairs.
 */
void forEachItem(Block block, BiConsumer<ItemStack, Integer> callback) {
    if (block.getType().equals(Material.JUKEBOX)) {
        final Jukebox jukebox = (Jukebox) block.getState();
        final Material playing = jukebox.getPlaying();
        if (playing.equals(Material.AIR)) {
            return;
        }
        final ItemStack i = new ItemStack(jukebox.getPlaying(), 1);
        callback.accept(i, 0);
        return;
    }
    if (block.getState() instanceof InventoryHolder) {
        InventoryHolder container = (InventoryHolder) block.getState();
        if (container instanceof DoubleChest) {
            if (((Chest) block.getBlockData()).getType() == Type.LEFT) {
                container = ((DoubleChest) container).getLeftSide();
            } else {
                container = ((DoubleChest) container).getRightSide();
            }
        }
        int slot = 0;
        if (container != null) {
            for (final ItemStack i : container.getInventory().getContents()) {
                // even though only half of the chest breaks.
                if ((block.getType().equals(Material.CHEST) || block.getType().equals(Material.TRAPPED_CHEST)) && slot > 26) {
                    break;
                }
                // record item
                if (i != null) {
                    callback.accept(i, slot);
                }
                slot++;
            }
        }
    }
}
Also used : Jukebox(org.bukkit.block.Jukebox) Material(org.bukkit.Material) ItemStack(org.bukkit.inventory.ItemStack) DoubleChest(org.bukkit.block.DoubleChest) InventoryHolder(org.bukkit.inventory.InventoryHolder)

Example 14 with Jukebox

use of org.bukkit.block.Jukebox in project MagicPlugin by elBukkit.

the class CompatibilityUtils method clearItems.

@Override
public void clearItems(Location location) {
    if (location == null)
        return;
    // Block-specific behaviors
    Block block = location.getBlock();
    BlockState blockState = block.getState();
    if (blockState instanceof Lootable) {
        Lootable lootable = (Lootable) blockState;
        lootable.setLootTable(null);
        blockState.update();
    }
    if (blockState instanceof Lectern) {
        Lectern lectern = (Lectern) blockState;
        lectern.getInventory().setItem(0, new ItemStack(Material.AIR));
        blockState.update();
    }
    if (blockState instanceof Jukebox) {
        ((Jukebox) blockState).setRecord(null);
        blockState.update();
    }
    // TODO: Just clear inventory instead?
    BlockEntity tileEntity = getTileEntity(location);
    if (tileEntity == null)
        return;
    CompoundTag tag = new CompoundTag();
    tileEntity.save(tag);
    // Is there really not an enum for these NBT types?
    ListTag itemList = tag.getList("Items", CompatibilityConstants.NBT_TYPE_COMPOUND);
    // Is it really necessary to clear the list before removing it?
    if (itemList != null) {
        itemList.clear();
        tag.remove("Items");
        tileEntity.load(tag);
        tileEntity.setChanged();
    }
}
Also used : Jukebox(org.bukkit.block.Jukebox) BlockState(org.bukkit.block.BlockState) Lootable(org.bukkit.loot.Lootable) FallingBlock(org.bukkit.entity.FallingBlock) CraftBlock(org.bukkit.craftbukkit.v1_17_R1.block.CraftBlock) Block(org.bukkit.block.Block) Lectern(org.bukkit.block.Lectern) ItemStack(org.bukkit.inventory.ItemStack) ListTag(net.minecraft.nbt.ListTag) CompoundTag(net.minecraft.nbt.CompoundTag) BlockEntity(net.minecraft.world.level.block.entity.BlockEntity) FallingBlockEntity(net.minecraft.world.entity.item.FallingBlockEntity) SignBlockEntity(net.minecraft.world.level.block.entity.SignBlockEntity)

Example 15 with Jukebox

use of org.bukkit.block.Jukebox in project MagicPlugin by elBukkit.

the class CompatibilityUtils method clearItems.

@Override
public void clearItems(Location location) {
    if (location == null)
        return;
    // Block-specific behaviors
    Block block = location.getBlock();
    BlockState blockState = block.getState();
    if (blockState instanceof Lootable) {
        Lootable lootable = (Lootable) blockState;
        lootable.setLootTable(null);
        blockState.update();
    }
    if (blockState instanceof Lectern) {
        Lectern lectern = (Lectern) blockState;
        lectern.getInventory().setItem(0, new ItemStack(Material.AIR));
        blockState.update();
    }
    if (blockState instanceof Jukebox) {
        ((Jukebox) blockState).setRecord(null);
        blockState.update();
    }
    // TODO: Just clear inventory instead?
    BlockEntity tileEntity = getTileEntity(location);
    if (tileEntity == null)
        return;
    CompoundTag tag = tileEntity.saveWithFullMetadata();
    // Is there really not an enum for these NBT types?
    ListTag itemList = tag.getList("Items", CompatibilityConstants.NBT_TYPE_COMPOUND);
    // Is it really necessary to clear the list before removing it?
    if (itemList != null) {
        itemList.clear();
        tag.remove("Items");
        tileEntity.load(tag);
        tileEntity.setChanged();
    }
}
Also used : Jukebox(org.bukkit.block.Jukebox) BlockState(org.bukkit.block.BlockState) Lootable(org.bukkit.loot.Lootable) FallingBlock(org.bukkit.entity.FallingBlock) CraftBlock(org.bukkit.craftbukkit.v1_18_R1.block.CraftBlock) Block(org.bukkit.block.Block) Lectern(org.bukkit.block.Lectern) ItemStack(org.bukkit.inventory.ItemStack) ListTag(net.minecraft.nbt.ListTag) CompoundTag(net.minecraft.nbt.CompoundTag) BlockEntity(net.minecraft.world.level.block.entity.BlockEntity) FallingBlockEntity(net.minecraft.world.entity.item.FallingBlockEntity) SignBlockEntity(net.minecraft.world.level.block.entity.SignBlockEntity)

Aggregations

Jukebox (org.bukkit.block.Jukebox)22 ItemStack (org.bukkit.inventory.ItemStack)13 Block (org.bukkit.block.Block)12 BlockState (org.bukkit.block.BlockState)10 InventoryHolder (org.bukkit.inventory.InventoryHolder)8 Location (org.bukkit.Location)6 CompoundTag (net.minecraft.nbt.CompoundTag)5 ListTag (net.minecraft.nbt.ListTag)5 FallingBlockEntity (net.minecraft.world.entity.item.FallingBlockEntity)5 BlockEntity (net.minecraft.world.level.block.entity.BlockEntity)5 SignBlockEntity (net.minecraft.world.level.block.entity.SignBlockEntity)5 Lectern (org.bukkit.block.Lectern)5 FallingBlock (org.bukkit.entity.FallingBlock)5 Lootable (org.bukkit.loot.Lootable)5 Sign (org.bukkit.block.Sign)4 Material (org.bukkit.Material)3 NoteBlock (org.bukkit.block.NoteBlock)3 EventHandler (org.bukkit.event.EventHandler)3 Banner (org.bukkit.block.Banner)2 BlockFace (org.bukkit.block.BlockFace)2