24package com.dreamfirestudios.dreamcore.DreamItems;
26import net.kyori.adventure.text.Component;
27import org.bukkit.Material;
28import org.bukkit.NamespacedKey;
29import org.bukkit.enchantments.Enchantment;
30import org.bukkit.inventory.Inventory;
31import org.bukkit.inventory.ItemStack;
32import org.bukkit.inventory.meta.ItemMeta;
33import org.bukkit.persistence.PersistentDataContainer;
34import org.bukkit.persistence.PersistentDataType;
35import org.bukkit.plugin.Plugin;
38import java.util.function.Function;
75 public static NamespacedKey
keyId(Plugin plugin) {
76 return new NamespacedKey(plugin,
"dream_item_id");
99 Objects.requireNonNull(plugin,
"plugin");
100 Objects.requireNonNull(def,
"definition");
102 ItemStack stack =
new ItemStack(def.
type(), Math.max(1, def.
amount()));
103 ItemMeta meta = stack.getItemMeta();
107 if (name !=
null) meta.displayName(name);
110 List<Component> lore = def.
lore();
111 if (lore !=
null && !lore.isEmpty()) meta.lore(lore);
118 Set<?> flags = def.
flags();
119 if (flags !=
null && !flags.isEmpty()) {
120 meta.addItemFlags(def.
flags().toArray(
new org.bukkit.inventory.ItemFlag[0]));
125 if (attrs !=
null && !attrs.isEmpty()) {
127 if (attr ==
null || mods ==
null)
return;
128 for (var mod : mods)
if (mod !=
null) meta.addAttributeModifier(attr, mod);
133 PersistentDataContainer pdc = meta.getPersistentDataContainer();
134 def.
id().ifPresent(
id -> pdc.set(
keyId(plugin), PersistentDataType.STRING, id));
137 stack.setItemMeta(meta);
141 if (ench !=
null && !ench.isEmpty()) {
142 ench.forEach((e, lvl) -> {
143 if (e !=
null && lvl !=
null && lvl > 0) stack.addUnsafeEnchantment(e, lvl);
165 public static Optional<String>
readId(Plugin plugin, ItemStack stack) {
166 if (stack ==
null || stack.getType() == Material.AIR)
return Optional.empty();
167 ItemMeta meta = stack.getItemMeta();
168 if (meta ==
null)
return Optional.empty();
169 String
id = meta.getPersistentDataContainer().get(
keyId(plugin), PersistentDataType.STRING);
170 return Optional.ofNullable(
id);
191 Function<String, IDreamItemStack> registryLookup
193 Objects.requireNonNull(registryLookup,
"registryLookup");
194 return readId(plugin, stack).map(registryLookup);
212 Collection<IDreamItemStack> registry
214 Optional<String>
id =
readId(plugin, stack);
215 if (
id.isEmpty())
return Optional.empty();
216 String key =
id.get();
218 if (def !=
null && def.id().isPresent() && def.id().get().equals(key))
return Optional.of(def);
220 return Optional.empty();
243 public static boolean isSame(Plugin plugin, ItemStack a, ItemStack b) {
244 if (a == b)
return true;
245 if (a ==
null || b ==
null)
return false;
247 Optional<String> idA =
readId(plugin, a);
248 Optional<String> idB =
readId(plugin, b);
249 if (idA.isPresent() && idB.isPresent()) {
250 return idA.get().equals(idB.get());
252 return a.isSimilar(b);
267 public static int count(Plugin plugin, Inventory inv, ItemStack probe) {
268 Objects.requireNonNull(inv,
"inventory");
269 Objects.requireNonNull(probe,
"probe");
271 for (ItemStack s : inv.getContents()) {
272 if (s ==
null)
continue;
273 if (
isSame(plugin, s, probe)) total += s.getAmount();
289 public static int count(Inventory inv, Material material) {
290 Objects.requireNonNull(inv,
"inventory");
291 Objects.requireNonNull(material,
"material");
293 for (ItemStack s : inv.getContents()) {
294 if (s ==
null)
continue;
295 if (s.getType() == material) total += s.getAmount();
Utilities for building, resolving, comparing, and counting custom items.
static boolean isSame(Plugin plugin, ItemStack a, ItemStack b)
Safer equality check for items:
static int count(Inventory inv, Material material)
Counts items by Material (null-safe).
static Optional< IDreamItemStack > resolveById(Plugin plugin, ItemStack stack, Collection< IDreamItemStack > registry)
Resolves a definition by scanning a collection for a matching ID.
static ItemStack build(Plugin plugin, IDreamItemStack def)
Builds an ItemStack from a definition and writes its ID (if any) to PDC.
static Optional< String > readId(Plugin plugin, ItemStack stack)
Reads the stored item ID from PDC, if present.
static Optional< IDreamItemStack > resolveById(Plugin plugin, ItemStack stack, Function< String, IDreamItemStack > registryLookup)
Resolves a definition by PDC ID using a registry lookup function.
static NamespacedKey keyId(Plugin plugin)
Generates the PDC key used to store the optional custom item ID.
static int count(Plugin plugin, Inventory inv, ItemStack probe)
Counts how many items equivalent to probe exist in an inventory.
Definition for a custom item.
default List< Component > lore()
Lore lines (Adventure).
default Optional< String > id()
Optional stable ID.
default Material type()
Base material type for the item.
default Map< Attribute, Collection< AttributeModifier > > attributeModifiers()
Attribute modifiers.
default Component displayName()
Display name (Adventure).
default Set< ItemFlag > flags()
Item flags to apply (e.g., hide attributes).
default int amount()
Initial stack amount (clamped to ≥ 1).
default void writePdc(Plugin plugin, PersistentDataContainer pdc)
Hook to write any custom Persistent Data Container values.
default Map< Enchantment, Integer > enchantments()
Enchantments to apply after meta is set.
default OptionalInt customModelData()
Optional custom model data.
default boolean unbreakable()
Whether the item is unbreakable.