diff --git a/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserItemMapper.java b/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserItemMapper.java index 5f4d2cf..eb47968 100644 --- a/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserItemMapper.java +++ b/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserItemMapper.java @@ -38,14 +38,14 @@ import java.util.stream.Stream; public class GeyserItemMapper { - public static Stream mapItem(ResourceLocation modelLocation, String displayName, int protectionValue, DataComponentPatch componentPatch, - ProblemReporter reporter) { + public static Stream mapItem(ResourceLocation modelLocation, String displayName, int protectionValue, DataComponentPatch componentPatch, + ProblemReporter reporter) { ItemModel model = Minecraft.getInstance().getModelManager().getItemModel(modelLocation); MappingContext context = new MappingContext(List.of(), modelLocation, displayName, protectionValue, componentPatch, reporter.forChild(() -> "model " + modelLocation + " ")); return mapItem(model, context); } - private static Stream mapItem(ItemModel model, MappingContext context) { + private static Stream mapItem(ItemModel model, MappingContext context) { switch (model) { case BlockModelWrapper modelWrapper -> { ResourceLocation itemModel = ((BlockModelWrapperLocationAccessor) modelWrapper).geyser_mappings_generator$getModelOrigin(); @@ -66,7 +66,7 @@ public class GeyserItemMapper { return Stream.empty(); } - private static Stream mapConditionalModel(ConditionalItemModel model, MappingContext context) { + private static Stream mapConditionalModel(ConditionalItemModel model, MappingContext context) { ItemModelPropertyTest property = ((ConditionalItemModelAccessor) model).getProperty(); GeyserConditionPredicate.Property predicateProperty = switch (property) { case Broken ignored -> GeyserConditionPredicate.BROKEN; @@ -90,7 +90,7 @@ public class GeyserItemMapper { ); } - private static Stream mapSelectModel(SelectItemModel model, MappingContext context) { + private static Stream mapSelectModel(SelectItemModel model, MappingContext context) { //noinspection unchecked SelectItemModelProperty property = ((SelectItemModelAccessor) model).getProperty(); Function dataConstructor = switch (property) { @@ -127,9 +127,9 @@ public class GeyserItemMapper { return new MappingContext(predicateStack, model, displayName, protectionValue, componentPatch, reporter.forChild(() -> childName)); } - public GeyserMapping create(ResourceLocation bedrockIdentifier) { - return new GeyserMapping(model, bedrockIdentifier, Optional.of(displayName), predicateStack, - new GeyserMapping.BedrockOptions(Optional.empty(), true, false, protectionValue), // TODO handheld prediction + public GeyserMapping_ create(ResourceLocation bedrockIdentifier) { + return new GeyserMapping_(model, bedrockIdentifier, Optional.of(displayName), predicateStack, + new GeyserMapping_.BedrockOptions(Optional.empty(), true, false, protectionValue), // TODO handheld prediction componentPatch); } } diff --git a/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMappingNew.java b/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMappingNew.java new file mode 100644 index 0000000..6929eda --- /dev/null +++ b/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMappingNew.java @@ -0,0 +1,37 @@ +package org.geysermc.packgenerator.mapping.geyser; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import net.minecraft.util.StringRepresentable; +import org.jetbrains.annotations.NotNull; + +public interface GeyserMappingNew { + + Codec CODEC = Type.CODEC.dispatch(GeyserMappingNew::type, Type::codec); + + Type type(); + + enum Type implements StringRepresentable { + SINGLE("definition", GeyserMapping_.CODEC), + GROUP("group", GroupDefinition.CODEC); + + public static final Codec CODEC = StringRepresentable.fromEnum(Type::values); + + private final String name; + private final MapCodec codec; + + Type(String name, MapCodec codec) { + this.name = name; + this.codec = codec; + } + + public MapCodec codec() { + return codec; + } + + @Override + public @NotNull String getSerializedName() { + return name; + } + } +} diff --git a/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMapping.java b/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMapping_.java similarity index 79% rename from src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMapping.java rename to src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMapping_.java index 189e9b9..5d98625 100644 --- a/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMapping.java +++ b/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMapping_.java @@ -1,6 +1,7 @@ package org.geysermc.packgenerator.mapping.geyser; import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.component.DataComponentType; @@ -13,8 +14,9 @@ import java.util.Optional; import java.util.function.Function; // TODO other keys, etc. -public record GeyserMapping(ResourceLocation model, ResourceLocation bedrockIdentifier, Optional displayName, - List predicates, BedrockOptions bedrockOptions, DataComponentPatch components) { +// TODO sometimes still includes components key when patch before filtering is not empty but after is +public record GeyserMapping_(ResourceLocation model, ResourceLocation bedrockIdentifier, Optional displayName, + List predicates, BedrockOptions bedrockOptions, DataComponentPatch components) implements GeyserMappingNew { private static final List> SUPPORTED_COMPONENTS = List.of(DataComponents.CONSUMABLE, DataComponents.EQUIPPABLE, DataComponents.FOOD, DataComponents.MAX_DAMAGE, DataComponents.MAX_STACK_SIZE, DataComponents.USE_COOLDOWN, DataComponents.ENCHANTABLE, DataComponents.ENCHANTMENT_GLINT_OVERRIDE); @@ -32,28 +34,22 @@ public record GeyserMapping(ResourceLocation model, ResourceLocation bedrockIden return filtered.build(); }); - public static final Codec CODEC = RecordCodecBuilder.create(instance -> + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Codec.STRING.fieldOf("type").forGetter(mapping -> "definition"), // TODO - ResourceLocation.CODEC.fieldOf("model").forGetter(GeyserMapping::model), - ResourceLocation.CODEC.fieldOf("bedrock_identifier").forGetter(GeyserMapping::bedrockIdentifier), - Codec.STRING.optionalFieldOf("display_name").forGetter(GeyserMapping::displayName), - GeyserPredicate.LIST_CODEC.optionalFieldOf("predicate", List.of()).forGetter(GeyserMapping::predicates), - BedrockOptions.CODEC.optionalFieldOf("bedrock_options", BedrockOptions.DEFAULT).forGetter(GeyserMapping::bedrockOptions), - FILTERED_COMPONENT_MAP_CODEC.optionalFieldOf("components", DataComponentPatch.EMPTY).forGetter(GeyserMapping::components) - ).apply(instance, (type, model, bedrockIdentifier, displayName, predicates, bedrockOptions, components) - -> new GeyserMapping(model, bedrockIdentifier, displayName, predicates, bedrockOptions, components)) + ResourceLocation.CODEC.fieldOf("model").forGetter(GeyserMapping_::model), + ResourceLocation.CODEC.fieldOf("bedrock_identifier").forGetter(GeyserMapping_::bedrockIdentifier), + Codec.STRING.optionalFieldOf("display_name").forGetter(GeyserMapping_::displayName), + GeyserPredicate.LIST_CODEC.optionalFieldOf("predicate", List.of()).forGetter(GeyserMapping_::predicates), + BedrockOptions.CODEC.optionalFieldOf("bedrock_options", BedrockOptions.DEFAULT).forGetter(GeyserMapping_::bedrockOptions), + FILTERED_COMPONENT_MAP_CODEC.optionalFieldOf("components", DataComponentPatch.EMPTY).forGetter(GeyserMapping_::components) + ).apply(instance, GeyserMapping_::new) ); public String textureName() { return bedrockOptions.icon.orElse(iconFromResourceLocation(bedrockIdentifier)); } - public static String iconFromResourceLocation(ResourceLocation location) { - return location.toString().replace(':', '.').replace('/', '_'); - } - - public boolean conflictsWith(GeyserMapping other) { + public boolean conflictsWith(GeyserMapping_ other) { if (!model.equals(other.model)) { return false; } else if (predicates.size() == other.predicates.size()) { @@ -69,6 +65,11 @@ public record GeyserMapping(ResourceLocation model, ResourceLocation bedrockIden return false; } + @Override + public Type type() { + return Type.SINGLE; + } + public record BedrockOptions(Optional icon, boolean allowOffhand, boolean displayHandheld, int protectionValue) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( @@ -80,4 +81,8 @@ public record GeyserMapping(ResourceLocation model, ResourceLocation bedrockIden ); public static final BedrockOptions DEFAULT = new BedrockOptions(Optional.empty(), true, false, 0); } + + public static String iconFromResourceLocation(ResourceLocation location) { + return location.toString().replace(':', '.').replace('/', '_'); + } } diff --git a/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMappings.java b/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMappings.java index 2132f41..20802aa 100644 --- a/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMappings.java +++ b/src/main/java/org/geysermc/packgenerator/mapping/geyser/GeyserMappings.java @@ -21,7 +21,7 @@ import java.util.function.Function; // TODO group definitions public class GeyserMappings { - private static final Codec, Collection>> MAPPINGS_CODEC = Codec.unboundedMap(Item.CODEC, GeyserMapping.CODEC.listOf().xmap(Function.identity(), ArrayList::new)); + private static final Codec, Collection>> MAPPINGS_CODEC = Codec.unboundedMap(Item.CODEC, GeyserMapping_.CODEC.listOf().xmap(Function.identity(), ArrayList::new)); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( @@ -30,18 +30,18 @@ public class GeyserMappings { ).apply(instance, (format, mappings) -> new GeyserMappings(mappings)) ); - private final Multimap, GeyserMapping> mappings = MultimapBuilder.hashKeys().hashSetValues().build(); + private final Multimap, GeyserMapping_> mappings = MultimapBuilder.hashKeys().hashSetValues().build(); public GeyserMappings() {} - private GeyserMappings(Map, Collection> mappings) { + private GeyserMappings(Map, Collection> mappings) { for (Holder item : mappings.keySet()) { this.mappings.putAll(item, mappings.get(item)); } } - public void map(Holder item, GeyserMapping mapping) { - for (GeyserMapping existing : mappings.get(item)) { + public void map(Holder item, GeyserMapping_ mapping) { + for (GeyserMapping_ existing : mappings.get(item)) { if (existing.conflictsWith(mapping)) { throw new IllegalArgumentException("Mapping conflicts with existing mapping"); } @@ -53,7 +53,7 @@ public class GeyserMappings { return mappings.size(); } - public void map(ItemStack stack, ProblemReporter reporter, Consumer mappingConsumer) { + public void map(ItemStack stack, ProblemReporter reporter, Consumer mappingConsumer) { Optional patchedModel = stack.getComponentsPatch().get(DataComponents.ITEM_MODEL); //noinspection OptionalAssignedToNull - annoying Mojang if (patchedModel == null || patchedModel.isEmpty()) { @@ -76,7 +76,7 @@ public class GeyserMappings { }); } - public Map, Collection> mappings() { + public Map, Collection> mappings() { return mappings.asMap(); } } diff --git a/src/main/java/org/geysermc/packgenerator/mapping/geyser/GroupDefinition.java b/src/main/java/org/geysermc/packgenerator/mapping/geyser/GroupDefinition.java new file mode 100644 index 0000000..623eb24 --- /dev/null +++ b/src/main/java/org/geysermc/packgenerator/mapping/geyser/GroupDefinition.java @@ -0,0 +1,23 @@ +package org.geysermc.packgenerator.mapping.geyser; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.resources.ResourceLocation; + +import java.util.List; +import java.util.Optional; + +public record GroupDefinition(Optional model, List definitions) implements GeyserMappingNew { + + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + ResourceLocation.CODEC.optionalFieldOf("model").forGetter(GroupDefinition::model), + GeyserMappingNew.CODEC.listOf().fieldOf("definitions").forGetter(GroupDefinition::definitions) + ).apply(instance, GroupDefinition::new) + ); + + @Override + public Type type() { + return Type.GROUP; + } +} diff --git a/src/main/java/org/geysermc/packgenerator/pack/BedrockTextures.java b/src/main/java/org/geysermc/packgenerator/pack/BedrockTextures.java index 860f81b..dba59ec 100644 --- a/src/main/java/org/geysermc/packgenerator/pack/BedrockTextures.java +++ b/src/main/java/org/geysermc/packgenerator/pack/BedrockTextures.java @@ -2,7 +2,7 @@ package org.geysermc.packgenerator.pack; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; -import org.geysermc.packgenerator.mapping.geyser.GeyserMapping; +import org.geysermc.packgenerator.mapping.geyser.GeyserMapping_; import java.util.HashMap; import java.util.List; @@ -33,7 +33,7 @@ public record BedrockTextures(Map textures) { public static class Builder { private final Map textures = new HashMap<>(); - public Builder withItemTexture(GeyserMapping mapping, String texturePath) { + public Builder withItemTexture(GeyserMapping_ mapping, String texturePath) { return withTexture(mapping.textureName(), TEXTURES_FOLDER + texturePath); } diff --git a/src/main/java/org/geysermc/packgenerator/pack/attachable/BedrockAttachable.java b/src/main/java/org/geysermc/packgenerator/pack/attachable/BedrockAttachable.java index d43ef5f..ec8ca55 100644 --- a/src/main/java/org/geysermc/packgenerator/pack/attachable/BedrockAttachable.java +++ b/src/main/java/org/geysermc/packgenerator/pack/attachable/BedrockAttachable.java @@ -7,7 +7,7 @@ import net.minecraft.util.StringRepresentable; import net.minecraft.world.entity.EquipmentSlot; import org.geysermc.packgenerator.CodecUtil; import org.geysermc.packgenerator.PackConstants; -import org.geysermc.packgenerator.mapping.geyser.GeyserMapping; +import org.geysermc.packgenerator.mapping.geyser.GeyserMapping_; import org.geysermc.packgenerator.pack.BedrockTextures; import org.geysermc.packgenerator.pack.BedrockVersion; import org.jetbrains.annotations.NotNull; @@ -53,7 +53,7 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf public void save(Path attachablesPath) throws IOException { // Get a safe attachable path by using Geyser's way of getting icons - CodecUtil.trySaveJson(CODEC, this, attachablesPath.resolve(GeyserMapping.iconFromResourceLocation(info.identifier) + ".json")); + CodecUtil.trySaveJson(CODEC, this, attachablesPath.resolve(GeyserMapping_.iconFromResourceLocation(info.identifier) + ".json")); } public static class Builder {