package ar.com.companeros.flags; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import java.util.Locale; import java.util.Set; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.resources.ResourceKey; import net.minecraft.world.item.DyeColor; import net.minecraft.world.level.block.entity.BannerPattern; import net.minecraft.world.level.block.entity.BannerPatterns; /** Diseño acotado: un círculo y, opcionalmente, un patrón geométrico vanilla. */ public record BannerDesign(DyeColor baseColor, DyeColor circleColor, Symbol symbol, DyeColor symbolColor) { private static final Set FIELDS = Set.of("baseColor", "circleColor", "symbol", "symbolColor"); // Cada símbolo usa un único tinte y nunca necesita plantillas especiales. public enum Symbol { NONE(null), STRIPE_CENTER(BannerPatterns.STRIPE_CENTER), STRIPE_MIDDLE(BannerPatterns.STRIPE_MIDDLE), STRIPE_DOWNRIGHT(BannerPatterns.STRIPE_DOWNRIGHT), STRIPE_DOWNLEFT(BannerPatterns.STRIPE_DOWNLEFT), CROSS(BannerPatterns.CROSS), STRAIGHT_CROSS(BannerPatterns.STRAIGHT_CROSS), TRIANGLE_BOTTOM(BannerPatterns.TRIANGLE_BOTTOM), TRIANGLE_TOP(BannerPatterns.TRIANGLE_TOP), RHOMBUS_MIDDLE(BannerPatterns.RHOMBUS_MIDDLE), BORDER(BannerPatterns.BORDER); final ResourceKey pattern; Symbol(ResourceKey pattern) { this.pattern = pattern; } public String inputName() { return name().toLowerCase(Locale.ROOT); } } public BannerDesign { if (baseColor == null || circleColor == null || symbol == null || symbol != Symbol.NONE && symbolColor == null) throw new IllegalArgumentException("Diseño incompleto"); if (symbol == Symbol.NONE) symbolColor = null; } // No se aceptan NBT, comandos ni campos adicionales provenientes del agente. public static BannerDesign parse(JsonObject input) { if (input == null || !FIELDS.containsAll(input.keySet())) throw new IllegalArgumentException("Campos de diseño inválidos"); DyeColor base = color(text(input, "baseColor")); DyeColor circle = color(text(input, "circleColor")); Symbol symbol = input.has("symbol") ? Symbol.valueOf(text(input, "symbol").toUpperCase(Locale.ROOT)) : Symbol.NONE; DyeColor ink = input.has("symbolColor") ? color(text(input, "symbolColor")) : null; return new BannerDesign(base, circle, symbol, ink); } public static BannerDesign fromTag(CompoundTag tag) { if (!FIELDS.containsAll(tag.getAllKeys())) throw new IllegalArgumentException("Campos guardados de diseño inválidos"); JsonObject input = new JsonObject(); for (String key : FIELDS) if (tag.contains(key, 8)) input.addProperty(key, tag.getString(key)); return parse(input); } public CompoundTag toTag() { CompoundTag tag = new CompoundTag(); tag.putString("baseColor", baseColor.getName()); tag.putString("circleColor", circleColor.getName()); tag.putString("symbol", symbol.inputName()); if (symbolColor != null) tag.putString("symbolColor", symbolColor.getName()); return tag; } public ListTag patterns() { var builder = new BannerPattern.Builder().addPattern(BannerPatterns.CIRCLE_MIDDLE, circleColor); if (symbol != Symbol.NONE) builder.addPattern(symbol.pattern, symbolColor); return builder.toListTag(); } private static String text(JsonObject input, String key) { JsonElement value = input.get(key); if (value == null || !value.isJsonPrimitive() || !value.getAsJsonPrimitive().isString()) throw new IllegalArgumentException("Se necesita un nombre para " + key); return value.getAsString(); } private static DyeColor color(String name) { DyeColor color = DyeColor.byName(name, null); if (color == null) throw new IllegalArgumentException("Color desconocido"); return color; } }