diff --git a/paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperItemExtensions.java b/paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperItemExtensions.java index f2829a34fe..b5b28a29dd 100644 --- a/paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperItemExtensions.java +++ b/paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperItemExtensions.java @@ -1,5 +1,7 @@ package com.denizenscript.denizen.paper.properties; +import com.denizenscript.denizen.nms.NMSHandler; +import com.denizenscript.denizen.nms.NMSVersion; import com.denizenscript.denizen.objects.ItemTag; import com.denizenscript.denizencore.objects.core.ElementTag; @@ -7,16 +9,10 @@ public class PaperItemExtensions { public static void register() { - // <--[tag] - // @attribute - // @returns ElementTag - // @group paper - // @Plugin Paper - // @description - // Returns the rarity of an item, as "common", "uncommon", "rare", or "epic". - // --> - ItemTag.tagProcessor.registerTag(ElementTag.class, "rarity", (attribute, item) -> { - return new ElementTag(item.getItemStack().getRarity()); - }); + if (NMSHandler.getVersion().isAtMost(NMSVersion.v1_19)) { + ItemTag.tagProcessor.registerTag(ElementTag.class, "rarity", (attribute, item) -> { + return new ElementTag(item.getItemStack().getRarity()); + }); + } } } diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/PropertyRegistry.java b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/PropertyRegistry.java index 477c8bb129..e9161be14e 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/PropertyRegistry.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/PropertyRegistry.java @@ -239,6 +239,9 @@ public static void registerMainProperties() { registerItemProperty(ItemFireworkPower.class, "fireworks"); registerItemProperty(ItemFirework.class, "fireworks", "firework_explosion"); PropertyParser.registerProperty(ItemFlags.class, ItemTag.class); + if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_20)) { + registerItemProperty(ItemFood.class, "food"); + } PropertyParser.registerProperty(ItemFrameInvisible.class, ItemTag.class); // Special case handling in ItemComponentsPatch PropertyParser.registerProperty(ItemHidden.class, ItemTag.class); // Relevant components control their own hiding internally if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_19)) { @@ -251,10 +254,18 @@ public static void registerMainProperties() { registerItemProperty(ItemLodestoneTracked.class, "lodestone_tracker"); registerItemProperty(ItemLore.class, "lore"); registerItemProperty(ItemMap.class, "map_id"); + if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_20)) { + registerItemProperty(ItemMaxDurability.class, "max_damage"); + registerItemProperty(ItemMaxStackSize.class, "max_stack_size"); + registerItemProperty(ItemModel.class, "item_model"); + } PropertyParser.registerProperty(ItemNBT.class, ItemTag.class); registerItemProperty(ItemPatterns.class, "banner_patterns"); registerItemProperty(ItemPotion.class, "potion_contents"); PropertyParser.registerProperty(ItemQuantity.class, ItemTag.class); + if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_20)) { + registerItemProperty(ItemRarity.class, "rarity"); + } PropertyParser.registerProperty(ItemRawNBT.class, ItemTag.class); registerItemProperty(ItemRepairCost.class, "repair_cost"); PropertyParser.registerProperty(ItemScript.class, ItemTag.class); diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemDurability.java b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemDurability.java index ddd46aa1fb..92ed86a511 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemDurability.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemDurability.java @@ -1,9 +1,11 @@ package com.denizenscript.denizen.objects.properties.item; +import com.denizenscript.denizen.nms.NMSHandler; +import com.denizenscript.denizen.nms.NMSVersion; import com.denizenscript.denizen.objects.ItemTag; -import com.denizenscript.denizencore.objects.core.ElementTag; import com.denizenscript.denizencore.objects.Mechanism; import com.denizenscript.denizencore.objects.ObjectTag; +import com.denizenscript.denizencore.objects.core.ElementTag; import com.denizenscript.denizencore.objects.properties.Property; import com.denizenscript.denizencore.tags.Attribute; import org.bukkit.inventory.meta.Damageable; @@ -58,19 +60,20 @@ public ObjectTag getObjectAttribute(Attribute attribute) { .getObjectAttribute(attribute.fulfill(1)); } - // <--[tag] - // @attribute - // @returns ElementTag(Number) - // @group properties - // @description - // Returns the maximum durability (number of uses) of this item. - // For use with <@link tag ItemTag.durability> and <@link mechanism ItemTag.durability>. - // --> - if (attribute.startsWith("max_durability")) { - return new ElementTag(item.getMaterial().getMaterial().getMaxDurability()) - .getObjectAttribute(attribute.fulfill(1)); + if (NMSHandler.getVersion().isAtMost(NMSVersion.v1_19)) { + // <--[tag] + // @attribute + // @returns ElementTag(Number) + // @group properties + // @description + // Returns the maximum durability (number of uses) of this item. + // For use with <@link tag ItemTag.durability> and <@link mechanism ItemTag.durability>. + // --> + if (attribute.startsWith("max_durability")) { + return new ElementTag(item.getMaterial().getMaterial().getMaxDurability()) + .getObjectAttribute(attribute.fulfill(1)); + } } - return null; } @@ -101,7 +104,6 @@ public void adjust(Mechanism mechanism) { // Changes the durability of damageable items. // @tags // - // // // --> if (mechanism.matches("durability") && mechanism.requireInteger()) { diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemFood.java b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemFood.java new file mode 100644 index 0000000000..9bbfb2221a --- /dev/null +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemFood.java @@ -0,0 +1,78 @@ +package com.denizenscript.denizen.objects.properties.item; + +import com.denizenscript.denizen.objects.ItemTag; +import com.denizenscript.denizencore.objects.Mechanism; +import com.denizenscript.denizencore.objects.core.ElementTag; +import com.denizenscript.denizencore.objects.core.MapTag; +import org.bukkit.Material; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.components.FoodComponent; + +public class ItemFood extends ItemProperty { + + // <--[property] + // @object ItemTag + // @name food + // @input MapTag + // @description + // Controls the food properties of the item. + // A food item has the 'nutrition', 'saturation', and 'can_always_eat' properties. + // The 'nutrition' is the amount of hunger points the food restores. + // The 'saturation' is the amount of saturation points the food restores. + // The 'can_always_eat' is a boolean indicating if the food can be eaten even when the player is not hungry. + // @tag + // If the item does not have food properties, this will return null. + // @mechanism + // Provide no input to entirely remove the food component from the item. + // --> + + public static boolean describes(ItemTag item) { + return item.getBukkitMaterial() != Material.AIR; + } + + @Override + public MapTag getPropertyValue() { + if (getItemMeta().hasFood()) { + FoodComponent food = getItemMeta().getFood(); + MapTag map = new MapTag(); + map.putObject("nutrition", new ElementTag(food.getNutrition())); + map.putObject("saturation", new ElementTag(food.getSaturation())); + map.putObject("can_always_eat", new ElementTag(food.canAlwaysEat())); + return map; + } + return null; + } + + @Override + public void setPropertyValue(MapTag map, Mechanism mechanism) { + editMeta(ItemMeta.class, meta -> { + if (map == null) { + meta.setFood(null); + return; + } + FoodComponent food = meta.getFood(); + ElementTag nutrition = map.getElement("nutrition"); + if (nutrition != null) { + food.setNutrition(nutrition.asInt()); + } + ElementTag saturation = map.getElement("saturation"); + if (saturation != null) { + food.setSaturation(saturation.asFloat()); + } + ElementTag canAlwaysEat = map.getElement("can_always_eat"); + if (canAlwaysEat != null) { + food.setCanAlwaysEat(canAlwaysEat.asBoolean()); + } + meta.setFood(food); + }); + } + + @Override + public String getPropertyId() { + return "food"; + } + + public static void register() { + autoRegisterNullable("food", ItemFood.class, MapTag.class, false); + } +} diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemMaxDurability.java b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemMaxDurability.java new file mode 100644 index 0000000000..c814e238cd --- /dev/null +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemMaxDurability.java @@ -0,0 +1,63 @@ +package com.denizenscript.denizen.objects.properties.item; + +import com.denizenscript.denizen.objects.ItemTag; +import com.denizenscript.denizencore.objects.Mechanism; +import com.denizenscript.denizencore.objects.core.ElementTag; +import org.bukkit.Material; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.ItemMeta; + +public class ItemMaxDurability extends ItemProperty { + + // <--[property] + // @object ItemTag + // @name max_durability + // @input ElementTag + // @description + // Controls the maximum durability of an item, if it can have durability. + // If the item cannot have durability (e.g. is not a tool or armor), this will return null. + // @tag + // If the item does not have a max durability item component set, this will return the default max durability for the item type. + // --> + + public static boolean describes(ItemTag item) { + return item.getBukkitMaterial() != Material.AIR + && item.getItemMeta() instanceof Damageable; + } + + @Override + public ElementTag getPropertyValue() { + if (getItemMeta() instanceof Damageable damageable) { + if (damageable.hasMaxDamage()) { + return new ElementTag(damageable.getMaxDamage()); + } + else { + return new ElementTag(getItemStack().getType().getMaxDurability()); + } + } + return null; + } + + @Override + public void setPropertyValue(ElementTag element, Mechanism mechanism) { + editMeta(ItemMeta.class, meta -> { + if (meta instanceof Damageable damageable) { + if (element == null) { + damageable.setMaxDamage((int) getItemStack().getType().getMaxDurability()); + } + else if (mechanism.requireInteger()) { + damageable.setMaxDamage(element.asInt()); + } + } + }); + } + + @Override + public String getPropertyId() { + return "max_durability"; + } + + public static void register() { + autoRegisterNullable("max_durability", ItemMaxDurability.class, ElementTag.class, false); + } +} diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemMaxStackSize.java b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemMaxStackSize.java new file mode 100644 index 0000000000..f350662d56 --- /dev/null +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemMaxStackSize.java @@ -0,0 +1,53 @@ +package com.denizenscript.denizen.objects.properties.item; + +import com.denizenscript.denizen.objects.ItemTag; +import com.denizenscript.denizencore.objects.Mechanism; +import com.denizenscript.denizencore.objects.core.ElementTag; +import org.bukkit.Material; +import org.bukkit.inventory.meta.ItemMeta; + +public class ItemMaxStackSize extends ItemProperty { + + // <--[property] + // @object ItemTag + // @name max_stack_size + // @input ElementTag + // @description + // Controls the maximum stack size of the item. + // @mechanism + // Provide no input to reset the max stack size to the default for the item type. + // --> + + public static boolean describes(ItemTag item) { + return item.getBukkitMaterial() != Material.AIR; + } + + @Override + public ElementTag getPropertyValue() { + if (getItemMeta().hasMaxStackSize()) { + return new ElementTag(getItemMeta().getMaxStackSize()); + } + return null; + } + + @Override + public void setPropertyValue(ElementTag element, Mechanism mechanism) { + editMeta(ItemMeta.class, meta -> { + if (element == null) { + meta.setMaxStackSize(getItemStack().getType().getMaxStackSize()); + } + else { + meta.setMaxStackSize(element.asInt()); + } + }); + } + + @Override + public String getPropertyId() { + return "max_stack_size"; + } + + public static void register() { + autoRegisterNullable("max_stack_size", ItemMaxStackSize.class, ElementTag.class, false); + } +} diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemModel.java b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemModel.java new file mode 100644 index 0000000000..1266007165 --- /dev/null +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemModel.java @@ -0,0 +1,54 @@ +package com.denizenscript.denizen.objects.properties.item; + +import com.denizenscript.denizen.objects.ItemTag; +import com.denizenscript.denizen.utilities.Utilities; +import com.denizenscript.denizencore.objects.Mechanism; +import com.denizenscript.denizencore.objects.core.ElementTag; +import org.bukkit.Material; +import org.bukkit.inventory.meta.ItemMeta; + +public class ItemModel extends ItemProperty { + + // <--[property] + // @object ItemTag + // @name item_model + // @input ElementTag + // @description + // Controls the item model of the item in namespaced key format, if any. + // @mechanism + // Provide no input to remove the item model component from the item. + // --> + + public static boolean describes(ItemTag item) { + return item.getBukkitMaterial() != Material.AIR; + } + + @Override + public ElementTag getPropertyValue() { + if (getItemMeta().hasItemModel()) { + return new ElementTag(Utilities.namespacedKeyToString(getItemMeta().getItemModel())); + } + return null; + } + + @Override + public void setPropertyValue(ElementTag element, Mechanism mechanism) { + editMeta(ItemMeta.class, meta -> { + if (element == null) { + meta.setItemModel(null); + } + else { + meta.setItemModel(Utilities.parseNamespacedKey(element.toString())); + } + }); + } + + @Override + public String getPropertyId() { + return "item_model"; + } + + public static void register() { + autoRegisterNullable("item_model", ItemModel.class, ElementTag.class, false); + } +} diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemRarity.java b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemRarity.java new file mode 100644 index 0000000000..847f714c48 --- /dev/null +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/properties/item/ItemRarity.java @@ -0,0 +1,53 @@ +package com.denizenscript.denizen.objects.properties.item; + +import com.denizenscript.denizen.objects.ItemTag; +import com.denizenscript.denizen.utilities.Utilities; +import com.denizenscript.denizencore.objects.Mechanism; +import com.denizenscript.denizencore.objects.core.ElementTag; +import org.bukkit.Material; +import org.bukkit.inventory.meta.ItemMeta; + +public class ItemRarity extends ItemProperty { + + // <--[property] + // @object ItemTag + // @name rarity + // @input ElementTag + // @description + // Controls the rarity of the item. + // Valid rarities are: 'COMMON', 'UNCOMMON', 'RARE', and 'EPIC'. + // @mechanism + // Provide no input to reset the rarity to the default for the item type. + // --> + + public static boolean describes(ItemTag item) { + return item.getBukkitMaterial() != Material.AIR; + } + + @Override + public ElementTag getPropertyValue() { + if (getItemMeta().hasRarity()) { + return Utilities.enumlikeToElement(getItemMeta().getRarity()); + } + return null; + } + + @Override + public void setPropertyValue(ElementTag element, Mechanism mechanism) { + if (element == null) { + editMeta(ItemMeta.class, meta -> meta.setRarity(getItemMeta().getRarity())); + } + else if (mechanism.requireEnum(org.bukkit.inventory.ItemRarity.class)) { + editMeta(ItemMeta.class, meta -> meta.setRarity(element.asEnum(org.bukkit.inventory.ItemRarity.class))); + } + } + + @Override + public String getPropertyId() { + return "rarity"; + } + + public static void register() { + autoRegisterNullable("rarity", ItemRarity.class, ElementTag.class, false); + } +}