001package net.tnemc.item;
002
003/*
004 * The New Item Library Minecraft Server Plugin
005 *
006 * Copyright (C) 2022 - 2025 Daniel "creatorfromhell" Vidmar
007 *
008 * This program is free software; you can redistribute it and/or
009 * modify it under the terms of the GNU Lesser General Public
010 * License as published by the Free Software Foundation; either
011 * version 3 of the License, or (at your option) any later version.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
016 * Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public License
019 * along with this program; if not, write to the Free Software Foundation,
020 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
021 */
022
023import net.kyori.adventure.text.Component;
024import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
025import net.tnemc.item.component.SerialComponent;
026import net.tnemc.item.component.helper.AttributeModifier;
027import net.tnemc.item.component.helper.BlockPredicate;
028import net.tnemc.item.component.helper.EquipSlot;
029import net.tnemc.item.component.helper.ExplosionData;
030import net.tnemc.item.component.helper.ItemDamage;
031import net.tnemc.item.component.helper.PatternData;
032import net.tnemc.item.component.helper.ToolRule;
033import net.tnemc.item.component.helper.effect.ComponentEffect;
034import net.tnemc.item.component.helper.effect.EffectInstance;
035import net.tnemc.item.component.impl.AttributeModifiersComponent;
036import net.tnemc.item.component.impl.BannerPatternsComponent;
037import net.tnemc.item.component.impl.BaseColorComponent;
038import net.tnemc.item.component.impl.BlocksAttacksComponent;
039import net.tnemc.item.component.impl.BreakSoundComponent;
040import net.tnemc.item.component.impl.BucketEntityDataComponent;
041import net.tnemc.item.component.impl.BundleComponent;
042import net.tnemc.item.component.impl.CanBreakComponent;
043import net.tnemc.item.component.impl.CanPlaceOnComponent;
044import net.tnemc.item.component.impl.ConsumableComponent;
045import net.tnemc.item.component.impl.ContainerComponent;
046import net.tnemc.item.component.impl.CustomNameComponent;
047import net.tnemc.item.component.impl.DamageComponent;
048import net.tnemc.item.component.impl.DamageResistantComponent;
049import net.tnemc.item.component.impl.DeathProtectionComponent;
050import net.tnemc.item.component.impl.DyedColorComponent;
051import net.tnemc.item.component.impl.EnchantableComponent;
052import net.tnemc.item.component.impl.EnchantmentGlintOverrideComponent;
053import net.tnemc.item.component.impl.EnchantmentsComponent;
054import net.tnemc.item.component.impl.EntityVariantComponent;
055import net.tnemc.item.component.impl.EquipComponent;
056import net.tnemc.item.component.impl.FireworkExplosionComponent;
057import net.tnemc.item.component.impl.FireworksComponent;
058import net.tnemc.item.component.impl.FoodComponent;
059import net.tnemc.item.component.impl.GliderComponent;
060import net.tnemc.item.component.impl.HideAdditionalTooltipComponent;
061import net.tnemc.item.component.impl.HideTooltipComponent;
062import net.tnemc.item.component.impl.InstrumentComponent;
063import net.tnemc.item.component.impl.IntangibleProjectileComponent;
064import net.tnemc.item.component.impl.ItemModelComponent;
065import net.tnemc.item.component.impl.ItemNameComponent;
066import net.tnemc.item.component.impl.JukeBoxComponent;
067import net.tnemc.item.component.impl.LodestoneTrackerComponent;
068import net.tnemc.item.component.impl.LoreComponent;
069import net.tnemc.item.component.impl.MapColorComponent;
070import net.tnemc.item.component.impl.MapIDComponent;
071import net.tnemc.item.component.impl.MaxDamageComponent;
072import net.tnemc.item.component.impl.MaxStackSizeComponent;
073import net.tnemc.item.component.impl.ModelDataComponent;
074import net.tnemc.item.component.impl.ModelDataOldComponent;
075import net.tnemc.item.component.impl.NoteBlockSoundComponent;
076import net.tnemc.item.component.impl.OminousBottleAmplifierComponent;
077import net.tnemc.item.component.impl.PotDecorationsComponent;
078import net.tnemc.item.component.impl.PotionContentsComponent;
079import net.tnemc.item.component.impl.PotionDurationScaleComponent;
080import net.tnemc.item.component.impl.ProfileComponent;
081import net.tnemc.item.component.impl.ProvidesBannerPatternsComponent;
082import net.tnemc.item.component.impl.ProvidesTrimMaterialComponent;
083import net.tnemc.item.component.impl.RarityComponent;
084import net.tnemc.item.component.impl.RecipesComponent;
085import net.tnemc.item.component.impl.RepairCostComponent;
086import net.tnemc.item.component.impl.RepairableComponent;
087import net.tnemc.item.component.impl.StoredEnchantmentsComponent;
088import net.tnemc.item.component.impl.SuspiciousStewEffectsComponent;
089import net.tnemc.item.component.impl.ToolComponent;
090import net.tnemc.item.component.impl.TooltipDisplayComponent;
091import net.tnemc.item.component.impl.TooltipStyleComponent;
092import net.tnemc.item.component.impl.TrimComponent;
093import net.tnemc.item.component.impl.UnbreakableComponent;
094import net.tnemc.item.component.impl.UseCooldownComponent;
095import net.tnemc.item.component.impl.WeaponComponent;
096import net.tnemc.item.component.impl.WritableBookContentComponent;
097import net.tnemc.item.component.impl.WrittenBookContentComponent;
098import net.tnemc.item.persistent.PersistentDataHolder;
099import net.tnemc.item.persistent.PersistentDataType;
100import net.tnemc.item.providers.ItemProvider;
101import net.tnemc.item.providers.SkullProfile;
102import org.json.simple.JSONObject;
103import org.json.simple.parser.ParseException;
104
105import java.util.HashSet;
106import java.util.LinkedList;
107import java.util.List;
108import java.util.Map;
109import java.util.Optional;
110import java.util.Set;
111import java.util.UUID;
112
113/**
114 * Represents a generic abstraction for an item stack with various attributes and properties.
115 * This interface allows for chaining multiple properties and supports serialization.
116 *
117 * @param <T> The implementation-specific type of this item stack.
118 * @author creatorfromhell
119 */
120public interface AbstractItemStack<T> extends Cloneable {
121
122  /**
123   * Creates a new item stack with the specified material and amount.
124   *
125   * @param material The material of the item.
126   * @param amount   The number of items in the stack.
127   * @return A new item stack instance.
128   * @since 0.2.0.0
129   * @author creatorfromhell
130   */
131  AbstractItemStack<T> of(final String material, final int amount);
132
133  /**
134   * Creates a new item stack from a locale-specific object.
135   *
136   * @param locale The locale-specific representation.
137   * @return A new item stack instance.
138   * @since 0.2.0.0
139   * @author creatorfromhell
140   */
141  AbstractItemStack<T> of(T locale);
142
143  /**
144   * Creates a new item stack from a JSON representation.
145   *
146   * @param json The JSON object containing item stack data.
147   * @return A new item stack instance.
148   * @since 0.2.0.0
149   * @author creatorfromhell
150   * @throws ParseException If the JSON structure is invalid.
151   */
152  AbstractItemStack<T> of(JSONObject json) throws ParseException;
153
154  /**
155   * Sets the item flags.
156   *
157   * @param flags A list of flags to apply to the item.
158   * @return The updated item stack instance.
159   * @since 0.2.0.0
160   * @author creatorfromhell
161   */
162  AbstractItemStack<T> flags(List<String> flags);
163
164  /**
165   * Sets the lore (descriptive text) of the item stack.
166   *
167   * @param lore A list of components representing the lore.
168   * @return The updated item stack instance.
169   * @since 0.2.0.0
170   * @author creatorfromhell
171   */
172  AbstractItemStack<T> loreComponent(List<Component> lore);
173
174  /**
175   * Adds an enchantment to the item stack.
176   *
177   * @param enchantment The enchantment name.
178   * @param level       The level of the enchantment.
179   * @return The updated item stack instance.
180   * @since 0.2.0.0
181   * @author creatorfromhell
182   */
183  AbstractItemStack<T> enchant(String enchantment, int level);
184
185  /**
186   * Adds multiple enchantments to the item stack.
187   *
188   * @param enchantments A map of enchantment names and levels.
189   * @return The updated item stack instance.
190   * @since 0.2.0.0
191   * @author creatorfromhell
192   */
193  AbstractItemStack<T> enchant(Map<String, Integer> enchantments);
194
195  /**
196   * Adds enchantments to the item stack by name.
197   *
198   * @param enchantments A list of enchantment names.
199   * @return The updated item stack instance.
200   * @since 0.2.0.0
201   * @author creatorfromhell
202   */
203  AbstractItemStack<T> enchant(List<String> enchantments);
204
205  /**
206   * Returns the material of the item stack.
207   *
208   * @return The material of the item stack.
209   * @since 0.2.0.0
210   * @author creatorfromhell
211   */
212  String material();
213
214  /**
215   * Sets the material of the item stack.
216   *
217   * @param material The material name.
218   * @return The updated item stack instance.
219   * @since 0.2.0.0
220   * @author creatorfromhell
221   */
222  AbstractItemStack<T> material(String material);
223
224  /**
225   * The quantity of the item stack.
226   *
227   * @return the quantity of the item stack.
228   * @since 0.2.0.0
229   * @author creatorfromhell
230   */
231  int amount();
232
233  /**
234   * Sets the quantity of the item stack.
235   *
236   * @param amount The number of items in the stack.
237   * @return The updated item stack instance.
238   * @since 0.2.0.0
239   * @author creatorfromhell
240   */
241  AbstractItemStack<T> amount(final int amount);
242
243  /**
244   * Subtracts the specified amount from the current item stack.
245   *
246   * @param amount the amount to subtract from the item stack
247   * @return a new item stack with the specified amount subtracted
248   * @since 0.2.0.0
249   * @author creatorfromhell
250   */
251  default AbstractItemStack<T> subtract(final int amount) {
252
253    return amount(amount() - amount);
254  }
255
256  /**
257   * Adds the specified amount to the current amount of this item stack.
258   *
259   * @param amount the amount to be added to the item stack
260   * @return a new AbstractItemStack with the updated amount
261   * @since 0.2.0.0
262   * @author creatorfromhell
263   */
264  default AbstractItemStack<T> add(final int amount) {
265
266    return amount(amount() + amount);
267  }
268
269  /**
270   * Represents the inventory slot of the item stack.
271   *
272   * @return the inventory slot of the item stack.
273   * @since 0.2.0.0
274   * @author creatorfromhell
275   */
276  int slot();
277
278  /**
279   * Sets the inventory slot of the item stack.
280   *
281   * @param slot The slot index.
282   * @return The updated item stack instance.
283   * @since 0.2.0.0
284   * @author creatorfromhell
285   */
286  AbstractItemStack<T> slot(int slot);
287
288  /**
289   * Enables or disables debug mode for the item stack.
290   *
291   * @param debug True to enable, false to disable.
292   * @return The updated item stack instance.
293   * @since 0.2.0.0
294   * @author creatorfromhell
295   */
296  AbstractItemStack<T> debug(boolean debug);
297
298  /**
299   * Checks if a component with the specified identifier is present.
300   *
301   * @param identifier The identifier of the component to check.
302   * @return true if a component with the specified identifier is present, false otherwise.
303   */
304  default boolean hasComponent(final String identifier) {
305
306    return components().containsKey(identifier);
307  }
308
309  /**
310   * Applies a serialized component to the item stack.
311   *
312   * @param component The component to apply.
313   * @return The updated item stack instance.
314   * @since 0.2.0.0
315   * @author creatorfromhell
316   */
317  default <C extends SerialComponent<? extends AbstractItemStack<T>, T>> AbstractItemStack<T> applyComponent(final C component) {
318
319    components().put(component.identifier(), component);
320    return this;
321  }
322
323  /**
324   * Retrieves a SerialComponent associated with the specified identifier.
325   *
326   * @param identifier the identifier of the SerialComponent to retrieve
327   * @return an Optional containing the SerialComponent if found, empty Optional otherwise
328   * @since 0.2.0.0
329   * @author creatorfromhell
330   */
331  default <C extends SerialComponent<? extends AbstractItemStack<T>, T>> Optional<C> component(final String identifier) {
332    return (Optional<C>)Optional.ofNullable(components().get(identifier));
333  }
334
335  /**
336   * Applies persistent data to the item stack.
337   *
338   * @param data The persistent data to apply.
339   * @return The updated item stack instance.
340   * @since 0.2.0.0
341   * @author creatorfromhell
342   */
343  default AbstractItemStack<T> applyPersistent(final PersistentDataType<?> data) {
344    persistentHolder().getData().put(data.identifier(), data);
345    return this;
346  }
347
348  /**
349   * Replaces the persistent data holder for the item stack.
350   *
351   * @param newHolder The new persistent data holder.
352   * @param replaceOld True to replace existing data, false to merge.
353   * @return The updated item stack instance.
354   * @since 0.2.0.0
355   * @author creatorfromhell
356   */
357  AbstractItemStack<T> applyPersistentHolder(final PersistentDataHolder newHolder, boolean replaceOld);
358
359  /**
360   * Retrieves the item flags.
361   *
362   * @return A list of flags applied to the item.
363   * @since 0.2.0.0
364   * @author creatorfromhell
365   */
366  List<String> flags();
367
368  /**
369   * Retrieves the components applied to the item stack.
370   *
371   * @return A map of component types and their serialized representations.
372   * @since 0.2.0.0
373   * @author creatorfromhell
374   */
375  <C extends SerialComponent<? extends AbstractItemStack<T>, T>> Map<String, C> components();
376
377  /**
378   * Retrieves the persistent data holder for the item stack.
379   *
380   * @return The persistent data holder.
381   * @since 0.2.0.0
382   * @author creatorfromhell
383   */
384  PersistentDataHolder persistentHolder();
385
386  /**
387   * Resets the dirty flag, indicating that the object's state has been synchronized with the database.
388   */
389  void resetDirty();
390
391  /**
392   * Marks the item stack as dirty, indicating changes have been made.
393   */
394  void markDirty();
395
396  /**
397   * Checks whether the object is dirty or has unsaved changes.
398   *
399   * @return true if the object is dirty, false otherwise
400   */
401  boolean isDirty();
402
403  /**
404   * This method returns a String representing the item provider.
405   *
406   * @see net.tnemc.item.providers.ItemProvider
407   * @return the item provider as a String
408   */
409  String itemProvider();
410
411  /**
412   * Sets the item provider to be used for retrieving items.
413   *
414   * @param itemProvider the string representing the item provider to be set
415   */
416  AbstractItemStack<T> setItemProvider(final String itemProvider);
417
418  /**
419   * Retrieves the provider item ID associated with the current object.
420   *
421   * @return The provider item ID of the object.
422   */
423  String providerItemID();
424
425  /**
426   * Sets the provider's item ID for the current item.
427   *
428   * @param providerItemID the unique ID assigned by the provider for the item
429   */
430  AbstractItemStack<T> setProviderItemID(final String providerItemID);
431
432  /**
433   * This method is used to return an ItemProvider object.
434   *
435   * @return ItemProvider object representing the item provider.
436   */
437  ItemProvider<T> provider();
438
439  /**
440   * Converts the object to a JSONObject representation.
441   *
442   * @return A JSONObject representing the object data.
443   * @since 0.2.0.0
444   * @author creatorfromhell
445   */
446  JSONObject toJSON();
447
448  //Our component getters/setters
449  /**
450   * Retrieves the AttributeModifiersComponent of the item stack if present.
451   *
452   * @return an Optional containing the AttributeModifiersComponent if it exists
453   * @since 0.2.0.0
454   * @author creatorfromhell
455   * @see AttributeModifiersComponent
456   */
457  default Optional<AttributeModifiersComponent<AbstractItemStack<T>, T>> attributeModifiers() {
458    return Optional.ofNullable((AttributeModifiersComponent<AbstractItemStack<T>, T>) components().get("attribute_modifiers"));
459  }
460
461  /**
462   * Updates the attribute modifiers of the item stack.
463   *
464   * @param modifiers     a list of attribute modifiers
465   * @param showInTooltip whether to display the modifiers in the tooltip
466   * @return the updated AbstractItemStack instance
467   * @since 0.2.0.0
468   * @author creatorfromhell
469   * @see AttributeModifiersComponent
470   */
471  AbstractItemStack<T> attributeModifiers(List<AttributeModifier> modifiers, boolean showInTooltip);
472
473  /**
474   * Retrieves the BannerPatternsComponent of the item stack if present.
475   *
476   * @return an Optional containing the BannerPatternsComponent if it exists
477   * @since 0.2.0.0
478   * @author creatorfromhell
479   * @see BannerPatternsComponent
480   */
481  default Optional<BannerPatternsComponent<AbstractItemStack<T>, T>> bannerPatterns() {
482    return Optional.ofNullable((BannerPatternsComponent<AbstractItemStack<T>, T>) components().get("banner_patterns"));
483  }
484
485  /**
486   * Updates the banner patterns of the item stack.
487   *
488   * @param patterns a list of pattern data
489   * @return the updated AbstractItemStack instance
490   * @since 0.2.0.0
491   * @author creatorfromhell
492   * @see BannerPatternsComponent
493   */
494  AbstractItemStack<T> bannerPatterns(List<PatternData> patterns);
495
496  /**
497   * Retrieves the BaseColorComponent of the item stack if present.
498   *
499   * @return an Optional containing the BaseColorComponent if it exists
500   * @since 0.2.0.0
501   * @author creatorfromhell
502   * @see BaseColorComponent
503   */
504  default Optional<BaseColorComponent<AbstractItemStack<T>, T>> baseColor() {
505    return Optional.ofNullable((BaseColorComponent<AbstractItemStack<T>, T>) components().get("base_color"));
506  }
507
508  /**
509   * Updates the base color of the item stack.
510   *
511   * @param color the new base color
512   * @return the updated AbstractItemStack instance
513   * @since 0.2.0.0
514   * @author creatorfromhell
515   * @see BaseColorComponent
516   */
517  AbstractItemStack<T> baseColor(String color);
518
519  /**
520   * Retrieves the BlocksAttacksComponent associated with this method.
521   *
522   * @return an Optional containing the BlocksAttacksComponent if found, otherwise an empty Optional
523   * @since 0.2.0.0
524   * @author creatorfromhell
525   * @see BlocksAttacksComponent
526   */
527  default Optional<BlocksAttacksComponent<AbstractItemStack<T>, T>> blocksAttacks() {
528    return Optional.ofNullable((BlocksAttacksComponent<AbstractItemStack<T>, T>) components().get("blocks_attacks"));
529  }
530
531  /**
532   * Blocks attacks with the specified damage type using this item.
533   *
534   * @param damage the type of damage to block attacks from
535   * @return an AbstractItemStack object representing the item after blocking attacks
536   * @since 0.2.0.0
537   * @author creatorfromhell
538   * @see BlocksAttacksComponent
539   */
540  AbstractItemStack<T> blocksAttacks(ItemDamage damage);
541
542  /**
543   * Retrieves the break sound component associated with the object.
544   *
545   * @return an Optional containing the BreakSoundComponent if it exists, else an empty Optional
546   * @since 0.2.0.0
547   * @author creatorfromhell
548   * @see BreakSoundComponent
549   */
550  default Optional<BreakSoundComponent<AbstractItemStack<T>, T>> breakSound() {
551    return Optional.ofNullable((BreakSoundComponent<AbstractItemStack<T>, T>) components().get("break_sound"));
552  }
553
554  /**
555   * Set the break sound for this item stack.
556   *
557   * @param sound the sound to be played when the item is broken
558   * @return the updated item stack object
559   * @since 0.2.0.0
560   * @author creatorfromhell
561   * @see BreakSoundComponent
562   */
563  AbstractItemStack<T> breakSound(final String sound);
564
565  /**
566   * Retrieves the BucketEntityDataComponent of the item stack if present.
567   *
568   * @return an Optional containing the BucketEntityDataComponent if it exists
569   * @since 0.2.0.0
570   * @author creatorfromhell
571   * @see BucketEntityDataComponent
572   */
573  default Optional<BucketEntityDataComponent<AbstractItemStack<T>, T>> bucketEntityData() {
574    return Optional.ofNullable((BucketEntityDataComponent<AbstractItemStack<T>, T>) components().get("bucket_entity_data"));
575  }
576
577  /**
578   * Updates the bucket entity data of the item stack.
579   *
580   * @param noAI             whether the entity has AI disabled
581   * @param silent           whether the entity is silent
582   * @param noGravity        whether the entity is affected by gravity
583   * @param glowing          whether the entity is glowing
584   * @param invulnerable     whether the entity is invulnerable
585   * @param health           the health of the entity
586   * @param age              the age of the entity
587   * @param variant          the variant of the entity
588   * @param huntingCooldown  the hunting cooldown of the entity
589   * @param bucketVariantTag the variant tag of the bucket
590   * @param type             the type of the entity
591   * @return the updated AbstractItemStack instance
592   * @since 0.2.0.0
593   * @author creatorfromhell
594   * @see BucketEntityDataComponent
595   */
596  AbstractItemStack<T> bucketEntityData(boolean noAI, boolean silent, boolean noGravity, boolean glowing,
597                                              boolean invulnerable, float health, int age, int variant,
598                                              long huntingCooldown, int bucketVariantTag, String type);
599
600  /**
601   * Retrieves the bundle component from the components map.
602   *
603   * @return An Optional containing the BundleComponent of AbstractItemStack with type T,
604   *          or an empty Optional if the bundle component does not exist in the components map.
605   * @since 0.2.0.0
606   * @author creatorfromhell
607   * @see BundleComponent
608   */
609  default Optional<BundleComponent<AbstractItemStack<T>, T>> bundle() {
610    return Optional.ofNullable((BundleComponent<AbstractItemStack<T>, T>) components().get("bundle"));
611  }
612
613  /**
614   * Bundles a collection of {@link AbstractItemStack} instances into a single collection.
615   *
616   * @param items A {@link Map} containing integer keys and {@link AbstractItemStack} values to be bundled.
617   * @return An {@link AbstractItemStack} instance that represents the bundled items.
618   * @since 0.2.0.0
619   * @author creatorfromhell
620   * @see BundleComponent
621   */
622  AbstractItemStack<T> bundle(final Map<Integer, AbstractItemStack<T>> items);
623
624  /**
625   * Retrieves the CanBreakComponent of the item stack if present.
626   *
627   * @return an Optional containing the CanBreakComponent if it exists
628   * @since 0.2.0.0
629   * @author creatorfromhell
630   * @see CanBreakComponent
631   */
632  default Optional<CanBreakComponent<AbstractItemStack<T>, T>> canBreak() {
633    return Optional.ofNullable((CanBreakComponent<AbstractItemStack<T>, T>) components().get("can_break"));
634  }
635
636  /**
637   * Updates the blocks that the item stack can break.
638   *
639   * @param predicates a list of block predicates
640   * @return the updated AbstractItemStack instance
641   * @since 0.2.0.0
642   * @author creatorfromhell
643   * @see CanBreakComponent
644   */
645  AbstractItemStack<T> canBreak(List<BlockPredicate> predicates);
646
647  /**
648   * Retrieves the CanPlaceOnComponent of the item stack if present.
649   *
650   * @return an Optional containing the CanPlaceOnComponent if it exists
651   * @since 0.2.0.0
652   * @author creatorfromhell
653   * @see CanPlaceOnComponent
654   */
655  default Optional<CanPlaceOnComponent<AbstractItemStack<T>, T>> canPlaceOn() {
656    return Optional.ofNullable((CanPlaceOnComponent<AbstractItemStack<T>, T>) components().get("can_place_on"));
657  }
658
659  /**
660   * Updates the blocks that the item stack can be placed on.
661   *
662   * @param predicates a list of block predicates
663   * @return the updated AbstractItemStack instance
664   * @since 0.2.0.0
665   * @author creatorfromhell
666   * @see CanPlaceOnComponent
667   */
668  AbstractItemStack<T> canPlaceOn(List<BlockPredicate> predicates);
669
670  /**
671   * Retrieves the ConsumableComponent of the item stack if present.
672   *
673   * @return an Optional containing the ConsumableComponent if it exists
674   * @since 0.2.0.0
675   * @author creatorfromhell
676   * @see ConsumableComponent
677   */
678  default Optional<ConsumableComponent<AbstractItemStack<T>, T>> consumable() {
679    return Optional.ofNullable((ConsumableComponent<AbstractItemStack<T>, T>) components().get("consumable"));
680  }
681
682  /**
683   * Updates the consumable properties of the item stack.
684   *
685   * @param consumeSeconds     the time it takes to consume the item
686   * @param animation          the animation to display when consuming
687   * @param sound              the sound to play when consuming
688   * @param hasConsumeParticles whether to show consume particles
689   * @param effects            a list of effects applied on consumption
690   * @return the updated AbstractItemStack instance
691   * @since 0.2.0.0
692   * @author creatorfromhell
693   * @see ConsumableComponent
694   */
695  AbstractItemStack<T> consumable(float consumeSeconds, String animation, String sound, boolean hasConsumeParticles, List<ComponentEffect> effects);
696
697  /**
698   * Returns an {@link Optional} containing the {@link ContainerComponent} with type parameters {@link AbstractItemStack} and T stored in this container.
699   *
700   * @return an {@link Optional} object containing the {@link ContainerComponent} with type parameters {@link AbstractItemStack} and T, or an empty {@link Optional} if the component
701   *  is not found
702   * @since 0.2.0.0
703   * @author creatorfromhell
704   * @see ContainerComponent
705   */
706  default Optional<ContainerComponent<AbstractItemStack<T>, T>> container() {
707    return Optional.ofNullable((ContainerComponent<AbstractItemStack<T>, T>) components().get("container"));
708  }
709
710  /**
711   * Constructs a container with the given map of items.
712   *
713   * @param items a map of items where the key is the position of the item in the container and the value is the item
714   * @return an AbstractItemStack container with the specified items
715   * @since 0.2.0.0
716   * @author creatorfromhell
717   * @see ContainerComponent
718   */
719  AbstractItemStack<T> container(final Map<Integer, AbstractItemStack<T>> items);
720
721  /**
722   * Retrieves the CustomNameComponent of the item stack if present.
723   *
724   * @return an Optional containing the CustomNameComponent if it exists
725   * @since 0.2.0.0
726   * @author creatorfromhell
727   * @see CustomNameComponent
728   */
729  default Optional<CustomNameComponent<AbstractItemStack<T>, T>> customName() {
730    return Optional.ofNullable((CustomNameComponent<AbstractItemStack<T>, T>) components().get("custom_name"));
731  }
732
733  /**
734   * Updates the custom name of the item stack.
735   *
736   * @param customName the custom name to set
737   * @return the updated AbstractItemStack instance
738   * @since 0.2.0.0
739   * @author creatorfromhell
740   * @see CustomNameComponent
741   */
742  AbstractItemStack<T> customName(Component customName);
743
744  /**
745   * Retrieves the DamageComponent of the item stack if present.
746   *
747   * @return an Optional containing the DamageComponent if it exists
748   * @since 0.2.0.0
749   * @author creatorfromhell
750   * @see DamageComponent
751   */
752  default Optional<DamageComponent<AbstractItemStack<T>, T>> damage() {
753    return Optional.ofNullable((DamageComponent<AbstractItemStack<T>, T>) components().get("damage"));
754  }
755
756  /**
757   * Updates the damage of the item stack.
758   *
759   * @param damage the damage value to set
760   * @return the updated AbstractItemStack instance
761   * @since 0.2.0.0
762   * @author creatorfromhell
763   * @see DamageComponent
764   */
765  AbstractItemStack<T> damage(int damage);
766
767  /**
768   * Retrieves the DamageResistantComponent of the item stack if present.
769   *
770   * @return an Optional containing the DamageResistantComponent if it exists
771   * @since 0.2.0.0
772   * @author creatorfromhell
773   * @see DamageResistantComponent
774   */
775  default Optional<DamageResistantComponent<AbstractItemStack<T>, T>> damageResistant() {
776    return Optional.ofNullable((DamageResistantComponent<AbstractItemStack<T>, T>) components().get("damage_resistant"));
777  }
778
779  /**
780   * Updates the damage-resistant types of the item stack.
781   *
782   * @param types a list of damage-resistant types
783   * @return the updated AbstractItemStack instance
784   * @since 0.2.0.0
785   * @author creatorfromhell
786   * @see DamageResistantComponent
787   */
788  AbstractItemStack<T> damageResistant(List<String> types);
789
790  /**
791   * Retrieves the DeathProtectionComponent of the item stack if present.
792   *
793   * @return an Optional containing the DeathProtectionComponent if it exists
794   * @since 0.2.0.0
795   * @author creatorfromhell
796   * @see DeathProtectionComponent
797   */
798  default Optional<DeathProtectionComponent<AbstractItemStack<T>, T>> deathProtection() {
799    return Optional.ofNullable((DeathProtectionComponent<AbstractItemStack<T>, T>) components().get("death_protection"));
800  }
801
802  /**
803   * Updates the death protection effects of the item stack.
804   *
805   * @param deathEffects a list of death protection effects
806   * @return the updated AbstractItemStack instance
807   * @since 0.2.0.0
808   * @author creatorfromhell
809   * @see DeathProtectionComponent
810   */
811  AbstractItemStack<T> deathProtection(List<ComponentEffect> deathEffects);
812
813  /**
814   * Retrieves the DyedColorComponent of the item stack if present.
815   *
816   * @return an Optional containing the DyedColorComponent if it exists
817   * @since 0.2.0.0
818   * @author creatorfromhell
819   * @see DyedColorComponent
820   */
821  default Optional<DyedColorComponent<AbstractItemStack<T>, T>> dyedColor() {
822    return Optional.ofNullable((DyedColorComponent<AbstractItemStack<T>, T>) components().get("dyed_color"));
823  }
824
825  /**
826   * Updates the dyed color of the item stack.
827   *
828   * @param rgb the RGB color value to set
829   * @return the updated AbstractItemStack instance
830   * @since 0.2.0.0
831   * @author creatorfromhell
832   * @see DyedColorComponent
833   */
834  AbstractItemStack<T> dyedColor(int rgb);
835
836  /**
837   * Retrieves the EnchantableComponent of the item stack if present.
838   *
839   * @return an Optional containing the EnchantableComponent if it exists
840   * @since 0.2.0.0
841   * @author creatorfromhell
842   * @see EnchantableComponent
843   */
844  default Optional<EnchantableComponent<AbstractItemStack<T>, T>> enchantable() {
845    return Optional.ofNullable((EnchantableComponent<AbstractItemStack<T>, T>) components().get("enchantable"));
846  }
847
848  /**
849   * Updates the enchantability of the item stack.
850   *
851   * @param value the enchantability value to set
852   * @return the updated AbstractItemStack instance
853   * @since 0.2.0.0
854   * @author creatorfromhell
855   * @see EnchantableComponent
856   */
857  AbstractItemStack<T> enchantable(int value);
858
859  /**
860   * Retrieves the EnchantmentGlintOverrideComponent of the item stack if present.
861   *
862   * @return an Optional containing the EnchantmentGlintOverrideComponent if it exists
863   * @since 0.2.0.0
864   * @author creatorfromhell
865   * @see EnchantmentGlintOverrideComponent
866   */
867  default Optional<EnchantmentGlintOverrideComponent<AbstractItemStack<T>, T>> enchantmentGlintOverride() {
868    return Optional.ofNullable((EnchantmentGlintOverrideComponent<AbstractItemStack<T>, T>) components().get("enchantment_glint_override"));
869  }
870
871  /**
872   * Updates the enchantment glint override of the item stack.
873   *
874   * @param glintOverride whether the enchantment glint should be overridden
875   * @return the updated AbstractItemStack instance
876   * @since 0.2.0.0
877   * @author creatorfromhell
878   * @see EnchantmentGlintOverrideComponent
879   */
880  AbstractItemStack<T> enchantmentGlintOverride(boolean glintOverride);
881
882  /**
883   * Retrieves the EnchantmentsComponent of the item stack if present.
884   *
885   * @return an Optional containing the EnchantmentsComponent if it exists
886   * @since 0.2.0.0
887   * @author creatorfromhell
888   * @see EnchantmentsComponent
889   */
890  default Optional<EnchantmentsComponent<AbstractItemStack<T>, T>> enchantments() {
891    return Optional.ofNullable((EnchantmentsComponent<AbstractItemStack<T>, T>) components().get("enchantments"));
892  }
893
894  /**
895   * Updates the enchantments of the item stack.
896   *
897   * @param levels a map of enchantments and their levels
898   * @return the updated AbstractItemStack instance
899   * @since 0.2.0.0
900   * @author creatorfromhell
901   * @see EnchantmentsComponent
902   */
903  AbstractItemStack<T> enchantments(Map<String, Integer> levels);
904
905  /**
906   * Retrieves the Entity Variant Component for the current stack.
907   *
908   * @return An optional containing the Entity Variant Component if present in the components map, otherwise empty.
909   * @since 0.2.0.0
910   * @author creatorfromhell
911   * @see EntityVariantComponent
912   */
913  default Optional<EntityVariantComponent<AbstractItemStack<T>, T>> entityVariant() {
914    return Optional.ofNullable((EntityVariantComponent<AbstractItemStack<T>, T>) components().get("entity_variant"));
915  }
916
917  /**
918   * Generates an AbstractItemStack based on the given entity and variant.
919   *
920   * @param entity the entity name to create the stack for
921   * @param variant the variant of the entity
922   * @return an AbstractItemStack representing the entity with the specified variant
923   * @since 0.2.0.0
924   * @author creatorfromhell
925   * @see EntityVariantComponent
926   */
927  AbstractItemStack<T> entityVariant(final String entity, final String variant);
928
929  /**
930   * Retrieves the EquipComponent of the item stack if present.
931   *
932   * @return an Optional containing the EquipComponent if it exists
933   * @since 0.2.0.0
934   * @author creatorfromhell
935   * @see EquipComponent
936   */
937  default Optional<EquipComponent<AbstractItemStack<T>, T>> equip() {
938    return Optional.ofNullable((EquipComponent<AbstractItemStack<T>, T>) components().get("equip"));
939  }
940
941  /**
942   * Equips an item with specified parameters.
943   *
944   * @param cameraKey the key identifying the camera
945   * @param equipSound the key identifying the equip sound
946   * @param modelKey the key identifying the model
947   * @param slot the slot in which the item should be equipped
948   * @param damageOnHurt flag indicating if damage should be taken on hurt
949   * @param dispensable flag indicating if the item is dispensable
950   * @param swappable flag indicating if the item is swappable
951   * @param equipOnInteract flag indicating if the item should be equipped on interact
952   * @param entities a list of entities to be equipped
953   *
954   * @return an AbstractItemStack object representing the equipped item
955   * @since 0.2.0.0
956   * @author creatorfromhell
957   * @see EquipComponent
958   */
959  AbstractItemStack<T> equip(String cameraKey, String equipSound, String modelKey, EquipSlot slot,
960                                   boolean damageOnHurt, boolean dispensable, boolean swappable,
961                                   boolean equipOnInteract, List<String> entities);
962
963  /**
964   * Retrieves the FireworkExplosionComponent of the item stack if present.
965   *
966   * @return an Optional containing the FireworkExplosionComponent if it exists
967   * @since 0.2.0.0
968   * @author creatorfromhell
969   * @see FireworkExplosionComponent
970   */
971  default Optional<FireworkExplosionComponent<AbstractItemStack<T>, T>> fireworkExplosion() {
972    return Optional.ofNullable((FireworkExplosionComponent<AbstractItemStack<T>, T>) components().get("firework_explosion"));
973  }
974
975  /**
976   * Updates the firework explosion properties of the item stack.
977   *
978   * @param explosion the explosion data to set
979   * @return the updated AbstractItemStack instance
980   * @since 0.2.0.0
981   * @author creatorfromhell
982   * @see FireworkExplosionComponent
983   */
984  AbstractItemStack<T> fireworkExplosion(ExplosionData explosion);
985
986  /**
987   * Retrieves the FireworksComponent of the item stack if present.
988   *
989   * @return an Optional containing the FireworksComponent if it exists
990   * @since 0.2.0.0
991   * @author creatorfromhell
992   * @see FireworksComponent
993   */
994  default Optional<FireworksComponent<AbstractItemStack<T>, T>> fireworks() {
995    return Optional.ofNullable((FireworksComponent<AbstractItemStack<T>, T>) components().get("fireworks"));
996  }
997
998  /**
999   * Updates the fireworks properties of the item stack.
1000   *
1001   * @param flightDuration the flight duration of the fireworks
1002   * @param explosions     a list of explosion data
1003   * @return the updated AbstractItemStack instance
1004   * @since 0.2.0.0
1005   * @author creatorfromhell
1006   * @see FireworksComponent
1007   */
1008  AbstractItemStack<T> fireworks(byte flightDuration, List<ExplosionData> explosions);
1009
1010  /**
1011   * Retrieves the FoodComponent of the item stack if present.
1012   *
1013   * @return an Optional containing the FoodComponent if it exists
1014   * @since 0.2.0.0
1015   * @author creatorfromhell
1016   * @see FoodComponent
1017   */
1018  default Optional<FoodComponent<AbstractItemStack<T>, T>> food() {
1019    return Optional.ofNullable((FoodComponent<AbstractItemStack<T>, T>) components().get("food"));
1020  }
1021
1022  /**
1023   * Updates the food properties of the item stack.
1024   *
1025   * @param noHunger   whether the item causes no hunger
1026   * @param saturation the saturation value
1027   * @param nutrition  the nutrition value
1028   * @return the updated AbstractItemStack instance
1029   * @since 0.2.0.0
1030   * @author creatorfromhell
1031   * @see FoodComponent
1032   */
1033  AbstractItemStack<T> food(boolean noHunger, float saturation, int nutrition);
1034
1035  /**
1036   * Retrieves the GliderComponent of the item stack if present.
1037   *
1038   * @return an Optional containing the GliderComponent if it exists
1039   * @since 0.2.0.0
1040   * @author creatorfromhell
1041   * @see GliderComponent
1042   */
1043  default Optional<GliderComponent<AbstractItemStack<T>, T>> glider() {
1044    return Optional.ofNullable((GliderComponent<AbstractItemStack<T>, T>) components().get("glider"));
1045  }
1046
1047  /**
1048   * Updates the item stack to enable glider functionality.
1049   *
1050   * @return the updated AbstractItemStack instance
1051   * @since 0.2.0.0
1052   * @author creatorfromhell
1053   * @see GliderComponent
1054   */
1055  AbstractItemStack<T> gliderTag();
1056
1057  /**
1058   * Retrieves the HideAdditionalTooltipComponent of the item stack if present.
1059   *
1060   * @return an Optional containing the HideAdditionalTooltipComponent if it exists
1061   * @since 0.2.0.0
1062   * @author creatorfromhell
1063   * @see HideAdditionalTooltipComponent
1064   */
1065  default Optional<HideAdditionalTooltipComponent<AbstractItemStack<T>, T>> hideAdditionalTooltip() {
1066    return Optional.ofNullable((HideAdditionalTooltipComponent<AbstractItemStack<T>, T>) components().get("hide_additional_tooltip"));
1067  }
1068
1069  /**
1070   * Updates the item stack to hide additional tooltip.
1071   *
1072   * @return the updated AbstractItemStack instance
1073   * @since 0.2.0.0
1074   * @author creatorfromhell
1075   * @see HideAdditionalTooltipComponent
1076   */
1077  AbstractItemStack<T> hideAdditionalTooltipTag();
1078
1079  /**
1080   * Retrieves the HideTooltipComponent of the item stack if present.
1081   *
1082   * @return an Optional containing the HideTooltipComponent if it exists
1083   * @since 0.2.0.0
1084   * @author creatorfromhell
1085   * @see HideTooltipComponent
1086   */
1087  default Optional<HideTooltipComponent<AbstractItemStack<T>, T>> hideTooltip() {
1088    return Optional.ofNullable((HideTooltipComponent<AbstractItemStack<T>, T>) components().get("hide_tooltip"));
1089  }
1090
1091  /**
1092   * Updates the item stack to hide its tooltip.
1093   *
1094   * @return the updated AbstractItemStack instance
1095   * @since 0.2.0.0
1096   * @author creatorfromhell
1097   * @see HideTooltipComponent
1098   */
1099  AbstractItemStack<T> hideTooltipTag();
1100
1101  /**
1102   * Retrieves the InstrumentComponent of the item stack if present.
1103   *
1104   * @return an Optional containing the InstrumentComponent if it exists
1105   * @since 0.2.0.0
1106   * @author creatorfromhell
1107   * @see InstrumentComponent
1108   */
1109  default Optional<InstrumentComponent<AbstractItemStack<T>, T>> instrument() {
1110    return Optional.ofNullable((InstrumentComponent<AbstractItemStack<T>, T>) components().get("instrument"));
1111  }
1112
1113  /**
1114   * Updates the instrument properties of the item stack.
1115   *
1116   * @param soundEvent the sound event identifier
1117   * @param useDuration the duration of the sound in ticks
1118   * @param range the range of the sound
1119   * @return the updated AbstractItemStack instance
1120   * @since 0.2.0.0
1121   * @author creatorfromhell
1122   * @see InstrumentComponent
1123   */
1124  AbstractItemStack<T> instrument(String soundEvent, int useDuration, int range);
1125
1126  /**
1127   * Retrieves the IntangibleProjectileComponent of the item stack if present.
1128   *
1129   * @return an Optional containing the IntangibleProjectileComponent if it exists
1130   * @since 0.2.0.0
1131   * @author creatorfromhell
1132   * @see IntangibleProjectileComponent
1133   */
1134  default Optional<IntangibleProjectileComponent<AbstractItemStack<T>, T>> intangibleProjectile() {
1135    return Optional.ofNullable((IntangibleProjectileComponent<AbstractItemStack<T>, T>) components().get("intangible_projectile"));
1136  }
1137
1138  /**
1139   * Updates the item stack as an intangible projectile.
1140   *
1141   * @return the updated AbstractItemStack instance
1142   * @since 0.2.0.0
1143   * @author creatorfromhell
1144   * @see IntangibleProjectileComponent
1145   */
1146  AbstractItemStack<T> intangibleProjectileTag();
1147
1148  /**
1149   * Retrieves the ItemModelComponent of the item stack if present.
1150   *
1151   * @return an Optional containing the ItemModelComponent if it exists
1152   * @since 0.2.0.0
1153   * @author creatorfromhell
1154   * @see ItemModelComponent
1155   */
1156  default Optional<ItemModelComponent<AbstractItemStack<T>, T>> itemModel() {
1157    return Optional.ofNullable((ItemModelComponent<AbstractItemStack<T>, T>) components().get("item_model"));
1158  }
1159
1160  /**
1161   * Updates the model properties of the item stack.
1162   *
1163   * @param model the model identifier
1164   * @return the updated AbstractItemStack instance
1165   * @since 0.2.0.0
1166   * @author creatorfromhell
1167   * @see ItemModelComponent
1168   */
1169  AbstractItemStack<T> itemModel(String model);
1170
1171  /**
1172   * Retrieves the ItemNameComponent of the item stack if present.
1173   *
1174   * @return an Optional containing the ItemNameComponent if it exists
1175   * @since 0.2.0.0
1176   * @author creatorfromhell
1177   * @see ItemNameComponent
1178   */
1179  default Optional<ItemNameComponent<AbstractItemStack<T>, T>> itemName() {
1180    return Optional.ofNullable((ItemNameComponent<AbstractItemStack<T>, T>) components().get("item_name"));
1181  }
1182
1183  /**
1184   * Updates the name of the item stack.
1185   *
1186   * @param itemName the name of the item
1187   * @return the updated AbstractItemStack instance
1188   * @since 0.2.0.0
1189   * @author creatorfromhell
1190   * @see ItemNameComponent
1191   */
1192  AbstractItemStack<T> itemName(Component itemName);
1193
1194  /**
1195   * Retrieves the JukeBoxComponent of the item stack if present.
1196   *
1197   * @return an Optional containing the JukeBoxComponent if it exists
1198   * @since 0.2.0.0
1199   * @author creatorfromhell
1200   * @see JukeBoxComponent
1201   */
1202  default Optional<JukeBoxComponent<AbstractItemStack<T>, T>> jukebox() {
1203    return Optional.ofNullable((JukeBoxComponent<AbstractItemStack<T>, T>) components().get("jukebox"));
1204  }
1205
1206  /**
1207   * Updates the jukebox properties of the item stack.
1208   *
1209   * @param song the song identifier
1210   * @param showInTooltip whether to display the song in the tooltip
1211   * @return the updated AbstractItemStack instance
1212   * @since 0.2.0.0
1213   * @author creatorfromhell
1214   * @see JukeBoxComponent
1215   */
1216  AbstractItemStack<T> jukebox(String song, boolean showInTooltip);
1217
1218  /**
1219   * Retrieves the LodestoneTrackerComponent of the item stack if present.
1220   *
1221   * @return an Optional containing the LodestoneTrackerComponent if it exists
1222   * @since 0.2.0.0
1223   * @author creatorfromhell
1224   * @see LodestoneTrackerComponent
1225   */
1226  default Optional<LodestoneTrackerComponent<AbstractItemStack<T>, T>> lodestoneTracker() {
1227    return Optional.ofNullable((LodestoneTrackerComponent<AbstractItemStack<T>, T>) components().get("lodestone_tracker"));
1228  }
1229
1230  /**
1231   * Updates the lodestone tracker properties of the item stack.
1232   *
1233   * @param target the target identifier
1234   * @param pos the position array
1235   * @param dimension the dimension identifier
1236   * @param tracked whether the lodestone is tracked
1237   * @return the updated AbstractItemStack instance
1238   * @since 0.2.0.0
1239   * @author creatorfromhell
1240   * @see LodestoneTrackerComponent
1241   */
1242  AbstractItemStack<T> lodestoneTracker(String target, int[] pos, String dimension, boolean tracked);
1243
1244  /**
1245   * Retrieves the LoreComponent of the item stack if present.
1246   *
1247   * @return an Optional containing the LoreComponent if it exists
1248   * @since 0.2.0.0
1249   * @author creatorfromhell
1250   * @see LoreComponent
1251   */
1252  default Optional<LoreComponent<AbstractItemStack<T>, T>> lore() {
1253    return Optional.ofNullable((LoreComponent<AbstractItemStack<T>, T>) components().get("lore"));
1254  }
1255
1256  /**
1257   * Updates the lore of the item stack.
1258   *
1259   * @param lore a list of lore strings
1260   * @return the updated AbstractItemStack instance
1261   * @since 0.2.0.0
1262   * @author creatorfromhell
1263   * @see LoreComponent
1264   */
1265  AbstractItemStack<T> lore(List<Component> lore);
1266
1267  /**
1268   * Retrieves the MapColorComponent of the item stack if present.
1269   *
1270   * @return an Optional containing the MapColorComponent if it exists
1271   * @since 0.2.0.0
1272   * @author creatorfromhell
1273   * @see MapColorComponent
1274   */
1275  default Optional<MapColorComponent<AbstractItemStack<T>, T>> mapColor() {
1276    return Optional.ofNullable((MapColorComponent<AbstractItemStack<T>, T>) components().get("map_color"));
1277  }
1278
1279  /**
1280   * Updates the map color of the item stack.
1281   *
1282   * @param mapColor the map color value
1283   * @return the updated AbstractItemStack instance
1284   * @since 0.2.0.0
1285   * @author creatorfromhell
1286   * @see MapColorComponent
1287   */
1288  AbstractItemStack<T> mapColor(int mapColor);
1289
1290  /**
1291   * Retrieves the MapIDComponent of the item stack if present.
1292   *
1293   * @return an Optional containing the MapIDComponent if it exists
1294   * @since 0.2.0.0
1295   * @author creatorfromhell
1296   * @see MapIDComponent
1297   */
1298  default Optional<MapIDComponent<AbstractItemStack<T>, T>> mapId() {
1299    return Optional.ofNullable((MapIDComponent<AbstractItemStack<T>, T>) components().get("map_id"));
1300  }
1301
1302  /**
1303   * Updates the map ID of the item stack.
1304   *
1305   * @param mapId the map ID value
1306   * @return the updated AbstractItemStack instance
1307   * @since 0.2.0.0
1308   * @author creatorfromhell
1309   * @see MapIDComponent
1310   */
1311  AbstractItemStack<T> mapId(int mapId);
1312
1313  /**
1314   * Retrieves the MaxDamageComponent of the item stack if present.
1315   *
1316   * @return an Optional containing the MaxDamageComponent if it exists
1317   * @since 0.2.0.0
1318   * @author creatorfromhell
1319   * @see MaxDamageComponent
1320   */
1321  default Optional<MaxDamageComponent<AbstractItemStack<T>, T>> maxDamage() {
1322    return Optional.ofNullable((MaxDamageComponent<AbstractItemStack<T>, T>) components().get("max_damage"));
1323  }
1324
1325  /**
1326   * Updates the maximum damage of the item stack.
1327   *
1328   * @param maxDamage the maximum damage value
1329   * @return the updated AbstractItemStack instance
1330   * @since 0.2.0.0
1331   * @author creatorfromhell
1332   * @see MaxDamageComponent
1333   */
1334  AbstractItemStack<T> maxDamage(int maxDamage);
1335
1336  /**
1337   * Retrieves the MaxStackSizeComponent of the item stack if present.
1338   *
1339   * @return an Optional containing the MaxStackSizeComponent if it exists
1340   * @since 0.2.0.0
1341   * @author creatorfromhell
1342   * @see MaxStackSizeComponent
1343   */
1344  default Optional<MaxStackSizeComponent<AbstractItemStack<T>, T>> maxStackSize() {
1345    return Optional.ofNullable((MaxStackSizeComponent<AbstractItemStack<T>, T>) components().get("max_stack_size"));
1346  }
1347
1348  /**
1349   * Updates the maximum stack size of the item stack.
1350   *
1351   * @param maxStackSize the maximum stack size value
1352   * @return the updated AbstractItemStack instance
1353   * @since 0.2.0.0
1354   * @author creatorfromhell
1355   * @see MaxStackSizeComponent
1356   */
1357  AbstractItemStack<T> maxStackSize(int maxStackSize);
1358
1359  /**
1360   * Retrieves the ModelDataComponent of the item stack if present.
1361   *
1362   * @return an Optional containing the ModelDataComponent if it exists
1363   * @since 0.2.0.0
1364   * @author creatorfromhell
1365   * @see ModelDataComponent
1366   */
1367  default Optional<ModelDataComponent<AbstractItemStack<T>, T>> modelData() {
1368    return Optional.ofNullable((ModelDataComponent<AbstractItemStack<T>, T>) components().get("model-data"));
1369  }
1370
1371  /**
1372   * Updates the model data of the item stack.
1373   *
1374   * @param colours a list of color strings
1375   * @param floats  a list of float values
1376   * @param flags   a list of boolean flags
1377   * @param strings a list of string identifiers
1378   * @return the updated AbstractItemStack instance
1379   * @since 0.2.0.0
1380   * @author creatorfromhell
1381   * @see ModelDataComponent
1382   */
1383  AbstractItemStack<T> modelData(List<String> colours, List<Float> floats, List<Boolean> flags, List<String> strings);
1384
1385  /**
1386   * Retrieves the ModelDataOldComponent of the item stack if present.
1387   *
1388   * @return an Optional containing the ModelDataOldComponent if it exists
1389   * @deprecated Since MC 1.21.3 Use {@link ItemModelComponent} and {@link ModelDataComponent}.
1390   * @since 0.2.0.0
1391   * @author creatorfromhell
1392   * @see ModelDataComponent
1393   */
1394  default Optional<ModelDataOldComponent<AbstractItemStack<T>, T>> modelDataOld() {
1395    return Optional.ofNullable((ModelDataOldComponent<AbstractItemStack<T>, T>) components().get("model-data-old"));
1396  }
1397
1398  /**
1399   * Retrieves the model data for a custom item stack.
1400   *
1401   * @param customModelData the custom model data to retrieve
1402   * @return an AbstractItemStack with the specified custom model data
1403   * @deprecated Since MC 1.21.3 Use {@link ItemModelComponent} and {@link ModelDataComponent}.
1404   * @since 0.2.0.0
1405   * @author creatorfromhell
1406   * @see ModelDataOldComponent
1407   */
1408  AbstractItemStack<T> modelDataOld(int customModelData);
1409
1410  /**
1411   * Retrieves the NoteBlockSoundComponent of the item stack if present.
1412   *
1413   * @return an Optional containing the NoteBlockSoundComponent if it exists
1414   * @since 0.2.0.0
1415   * @author creatorfromhell
1416   * @see NoteBlockSoundComponent
1417   */
1418  default Optional<NoteBlockSoundComponent<AbstractItemStack<T>, T>> noteBlockSound() {
1419    return Optional.ofNullable((NoteBlockSoundComponent<AbstractItemStack<T>, T>) components().get("note_block_sound"));
1420  }
1421
1422  /**
1423   * Updates the note block sound of the item stack.
1424   *
1425   * @param soundId the identifier of the sound
1426   * @return the updated AbstractItemStack instance
1427   * @since 0.2.0.0
1428   * @author creatorfromhell
1429   * @see NoteBlockSoundComponent
1430   */
1431  AbstractItemStack<T> noteBlockSound(String soundId);
1432
1433  /**
1434   * Retrieves the OminousBottleAmplifierComponent of the item stack if present.
1435   *
1436   * @return an Optional containing the OminousBottleAmplifierComponent if it exists
1437   * @since 0.2.0.0
1438   * @author creatorfromhell
1439   * @see OminousBottleAmplifierComponent
1440   */
1441  default Optional<OminousBottleAmplifierComponent<AbstractItemStack<T>, T>> ominousBottleAmplifier() {
1442    return Optional.ofNullable((OminousBottleAmplifierComponent<AbstractItemStack<T>, T>) components().get("ominous_bottle_amplifier"));
1443  }
1444
1445  /**
1446   * Updates the ominous bottle amplifier of the item stack.
1447   *
1448   * @param amplifier the amplifier value
1449   * @return the updated AbstractItemStack instance
1450   * @since 0.2.0.0
1451   * @author creatorfromhell
1452   * @see OminousBottleAmplifierComponent
1453   */
1454  AbstractItemStack<T> ominousBottleAmplifier(int amplifier);
1455
1456  /**
1457   * Retrieves the PotDecorationsComponent of the item stack if present.
1458   *
1459   * @return an Optional containing the PotDecorationsComponent if it exists
1460   * @since 0.2.0.0
1461   * @author creatorfromhell
1462   * @see PotDecorationsComponent
1463   */
1464  default Optional<PotDecorationsComponent<AbstractItemStack<T>, T>> potDecorations() {
1465    return Optional.ofNullable((PotDecorationsComponent<AbstractItemStack<T>, T>) components().get("pot_decorations"));
1466  }
1467
1468  /**
1469   * Updates the pot decorations of the item stack.
1470   *
1471   * @param decorations a list of decorations
1472   * @return the updated AbstractItemStack instance
1473   * @since 0.2.0.0
1474   * @author creatorfromhell
1475   * @see PotDecorationsComponent
1476   */
1477  AbstractItemStack<T> potDecorations(List<String> decorations);
1478
1479  /**
1480   * Retrieves the PotionContentsComponent of the item stack if present.
1481   *
1482   * @return an Optional containing the PotionContentsComponent if it exists
1483   * @since 0.2.0.0
1484   * @author creatorfromhell
1485   * @see PotionContentsComponent
1486   */
1487  default Optional<PotionContentsComponent<AbstractItemStack<T>, T>> potionContents() {
1488    return Optional.ofNullable((PotionContentsComponent<AbstractItemStack<T>, T>) components().get("potion_contents"));
1489  }
1490
1491  /**
1492   * Updates the potion contents of the item stack.
1493   *
1494   * @param potionId   the ID of the potion
1495   * @param customColor the custom color of the potion
1496   * @param customName the custom name of the potion
1497   * @param effects    a list of effect instances
1498   * @return the updated AbstractItemStack instance
1499   * @since 0.2.0.0
1500   * @author creatorfromhell
1501   * @see PotionContentsComponent
1502   */
1503  AbstractItemStack<T> potionContents(String potionId, int customColor, String customName, List<EffectInstance> effects);
1504
1505  /**
1506   * Retrieves the potion duration scale component from the item's components. Since MC Snapshot 25w02a.
1507   *
1508   * @return an Optional containing the PotionDurationScaleComponent if present, otherwise an empty Optional
1509   * @since 0.2.0.0
1510   * @author creatorfromhell
1511   * @see PotionDurationScaleComponent
1512   */
1513  default Optional<PotionDurationScaleComponent<AbstractItemStack<T>, T>> potionDuration() {
1514    return Optional.ofNullable((PotionDurationScaleComponent<AbstractItemStack<T>, T>) components().get("potion_duration_scale"));
1515  }
1516
1517  /**
1518   * Sets the duration of a potion effect for the item stack. Since MC Snapshot 25w02a.
1519   *
1520   * @param potionDuration the duration of the potion effect in seconds
1521   * @return the modified AbstractItemStack object with the updated potion duration
1522   * @since 0.2.0.0
1523   * @author creatorfromhell
1524   * @see PotionDurationScaleComponent
1525   */
1526  AbstractItemStack<T> potionDuration(final float potionDuration);
1527
1528  /**
1529   * Retrieves the profile component from the components map if it exists.
1530   *
1531   * @return An Optional containing the profile component if found, or an empty Optional otherwise.
1532   * @since 0.2.0.0
1533   * @author creatorfromhell
1534   * @see ProfileComponent
1535   */
1536  default Optional<ProfileComponent<AbstractItemStack<T>, T>> profile() {
1537    return Optional.ofNullable((ProfileComponent<AbstractItemStack<T>, T>) components().get("profile"));
1538  }
1539
1540  /**
1541   * Create a Profile based on the provided name and UUID.
1542   *
1543   * @param name The name for the profile.
1544   * @param uuid The UUID for the profile.
1545   * @return A new AbstractItemStack based on the created SkullProfile with the given name and UUID.
1546   * @since 0.2.0.0
1547   * @author creatorfromhell
1548   * @see ProfileComponent
1549   */
1550  default AbstractItemStack<T> profile(final String name, final UUID uuid) {
1551    return profile(new SkullProfile(name, uuid));
1552  }
1553
1554  /**
1555   * Profiles the item stack with the given name, UUID, and texture.
1556   *
1557   * @param name The name of the profile.
1558   * @param uuid The UUID of the profile.
1559   * @param texture The texture of the profile.
1560   * @return The AbstractItemStack with the specified profile.
1561   * @since 0.2.0.0
1562   * @author creatorfromhell
1563   * @see ProfileComponent
1564   */
1565  default AbstractItemStack<T> profile(final String name, final UUID uuid, final String texture) {
1566    return profile(new SkullProfile(name, uuid, texture));
1567  }
1568
1569  /**
1570   * Profiles the given SkullProfile to the AbstractItemStack object.
1571   *
1572   * @param profile the SkullProfile to be assigned
1573   * @return an AbstractItemStack object with the provided profile
1574   */
1575  AbstractItemStack<T> profile(final SkullProfile profile);
1576
1577  /**
1578   * Retrieves the component that provides banner patterns.
1579   *
1580   * @return an Optional containing the ProvidesBannerPatternsComponent for the specified item stack type T,
1581   *         or an empty Optional if the component is not present
1582   * @since 0.2.0.0
1583   * @author creatorfromhell
1584   * @see ProvidesBannerPatternsComponent
1585   */
1586  default Optional<ProvidesBannerPatternsComponent<AbstractItemStack<T>, T>> providesPattern() {
1587    return Optional.ofNullable((ProvidesBannerPatternsComponent<AbstractItemStack<T>, T>) components().get("provides_trim_material"));
1588  }
1589
1590  /**
1591   * Retrieve an AbstractItemStack object that provides a specific pattern identified by the patternTag.
1592   *
1593   * @param patternTag The unique identifier of the pattern to be provided.
1594   * @return An AbstractItemStack object that provides the specified pattern.
1595   * @since 0.2.0.0
1596   * @author creatorfromhell
1597   * @see ProvidesBannerPatternsComponent
1598   */
1599  AbstractItemStack<T> providesPattern(final String patternTag);
1600
1601  /**
1602   * Retrieves the component responsible for providing trim materials.
1603   *
1604   * @return An Optional containing the ProvidesTrimMaterialComponent for trim, or an empty Optional if not found.
1605   * @since 0.2.0.0
1606   * @author creatorfromhell
1607   * @see ProvidesTrimMaterialComponent
1608   */
1609  default Optional<ProvidesTrimMaterialComponent<AbstractItemStack<T>, T>> providesTrim() {
1610    return Optional.ofNullable((ProvidesTrimMaterialComponent<AbstractItemStack<T>, T>) components().get("provides_trim_material"));
1611  }
1612
1613  /**
1614   * Applies the specified trim material
1615   *
1616   * @param material the trim material
1617   * @return an AbstractItemStack object representing the trimmed material
1618   * @since 0.2.0.0
1619   * @author creatorfromhell
1620   * @see ProvidesTrimMaterialComponent
1621   */
1622  AbstractItemStack<T> providesTrim(final String material);
1623
1624  /**
1625   * Retrieves the RarityComponent of the item stack if present.
1626   *
1627   * @return an Optional containing the RarityComponent if it exists
1628   * @since 0.2.0.0
1629   * @author creatorfromhell
1630   * @see RarityComponent
1631   */
1632  default Optional<RarityComponent<AbstractItemStack<T>, T>> rarity() {
1633    return Optional.ofNullable((RarityComponent<AbstractItemStack<T>, T>) components().get("rarity"));
1634  }
1635
1636  /**
1637   * Updates the rarity of the item stack.
1638   *
1639   * @param rarity the rarity value
1640   * @return the updated AbstractItemStack instance
1641   * @since 0.2.0.0
1642   * @author creatorfromhell
1643   * @see RarityComponent
1644   */
1645  AbstractItemStack<T> rarity(String rarity);
1646
1647  /**
1648   * Retrieves the RecipesComponent of the item stack if present.
1649   *
1650   * @return an Optional containing the RecipesComponent if it exists
1651   * @since 0.2.0.0
1652   * @author creatorfromhell
1653   * @see RecipesComponent
1654   */
1655  default Optional<RecipesComponent<AbstractItemStack<T>, T>> recipes() {
1656    return Optional.ofNullable((RecipesComponent<AbstractItemStack<T>, T>) components().get("recipes"));
1657  }
1658
1659  /**
1660   * Updates the recipes of the item stack.
1661   *
1662   * @param recipes a list of recipe identifiers
1663   * @return the updated AbstractItemStack instance
1664   * @since 0.2.0.0
1665   * @author creatorfromhell
1666   * @see RecipesComponent
1667   */
1668  AbstractItemStack<T> recipes(List<String> recipes);
1669
1670  /**
1671   * Retrieves the RepairableComponent of the item stack if present.
1672   *
1673   * @return an Optional containing the RepairableComponent if it exists
1674   * @since 0.2.0.0
1675   * @author creatorfromhell
1676   * @see RepairableComponent
1677   */
1678  default Optional<RepairableComponent<AbstractItemStack<T>, T>> repairable() {
1679    return Optional.ofNullable((RepairableComponent<AbstractItemStack<T>, T>) components().get("repairable"));
1680  }
1681
1682  /**
1683   * Updates the repairable items of the item stack.
1684   *
1685   * @param repairItems a list of repair item identifiers
1686   * @return the updated AbstractItemStack instance
1687   * @since 0.2.0.0
1688   * @author creatorfromhell
1689   * @see RepairableComponent
1690   */
1691  AbstractItemStack<T> repairable(List<String> repairItems);
1692
1693  /**
1694   * Retrieves the RepairCostComponent of the item stack if present.
1695   *
1696   * @return an Optional containing the RepairCostComponent if it exists
1697   * @since 0.2.0.0
1698   * @author creatorfromhell
1699   * @see RepairCostComponent
1700   */
1701  default Optional<RepairCostComponent<AbstractItemStack<T>, T>> repairCost() {
1702    return Optional.ofNullable((RepairCostComponent<AbstractItemStack<T>, T>) components().get("repair_cost"));
1703  }
1704
1705  /**
1706   * Updates the repair cost of the item stack.
1707   *
1708   * @param repairCost the repair cost value
1709   * @return the updated AbstractItemStack instance
1710   * @since 0.2.0.0
1711   * @author creatorfromhell
1712   * @see RepairCostComponent
1713   */
1714  AbstractItemStack<T> repairCost(int repairCost);
1715
1716  /**
1717   * Retrieves the StoredEnchantmentsComponent of the item stack if present.
1718   *
1719   * @return an Optional containing the StoredEnchantmentsComponent if it exists
1720   * @since 0.2.0.0
1721   * @author creatorfromhell
1722   * @see StoredEnchantmentsComponent
1723   */
1724  default Optional<StoredEnchantmentsComponent<AbstractItemStack<T>, T>> storedEnchantments() {
1725    return Optional.ofNullable((StoredEnchantmentsComponent<AbstractItemStack<T>, T>) components().get("stored_enchantments"));
1726  }
1727
1728  /**
1729   * Updates the stored enchantments of the item stack.
1730   *
1731   * @param enchantments a map of enchantment names to their levels
1732   * @return the updated AbstractItemStack instance
1733   * @since 0.2.0.0
1734   * @author creatorfromhell
1735   * @see StoredEnchantmentsComponent
1736   */
1737  AbstractItemStack<T> storedEnchantments(Map<String, Integer> enchantments);
1738
1739  /**
1740   * Retrieves the SuspiciousStewEffectsComponent of the item stack if present.
1741   *
1742   * @return an Optional containing the SuspiciousStewEffectsComponent if it exists
1743   * @since 0.2.0.0
1744   * @author creatorfromhell
1745   * @see SuspiciousStewEffectsComponent
1746   */
1747  default Optional<SuspiciousStewEffectsComponent<AbstractItemStack<T>, T>> suspiciousStewEffects() {
1748
1749    return Optional.ofNullable((SuspiciousStewEffectsComponent<AbstractItemStack<T>, T>) components().get("suspicious_stew_effects"));
1750  }
1751
1752  /**
1753   * Applies the given effects to the suspicious stew item.
1754   *
1755   * @param effects a list of EffectInstance objects representing the effects to be applied to the suspicious stew
1756   * @return an AbstractItemStack representing the suspicious stew with the applied effects
1757   * @since 0.2.0.0
1758   * @author creatorfromhell
1759   * @see SuspiciousStewEffectsComponent
1760   */
1761  AbstractItemStack<T> suspiciousStewEffects(final List<EffectInstance> effects);
1762
1763  /**
1764   * Applies the given effects to a suspicious stew item.
1765   *
1766   * @param effects an array of EffectInstance objects representing the effects to apply to the suspicious stew
1767   * @return an AbstractItemStack representing the suspicious stew item with the applied effects
1768   * @since 0.2.0.0
1769   * @author creatorfromhell
1770   * @see SuspiciousStewEffectsComponent
1771   */
1772  AbstractItemStack<T> suspiciousStewEffects(final EffectInstance... effects);
1773
1774  /**
1775   * Retrieves the ToolComponent of the item stack if present.
1776   *
1777   * @return an Optional containing the ToolComponent if it exists
1778   * @since 0.2.0.0
1779   * @author creatorfromhell
1780   * @see ToolComponent
1781   */
1782  default Optional<ToolComponent<AbstractItemStack<T>, T>> tool() {
1783    return Optional.ofNullable((ToolComponent<AbstractItemStack<T>, T>) components().get("tool"));
1784  }
1785
1786  /**
1787   * Constructs a new tool item with the specified characteristics.
1788   *
1789   * @param defaultSpeed the default speed of the tool
1790   * @param blockDamage the damage inflicted by the tool to blocks
1791   * @param canDestroyBlocksCreative if the tool can destroy blocks in creative mode
1792   * @param rules a list of rules that define the behavior of the tool
1793   * @return an AbstractItemStack instance representing the created tool
1794   * @since 0.2.0.0
1795   * @author creatorfromhell
1796   * @see ToolComponent
1797   */
1798  AbstractItemStack<T> tool(float defaultSpeed, int blockDamage, boolean canDestroyBlocksCreative, List<ToolRule> rules);
1799
1800  /**
1801   * Retrieves the tooltip display component associated with the item.
1802   *
1803   * @return An Optional containing the tooltip display component, or empty if none is found.
1804   * @since 0.2.0.0
1805   * @author creatorfromhell
1806   * @see TooltipDisplayComponent
1807   */
1808  default Optional<TooltipDisplayComponent<AbstractItemStack<T>, T>> tooltipDisplay() {
1809    return Optional.ofNullable((TooltipDisplayComponent<AbstractItemStack<T>, T>) components().get("tooltip_display"));
1810  }
1811
1812  /**
1813   * Displays tooltip for the item stack with an option to hide certain components.
1814   *
1815   * @param hideTooltip Flag to hide the tooltip
1816   * @param hiddenComponents Array of components to hide in the tooltip
1817   * @return An AbstractItemStack object with the tooltip displayed
1818   * @since 0.2.0.0
1819   * @author creatorfromhell
1820   * @see TooltipDisplayComponent
1821   */
1822  AbstractItemStack<T> tooltipDisplay(final boolean hideTooltip, final String... hiddenComponents);
1823
1824  /**
1825   * Retrieves the TooltipStyleComponent of the item stack if present.
1826   *
1827   * @return an Optional containing the TooltipStyleComponent if it exists
1828   * @since 0.2.0.0
1829   * @author creatorfromhell
1830   * @see TooltipStyleComponent
1831   */
1832  default Optional<TooltipStyleComponent<AbstractItemStack<T>, T>> tooltipStyle() {
1833    return Optional.ofNullable((TooltipStyleComponent<AbstractItemStack<T>, T>) components().get("tooltip_style"));
1834  }
1835
1836  /**
1837   * Updates the tooltip style of the item stack.
1838   *
1839   * @param style the style to apply to the tooltip
1840   * @return the updated AbstractItemStack instance
1841   * @since 0.2.0.0
1842   * @author creatorfromhell
1843   * @see TooltipStyleComponent
1844   */
1845  AbstractItemStack<T> tooltipStyle(String style);
1846
1847  /**
1848   * Retrieves the TrimComponent of the item stack if present.
1849   *
1850   * @return an Optional containing the TrimComponent if it exists
1851   * @since 0.2.0.0
1852   * @author creatorfromhell
1853   * @see TrimComponent
1854   */
1855  default Optional<TrimComponent<AbstractItemStack<T>, T>> trim() {
1856    return Optional.ofNullable((TrimComponent<AbstractItemStack<T>, T>) components().get("trim"));
1857  }
1858
1859  /**
1860   * Updates the trim properties of the item stack.
1861   *
1862   * @param pattern       the trim pattern
1863   * @param material      the trim material
1864   * @param showInTooltip whether to display the trim in the tooltip
1865   * @return the updated AbstractItemStack instance
1866   * @since 0.2.0.0
1867   * @author creatorfromhell
1868   * @see TrimComponent
1869   */
1870  AbstractItemStack<T> trim(String pattern, String material, boolean showInTooltip);
1871
1872  /**
1873   * Retrieves the UnbreakableComponent of the item stack if present.
1874   *
1875   * @return an Optional containing the UnbreakableComponent if it exists
1876   * @since 0.2.0.0
1877   * @author creatorfromhell
1878   * @see UnbreakableComponent
1879   */
1880  default Optional<UnbreakableComponent<AbstractItemStack<T>, T>> unbreakable() {
1881    return Optional.ofNullable((UnbreakableComponent<AbstractItemStack<T>, T>) components().get("unbreakable"));
1882  }
1883
1884  /**
1885   * Updates the unbreakable property of the item stack.
1886   *
1887   * @param showInTooltip whether to display the unbreakable property in the tooltip
1888   * @return the updated AbstractItemStack instance
1889   * @since 0.2.0.0
1890   * @author creatorfromhell
1891   * @see UnbreakableComponent
1892   */
1893  AbstractItemStack<T> unbreakable(boolean showInTooltip);
1894
1895  /**
1896   * Retrieves the UseCooldownComponent of the item stack if present.
1897   *
1898   * @return an Optional containing the UseCooldownComponent if it exists
1899   * @since 0.2.0.0
1900   * @author creatorfromhell
1901   * @see UseCooldownComponent
1902   */
1903  default Optional<UseCooldownComponent<AbstractItemStack<T>, T>> useCooldown() {
1904    return Optional.ofNullable((UseCooldownComponent<AbstractItemStack<T>, T>) components().get("use_cooldown"));
1905  }
1906
1907  /**
1908   * Updates the use cooldown properties of the item stack.
1909   *
1910   * @param cooldownGroup the cooldown group identifier
1911   * @param seconds       the cooldown duration in seconds
1912   * @return the updated AbstractItemStack instance
1913   * @since 0.2.0.0
1914   * @author creatorfromhell
1915   * @see UseCooldownComponent
1916   */
1917  AbstractItemStack<T> useCooldown(String cooldownGroup, float seconds);
1918
1919  /**
1920   * Retrieves the weapon component associated with this item. Since MC Snapshot 25w02a.
1921   *
1922   * @return an Optional containing the weapon component if it exists, otherwise an empty Optional.
1923   * @since 0.2.0.0
1924   * @author creatorfromhell
1925   * @see WeaponComponent
1926   */
1927  default Optional<WeaponComponent<AbstractItemStack<T>, T>> weapon() {
1928    return Optional.ofNullable((WeaponComponent<AbstractItemStack<T>, T>) components().get("weapon"));
1929  }
1930
1931  /**
1932   * Represents a weapon item that can be used for combat. Since MC Snapshot 25w02a.
1933   *
1934   * @param damagePerAttack The amount of damage this weapon inflicts per attack
1935   * @param canDisableBlocking Whether this weapon can disable blocking when used
1936   * @since 0.2.0.0
1937   * @author creatorfromhell
1938   * @see WeaponComponent
1939   */
1940  AbstractItemStack<T> weapon(final int damagePerAttack, final boolean canDisableBlocking);
1941
1942  /**
1943   * Retrieves the WritableBookContentComponent of the item stack if present.
1944   *
1945   * @return an Optional containing the WritableBookContentComponent if it exists
1946   * @since 0.2.0.0
1947   * @author creatorfromhell
1948   * @see WritableBookContentComponent
1949   */
1950  default Optional<WritableBookContentComponent<AbstractItemStack<T>, T>> writableBookContent() {
1951    return Optional.ofNullable((WritableBookContentComponent<AbstractItemStack<T>, T>) components().get("writable_book_content"));
1952  }
1953
1954  /**
1955   * Updates the writable book content of the item stack.
1956   *
1957   * @param pages the pages to include in the writable book
1958   * @return the updated AbstractItemStack instance
1959   * @since 0.2.0.0
1960   * @author creatorfromhell
1961   * @see WritableBookContentComponent
1962   */
1963  AbstractItemStack<T> writableBookContent(List<String> pages);
1964
1965  /**
1966   * Retrieves the WrittenBookContentComponent of the item stack if present.
1967   *
1968   * @return an Optional containing the WrittenBookContentComponent if it exists
1969   * @since 0.2.0.0
1970   * @author creatorfromhell
1971   * @see WrittenBookContentComponent
1972   */
1973  default Optional<WrittenBookContentComponent<AbstractItemStack<T>, T>> writtenBookContent() {
1974    return Optional.ofNullable((WrittenBookContentComponent<AbstractItemStack<T>, T>) components().get("written_book_content"));
1975  }
1976
1977  /**
1978   * Updates the written book content of the item stack.
1979   *
1980   * @param title     the title of the book
1981   * @param author    the author of the book
1982   * @param generation the generation of the book
1983   * @param resolved  whether the book is resolved
1984   * @param pages     the pages to include in the book
1985   * @return the updated AbstractItemStack instance
1986   * @since 0.2.0.0
1987   * @author creatorfromhell
1988   * @see WrittenBookContentComponent
1989   */
1990  AbstractItemStack<T> writtenBookContent(String title, String author, int generation, boolean resolved, List<String> pages);
1991}