2020-04-24 03:25:58 +02:00
|
|
|
package net.minestom.server.item;
|
2019-08-12 08:30:59 +02:00
|
|
|
|
2021-03-03 20:27:33 +01:00
|
|
|
import net.kyori.adventure.text.Component;
|
2021-04-10 17:01:50 +02:00
|
|
|
import net.kyori.adventure.text.event.HoverEvent;
|
|
|
|
import net.kyori.adventure.text.event.HoverEventSource;
|
2021-05-28 17:00:48 +02:00
|
|
|
import net.minestom.server.tag.Tag;
|
2022-04-13 17:57:15 +02:00
|
|
|
import net.minestom.server.tag.TagHandler;
|
2021-05-28 17:00:48 +02:00
|
|
|
import net.minestom.server.tag.TagReadable;
|
2022-05-02 21:51:33 +02:00
|
|
|
import net.minestom.server.tag.TagWritable;
|
2021-04-10 17:01:50 +02:00
|
|
|
import net.minestom.server.utils.NBTUtils;
|
2021-08-30 23:51:19 +02:00
|
|
|
import net.minestom.server.utils.validate.Check;
|
2022-03-10 16:07:56 +01:00
|
|
|
import org.jetbrains.annotations.*;
|
2021-04-13 03:27:51 +02:00
|
|
|
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
2019-08-29 02:15:52 +02:00
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
import java.util.function.IntUnaryOperator;
|
2021-03-11 18:07:04 +01:00
|
|
|
import java.util.function.UnaryOperator;
|
2020-02-13 15:14:41 +01:00
|
|
|
|
2021-04-03 00:21:23 +02:00
|
|
|
/**
|
|
|
|
* Represents an immutable item to be placed inside {@link net.minestom.server.inventory.PlayerInventory},
|
|
|
|
* {@link net.minestom.server.inventory.Inventory} or even on the ground {@link net.minestom.server.entity.ItemEntity}.
|
|
|
|
* <p>
|
|
|
|
* An item stack cannot be null, {@link ItemStack#AIR} should be used instead.
|
|
|
|
*/
|
2022-04-13 17:57:15 +02:00
|
|
|
public sealed interface ItemStack extends TagReadable, HoverEventSource<HoverEvent.ShowItem>
|
|
|
|
permits ItemStackImpl {
|
2021-04-03 00:21:23 +02:00
|
|
|
/**
|
|
|
|
* Constant AIR item. Should be used instead of 'null'.
|
|
|
|
*/
|
2022-04-13 17:57:15 +02:00
|
|
|
@NotNull ItemStack AIR = ItemStack.of(Material.AIR);
|
2020-07-23 05:36:15 +02:00
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
@Contract(value = "_ -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
static @NotNull Builder builder(@NotNull Material material) {
|
|
|
|
return new ItemStackImpl.Builder(material, 1);
|
2019-08-13 17:52:09 +02:00
|
|
|
}
|
|
|
|
|
2021-04-02 18:25:20 +02:00
|
|
|
@Contract(value = "_ ,_ -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
static @NotNull ItemStack of(@NotNull Material material, int amount) {
|
|
|
|
return ItemStackImpl.create(material, amount);
|
2021-02-07 19:38:14 +01:00
|
|
|
}
|
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
@Contract(value = "_ -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
static @NotNull ItemStack of(@NotNull Material material) {
|
2021-04-02 18:13:02 +02:00
|
|
|
return of(material, 1);
|
2021-02-28 19:37:31 +01:00
|
|
|
}
|
|
|
|
|
2021-04-13 03:27:51 +02:00
|
|
|
@Contract(value = "_, _, _ -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
static @NotNull ItemStack fromNBT(@NotNull Material material, @Nullable NBTCompound nbtCompound, int amount) {
|
|
|
|
if (nbtCompound == null) return of(material, amount);
|
|
|
|
return builder(material).amount(amount).meta(nbtCompound).build();
|
2021-04-13 03:27:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Contract(value = "_, _ -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
static @NotNull ItemStack fromNBT(@NotNull Material material, @Nullable NBTCompound nbtCompound) {
|
2021-04-13 03:27:51 +02:00
|
|
|
return fromNBT(material, nbtCompound, 1);
|
|
|
|
}
|
|
|
|
|
2021-08-31 00:00:57 +02:00
|
|
|
/**
|
|
|
|
* Converts this item to an NBT tag containing the id (material), count (amount), and tag (meta).
|
|
|
|
*
|
|
|
|
* @param nbtCompound The nbt representation of the item
|
|
|
|
*/
|
|
|
|
@ApiStatus.Experimental
|
2022-04-13 17:57:15 +02:00
|
|
|
static @NotNull ItemStack fromItemNBT(@NotNull NBTCompound nbtCompound) {
|
2021-08-30 23:51:19 +02:00
|
|
|
String id = nbtCompound.getString("id");
|
|
|
|
Check.notNull(id, "Item NBT must contain an id field.");
|
|
|
|
Material material = Material.fromNamespaceId(id);
|
2021-08-31 00:00:57 +02:00
|
|
|
Check.notNull(material, "Unknown material: {0}", id);
|
2021-08-30 23:51:19 +02:00
|
|
|
|
|
|
|
Byte amount = nbtCompound.getByte("Count");
|
2022-04-10 10:01:39 +02:00
|
|
|
if (amount == null) amount = 1;
|
|
|
|
final NBTCompound tag = nbtCompound.getCompound("tag");
|
|
|
|
return tag != null ? fromNBT(material, tag, amount) : of(material, amount);
|
2021-08-30 23:51:19 +02:00
|
|
|
}
|
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
@Contract(pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
@NotNull Material material();
|
2019-09-06 16:05:36 +02:00
|
|
|
|
2022-04-13 17:57:15 +02:00
|
|
|
@Contract(pure = true)
|
|
|
|
int amount();
|
|
|
|
|
|
|
|
@Contract(pure = true)
|
|
|
|
@NotNull ItemMeta meta();
|
2020-08-12 13:10:57 +02:00
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
@Contract(pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
@ApiStatus.Experimental
|
|
|
|
<T extends ItemMetaView<?>> @NotNull T meta(@NotNull Class<T> metaClass);
|
|
|
|
|
|
|
|
@Contract(value = "_, -> new", pure = true)
|
2022-04-21 18:43:42 +02:00
|
|
|
@NotNull ItemStack with(@NotNull Consumer<@NotNull Builder> consumer);
|
2022-04-13 17:57:15 +02:00
|
|
|
|
|
|
|
@Contract(value = "_, _ -> new", pure = true)
|
|
|
|
@ApiStatus.Experimental
|
|
|
|
<V extends ItemMetaView.Builder, T extends ItemMetaView<V>> @NotNull ItemStack withMeta(@NotNull Class<T> metaType,
|
2022-04-21 18:43:42 +02:00
|
|
|
@NotNull Consumer<V> consumer);
|
2022-04-13 17:57:15 +02:00
|
|
|
|
|
|
|
@Contract(value = "_ -> new", pure = true)
|
2022-04-21 18:43:42 +02:00
|
|
|
@NotNull ItemStack withMeta(@NotNull Consumer<ItemMeta.@NotNull Builder> consumer);
|
2022-04-13 17:57:15 +02:00
|
|
|
|
|
|
|
@Contract(value = "_, -> new", pure = true)
|
2022-06-25 11:34:09 +02:00
|
|
|
@NotNull ItemStack withMaterial(@NotNull Material material);
|
2020-04-22 02:42:58 +02:00
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
@Contract(value = "_, -> new", pure = true)
|
2022-06-25 11:34:09 +02:00
|
|
|
@NotNull ItemStack withAmount(int amount);
|
2020-07-23 07:36:49 +02:00
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
@Contract(value = "_, -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
default @NotNull ItemStack withAmount(@NotNull IntUnaryOperator intUnaryOperator) {
|
|
|
|
return withAmount(intUnaryOperator.applyAsInt(amount()));
|
2021-03-03 20:27:33 +01:00
|
|
|
}
|
|
|
|
|
2021-07-23 01:47:43 +02:00
|
|
|
@ApiStatus.Experimental
|
|
|
|
@Contract(value = "_, -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
@NotNull ItemStack consume(int amount);
|
2021-07-23 01:47:43 +02:00
|
|
|
|
2022-04-13 17:57:15 +02:00
|
|
|
@Contract(pure = true)
|
|
|
|
default @Nullable Component getDisplayName() {
|
|
|
|
return meta().getDisplayName();
|
2019-08-22 14:52:32 +02:00
|
|
|
}
|
|
|
|
|
2022-04-13 17:57:15 +02:00
|
|
|
@Contract(pure = true)
|
|
|
|
default @NotNull List<@NotNull Component> getLore() {
|
|
|
|
return meta().getLore();
|
2021-04-02 22:14:48 +02:00
|
|
|
}
|
|
|
|
|
2021-08-21 04:45:19 +02:00
|
|
|
@ApiStatus.Experimental
|
|
|
|
@Contract(value = "_ -> new", pure = true)
|
2022-06-25 11:34:09 +02:00
|
|
|
@NotNull ItemStack withMeta(@NotNull ItemMeta meta);
|
2021-03-03 20:27:33 +01:00
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
@Contract(value = "_, -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
default @NotNull ItemStack withDisplayName(@Nullable Component displayName) {
|
|
|
|
return withMeta(builder -> builder.displayName(displayName));
|
2019-08-22 14:52:32 +02:00
|
|
|
}
|
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
@Contract(value = "_, -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
default @NotNull ItemStack withDisplayName(@NotNull UnaryOperator<@Nullable Component> componentUnaryOperator) {
|
2021-04-02 18:13:02 +02:00
|
|
|
return withDisplayName(componentUnaryOperator.apply(getDisplayName()));
|
2020-02-13 15:14:41 +01:00
|
|
|
}
|
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
@Contract(value = "_, -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
default @NotNull ItemStack withLore(@NotNull List<? extends Component> lore) {
|
|
|
|
return withMeta(builder -> builder.lore(lore));
|
2020-02-13 15:14:41 +01:00
|
|
|
}
|
|
|
|
|
2021-04-02 18:13:02 +02:00
|
|
|
@Contract(value = "_, -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
default @NotNull ItemStack withLore(@NotNull UnaryOperator<@NotNull List<@NotNull Component>> loreUnaryOperator) {
|
2021-04-02 18:13:02 +02:00
|
|
|
return withLore(loreUnaryOperator.apply(getLore()));
|
2020-04-29 20:17:04 +02:00
|
|
|
}
|
|
|
|
|
2021-04-02 19:10:46 +02:00
|
|
|
@Contract(pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
default boolean isAir() {
|
|
|
|
return material() == Material.AIR;
|
2020-05-22 21:46:50 +02:00
|
|
|
}
|
2020-07-13 14:36:39 +02:00
|
|
|
|
2021-04-02 19:10:46 +02:00
|
|
|
@Contract(pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
boolean isSimilar(@NotNull ItemStack itemStack);
|
2021-08-13 21:15:43 +02:00
|
|
|
|
2021-05-28 17:05:14 +02:00
|
|
|
@Contract(value = "_, _ -> new", pure = true)
|
2022-04-13 17:57:15 +02:00
|
|
|
default <T> @NotNull ItemStack withTag(@NotNull Tag<T> tag, @Nullable T value) {
|
|
|
|
return withMeta(builder -> builder.set(tag, value));
|
2021-05-28 17:05:14 +02:00
|
|
|
}
|
|
|
|
|
2021-05-28 17:00:48 +02:00
|
|
|
@Override
|
2022-04-13 17:57:15 +02:00
|
|
|
default <T> @UnknownNullability T getTag(@NotNull Tag<T> tag) {
|
|
|
|
return meta().getTag(tag);
|
2021-05-28 17:00:48 +02:00
|
|
|
}
|
|
|
|
|
2021-04-10 17:01:50 +02:00
|
|
|
@Override
|
2022-04-13 17:57:15 +02:00
|
|
|
default @NotNull HoverEvent<HoverEvent.ShowItem> asHoverEvent(@NotNull UnaryOperator<HoverEvent.ShowItem> op) {
|
|
|
|
return HoverEvent.showItem(op.apply(HoverEvent.ShowItem.of(material(), amount(),
|
|
|
|
NBTUtils.asBinaryTagHolder(meta().toNBT()))));
|
2021-04-10 17:01:50 +02:00
|
|
|
}
|
2021-07-19 04:27:44 +02:00
|
|
|
|
2021-08-31 00:00:57 +02:00
|
|
|
/**
|
|
|
|
* Converts this item to an NBT tag containing the id (material), count (amount), and tag (meta)
|
|
|
|
*
|
|
|
|
* @return The nbt representation of the item
|
|
|
|
*/
|
|
|
|
@ApiStatus.Experimental
|
2022-04-13 17:57:15 +02:00
|
|
|
@NotNull NBTCompound toItemNBT();
|
|
|
|
|
|
|
|
|
|
|
|
@Deprecated
|
|
|
|
@Contract(pure = true)
|
|
|
|
default @NotNull Material getMaterial() {
|
|
|
|
return material();
|
2021-08-30 23:51:19 +02:00
|
|
|
}
|
|
|
|
|
2022-04-13 17:57:15 +02:00
|
|
|
@Deprecated
|
|
|
|
@Contract(pure = true)
|
|
|
|
default int getAmount() {
|
|
|
|
return amount();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Deprecated
|
|
|
|
@Contract(pure = true)
|
|
|
|
default @NotNull ItemMeta getMeta() {
|
|
|
|
return meta();
|
|
|
|
}
|
|
|
|
|
2022-05-02 21:51:33 +02:00
|
|
|
sealed interface Builder extends TagWritable
|
2022-04-21 18:43:42 +02:00
|
|
|
permits ItemStackImpl.Builder {
|
2022-04-13 17:57:15 +02:00
|
|
|
@Contract(value = "_ -> this")
|
|
|
|
@NotNull Builder amount(int amount);
|
|
|
|
|
|
|
|
@Contract(value = "_ -> this")
|
|
|
|
@NotNull Builder meta(@NotNull TagHandler tagHandler);
|
|
|
|
|
|
|
|
@Contract(value = "_ -> this")
|
|
|
|
@NotNull Builder meta(@NotNull NBTCompound compound);
|
|
|
|
|
|
|
|
@Contract(value = "_ -> this")
|
|
|
|
@NotNull Builder meta(@NotNull ItemMeta itemMeta);
|
|
|
|
|
|
|
|
@Contract(value = "_ -> this")
|
2022-04-21 18:43:42 +02:00
|
|
|
@NotNull Builder meta(@NotNull Consumer<ItemMeta.@NotNull Builder> consumer);
|
2022-04-13 17:57:15 +02:00
|
|
|
|
|
|
|
@Contract(value = "_, _ -> this")
|
2022-04-21 18:43:42 +02:00
|
|
|
<V extends ItemMetaView.Builder, T extends ItemMetaView<V>> @NotNull Builder meta(@NotNull Class<T> metaType,
|
|
|
|
@NotNull Consumer<@NotNull V> itemMetaConsumer);
|
2022-04-13 17:57:15 +02:00
|
|
|
|
|
|
|
@Contract(value = "-> new", pure = true)
|
|
|
|
@NotNull ItemStack build();
|
|
|
|
|
2022-04-20 23:14:37 +02:00
|
|
|
@Contract(value = "_, _ -> this")
|
|
|
|
default <T> @NotNull Builder set(@NotNull Tag<T> tag, @Nullable T value) {
|
|
|
|
setTag(tag, value);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2022-04-13 17:57:15 +02:00
|
|
|
@Contract(value = "_ -> this")
|
|
|
|
default @NotNull Builder displayName(@Nullable Component displayName) {
|
|
|
|
return meta(builder -> builder.displayName(displayName));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Contract(value = "_ -> this")
|
|
|
|
default @NotNull Builder lore(@NotNull List<? extends Component> lore) {
|
|
|
|
return meta(builder -> builder.lore(lore));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Contract(value = "_ -> this")
|
|
|
|
default @NotNull Builder lore(Component... lore) {
|
|
|
|
return meta(builder -> builder.lore(lore));
|
|
|
|
}
|
2021-07-19 04:27:44 +02:00
|
|
|
}
|
2021-01-19 18:25:54 +01:00
|
|
|
}
|