From b09be32f5c9efb99de67d19b25e473e2d859e765 Mon Sep 17 00:00:00 2001 From: Tides Date: Tue, 14 Nov 2023 11:51:22 -0500 Subject: [PATCH] Add armor trims to registry --- .../Codecs/ArmorTrims/TrimDescription.cs | 7 ++ .../TrimMaterial/TrimMaterialCodec.cs | 9 ++ .../TrimMaterial/TrimMaterialElement.cs | 13 +++ .../TrimPattern/TrimPatternCodec.cs | 9 ++ .../TrimPattern/TrimPatternElement.cs | 11 +++ .../Registry/Models/Assets.cs | 4 +- .../Registry/NameHelper.cs | 4 +- .../RegistryAssetsGenerator.ArmorTrims.cs | 96 +++++++++++++++++++ .../RegistryAssetsGenerator.Codecs.cs | 5 + .../Registry/RegistryAssetsGenerator.cs | 56 +++++++++-- 10 files changed, 204 insertions(+), 10 deletions(-) create mode 100644 Obsidian.API/Registry/Codecs/ArmorTrims/TrimDescription.cs create mode 100644 Obsidian.API/Registry/Codecs/ArmorTrims/TrimMaterial/TrimMaterialCodec.cs create mode 100644 Obsidian.API/Registry/Codecs/ArmorTrims/TrimMaterial/TrimMaterialElement.cs create mode 100644 Obsidian.API/Registry/Codecs/ArmorTrims/TrimPattern/TrimPatternCodec.cs create mode 100644 Obsidian.API/Registry/Codecs/ArmorTrims/TrimPattern/TrimPatternElement.cs create mode 100644 Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.ArmorTrims.cs diff --git a/Obsidian.API/Registry/Codecs/ArmorTrims/TrimDescription.cs b/Obsidian.API/Registry/Codecs/ArmorTrims/TrimDescription.cs new file mode 100644 index 000000000..384dfec6d --- /dev/null +++ b/Obsidian.API/Registry/Codecs/ArmorTrims/TrimDescription.cs @@ -0,0 +1,7 @@ +namespace Obsidian.API.Registry.Codecs.ArmorTrims; +public sealed class TrimDescription +{ + public required string Translate { get; init; } + + public string? Color { get; init; } +} diff --git a/Obsidian.API/Registry/Codecs/ArmorTrims/TrimMaterial/TrimMaterialCodec.cs b/Obsidian.API/Registry/Codecs/ArmorTrims/TrimMaterial/TrimMaterialCodec.cs new file mode 100644 index 000000000..54b72f51f --- /dev/null +++ b/Obsidian.API/Registry/Codecs/ArmorTrims/TrimMaterial/TrimMaterialCodec.cs @@ -0,0 +1,9 @@ +namespace Obsidian.API.Registry.Codecs.ArmorTrims.TrimMaterial; +public sealed class TrimMaterialCodec : ICodec +{ + public required string Name { get; init; } + + public required int Id { get; init; } + + public required TrimMaterialElement Element { get; init; } +} diff --git a/Obsidian.API/Registry/Codecs/ArmorTrims/TrimMaterial/TrimMaterialElement.cs b/Obsidian.API/Registry/Codecs/ArmorTrims/TrimMaterial/TrimMaterialElement.cs new file mode 100644 index 000000000..878dbd331 --- /dev/null +++ b/Obsidian.API/Registry/Codecs/ArmorTrims/TrimMaterial/TrimMaterialElement.cs @@ -0,0 +1,13 @@ +namespace Obsidian.API.Registry.Codecs.ArmorTrims.TrimMaterial; +public sealed class TrimMaterialElement +{ + public required string Ingredient { get; init; } + + public required string AssetName { get; init; } + + public required double ItemModelIndex { get; init; } + + public required TrimDescription Description { get; init; } + + public Dictionary? OverrideArmorMaterials { get; init; } +} diff --git a/Obsidian.API/Registry/Codecs/ArmorTrims/TrimPattern/TrimPatternCodec.cs b/Obsidian.API/Registry/Codecs/ArmorTrims/TrimPattern/TrimPatternCodec.cs new file mode 100644 index 000000000..61d8cf6a4 --- /dev/null +++ b/Obsidian.API/Registry/Codecs/ArmorTrims/TrimPattern/TrimPatternCodec.cs @@ -0,0 +1,9 @@ +namespace Obsidian.API.Registry.Codecs.ArmorTrims.TrimPattern; +public sealed class TrimPatternCodec : ICodec +{ + public required string Name { get; init; } + + public required int Id { get; init; } + + public required TrimPatternElement Element { get; init; } +} diff --git a/Obsidian.API/Registry/Codecs/ArmorTrims/TrimPattern/TrimPatternElement.cs b/Obsidian.API/Registry/Codecs/ArmorTrims/TrimPattern/TrimPatternElement.cs new file mode 100644 index 000000000..5fceb88de --- /dev/null +++ b/Obsidian.API/Registry/Codecs/ArmorTrims/TrimPattern/TrimPatternElement.cs @@ -0,0 +1,11 @@ +namespace Obsidian.API.Registry.Codecs.ArmorTrims.TrimPattern; +public sealed class TrimPatternElement +{ + public required string TemplateItem { get; init; } + + public required TrimDescription Description { get; init; } + + public required string AssetId { get; init; } + + public required bool Decal { get; init; } +} diff --git a/Obsidian.SourceGenerators/Registry/Models/Assets.cs b/Obsidian.SourceGenerators/Registry/Models/Assets.cs index 28ccd39dd..49df728c1 100644 --- a/Obsidian.SourceGenerators/Registry/Models/Assets.cs +++ b/Obsidian.SourceGenerators/Registry/Models/Assets.cs @@ -36,7 +36,9 @@ public static Dictionary GetCodecs(ImmutableArray<(string name, { "dimensions", ParseCodec(files.GetJsonFromArray("dimensions")) }, { "biomes", ParseCodec(files.GetJsonFromArray("biomes")) }, { "chat_type", ParseCodec(files.GetJsonFromArray("chat_type")) }, - { "damage_type", ParseCodec(files.GetJsonFromArray("damage_type")) } + { "damage_type", ParseCodec(files.GetJsonFromArray("damage_type")) }, + { "trim_pattern", ParseCodec(files.GetJsonFromArray("trim_pattern")) }, + { "trim_material", ParseCodec(files.GetJsonFromArray("trim_material")) } }; } diff --git a/Obsidian.SourceGenerators/Registry/NameHelper.cs b/Obsidian.SourceGenerators/Registry/NameHelper.cs index 9bd931326..b74e04f47 100644 --- a/Obsidian.SourceGenerators/Registry/NameHelper.cs +++ b/Obsidian.SourceGenerators/Registry/NameHelper.cs @@ -1,4 +1,6 @@ -namespace Obsidian.SourceGenerators.Registry; +using System.Text.Json; + +namespace Obsidian.SourceGenerators.Registry; internal static class NameHelper { diff --git a/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.ArmorTrims.cs b/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.ArmorTrims.cs new file mode 100644 index 000000000..34afe91d5 --- /dev/null +++ b/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.ArmorTrims.cs @@ -0,0 +1,96 @@ +using Obsidian.SourceGenerators.Registry.Models; +using System.Text.Json; + +namespace Obsidian.SourceGenerators.Registry; +public partial class RegistryAssetsGenerator +{ + private static void GenerateTrimMaterial(Codec[] trimMaterials, CodeBuilder builder, SourceProductionContext ctx) + { + builder.Type($"public static class TrimMaterials"); + + builder.Indent().Append("public const string CodecKey = \"minecraft:trim_material\";").Line().Line(); + builder.Indent().Append($"public const int GlobalBitsPerEntry = {(int)Math.Ceiling(Math.Log(trimMaterials.Length, 2))};").Line().Line(); + + foreach (var trimMaterial in trimMaterials) + { + var propertyName = trimMaterial.Name.RemoveNamespace().ToPascalCase(); + + builder.Indent().Append($"public static TrimMaterialCodec {propertyName} {{ get; }} = new() {{ Id = {trimMaterial.RegistryId}, Name = \"{trimMaterial.Name}\", Element = new() {{ "); + + foreach (var property in trimMaterial.Properties) + { + var name = property.Key; + var value = property.Value; + + builder.Append($"{name} = "); + + if (value.ValueKind == JsonValueKind.Object) + { + ParseProperty(builder, value, ctx, name == "OverrideArmorMaterials"); + continue; + } + + AppendValueType(builder, value, ctx, name == "OverrideArmorMaterials"); + } + + builder.Append("} };").Line(); + } + + builder.Line().Statement("public static IReadOnlyDictionary All { get; } = new Dictionary"); + + foreach (var name in trimMaterials.Select(x => x.Name)) + { + var propertyName = name.RemoveNamespace().ToPascalCase(); + builder.Line($"{{ \"{name}\", {propertyName} }},"); + } + + builder.EndScope(".AsReadOnly()", true).Line(); + + builder.EndScope(); + } + + private static void GenerateTrimPattern(Codec[] trimPatterns, CodeBuilder builder, SourceProductionContext ctx) + { + builder.Type($"public static class TrimPatterns"); + + builder.Indent().Append("public const string CodecKey = \"minecraft:trim_pattern\";").Line().Line(); + builder.Indent().Append($"public const int GlobalBitsPerEntry = {(int)Math.Ceiling(Math.Log(trimPatterns.Length, 2))};").Line().Line(); + + foreach (var trimPattern in trimPatterns) + { + var propertyName = trimPattern.Name.RemoveNamespace().ToPascalCase(); + + builder.Indent().Append($"public static TrimPatternCodec {propertyName} {{ get; }} = new() {{ Id = {trimPattern.RegistryId}, Name = \"{trimPattern.Name}\", Element = new() {{ "); + + foreach (var property in trimPattern.Properties) + { + var name = property.Key; + var value = property.Value; + + builder.Append($"{name} = "); + + if (value.ValueKind == JsonValueKind.Object) + { + ParseProperty(builder, value, ctx); + continue; + } + + AppendValueType(builder, value, ctx); + } + + builder.Append("} };").Line(); + } + + builder.Line().Statement("public static IReadOnlyDictionary All { get; } = new Dictionary"); + + foreach (var name in trimPatterns.Select(x => x.Name)) + { + var propertyName = name.RemoveNamespace().ToPascalCase(); + builder.Line($"{{ \"{name}\", {propertyName} }},"); + } + + builder.EndScope(".AsReadOnly()", true).Line(); + + builder.EndScope(); + } +} diff --git a/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.Codecs.cs b/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.Codecs.cs index 586a4c1d5..b76b2811d 100644 --- a/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.Codecs.cs +++ b/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.Codecs.cs @@ -11,6 +11,9 @@ private static void GenerateCodecs(Assets assets, SourceProductionContext ctx) .Using("Obsidian.API.Registry.Codecs.Chat") .Using("Obsidian.API.Registry.Codecs.Dimensions") .Using("Obsidian.API.Registry.Codecs.DamageTypes") + .Using("Obsidian.API.Registry.Codecs.ArmorTrims") + .Using("Obsidian.API.Registry.Codecs.ArmorTrims.TrimPattern") + .Using("Obsidian.API.Registry.Codecs.ArmorTrims.TrimMaterial") .Line() .Namespace("Obsidian.Registries") .Line() @@ -22,6 +25,8 @@ private static void GenerateCodecs(Assets assets, SourceProductionContext ctx) GenerateBiomes(codecs["biomes"].ToArray(), builder, ctx); GenerateChatType(codecs["chat_type"].ToArray(), builder, ctx); GenerateDamageTypes(codecs["damage_type"].ToArray(), builder, ctx); + GenerateTrimMaterial(codecs["trim_material"].ToArray(), builder, ctx); + GenerateTrimPattern(codecs["trim_pattern"].ToArray(), builder, ctx); builder.EndScope(); diff --git a/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.cs b/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.cs index 79f57b3e5..91159b755 100644 --- a/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.cs +++ b/Obsidian.SourceGenerators/Registry/RegistryAssetsGenerator.cs @@ -41,7 +41,7 @@ private void Generate(SourceProductionContext context, (Compilation compilation, } } - private static void ParseProperty(CodeBuilder builder, JsonElement element, SourceProductionContext ctx) + private static void ParseProperty(CodeBuilder builder, JsonElement element, SourceProductionContext ctx, bool isDictionary = false) { builder.Append("new() { "); @@ -53,11 +53,11 @@ private static void ParseProperty(CodeBuilder builder, JsonElement element, Sour { if (value.ValueKind is JsonValueKind.Object or JsonValueKind.Array) { - ParseProperty(builder, value, ctx); + ParseProperty(builder, value, ctx, isDictionary); continue; } - AppendValueType(builder, value, ctx); + AppendValueType(builder, value, ctx, isDictionary); } } else @@ -68,25 +68,65 @@ private static void ParseProperty(CodeBuilder builder, JsonElement element, Sour if (!isArray) { - var name = property.Name.ToPascalCase(); - builder.Append($"{name} = "); + if (isDictionary) + { + builder.Append($"{{ \"{property.Name}\", "); + } + else + { + var name = property.Name.ToPascalCase(); + builder.Append($"{name} = "); + } } if (value.ValueKind is JsonValueKind.Object or JsonValueKind.Array) { - ParseProperty(builder, value, ctx); + ParseProperty(builder, value, ctx, isDictionary); continue; } - AppendValueType(builder, value, ctx); + AppendValueType(builder, value, ctx, isDictionary); } } builder.Append("}, "); } - private static void AppendValueType(CodeBuilder builder, JsonElement element, SourceProductionContext ctx) + private static void AppendValueType(CodeBuilder builder, JsonElement element, SourceProductionContext ctx, bool isDictionary = false) { + if (isDictionary) + { + switch (element.ValueKind) + { + case JsonValueKind.String: + builder.Append($"\"{element.GetString()}\" }},"); + break; + case JsonValueKind.Number: + { + if (element.TryGetInt32(out var intValue)) + builder.Append($"{intValue} }},"); + else if (element.TryGetInt64(out var longValue)) + builder.Append($"{longValue} }},"); + else if (element.TryGetSingle(out var floatValue)) + builder.Append($"{floatValue}f }},"); + else if (element.TryGetDouble(out var doubleValue)) + builder.Append($"{doubleValue}d }},"); + break; + } + case JsonValueKind.True: + case JsonValueKind.False: + builder.Append($"{element.GetBoolean().ToString().ToLower()} }},"); + break; + case JsonValueKind.Null: + break; + default: + ctx.ReportDiagnostic(DiagnosticSeverity.Error, $"Found an invalid property type: {element.ValueKind} in json."); + break; + } + + return; + } + switch (element.ValueKind) { case JsonValueKind.String: