Search in sources :

Example 1 with ChangeResultType

use of me.botsko.prism.api.ChangeResultType 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)

Aggregations

ChangeResultType (me.botsko.prism.api.ChangeResultType)1 PrismProcessType (me.botsko.prism.api.actions.PrismProcessType)1 ChangeResultImpl (me.botsko.prism.appliers.ChangeResultImpl)1 Location (org.bukkit.Location)1 Block (org.bukkit.block.Block)1 BlockFace (org.bukkit.block.BlockFace)1 Jukebox (org.bukkit.block.Jukebox)1 ArmorStand (org.bukkit.entity.ArmorStand)1 Entity (org.bukkit.entity.Entity)1 Item (org.bukkit.entity.Item)1 ItemFrame (org.bukkit.entity.ItemFrame)1 LivingEntity (org.bukkit.entity.LivingEntity)1 Player (org.bukkit.entity.Player)1 EquipmentSlot (org.bukkit.inventory.EquipmentSlot)1 Inventory (org.bukkit.inventory.Inventory)1 InventoryHolder (org.bukkit.inventory.InventoryHolder)1 ItemStack (org.bukkit.inventory.ItemStack)1