Add direct access to nbt for meta subclasses

This commit is contained in:
themode 2021-12-20 22:51:01 +01:00 committed by TheMode
parent c5141f4145
commit 9927665d91
11 changed files with 77 additions and 110 deletions

View File

@ -39,30 +39,28 @@ public abstract class ItemMetaBuilder implements TagWritable {
@Contract("_ -> this")
public @NotNull ItemMetaBuilder damage(int damage) {
this.damage = damage;
mutateNbt(compound -> compound.setInt("Damage", damage));
this.nbt.setInt("Damage", damage);
return this;
}
@Contract("_ -> this")
public @NotNull ItemMetaBuilder unbreakable(boolean unbreakable) {
this.unbreakable = unbreakable;
mutateNbt(compound -> compound.set("Unbreakable", NBT.Boolean(unbreakable)));
this.nbt.set("Unbreakable", NBT.Boolean(unbreakable));
return this;
}
@Contract("_ -> this")
public @NotNull ItemMetaBuilder hideFlag(int hideFlag) {
this.hideFlag = hideFlag;
mutateNbt(compound -> compound.setInt("HideFlags", hideFlag));
this.nbt.setInt("HideFlags", hideFlag);
return this;
}
@Contract("_ -> this")
public @NotNull ItemMetaBuilder hideFlag(@NotNull ItemHideFlag... hideFlags) {
int result = 0;
for (ItemHideFlag hideFlag : hideFlags) {
result |= hideFlag.getBitFieldPart();
}
for (ItemHideFlag hideFlag : hideFlags) result |= hideFlag.getBitFieldPart();
return hideFlag(result);
}
@ -71,8 +69,7 @@ public abstract class ItemMetaBuilder implements TagWritable {
this.displayName = displayName;
handleCompound("display", nbtCompound -> {
if (displayName != null) {
final String name = GsonComponentSerializer.gson().serialize(displayName);
nbtCompound.setString("Name", name);
nbtCompound.setString("Name", GsonComponentSerializer.gson().serialize(displayName));
} else {
nbtCompound.remove("Name");
}
@ -118,16 +115,14 @@ public abstract class ItemMetaBuilder implements TagWritable {
@Contract("-> this")
public @NotNull ItemMetaBuilder clearEnchantment() {
this.enchantmentMap = new HashMap<>();
enchantments(enchantmentMap);
this.nbt.remove("Enchantments");
return this;
}
@Contract("_ -> this")
public @NotNull ItemMetaBuilder attributes(@NotNull List<@NotNull ItemAttribute> attributes) {
this.attributes = new ArrayList<>(attributes);
handleCollection(attributes, "AttributeModifiers", () -> NBT.List(
NBTType.TAG_Compound,
handleCollection(attributes, "AttributeModifiers", () -> NBT.List(NBTType.TAG_Compound,
attributes.stream()
.map(itemAttribute -> NBT.Compound(Map.of(
"UUID", NBT.IntArray(Utils.uuidToIntArray(itemAttribute.getUuid())),
@ -138,14 +133,13 @@ public abstract class ItemMetaBuilder implements TagWritable {
"Name", NBT.String(itemAttribute.getInternalName()))))
.toList()
));
return this;
}
@Contract("_ -> this")
public @NotNull ItemMetaBuilder customModelData(int customModelData) {
this.customModelData = customModelData;
mutateNbt(compound -> compound.setInt("CustomModelData", customModelData));
this.nbt.setInt("CustomModelData", customModelData);
return this;
}
@ -185,7 +179,7 @@ public abstract class ItemMetaBuilder implements TagWritable {
@Override
public <T> void setTag(@NotNull Tag<T> tag, @Nullable T value) {
mutateNbt(compound -> tag.write(compound, value));
tag.write(nbt, value);
}
public <T> @NotNull ItemMetaBuilder set(@NotNull Tag<T> tag, @Nullable T value) {
@ -208,68 +202,59 @@ public abstract class ItemMetaBuilder implements TagWritable {
}
}
protected MutableNBTCompound mutableNbt() {
return nbt;
}
protected void mutateNbt(Consumer<MutableNBTCompound> consumer) {
consumer.accept(nbt);
}
protected @NotNull ItemMeta generate() {
return build();
}
protected void handleCompound(@NotNull String key,
@NotNull Consumer<@NotNull MutableNBTCompound> consumer) {
mutateNbt(nbt -> {
MutableNBTCompound compoundToModify = nbt.get(key) instanceof NBTCompound compound ?
compound.toMutableCompound() : new MutableNBTCompound();
consumer.accept(compoundToModify);
if (compoundToModify.isEmpty()) {
nbt.remove(key);
} else {
nbt.set(key, compoundToModify.toCompound());
}
});
MutableNBTCompound compoundToModify = nbt.get(key) instanceof NBTCompound compound ?
compound.toMutableCompound() : new MutableNBTCompound();
consumer.accept(compoundToModify);
if (compoundToModify.isEmpty()) {
this.nbt.remove(key);
} else {
this.nbt.set(key, compoundToModify.toCompound());
}
}
protected void handleNullable(@Nullable Object value,
@NotNull String key,
@NotNull Supplier<@NotNull NBT> supplier) {
mutateNbt(compound -> {
if (value != null) {
compound.set(key, supplier.get());
} else {
compound.remove(key);
}
});
if (value != null) {
this.nbt.set(key, supplier.get());
} else {
this.nbt.remove(key);
}
}
protected void handleCollection(@NotNull Collection<?> objects,
@NotNull String key,
@NotNull Supplier<@NotNull NBT> supplier) {
mutateNbt(compound -> {
if (!objects.isEmpty()) {
compound.set(key, supplier.get());
} else {
compound.remove(key);
}
});
if (!objects.isEmpty()) {
this.nbt.set(key, supplier.get());
} else {
this.nbt.remove(key);
}
}
protected void handleMap(@NotNull Map<?, ?> objects,
@NotNull String key,
@NotNull Consumer<MutableNBTCompound> consumer) {
mutateNbt(compound -> {
if (!objects.isEmpty()) {
consumer.accept(compound);
} else {
compound.remove(key);
}
});
if (!objects.isEmpty()) {
consumer.accept(nbt);
} else {
nbt.remove(key);
}
}
@ApiStatus.Internal
public static void resetMeta(@NotNull ItemMetaBuilder src, @NotNull NBTCompound nbtCompound) {
src.nbt = nbtCompound.toMutableCompound();
src.nbt.copyFrom(nbtCompound);
appendMeta(src, nbtCompound);
}
@ -339,8 +324,6 @@ public abstract class ItemMetaBuilder implements TagWritable {
if (nbt.get("CustomModelData") instanceof NBTInt customModelData) {
metaBuilder.customModelData = customModelData.getValue();
}
// Meta specific fields
metaBuilder.read(nbt);
// CanPlaceOn
if (nbt.get("CanPlaceOn") instanceof NBTList<?> canPlaceOn &&
canPlaceOn.getSubtagType() == NBTType.TAG_String) {
@ -357,6 +340,8 @@ public abstract class ItemMetaBuilder implements TagWritable {
metaBuilder.canDestroy.add(block);
}
}
// Meta specific fields
metaBuilder.read(nbt);
}
public interface Provider<T extends ItemMetaBuilder> {

View File

@ -116,7 +116,7 @@ public final class ItemStackBuilder {
@Contract(value = "-> new", pure = true)
public @NotNull ItemStack build() {
if (amount < 1) return ItemStack.AIR;
return new ItemStack(material, amount, metaBuilder.generate(), stackingRule);
return new ItemStack(material, amount, metaBuilder.build(), stackingRule);
}
private static final class DefaultMeta extends ItemMetaBuilder {

View File

@ -57,8 +57,7 @@ public class BundleMeta extends ItemMeta implements ItemMetaBuilder.Provider<Bun
}
private void updateItems() {
mutateNbt(compound -> compound.set("Items", NBT.List(NBTType.TAG_Compound,
items.size(), i -> items.get(i).toItemNBT())));
mutableNbt().set("Items", NBT.List(NBTType.TAG_Compound, items.size(), i -> items.get(i).toItemNBT()));
}
@Override

View File

@ -49,38 +49,30 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
public Builder lodestoneTracked(boolean lodestoneTracked) {
this.lodestoneTracked = lodestoneTracked;
mutateNbt(compound -> compound.setByte("LodestoneTracked", (byte) (lodestoneTracked ? 1 : 0)));
mutableNbt().setByte("LodestoneTracked", (byte) (lodestoneTracked ? 1 : 0));
return this;
}
public Builder lodestoneDimension(@Nullable String lodestoneDimension) {
this.lodestoneDimension = lodestoneDimension;
mutateNbt(compound -> {
if (lodestoneDimension != null) {
compound.setString("LodestoneDimension", lodestoneDimension);
} else {
compound.remove("LodestoneDimension");
}
});
if (lodestoneDimension != null) {
mutableNbt().setString("LodestoneDimension", lodestoneDimension);
} else {
mutableNbt().remove("LodestoneDimension");
}
return this;
}
public Builder lodestonePosition(@Nullable Point lodestonePosition) {
this.lodestonePosition = lodestonePosition;
mutateNbt(compound -> {
if (lodestonePosition != null) {
compound.set("LodestonePos", NBT.Compound(Map.of(
"X", NBT.Int(lodestonePosition.blockX()),
"Y", NBT.Int(lodestonePosition.blockY()),
"Z", NBT.Int(lodestonePosition.blockZ()))));
} else {
compound.remove("LodestonePos");
}
});
if (lodestonePosition != null) {
mutableNbt().set("LodestonePos", NBT.Compound(Map.of(
"X", NBT.Int(lodestonePosition.blockX()),
"Y", NBT.Int(lodestonePosition.blockY()),
"Z", NBT.Int(lodestonePosition.blockZ()))));
} else {
mutableNbt().remove("LodestonePos");
}
return this;
}

View File

@ -90,11 +90,8 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider<S
public Builder projectile(@NotNull ItemStack projectile) {
this.projectile1 = projectile;
this.triple = false;
List<NBTCompound> chargedProjectiles =
projectile.isAir() ? List.of() : List.of(getItemCompound(projectile));
mutateNbt(compound -> compound.set("ChargedProjectiles", NBT.List(NBTType.TAG_Compound, chargedProjectiles)));
mutableNbt().set("ChargedProjectiles", NBT.List(NBTType.TAG_Compound,
projectile.isAir() ? List.of() : List.of(getItemCompound(projectile))));
return this;
}
@ -109,16 +106,13 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider<S
Check.argCondition(projectile1.isAir(), "the projectile1 of your crossbow isn't visible");
Check.argCondition(projectile2.isAir(), "the projectile2 of your crossbow isn't visible");
Check.argCondition(projectile3.isAir(), "the projectile3 of your crossbow isn't visible");
this.projectile1 = projectile1;
this.projectile2 = projectile2;
this.projectile3 = projectile3;
this.triple = true;
List<NBTCompound> chargedProjectiles =
List.of(getItemCompound(projectile1), getItemCompound(projectile2), getItemCompound(projectile3));
mutateNbt(compound -> compound.set("ChargedProjectiles", NBT.List(NBTType.TAG_Compound, chargedProjectiles)));
mutableNbt().set("ChargedProjectiles", NBT.List(NBTType.TAG_Compound, chargedProjectiles));
return this;
}
@ -129,7 +123,7 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider<S
*/
public Builder charged(boolean charged) {
this.charged = charged;
mutateNbt(compound -> compound.setByte("Charged", (byte) (charged ? 1 : 0)));
mutableNbt().set("Charged", NBT.Boolean(charged));
return this;
}

View File

@ -37,7 +37,7 @@ public class EnchantedBookMeta extends ItemMeta implements ItemMetaBuilder.Provi
public @NotNull Builder enchantments(@NotNull Map<Enchantment, Short> enchantments) {
this.enchantments = enchantments;
mutateNbt(compound -> NBTUtils.writeEnchant(compound, "StoredEnchantments", enchantments));
NBTUtils.writeEnchant(mutableNbt(), "StoredEnchantments", enchantments);
return this;
}

View File

@ -7,6 +7,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import java.util.Objects;
public class FireworkEffectMeta extends ItemMeta implements ItemMetaBuilder.Provider<FireworkEffectMeta.Builder> {
private final FireworkEffect fireworkEffect;
@ -26,7 +28,7 @@ public class FireworkEffectMeta extends ItemMeta implements ItemMetaBuilder.Prov
public Builder effect(@Nullable FireworkEffect fireworkEffect) {
this.fireworkEffect = fireworkEffect;
mutateNbt(compound -> compound.set("Explosion", this.fireworkEffect.asCompound()));
handleNullable(fireworkEffect, "Explosion", () -> Objects.requireNonNull(fireworkEffect).asCompound());
return this;
}

View File

@ -75,21 +75,19 @@ public class MapMeta extends ItemMeta implements ItemMetaBuilder.Provider<MapMet
public Builder mapId(int value) {
this.mapId = value;
mutateNbt(compound -> compound.setInt("map", mapId));
mutableNbt().setInt("map", mapId);
return this;
}
public Builder mapScaleDirection(int value) {
this.mapScaleDirection = value;
mutateNbt(compound -> compound.setInt("map_scale_direction", value));
mutableNbt().setInt("map_scale_direction", value);
return this;
}
public Builder decorations(List<Decoration> value) {
this.decorations = new ArrayList<>(value);
mutateNbt(compound -> compound.set("Decorations", NBT.List(
NBTType.TAG_Compound,
mutableNbt().set("Decorations", NBT.List(NBTType.TAG_Compound,
decorations.stream()
.map(decoration -> NBT.Compound(Map.of(
"id", NBT.String(decoration.id()),
@ -98,7 +96,7 @@ public class MapMeta extends ItemMeta implements ItemMetaBuilder.Provider<MapMet
"z", NBT.Byte(decoration.z()),
"rot", NBT.Double(decoration.rotation()))))
.toList()
)));
));
return this;
}

View File

@ -49,15 +49,13 @@ public class PotionMeta extends ItemMeta implements ItemMetaBuilder.Provider<Pot
public Builder potionType(@NotNull PotionType potionType) {
this.potionType = potionType;
mutateNbt(compound -> compound.setString("Potion", potionType.name()));
mutableNbt().setString("Potion", potionType.name());
return this;
}
public Builder effects(@NotNull List<CustomPotionEffect> customPotionEffects) {
this.customPotionEffects = customPotionEffects;
NBTList<NBTCompound> potionList = NBT.List(
NBTType.TAG_Compound,
mutableNbt().set("CustomPotionEffects", NBT.List(NBTType.TAG_Compound,
customPotionEffects.stream()
.map(customPotionEffect -> NBT.Compound(Map.of(
"Id", NBT.Byte(customPotionEffect.id()),
@ -67,15 +65,13 @@ public class PotionMeta extends ItemMeta implements ItemMetaBuilder.Provider<Pot
"ShowParticles", NBT.Boolean(customPotionEffect.showParticles()),
"ShowIcon", NBT.Boolean(customPotionEffect.showIcon()))))
.toList()
);
mutateNbt(compound -> compound.set("CustomPotionEffects", potionList));
));
return this;
}
public Builder color(@NotNull Color color) {
this.color = color;
mutateNbt(compound -> compound.setInt("CustomPotionColor", color.asRGB()));
mutableNbt().setInt("CustomPotionColor", color.asRGB());
return this;
}

View File

@ -89,7 +89,7 @@ public class WrittenBookMeta extends ItemMeta implements ItemMetaBuilder.Provide
public Builder resolved(boolean resolved) {
this.resolved = resolved;
mutateNbt(compound -> compound.setByte("resolved", (byte) (resolved ? 1 : 0)));
mutableNbt().set("resolved", NBT.Boolean(resolved));
return this;
}

View File

@ -2,10 +2,7 @@ package item;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.item.Enchantment;
import net.minestom.server.item.ItemHideFlag;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.*;
import org.junit.jupiter.api.Test;
import java.util.Map;
@ -102,6 +99,10 @@ public class ItemTest {
item = item.withMeta(meta -> meta.enchantment(Enchantment.EFFICIENCY, (short) 10));
enchantments = item.getMeta().getEnchantmentMap();
assertEquals(enchantments.get(Enchantment.EFFICIENCY), (short) 10);
item = item.withMeta(ItemMetaBuilder::clearEnchantment);
enchantments = item.getMeta().getEnchantmentMap();
assertTrue(enchantments.isEmpty());
}
@Test