From e5643b591baa309048c14516fed9d3803bd0551e Mon Sep 17 00:00:00 2001 From: Kil'jaeden <63972649+lordtgm@users.noreply.github.com> Date: Sat, 3 Feb 2024 15:58:21 +0330 Subject: [PATCH] Added support for trim registries (#128) * trim_material and trim_pattern registries are now generated, loaded and sent to the clients * fixed override_armor_materials * allowing TrimMaterial and TrimPattern to be created dynamically * cleanup and formatting (cherry picked from commit 70e4355ca106b5a7e684ffcb887508a0047d58ee) --- .../java/net/minestom/codegen/Generators.java | 3 + gradle/libs.versions.toml | 2 +- .../server/item/armor/TrimMaterials.java | 27 +++++ .../server/item/armor/TrimPatterns.java | 39 +++++++ .../net/minestom/server/MinecraftServer.java | 5 + .../net/minestom/server/ServerProcess.java | 3 + .../minestom/server/ServerProcessImpl.java | 8 ++ .../server/item/armor/TrimManager.java | 107 ++++++++++++++++++ .../server/item/armor/TrimMaterial.java | 89 +++++++++++++++ .../server/item/armor/TrimMaterialImpl.java | 49 ++++++++ .../server/item/armor/TrimPattern.java | 66 +++++++++++ .../server/item/armor/TrimPatternImpl.java | 41 +++++++ .../server/network/ConnectionManager.java | 2 + .../minestom/server/registry/Registry.java | 63 ++++++++++- 14 files changed, 502 insertions(+), 2 deletions(-) create mode 100644 src/autogenerated/java/net/minestom/server/item/armor/TrimMaterials.java create mode 100644 src/autogenerated/java/net/minestom/server/item/armor/TrimPatterns.java create mode 100644 src/main/java/net/minestom/server/item/armor/TrimManager.java create mode 100644 src/main/java/net/minestom/server/item/armor/TrimMaterial.java create mode 100644 src/main/java/net/minestom/server/item/armor/TrimMaterialImpl.java create mode 100644 src/main/java/net/minestom/server/item/armor/TrimPattern.java create mode 100644 src/main/java/net/minestom/server/item/armor/TrimPatternImpl.java diff --git a/code-generators/src/main/java/net/minestom/codegen/Generators.java b/code-generators/src/main/java/net/minestom/codegen/Generators.java index 469ad0749..911e2b59e 100644 --- a/code-generators/src/main/java/net/minestom/codegen/Generators.java +++ b/code-generators/src/main/java/net/minestom/codegen/Generators.java @@ -34,6 +34,9 @@ public class Generators { generator.generate(resource("sounds.json"), "net.minestom.server.sound", "SoundEvent", "SoundEventImpl", "SoundEvents"); generator.generate(resource("custom_statistics.json"), "net.minestom.server.statistic", "StatisticType", "StatisticTypeImpl", "StatisticTypes"); generator.generate(resource("damage_types.json"), "net.minestom.server.entity.damage", "DamageType", "DamageTypeImpl", "DamageTypes"); + generator.generate(resource("trim_materials.json"), "net.minestom.server.item.armor", "TrimMaterial", "TrimMaterialImpl", "TrimMaterials"); + generator.generate(resource("trim_patterns.json"), "net.minestom.server.item.armor", "TrimPattern", "TrimPatternImpl", "TrimPatterns"); + // Generate fluids new FluidGenerator(resource("fluids.json"), outputFolder).generate(); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 85391204c..2d85acc63 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ metadata.format.version = "1.1" [versions] # Important dependencies -data = "1.20.4-rv1" +data = "1.20.4-rv2" adventure = "4.15.0" kotlin = "1.7.22" dependencyGetter = "v1.0.1" diff --git a/src/autogenerated/java/net/minestom/server/item/armor/TrimMaterials.java b/src/autogenerated/java/net/minestom/server/item/armor/TrimMaterials.java new file mode 100644 index 000000000..07e0e19ee --- /dev/null +++ b/src/autogenerated/java/net/minestom/server/item/armor/TrimMaterials.java @@ -0,0 +1,27 @@ +package net.minestom.server.item.armor; + +/** + * Code autogenerated, do not edit! + */ +@SuppressWarnings("unused") +interface TrimMaterials { + TrimMaterial LAPIS = TrimMaterialImpl.get("minecraft:lapis"); + + TrimMaterial IRON = TrimMaterialImpl.get("minecraft:iron"); + + TrimMaterial DIAMOND = TrimMaterialImpl.get("minecraft:diamond"); + + TrimMaterial AMETHYST = TrimMaterialImpl.get("minecraft:amethyst"); + + TrimMaterial COPPER = TrimMaterialImpl.get("minecraft:copper"); + + TrimMaterial QUARTZ = TrimMaterialImpl.get("minecraft:quartz"); + + TrimMaterial EMERALD = TrimMaterialImpl.get("minecraft:emerald"); + + TrimMaterial REDSTONE = TrimMaterialImpl.get("minecraft:redstone"); + + TrimMaterial GOLD = TrimMaterialImpl.get("minecraft:gold"); + + TrimMaterial NETHERITE = TrimMaterialImpl.get("minecraft:netherite"); +} diff --git a/src/autogenerated/java/net/minestom/server/item/armor/TrimPatterns.java b/src/autogenerated/java/net/minestom/server/item/armor/TrimPatterns.java new file mode 100644 index 000000000..1233b0497 --- /dev/null +++ b/src/autogenerated/java/net/minestom/server/item/armor/TrimPatterns.java @@ -0,0 +1,39 @@ +package net.minestom.server.item.armor; + +/** + * Code autogenerated, do not edit! + */ +@SuppressWarnings("unused") +interface TrimPatterns { + TrimPattern TIDE = TrimPatternImpl.get("minecraft:tide"); + + TrimPattern RIB = TrimPatternImpl.get("minecraft:rib"); + + TrimPattern HOST = TrimPatternImpl.get("minecraft:host"); + + TrimPattern SILENCE = TrimPatternImpl.get("minecraft:silence"); + + TrimPattern WILD = TrimPatternImpl.get("minecraft:wild"); + + TrimPattern WAYFINDER = TrimPatternImpl.get("minecraft:wayfinder"); + + TrimPattern DUNE = TrimPatternImpl.get("minecraft:dune"); + + TrimPattern RAISER = TrimPatternImpl.get("minecraft:raiser"); + + TrimPattern SNOUT = TrimPatternImpl.get("minecraft:snout"); + + TrimPattern VEX = TrimPatternImpl.get("minecraft:vex"); + + TrimPattern SPIRE = TrimPatternImpl.get("minecraft:spire"); + + TrimPattern SENTRY = TrimPatternImpl.get("minecraft:sentry"); + + TrimPattern EYE = TrimPatternImpl.get("minecraft:eye"); + + TrimPattern WARD = TrimPatternImpl.get("minecraft:ward"); + + TrimPattern COAST = TrimPatternImpl.get("minecraft:coast"); + + TrimPattern SHAPER = TrimPatternImpl.get("minecraft:shaper"); +} diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index 7832a2060..4bfe33d3b 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -10,6 +10,7 @@ import net.minestom.server.extensions.ExtensionManager; import net.minestom.server.gamedata.tags.TagManager; import net.minestom.server.instance.InstanceManager; import net.minestom.server.instance.block.BlockManager; +import net.minestom.server.item.armor.TrimManager; import net.minestom.server.listener.manager.PacketListenerManager; import net.minestom.server.monitoring.BenchmarkManager; import net.minestom.server.network.ConnectionManager; @@ -262,6 +263,10 @@ public final class MinecraftServer { return serverProcess.tag(); } + public static TrimManager getTrimManager() { + return serverProcess.trim(); + } + public static Server getServer() { return serverProcess.server(); } diff --git a/src/main/java/net/minestom/server/ServerProcess.java b/src/main/java/net/minestom/server/ServerProcess.java index 7ffa35bf4..5ebf5f9e5 100644 --- a/src/main/java/net/minestom/server/ServerProcess.java +++ b/src/main/java/net/minestom/server/ServerProcess.java @@ -11,6 +11,7 @@ import net.minestom.server.instance.Chunk; import net.minestom.server.instance.InstanceManager; import net.minestom.server.instance.block.BlockManager; import net.minestom.server.instance.block.rule.BlockPlacementRule; +import net.minestom.server.item.armor.TrimManager; import net.minestom.server.listener.manager.PacketListenerManager; import net.minestom.server.monitoring.BenchmarkManager; import net.minestom.server.network.ConnectionManager; @@ -107,6 +108,8 @@ public interface ServerProcess extends Snapshotable { */ @NotNull TagManager tag(); + @NotNull TrimManager trim(); + /** * Handles all thrown exceptions from the server. */ diff --git a/src/main/java/net/minestom/server/ServerProcessImpl.java b/src/main/java/net/minestom/server/ServerProcessImpl.java index 061115c6c..c8dde4b25 100644 --- a/src/main/java/net/minestom/server/ServerProcessImpl.java +++ b/src/main/java/net/minestom/server/ServerProcessImpl.java @@ -15,6 +15,7 @@ import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Instance; import net.minestom.server.instance.InstanceManager; import net.minestom.server.instance.block.BlockManager; +import net.minestom.server.item.armor.TrimManager; import net.minestom.server.listener.manager.PacketListenerManager; import net.minestom.server.monitoring.BenchmarkManager; import net.minestom.server.monitoring.TickMonitor; @@ -67,6 +68,7 @@ final class ServerProcessImpl implements ServerProcess { private final AdvancementManager advancement; private final BossBarManager bossBar; private final TagManager tag; + private final TrimManager trim; private final Server server; private final ThreadDispatcher dispatcher; @@ -94,6 +96,7 @@ final class ServerProcessImpl implements ServerProcess { this.advancement = new AdvancementManager(); this.bossBar = new BossBarManager(); this.tag = new TagManager(); + this.trim = new TrimManager(); this.server = new Server(packetProcessor); this.dispatcher = ThreadDispatcher.singleThread(); @@ -175,6 +178,11 @@ final class ServerProcessImpl implements ServerProcess { return tag; } + @Override + public @NotNull TrimManager trim() { + return trim; + } + @Override public @NotNull ExceptionManager exception() { return exception; diff --git a/src/main/java/net/minestom/server/item/armor/TrimManager.java b/src/main/java/net/minestom/server/item/armor/TrimManager.java new file mode 100644 index 000000000..c9c94aa1a --- /dev/null +++ b/src/main/java/net/minestom/server/item/armor/TrimManager.java @@ -0,0 +1,107 @@ +package net.minestom.server.item.armor; + +import net.minestom.server.item.Material; +import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBT; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; +import org.jglrxavpok.hephaistos.nbt.NBTType; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class TrimManager { + private final Set trimMaterials; + private final Set trimPatterns; + private NBTCompound trimMaterialCache = null; + private NBTCompound trimPatternCache = null; + + public TrimManager() { + this.trimMaterials = new HashSet<>(); + this.trimPatterns = new HashSet<>(); + } + + public @Nullable TrimMaterial fromIngredient(Material ingredient) { + return this.trimMaterials.stream().filter(trimMaterial -> trimMaterial.ingredient().equals(ingredient)).findFirst().orElse(null); + } + + public @Nullable TrimPattern fromTemplate(Material material) { + return this.trimPatterns.stream().filter(trimPattern -> trimPattern.template().equals(material)).findFirst().orElse(null); + } + + + public NBTCompound getTrimMaterialNBT() { + if (trimMaterialCache == null) { + var trimMaterials = this.trimMaterials.stream() + .map((trimMaterial) -> NBT.Compound(Map.of( + "id", NBT.Int(trimMaterial.id()), + "name", NBT.String(trimMaterial.name()), + "element", trimMaterial.asNBT() + ))) + .toList(); + + trimMaterialCache = NBT.Compound(Map.of( + "type", NBT.String("minecraft:trim_material"), + "value", NBT.List(NBTType.TAG_Compound, trimMaterials) + )); + } + return trimMaterialCache; + } + + public NBTCompound getTrimPatternNBT() { + if (trimPatternCache == null) { + var trimPatterns = this.trimPatterns.stream() + .map((trimPattern) -> NBT.Compound(Map.of( + "id", NBT.Int(trimPattern.id()), + "name", NBT.String(trimPattern.name()), + "element", trimPattern.asNBT() + ))) + .toList(); + + trimPatternCache = NBT.Compound(Map.of( + "type", NBT.String("minecraft:trim_pattern"), + "value", NBT.List(NBTType.TAG_Compound, trimPatterns) + )); + } + + return trimPatternCache; + } + + public Set getTrimMaterials() { + return Set.copyOf(this.trimMaterials); + } + + public Set getTrimPatterns() { + return Set.copyOf(trimPatterns); + } + + public void addDefaultTrimMaterials() { + this.trimMaterialCache = null; + this.trimMaterials.addAll(TrimMaterial.values()); + } + + public void addDefaultTrimPatterns() { + this.trimMaterialCache = null; + this.trimPatterns.addAll(TrimPattern.values()); + } + + public boolean addTrimMaterial(TrimMaterial trimMaterial) { + this.trimMaterialCache = null; + return this.trimMaterials.add(trimMaterial); + } + + public boolean removeTrimMaterial(TrimMaterial trimMaterial) { + this.trimMaterialCache = null; + return this.trimMaterials.remove(trimMaterial); + } + + public boolean addTrimPattern(TrimPattern trimPattern) { + this.trimMaterialCache = null; + return this.trimPatterns.add(trimPattern); + } + + public boolean removeTrimPattern(TrimPattern trimPattern) { + this.trimMaterialCache = null; + return this.trimPatterns.remove(trimPattern); + } +} diff --git a/src/main/java/net/minestom/server/item/armor/TrimMaterial.java b/src/main/java/net/minestom/server/item/armor/TrimMaterial.java new file mode 100644 index 000000000..23effa3c3 --- /dev/null +++ b/src/main/java/net/minestom/server/item/armor/TrimMaterial.java @@ -0,0 +1,89 @@ +package net.minestom.server.item.armor; + +import net.kyori.adventure.text.Component; +import net.minestom.server.item.Material; +import net.minestom.server.registry.ProtocolObject; +import net.minestom.server.registry.Registry; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; + +import java.util.Collection; +import java.util.Map; + +public interface TrimMaterial extends ProtocolObject { + static @NotNull TrimMaterial create(@NotNull NamespaceID namespace, + @NotNull String assetName, + @NotNull Material ingredient, + float itemModelIndex, + @NotNull Map overrideArmorMaterials, + @NotNull Component description, + Registry.Properties custom) { + return new TrimMaterialImpl( + new Registry.TrimMaterialEntry( + namespace, + assetName, + ingredient, + itemModelIndex, + overrideArmorMaterials, + description, + custom + ) + ); + } + + static @NotNull TrimMaterial create(@NotNull NamespaceID namespace, + @NotNull String assetName, + @NotNull Material ingredient, + float itemModelIndex, + @NotNull Map overrideArmorMaterials, + @NotNull Component description) { + return new TrimMaterialImpl( + new Registry.TrimMaterialEntry( + namespace, + assetName, + ingredient, + itemModelIndex, + overrideArmorMaterials, + description, + null + ) + ); + } + + static Collection values() { + return TrimMaterialImpl.values(); + } + + @Contract(pure = true) + @NotNull Registry.TrimMaterialEntry registry(); + + @Override + default @NotNull NamespaceID namespace() { + return registry().namespace(); + } + + default @NotNull String assetName() { + return registry().assetName(); + } + + default @NotNull Material ingredient() { + return registry().ingredient(); + } + + default float itemModelIndex() { + return registry().itemModelIndex(); + } + + default @NotNull Map overrideArmorMaterials() { + return registry().overrideArmorMaterials(); + } + + default @NotNull Component description() { + return registry().description(); + } + + NBTCompound asNBT(); + +} diff --git a/src/main/java/net/minestom/server/item/armor/TrimMaterialImpl.java b/src/main/java/net/minestom/server/item/armor/TrimMaterialImpl.java new file mode 100644 index 000000000..89ff795db --- /dev/null +++ b/src/main/java/net/minestom/server/item/armor/TrimMaterialImpl.java @@ -0,0 +1,49 @@ +package net.minestom.server.item.armor; + +import net.minestom.server.adventure.serializer.nbt.NbtComponentSerializer; +import net.minestom.server.registry.Registry; +import org.jglrxavpok.hephaistos.nbt.NBT; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; + +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +record TrimMaterialImpl(Registry.TrimMaterialEntry registry, int id) implements TrimMaterial { + static final AtomicInteger i = new AtomicInteger(); + private static final Registry.Container CONTAINER; + + static { + CONTAINER = Registry.createContainer(Registry.Resource.TRIM_MATERIALS, + (namespace, properties) -> new TrimMaterialImpl(Registry.trimMaterial(namespace, properties))); + } + + public TrimMaterialImpl(Registry.TrimMaterialEntry registry) { + this(registry, i.getAndIncrement()); + } + + public static TrimMaterial get(String namespace) { + return CONTAINER.get(namespace); + } + + static Collection values() { + return CONTAINER.values(); + } + + public NBTCompound asNBT() { + return NBT.Compound(nbt -> { + nbt.setString("asset_name", assetName()); + nbt.setString("ingredient", ingredient().namespace().asString()); + nbt.setFloat("item_model_index", itemModelIndex()); + nbt.set("override_armor_materials", NBT.Compound(overrideArmorMaterials().entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + entry -> NBT.String(entry.getValue()) + )) + )); + nbt.set("description", NbtComponentSerializer.nbt().serialize(description())); + }); + } + +} diff --git a/src/main/java/net/minestom/server/item/armor/TrimPattern.java b/src/main/java/net/minestom/server/item/armor/TrimPattern.java new file mode 100644 index 000000000..590bd2dd1 --- /dev/null +++ b/src/main/java/net/minestom/server/item/armor/TrimPattern.java @@ -0,0 +1,66 @@ +package net.minestom.server.item.armor; + +import net.kyori.adventure.text.Component; +import net.minestom.server.item.Material; +import net.minestom.server.registry.ProtocolObject; +import net.minestom.server.registry.Registry; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; + +import java.util.Collection; + +public interface TrimPattern extends ProtocolObject { + static @NotNull TrimPattern create(@NotNull NamespaceID namespace, + @NotNull NamespaceID assetID, + @NotNull Material template, + @NotNull Component description, + boolean decal, + @NotNull Registry.Properties custom) { + return new TrimPatternImpl( + new Registry.TrimPatternEntry(namespace, assetID, template, description, decal, custom) + ); + } + + static @NotNull TrimPattern create(@NotNull NamespaceID namespace, + @NotNull NamespaceID assetID, + @NotNull Material template, + @NotNull Component description, + boolean decal) { + return new TrimPatternImpl( + new Registry.TrimPatternEntry(namespace, assetID, template, description, decal, null) + ); + } + + static Collection values() { + return TrimPatternImpl.values(); + } + + @Contract(pure = true) + @NotNull Registry.TrimPatternEntry registry(); + + @Override + default @NotNull NamespaceID namespace() { + return registry().namespace(); + } + + default @NotNull NamespaceID assetID() { + return registry().assetID(); + } + + default @NotNull Material template() { + return registry().template(); + } + + default @NotNull Component description() { + return registry().description(); + } + + default boolean decal() { + return registry().decal(); + } + + NBTCompound asNBT(); + +} diff --git a/src/main/java/net/minestom/server/item/armor/TrimPatternImpl.java b/src/main/java/net/minestom/server/item/armor/TrimPatternImpl.java new file mode 100644 index 000000000..304d65b3f --- /dev/null +++ b/src/main/java/net/minestom/server/item/armor/TrimPatternImpl.java @@ -0,0 +1,41 @@ +package net.minestom.server.item.armor; + +import net.minestom.server.adventure.serializer.nbt.NbtComponentSerializer; +import net.minestom.server.registry.Registry; +import org.jglrxavpok.hephaistos.nbt.NBT; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicInteger; + +record TrimPatternImpl(Registry.TrimPatternEntry registry, int id) implements TrimPattern { + static final AtomicInteger i = new AtomicInteger(); + private static final Registry.Container CONTAINER; + + static { + CONTAINER = Registry.createContainer(Registry.Resource.TRIM_PATTERNS, + (namespace, properties) -> new TrimPatternImpl(Registry.trimPattern(namespace, properties))); + } + + public TrimPatternImpl(Registry.TrimPatternEntry registry) { + this(registry, i.getAndIncrement()); + } + + public static TrimPattern get(String namespace) { + return CONTAINER.get(namespace); + } + + static Collection values() { + return CONTAINER.values(); + } + + public NBTCompound asNBT() { + return NBT.Compound(nbt -> { + nbt.setString("asset_id", assetID().asString()); + nbt.setString("template_item", template().namespace().asString()); + nbt.set("description", NbtComponentSerializer.nbt().serialize(description())); + nbt.setByte("decal", (byte) (decal() ? 1 : 0)); + }); + } + +} diff --git a/src/main/java/net/minestom/server/network/ConnectionManager.java b/src/main/java/net/minestom/server/network/ConnectionManager.java index 4caf952ea..f59f075ce 100644 --- a/src/main/java/net/minestom/server/network/ConnectionManager.java +++ b/src/main/java/net/minestom/server/network/ConnectionManager.java @@ -278,6 +278,8 @@ public final class ConnectionManager { registry.put("minecraft:dimension_type", MinecraftServer.getDimensionTypeManager().toNBT()); registry.put("minecraft:worldgen/biome", MinecraftServer.getBiomeManager().toNBT()); registry.put("minecraft:damage_type", DamageType.getNBT()); + registry.put("minecraft:trim_material", MinecraftServer.getTrimManager().getTrimMaterialNBT()); + registry.put("minecraft:trim_pattern", MinecraftServer.getTrimManager().getTrimPatternNBT()); player.sendPacket(new RegistryDataPacket(NBT.Compound(registry))); player.sendPacket(TagsPacket.DEFAULT_TAGS); diff --git a/src/main/java/net/minestom/server/registry/Registry.java b/src/main/java/net/minestom/server/registry/Registry.java index e343c512a..e29de8d4d 100644 --- a/src/main/java/net/minestom/server/registry/Registry.java +++ b/src/main/java/net/minestom/server/registry/Registry.java @@ -2,6 +2,8 @@ package net.minestom.server.registry; import com.google.gson.ToNumberPolicy; import com.google.gson.stream.JsonReader; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.json.JSONComponentSerializer; import net.minestom.server.MinecraftServer; import net.minestom.server.collision.BoundingBox; import net.minestom.server.collision.CollisionUtils; @@ -21,7 +23,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.*; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; +import java.util.stream.Collectors; /** * Handles registry data, used by {@link ProtocolObject} implementations and is strictly internal. @@ -58,6 +62,16 @@ public final class Registry { return new DamageTypeEntry(namespace, main, null); } + @ApiStatus.Internal + public static TrimMaterialEntry trimMaterial(String namespace, @NotNull Properties main) { + return new TrimMaterialEntry(namespace, main, null); + } + + @ApiStatus.Internal + public static TrimPatternEntry trimPattern(String namespace, @NotNull Properties main) { + return new TrimPatternEntry(namespace, main, null); + } + @ApiStatus.Internal public static Map> load(Resource resource) { Map> map = new HashMap<>(); @@ -148,7 +162,8 @@ public final class Registry { POTION_TYPES("potions.json"), PARTICLES("particles.json"), DAMAGE_TYPES("damage_types.json"), - + TRIM_MATERIALS("trim_materials.json"), + TRIM_PATTERNS("trim_patterns.json"), BLOCK_TAGS("tags/block_tags.json"), ENTITY_TYPE_TAGS("tags/entity_type_tags.json"), FLUID_TAGS("tags/fluid_tags.json"), @@ -430,6 +445,44 @@ public final class Registry { custom); } } + public record TrimMaterialEntry(@NotNull NamespaceID namespace, + @NotNull String assetName, + @NotNull Material ingredient, + float itemModelIndex, + @NotNull Map overrideArmorMaterials, + @NotNull Component description, + Properties custom) implements Entry { + public TrimMaterialEntry(@NotNull String namespace, @NotNull Properties main, Properties custom) { + this( + NamespaceID.from(namespace), + main.getString("asset_name"), + Objects.requireNonNull(Material.fromNamespaceId(main.getString("ingredient"))), + (float) main.getDouble("item_model_index"), + Objects.requireNonNullElse(main.section("override_armor_materials"),new PropertiesMap(Map.of())) + .asMap().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> (String) entry.getValue())), + JSONComponentSerializer.json().deserialize(main.section("description").toString()), + custom + ); + } + } + + public record TrimPatternEntry(@NotNull NamespaceID namespace, + @NotNull NamespaceID assetID, + @NotNull Material template, + @NotNull Component description, + boolean decal, + Properties custom) implements Entry { + public TrimPatternEntry(@NotNull String namespace, @NotNull Properties main, Properties custom) { + this( + NamespaceID.from(namespace), + NamespaceID.from(main.getString("asset_id")), + Objects.requireNonNull(Material.fromNamespaceId(main.getString("template_item"))), + JSONComponentSerializer.json().deserialize(main.section("description").toString()), + main.getBoolean("decal"), + custom + ); + } + } public record EnchantmentEntry(NamespaceID namespace, int id, String translationKey, @@ -556,6 +609,14 @@ public final class Registry { //noinspection unchecked return (T) map.get(name); } + + @Override + public String toString() { + AtomicReference string = new AtomicReference<>("{ "); + this.map.forEach((s, object) -> string.set(string.get() + " , " + "\"" + s + "\"" + " : " + "\"" + object.toString() + "\"")); + return string.updateAndGet(s -> s.replaceFirst(" , ","") + "}"); + } + } public interface Properties extends Iterable> {