Search in sources :

Example 26 with ScriptTag

use of com.denizenscript.denizencore.objects.core.ScriptTag in project Denizen-For-Bukkit by DenizenScript.

the class InventoryTag method registerTags.

public static void registerTags() {
    AbstractFlagTracker.registerFlagHandlers(tagProcessor);
    PropertyParser.registerPropertyTagHandlers(InventoryTag.class, tagProcessor);
    // <--[tag]
    // @attribute <InventoryTag.empty_slots>
    // @returns ElementTag(Number)
    // @description
    // Returns the number of empty slots in an inventory.
    // -->
    tagProcessor.registerTag(ElementTag.class, "empty_slots", (attribute, object) -> {
        InventoryTag dummyInv;
        if (object.inventory.getType() == InventoryType.PLAYER) {
            ItemStack[] contents = object.getStorageContents();
            dummyInv = new InventoryTag(contents.length);
            if (contents.length != dummyInv.getSize()) {
                contents = Arrays.copyOf(contents, dummyInv.getSize());
            }
            dummyInv.setContents(contents);
        } else {
            dummyInv = object;
        }
        int full = dummyInv.count(null, true);
        return new ElementTag(dummyInv.getSize() - full);
    });
    // <--[tag]
    // @attribute <InventoryTag.can_fit[<item>|...]>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the inventory can fit an item.
    // -->
    tagProcessor.registerTag(ElementTag.class, "can_fit", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        List<ItemTag> items = attribute.paramAsType(ListTag.class).filter(ItemTag.class, attribute.context, !attribute.hasAlternative());
        if (items == null || items.isEmpty()) {
            return null;
        }
        InventoryType type = object.inventory.getType();
        InventoryTag dummyInv = new InventoryTag(type == InventoryType.PLAYER ? InventoryType.CHEST : type, AdvancedTextImpl.instance.getTitle(object.inventory));
        ItemStack[] contents = object.getStorageContents();
        if (dummyInv.getInventoryType() == InventoryType.CHEST) {
            dummyInv.setSize(contents.length);
        }
        if (contents.length != dummyInv.getSize()) {
            contents = Arrays.copyOf(contents, dummyInv.getSize());
        }
        dummyInv.setContents(contents);
        // -->
        if (attribute.startsWith("count", 2)) {
            ItemStack toAdd = items.get(0).getItemStack().clone();
            // Technically nothing stops us from ridiculous numbers in an ItemStack amount.
            int totalCount = 64 * 64 * 4;
            toAdd.setAmount(totalCount);
            List<ItemStack> leftovers = dummyInv.addWithLeftovers(0, true, toAdd);
            int result = 0;
            if (leftovers.size() > 0) {
                result += leftovers.get(0).getAmount();
            }
            attribute.fulfill(1);
            return new ElementTag(totalCount - result);
        }
        // -->
        if ((attribute.startsWith("quantity", 2) || attribute.startsWith("qty", 2)) && attribute.hasContext(2)) {
            if (attribute.startsWith("qty", 2)) {
                Deprecations.qtyTags.warn(attribute.context);
            }
            int qty = attribute.getIntContext(2);
            ItemTag itemZero = new ItemTag(items.get(0).getItemStack().clone());
            itemZero.setAmount(qty);
            items.set(0, itemZero);
            attribute.fulfill(1);
        }
        // NOTE: Could just also convert items to an array and pass it all in at once...
        for (ItemTag itm : items) {
            List<ItemStack> leftovers = dummyInv.addWithLeftovers(0, true, itm.getItemStack().clone());
            if (!leftovers.isEmpty()) {
                return new ElementTag(false);
            }
        }
        return new ElementTag(true);
    });
    // <--[tag]
    // @attribute <InventoryTag.include[<item>|...]>
    // @returns InventoryTag
    // @description
    // Returns a copy of the InventoryTag with items added.
    // -->
    tagProcessor.registerTag(InventoryTag.class, "include", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        List<ItemTag> items = ListTag.getListFor(attribute.getParamObject(), attribute.context).filter(ItemTag.class, attribute.context);
        InventoryTag dummyInv = new InventoryTag(object.inventory.getType(), AdvancedTextImpl.instance.getTitle(object.inventory));
        if (object.inventory.getType() == InventoryType.CHEST) {
            dummyInv.setSize(object.inventory.getSize());
        }
        dummyInv.setContents(object.getContents());
        if (object.idHolder instanceof ScriptTag) {
            dummyInv.idType = "script";
            dummyInv.idHolder = object.idHolder;
        }
        trackTemporaryInventory(dummyInv);
        // -->
        if ((attribute.startsWith("quantity", 2) || attribute.startsWith("qty", 2)) && attribute.hasContext(2)) {
            if (attribute.startsWith("qty", 2)) {
                Deprecations.qtyTags.warn(attribute.context);
            }
            int qty = attribute.getIntContext(2);
            ItemTag itemZero = new ItemTag(items.get(0).getItemStack().clone());
            itemZero.setAmount(qty);
            items.set(0, itemZero);
            attribute.fulfill(1);
        }
        for (ItemTag item : items) {
            dummyInv.add(0, item.getItemStack().clone());
        }
        return dummyInv;
    });
    // <--[tag]
    // @attribute <InventoryTag.exclude_item[<item_matcher>]>
    // @returns InventoryTag
    // @description
    // Returns a copy of the InventoryTag with all matching items excluded.
    // -->
    tagProcessor.registerTag(InventoryTag.class, "exclude_item", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        String matcher = attribute.getParam();
        InventoryTag dummyInv = new InventoryTag(object.inventory.getType(), AdvancedTextImpl.instance.getTitle(object.inventory));
        if (object.inventory.getType() == InventoryType.CHEST) {
            dummyInv.setSize(object.inventory.getSize());
        }
        dummyInv.setContents(object.getContents());
        if (object.idHolder instanceof ScriptTag) {
            dummyInv.idType = "script";
            dummyInv.idHolder = object.idHolder;
        }
        trackTemporaryInventory(dummyInv);
        int quantity = Integer.MAX_VALUE;
        // -->
        if (attribute.startsWith("quantity", 2) && attribute.hasContext(2)) {
            quantity = attribute.getIntContext(2);
            attribute.fulfill(1);
        }
        for (int slot = 0; slot < dummyInv.inventory.getSize(); slot++) {
            ItemStack item = dummyInv.inventory.getItem(slot);
            if (item != null && BukkitScriptEvent.tryItem(new ItemTag(item), matcher)) {
                quantity -= item.getAmount();
                if (quantity >= 0) {
                    dummyInv.inventory.setItem(slot, null);
                } else {
                    item = item.clone();
                    item.setAmount(-quantity);
                    dummyInv.inventory.setItem(slot, item);
                }
                if (quantity <= 0) {
                    break;
                }
            }
        }
        return dummyInv;
    });
    tagProcessor.registerTag(InventoryTag.class, "exclude", (attribute, object) -> {
        Deprecations.inventoryNonMatcherTags.warn(attribute.context);
        if (!attribute.hasParam()) {
            return null;
        }
        List<ItemTag> items = ListTag.getListFor(attribute.getParamObject(), attribute.context).filter(ItemTag.class, attribute.context);
        InventoryTag dummyInv = new InventoryTag(object.inventory.getType(), AdvancedTextImpl.instance.getTitle(object.inventory));
        if (object.inventory.getType() == InventoryType.CHEST) {
            dummyInv.setSize(object.inventory.getSize());
        }
        dummyInv.setContents(object.getContents());
        if (object.idHolder instanceof ScriptTag) {
            dummyInv.idType = "script";
            dummyInv.idHolder = object.idHolder;
        }
        trackTemporaryInventory(dummyInv);
        if ((attribute.startsWith("quantity", 2) || attribute.startsWith("qty", 2)) && attribute.hasContext(2)) {
            if (attribute.startsWith("qty", 2)) {
                Deprecations.qtyTags.warn(attribute.context);
            }
            int qty = attribute.getIntContext(2);
            ItemTag itemZero = new ItemTag(items.get(0).getItemStack().clone());
            itemZero.setAmount(qty);
            items.set(0, itemZero);
            attribute.fulfill(1);
        }
        for (ItemTag item : items) {
            dummyInv.inventory.removeItem(item.getItemStack().clone());
        }
        return dummyInv;
    });
    // <--[tag]
    // @attribute <InventoryTag.is_empty>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the inventory is empty.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_empty", (attribute, object) -> {
        boolean empty = true;
        for (ItemStack item : object.getStorageContents()) {
            if (item != null && item.getType() != Material.AIR) {
                empty = false;
                break;
            }
        }
        return new ElementTag(empty);
    });
    // <--[tag]
    // @attribute <InventoryTag.is_full>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the inventory is completely full.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_full", (attribute, object) -> {
        boolean full = true;
        for (ItemStack item : object.getStorageContents()) {
            if ((item == null) || (item.getType() == Material.AIR) || (item.getAmount() < item.getMaxStackSize())) {
                full = false;
                break;
            }
        }
        return new ElementTag(full);
    });
    // <--[tag]
    // @attribute <InventoryTag.contains_item[<matcher>]>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the inventory contains any item that matches the specified item matcher.
    // Uses the system behind <@link language Advanced Script Event Matching>.
    // -->
    tagProcessor.registerTag(ElementTag.class, "contains_item", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        int qty = 1;
        String matcher = attribute.getParam();
        // -->
        if (attribute.startsWith("quantity", 2) && attribute.hasContext(2)) {
            qty = attribute.getIntContext(2);
            attribute.fulfill(1);
        }
        int found_items = 0;
        for (ItemStack item : object.getContents()) {
            if (item != null) {
                if (BukkitScriptEvent.tryItem(new ItemTag(item), matcher)) {
                    found_items += item.getAmount();
                    if (found_items >= qty) {
                        break;
                    }
                }
            }
        }
        return new ElementTag(found_items >= qty);
    });
    tagProcessor.registerTag(ElementTag.class, "contains", (attribute, object) -> {
        // -->
        if (attribute.startsWith("display", 2)) {
            if (!attribute.hasContext(2)) {
                return null;
            }
            String search_string = attribute.getContext(2);
            boolean strict = false;
            if (CoreUtilities.toLowerCase(search_string).startsWith("strict:") && search_string.length() > 7) {
                strict = true;
                search_string = search_string.substring(7);
            }
            if (search_string.length() == 0) {
                return null;
            }
            int qty = 1;
            // -->
            if ((attribute.startsWith("quantity", 3) || attribute.startsWith("qty", 3)) && attribute.hasContext(3)) {
                if (attribute.startsWith("qty", 3)) {
                    Deprecations.qtyTags.warn(attribute.context);
                }
                qty = attribute.getIntContext(3);
                attribute.fulfill(1);
            }
            int found_items = 0;
            if (strict) {
                for (ItemStack item : object.getContents()) {
                    if (item == null || !item.hasItemMeta()) {
                        continue;
                    }
                    ItemMeta meta = item.getItemMeta();
                    if (item.getType() == Material.WRITTEN_BOOK && ((BookMeta) meta).getTitle().equalsIgnoreCase(search_string)) {
                        found_items += item.getAmount();
                        if (found_items >= qty) {
                            break;
                        }
                    } else if (meta.hasDisplayName() && meta.getDisplayName().equalsIgnoreCase(search_string)) {
                        found_items += item.getAmount();
                        if (found_items >= qty) {
                            break;
                        }
                    }
                }
            } else {
                for (ItemStack item : object.getContents()) {
                    if (item == null || !item.hasItemMeta()) {
                        continue;
                    }
                    ItemMeta meta = item.getItemMeta();
                    if (item.getType() == Material.WRITTEN_BOOK && CoreUtilities.toLowerCase(((BookMeta) meta).getTitle()).contains(CoreUtilities.toLowerCase(search_string))) {
                        found_items += item.getAmount();
                        if (found_items >= qty) {
                            break;
                        }
                    } else if (meta.hasDisplayName() && CoreUtilities.toLowerCase(meta.getDisplayName()).contains(CoreUtilities.toLowerCase(search_string))) {
                        found_items += item.getAmount();
                        if (found_items >= qty) {
                            break;
                        }
                    }
                }
            }
            attribute.fulfill(1);
            return new ElementTag(found_items >= qty);
        }
        // -->
        if (attribute.startsWith("lore", 2)) {
            if (!attribute.hasContext(2)) {
                return null;
            }
            String search_string = attribute.getContext(2);
            boolean strict = false;
            if (CoreUtilities.toLowerCase(search_string).startsWith("strict:")) {
                strict = true;
                search_string = search_string.substring("strict:".length());
            }
            if (search_string.length() == 0) {
                return null;
            }
            ListTag lore = ListTag.valueOf(search_string, attribute.context);
            int qty = 1;
            // -->
            if ((attribute.startsWith("quantity", 3) || attribute.startsWith("qty", 3)) && attribute.hasContext(3)) {
                if (attribute.startsWith("qty", 3)) {
                    Deprecations.qtyTags.warn(attribute.context);
                }
                qty = attribute.getIntContext(3);
                attribute.fulfill(1);
            }
            int found_items = 0;
            if (strict) {
                strict_items: for (ItemStack item : object.getContents()) {
                    if (item == null || !item.hasItemMeta()) {
                        continue;
                    }
                    ItemMeta meta = item.getItemMeta();
                    if (meta.hasLore()) {
                        List<String> item_lore = meta.getLore();
                        if (lore.size() != item_lore.size()) {
                            continue;
                        }
                        for (int i = 0; i < item_lore.size(); i++) {
                            if (!lore.get(i).equalsIgnoreCase(item_lore.get(i))) {
                                continue strict_items;
                            }
                        }
                        found_items += item.getAmount();
                        if (found_items >= qty) {
                            break;
                        }
                    }
                }
            } else {
                for (ItemStack item : object.getContents()) {
                    if (item == null || !item.hasItemMeta()) {
                        continue;
                    }
                    ItemMeta meta = item.getItemMeta();
                    if (meta.hasLore()) {
                        List<String> item_lore = meta.getLore();
                        int loreCount = 0;
                        lines: for (String line : lore) {
                            for (String item_line : item_lore) {
                                if (CoreUtilities.toLowerCase(item_line).contains(CoreUtilities.toLowerCase(line))) {
                                    loreCount++;
                                    continue lines;
                                }
                            }
                        }
                        if (loreCount == lore.size()) {
                            found_items += item.getAmount();
                            if (found_items >= qty) {
                                break;
                            }
                        }
                    }
                }
            }
            attribute.fulfill(1);
            return new ElementTag(found_items >= qty);
        }
        if (attribute.startsWith("scriptname", 2)) {
            Deprecations.inventoryNonMatcherTags.warn(attribute.context);
            if (!attribute.hasContext(2)) {
                return null;
            }
            ListTag scrNameList = attribute.contextAsType(2, ListTag.class);
            HashSet<String> scrNames = new HashSet<>();
            for (String name : scrNameList) {
                scrNames.add(CoreUtilities.toLowerCase(name));
            }
            int qty = 1;
            if ((attribute.startsWith("quantity", 3) || attribute.startsWith("qty", 3)) && attribute.hasContext(3)) {
                if (attribute.startsWith("qty", 3)) {
                    Deprecations.qtyTags.warn(attribute.context);
                }
                qty = attribute.getIntContext(3);
                attribute.fulfill(1);
            }
            int found_items = 0;
            for (ItemStack item : object.getContents()) {
                if (item != null) {
                    String itemName = new ItemTag(item).getScriptName();
                    if (itemName != null && scrNames.contains(CoreUtilities.toLowerCase(itemName))) {
                        found_items += item.getAmount();
                        if (found_items >= qty) {
                            break;
                        }
                    }
                }
            }
            attribute.fulfill(1);
            return new ElementTag(found_items >= qty);
        }
        if (attribute.startsWith("flagged", 2)) {
            Deprecations.inventoryNonMatcherTags.warn(attribute.context);
            if (!attribute.hasContext(2)) {
                return null;
            }
            ListTag scrNameList = attribute.contextAsType(2, ListTag.class);
            String[] flags = scrNameList.toArray(new String[0]);
            int qty = 1;
            if (attribute.startsWith("quantity", 3) && attribute.hasContext(3)) {
                qty = attribute.getIntContext(3);
                attribute.fulfill(1);
            }
            int found_items = 0;
            for (ItemStack item : object.getContents()) {
                if (item != null) {
                    ItemTag itemTag = new ItemTag(item);
                    for (String flag : flags) {
                        if (itemTag.getFlagTracker().hasFlag(flag)) {
                            found_items += item.getAmount();
                            break;
                        }
                    }
                    if (found_items >= qty) {
                        break;
                    }
                }
            }
            attribute.fulfill(1);
            return new ElementTag(found_items >= qty);
        }
        if (attribute.startsWith("nbt", 2)) {
            Deprecations.itemNbt.warn(attribute.context);
            if (!attribute.hasContext(2)) {
                return null;
            }
            String keyName = attribute.getContext(2);
            int qty = 1;
            if ((attribute.startsWith("quantity", 3) || attribute.startsWith("qty", 3)) && attribute.hasContext(3)) {
                if (attribute.startsWith("qty", 3)) {
                    Deprecations.qtyTags.warn(attribute.context);
                }
                qty = attribute.getIntContext(3);
                attribute.fulfill(1);
            }
            int found_items = 0;
            for (ItemStack item : object.getContents()) {
                if (CustomNBT.hasCustomNBT(item, keyName, CustomNBT.KEY_DENIZEN)) {
                    found_items += item.getAmount();
                    if (found_items >= qty) {
                        break;
                    }
                }
            }
            attribute.fulfill(1);
            return new ElementTag(found_items >= qty);
        }
        if (attribute.startsWith("material", 2)) {
            Deprecations.inventoryNonMatcherTags.warn(attribute.context);
            if (!attribute.hasContext(2)) {
                return null;
            }
            List<MaterialTag> materials = attribute.contextAsType(2, ListTag.class).filter(MaterialTag.class, attribute.context);
            int qty = 1;
            if ((attribute.startsWith("quantity", 3) || attribute.startsWith("qty", 3)) && attribute.hasContext(3)) {
                if (attribute.startsWith("qty", 3)) {
                    Deprecations.qtyTags.warn(attribute.context);
                }
                qty = attribute.getIntContext(3);
                attribute.fulfill(1);
            }
            int found_items = 0;
            mainLoop: for (ItemStack item : object.getContents()) {
                if (item == null) {
                    continue;
                }
                for (MaterialTag material : materials) {
                    if (item.getType() == material.getMaterial() && !(new ItemTag(item).isItemscript())) {
                        found_items += item.getAmount();
                        if (found_items >= qty) {
                            break mainLoop;
                        }
                    }
                }
            }
            attribute.fulfill(1);
            return new ElementTag(found_items >= qty);
        }
        if (!attribute.hasParam()) {
            return null;
        }
        ListTag list = attribute.paramAsType(ListTag.class);
        if (list.isEmpty()) {
            return null;
        }
        int qty = 1;
        Deprecations.inventoryNonMatcherTags.warn(attribute.context);
        if ((attribute.startsWith("quantity", 2) || attribute.startsWith("qty", 2)) && attribute.hasContext(2)) {
            if (attribute.startsWith("qty", 2)) {
                Deprecations.qtyTags.warn(attribute.context);
            }
            qty = attribute.getIntContext(2);
            attribute.fulfill(1);
        }
        List<ItemTag> contains = list.filter(ItemTag.class, attribute.context, !attribute.hasAlternative());
        if (contains.size() == list.size()) {
            for (ItemTag item : contains) {
                if (!object.containsItem(item, qty)) {
                    return new ElementTag(false);
                }
            }
            return new ElementTag(true);
        }
        return new ElementTag(false);
    });
    tagProcessor.registerTag(ElementTag.class, "contains_any", (attribute, object) -> {
        Deprecations.inventoryNonMatcherTags.warn(attribute.context);
        if (!attribute.hasParam()) {
            return null;
        }
        ListTag list = attribute.paramAsType(ListTag.class);
        if (list.isEmpty()) {
            return null;
        }
        int qty = 1;
        if ((attribute.startsWith("quantity", 2) || attribute.startsWith("qty", 2)) && attribute.hasContext(2)) {
            if (attribute.startsWith("qty", 2)) {
                Deprecations.qtyTags.warn(attribute.context);
            }
            qty = attribute.getIntContext(2);
            attribute.fulfill(1);
        }
        List<ItemTag> contains = list.filter(ItemTag.class, attribute.context, !attribute.hasAlternative());
        if (!contains.isEmpty()) {
            for (ItemTag item : contains) {
                if (object.containsItem(item, qty)) {
                    return new ElementTag(true);
                }
            }
        }
        return new ElementTag(false);
    });
    // <--[tag]
    // @attribute <InventoryTag.first_empty>
    // @returns ElementTag(Number)
    // @description
    // Returns the location of the first empty slot.
    // Returns -1 if the inventory is full.
    // -->
    tagProcessor.registerTag(ElementTag.class, "first_empty", (attribute, object) -> {
        int val = object.firstEmpty(0);
        return new ElementTag(val >= 0 ? (val + 1) : -1);
    });
    // <--[tag]
    // @attribute <InventoryTag.find_item[<matcher>]>
    // @returns ElementTag(Number)
    // @description
    // Returns the location of the first slot that contains an item that matches the given item matcher.
    // Returns -1 if there's no match.
    // Uses the system behind <@link language Advanced Script Event Matching>.
    // -->
    tagProcessor.registerTag(ElementTag.class, "find_item", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        String matcher = attribute.getParam();
        for (int i = 0; i < object.inventory.getSize(); i++) {
            ItemStack item = object.inventory.getItem(i);
            if (item != null) {
                if (BukkitScriptEvent.tryItem(new ItemTag(item), matcher)) {
                    return new ElementTag(i + 1);
                }
            }
        }
        return new ElementTag(-1);
    });
    // <--[tag]
    // @attribute <InventoryTag.find_all_items[<matcher>]>
    // @returns ListTag
    // @description
    // Returns a list of the location of all slots that contains an item that matches the given item matcher.
    // Returns an empty list if there's no match.
    // Uses the system behind <@link language Advanced Script Event Matching>.
    // -->
    tagProcessor.registerTag(ListTag.class, "find_all_items", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        ListTag result = new ListTag();
        String matcher = attribute.getParam();
        for (int i = 0; i < object.inventory.getSize(); i++) {
            ItemStack item = object.inventory.getItem(i);
            if (item != null) {
                if (BukkitScriptEvent.tryItem(new ItemTag(item), matcher)) {
                    result.addObject(new ElementTag(i + 1));
                }
            }
        }
        return result;
    });
    tagProcessor.registerTag(ElementTag.class, "find", (attribute, object) -> {
        Deprecations.inventoryNonMatcherTags.warn(attribute.context);
        if (attribute.startsWith("material", 2)) {
            ListTag list = attribute.contextAsType(2, ListTag.class);
            if (list == null) {
                return null;
            }
            HashSet<Material> materials = new HashSet<>();
            for (ObjectTag obj : list.objectForms) {
                materials.add(obj.asType(MaterialTag.class, attribute.context).getMaterial());
            }
            int slot = -1;
            for (int i = 0; i < object.inventory.getSize(); i++) {
                if (object.inventory.getItem(i) != null && materials.contains(object.inventory.getItem(i).getType())) {
                    slot = i + 1;
                    break;
                }
            }
            attribute.fulfill(1);
            return new ElementTag(slot);
        }
        if (attribute.startsWith("scriptname", 2)) {
            String scrname = attribute.contextAsType(2, ItemTag.class).getScriptName();
            if (scrname == null) {
                return null;
            }
            int slot = -1;
            for (int i = 0; i < object.inventory.getSize(); i++) {
                if (object.inventory.getItem(i) != null && scrname.equalsIgnoreCase(new ItemTag(object.inventory.getItem(i)).getScriptName())) {
                    slot = i + 1;
                    break;
                }
            }
            attribute.fulfill(1);
            return new ElementTag(slot);
        }
        if (!attribute.hasParam() || !ItemTag.matches(attribute.getParam())) {
            return null;
        }
        ItemTag item = attribute.paramAsType(ItemTag.class);
        item.setAmount(1);
        int slot = -1;
        for (int i = 0; i < object.inventory.getSize(); i++) {
            if (object.inventory.getItem(i) != null) {
                ItemTag compare_to = new ItemTag(object.inventory.getItem(i).clone());
                compare_to.setAmount(1);
                if (item.identify().equalsIgnoreCase(compare_to.identify())) {
                    slot = i + 1;
                    break;
                }
            }
        }
        return new ElementTag(slot);
    });
    tagProcessor.registerTag(ElementTag.class, "find_imperfect", (attribute, object) -> {
        Deprecations.inventoryNonMatcherTags.warn(attribute.context);
        if (!attribute.hasParam() || !ItemTag.matches(attribute.getParam())) {
            return null;
        }
        ItemTag item = attribute.paramAsType(ItemTag.class);
        item.setAmount(1);
        int slot = -1;
        for (int i = 0; i < object.inventory.getSize(); i++) {
            if (object.inventory.getItem(i) != null) {
                ItemTag compare_to = new ItemTag(object.inventory.getItem(i).clone());
                compare_to.setAmount(1);
                if (item.identify().equalsIgnoreCase(compare_to.identify()) || item.getScriptName().equalsIgnoreCase(compare_to.getScriptName())) {
                    slot = i + 1;
                    break;
                }
            }
        }
        return new ElementTag(slot);
    });
    // <--[tag]
    // @attribute <InventoryTag.id_type>
    // @returns ElementTag
    // @description
    // Returns Denizen's type ID for this inventory (player, location, etc.).
    // -->
    tagProcessor.registerTag(ElementTag.class, "id_type", (attribute, object) -> {
        return new ElementTag(object.idType);
    });
    // <--[tag]
    // @attribute <InventoryTag.note_name>
    // @returns ElementTag
    // @description
    // Gets the name of a noted InventoryTag. If the inventory isn't noted, this is null.
    // -->
    tagProcessor.registerTag(ElementTag.class, "note_name", (attribute, object) -> {
        String noteName = NoteManager.getSavedId(object);
        if (noteName == null) {
            return null;
        }
        return new ElementTag(noteName);
    }, "notable_name");
    // <--[tag]
    // @attribute <InventoryTag.location>
    // @returns LocationTag
    // @description
    // Returns the location of this inventory's holder.
    // -->
    tagProcessor.registerTag(LocationTag.class, "location", (attribute, object) -> {
        return object.getLocation();
    });
    // <--[tag]
    // @attribute <InventoryTag.quantity_item[(<matcher>)]>
    // @returns ElementTag(Number)
    // @description
    // Returns the combined quantity of itemstacks that match an item matcher if one is specified,
    // or the combined quantity of all itemstacks if one is not.
    // Uses the system behind <@link language Advanced Script Event Matching>.
    // -->
    tagProcessor.registerTag(ElementTag.class, "quantity_item", (attribute, object) -> {
        String matcher = attribute.hasParam() ? attribute.getParam() : null;
        int found_items = 0;
        for (ItemStack item : object.getContents()) {
            if (item != null) {
                if (matcher == null || BukkitScriptEvent.tryItem(new ItemTag(item), matcher)) {
                    found_items += item.getAmount();
                }
            }
        }
        return new ElementTag(found_items);
    });
    tagProcessor.registerTag(ElementTag.class, "quantity", (attribute, object) -> {
        Deprecations.inventoryNonMatcherTags.warn(attribute.context);
        if (attribute.startsWith("scriptname", 2)) {
            if (!attribute.hasContext(2)) {
                return null;
            }
            String scriptName = attribute.getContext(2);
            attribute.fulfill(1);
            return new ElementTag(object.countByScriptName(scriptName));
        }
        if (attribute.startsWith("flagged", 2)) {
            if (!attribute.hasContext(2)) {
                return null;
            }
            String flag = attribute.getContext(2);
            attribute.fulfill(1);
            return new ElementTag(object.countByFlag(flag));
        }
        if (attribute.startsWith("material", 2)) {
            if (!attribute.hasContext(2) || !MaterialTag.matches(attribute.getContext(2))) {
                return null;
            }
            MaterialTag material = attribute.contextAsType(2, MaterialTag.class);
            attribute.fulfill(1);
            return new ElementTag(object.countByMaterial(material.getMaterial()));
        }
        if (attribute.hasParam() && ItemTag.matches(attribute.getParam())) {
            return new ElementTag(object.count(attribute.paramAsType(ItemTag.class).getItemStack(), false));
        } else {
            return new ElementTag(object.count(null, false));
        }
    }, "qty");
    // <--[tag]
    // @attribute <InventoryTag.stacks[(<item>)]>
    // @returns ElementTag(Number)
    // @description
    // Returns the number of itemstacks that match an item if one is specified, or the number of all itemstacks if one is not.
    // -->
    tagProcessor.registerTag(ElementTag.class, "stacks", (attribute, object) -> {
        if (attribute.hasParam() && ItemTag.matches(attribute.getParam())) {
            return new ElementTag(object.count(attribute.paramAsType(ItemTag.class).getItemStack(), true));
        } else {
            return new ElementTag(object.count(null, true));
        }
    });
    // <--[tag]
    // @attribute <InventoryTag.slot[<#>|...]>
    // @returns ObjectTag
    // @description
    // If one slot is specified, returns the ItemTag in the specified slot.
    // If more than one slot is specified, returns a ListTag(ItemTag) of the item in each given slot.
    // -->
    tagProcessor.registerTag(ObjectTag.class, "slot", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        ListTag slots = ListTag.getListFor(attribute.getParamObject(), attribute.context);
        if (slots.isEmpty()) {
            if (!attribute.hasAlternative()) {
                Debug.echoError("Cannot get a list of zero slots.");
            }
            return null;
        } else if (slots.size() == 1) {
            int slot = SlotHelper.nameToIndexFor(attribute.getParam(), object.getInventory().getHolder());
            if (slot < 0) {
                slot = 0;
            } else if (slot > object.getInventory().getSize() - 1) {
                slot = object.getInventory().getSize() - 1;
            }
            return new ItemTag(object.getInventory().getItem(slot));
        } else {
            ListTag result = new ListTag();
            for (String slotText : slots) {
                int slot = SlotHelper.nameToIndexFor(slotText, object.getInventory().getHolder());
                if (slot < 0) {
                    slot = 0;
                } else if (slot > object.getInventory().getSize() - 1) {
                    slot = object.getInventory().getSize() - 1;
                }
                result.addObject(new ItemTag(object.getInventory().getItem(slot)));
            }
            return result;
        }
    });
    // <--[tag]
    // @attribute <InventoryTag.inventory_type>
    // @returns ElementTag
    // @description
    // Returns the type of the inventory (e.g. "PLAYER", "CRAFTING", "HORSE").
    // -->
    tagProcessor.registerTag(ElementTag.class, "inventory_type", (attribute, object) -> {
        return new ElementTag(object.inventory instanceof HorseInventory ? "HORSE" : object.getInventory().getType().name());
    });
    // <--[tag]
    // @attribute <InventoryTag.equipment_map>
    // @returns MapTag
    // @description
    // Returns a MapTag containing the inventory's equipment.
    // Output keys for players are boots, leggings,  chestplate, helmet.
    // Output keys for horses are saddle, armor.
    // Air items will be left out of the map.
    // -->
    tagProcessor.registerTag(MapTag.class, "equipment_map", (attribute, object) -> {
        return object.getEquipmentMap();
    });
    // <--[tag]
    // @attribute <InventoryTag.equipment>
    // @returns ListTag(ItemTag)
    // @description
    // Returns the equipment of an inventory as a list of items.
    // For players, the order is boots|leggings|chestplate|helmet.
    // For horses, the order is saddle|armor.
    // -->
    tagProcessor.registerTag(ListTag.class, "equipment", (attribute, object) -> {
        return object.getEquipment();
    });
    // <--[tag]
    // @attribute <InventoryTag.matrix>
    // @returns ListTag(ItemTag)
    // @mechanism InventoryTag.matrix
    // @description
    // Returns the items currently in a crafting inventory's matrix.
    // -->
    tagProcessor.registerTag(ListTag.class, "matrix", (attribute, object) -> {
        if (!(object.inventory instanceof CraftingInventory)) {
            return null;
        }
        ListTag recipeList = new ListTag();
        for (ItemStack item : ((CraftingInventory) object.inventory).getMatrix()) {
            if (item != null) {
                recipeList.addObject(new ItemTag(item));
            } else {
                recipeList.addObject(new ItemTag(Material.AIR));
            }
        }
        return recipeList;
    });
    // <--[tag]
    // @attribute <InventoryTag.recipe>
    // @returns ElementTag
    // @description
    // Returns the recipe ID for the recipe currently formed in a crafting inventory.
    // Returns a list in the Namespace:Key format, for example "minecraft:stick".
    // -->
    tagProcessor.registerTag(ElementTag.class, "recipe", (attribute, object) -> {
        Recipe recipe;
        if ((object.inventory instanceof CraftingInventory)) {
            recipe = ((CraftingInventory) object.inventory).getRecipe();
        } else {
            return null;
        }
        if (recipe == null) {
            return null;
        }
        return new ElementTag(((Keyed) recipe).getKey().toString());
    });
    // <--[tag]
    // @attribute <InventoryTag.craftable_quantity>
    // @returns ElementTag(Number)
    // @description
    // Returns the quantity of items that would be received if this crafting inventory were fully crafted (eg via a shift click).
    // -->
    tagProcessor.registerTag(ElementTag.class, "craftable_quantity", (attribute, object) -> {
        Recipe recipe;
        if ((object.inventory instanceof CraftingInventory)) {
            recipe = ((CraftingInventory) object.inventory).getRecipe();
        } else {
            return null;
        }
        if (recipe == null) {
            return null;
        }
        return new ElementTag(RecipeHelper.getMaximumOutputQuantity(recipe, (CraftingInventory) object.inventory) * recipe.getResult().getAmount());
    });
    // <--[tag]
    // @attribute <InventoryTag.result>
    // @returns ItemTag
    // @mechanism InventoryTag.result
    // @description
    // Returns the item currently in the result section of a crafting inventory or furnace inventory.
    // -->
    tagProcessor.registerTag(ItemTag.class, "result", (attribute, object) -> {
        ItemStack result;
        if ((object.inventory instanceof CraftingInventory)) {
            result = ((CraftingInventory) object.inventory).getResult();
        } else if ((object.inventory instanceof FurnaceInventory)) {
            result = ((FurnaceInventory) object.inventory).getResult();
        } else {
            return null;
        }
        if (result == null) {
            return null;
        }
        return new ItemTag(result);
    });
    // <--[tag]
    // @attribute <InventoryTag.anvil_repair_cost>
    // @returns ElementTag(Number)
    // @mechanism InventoryTag.anvil_repair_cost
    // @description
    // Returns the current repair cost on an anvil.
    // -->
    tagProcessor.registerTag(ElementTag.class, "anvil_repair_cost", (attribute, object) -> {
        if (!(object.inventory instanceof AnvilInventory)) {
            return null;
        }
        return new ElementTag(((AnvilInventory) object.inventory).getRepairCost());
    });
    // <--[tag]
    // @attribute <InventoryTag.anvil_max_repair_cost>
    // @returns ElementTag(Number)
    // @mechanism InventoryTag.anvil_max_repair_cost
    // @description
    // Returns the maximum repair cost on an anvil.
    // -->
    tagProcessor.registerTag(ElementTag.class, "anvil_max_repair_cost", (attribute, object) -> {
        if (!(object.inventory instanceof AnvilInventory)) {
            return null;
        }
        return new ElementTag(((AnvilInventory) object.inventory).getMaximumRepairCost());
    });
    // <--[tag]
    // @attribute <InventoryTag.anvil_rename_text>
    // @returns ElementTag
    // @description
    // Returns the current entered renaming text on an anvil.
    // -->
    tagProcessor.registerTag(ElementTag.class, "anvil_rename_text", (attribute, object) -> {
        if (!(object.inventory instanceof AnvilInventory)) {
            return null;
        }
        return new ElementTag(((AnvilInventory) object.inventory).getRenameText(), true);
    });
    // <--[tag]
    // @attribute <InventoryTag.fuel>
    // @returns ItemTag
    // @mechanism InventoryTag.fuel
    // @description
    // Returns the item currently in the fuel section of a furnace or brewing stand inventory.
    // -->
    tagProcessor.registerTag(ItemTag.class, "fuel", (attribute, object) -> {
        if (object.getInventory() instanceof FurnaceInventory) {
            return new ItemTag(((FurnaceInventory) object.getInventory()).getFuel());
        }
        if (object.getInventory() instanceof BrewerInventory) {
            return new ItemTag(((BrewerInventory) object.getInventory()).getFuel());
        }
        return null;
    });
    // <--[tag]
    // @attribute <InventoryTag.input>
    // @returns ItemTag
    // @mechanism InventoryTag.input
    // @description
    // Returns the item currently in the smelting slot of a furnace inventory, or the ingredient slot of a brewing stand inventory.
    // -->
    tagProcessor.registerTag(ItemTag.class, "input", (attribute, object) -> {
        if (object.getInventory() instanceof FurnaceInventory) {
            return new ItemTag(((FurnaceInventory) object.getInventory()).getSmelting());
        }
        if (object.getInventory() instanceof BrewerInventory) {
            return new ItemTag(((BrewerInventory) object.getInventory()).getIngredient());
        }
        return null;
    });
    tagProcessor.registerFutureTagDeprecation("input", "smelting");
    // <--[tag]
    // @attribute <InventoryTag.advanced_matches[<matcher>]>
    // @returns ElementTag(Boolean)
    // @group element checking
    // @description
    // Returns whether the inventory matches some matcher text, using the system behind <@link language Advanced Script Event Matching>.
    // -->
    tagProcessor.registerTag(ElementTag.class, "advanced_matches", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        return new ElementTag(BukkitScriptEvent.tryInventory(object, attribute.getParam()));
    });
    // <--[tag]
    // @attribute <InventoryTag.viewers>
    // @returns ListTag(PlayerTag)
    // @description
    // Returns a list of players viewing the inventory.
    // -->
    tagProcessor.registerTag(ListTag.class, "viewers", (attribute, object) -> {
        ListTag list = new ListTag();
        for (HumanEntity viewer : object.getInventory().getViewers()) {
            if (!EntityTag.isNPC(viewer) && viewer instanceof Player) {
                list.addObject(new PlayerTag((Player) viewer));
            }
        }
        return list;
    });
}
Also used : Keyed(org.bukkit.Keyed) HumanEntity(org.bukkit.entity.HumanEntity) ItemMeta(org.bukkit.inventory.meta.ItemMeta) Player(org.bukkit.entity.Player) ImprovedOfflinePlayer(com.denizenscript.denizen.nms.abstracts.ImprovedOfflinePlayer) InventoryType(org.bukkit.event.inventory.InventoryType) Material(org.bukkit.Material) ListTag(com.denizenscript.denizencore.objects.core.ListTag) ScriptTag(com.denizenscript.denizencore.objects.core.ScriptTag) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) BookMeta(org.bukkit.inventory.meta.BookMeta)

Example 27 with ScriptTag

use of com.denizenscript.denizencore.objects.core.ScriptTag in project Denizen-For-Bukkit by DenizenScript.

the class ZapCommand method parseArgs.

@Override
public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {
    for (Argument arg : scriptEntry) {
        if (!scriptEntry.hasObject("script") && !scriptEntry.hasObject("step") && arg.hasPrefix() && arg.getPrefix().matchesArgumentType(ScriptTag.class)) {
            Deprecations.zapPrefix.warn(scriptEntry);
            scriptEntry.addObject("script", arg.getPrefix().asType(ScriptTag.class));
            scriptEntry.addObject("step", arg.asElement());
        } else if (!scriptEntry.hasObject("script") && arg.matchesArgumentType(ScriptTag.class) && arg.asType(ScriptTag.class).getContainer() instanceof InteractScriptContainer && arg.limitToOnlyPrefix("script")) {
            scriptEntry.addObject("script", arg.asType(ScriptTag.class));
        } else if (!scriptEntry.hasObject("step") && arg.limitToOnlyPrefix("step")) {
            scriptEntry.addObject("step", arg.asElement());
        } else if (!scriptEntry.hasObject("duration") && arg.matchesArgumentType(DurationTag.class) && arg.limitToOnlyPrefix("duration")) {
            scriptEntry.addObject("duration", arg.asType(DurationTag.class));
        } else {
            arg.reportUnhandled();
        }
    }
    PlayerTag player = Utilities.getEntryPlayer(scriptEntry);
    if (player == null || !player.isValid()) {
        throw new InvalidArgumentsException("Must have player context!");
    }
    if (!scriptEntry.hasObject("script")) {
        ScriptTag script = scriptEntry.getScript();
        if (script != null) {
            if (script.getContainer() instanceof InteractScriptContainer) {
                scriptEntry.addObject("script", script);
            } else if (script.getContainer() instanceof AssignmentScriptContainer) {
                InteractScriptContainer interact = ((AssignmentScriptContainer) script.getContainer()).interact;
                if (interact != null) {
                    scriptEntry.addObject("script", new ScriptTag(interact));
                }
            }
        }
        if (!scriptEntry.hasObject("script")) {
            NPCTag npc = Utilities.getEntryNPC(scriptEntry);
            if (npc != null && npc.getCitizen().hasTrait(AssignmentTrait.class)) {
                AssignmentTrait trait = npc.getCitizen().getOrAddTrait(AssignmentTrait.class);
                for (AssignmentScriptContainer container : trait.containerCache) {
                    if (container != null && container.getInteract() != null) {
                        scriptEntry.addObject("script", new ScriptTag(container.getInteract()));
                        break;
                    }
                }
            }
        }
        if (!scriptEntry.hasObject("script")) {
            throw new InvalidArgumentsException("No script to zap! Must be in an interact script, or have a linked NPC with an associated interact script.");
        }
    }
}
Also used : AssignmentTrait(com.denizenscript.denizen.npc.traits.AssignmentTrait) PlayerTag(com.denizenscript.denizen.objects.PlayerTag) ScriptTag(com.denizenscript.denizencore.objects.core.ScriptTag) NPCTag(com.denizenscript.denizen.objects.NPCTag) InteractScriptContainer(com.denizenscript.denizen.scripts.containers.core.InteractScriptContainer) AssignmentScriptContainer(com.denizenscript.denizen.scripts.containers.core.AssignmentScriptContainer) DurationTag(com.denizenscript.denizencore.objects.core.DurationTag) InvalidArgumentsException(com.denizenscript.denizencore.exceptions.InvalidArgumentsException)

Example 28 with ScriptTag

use of com.denizenscript.denizencore.objects.core.ScriptTag in project Denizen-For-Bukkit by DenizenScript.

the class ZapCommand method execute.

@Override
public void execute(final ScriptEntry scriptEntry) {
    final ScriptTag script = scriptEntry.getObjectTag("script");
    DurationTag duration = scriptEntry.getObjectTag("duration");
    ElementTag stepElement = scriptEntry.getElement("step");
    if (scriptEntry.dbCallShouldDebug()) {
        Debug.report(scriptEntry, getName(), Utilities.getEntryPlayer(scriptEntry), script, stepElement != null ? stepElement : db("step", "++ (inc)"), duration);
    }
    String step = stepElement == null ? null : stepElement.asString();
    String currentStep = InteractScriptHelper.getCurrentStep(Utilities.getEntryPlayer(scriptEntry), script.getName());
    // Special-case for backwards compatibility: ability to use ZAP to count up steps.
    if (step == null) {
        // to '1' so it can be incremented next time.
        if (ArgumentHelper.matchesInteger(currentStep)) {
            step = String.valueOf(Integer.parseInt(currentStep) + 1);
        } else {
            step = "1";
        }
    } else if (step.equals("*")) {
        step = ((InteractScriptContainer) script.getContainer()).getDefaultStepName();
    }
    if (step.equalsIgnoreCase(currentStep)) {
        Debug.echoError(scriptEntry, "Zapping to own current step!");
        return;
    }
    TimeTag expiration = null;
    if (duration != null && duration.getSeconds() > 0) {
        expiration = new TimeTag(TimeTag.now().millis() + duration.getMillis());
    }
    Utilities.getEntryPlayer(scriptEntry).getFlagTracker().setFlag("__interact_step." + script.getName(), new ElementTag(step), expiration);
}
Also used : ScriptTag(com.denizenscript.denizencore.objects.core.ScriptTag) InteractScriptContainer(com.denizenscript.denizen.scripts.containers.core.InteractScriptContainer) TimeTag(com.denizenscript.denizencore.objects.core.TimeTag) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) DurationTag(com.denizenscript.denizencore.objects.core.DurationTag)

Example 29 with ScriptTag

use of com.denizenscript.denizencore.objects.core.ScriptTag in project Denizen-For-Bukkit by DenizenScript.

the class EnchantmentTag method registerTags.

public static void registerTags() {
    AbstractFlagTracker.registerFlagHandlers(tagProcessor);
    // <--[tag]
    // @attribute <EnchantmentTag.name>
    // @returns ElementTag
    // @description
    // Gets the name of this enchantment. For vanilla enchantments, uses the vanilla name like 'sharpness'.
    // For Denizen custom enchantments, returns the 'id' specified in the script.
    // For any other enchantments, returns the full key.
    // -->
    tagProcessor.registerTag(ElementTag.class, "name", (attribute, object) -> {
        return new ElementTag(object.getCleanName());
    });
    // <--[tag]
    // @attribute <EnchantmentTag.key>
    // @returns ElementTag
    // @description
    // Returns the full key for this enchantment, like "minecraft:sharpness".
    // -->
    tagProcessor.registerTag(ElementTag.class, "key", (attribute, object) -> {
        return new ElementTag(object.enchantment.getKey().toString());
    });
    // <--[tag]
    // @attribute <EnchantmentTag.full_name[<level>]>
    // @returns ElementTag
    // @description
    // Returns the full name for this enchantment for a given level, like "Sharpness V".
    // For vanilla enchantments, uses language translation keys.
    // -->
    tagProcessor.registerTag(ElementTag.class, "full_name", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        return new ElementTag(NMSHandler.enchantmentHelper.getFullName(object.enchantment, attribute.getIntParam()));
    });
    // <--[tag]
    // @attribute <EnchantmentTag.script>
    // @returns ScriptTag
    // @description
    // Returns the script that created this enchantment type, if any.
    // -->
    tagProcessor.registerTag(ScriptTag.class, "script", (attribute, object) -> {
        if (!object.enchantment.getKey().getNamespace().equals("denizen")) {
            return null;
        }
        EnchantmentScriptContainer.EnchantmentReference ref = EnchantmentScriptContainer.registeredEnchantmentContainers.get(object.enchantment.getKey().getKey());
        if (ref == null) {
            return null;
        }
        return new ScriptTag(ref.script);
    });
    // <--[tag]
    // @attribute <EnchantmentTag.min_level>
    // @returns ElementTag(Number)
    // @description
    // Returns the minimum level of this enchantment. Usually '1'.
    // -->
    tagProcessor.registerTag(ElementTag.class, "min_level", (attribute, object) -> {
        return new ElementTag(object.enchantment.getStartLevel());
    });
    // <--[tag]
    // @attribute <EnchantmentTag.max_level>
    // @returns ElementTag(Number)
    // @description
    // Returns the minimum level of this enchantment. Usually between 1 and 5.
    // -->
    tagProcessor.registerTag(ElementTag.class, "max_level", (attribute, object) -> {
        return new ElementTag(object.enchantment.getMaxLevel());
    });
    // <--[tag]
    // @attribute <EnchantmentTag.treasure_only>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether this enchantment is only for spawning as treasure.
    // -->
    tagProcessor.registerTag(ElementTag.class, "treasure_only", (attribute, object) -> {
        return new ElementTag(object.enchantment.isTreasure());
    });
    // <--[tag]
    // @attribute <EnchantmentTag.is_tradable>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether this enchantment is only considered to be tradable. Villagers won't trade this enchantment if set to false.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_tradable", (attribute, object) -> {
        return new ElementTag(NMSHandler.enchantmentHelper.isTradable(object.enchantment));
    });
    // <--[tag]
    // @attribute <EnchantmentTag.is_discoverable>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether this enchantment is only considered to be discoverable.
    // If true, this will spawn from vanilla sources like the enchanting table. If false, it can only be given directly by script.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_discoverable", (attribute, object) -> {
        return new ElementTag(NMSHandler.enchantmentHelper.isDiscoverable(object.enchantment));
    });
    // <--[tag]
    // @attribute <EnchantmentTag.is_curse>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether this enchantment is only considered to be a curse. Curses are removed at grindstones, and spread from crafting table repairs.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_curse", (attribute, object) -> {
        return new ElementTag(NMSHandler.enchantmentHelper.isCurse(object.enchantment));
    });
    // <--[tag]
    // @attribute <EnchantmentTag.category>
    // @returns ElementTag
    // @description
    // Returns the category of this enchantment. Can be any of: ARMOR, ARMOR_FEET, ARMOR_LEGS, ARMOR_CHEST, ARMOR_HEAD,
    // WEAPON, DIGGER, FISHING_ROD, TRIDENT, BREAKABLE, BOW, WEARABLE, CROSSBOW, VANISHABLE
    // -->
    tagProcessor.registerTag(ElementTag.class, "category", (attribute, object) -> {
        return new ElementTag(object.enchantment.getItemTarget().name());
    });
    // <--[tag]
    // @attribute <EnchantmentTag.rarity>
    // @returns ElementTag
    // @description
    // Returns the rarity of this enchantment. Can be any of: COMMON, UNCOMMON, RARE, VERY_RARE
    // -->
    tagProcessor.registerTag(ElementTag.class, "rarity", (attribute, object) -> {
        return new ElementTag(NMSHandler.enchantmentHelper.getRarity(object.enchantment));
    });
    // <--[tag]
    // @attribute <EnchantmentTag.can_enchant[<item>]>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether this enchantment can enchant the given ItemTag (based on material mainly).
    // -->
    tagProcessor.registerTag(ElementTag.class, "can_enchant", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        return new ElementTag(object.enchantment.canEnchantItem(attribute.paramAsType(ItemTag.class).getItemStack()));
    });
    // <--[tag]
    // @attribute <EnchantmentTag.is_compatible[<enchantment>]>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether this enchantment is compatible with another given enchantment.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_compatible", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        return new ElementTag(!object.enchantment.conflictsWith(attribute.paramAsType(EnchantmentTag.class).enchantment));
    });
    // <--[tag]
    // @attribute <EnchantmentTag.min_cost[<level>]>
    // @returns ElementTag(Decimal)
    // @description
    // Returns the minimum cost for this enchantment for the given level.
    // -->
    tagProcessor.registerTag(ElementTag.class, "min_cost", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        return new ElementTag(NMSHandler.enchantmentHelper.getMinCost(object.enchantment, attribute.getIntParam()));
    });
    // <--[tag]
    // @attribute <EnchantmentTag.max_cost[<level>]>
    // @returns ElementTag(Decimal)
    // @description
    // Returns the maximum cost for this enchantment for the given level.
    // -->
    tagProcessor.registerTag(ElementTag.class, "max_cost", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        return new ElementTag(NMSHandler.enchantmentHelper.getMaxCost(object.enchantment, attribute.getIntParam()));
    });
    // <--[tag]
    // @attribute <EnchantmentTag.damage_bonus[level=<level>;type=<type>]>
    // @returns ElementTag(Decimal)
    // @description
    // Returns the damage bonus this enchantment applies against the given monster type.
    // The input is a MapTag with a level value and a monster type specified, where the type can be any of: ARTHROPOD, ILLAGER, WATER, UNDEAD, or UNDEFINED
    // For example, <[my_enchantment].damage_bonus[level=3;type=undead]>
    // -->
    tagProcessor.registerTag(ElementTag.class, "damage_bonus", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        MapTag map = attribute.paramAsType(MapTag.class);
        if (map == null) {
            attribute.echoError("Invalid MapTag input to damage_bonus - not a valid map.");
            return null;
        }
        ObjectTag level = map.getObject("level");
        ObjectTag type = map.getObject("type");
        if (level == null || type == null) {
            attribute.echoError("Invalid MapTag input to damage_bonus - missing 'level' or 'type'");
            return null;
        }
        return new ElementTag(NMSHandler.enchantmentHelper.getDamageBonus(object.enchantment, new ElementTag(level.toString()).asInt(), CoreUtilities.toLowerCase(type.toString())));
    });
    // <--[tag]
    // @attribute <EnchantmentTag.damage_protection[level=<level>;type=<cause>;attacker=<entity>]>
    // @returns ElementTag(Number)
    // @description
    // Returns the damage protection this enchantment applies against the given damage cause and optional attacker.
    // The input is a MapTag with a level value and a damage type specified, where the damage type must be from <@link language Damage Cause>.
    // For entity damage causes, optionally specify the entity attacker.
    // For example, <[my_enchantment].damage_protection[level=3;type=undead]>
    // -->
    tagProcessor.registerTag(ElementTag.class, "damage_protection", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        MapTag map = attribute.paramAsType(MapTag.class);
        if (map == null) {
            attribute.echoError("Invalid MapTag input to damage_protection - not a valid map.");
            return null;
        }
        ObjectTag level = map.getObject("level");
        ObjectTag type = map.getObject("type");
        if (level == null || type == null) {
            attribute.echoError("Invalid MapTag input to damage_protection - missing 'level' or 'type'");
            return null;
        }
        EntityDamageEvent.DamageCause cause;
        try {
            cause = EntityDamageEvent.DamageCause.valueOf(type.toString().toUpperCase());
        } catch (IllegalArgumentException ex) {
            attribute.echoError("Invalid MapTag input to damage_protection - cause '" + type.toString() + "' is not a valid DamageCause.");
            return null;
        }
        ObjectTag attacker = map.getObject("attacker");
        return new ElementTag(NMSHandler.enchantmentHelper.getDamageProtection(object.enchantment, new ElementTag(level.toString()).asInt(), cause, attacker == null ? null : attacker.asType(EntityTag.class, attribute.context).getBukkitEntity()));
    });
}
Also used : ObjectTag(com.denizenscript.denizencore.objects.ObjectTag) ScriptTag(com.denizenscript.denizencore.objects.core.ScriptTag) EnchantmentScriptContainer(com.denizenscript.denizen.scripts.containers.core.EnchantmentScriptContainer) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) MapTag(com.denizenscript.denizencore.objects.core.MapTag) EntityDamageEvent(org.bukkit.event.entity.EntityDamageEvent)

Example 30 with ScriptTag

use of com.denizenscript.denizencore.objects.core.ScriptTag in project Denizen-For-Bukkit by DenizenScript.

the class InventoryScriptContainer method getInventoryFrom.

public InventoryTag getInventoryFrom(TagContext context) {
    InventoryTag inventory;
    context = (context == null ? CoreUtilities.basicContext : context).clone();
    ScriptTag thisScript = new ScriptTag(this);
    context.script = thisScript;
    context.debug = context.debug && shouldDebug();
    try {
        InventoryType type = InventoryType.CHEST;
        if (contains("inventory", String.class)) {
            try {
                type = InventoryType.valueOf(getString("inventory").toUpperCase());
            } catch (IllegalArgumentException ex) {
                Debug.echoError(this, "Invalid inventory type specified. Assuming \"CHEST\" (" + ex.getMessage() + ")");
            }
        } else {
            Debug.echoError(this, "Inventory script '" + getName() + "' does not specify an inventory type. Assuming \"CHEST\".");
        }
        if (type == InventoryType.PLAYER) {
            Debug.echoError(this, "Inventory type 'player' is not valid for inventory scripts - defaulting to 'CHEST'.");
            type = InventoryType.CHEST;
        }
        int size = 0;
        if (contains("size", String.class)) {
            if (type != InventoryType.CHEST) {
                Debug.echoError(this, "You can only set the size of chest inventories!");
            } else {
                String sizeText = TagManager.tag(getString("size"), context);
                if (!ArgumentHelper.matchesInteger(sizeText)) {
                    Debug.echoError(this, "Invalid (not-a-number) size value.");
                } else {
                    size = Integer.parseInt(sizeText);
                }
                if (size == 0) {
                    Debug.echoError(this, "Inventory size can't be 0. Assuming default of inventory type...");
                }
                if (size % 9 != 0) {
                    size = (int) Math.ceil(size / 9.0) * 9;
                    Debug.echoError(this, "Inventory size must be a multiple of 9! Rounding up to " + size + "...");
                }
                if (size < 0) {
                    size = size * -1;
                    Debug.echoError(this, "Inventory size must be a positive number! Inverting to " + size + "...");
                }
            }
        }
        if (size == 0) {
            if (contains("slots", List.class) && type == InventoryType.CHEST) {
                size = getStringList("slots").size() * 9;
            } else {
                size = type.getDefaultSize();
            }
        }
        String title = contains("title", String.class) ? TagManager.tag(getString("title"), context) : null;
        if (type == InventoryType.CHEST) {
            inventory = new InventoryTag(size, title != null ? title : "Chest");
        } else {
            if (title == null) {
                inventory = new InventoryTag(type);
            } else {
                inventory = new InventoryTag(type, title);
            }
        }
        inventory.idType = "script";
        inventory.idHolder = thisScript;
        boolean[] filledSlots = new boolean[size];
        if (contains("slots", List.class)) {
            ItemStack[] finalItems = new ItemStack[size];
            int itemsAdded = 0;
            for (String items : getStringList("slots")) {
                items = TagManager.tag(items, context).trim();
                if (items.isEmpty()) {
                    continue;
                }
                if (!items.startsWith("[") || !items.endsWith("]")) {
                    Debug.echoError(this, "Invalid slots line: [" + items + "]... Ignoring it");
                    continue;
                }
                String[] itemsInLine = items.substring(1, items.length() - 1).split("\\[?\\]?\\s+\\[", -1);
                for (String item : itemsInLine) {
                    if (item.isEmpty()) {
                        finalItems[itemsAdded++] = new ItemStack(Material.AIR);
                        continue;
                    }
                    filledSlots[itemsAdded] = true;
                    if (contains("definitions." + item, String.class)) {
                        ItemTag def = ItemTag.valueOf(TagManager.tag(getString("definitions." + item), context), context);
                        if (def == null) {
                            Debug.echoError(this, "Invalid definition '" + item + "'... Ignoring it and assuming 'AIR'");
                            finalItems[itemsAdded] = new ItemStack(Material.AIR);
                        } else {
                            finalItems[itemsAdded] = def.getItemStack();
                        }
                    } else {
                        try {
                            ItemTag itemTag = ItemTag.valueOf(item, context);
                            if (itemTag == null) {
                                finalItems[itemsAdded] = new ItemStack(Material.AIR);
                                Debug.echoError(this, "Invalid slot item: [" + item + "]... ignoring it and assuming 'AIR'");
                            } else {
                                finalItems[itemsAdded] = itemTag.getItemStack();
                            }
                        } catch (Exception ex) {
                            Debug.echoError(this, "Invalid slot item: [" + item + "]...");
                            Debug.echoError(ex);
                        }
                    }
                    itemsAdded++;
                }
            }
            inventory.setContents(finalItems);
        }
        if (containsScriptSection("procedural items")) {
            List<ScriptEntry> entries = getEntries(context.getScriptEntryData(), "procedural items");
            if (!entries.isEmpty()) {
                InstantQueue queue = new InstantQueue("INV_SCRIPT_ITEM_PROC");
                queue.addEntries(entries);
                if (contains("definitions", Map.class)) {
                    YamlConfiguration section = getConfigurationSection("definitions");
                    for (StringHolder string : section.getKeys(false)) {
                        String definition = string.str;
                        queue.addDefinition(definition, section.getString(definition));
                    }
                }
                queue.procedural = true;
                queue.start();
                if (queue.determinations != null) {
                    ListTag list = ListTag.getListFor(queue.determinations.getObject(0), context);
                    if (list != null) {
                        int x = 0;
                        for (ItemTag item : list.filter(ItemTag.class, context, true)) {
                            while (x < filledSlots.length && filledSlots[x]) {
                                x++;
                            }
                            if (x >= filledSlots.length || filledSlots[x]) {
                                break;
                            }
                            inventory.setSlots(x, item.getItemStack());
                            filledSlots[x] = true;
                        }
                    }
                }
            }
        }
    } catch (Exception e) {
        Debug.echoError(this, "Woah! An exception has been called while building this inventory script!");
        Debug.echoError(e);
        inventory = null;
    }
    if (inventory != null) {
        InventoryTag.trackTemporaryInventory(inventory);
    }
    return inventory;
}
Also used : InventoryType(org.bukkit.event.inventory.InventoryType) ScriptEntry(com.denizenscript.denizencore.scripts.ScriptEntry) YamlConfiguration(com.denizenscript.denizencore.utilities.YamlConfiguration) ListTag(com.denizenscript.denizencore.objects.core.ListTag) StringHolder(com.denizenscript.denizencore.utilities.text.StringHolder) ScriptTag(com.denizenscript.denizencore.objects.core.ScriptTag) List(java.util.List) InstantQueue(com.denizenscript.denizencore.scripts.queues.core.InstantQueue) ItemStack(org.bukkit.inventory.ItemStack) ItemTag(com.denizenscript.denizen.objects.ItemTag) InventoryTag(com.denizenscript.denizen.objects.InventoryTag)

Aggregations

ScriptTag (com.denizenscript.denizencore.objects.core.ScriptTag)38 ElementTag (com.denizenscript.denizencore.objects.core.ElementTag)17 BukkitTagContext (com.denizenscript.denizen.tags.BukkitTagContext)16 PlayerTag (com.denizenscript.denizen.objects.PlayerTag)8 ListTag (com.denizenscript.denizencore.objects.core.ListTag)8 List (java.util.List)7 ItemTag (com.denizenscript.denizen.objects.ItemTag)5 InvalidArgumentsException (com.denizenscript.denizencore.exceptions.InvalidArgumentsException)5 ObjectTag (com.denizenscript.denizencore.objects.ObjectTag)5 DurationTag (com.denizenscript.denizencore.objects.core.DurationTag)5 EntityTag (com.denizenscript.denizen.objects.EntityTag)4 LocationTag (com.denizenscript.denizen.objects.LocationTag)4 FormatScriptContainer (com.denizenscript.denizen.scripts.containers.core.FormatScriptContainer)4 ScriptEntry (com.denizenscript.denizencore.scripts.ScriptEntry)4 Player (org.bukkit.entity.Player)4 ImprovedOfflinePlayer (com.denizenscript.denizen.nms.abstracts.ImprovedOfflinePlayer)3 NPCTag (com.denizenscript.denizen.objects.NPCTag)3 AssignmentScriptContainer (com.denizenscript.denizen.scripts.containers.core.AssignmentScriptContainer)3 InteractScriptContainer (com.denizenscript.denizen.scripts.containers.core.InteractScriptContainer)3 ScriptQueue (com.denizenscript.denizencore.scripts.queues.ScriptQueue)3