mirror of https://github.com/Minestom/Minestom.git
169 lines
6.0 KiB
Java
169 lines
6.0 KiB
Java
package net.minestom.server.item;
|
|
|
|
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
|
import net.minestom.server.ServerFlag;
|
|
import net.minestom.server.item.rule.VanillaStackingRule;
|
|
import net.minestom.server.tag.Tag;
|
|
import net.minestom.server.tag.TagHandler;
|
|
import org.jetbrains.annotations.Contract;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
record ItemStackImpl(Material material, int amount, ItemMetaImpl meta) implements ItemStack {
|
|
static final @NotNull StackingRule DEFAULT_STACKING_RULE;
|
|
|
|
static {
|
|
if (ServerFlag.STACKING_RULE == null) {
|
|
DEFAULT_STACKING_RULE = new VanillaStackingRule();
|
|
} else {
|
|
try {
|
|
DEFAULT_STACKING_RULE = (StackingRule) ClassLoader.getSystemClassLoader()
|
|
.loadClass(ServerFlag.STACKING_RULE).getConstructor().newInstance();
|
|
} catch (Exception e) {
|
|
throw new RuntimeException("Could not instantiate default stacking rule", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
static ItemStack create(Material material, int amount, ItemMetaImpl meta) {
|
|
if (amount <= 0) return AIR;
|
|
return new ItemStackImpl(material, amount, meta);
|
|
}
|
|
|
|
static ItemStack create(Material material, int amount) {
|
|
return create(material, amount, ItemMetaImpl.EMPTY);
|
|
}
|
|
|
|
@Override
|
|
public <T extends ItemMetaView<?>> @NotNull T meta(@NotNull Class<T> metaClass) {
|
|
return ItemMetaViewImpl.construct(metaClass, meta);
|
|
}
|
|
|
|
@Override
|
|
public @NotNull ItemStack with(@NotNull Consumer<ItemStack.@NotNull Builder> consumer) {
|
|
ItemStack.Builder builder = builder();
|
|
consumer.accept(builder);
|
|
return builder.build();
|
|
}
|
|
|
|
@Override
|
|
public @NotNull <V extends ItemMetaView.Builder, T extends ItemMetaView<V>> ItemStack withMeta(@NotNull Class<T> metaType,
|
|
@NotNull Consumer<V> consumer) {
|
|
return builder().meta(metaType, consumer).build();
|
|
}
|
|
|
|
@Override
|
|
public @NotNull ItemStack withMeta(@NotNull Consumer<ItemMeta.@NotNull Builder> consumer) {
|
|
return builder().meta(consumer).build();
|
|
}
|
|
|
|
@Override
|
|
public @NotNull ItemStack withMaterial(@NotNull Material material) {
|
|
return new ItemStackImpl(material, amount, meta);
|
|
}
|
|
|
|
@Override
|
|
public @NotNull ItemStack withAmount(int amount) {
|
|
return create(material, amount, meta);
|
|
}
|
|
|
|
@Override
|
|
public @NotNull ItemStack consume(int amount) {
|
|
return DEFAULT_STACKING_RULE.apply(this, currentAmount -> currentAmount - amount);
|
|
}
|
|
|
|
@Override
|
|
public @NotNull ItemStack withMeta(@NotNull ItemMeta meta) {
|
|
return new ItemStackImpl(material, amount, (ItemMetaImpl) meta);
|
|
}
|
|
|
|
@Override
|
|
public boolean isSimilar(@NotNull ItemStack itemStack) {
|
|
return material == itemStack.material() && meta.equals(itemStack.meta());
|
|
}
|
|
|
|
@Override
|
|
public @NotNull CompoundBinaryTag toItemNBT() {
|
|
CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder()
|
|
.putString("id", material.name())
|
|
.putByte("Count", (byte) amount);
|
|
CompoundBinaryTag nbt = meta.toNBT();
|
|
if (nbt.size() > 0) builder.put("tag", nbt);
|
|
return builder.build();
|
|
}
|
|
|
|
@Contract(value = "-> new", pure = true)
|
|
private @NotNull ItemStack.Builder builder() {
|
|
return new Builder(material, amount, new ItemMetaImpl.Builder(meta.tagHandler().copy()));
|
|
}
|
|
|
|
static final class Builder implements ItemStack.Builder {
|
|
final Material material;
|
|
int amount;
|
|
ItemMetaImpl.Builder metaBuilder;
|
|
|
|
Builder(Material material, int amount, ItemMetaImpl.Builder metaBuilder) {
|
|
this.material = material;
|
|
this.amount = amount;
|
|
this.metaBuilder = metaBuilder;
|
|
}
|
|
|
|
Builder(Material material, int amount) {
|
|
this(material, amount, new ItemMetaImpl.Builder(TagHandler.newHandler()));
|
|
}
|
|
|
|
@Override
|
|
public ItemStack.@NotNull Builder amount(int amount) {
|
|
this.amount = amount;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public ItemStack.@NotNull Builder meta(@NotNull TagHandler tagHandler) {
|
|
return metaBuilder(new ItemMetaImpl.Builder(tagHandler.copy()));
|
|
}
|
|
|
|
@Override
|
|
public ItemStack.@NotNull Builder meta(@NotNull CompoundBinaryTag compound) {
|
|
return metaBuilder(new ItemMetaImpl.Builder(TagHandler.fromCompound(compound)));
|
|
}
|
|
|
|
@Override
|
|
public ItemStack.@NotNull Builder meta(@NotNull ItemMeta itemMeta) {
|
|
final TagHandler tagHandler = ((ItemMetaImpl) itemMeta).tagHandler();
|
|
return metaBuilder(new ItemMetaImpl.Builder(tagHandler.copy()));
|
|
}
|
|
|
|
@Override
|
|
public ItemStack.@NotNull Builder meta(@NotNull Consumer<ItemMeta.Builder> consumer) {
|
|
consumer.accept(metaBuilder);
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public <V extends ItemMetaView.Builder, T extends ItemMetaView<V>> ItemStack.@NotNull Builder meta(@NotNull Class<T> metaType,
|
|
@NotNull Consumer<@NotNull V> itemMetaConsumer) {
|
|
V view = ItemMetaViewImpl.constructBuilder(metaType, metaBuilder.tagHandler());
|
|
itemMetaConsumer.accept(view);
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public <T> void setTag(@NotNull Tag<T> tag, @Nullable T value) {
|
|
this.metaBuilder.setTag(tag, value);
|
|
}
|
|
|
|
@Override
|
|
public @NotNull ItemStack build() {
|
|
return ItemStackImpl.create(material, amount, metaBuilder.build());
|
|
}
|
|
|
|
private ItemStack.@NotNull Builder metaBuilder(@NotNull ItemMetaImpl.Builder builder) {
|
|
this.metaBuilder = builder;
|
|
return this;
|
|
}
|
|
}
|
|
}
|