mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-21 18:15:54 +01:00
4187 lines
149 KiB
Diff
4187 lines
149 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||
|
Date: Sun, 28 Apr 2024 19:53:06 -0400
|
||
|
Subject: [PATCH] DataComponent API
|
||
|
|
||
|
Exposes the data component logic used by vanilla ItemStack to API
|
||
|
consumers as a version-specific API.
|
||
|
The types and methods introduced by this patch do not follow the general
|
||
|
API deprecation contracts and will be adapted to each new minecraft
|
||
|
release without backwards compatibility measures.
|
||
|
|
||
|
diff --git a/src/main/java/io/papermc/paper/block/BlockPredicate.java b/src/main/java/io/papermc/paper/block/BlockPredicate.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..92ea82ee95c449916955631297a059f1b9198c9b
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/block/BlockPredicate.java
|
||
|
@@ -0,0 +1,50 @@
|
||
|
+package io.papermc.paper.block;
|
||
|
+
|
||
|
+import io.papermc.paper.registry.set.RegistryKeySet;
|
||
|
+import org.bukkit.block.BlockType;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface BlockPredicate {
|
||
|
+
|
||
|
+ static Builder predicate() {
|
||
|
+ //<editor-fold desc="implementations" defaultstate="collapsed">
|
||
|
+ record BlockPredicateImpl(@Nullable RegistryKeySet<BlockType> blocks) implements BlockPredicate {
|
||
|
+ }
|
||
|
+
|
||
|
+ class BuilderImpl implements Builder {
|
||
|
+
|
||
|
+ private @Nullable RegistryKeySet<BlockType> blocks;
|
||
|
+
|
||
|
+ @Override
|
||
|
+ public Builder blocks(final @Nullable RegistryKeySet<BlockType> blocks) {
|
||
|
+ this.blocks = blocks;
|
||
|
+ return this;
|
||
|
+ }
|
||
|
+
|
||
|
+ @Override
|
||
|
+ public BlockPredicate build() {
|
||
|
+ return new BlockPredicateImpl(this.blocks);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ //</editor-fold>
|
||
|
+ return new BuilderImpl();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Nullable RegistryKeySet<BlockType> blocks();
|
||
|
+
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder blocks(@Nullable RegistryKeySet<BlockType> blocks);
|
||
|
+
|
||
|
+ BlockPredicate build();
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/BuildableDataComponent.java b/src/main/java/io/papermc/paper/datacomponent/BuildableDataComponent.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..4d2ee71b82ff4a66c7f84e73c028f146e0f851ad
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/BuildableDataComponent.java
|
||
|
@@ -0,0 +1,19 @@
|
||
|
+package io.papermc.paper.datacomponent;
|
||
|
+
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface BuildableDataComponent<C extends BuildableDataComponent<C, B>, B extends DataComponentBuilder<C>> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Creates a new builder from this data component.
|
||
|
+ *
|
||
|
+ * @return a new builder
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ B toBuilder();
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/DataComponentBuilder.java b/src/main/java/io/papermc/paper/datacomponent/DataComponentBuilder.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..9365e57499c8e337a40835b2ec9a92ebe4391bfc
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/DataComponentBuilder.java
|
||
|
@@ -0,0 +1,24 @@
|
||
|
+package io.papermc.paper.datacomponent;
|
||
|
+
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Base builder type for all component builders.
|
||
|
+ *
|
||
|
+ * @param <C> built component type
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface DataComponentBuilder<C> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builds the immutable component value.
|
||
|
+ *
|
||
|
+ * @return a new component value
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ C build();
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/DataComponentType.java b/src/main/java/io/papermc/paper/datacomponent/DataComponentType.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..e2266d86a4dd1bf20346e48c428f8baf8a84b76b
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/DataComponentType.java
|
||
|
@@ -0,0 +1,30 @@
|
||
|
+package io.papermc.paper.datacomponent;
|
||
|
+
|
||
|
+import org.bukkit.Keyed;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface DataComponentType extends Keyed {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Checks if this data component type is persistent, or
|
||
|
+ * that it will be saved with any itemstack it's attached to.
|
||
|
+ *
|
||
|
+ * @return {@code true} if persistent, {@code false} otherwise
|
||
|
+ */
|
||
|
+ boolean isPersistent();
|
||
|
+
|
||
|
+ @SuppressWarnings("unused")
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Valued<T> extends DataComponentType {
|
||
|
+
|
||
|
+ }
|
||
|
+
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface NonValued extends DataComponentType {
|
||
|
+
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java b/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..e79737ae012179fc7c89b14af8801b8b09fa042b
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java
|
||
|
@@ -0,0 +1,344 @@
|
||
|
+package io.papermc.paper.datacomponent;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.item.BannerPatternLayers;
|
||
|
+import io.papermc.paper.datacomponent.item.BlockItemDataProperties;
|
||
|
+import io.papermc.paper.datacomponent.item.BundleContents;
|
||
|
+import io.papermc.paper.datacomponent.item.ChargedProjectiles;
|
||
|
+import io.papermc.paper.datacomponent.item.Consumable;
|
||
|
+import io.papermc.paper.datacomponent.item.CustomModelData;
|
||
|
+import io.papermc.paper.datacomponent.item.DamageResistant;
|
||
|
+import io.papermc.paper.datacomponent.item.DeathProtection;
|
||
|
+import io.papermc.paper.datacomponent.item.DyedItemColor;
|
||
|
+import io.papermc.paper.datacomponent.item.Enchantable;
|
||
|
+import io.papermc.paper.datacomponent.item.Equippable;
|
||
|
+import io.papermc.paper.datacomponent.item.Fireworks;
|
||
|
+import io.papermc.paper.datacomponent.item.FoodProperties;
|
||
|
+import io.papermc.paper.datacomponent.item.ItemAdventurePredicate;
|
||
|
+import io.papermc.paper.datacomponent.item.ItemArmorTrim;
|
||
|
+import io.papermc.paper.datacomponent.item.ItemAttributeModifiers;
|
||
|
+import io.papermc.paper.datacomponent.item.ItemContainerContents;
|
||
|
+import io.papermc.paper.datacomponent.item.ItemEnchantments;
|
||
|
+import io.papermc.paper.datacomponent.item.ItemLore;
|
||
|
+import io.papermc.paper.datacomponent.item.JukeboxPlayable;
|
||
|
+import io.papermc.paper.datacomponent.item.LodestoneTracker;
|
||
|
+import io.papermc.paper.datacomponent.item.MapDecorations;
|
||
|
+import io.papermc.paper.datacomponent.item.MapId;
|
||
|
+import io.papermc.paper.datacomponent.item.MapItemColor;
|
||
|
+import io.papermc.paper.datacomponent.item.OminousBottleAmplifier;
|
||
|
+import io.papermc.paper.datacomponent.item.PotDecorations;
|
||
|
+import io.papermc.paper.datacomponent.item.PotionContents;
|
||
|
+import io.papermc.paper.datacomponent.item.Repairable;
|
||
|
+import io.papermc.paper.datacomponent.item.ResolvableProfile;
|
||
|
+import io.papermc.paper.datacomponent.item.SeededContainerLoot;
|
||
|
+import io.papermc.paper.datacomponent.item.SuspiciousStewEffects;
|
||
|
+import io.papermc.paper.datacomponent.item.Tool;
|
||
|
+import io.papermc.paper.datacomponent.item.Unbreakable;
|
||
|
+import io.papermc.paper.datacomponent.item.UseCooldown;
|
||
|
+import io.papermc.paper.datacomponent.item.UseRemainder;
|
||
|
+import io.papermc.paper.datacomponent.item.WritableBookContent;
|
||
|
+import io.papermc.paper.datacomponent.item.WrittenBookContent;
|
||
|
+import io.papermc.paper.item.MapPostProcessing;
|
||
|
+import java.util.List;
|
||
|
+import net.kyori.adventure.key.Key;
|
||
|
+import net.kyori.adventure.text.Component;
|
||
|
+import org.bukkit.DyeColor;
|
||
|
+import org.bukkit.FireworkEffect;
|
||
|
+import org.bukkit.MusicInstrument;
|
||
|
+import org.bukkit.NamespacedKey;
|
||
|
+import org.bukkit.Registry;
|
||
|
+import org.bukkit.inventory.ItemRarity;
|
||
|
+import org.checkerframework.checker.index.qual.NonNegative;
|
||
|
+import org.checkerframework.checker.index.qual.Positive;
|
||
|
+import org.checkerframework.common.value.qual.IntRange;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+import static java.util.Objects.requireNonNull;
|
||
|
+
|
||
|
+/**
|
||
|
+ * All the different types of data that {@link org.bukkit.inventory.ItemStack ItemStacks}
|
||
|
+ * and {@link org.bukkit.inventory.ItemType ItemTypes} can have.
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+public final class DataComponentTypes {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Controls the maximum stacking size of this item.
|
||
|
+ * <br>
|
||
|
+ * Values greater than 1 are mutually exclusive with the {@link #MAX_DAMAGE} component.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<@IntRange(from = 1, to = 99) Integer> MAX_STACK_SIZE = valued("max_stack_size");
|
||
|
+ /**
|
||
|
+ * Controls the maximum amount of damage than an item can take,
|
||
|
+ * if not present, the item cannot be damaged.
|
||
|
+ * <br>
|
||
|
+ * Mutually exclusive with the {@link #MAX_STACK_SIZE} component greater than 1.
|
||
|
+ *
|
||
|
+ * @see #DAMAGE
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<@Positive Integer> MAX_DAMAGE = valued("max_damage");
|
||
|
+ /**
|
||
|
+ * The amount of durability removed from an item,
|
||
|
+ * for damageable items (with the {@link #MAX_DAMAGE} component), has an implicit default value of: {@code 0}.
|
||
|
+ *
|
||
|
+ * @see #MAX_DAMAGE
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<@NonNegative Integer> DAMAGE = valued("damage");
|
||
|
+ /**
|
||
|
+ * If set, the item will not lose any durability when used.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<Unbreakable> UNBREAKABLE = valued("unbreakable");
|
||
|
+ /**
|
||
|
+ * Custom name override for an item (as set by renaming with an Anvil).
|
||
|
+ *
|
||
|
+ * @see #ITEM_NAME
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<Component> CUSTOM_NAME = valued("custom_name");
|
||
|
+ /**
|
||
|
+ * When present, replaces default item name with contained chat component.
|
||
|
+ * <p>
|
||
|
+ * Differences from {@link #CUSTOM_NAME}:
|
||
|
+ * <ul>
|
||
|
+ * <li>can't be changed or removed in Anvil</li>
|
||
|
+ * <li>is not styled with italics when displayed to player</li>
|
||
|
+ * <li>does not show labels where applicable
|
||
|
+ * (for example: banner markers, names in item frames)</li>
|
||
|
+ * </ul>
|
||
|
+ *
|
||
|
+ * @see #CUSTOM_NAME
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<Component> ITEM_NAME = valued("item_name");
|
||
|
+ public static final DataComponentType.Valued<Key> ITEM_MODEL = valued("item_model");
|
||
|
+ /**
|
||
|
+ * Additional lines to include in an item's tooltip.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ItemLore> LORE = valued("lore");
|
||
|
+ /**
|
||
|
+ * Controls the color of the item name.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ItemRarity> RARITY = valued("rarity");
|
||
|
+ /**
|
||
|
+ * Controls the enchantments on an item.
|
||
|
+ * <br>
|
||
|
+ * If not present on a non-enchantment book, this item will not work in an anvil.
|
||
|
+ *
|
||
|
+ * @see #STORED_ENCHANTMENTS
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ItemEnchantments> ENCHANTMENTS = valued("enchantments");
|
||
|
+ /**
|
||
|
+ * Controls which blocks a player in Adventure mode can place on with this item.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ItemAdventurePredicate> CAN_PLACE_ON = valued("can_place_on");
|
||
|
+ /**
|
||
|
+ * Controls which blocks a player in Adventure mode can break with this item.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ItemAdventurePredicate> CAN_BREAK = valued("can_break");
|
||
|
+ /**
|
||
|
+ * Holds attribute modifiers applied to any item,
|
||
|
+ * if not set, has an implicit default value based on the item type's
|
||
|
+ * default attributes (e.g. attack damage for weapons).
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ItemAttributeModifiers> ATTRIBUTE_MODIFIERS = valued("attribute_modifiers");
|
||
|
+ /**
|
||
|
+ * Controls the minecraft:custom_model_data property in the item model.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<CustomModelData> CUSTOM_MODEL_DATA = valued("custom_model_data");
|
||
|
+ /**
|
||
|
+ * If set, disables 'additional' tooltip part which comes from the item type
|
||
|
+ * (e.g. content of a shulker).
|
||
|
+ */
|
||
|
+ public static final DataComponentType.NonValued HIDE_ADDITIONAL_TOOLTIP = unvalued("hide_additional_tooltip");
|
||
|
+ /**
|
||
|
+ * If set, it will completely hide whole item tooltip (that includes item name).
|
||
|
+ */
|
||
|
+ public static final DataComponentType.NonValued HIDE_TOOLTIP = unvalued("hide_tooltip");
|
||
|
+ /**
|
||
|
+ * The additional experience cost required to modify an item in an Anvil.
|
||
|
+ * If not present, has an implicit default value of: {@code 0}.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<@NonNegative Integer> REPAIR_COST = valued("repair_cost");
|
||
|
+ /**
|
||
|
+ * Causes an item to not be pickable in the creative menu, currently not very useful.
|
||
|
+ */
|
||
|
+ // public static final DataComponentType.NonValued CREATIVE_SLOT_LOCK = unvalued("creative_slot_lock");
|
||
|
+ /**
|
||
|
+ * Overrides the enchantment glint effect on an item.
|
||
|
+ * If not present, default behaviour is used.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<Boolean> ENCHANTMENT_GLINT_OVERRIDE = valued("enchantment_glint_override");
|
||
|
+ /**
|
||
|
+ * Marks that a projectile item would be intangible when fired
|
||
|
+ * (i.e. can only be picked up by a creative mode player).
|
||
|
+ */
|
||
|
+ public static final DataComponentType.NonValued INTANGIBLE_PROJECTILE = unvalued("intangible_projectile");
|
||
|
+ /**
|
||
|
+ * Controls potential food benefits gained when consuming the item the component is applied on.
|
||
|
+ * Requires the {@link #CONSUMABLE} component to allow consumption in the first place.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<FoodProperties> FOOD = valued("food");
|
||
|
+ public static final DataComponentType.Valued<Consumable> CONSUMABLE = valued("consumable");
|
||
|
+ public static final DataComponentType.Valued<UseRemainder> USE_REMAINDER = valued("use_remainder");
|
||
|
+ public static final DataComponentType.Valued<UseCooldown> USE_COOLDOWN = valued("use_cooldown");
|
||
|
+ /**
|
||
|
+ * If present, this item will not burn in fire.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<DamageResistant> DAMAGE_RESISTANT = valued("damage_resistant");
|
||
|
+ /**
|
||
|
+ * Controls the behavior of the item as a tool.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<Tool> TOOL = valued("tool");
|
||
|
+ public static final DataComponentType.Valued<Enchantable> ENCHANTABLE = valued("enchantable");
|
||
|
+ public static final DataComponentType.Valued<Equippable> EQUIPPABLE = valued("equippable");
|
||
|
+ public static final DataComponentType.Valued<Repairable> REPAIRABLE = valued("repairable");
|
||
|
+ public static final DataComponentType.NonValued GLIDER = unvalued("glider");
|
||
|
+ public static final DataComponentType.Valued<Key> TOOLTIP_STYLE = valued("tooltip_style");
|
||
|
+ public static final DataComponentType.Valued<DeathProtection> DEATH_PROTECTION = valued("death_protection");
|
||
|
+ /**
|
||
|
+ * Stores list of enchantments and their levels for an Enchanted Book.
|
||
|
+ * Unlike {@link #ENCHANTMENTS}, the effects provided by enchantments
|
||
|
+ * do not apply from this component.
|
||
|
+ * <br>
|
||
|
+ * If not present on an Enchanted Book, it will not work in an anvil.
|
||
|
+ * <p>
|
||
|
+ * Has an undefined behaviour if present on an item that is not an Enchanted Book
|
||
|
+ * (currently the presence of this component allows enchantments from {@link #ENCHANTMENTS}
|
||
|
+ * to be applied as if this item was an Enchanted Book).
|
||
|
+ *
|
||
|
+ * @see #ENCHANTMENTS
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ItemEnchantments> STORED_ENCHANTMENTS = valued("stored_enchantments");
|
||
|
+ /**
|
||
|
+ * Represents a color applied to a dyeable item (in the {@link io.papermc.paper.registry.keys.tags.ItemTypeTagKeys#DYEABLE} item tag).
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<DyedItemColor> DYED_COLOR = valued("dyed_color");
|
||
|
+ /**
|
||
|
+ * Represents the tint of the decorations on the {@link org.bukkit.inventory.ItemType#FILLED_MAP} item.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<MapItemColor> MAP_COLOR = valued("map_color");
|
||
|
+ /**
|
||
|
+ * References the shared map state holding map contents and markers for a {@link org.bukkit.inventory.ItemType#FILLED_MAP}.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<MapId> MAP_ID = valued("map_id");
|
||
|
+ /**
|
||
|
+ * Holds a list of markers to be placed on a {@link org.bukkit.inventory.ItemType#FILLED_MAP} (used for Explorer Maps).
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<MapDecorations> MAP_DECORATIONS = valued("map_decorations");
|
||
|
+ /**
|
||
|
+ * Internal map item state used in the map crafting recipe.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<MapPostProcessing> MAP_POST_PROCESSING = valued("map_post_processing");
|
||
|
+ /**
|
||
|
+ * Holds all projectiles that have been loaded into a Crossbow.
|
||
|
+ * If not present, the Crossbow is not charged.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ChargedProjectiles> CHARGED_PROJECTILES = valued("charged_projectiles");
|
||
|
+ /**
|
||
|
+ * Holds all items stored inside a Bundle.
|
||
|
+ * If removed, items cannot be added to the Bundle.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<BundleContents> BUNDLE_CONTENTS = valued("bundle_contents");
|
||
|
+ /**
|
||
|
+ * Holds the contents of a potion (Potion, Splash Potion, Lingering Potion),
|
||
|
+ * or potion applied to a Tipped Arrow.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<PotionContents> POTION_CONTENTS = valued("potion_contents");
|
||
|
+ /**
|
||
|
+ * Holds the effects that will be applied when consuming Suspicious Stew.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<SuspiciousStewEffects> SUSPICIOUS_STEW_EFFECTS = valued("suspicious_stew_effects");
|
||
|
+ /**
|
||
|
+ * Holds the contents in a Book and Quill.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<WritableBookContent> WRITABLE_BOOK_CONTENT = valued("writable_book_content");
|
||
|
+ /**
|
||
|
+ * Holds the contents and metadata of a Written Book.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<WrittenBookContent> WRITTEN_BOOK_CONTENT = valued("written_book_content");
|
||
|
+ /**
|
||
|
+ * Holds the trims applied to an item in recipes
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ItemArmorTrim> TRIM = valued("trim");
|
||
|
+ // debug_stick_state - Block Property API
|
||
|
+ // entity_data
|
||
|
+ // bucket_entity_data
|
||
|
+ // block_entity_data
|
||
|
+ /**
|
||
|
+ * Holds the instrument type used by a Goat Horn.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<MusicInstrument> INSTRUMENT = valued("instrument");
|
||
|
+ /**
|
||
|
+ * Controls the amplifier amount for an Ominous Bottle's Bad Omen effect.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<OminousBottleAmplifier> OMINOUS_BOTTLE_AMPLIFIER = valued("ominous_bottle_amplifier");
|
||
|
+ /**
|
||
|
+ * List of recipes that should be unlocked when using the Knowledge Book item.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<JukeboxPlayable> JUKEBOX_PLAYABLE = valued("jukebox_playable");
|
||
|
+ public static final DataComponentType.Valued<List<Key>> RECIPES = valued("recipes");
|
||
|
+ /**
|
||
|
+ * If present, specifies that the Compass is a Lodestone Compass.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<LodestoneTracker> LODESTONE_TRACKER = valued("lodestone_tracker");
|
||
|
+ /**
|
||
|
+ * Stores the explosion crafted in a Firework Star.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<FireworkEffect> FIREWORK_EXPLOSION = valued("firework_explosion");
|
||
|
+ /**
|
||
|
+ * Stores all explosions crafted into a Firework Rocket, as well as flight duration.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<Fireworks> FIREWORKS = valued("fireworks");
|
||
|
+ /**
|
||
|
+ * Controls the skin displayed on a Player Head.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ResolvableProfile> PROFILE = valued("profile");
|
||
|
+ /**
|
||
|
+ * Controls the sound played by a Player Head when placed on a Note Block.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<Key> NOTE_BLOCK_SOUND = valued("note_block_sound");
|
||
|
+ /**
|
||
|
+ * Stores the additional patterns applied to a Banner or Shield.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<BannerPatternLayers> BANNER_PATTERNS = valued("banner_patterns");
|
||
|
+ /**
|
||
|
+ * Stores the base color for a Shield.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<DyeColor> BASE_COLOR = valued("base_color");
|
||
|
+ /**
|
||
|
+ * Stores the Sherds applied to each side of a Decorated Pot.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<PotDecorations> POT_DECORATIONS = valued("pot_decorations");
|
||
|
+ /**
|
||
|
+ * Holds the contents of container blocks (Chests, Shulker Boxes) in item form.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<ItemContainerContents> CONTAINER = valued("container");
|
||
|
+ /**
|
||
|
+ * Holds block state properties to apply when placing a block.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<BlockItemDataProperties> BLOCK_DATA = valued("block_state");
|
||
|
+ // bees
|
||
|
+ // /**
|
||
|
+ // * Holds the lock state of a container-like block,
|
||
|
+ // * copied to container block when placed.
|
||
|
+ // * <br>
|
||
|
+ // * An item with a custom name of the same value must be used
|
||
|
+ // * to open this container.
|
||
|
+ // */
|
||
|
+ // public static final DataComponentType.Valued<LockCode> LOCK = valued("lock");
|
||
|
+ /**
|
||
|
+ * Holds the unresolved loot table and seed of a container-like block.
|
||
|
+ */
|
||
|
+ public static final DataComponentType.Valued<SeededContainerLoot> CONTAINER_LOOT = valued("container_loot");
|
||
|
+
|
||
|
+ private static DataComponentType.NonValued unvalued(final String name) {
|
||
|
+ return (DataComponentType.NonValued) requireNonNull(Registry.DATA_COMPONENT_TYPE.get(NamespacedKey.minecraft(name)), name + " unvalued data component type couldn't be found, this is a bug.");
|
||
|
+ }
|
||
|
+
|
||
|
+ @SuppressWarnings("unchecked")
|
||
|
+ private static <T> DataComponentType.Valued<T> valued(final String name) {
|
||
|
+ return (DataComponentType.Valued<T>) requireNonNull(Registry.DATA_COMPONENT_TYPE.get(NamespacedKey.minecraft(name)), name + " valued data component type couldn't be found, this is a bug.");
|
||
|
+ }
|
||
|
+
|
||
|
+ private DataComponentTypes() {
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/BannerPatternLayers.java b/src/main/java/io/papermc/paper/datacomponent/item/BannerPatternLayers.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..12cfae82234b8c4cb231ab91e72ad82d28b85183
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/BannerPatternLayers.java
|
||
|
@@ -0,0 +1,66 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.Arrays;
|
||
|
+import java.util.List;
|
||
|
+import org.bukkit.block.banner.Pattern;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the layers of patterns on a banner.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#BANNER_PATTERNS
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface BannerPatternLayers {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static BannerPatternLayers bannerPatternLayers(final List<Pattern> patterns) {
|
||
|
+ return bannerPatternLayers().addAll(patterns).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static BannerPatternLayers.Builder bannerPatternLayers() {
|
||
|
+ return ItemComponentTypesBridge.bridge().bannerPatternLayers();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the patterns on the banner.
|
||
|
+ *
|
||
|
+ * @return the patterns
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<Pattern> patterns();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link BannerPatternLayers}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<BannerPatternLayers> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a pattern to the banner.
|
||
|
+ *
|
||
|
+ * @param pattern the pattern
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #patterns()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder add(Pattern pattern);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds multiple patterns to the banner.
|
||
|
+ *
|
||
|
+ * @param patterns the patterns
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #patterns()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addAll(List<Pattern> patterns);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/BlockItemDataProperties.java b/src/main/java/io/papermc/paper/datacomponent/item/BlockItemDataProperties.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..65f1bc8d1bea0042dca9683c439561132dbeea5c
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/BlockItemDataProperties.java
|
||
|
@@ -0,0 +1,51 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import org.bukkit.block.BlockType;
|
||
|
+import org.bukkit.block.data.BlockData;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the {@link BlockData} properties of a block item.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#BLOCK_DATA
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface BlockItemDataProperties {
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static BlockItemDataProperties.Builder blockItemStateProperties() {
|
||
|
+ return ItemComponentTypesBridge.bridge().blockItemStateProperties();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Creates a new {@link BlockData} instance for the given {@link BlockType}.
|
||
|
+ *
|
||
|
+ * @param blockType the block type
|
||
|
+ * @return the block data
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ BlockData createBlockData(BlockType blockType);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Applies the properties to the given {@link BlockData}. Doesn't
|
||
|
+ * mutate the parameter, but returns a new instance with the properties applied.
|
||
|
+ *
|
||
|
+ * @param blockData the block data to apply the properties to
|
||
|
+ * @return the block data with the properties applied
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ BlockData applyTo(BlockData blockData);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link BlockItemDataProperties}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<BlockItemDataProperties> {
|
||
|
+ // building this requires BlockProperty API, so an empty builder for now (essentially read-only)
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/BundleContents.java b/src/main/java/io/papermc/paper/datacomponent/item/BundleContents.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..c0f671aef8225c87632d2368d1b28fc8b1bce686
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/BundleContents.java
|
||
|
@@ -0,0 +1,66 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.Arrays;
|
||
|
+import java.util.List;
|
||
|
+import org.bukkit.inventory.ItemStack;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds all items stored inside of a Bundle.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#BUNDLE_CONTENTS
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface BundleContents {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static BundleContents bundleContents(final List<ItemStack> contents) {
|
||
|
+ return ItemComponentTypesBridge.bridge().bundleContents().addAll(contents).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static BundleContents.Builder bundleContents() {
|
||
|
+ return ItemComponentTypesBridge.bridge().bundleContents();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Lists the items that are currently stored inside of this component.
|
||
|
+ *
|
||
|
+ * @return items
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ @Unmodifiable List<ItemStack> contents();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link BundleContents}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<BundleContents> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds an item to this builder.
|
||
|
+ *
|
||
|
+ * @param stack item
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #contents()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder add(ItemStack stack);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds items to this builder.
|
||
|
+ *
|
||
|
+ * @param stacks items
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #contents()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addAll(List<ItemStack> stacks);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ChargedProjectiles.java b/src/main/java/io/papermc/paper/datacomponent/item/ChargedProjectiles.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..d0a6e7db06f540e13ac00e8da3acabd9f7838f1f
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/ChargedProjectiles.java
|
||
|
@@ -0,0 +1,66 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.Arrays;
|
||
|
+import java.util.List;
|
||
|
+import org.bukkit.inventory.ItemStack;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds all projectiles that have been loaded into a Crossbow.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#CHARGED_PROJECTILES
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface ChargedProjectiles {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static ChargedProjectiles chargedProjectiles(final List<ItemStack> projectiles) {
|
||
|
+ return chargedProjectiles().addAll(projectiles).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static ChargedProjectiles.Builder chargedProjectiles() {
|
||
|
+ return ItemComponentTypesBridge.bridge().chargedProjectiles();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Lists the projectiles that are currently loaded into this component.
|
||
|
+ *
|
||
|
+ * @return the loaded projectiles
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ @Unmodifiable List<ItemStack> projectiles();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link ChargedProjectiles}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<ChargedProjectiles> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a projectile to be loaded in this builder.
|
||
|
+ *
|
||
|
+ * @param stack projectile
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #projectiles()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder add(ItemStack stack);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds projectiles to be loaded in this builder.
|
||
|
+ *
|
||
|
+ * @param stacks projectiles
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #projectiles()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addAll(List<ItemStack> stacks);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Consumable.java b/src/main/java/io/papermc/paper/datacomponent/item/Consumable.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..a448fedb63ffce18b9f6a1bd0fecfc5cd90224a6
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/Consumable.java
|
||
|
@@ -0,0 +1,70 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.BuildableDataComponent;
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect;
|
||
|
+import io.papermc.paper.datacomponent.item.consumable.ItemUseAnimation;
|
||
|
+import java.util.Collection;
|
||
|
+import java.util.List;
|
||
|
+import net.kyori.adventure.key.Key;
|
||
|
+import org.checkerframework.checker.index.qual.NonNegative;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the properties for this item for when it is consumed.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#CONSUMABLE
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface Consumable extends BuildableDataComponent<Consumable, Consumable.Builder> {
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static Consumable.Builder consumable() {
|
||
|
+ return ItemComponentTypesBridge.bridge().consumable();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ @NonNegative float consumeSeconds();
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ ItemUseAnimation animation();
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ Key sound();
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ boolean hasConsumeParticles();
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<ConsumeEffect> consumeEffects();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link Consumable}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<Consumable> {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder consumeSeconds(@NonNegative float consumeSeconds);
|
||
|
+
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder animation(ItemUseAnimation animation);
|
||
|
+
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder sound(Key sound);
|
||
|
+
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder hasConsumeParticles(boolean hasConsumeParticles);
|
||
|
+
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addEffect(ConsumeEffect effect);
|
||
|
+
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addEffects(List<ConsumeEffect> effects);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/CustomModelData.java b/src/main/java/io/papermc/paper/datacomponent/item/CustomModelData.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..d416c9d25b3ab88bf1e208c6faf92a8e2378c376
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/CustomModelData.java
|
||
|
@@ -0,0 +1,28 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the custom model data.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#CUSTOM_MODEL_DATA
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface CustomModelData {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static CustomModelData customModelData(final int id) {
|
||
|
+ return ItemComponentTypesBridge.bridge().customModelData(id);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the custom model data id.
|
||
|
+ *
|
||
|
+ * @return the id
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ int id();
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/DamageResistant.java b/src/main/java/io/papermc/paper/datacomponent/item/DamageResistant.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..6cbd73cb2a11f4858b44a2f57d2fe0acb1eb9fb5
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/DamageResistant.java
|
||
|
@@ -0,0 +1,30 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.registry.tag.TagKey;
|
||
|
+import org.bukkit.damage.DamageType;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the contents of damage types that the item entity containing this item is invincible to.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#DAMAGE_RESISTANT
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface DamageResistant {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static DamageResistant damageResistant(final TagKey<DamageType> types) {
|
||
|
+ return ItemComponentTypesBridge.bridge().damageResistant(types);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The types that this damage type is invincible tp.
|
||
|
+ *
|
||
|
+ * @return item
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ TagKey<DamageType> types();
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/DeathProtection.java b/src/main/java/io/papermc/paper/datacomponent/item/DeathProtection.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..87c2220708af7db06348994ad5940c7cecd9f691
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/DeathProtection.java
|
||
|
@@ -0,0 +1,48 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect;
|
||
|
+import java.util.Arrays;
|
||
|
+import java.util.Collection;
|
||
|
+import java.util.List;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Sets whether this item should protect the entity upon death, and what effects should be played.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#DEATH_PROTECTION
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface DeathProtection {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static DeathProtection deathProtection(final List<ConsumeEffect> deathEffects) {
|
||
|
+ return deathProtection().addEffects(deathEffects).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static DeathProtection.Builder deathProtection() {
|
||
|
+ return ItemComponentTypesBridge.bridge().deathProtection();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ @Unmodifiable List<ConsumeEffect> deathEffects();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link DeathProtection}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<DeathProtection> {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addEffect(ConsumeEffect effect);
|
||
|
+
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addEffects(List<ConsumeEffect> effects);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/DyedItemColor.java b/src/main/java/io/papermc/paper/datacomponent/item/DyedItemColor.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..d80581fc8b894cc4d4af9741244b1bb03468b263
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/DyedItemColor.java
|
||
|
@@ -0,0 +1,53 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import org.bukkit.Color;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Represents a color applied to a dyeable item.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#DYED_COLOR
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface DyedItemColor extends ShownInTooltip<DyedItemColor> {
|
||
|
+
|
||
|
+ @Contract(value = "_, _ -> new", pure = true)
|
||
|
+ static DyedItemColor dyedItemColor(final Color color, final boolean showInTooltip) {
|
||
|
+ return dyedItemColor().color(color).showInTooltip(showInTooltip).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static DyedItemColor.Builder dyedItemColor() {
|
||
|
+ return ItemComponentTypesBridge.bridge().dyedItemColor();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Color of the item.
|
||
|
+ *
|
||
|
+ * @return color
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ Color color();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link DyedItemColor}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends ShownInTooltip.Builder<Builder>, DataComponentBuilder<DyedItemColor> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the color of this builder.
|
||
|
+ *
|
||
|
+ * @param color color
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #color()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder color(Color color);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Enchantable.java b/src/main/java/io/papermc/paper/datacomponent/item/Enchantable.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..5169b9cd73dc0ffc8297f8d5f63d3d707a47d279
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/Enchantable.java
|
||
|
@@ -0,0 +1,31 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import org.checkerframework.checker.index.qual.Positive;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds if an item is enchantable, allowing for enchantments of the type to be seen in an enchanting table.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#ENCHANTABLE
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface Enchantable {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static Enchantable enchantable(final @Positive int level) {
|
||
|
+ return ItemComponentTypesBridge.bridge().enchantable(level);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the current enchantment value level allowed,
|
||
|
+ * a higher value allows enchantments with a higher cost to be picked.
|
||
|
+ *
|
||
|
+ * @see <a href="https://minecraft.wiki/w/Enchanting_mechanics#Java_Edition_2">Minecraft Wiki</a>
|
||
|
+ * @return the value
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Positive int value();
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Equippable.java b/src/main/java/io/papermc/paper/datacomponent/item/Equippable.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..7d84217814bba4ce826e33755fee0d5c3b280009
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/Equippable.java
|
||
|
@@ -0,0 +1,170 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.BuildableDataComponent;
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import io.papermc.paper.registry.set.RegistryKeySet;
|
||
|
+import net.kyori.adventure.key.Key;
|
||
|
+import org.bukkit.entity.EntityType;
|
||
|
+import org.bukkit.inventory.EquipmentSlot;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the equippable properties of an item.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#EQUIPPABLE
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface Equippable extends BuildableDataComponent<Equippable, Equippable.Builder> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Creates a new {@link Equippable.Builder} instance.
|
||
|
+ * @param slot The slot for the new equippable to be equippable in.
|
||
|
+ *
|
||
|
+ * @return a new builder
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static Equippable.Builder equippable(final EquipmentSlot slot) {
|
||
|
+ return ItemComponentTypesBridge.bridge().equippable(slot);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the equipment slot this item can be equipped in.
|
||
|
+ *
|
||
|
+ * @return the equipment slot
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ EquipmentSlot slot();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the equip sound key.
|
||
|
+ *
|
||
|
+ * @return the equip sound key
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ Key equipSound();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the model key if present.
|
||
|
+ *
|
||
|
+ * @return the model key or null
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable Key model();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the camera overlay key if present.
|
||
|
+ *
|
||
|
+ * @return the camera overlay key or null
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable Key cameraOverlay();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the set of allowed entities that can equip this item.
|
||
|
+ * May be null if all entities are allowed.
|
||
|
+ *
|
||
|
+ * @return the set of allowed entities
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable RegistryKeySet<EntityType> allowedEntities();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Checks if the item is dispensable.
|
||
|
+ *
|
||
|
+ * @return true if dispensable, false otherwise
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ boolean dispensable();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Checks if the item is swappable.
|
||
|
+ *
|
||
|
+ * @return true if swappable, false otherwise
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ boolean swappable();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Checks if the item takes damage when the wearer is hurt.
|
||
|
+ *
|
||
|
+ * @return true if it damages on hurt, false otherwise
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ boolean damageOnHurt();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link Equippable}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<Equippable> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the equip sound key for this item.
|
||
|
+ *
|
||
|
+ * @param equipSound the equip sound key
|
||
|
+ * @return the builder for chaining
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder equipSound(Key equipSound);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the model key for this item.
|
||
|
+ *
|
||
|
+ * @param model the model key, nullable
|
||
|
+ * @return the builder for chaining
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder model(@Nullable Key model);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the camera overlay key for this item.
|
||
|
+ *
|
||
|
+ * @param cameraOverlay the camera overlay key, nullable
|
||
|
+ * @return the builder for chaining
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder cameraOverlay(@Nullable Key cameraOverlay);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the allowed entities that can equip this item.
|
||
|
+ *
|
||
|
+ * @param allowedEntities the set of allowed entity types, or null if any
|
||
|
+ * @return the builder for chaining
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder allowedEntities(@Nullable RegistryKeySet<EntityType> allowedEntities);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets whether the item is dispensable.
|
||
|
+ *
|
||
|
+ * @param dispensable true if dispensable
|
||
|
+ * @return the builder for chaining
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder dispensable(boolean dispensable);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets whether the item is swappable.
|
||
|
+ *
|
||
|
+ * @param swappable true if swappable
|
||
|
+ * @return the builder for chaining
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder swappable(boolean swappable);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets whether the item takes damage when the wearer is hurt.
|
||
|
+ *
|
||
|
+ * @param damageOnHurt true if it damages on hurt
|
||
|
+ * @return the builder for chaining
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder damageOnHurt(boolean damageOnHurt);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Fireworks.java b/src/main/java/io/papermc/paper/datacomponent/item/Fireworks.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..72aa1b4bda2693e0cd78d93449dda23bd1b74062
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/Fireworks.java
|
||
|
@@ -0,0 +1,84 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.List;
|
||
|
+import org.bukkit.FireworkEffect;
|
||
|
+import org.checkerframework.common.value.qual.IntRange;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Stores all explosions crafted into a Firework Rocket, as well as flight duration.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#FIREWORKS
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface Fireworks {
|
||
|
+
|
||
|
+ @Contract(value = "_, _ -> new", pure = true)
|
||
|
+ static Fireworks fireworks(final List<FireworkEffect> effects, final int flightDuration) {
|
||
|
+ return fireworks().addEffects(effects).flightDuration(flightDuration).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static Fireworks.Builder fireworks() {
|
||
|
+ return ItemComponentTypesBridge.bridge().fireworks();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Lists the effects stored in this component.
|
||
|
+ *
|
||
|
+ * @return the effects
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<FireworkEffect> effects();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Number of gunpowder in this component.
|
||
|
+ *
|
||
|
+ * @return the flight duration
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @IntRange(from = 0, to = 255) int flightDuration();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link Fireworks}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<Fireworks> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the number of gunpowder used in this builder.
|
||
|
+ *
|
||
|
+ * @param duration duration
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #flightDuration()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder flightDuration(@IntRange(from = 0, to = 255) int duration);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds an explosion to this builder.
|
||
|
+ *
|
||
|
+ * @param effect effect
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #effects()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addEffect(FireworkEffect effect);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds explosions to this builder.
|
||
|
+ *
|
||
|
+ * @param effects effects
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #effects()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addEffects(List<FireworkEffect> effects);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/FoodProperties.java b/src/main/java/io/papermc/paper/datacomponent/item/FoodProperties.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..369208e15a0e7fc91a9505fef2097c4283445e4a
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/FoodProperties.java
|
||
|
@@ -0,0 +1,87 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.BuildableDataComponent;
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import org.checkerframework.checker.index.qual.NonNegative;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the food properties of an item.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#FOOD
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface FoodProperties extends BuildableDataComponent<FoodProperties, FoodProperties.Builder> {
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static FoodProperties.Builder food() {
|
||
|
+ return ItemComponentTypesBridge.bridge().food();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Number of food points to restore when eaten.
|
||
|
+ *
|
||
|
+ * @return the nutrition
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @NonNegative int nutrition();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Amount of saturation to restore when eaten.
|
||
|
+ *
|
||
|
+ * @return the saturation
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ float saturation();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * If {@code true}, this food can be eaten even if not hungry.
|
||
|
+ *
|
||
|
+ * @return can always be eaten
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ boolean canAlwaysEat();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link FoodProperties}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<FoodProperties> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Set if this food can always be eaten, even if the
|
||
|
+ * player is not hungry.
|
||
|
+ *
|
||
|
+ * @param canAlwaysEat true to allow always eating
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #canAlwaysEat()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder canAlwaysEat(boolean canAlwaysEat);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the saturation of the food.
|
||
|
+ *
|
||
|
+ * @param saturation the saturation
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #saturation()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder saturation(float saturation);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the nutrition of the food.
|
||
|
+ *
|
||
|
+ * @param nutrition the nutrition, must be non-negative
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #nutrition()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder nutrition(@NonNegative int nutrition);
|
||
|
+
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemAdventurePredicate.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemAdventurePredicate.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..f5061d1f349b35e5ec57d2d1c64eafb096141404
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemAdventurePredicate.java
|
||
|
@@ -0,0 +1,65 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.block.BlockPredicate;
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.List;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Controls which blocks a player in Adventure mode can do a certain action with this item.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#CAN_BREAK
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#CAN_PLACE_ON
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface ItemAdventurePredicate extends ShownInTooltip<ItemAdventurePredicate> {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static ItemAdventurePredicate itemAdventurePredicate(final List<BlockPredicate> predicates) {
|
||
|
+ return itemAdventurePredicate().addPredicates(predicates).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static ItemAdventurePredicate.Builder itemAdventurePredicate() {
|
||
|
+ return ItemComponentTypesBridge.bridge().itemAdventurePredicate();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * List of block predicates that control if the action is allowed.
|
||
|
+ *
|
||
|
+ * @return predicates
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<BlockPredicate> predicates();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link ItemAdventurePredicate}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends ShownInTooltip.Builder<Builder>, DataComponentBuilder<ItemAdventurePredicate> {
|
||
|
+ /**
|
||
|
+ * Adds a block predicate to this builder.
|
||
|
+ *
|
||
|
+ * @param predicate predicate
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #predicates()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addPredicate(BlockPredicate predicate);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds block predicates to this builder.
|
||
|
+ *
|
||
|
+ * @param predicates predicates
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #predicates()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addPredicates(List<BlockPredicate> predicates);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemArmorTrim.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemArmorTrim.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..0309ae59ab7945ddfb5410930d161e2ce3d1878a
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemArmorTrim.java
|
||
|
@@ -0,0 +1,53 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import org.bukkit.inventory.meta.trim.ArmorTrim;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the trims applied to an item.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#TRIM
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface ItemArmorTrim extends ShownInTooltip<ItemArmorTrim> {
|
||
|
+
|
||
|
+ @Contract(value = "_, _ -> new", pure = true)
|
||
|
+ static ItemArmorTrim itemArmorTrim(final ArmorTrim armorTrim, final boolean showInTooltip) {
|
||
|
+ return itemArmorTrim(armorTrim).showInTooltip(showInTooltip).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static ItemArmorTrim.Builder itemArmorTrim(final ArmorTrim armorTrim) {
|
||
|
+ return ItemComponentTypesBridge.bridge().itemArmorTrim(armorTrim);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Armor trim present on this item.
|
||
|
+ *
|
||
|
+ * @return trim
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ ArmorTrim armorTrim();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link ItemArmorTrim}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends ShownInTooltip.Builder<Builder>, DataComponentBuilder<ItemArmorTrim> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the armor trim for this builder.
|
||
|
+ *
|
||
|
+ * @param armorTrim trim
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #armorTrim()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder armorTrim(ArmorTrim armorTrim);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemAttributeModifiers.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemAttributeModifiers.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..948505d38121d54df62e6a67d4597bc7d42c356f
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemAttributeModifiers.java
|
||
|
@@ -0,0 +1,98 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.List;
|
||
|
+import org.bukkit.attribute.Attribute;
|
||
|
+import org.bukkit.attribute.AttributeModifier;
|
||
|
+import org.bukkit.inventory.EquipmentSlotGroup;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds attribute modifiers applied to any item.
|
||
|
+ *
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#ATTRIBUTE_MODIFIERS
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface ItemAttributeModifiers extends ShownInTooltip<ItemAttributeModifiers> {
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static ItemAttributeModifiers.Builder itemAttributes() {
|
||
|
+ return ItemComponentTypesBridge.bridge().modifiers();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Lists the attribute modifiers that are present on this item.
|
||
|
+ *
|
||
|
+ * @return modifiers
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<Entry> modifiers();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Holds an attribute entry.
|
||
|
+ */
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Entry {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the target attribute for the paired modifier.
|
||
|
+ *
|
||
|
+ * @return the attribute
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ Attribute attribute();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The modifier for the paired attribute.
|
||
|
+ *
|
||
|
+ * @return the modifier
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ AttributeModifier modifier();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the slot group for this attribute.
|
||
|
+ *
|
||
|
+ * @return the slot group
|
||
|
+ */
|
||
|
+ default EquipmentSlotGroup getGroup() {
|
||
|
+ return this.modifier().getSlotGroup();
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link ItemAttributeModifiers}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends ShownInTooltip.Builder<Builder>, DataComponentBuilder<ItemAttributeModifiers> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a modifier to this builder.
|
||
|
+ *
|
||
|
+ * @param attribute attribute
|
||
|
+ * @param modifier modifier
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #modifiers()
|
||
|
+ */
|
||
|
+ @Contract(value = "_, _, _ -> this", mutates = "this")
|
||
|
+ Builder addModifier(Attribute attribute, AttributeModifier modifier);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a modifier to this builder.
|
||
|
+ *
|
||
|
+ * @param attribute attribute
|
||
|
+ * @param modifier modifier
|
||
|
+ * @param equipmentSlotGroup the slot group this modifier applies to (overrides any slot group in the modifier)
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #modifiers()
|
||
|
+ */
|
||
|
+ @Contract(value = "_, _, _ -> this", mutates = "this")
|
||
|
+ Builder addModifier(Attribute attribute, AttributeModifier modifier, EquipmentSlotGroup equipmentSlotGroup);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemComponentTypesBridge.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemComponentTypesBridge.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..1ce34642371a65590ce1ac74b402ccfc301671d7
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemComponentTypesBridge.java
|
||
|
@@ -0,0 +1,112 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||
|
+import io.papermc.paper.registry.set.RegistryKeySet;
|
||
|
+import io.papermc.paper.registry.tag.TagKey;
|
||
|
+import io.papermc.paper.text.Filtered;
|
||
|
+import java.util.Optional;
|
||
|
+import java.util.ServiceLoader;
|
||
|
+import net.kyori.adventure.key.Key;
|
||
|
+import net.kyori.adventure.util.TriState;
|
||
|
+import org.bukkit.JukeboxSong;
|
||
|
+import org.bukkit.block.BlockType;
|
||
|
+import org.bukkit.damage.DamageType;
|
||
|
+import org.bukkit.inventory.EquipmentSlot;
|
||
|
+import org.bukkit.inventory.ItemStack;
|
||
|
+import org.bukkit.inventory.ItemType;
|
||
|
+import org.bukkit.inventory.meta.trim.ArmorTrim;
|
||
|
+import org.bukkit.map.MapCursor;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Internal
|
||
|
+interface ItemComponentTypesBridge {
|
||
|
+
|
||
|
+ Optional<ItemComponentTypesBridge> BRIDGE = ServiceLoader.load(ItemComponentTypesBridge.class).findFirst();
|
||
|
+
|
||
|
+ static ItemComponentTypesBridge bridge() {
|
||
|
+ return BRIDGE.orElseThrow();
|
||
|
+ }
|
||
|
+
|
||
|
+ ChargedProjectiles.Builder chargedProjectiles();
|
||
|
+
|
||
|
+ PotDecorations.Builder potDecorations();
|
||
|
+
|
||
|
+ Unbreakable.Builder unbreakable();
|
||
|
+
|
||
|
+ ItemLore.Builder lore();
|
||
|
+
|
||
|
+ ItemEnchantments.Builder enchantments();
|
||
|
+
|
||
|
+ ItemAttributeModifiers.Builder modifiers();
|
||
|
+
|
||
|
+ FoodProperties.Builder food();
|
||
|
+
|
||
|
+ DyedItemColor.Builder dyedItemColor();
|
||
|
+
|
||
|
+ PotionContents.Builder potionContents();
|
||
|
+
|
||
|
+ BundleContents.Builder bundleContents();
|
||
|
+
|
||
|
+ SuspiciousStewEffects.Builder suspiciousStewEffects();
|
||
|
+
|
||
|
+ MapItemColor.Builder mapItemColor();
|
||
|
+
|
||
|
+ MapDecorations.Builder mapDecorations();
|
||
|
+
|
||
|
+ MapDecorations.DecorationEntry decorationEntry(MapCursor.Type type, double x, double z, float rotation);
|
||
|
+
|
||
|
+ SeededContainerLoot.Builder seededContainerLoot(Key lootTableKey);
|
||
|
+
|
||
|
+ WrittenBookContent.Builder writtenBookContent(Filtered<String> title, String author);
|
||
|
+
|
||
|
+ WritableBookContent.Builder writeableBookContent();
|
||
|
+
|
||
|
+ ItemArmorTrim.Builder itemArmorTrim(ArmorTrim armorTrim);
|
||
|
+
|
||
|
+ LodestoneTracker.Builder lodestoneTracker();
|
||
|
+
|
||
|
+ Fireworks.Builder fireworks();
|
||
|
+
|
||
|
+ ResolvableProfile.Builder resolvableProfile();
|
||
|
+
|
||
|
+ ResolvableProfile resolvableProfile(PlayerProfile profile);
|
||
|
+
|
||
|
+ BannerPatternLayers.Builder bannerPatternLayers();
|
||
|
+
|
||
|
+ BlockItemDataProperties.Builder blockItemStateProperties();
|
||
|
+
|
||
|
+ ItemContainerContents.Builder itemContainerContents();
|
||
|
+
|
||
|
+ JukeboxPlayable.Builder jukeboxPlayable(JukeboxSong song);
|
||
|
+
|
||
|
+ Tool.Builder tool();
|
||
|
+
|
||
|
+ Tool.Rule rule(RegistryKeySet<BlockType> blocks, @Nullable Float speed, TriState correctForDrops);
|
||
|
+
|
||
|
+ ItemAdventurePredicate.Builder itemAdventurePredicate();
|
||
|
+
|
||
|
+ CustomModelData customModelData(int id);
|
||
|
+
|
||
|
+ MapId mapId(int id);
|
||
|
+
|
||
|
+ UseRemainder useRemainder(ItemStack itemStack);
|
||
|
+
|
||
|
+ Consumable.Builder consumable();
|
||
|
+
|
||
|
+ UseCooldown.Builder useCooldown(final float seconds);
|
||
|
+
|
||
|
+ DamageResistant damageResistant(TagKey<DamageType> types);
|
||
|
+
|
||
|
+ Enchantable enchantable(int level);
|
||
|
+
|
||
|
+ Repairable repairable(RegistryKeySet<ItemType> types);
|
||
|
+
|
||
|
+ Equippable.Builder equippable(EquipmentSlot slot);
|
||
|
+
|
||
|
+ DeathProtection.Builder deathProtection();
|
||
|
+
|
||
|
+ OminousBottleAmplifier ominousBottleAmplifier(int amplifier);
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemContainerContents.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemContainerContents.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..7d1c973ba566752d7a85496327b1352d973f2218
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemContainerContents.java
|
||
|
@@ -0,0 +1,63 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.Arrays;
|
||
|
+import java.util.List;
|
||
|
+import org.bukkit.inventory.ItemStack;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the contents of an item container.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#CONTAINER
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface ItemContainerContents {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static ItemContainerContents containerContents(final List<ItemStack> contents) {
|
||
|
+ return containerContents().addAll(contents).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static ItemContainerContents.Builder containerContents() {
|
||
|
+ return ItemComponentTypesBridge.bridge().itemContainerContents();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the contents of the container.
|
||
|
+ *
|
||
|
+ * @return the contents
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ @Unmodifiable List<ItemStack> contents();
|
||
|
+
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<ItemContainerContents> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds an item stack to the container.
|
||
|
+ *
|
||
|
+ * @param stack the item stack
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #contents()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder add(ItemStack stack);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds item stacks to the container.
|
||
|
+ *
|
||
|
+ * @param stacks the item stacks
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #contents()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addAll(List<ItemStack> stacks);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemEnchantments.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemEnchantments.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..fca271ea198209bd48cd02f4476e89e5e3e9f396
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemEnchantments.java
|
||
|
@@ -0,0 +1,68 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.Map;
|
||
|
+import org.bukkit.enchantments.Enchantment;
|
||
|
+import org.checkerframework.common.value.qual.IntRange;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Stores a list of enchantments and their levels on an item.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#ENCHANTMENTS
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#STORED_ENCHANTMENTS
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface ItemEnchantments extends ShownInTooltip<ItemEnchantments> {
|
||
|
+
|
||
|
+ @Contract(value = "_, _ -> new", pure = true)
|
||
|
+ static ItemEnchantments itemEnchantments(final Map<Enchantment, @IntRange(from = 1, to = 255) Integer> enchantments, final boolean showInTooltip) {
|
||
|
+ return itemEnchantments().addAll(enchantments).showInTooltip(showInTooltip).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static ItemEnchantments.Builder itemEnchantments() {
|
||
|
+ return ItemComponentTypesBridge.bridge().enchantments();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Enchantments currently present on this item.
|
||
|
+ *
|
||
|
+ * @return enchantments
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable Map<Enchantment, @IntRange(from = 1, to = 255) Integer> enchantments();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link ItemEnchantments}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends ShownInTooltip.Builder<Builder>, DataComponentBuilder<ItemEnchantments> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds an enchantment with the given level to this component.
|
||
|
+ *
|
||
|
+ * @param enchantment enchantment
|
||
|
+ * @param level level
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #enchantments()
|
||
|
+ */
|
||
|
+ @Contract(value = "_, _ -> this", mutates = "this")
|
||
|
+ Builder add(Enchantment enchantment, @IntRange(from = 1, to = 255) int level);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds enchantments with the given level to this component.
|
||
|
+ *
|
||
|
+ * @param enchantments enchantments
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #enchantments()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addAll(Map<Enchantment, @IntRange(from = 1, to = 255) Integer> enchantments);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ItemLore.java b/src/main/java/io/papermc/paper/datacomponent/item/ItemLore.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..3be62f6005e0343c3a6ebd04e3ee824e0b969113
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/ItemLore.java
|
||
|
@@ -0,0 +1,84 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.List;
|
||
|
+import net.kyori.adventure.text.Component;
|
||
|
+import net.kyori.adventure.text.ComponentLike;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Additional lines to include in an item's tooltip.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#LORE
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface ItemLore {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static ItemLore lore(final List<? extends ComponentLike> lines) {
|
||
|
+ return lore().lines(lines).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static ItemLore.Builder lore() {
|
||
|
+ return ItemComponentTypesBridge.bridge().lore();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Lists the components that are added to an item's tooltip.
|
||
|
+ *
|
||
|
+ * @return component list
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<Component> lines();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Lists the styled components (example: italicized and purple) that are added to an item's tooltip.
|
||
|
+ *
|
||
|
+ * @return component list
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<Component> styledLines();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link ItemLore}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<ItemLore> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the components of this lore.
|
||
|
+ *
|
||
|
+ * @param lines components
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #lines()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder lines(List<? extends ComponentLike> lines);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a component to the lore.
|
||
|
+ *
|
||
|
+ * @param line component
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #lines()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addLine(ComponentLike line);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds components to the lore.
|
||
|
+ *
|
||
|
+ * @param lines components
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #lines()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addLines(List<? extends ComponentLike> lines);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/JukeboxPlayable.java b/src/main/java/io/papermc/paper/datacomponent/item/JukeboxPlayable.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..c59942df7101c7630eabeb247b9690b9c4c76da4
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/JukeboxPlayable.java
|
||
|
@@ -0,0 +1,43 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import org.bukkit.JukeboxSong;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the jukebox song for an item.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#JUKEBOX_PLAYABLE
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface JukeboxPlayable extends ShownInTooltip<JukeboxPlayable> {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static JukeboxPlayable.Builder jukeboxPlayable(final JukeboxSong song) {
|
||
|
+ return ItemComponentTypesBridge.bridge().jukeboxPlayable(song);
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ JukeboxSong jukeboxSong();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link JukeboxPlayable}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends ShownInTooltip.Builder<JukeboxPlayable.Builder>, DataComponentBuilder<JukeboxPlayable> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the jukebox song.
|
||
|
+ *
|
||
|
+ * @param song the song
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #jukeboxSong()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder jukeboxSong(JukeboxSong song);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/LodestoneTracker.java b/src/main/java/io/papermc/paper/datacomponent/item/LodestoneTracker.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..b919672ceea74ae09324653847b30fde293054d8
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/LodestoneTracker.java
|
||
|
@@ -0,0 +1,72 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import org.bukkit.Location;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+/**
|
||
|
+ * If present, specifies the target Lodestone that a Compass should point towards.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#LODESTONE_TRACKER
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface LodestoneTracker {
|
||
|
+
|
||
|
+ @Contract(value = "_, _ -> new", pure = true)
|
||
|
+ static LodestoneTracker lodestoneTracker(final @Nullable Location location, final boolean tracked) {
|
||
|
+ return lodestoneTracker().location(location).tracked(tracked).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static LodestoneTracker.Builder lodestoneTracker() {
|
||
|
+ return ItemComponentTypesBridge.bridge().lodestoneTracker();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The location that the compass should point towards.
|
||
|
+ *
|
||
|
+ * @return location
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ @Nullable Location location();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * If {@code true}, when the Lodestone at the target position is removed, the component will be removed.
|
||
|
+ *
|
||
|
+ * @return tracked
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ boolean tracked();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link LodestoneTracker}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<LodestoneTracker> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the location to point towards for this builder.
|
||
|
+ *
|
||
|
+ * @param location location to point towards
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #location()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder location(@Nullable Location location);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets if this location lodestone is tracked for this builder.
|
||
|
+ *
|
||
|
+ * @param tracked is tracked
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #tracked()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder tracked(boolean tracked);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/MapDecorations.java b/src/main/java/io/papermc/paper/datacomponent/item/MapDecorations.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..1e611f1f918c33f8d89ad23cf2fc44a127af233c
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/MapDecorations.java
|
||
|
@@ -0,0 +1,121 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.Map;
|
||
|
+import org.bukkit.map.MapCursor;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds a list of markers to be placed on a Filled Map (used for Explorer Maps).
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#MAP_DECORATIONS
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface MapDecorations {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static MapDecorations mapDecorations(final Map<String, DecorationEntry> entries) {
|
||
|
+ return mapDecorations().putAll(entries).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static MapDecorations.Builder mapDecorations() {
|
||
|
+ return ItemComponentTypesBridge.bridge().mapDecorations();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "_, _, _, _ -> new", pure = true)
|
||
|
+ static DecorationEntry decorationEntry(final MapCursor.Type type, final double x, final double z, final float rotation) {
|
||
|
+ return ItemComponentTypesBridge.bridge().decorationEntry(type, x, z, rotation);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the decoration entry with the given id.
|
||
|
+ *
|
||
|
+ * @param id id
|
||
|
+ * @return decoration entry, or {@code null} if not present
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable DecorationEntry decoration(String id);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the decoration entries.
|
||
|
+ *
|
||
|
+ * @return the decoration entries
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable Map<String, DecorationEntry> decorations();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Decoration present on the map.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface DecorationEntry {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Type of decoration.
|
||
|
+ *
|
||
|
+ * @return type
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ MapCursor.Type type();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * X world coordinate of the decoration.
|
||
|
+ *
|
||
|
+ * @return x coordinate
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ double x();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Z world coordinate of the decoration.
|
||
|
+ *
|
||
|
+ * @return z coordinate
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ double z();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Clockwise rotation from north in degrees.
|
||
|
+ *
|
||
|
+ * @return rotation
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ float rotation();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link MapDecorations}.
|
||
|
+ */
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ interface Builder extends DataComponentBuilder<MapDecorations> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Puts the decoration with the given id in this builder.
|
||
|
+ *
|
||
|
+ * @param id id
|
||
|
+ * @param entry decoration
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #decorations()
|
||
|
+ */
|
||
|
+ @Contract(value = "_, _ -> this", mutates = "this")
|
||
|
+ MapDecorations.Builder put(String id, DecorationEntry entry);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Puts all the decoration with the given id in this builder.
|
||
|
+ *
|
||
|
+ * @param entries decorations
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #decorations()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ MapDecorations.Builder putAll(Map<String, DecorationEntry> entries);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/MapId.java b/src/main/java/io/papermc/paper/datacomponent/item/MapId.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..045bfe0ce5080b57a40be03a65b1a2aaf9089120
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/MapId.java
|
||
|
@@ -0,0 +1,28 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * References the shared map state holding map contents and markers for a Filled Map.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#MAP_ID
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+@ApiStatus.Experimental
|
||
|
+public interface MapId {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static MapId mapId(final int id) {
|
||
|
+ return ItemComponentTypesBridge.bridge().mapId(id);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The map id.
|
||
|
+ *
|
||
|
+ * @return id
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ int id();
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/MapItemColor.java b/src/main/java/io/papermc/paper/datacomponent/item/MapItemColor.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..87845d19a25ed2ae79b868fcfe40b88a2dc83f97
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/MapItemColor.java
|
||
|
@@ -0,0 +1,43 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import org.bukkit.Color;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Represents the tint of the decorations on the Filled Map item.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#MAP_COLOR
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface MapItemColor {
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static MapItemColor.Builder mapItemColor() {
|
||
|
+ return ItemComponentTypesBridge.bridge().mapItemColor();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The tint to apply.
|
||
|
+ *
|
||
|
+ * @return color
|
||
|
+ */
|
||
|
+ Color color();
|
||
|
+
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<MapItemColor> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the tint color of this map.
|
||
|
+ *
|
||
|
+ * @param color tint color
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #color()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder color(Color color);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/OminousBottleAmplifier.java b/src/main/java/io/papermc/paper/datacomponent/item/OminousBottleAmplifier.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..4f16e08f04c2cea24f3cb132ff21f4bdd6b70582
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/OminousBottleAmplifier.java
|
||
|
@@ -0,0 +1,29 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import org.checkerframework.common.value.qual.IntRange;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the ominous bottle amplifier.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#OMINOUS_BOTTLE_AMPLIFIER
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface OminousBottleAmplifier {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static OminousBottleAmplifier amplifier(final @IntRange(from = 0, to = 4) int amplifier) {
|
||
|
+ return ItemComponentTypesBridge.bridge().ominousBottleAmplifier(amplifier);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the bottle amplifier.
|
||
|
+ *
|
||
|
+ * @return the amplifier
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @IntRange(from = 0, to = 4) int amplifier();
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PotDecorations.java b/src/main/java/io/papermc/paper/datacomponent/item/PotDecorations.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..6da78b8735a6cadd1282fa2fafd8b0f74f087fb4
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/PotDecorations.java
|
||
|
@@ -0,0 +1,109 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import org.bukkit.inventory.ItemType;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+// CONTRIBUTORS: LEAVE THIS AS ITEM TYPE!!!
|
||
|
+/**
|
||
|
+ * Holds the item types for the decorations on a flower pot.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#POT_DECORATIONS
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface PotDecorations {
|
||
|
+
|
||
|
+ @Contract(value = "_, _, _, _ -> new", pure = true)
|
||
|
+ static PotDecorations potDecorations(final @Nullable ItemType back, final @Nullable ItemType left, final @Nullable ItemType right, final @Nullable ItemType front) {
|
||
|
+ return potDecorations().back(back).left(left).right(right).front(front).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static PotDecorations.Builder potDecorations() {
|
||
|
+ return ItemComponentTypesBridge.bridge().potDecorations();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Get the item type for the back.
|
||
|
+ *
|
||
|
+ * @return the back item type.
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable ItemType back();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Get the item type for the left.
|
||
|
+ *
|
||
|
+ * @return the left item type.
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable ItemType left();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Get the item type for the right.
|
||
|
+ *
|
||
|
+ * @return the right item type.
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable ItemType right();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Get the item type for the front.
|
||
|
+ *
|
||
|
+ * @return the front item type.
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable ItemType front();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link PotDecorations}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<PotDecorations> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Set the {@link ItemType} for the back.
|
||
|
+ *
|
||
|
+ * @param back item for the back
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #back()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder back(@Nullable ItemType back);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Set the {@link ItemType} for the left.
|
||
|
+ *
|
||
|
+ * @param left item for the left
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #left()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder left(@Nullable ItemType left);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Set the {@link ItemType} for the right.
|
||
|
+ *
|
||
|
+ * @param right item for the right
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #right()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder right(@Nullable ItemType right);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Set the {@link ItemType} for the front.
|
||
|
+ *
|
||
|
+ * @param front item for the front
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #front()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder front(@Nullable ItemType front);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java b/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..7cf05b382319064d45433a7e2678f65c25d11b14
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java
|
||
|
@@ -0,0 +1,120 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.List;
|
||
|
+import org.bukkit.Color;
|
||
|
+import org.bukkit.potion.PotionEffect;
|
||
|
+import org.bukkit.potion.PotionType;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the contents of a potion (Potion, Splash Potion, Lingering Potion), or potion applied to a Tipped Arrow.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#POTION_CONTENTS
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface PotionContents {
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static PotionContents.Builder potionContents() {
|
||
|
+ return ItemComponentTypesBridge.bridge().potionContents();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The potion type in this item: the item will inherit all effects from this.
|
||
|
+ *
|
||
|
+ * @return potion type, or {@code null} if not present
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable PotionType potion();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Overrides the visual color of the potion.
|
||
|
+ *
|
||
|
+ * @return color override, or {@code null} if not present
|
||
|
+ * @apiNote alpha channel of the color is only relevant
|
||
|
+ * for Tipped Arrow
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable Color customColor();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Additional list of effect instances that this item should apply.
|
||
|
+ *
|
||
|
+ * @return effects
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<PotionEffect> customEffects();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Suffix to the translation key of the potion item.
|
||
|
+ *
|
||
|
+ * @return translation key suffix, or {@code null} if not present
|
||
|
+ * @apiNote This is used in the display of tipped arrow and potion items.
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable String customName();
|
||
|
+
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<PotionContents> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the potion type for this builder.
|
||
|
+ *
|
||
|
+ * @param type builder
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #potion()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder potion(@Nullable PotionType type);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the color override for this builder.
|
||
|
+ *
|
||
|
+ * @param color color
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #customColor()
|
||
|
+ * @apiNote alpha channel of the color is supported only for Tipped Arrow
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder customColor(@Nullable Color color);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the suffix to the translation key of the potion item.
|
||
|
+ *
|
||
|
+ * @param name name
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #customName()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder customName(@Nullable String name);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a custom effect instance to this builder.
|
||
|
+ *
|
||
|
+ * @param effect effect
|
||
|
+ * @see #customEffects()
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #customEffects()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addCustomEffect(PotionEffect effect);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds custom effect instances to this builder.
|
||
|
+ *
|
||
|
+ * @param effects effects
|
||
|
+ * @see #customEffects()
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #customEffects()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addCustomEffects(List<PotionEffect> effects);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Repairable.java b/src/main/java/io/papermc/paper/datacomponent/item/Repairable.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..ff84d9123aab0ad2f93b397e20a37f21894547a3
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/Repairable.java
|
||
|
@@ -0,0 +1,30 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.registry.set.RegistryKeySet;
|
||
|
+import org.bukkit.inventory.ItemType;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds if this item is repairable, and what item types it can be repaired with.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#REPAIRABLE
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface Repairable {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static Repairable repairable(final RegistryKeySet<ItemType> types) {
|
||
|
+ return ItemComponentTypesBridge.bridge().repairable(types);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The types that this item is repairable to.
|
||
|
+ *
|
||
|
+ * @return item
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ RegistryKeySet<ItemType> types();
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ResolvableProfile.java b/src/main/java/io/papermc/paper/datacomponent/item/ResolvableProfile.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..dc6cd191553e7ca5b6c5768f594924e4c39fcbbe
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/ResolvableProfile.java
|
||
|
@@ -0,0 +1,123 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||
|
+import com.destroystokyo.paper.profile.ProfileProperty;
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import java.util.Collection;
|
||
|
+import java.util.UUID;
|
||
|
+import java.util.concurrent.CompletableFuture;
|
||
|
+import org.intellij.lang.annotations.Pattern;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds player profile data that can be resolved to a {@link PlayerProfile}.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#PROFILE
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface ResolvableProfile {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static ResolvableProfile resolvableProfile(final PlayerProfile profile) {
|
||
|
+ return ItemComponentTypesBridge.bridge().resolvableProfile(profile);
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static ResolvableProfile.Builder resolvableProfile() {
|
||
|
+ return ItemComponentTypesBridge.bridge().resolvableProfile();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable UUID uuid();
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable String name();
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable Collection<ProfileProperty> properties();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Produces an updated player profile based on this.
|
||
|
+ * <p>
|
||
|
+ * This tries to produce a completed profile by filling in missing
|
||
|
+ * properties (name, unique id, textures, etc.), and updates existing
|
||
|
+ * properties (e.g. name, textures, etc.) to their official and up-to-date
|
||
|
+ * values. This operation does not alter the current profile, but produces a
|
||
|
+ * new updated {@link PlayerProfile}.
|
||
|
+ * <p>
|
||
|
+ * If no player exists for the unique id or name of this profile, this
|
||
|
+ * operation yields a profile that is equal to the current profile, which
|
||
|
+ * might not be complete.
|
||
|
+ * <p>
|
||
|
+ * This is an asynchronous operation: Updating the profile can result in an
|
||
|
+ * outgoing connection in another thread in order to fetch the latest
|
||
|
+ * profile properties. The returned {@link CompletableFuture} will be
|
||
|
+ * completed once the updated profile is available. In order to not block
|
||
|
+ * the server's main thread, you should not wait for the result of the
|
||
|
+ * returned CompletableFuture on the server's main thread. Instead, if you
|
||
|
+ * want to do something with the updated player profile on the server's main
|
||
|
+ * thread once it is available, you could do something like this:
|
||
|
+ * <pre>
|
||
|
+ * profile.resolve().thenAcceptAsync(updatedProfile -> {
|
||
|
+ * // Do something with the updated profile:
|
||
|
+ * // ...
|
||
|
+ * }, runnable -> Bukkit.getScheduler().runTask(plugin, runnable));
|
||
|
+ * </pre>
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ CompletableFuture<PlayerProfile> resolve();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link ResolvableProfile}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<ResolvableProfile> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the name for this profile. Must be 16-or-less
|
||
|
+ * characters and not contain invalid characters.
|
||
|
+ *
|
||
|
+ * @param name the name
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #name()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder name(@Pattern("^[!-~]{0,16}$") @Nullable String name);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the UUID for this profile.
|
||
|
+ *
|
||
|
+ * @param uuid the UUID
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #uuid()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder uuid(@Nullable UUID uuid);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a property to this profile.
|
||
|
+ *
|
||
|
+ * @param property the property
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #properties()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addProperty(ProfileProperty property);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds properties to this profile.
|
||
|
+ *
|
||
|
+ * @param properties the properties
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #properties()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addProperties(Collection<ProfileProperty> properties);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/SeededContainerLoot.java b/src/main/java/io/papermc/paper/datacomponent/item/SeededContainerLoot.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..f79af65e8f3f8ffbb9be1cf1c6b537cd1e2b1031
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/SeededContainerLoot.java
|
||
|
@@ -0,0 +1,71 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import net.kyori.adventure.key.Key;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the loot table and seed for a container.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#CONTAINER_LOOT
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface SeededContainerLoot {
|
||
|
+
|
||
|
+ @Contract(value = "_, _ -> new", pure = true)
|
||
|
+ static SeededContainerLoot seededContainerLoot(final Key lootTableKey, final long seed) {
|
||
|
+ return SeededContainerLoot.seededContainerLoot(lootTableKey).seed(seed).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static SeededContainerLoot.Builder seededContainerLoot(final Key lootTableKey) {
|
||
|
+ return ItemComponentTypesBridge.bridge().seededContainerLoot(lootTableKey);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the loot table key.
|
||
|
+ *
|
||
|
+ * @return the loot table key
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ Key lootTable();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the loot table seed.
|
||
|
+ *
|
||
|
+ * @return the seed
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ long seed();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link SeededContainerLoot}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<SeededContainerLoot> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the loot table key.
|
||
|
+ *
|
||
|
+ * @param key the loot table key
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #lootTable()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder lootTable(Key key);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the loot table seed.
|
||
|
+ *
|
||
|
+ * @param seed the seed
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #seed()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder seed(long seed);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/ShownInTooltip.java b/src/main/java/io/papermc/paper/datacomponent/item/ShownInTooltip.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..7e058aebcbd768517f6db51540598721cdae4425
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/ShownInTooltip.java
|
||
|
@@ -0,0 +1,52 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the state of whether a data component should be shown
|
||
|
+ * in an item's tooltip.
|
||
|
+ * @param <T> the data component type
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface ShownInTooltip<T> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets if the data component should be shown in the item's tooltip.
|
||
|
+ *
|
||
|
+ * @return {@code true} to show in the tooltip
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ boolean showInTooltip();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Returns a copy of this data component with the specified
|
||
|
+ * show-in-tooltip state.
|
||
|
+ * @param showInTooltip {@code true} to show in the tooltip
|
||
|
+ * @return the new data component
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ T showInTooltip(boolean showInTooltip);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * A builder for creating a {@link ShownInTooltip} data component.
|
||
|
+ * @param <B> builder type
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder<B> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets if the data component should be shown in the item's tooltip.
|
||
|
+ *
|
||
|
+ * @param showInTooltip {@code true} to show in the tooltip
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #showInTooltip()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ B showInTooltip(boolean showInTooltip);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/SuspiciousStewEffects.java b/src/main/java/io/papermc/paper/datacomponent/item/SuspiciousStewEffects.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..422bb5ccc42b94b60fba6714e9e6fb8aced6eb0c
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/SuspiciousStewEffects.java
|
||
|
@@ -0,0 +1,67 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import io.papermc.paper.potion.SuspiciousEffectEntry;
|
||
|
+import java.util.Arrays;
|
||
|
+import java.util.Collection;
|
||
|
+import java.util.List;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the effects that will be applied when consuming Suspicious Stew.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#SUSPICIOUS_STEW_EFFECTS
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface SuspiciousStewEffects {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static SuspiciousStewEffects suspiciousStewEffects(final Collection<SuspiciousEffectEntry> effects) {
|
||
|
+ return suspiciousStewEffects().addAll(effects).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static SuspiciousStewEffects.Builder suspiciousStewEffects() {
|
||
|
+ return ItemComponentTypesBridge.bridge().suspiciousStewEffects();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Effects that will be applied when consuming Suspicious Stew.
|
||
|
+ *
|
||
|
+ * @return effects
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<SuspiciousEffectEntry> effects();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link SuspiciousStewEffects}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<SuspiciousStewEffects> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds an effect applied to this builder.
|
||
|
+ *
|
||
|
+ * @param entry effect
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #effects()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder add(SuspiciousEffectEntry entry);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds effects applied to this builder.
|
||
|
+ *
|
||
|
+ * @param entries effect
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #effects()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addAll(Collection<SuspiciousEffectEntry> entries);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Tool.java b/src/main/java/io/papermc/paper/datacomponent/item/Tool.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..4e87feb83204266e1fefdafe7b7e5ac53da3160e
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/Tool.java
|
||
|
@@ -0,0 +1,149 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import io.papermc.paper.registry.set.RegistryKeySet;
|
||
|
+import java.util.Collection;
|
||
|
+import java.util.List;
|
||
|
+import net.kyori.adventure.util.TriState;
|
||
|
+import org.bukkit.block.BlockType;
|
||
|
+import org.checkerframework.checker.index.qual.NonNegative;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Controls the behavior of the item as a tool.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#TOOL
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface Tool {
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static Tool.Builder tool() {
|
||
|
+ return ItemComponentTypesBridge.bridge().tool();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Creates a mining rule that specifies how an item interacts with certain block types.
|
||
|
+ *
|
||
|
+ * <p>This method allows you to define a rule for a set of block types, optionally setting a custom mining speed
|
||
|
+ * and determining whether the item should correct for drops when mining these blocks.</p>
|
||
|
+ *
|
||
|
+ * @param blocks The set of block types this rule applies to.
|
||
|
+ * @param speed The custom mining speed multiplier for these blocks. If {@code null}, the default speed is used.
|
||
|
+ * @param correctForDrops A {@link TriState} indicating how to handle item drops:
|
||
|
+ * <ul>
|
||
|
+ * <li>{@link TriState#TRUE} - Items will be dropped.</li>
|
||
|
+ * <li>{@link TriState#FALSE} - Items will not be dropped.</li>
|
||
|
+ * <li>{@link TriState#NOT_SET} - The default drop behavior is used.</li>
|
||
|
+ * </ul>
|
||
|
+ * @return A new {@link Rule} instance representing the mining rule.
|
||
|
+ */
|
||
|
+ static Rule rule(final RegistryKeySet<BlockType> blocks, final @Nullable Float speed, final TriState correctForDrops) {
|
||
|
+ return ItemComponentTypesBridge.bridge().rule(blocks, speed, correctForDrops);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Mining speed to use if no rules match and don't override mining speed.
|
||
|
+ *
|
||
|
+ * @return default mining speed
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ float defaultMiningSpeed();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Amount of durability to remove each time a block is mined with this tool.
|
||
|
+ *
|
||
|
+ * @return durability
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @NonNegative int damagePerBlock();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * List of rule entries.
|
||
|
+ *
|
||
|
+ * @return rules
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<Tool.Rule> rules();
|
||
|
+
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Rule {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Blocks to match.
|
||
|
+ *
|
||
|
+ * @return blocks
|
||
|
+ */
|
||
|
+ RegistryKeySet<BlockType> blocks();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Overrides the mining speed if present and matched.
|
||
|
+ * <p>
|
||
|
+ * {@code true} will cause the block to mine at its most efficient speed, and drop items if the targeted block requires that.
|
||
|
+ *
|
||
|
+ * @return speed override
|
||
|
+ */
|
||
|
+ @Nullable Float speed();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Overrides whether this tool is considered 'correct' if present and matched.
|
||
|
+ *
|
||
|
+ * @return a tri-state
|
||
|
+ */
|
||
|
+ TriState correctForDrops();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link Tool}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<Tool> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Controls the amount of durability to remove each time a block is mined with this tool.
|
||
|
+ *
|
||
|
+ * @param damage durability to remove
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #damagePerBlock()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder damagePerBlock(@NonNegative int damage);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Controls mining speed to use if no rules match and don't override mining speed.
|
||
|
+ *
|
||
|
+ * @param miningSpeed mining speed
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #defaultMiningSpeed()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder defaultMiningSpeed(float miningSpeed);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a rule to the tool that controls the breaking speed / damage per block if matched.
|
||
|
+ *
|
||
|
+ * @param rule rule
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #rules()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addRule(Rule rule);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds rules to the tool that control the breaking speed / damage per block if matched.
|
||
|
+ *
|
||
|
+ * @param rules rules
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #rules()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addRules(Collection<Rule> rules);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/Unbreakable.java b/src/main/java/io/papermc/paper/datacomponent/item/Unbreakable.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..498eb479dce406d2b0b470b327eac8279a0d98bc
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/Unbreakable.java
|
||
|
@@ -0,0 +1,34 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * If set, the item will not lose any durability when used.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#UNBREAKABLE
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface Unbreakable extends ShownInTooltip<Unbreakable> {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static Unbreakable unbreakable(final boolean showInTooltip) {
|
||
|
+ return unbreakable().showInTooltip(showInTooltip).build();
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static Unbreakable.Builder unbreakable() {
|
||
|
+ return ItemComponentTypesBridge.bridge().unbreakable();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link Unbreakable}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends ShownInTooltip.Builder<Builder>, DataComponentBuilder<Unbreakable> {
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/UseCooldown.java b/src/main/java/io/papermc/paper/datacomponent/item/UseCooldown.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..57fc55ad1def2bb14fc0a95ee3c0c157b0ac53fb
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/UseCooldown.java
|
||
|
@@ -0,0 +1,65 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import net.kyori.adventure.key.Key;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the contents of cooldown information when an item is used.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#USE_COOLDOWN
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface UseCooldown {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Creates a new builder for use cooldown.
|
||
|
+ *
|
||
|
+ * @param seconds the duration in seconds; must be positive
|
||
|
+ * @return builder
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static UseCooldown.Builder useCooldown(final float seconds) {
|
||
|
+ return ItemComponentTypesBridge.bridge().useCooldown(seconds);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The amount of seconds the cooldown will be active for.
|
||
|
+ *
|
||
|
+ * @return cooldown seconds
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ float seconds();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The unique resource location to identify this cooldown group.
|
||
|
+ * <p>
|
||
|
+ * This allows items to share cooldowns with other items in the same cooldown group, if present.
|
||
|
+ *
|
||
|
+ * @return cooldown group, or null if not present
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable Key cooldownGroup();
|
||
|
+
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<UseCooldown> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets a unique resource location for this cooldown group.
|
||
|
+ * <p>
|
||
|
+ * This allows items to share cooldowns with other items in the same cooldown group.
|
||
|
+ * </p>
|
||
|
+ *
|
||
|
+ * @param key the unique resource location; can be null
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #cooldownGroup()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder cooldownGroup(@Nullable Key key);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/UseRemainder.java b/src/main/java/io/papermc/paper/datacomponent/item/UseRemainder.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..50e42e073311332142980828d0beec1828570512
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/UseRemainder.java
|
||
|
@@ -0,0 +1,31 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import org.bukkit.inventory.ItemStack;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the contents of item transformation information when an item is used.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#USE_REMAINDER
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface UseRemainder {
|
||
|
+
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static UseRemainder useRemainder(final ItemStack itemStack) {
|
||
|
+ return ItemComponentTypesBridge.bridge().useRemainder(itemStack);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The item that the item that is consumed is transformed into.
|
||
|
+ *
|
||
|
+ * @return item
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ ItemStack transformInto();
|
||
|
+
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/WritableBookContent.java b/src/main/java/io/papermc/paper/datacomponent/item/WritableBookContent.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..828d3bb1c763e0f3c89a73d6b70d1f006258644f
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/WritableBookContent.java
|
||
|
@@ -0,0 +1,80 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import io.papermc.paper.text.Filtered;
|
||
|
+import java.util.List;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the pages for a writable book.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#WRITABLE_BOOK_CONTENT
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface WritableBookContent {
|
||
|
+
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static WritableBookContent.Builder writeableBookContent() {
|
||
|
+ return ItemComponentTypesBridge.bridge().writeableBookContent();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Holds the pages that can be written to for this component.
|
||
|
+ *
|
||
|
+ * @return pages, as filtered objects
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<Filtered<String>> pages();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link WritableBookContent}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<WritableBookContent> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a page that can be written to for this builder.
|
||
|
+ *
|
||
|
+ * @param page page
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #pages()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addPage(String page);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds pages that can be written to for this builder.
|
||
|
+ *
|
||
|
+ * @param pages pages
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #pages()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addPages(List<String> pages);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a filterable page that can be written to for this builder.
|
||
|
+ *
|
||
|
+ * @param page page
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #pages()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addFilteredPage(Filtered<String> page);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds filterable pages that can be written to for this builder.
|
||
|
+ *
|
||
|
+ * @param pages pages
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #pages()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addFilteredPages(List<Filtered<String>> pages);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/WrittenBookContent.java b/src/main/java/io/papermc/paper/datacomponent/item/WrittenBookContent.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..979bc05009b84b6fcdb59938cceace351e61c78b
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/WrittenBookContent.java
|
||
|
@@ -0,0 +1,172 @@
|
||
|
+package io.papermc.paper.datacomponent.item;
|
||
|
+
|
||
|
+import io.papermc.paper.datacomponent.DataComponentBuilder;
|
||
|
+import io.papermc.paper.text.Filtered;
|
||
|
+import java.util.List;
|
||
|
+import net.kyori.adventure.text.Component;
|
||
|
+import net.kyori.adventure.text.ComponentLike;
|
||
|
+import org.checkerframework.common.value.qual.IntRange;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jetbrains.annotations.Unmodifiable;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Holds the contents and metadata of a Written Book.
|
||
|
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#WRITTEN_BOOK_CONTENT
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface WrittenBookContent {
|
||
|
+
|
||
|
+ @Contract(value = "_, _ -> new", pure = true)
|
||
|
+ static WrittenBookContent.Builder writtenBookContent(final String title, final String author) {
|
||
|
+ return writtenBookContent(Filtered.of(title, null), author);
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(value = "_, _ -> new", pure = true)
|
||
|
+ static WrittenBookContent.Builder writtenBookContent(final Filtered<String> title, final String author) {
|
||
|
+ return ItemComponentTypesBridge.bridge().writtenBookContent(title, author);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Title of this book.
|
||
|
+ *
|
||
|
+ * @return title
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ Filtered<String> title();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Player name of the author of this book.
|
||
|
+ *
|
||
|
+ * @return author
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ String author();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The number of times this book has been copied (0 = original).
|
||
|
+ *
|
||
|
+ * @return generation
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @IntRange(from = 0, to = 3) int generation();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the pages of this book.
|
||
|
+ *
|
||
|
+ * @return pages
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Unmodifiable List<Filtered<Component>> pages();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * If the chat components in this book have already been resolved (entity selectors, scores substituted).
|
||
|
+ * If {@code false}, will be resolved when opened by a player.
|
||
|
+ *
|
||
|
+ * @return resolved
|
||
|
+ */
|
||
|
+ @Contract(pure = true)
|
||
|
+ boolean resolved();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Builder for {@link WrittenBookContent}.
|
||
|
+ */
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface Builder extends DataComponentBuilder<WrittenBookContent> {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the title of this book.
|
||
|
+ *
|
||
|
+ * @param title the title
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #title()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder title(String title);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the filterable title of this book.
|
||
|
+ *
|
||
|
+ * @param title the title
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #title()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder filteredTitle(Filtered<String> title);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the author of this book.
|
||
|
+ *
|
||
|
+ * @param author the author
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #author()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder author(String author);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the generation of this book.
|
||
|
+ *
|
||
|
+ * @param generation the generation, [0-3]
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #generation()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder generation(@IntRange(from = 0, to = 3) int generation);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets if the chat components in this book have already been resolved (entity selectors, scores substituted).
|
||
|
+ * If {@code false}, will be resolved when opened by a player.
|
||
|
+ *
|
||
|
+ * @param resolved resolved
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #resolved()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder resolved(boolean resolved);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a page to this book.
|
||
|
+ *
|
||
|
+ * @param page the page
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #pages()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addPage(ComponentLike page);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds pages to this book.
|
||
|
+ *
|
||
|
+ * @param page the pages
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #pages()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addPages(List<? extends ComponentLike> page);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a filterable page to this book.
|
||
|
+ *
|
||
|
+ * @param page the page
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #pages()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addFilteredPage(Filtered<? extends ComponentLike> page);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds filterable pages to this book.
|
||
|
+ *
|
||
|
+ * @param pages the pages
|
||
|
+ * @return the builder for chaining
|
||
|
+ * @see #pages()
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> this", mutates = "this")
|
||
|
+ Builder addFilteredPages(List<Filtered<? extends ComponentLike>> pages);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumableTypesBridge.java b/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumableTypesBridge.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..a845ccfc21f101f0632249745bbd8b334f85e72c
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumableTypesBridge.java
|
||
|
@@ -0,0 +1,32 @@
|
||
|
+package io.papermc.paper.datacomponent.item.consumable;
|
||
|
+
|
||
|
+import io.papermc.paper.registry.set.RegistryKeySet;
|
||
|
+import java.util.List;
|
||
|
+import java.util.Optional;
|
||
|
+import java.util.ServiceLoader;
|
||
|
+import net.kyori.adventure.key.Key;
|
||
|
+import org.bukkit.potion.PotionEffect;
|
||
|
+import org.bukkit.potion.PotionEffectType;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Internal
|
||
|
+interface ConsumableTypesBridge {
|
||
|
+
|
||
|
+ Optional<ConsumableTypesBridge> BRIDGE = ServiceLoader.load(ConsumableTypesBridge.class).findFirst();
|
||
|
+
|
||
|
+ static ConsumableTypesBridge bridge() {
|
||
|
+ return BRIDGE.orElseThrow();
|
||
|
+ }
|
||
|
+
|
||
|
+ ConsumeEffect.ApplyStatusEffects applyStatusEffects(List<PotionEffect> effectList, float probability);
|
||
|
+
|
||
|
+ ConsumeEffect.RemoveStatusEffects removeStatusEffects(RegistryKeySet<PotionEffectType> potionEffectTypeTagKey);
|
||
|
+
|
||
|
+ ConsumeEffect.ClearAllStatusEffects clearAllStatusEffects();
|
||
|
+
|
||
|
+ ConsumeEffect.PlaySound playSoundEffect(Key sound);
|
||
|
+
|
||
|
+ ConsumeEffect.TeleportRandomly teleportRandomlyEffect(float diameter);
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumeEffect.java b/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumeEffect.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..ff1a14e19c21dd22f249503a0b738f190a75aca0
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumeEffect.java
|
||
|
@@ -0,0 +1,150 @@
|
||
|
+package io.papermc.paper.datacomponent.item.consumable;
|
||
|
+
|
||
|
+import io.papermc.paper.registry.set.RegistryKeySet;
|
||
|
+import net.kyori.adventure.key.Key;
|
||
|
+import org.bukkit.potion.PotionEffect;
|
||
|
+import org.bukkit.potion.PotionEffectType;
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import java.util.List;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Effect that occurs when consuming an item.
|
||
|
+ */
|
||
|
+@NullMarked
|
||
|
+@ApiStatus.Experimental
|
||
|
+@ApiStatus.NonExtendable
|
||
|
+public interface ConsumeEffect {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Creates a consume effect that randomly teleports the entity on consumption.
|
||
|
+ *
|
||
|
+ * @param diameter diameter of random teleportation
|
||
|
+ * @return the effect
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static TeleportRandomly teleportRandomlyEffect(final float diameter) {
|
||
|
+ return ConsumableTypesBridge.bridge().teleportRandomlyEffect(diameter);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Creates a consume effect that gives status effects on consumption.
|
||
|
+ *
|
||
|
+ * @param key the sound effect to play
|
||
|
+ * @return the effect
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static RemoveStatusEffects removeEffects(final RegistryKeySet<PotionEffectType> key) {
|
||
|
+ return ConsumableTypesBridge.bridge().removeStatusEffects(key);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Creates a consume effect that plays a sound on consumption.
|
||
|
+ *
|
||
|
+ * @param key the sound effect to play
|
||
|
+ * @return the effect
|
||
|
+ */
|
||
|
+ @Contract(value = "_ -> new", pure = true)
|
||
|
+ static PlaySound playSoundConsumeEffect(final Key key) {
|
||
|
+ return ConsumableTypesBridge.bridge().playSoundEffect(key);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Creates a consume effect that clears all status effects.
|
||
|
+ *
|
||
|
+ * @return effect instance
|
||
|
+ */
|
||
|
+ @Contract(value = "-> new", pure = true)
|
||
|
+ static ClearAllStatusEffects clearAllStatusEffects() {
|
||
|
+ return ConsumableTypesBridge.bridge().clearAllStatusEffects();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Creates a consume effect that gives status effects on consumption.
|
||
|
+ *
|
||
|
+ * @param effects the potion effects to apply
|
||
|
+ * @param probability the probability of these effects being applied, between 0 and 1 inclusive.
|
||
|
+ * @return the effect
|
||
|
+ */
|
||
|
+ @Contract(value = "_, _ -> new", pure = true)
|
||
|
+ static ApplyStatusEffects applyStatusEffects(final List<PotionEffect> effects, final float probability) {
|
||
|
+ return ConsumableTypesBridge.bridge().applyStatusEffects(effects, probability);
|
||
|
+ }
|
||
|
+
|
||
|
+ @NullMarked
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface TeleportRandomly extends ConsumeEffect {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * The max range that the entity can be teleported to.
|
||
|
+ *
|
||
|
+ * @return teleportation diameter
|
||
|
+ */
|
||
|
+ float diameter();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Represents a consumable effect that removes status effects on consumption
|
||
|
+ */
|
||
|
+ @NullMarked
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface RemoveStatusEffects extends ConsumeEffect {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Potion effects to remove
|
||
|
+ *
|
||
|
+ * @return effects
|
||
|
+ */
|
||
|
+ RegistryKeySet<PotionEffectType> removeEffects();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Represents a consumable effect that plays a sound on consumption.
|
||
|
+ */
|
||
|
+ @NullMarked
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface PlaySound extends ConsumeEffect {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sound effect to play in the world
|
||
|
+ *
|
||
|
+ * @return sound effect
|
||
|
+ */
|
||
|
+ Key sound();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Represents a consumable effect that clears all effects on consumption.
|
||
|
+ */
|
||
|
+ @NullMarked
|
||
|
+ interface ClearAllStatusEffects extends ConsumeEffect {
|
||
|
+
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Represents a consumable effect that applies effects based on a probability on consumption.
|
||
|
+ */
|
||
|
+ @NullMarked
|
||
|
+ @ApiStatus.Experimental
|
||
|
+ @ApiStatus.NonExtendable
|
||
|
+ interface ApplyStatusEffects extends ConsumeEffect {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Effect instances to grant
|
||
|
+ *
|
||
|
+ * @return effect
|
||
|
+ */
|
||
|
+ List<PotionEffect> effects();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Float between 0 and 1, chance for the effect to be applied.
|
||
|
+ *
|
||
|
+ * @return chance
|
||
|
+ */
|
||
|
+ float probability();
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/datacomponent/item/consumable/ItemUseAnimation.java b/src/main/java/io/papermc/paper/datacomponent/item/consumable/ItemUseAnimation.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..8cd6dbe4ea5ee3270b9428a9c29cbd88823d9f6c
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/datacomponent/item/consumable/ItemUseAnimation.java
|
||
|
@@ -0,0 +1,17 @@
|
||
|
+package io.papermc.paper.datacomponent.item.consumable;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Represents the hand animation that is used when a player is consuming this item.
|
||
|
+ */
|
||
|
+public enum ItemUseAnimation {
|
||
|
+ NONE,
|
||
|
+ EAT,
|
||
|
+ DRINK,
|
||
|
+ BLOCK,
|
||
|
+ BOW,
|
||
|
+ SPEAR,
|
||
|
+ CROSSBOW,
|
||
|
+ SPYGLASS,
|
||
|
+ TOOT_HORN,
|
||
|
+ BRUSH
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/item/MapPostProcessing.java b/src/main/java/io/papermc/paper/item/MapPostProcessing.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..5843768d0be2ae4a0219636ed7640727808da567
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/item/MapPostProcessing.java
|
||
|
@@ -0,0 +1,6 @@
|
||
|
+package io.papermc.paper.item;
|
||
|
+
|
||
|
+public enum MapPostProcessing {
|
||
|
+ LOCK,
|
||
|
+ SCALE
|
||
|
+}
|
||
|
diff --git a/src/main/java/io/papermc/paper/registry/RegistryKey.java b/src/main/java/io/papermc/paper/registry/RegistryKey.java
|
||
|
index 9b39e33514b15a9d07104e2ad826d0da11f569d6..e5319bdb9f75358b8bb0ac35373125a7d94edfa6 100644
|
||
|
--- a/src/main/java/io/papermc/paper/registry/RegistryKey.java
|
||
|
+++ b/src/main/java/io/papermc/paper/registry/RegistryKey.java
|
||
|
@@ -1,5 +1,6 @@
|
||
|
package io.papermc.paper.registry;
|
||
|
|
||
|
+import io.papermc.paper.datacomponent.DataComponentType;
|
||
|
import net.kyori.adventure.key.Keyed;
|
||
|
import org.bukkit.Art;
|
||
|
import org.bukkit.Fluid;
|
||
|
@@ -124,6 +125,11 @@ public sealed interface RegistryKey<T> extends Keyed permits RegistryKeyImpl {
|
||
|
* @see io.papermc.paper.registry.keys.SoundEventKeys
|
||
|
*/
|
||
|
RegistryKey<Sound> SOUND_EVENT = create("sound_event");
|
||
|
+ /**
|
||
|
+ * Built-in registry for data component types.
|
||
|
+ * <!-- @see io.papermc.paper.registry.keys.DataComponentTypeKeys -->
|
||
|
+ */
|
||
|
+ RegistryKey<DataComponentType> DATA_COMPONENT_TYPE = create("data_component_type");
|
||
|
|
||
|
|
||
|
|
||
|
diff --git a/src/main/java/io/papermc/paper/text/Filtered.java b/src/main/java/io/papermc/paper/text/Filtered.java
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..9e892621354c784632204559f9fdf0827b3bc4f1
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/io/papermc/paper/text/Filtered.java
|
||
|
@@ -0,0 +1,32 @@
|
||
|
+package io.papermc.paper.text;
|
||
|
+
|
||
|
+import org.jetbrains.annotations.ApiStatus;
|
||
|
+import org.jetbrains.annotations.Contract;
|
||
|
+import org.jspecify.annotations.NullMarked;
|
||
|
+import org.jspecify.annotations.Nullable;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Denotes that this type is filterable by the client, and may be shown differently
|
||
|
+ * depending on the player's set configuration.
|
||
|
+ *
|
||
|
+ * @param <T> type of value
|
||
|
+ */
|
||
|
+@ApiStatus.Experimental
|
||
|
+@NullMarked
|
||
|
+public interface Filtered<T> {
|
||
|
+
|
||
|
+ @Contract(value = "_, _ -> new", pure = true)
|
||
|
+ static <T> Filtered<T> of(final T raw, final @Nullable T filtered) {
|
||
|
+ @ApiStatus.Internal
|
||
|
+ record Instance<T>(T raw, @Nullable T filtered) implements Filtered<T> {}
|
||
|
+
|
||
|
+ return new Instance<>(raw, filtered);
|
||
|
+ }
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ T raw();
|
||
|
+
|
||
|
+ @Contract(pure = true)
|
||
|
+ @Nullable
|
||
|
+ T filtered();
|
||
|
+}
|
||
|
diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java
|
||
|
index 615eb24ffdd8f6d55ccd4f21760b809c1098bc68..c7ce8fa1ff9feda66d5a4e497112a24ff51c9d2b 100644
|
||
|
--- a/src/main/java/org/bukkit/Material.java
|
||
|
+++ b/src/main/java/org/bukkit/Material.java
|
||
|
@@ -137,7 +137,7 @@ import org.jetbrains.annotations.Nullable;
|
||
|
@SuppressWarnings({"DeprecatedIsStillUsed", "deprecation"}) // Paper
|
||
|
public enum Material implements Keyed, Translatable, net.kyori.adventure.translation.Translatable { // Paper
|
||
|
//<editor-fold desc="Materials" defaultstate="collapsed">
|
||
|
- AIR(9648, 0),
|
||
|
+ AIR(9648, 64), // Paper - air stacks to 64
|
||
|
STONE(22948),
|
||
|
GRANITE(21091),
|
||
|
POLISHED_GRANITE(5477),
|
||
|
@@ -5784,6 +5784,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla
|
||
|
*/
|
||
|
@ApiStatus.Internal
|
||
|
@Nullable
|
||
|
+ @org.jetbrains.annotations.Contract(pure = true) // Paper
|
||
|
public ItemType asItemType() {
|
||
|
return itemType.get();
|
||
|
}
|
||
|
@@ -5796,7 +5797,47 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla
|
||
|
*/
|
||
|
@ApiStatus.Internal
|
||
|
@Nullable
|
||
|
+ @org.jetbrains.annotations.Contract(pure = true) // Paper
|
||
|
public BlockType asBlockType() {
|
||
|
return blockType.get();
|
||
|
}
|
||
|
+
|
||
|
+ // Paper start - data component API
|
||
|
+ /**
|
||
|
+ * Gets the default value of the data component type for this item type.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ * @param <T> the value type
|
||
|
+ * @return the default value or {@code null} if there is none
|
||
|
+ * @see #hasDefaultData(io.papermc.paper.datacomponent.DataComponentType) for DataComponentType.NonValued
|
||
|
+ * @throws IllegalArgumentException if {@link #isItem()} is {@code false}
|
||
|
+ */
|
||
|
+ public @Nullable <T> T getDefaultData(final io.papermc.paper.datacomponent.DataComponentType.@NotNull Valued<T> type) {
|
||
|
+ Preconditions.checkArgument(this.asItemType() != null);
|
||
|
+ return this.asItemType().getDefaultData(type);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Checks if the data component type has a default value for this item type.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ * @return {@code true} if there is a default value
|
||
|
+ * @throws IllegalArgumentException if {@link #isItem()} is {@code false}
|
||
|
+ */
|
||
|
+ public boolean hasDefaultData(final io.papermc.paper.datacomponent.@NotNull DataComponentType type) {
|
||
|
+ Preconditions.checkArgument(this.asItemType() != null);
|
||
|
+ return this.asItemType().hasDefaultData(type);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the default data component types for this item type.
|
||
|
+ *
|
||
|
+ * @return an immutable set of data component types
|
||
|
+ * @throws IllegalArgumentException if {@link #isItem()} is {@code false}
|
||
|
+ */
|
||
|
+ public java.util.@org.jetbrains.annotations.Unmodifiable @NotNull Set<io.papermc.paper.datacomponent.DataComponentType> getDefaultDataTypes() {
|
||
|
+ Preconditions.checkArgument(this.asItemType() != null);
|
||
|
+ return this.asItemType().getDefaultDataTypes();
|
||
|
+ }
|
||
|
+ // Paper end - data component API
|
||
|
}
|
||
|
diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java
|
||
|
index 7cf7c6d05aa6cbf3f0c8612831404552c6a7b84a..c60e31425efd7b863941f5538faef6c0552290ae 100644
|
||
|
--- a/src/main/java/org/bukkit/Registry.java
|
||
|
+++ b/src/main/java/org/bukkit/Registry.java
|
||
|
@@ -376,6 +376,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
||
|
*/
|
||
|
Registry<org.bukkit.potion.PotionEffectType> POTION_EFFECT_TYPE = EFFECT;
|
||
|
// Paper end - potion effect type registry
|
||
|
+ Registry<io.papermc.paper.datacomponent.DataComponentType> DATA_COMPONENT_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.DATA_COMPONENT_TYPE); // Paper
|
||
|
/**
|
||
|
* Get the object by its key.
|
||
|
*
|
||
|
diff --git a/src/main/java/org/bukkit/block/BlockType.java b/src/main/java/org/bukkit/block/BlockType.java
|
||
|
index ed534fe4983873a2d5f623f0d9d5e3ce254615eb..f019d490794b49d21057820bab047e2f909934a1 100644
|
||
|
--- a/src/main/java/org/bukkit/block/BlockType.java
|
||
|
+++ b/src/main/java/org/bukkit/block/BlockType.java
|
||
|
@@ -128,7 +128,7 @@ import org.jetbrains.annotations.Nullable;
|
||
|
* official replacement for the aforementioned enum. Entirely incompatible
|
||
|
* changes may occur. Do not use this API in plugins.
|
||
|
*/
|
||
|
-@ApiStatus.Internal
|
||
|
+@org.jetbrains.annotations.ApiStatus.Experimental // Paper - data component API - already required for data component API
|
||
|
public interface BlockType extends Keyed, Translatable, net.kyori.adventure.translation.Translatable, io.papermc.paper.world.flag.FeatureDependant { // Paper - add translatable & feature flag API
|
||
|
|
||
|
/**
|
||
|
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||
|
index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..6e4ca7d95953a25c0aaafd35e54ef9254a1b5f0b 100644
|
||
|
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
|
||
|
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||
|
@@ -1137,4 +1137,185 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
||
|
return Bukkit.getUnsafe().computeTooltipLines(this, tooltipContext, player);
|
||
|
}
|
||
|
// Paper end - expose itemstack tooltip lines
|
||
|
+
|
||
|
+ // Paper start - data component API
|
||
|
+ /**
|
||
|
+ * Gets the value for the data component type on this stack.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ * @param <T> the value type
|
||
|
+ * @return the value for the data component type, or {@code null} if not set or marked as removed
|
||
|
+ * @see #hasData(io.papermc.paper.datacomponent.DataComponentType) for DataComponentType.NonValued
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.Contract(pure = true)
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public <T> @Nullable T getData(final io.papermc.paper.datacomponent.DataComponentType.@NotNull Valued<T> type) {
|
||
|
+ return this.craftDelegate.getData(type);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the value for the data component type on this stack with
|
||
|
+ * a fallback value.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ * @param fallback the fallback value if the value isn't present
|
||
|
+ * @param <T> the value type
|
||
|
+ * @return the value for the data component type or the fallback value
|
||
|
+ */
|
||
|
+ @Utility
|
||
|
+ @org.jetbrains.annotations.Contract(value = "_, !null -> !null", pure = true)
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public <T> @Nullable T getDataOrDefault(final io.papermc.paper.datacomponent.DataComponentType.@NotNull Valued<? extends T> type, final @Nullable T fallback) {
|
||
|
+ final T object = this.getData(type);
|
||
|
+ return object != null ? object : fallback;
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Checks if the data component type is set on the itemstack.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ * @return {@code true} if set, {@code false} otherwise
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.Contract(pure = true)
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public boolean hasData(final io.papermc.paper.datacomponent.@NotNull DataComponentType type) {
|
||
|
+ return this.craftDelegate.hasData(type);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets all the data component types set on this stack.
|
||
|
+ *
|
||
|
+ * @return an immutable set of data component types
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.Contract("-> new")
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public java.util.@org.jetbrains.annotations.Unmodifiable Set<io.papermc.paper.datacomponent.@NotNull DataComponentType> getDataTypes() {
|
||
|
+ return this.craftDelegate.getDataTypes();
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the value of the data component type for this itemstack. To
|
||
|
+ * reset the value to the default for the {@link #getType() item type}, use
|
||
|
+ * {@link #resetData(io.papermc.paper.datacomponent.DataComponentType)}. To mark the data component type
|
||
|
+ * as removed, use {@link #unsetData(io.papermc.paper.datacomponent.DataComponentType)}.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ * @param valueBuilder value builder
|
||
|
+ * @param <T> value type
|
||
|
+ */
|
||
|
+ @Utility
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public <T> void setData(final io.papermc.paper.datacomponent.DataComponentType.@NotNull Valued<T> type, final @NotNull io.papermc.paper.datacomponent.DataComponentBuilder<T> valueBuilder) {
|
||
|
+ this.setData(type, valueBuilder.build());
|
||
|
+ }
|
||
|
+
|
||
|
+ // /**
|
||
|
+ // * Modifies the value of the specified data component type for this item stack based on the result
|
||
|
+ // * of applying a given function to the current value.
|
||
|
+ // *
|
||
|
+ // * <p>If the function returns {@code null}, the data component type will be reset using
|
||
|
+ // * {@link #unsetData(DataComponentType)}. Otherwise, the
|
||
|
+ // * component value will be updated with the new result using {@link #setData(DataComponentType.Valued, Object)}.</p>
|
||
|
+ // *
|
||
|
+ // * @param <T> the type of the data component's value
|
||
|
+ // * @param type the data component type to be modified
|
||
|
+ // * @param consumer a function that takes the current component value (can be {@code null}) and
|
||
|
+ // * returns the modified value (or {@code null} to unset)
|
||
|
+ // */
|
||
|
+ // @Utility
|
||
|
+ // public <T> void editData(final io.papermc.paper.datacomponent.DataComponentType.@NotNull Valued<T> type, final @NotNull java.util.function.Function<@Nullable T, @Nullable T> consumer) {
|
||
|
+ // T value = getData(type);
|
||
|
+ // T newType = consumer.apply(value);
|
||
|
+ // if (newType == null) {
|
||
|
+ // unsetData(type);
|
||
|
+ // } else {
|
||
|
+ // setData(type, newType);
|
||
|
+ // }
|
||
|
+ // }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Sets the value of the data component type for this itemstack. To
|
||
|
+ * reset the value to the default for the {@link #getType() item type}, use
|
||
|
+ * {@link #resetData(io.papermc.paper.datacomponent.DataComponentType)}. To mark the data component type
|
||
|
+ * as removed, use {@link #unsetData(io.papermc.paper.datacomponent.DataComponentType)}.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ * @param value value to set
|
||
|
+ * @param <T> value type
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public <T> void setData(final io.papermc.paper.datacomponent.DataComponentType.@NotNull Valued<T> type, final @NotNull T value) {
|
||
|
+ this.craftDelegate.setData(type, value);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Marks this non-valued data component type as present in this itemstack.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public void setData(final io.papermc.paper.datacomponent.DataComponentType.@NotNull NonValued type) {
|
||
|
+ this.craftDelegate.setData(type);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Marks this data component as removed for this itemstack.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public void unsetData(final io.papermc.paper.datacomponent.@NotNull DataComponentType type) {
|
||
|
+ this.craftDelegate.unsetData(type);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Resets the value of this component to be the default
|
||
|
+ * value for the item type from {@link Material#getDefaultData(io.papermc.paper.datacomponent.DataComponentType.Valued)}.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public void resetData(final io.papermc.paper.datacomponent.@NotNull DataComponentType type) {
|
||
|
+ this.craftDelegate.resetData(type);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Checks if the data component type is overridden from the default for the
|
||
|
+ * item type.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ * @return {@code true} if the data type is overridden
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public boolean isDataOverridden(final io.papermc.paper.datacomponent.@NotNull DataComponentType type) {
|
||
|
+ return this.craftDelegate.isDataOverridden(type);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Checks if this itemstack matches another given itemstack excluding the provided components.
|
||
|
+ * This is useful if you are wanting to ignore certain properties of itemstacks, such as durability.
|
||
|
+ *
|
||
|
+ * @param item the item to compare
|
||
|
+ * @param excludeTypes the data component types to ignore
|
||
|
+ * @return {@code true} if the provided item is equal, ignoring the provided components
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public boolean matchesWithoutData(final @NotNull ItemStack item, final @NotNull java.util.Set<io.papermc.paper.datacomponent.@NotNull DataComponentType> excludeTypes) {
|
||
|
+ return this.matchesWithoutData(item, excludeTypes, false);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Checks if this itemstack matches another given itemstack excluding the provided components.
|
||
|
+ * This is useful if you are wanting to ignore certain properties of itemstacks, such as durability.
|
||
|
+ *
|
||
|
+ * @param item the item to compare
|
||
|
+ * @param excludeTypes the data component types to ignore
|
||
|
+ * @param ignoreCount ignore the count of the item
|
||
|
+ * @return {@code true} if the provided item is equal, ignoring the provided components
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ public boolean matchesWithoutData(final @NotNull ItemStack item, final @NotNull java.util.Set<io.papermc.paper.datacomponent.@NotNull DataComponentType> excludeTypes, final boolean ignoreCount) {
|
||
|
+ return this.craftDelegate.matchesWithoutData(item, excludeTypes, ignoreCount);
|
||
|
+ }
|
||
|
+ // Paper end - data component API
|
||
|
}
|
||
|
diff --git a/src/main/java/org/bukkit/inventory/ItemType.java b/src/main/java/org/bukkit/inventory/ItemType.java
|
||
|
index 72803c00e4af576f286d2af34bf300ee554a7f3c..2a3c4f055d0e4ef009caed95152570660ab100d5 100644
|
||
|
--- a/src/main/java/org/bukkit/inventory/ItemType.java
|
||
|
+++ b/src/main/java/org/bukkit/inventory/ItemType.java
|
||
|
@@ -2483,4 +2483,33 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans
|
||
|
*/
|
||
|
@Nullable ItemRarity getItemRarity();
|
||
|
// Paper end - expand ItemRarity API
|
||
|
+ // Paper start - data component API
|
||
|
+ /**
|
||
|
+ * Gets the default value of the data component type for this item type.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ * @param <T> the value type
|
||
|
+ * @return the default value or {@code null} if there is none
|
||
|
+ * @see #hasDefaultData(io.papermc.paper.datacomponent.DataComponentType) for DataComponentType.NonValued
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ @Nullable <T> T getDefaultData(io.papermc.paper.datacomponent.DataComponentType.@NotNull Valued<T> type);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Checks if the data component type has a default value for this item type.
|
||
|
+ *
|
||
|
+ * @param type the data component type
|
||
|
+ * @return {@code true} if there is a default value
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ boolean hasDefaultData(io.papermc.paper.datacomponent.@NotNull DataComponentType type);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Gets the default data component types for this item type.
|
||
|
+ *
|
||
|
+ * @return an immutable set of data component types
|
||
|
+ */
|
||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental
|
||
|
+ java.util.@org.jetbrains.annotations.Unmodifiable @NotNull Set<io.papermc.paper.datacomponent.DataComponentType> getDefaultDataTypes();
|
||
|
+ // Paper end - data component API
|
||
|
}
|