diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/MachineRecipeSchema.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/MachineRecipeSchema.java index 5d39f3447..e5203ecf2 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/MachineRecipeSchema.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/MachineRecipeSchema.java @@ -59,9 +59,6 @@ import net.neoforged.neoforge.common.crafting.SizedIngredient; public final class MachineRecipeSchema { - private static final RecipeComponent POSITIVE_INTEGER = NumberComponent.intRange(1, Integer.MAX_VALUE); - private static final RecipeComponent PROBABILITY = NumberComponent.floatRange(0, 1); - private static final RecipeComponent ITEM_INPUT = new RecipeComponent<>() { @Override public Codec codec() { @@ -172,9 +169,10 @@ public void buildUniqueId(UniqueIdBuilder builder, MachineRecipe.ItemOutput valu private static final RecipeKey EU = NumberComponent.intRange(1, Integer.MAX_VALUE).key("eu", ComponentRole.OTHER); private static final RecipeKey DURATION = NumberComponent.intRange(1, Integer.MAX_VALUE).key("duration", ComponentRole.OTHER); - private static final RecipeKey> ITEM_INPUTS = maybeList(ITEM_INPUT).key("item_inputs", ComponentRole.INPUT); - private static final RecipeKey> ITEM_OUTPUTS = maybeList(ITEM_OUTPUT).key("item_outputs", - ComponentRole.OUTPUT); + private static final RecipeKey> ITEM_INPUTS = maybeList(ITEM_INPUT) + .key("item_inputs", ComponentRole.INPUT); + private static final RecipeKey> ITEM_OUTPUTS = maybeList(ITEM_OUTPUT) + .key("item_outputs", ComponentRole.OUTPUT); private static ListRecipeComponent maybeList(RecipeComponent component) { // Don't use component.asListOrSelf() because we want to support conditions in list elements! @@ -204,15 +202,20 @@ private MachineRecipeSchema() { } public static class MachineRecipeJS extends KubeRecipe implements ProcessConditionHelper { + private void addToList(RecipeKey> key, T element) { + // In 1.21, this can be null when the recipe is constructed via a JS constructor apparently. + var value = getValue(key); + var list = value == null ? new ArrayList() : new ArrayList<>(value); + list.add(element); + setValue(key, list); + } public MachineRecipeJS itemIn(SizedIngredient ingredient) { return itemIn(ingredient, 1); } public MachineRecipeJS itemIn(SizedIngredient ingredient, float chance) { - var newList = new ArrayList<>(getValue(ITEM_INPUTS)); - newList.add(new MachineRecipe.ItemInput(ingredient.ingredient(), ingredient.count(), chance)); - setValue(ITEM_INPUTS, newList); + addToList(ITEM_INPUTS, new MachineRecipe.ItemInput(ingredient.ingredient(), ingredient.count(), chance)); return this; } @@ -221,9 +224,7 @@ public MachineRecipeJS itemOut(ItemStack output) { } public MachineRecipeJS itemOut(ItemStack output, float chance) { - var newList = new ArrayList<>(getValue(ITEM_OUTPUTS)); - newList.add(new MachineRecipe.ItemOutput(ItemVariant.of(output), output.getCount(), chance)); - setValue(ITEM_OUTPUTS, newList); + addToList(ITEM_OUTPUTS, new MachineRecipe.ItemOutput(ItemVariant.of(output), output.getCount(), chance)); return this; } diff --git a/src/main/java/aztech/modern_industrialization/machines/recipe/MachineRecipe.java b/src/main/java/aztech/modern_industrialization/machines/recipe/MachineRecipe.java index 0b360d9f5..08fbb01b1 100644 --- a/src/main/java/aztech/modern_industrialization/machines/recipe/MachineRecipe.java +++ b/src/main/java/aztech/modern_industrialization/machines/recipe/MachineRecipe.java @@ -67,7 +67,7 @@ public static MapCodec codec(MachineRecipeType type) { MIExtraCodecs.maybeList(FluidInput.CODEC, "fluid_inputs").forGetter(recipe -> recipe.fluidInputs), MIExtraCodecs.maybeList(ItemOutput.CODEC, "item_outputs").forGetter(recipe -> recipe.itemOutputs), MIExtraCodecs.maybeList(FluidOutput.CODEC, "fluid_outputs").forGetter(recipe -> recipe.fluidOutputs), - MIExtraCodecs.maybeList(MachineProcessCondition.CODEC, "conditions").forGetter(recipe -> recipe.conditions)) + MIExtraCodecs.maybeList(MachineProcessCondition.CODEC, "process_conditions").forGetter(recipe -> recipe.conditions)) .apply(g, (eu, duration, itemInputs, fluidInputs, itemOutputs, fluidOutputs, conditions) -> { var ret = new MachineRecipe(type); ret.eu = eu; diff --git a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/AdjacentBlockProcessCondition.java b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/AdjacentBlockProcessCondition.java index 86e2212b5..5b5780bd1 100644 --- a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/AdjacentBlockProcessCondition.java +++ b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/AdjacentBlockProcessCondition.java @@ -30,7 +30,11 @@ import java.util.List; import java.util.Locale; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.util.StringRepresentable; import net.minecraft.world.level.block.Block; @@ -40,6 +44,12 @@ public record AdjacentBlockProcessCondition(Block block, RelativePosition relati BuiltInRegistries.BLOCK.byNameCodec().fieldOf("block").forGetter(c -> c.block), StringRepresentable.fromEnum(RelativePosition::values).fieldOf("position").forGetter(c -> c.relativePosition)) .apply(g, AdjacentBlockProcessCondition::new)); + static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.registry(Registries.BLOCK), + AdjacentBlockProcessCondition::block, + ByteBufCodecs.fromCodec(StringRepresentable.fromEnum(RelativePosition::values)), + AdjacentBlockProcessCondition::relativePosition, + AdjacentBlockProcessCondition::new); public AdjacentBlockProcessCondition(Block block, String relativePosition) { this(block, RelativePosition.valueOf(relativePosition.toUpperCase(Locale.ROOT))); @@ -67,9 +77,14 @@ public void appendDescription(List list) { } @Override - public MapCodec codec(boolean syncToClient) { + public MapCodec codec() { return CODEC; } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } } enum RelativePosition implements StringRepresentable { diff --git a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/BiomeProcessCondition.java b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/BiomeProcessCondition.java index 5109aade7..515b3f44d 100644 --- a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/BiomeProcessCondition.java +++ b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/BiomeProcessCondition.java @@ -28,7 +28,9 @@ import com.mojang.serialization.MapCodec; import java.util.List; import net.minecraft.core.registries.Registries; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.biome.Biome; @@ -36,6 +38,10 @@ public record BiomeProcessCondition(ResourceKey biome) implements Machine static final MapCodec CODEC = ResourceKey.codec(Registries.BIOME) .fieldOf("biome") .xmap(BiomeProcessCondition::new, BiomeProcessCondition::biome); + static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ResourceKey.streamCodec(Registries.BIOME), + BiomeProcessCondition::biome, + BiomeProcessCondition::new); @Override public boolean canProcessRecipe(Context context, MachineRecipe recipe) { @@ -51,7 +57,12 @@ public void appendDescription(List list) { } @Override - public MapCodec codec(boolean syncToClient) { + public MapCodec codec() { return CODEC; } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } } diff --git a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/CustomProcessCondition.java b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/CustomProcessCondition.java index 2522abae2..579e9182c 100644 --- a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/CustomProcessCondition.java +++ b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/CustomProcessCondition.java @@ -34,8 +34,11 @@ import java.util.Objects; import java.util.Optional; import java.util.function.BiPredicate; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; public class CustomProcessCondition implements MachineProcessCondition { static final Map definitions = new HashMap<>(); @@ -75,8 +78,13 @@ private static MapCodec makeCodec(boolean syncToClient) .apply(g, (id, desc) -> desc.map(d -> new CustomProcessCondition(id, d)).orElseGet(() -> new CustomProcessCondition(id)))); } - static final MapCodec CODEC = makeCodec(false); - private static final MapCodec CODEC_FOR_SYNC = makeCodec(true); + static final MapCodec CODEC = Codec.STRING.fieldOf("custom_id").xmap(CustomProcessCondition::new, c -> c.id); + static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.STRING_UTF8, + c -> c.id, + ComponentSerialization.TRUSTED_STREAM_CODEC.apply(ByteBufCodecs.list()), + c -> c.description, + CustomProcessCondition::new); public CustomProcessCondition(String id) { var definition = definitions.get(id); @@ -106,7 +114,12 @@ public void appendDescription(List list) { } @Override - public MapCodec codec(boolean syncToClient) { - return syncToClient ? CODEC_FOR_SYNC : CODEC; + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; } } diff --git a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/DimensionProcessCondition.java b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/DimensionProcessCondition.java index 5ac5a0045..751547510 100644 --- a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/DimensionProcessCondition.java +++ b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/DimensionProcessCondition.java @@ -28,7 +28,9 @@ import com.mojang.serialization.MapCodec; import java.util.List; import net.minecraft.core.registries.Registries; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.Level; @@ -37,6 +39,11 @@ public record DimensionProcessCondition(ResourceKey dimension) implements .fieldOf("dimension") .xmap(DimensionProcessCondition::new, DimensionProcessCondition::dimension); + static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ResourceKey.streamCodec(Registries.DIMENSION), + DimensionProcessCondition::dimension, + DimensionProcessCondition::new); + @Override public boolean canProcessRecipe(Context context, MachineRecipe recipe) { return context.getLevel().dimension() == dimension; @@ -50,7 +57,12 @@ public void appendDescription(List list) { } @Override - public MapCodec codec(boolean syncToClient) { + public MapCodec codec() { return CODEC; } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } } diff --git a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/MachineProcessCondition.java b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/MachineProcessCondition.java index 544f5042e..dedb41be0 100644 --- a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/MachineProcessCondition.java +++ b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/MachineProcessCondition.java @@ -28,36 +28,41 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.MapCodec; -import io.netty.buffer.ByteBuf; import java.util.List; import java.util.Optional; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; public interface MachineProcessCondition { - private static Codec makeCodec(boolean syncToClient) { - return ResourceLocation.CODEC - .>flatXmap( - resLoc -> Optional.ofNullable(MachineProcessConditions.get(resLoc)) - .map(DataResult::success) - .orElseGet(() -> DataResult.error(() -> "Unknown machine process condition " + resLoc)), - codec -> Optional.ofNullable(MachineProcessConditions.getId(codec)) - .map(DataResult::success) - .orElseGet(() -> DataResult.error(() -> "Unknown machine process condition codec " + codec))) - .dispatch(cond -> cond.codec(syncToClient), c -> c); - } - - Codec CODEC = makeCodec(false); - StreamCodec STREAM_CODEC = ByteBufCodecs.fromCodec(makeCodec(true)); + Codec CODEC = ResourceLocation.CODEC + .>flatXmap( + resLoc -> Optional.ofNullable(MachineProcessConditions.getCodec(resLoc)) + .map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> "Unknown machine process condition " + resLoc)), + codec -> Optional.ofNullable(MachineProcessConditions.getId(codec)) + .map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> "Unknown machine process condition codec " + codec))) + .dispatch(MachineProcessCondition::codec, c -> c); + @SuppressWarnings({ "unchecked", "rawtypes" }) + StreamCodec STREAM_CODEC = ResourceLocation.STREAM_CODEC + .mapStream(b -> b) + .map( + resLoc -> Optional.ofNullable(MachineProcessConditions.getStreamCodec(resLoc)) + .orElseThrow(() -> new IllegalArgumentException("Unknown machine process condition " + resLoc)), + streamCodec -> Optional.ofNullable(MachineProcessConditions.getId(streamCodec)) + .orElseThrow(() -> new IllegalArgumentException("Unknown machine process condition codec " + streamCodec))) + .dispatch(r -> (StreamCodec) r.streamCodec(), c -> c); boolean canProcessRecipe(Context context, MachineRecipe recipe); void appendDescription(List list); - MapCodec codec(boolean syncToClient); + MapCodec codec(); + + StreamCodec streamCodec(); interface Context { MachineBlockEntity getBlockEntity(); diff --git a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/MachineProcessConditions.java b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/MachineProcessConditions.java index e25b8d94c..3c3257842 100644 --- a/src/main/java/aztech/modern_industrialization/machines/recipe/condition/MachineProcessConditions.java +++ b/src/main/java/aztech/modern_industrialization/machines/recipe/condition/MachineProcessConditions.java @@ -27,33 +27,50 @@ import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.mojang.serialization.MapCodec; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.Nullable; public final class MachineProcessConditions { private static final BiMap> MAP = HashBiMap.create(); + private static final BiMap> STREAM_MAP = HashBiMap + .create(); - public static void register(ResourceLocation id, MapCodec serializer) { - if (MAP.get(id) != null || MAP.inverse().get(serializer) != null) { + public static void register( + ResourceLocation id, + MapCodec codec, + StreamCodec streamCodec) { + if (MAP.get(id) != null || MAP.inverse().get(codec) != null || STREAM_MAP.inverse().get(streamCodec) != null) { throw new IllegalArgumentException("Duplicate registration for process condition " + id); } - MAP.put(id, serializer); + MAP.put(id, codec); + STREAM_MAP.put(id, streamCodec); } @Nullable - public static MapCodec get(ResourceLocation id) { + public static MapCodec getCodec(ResourceLocation id) { return MAP.get(id); } - public static ResourceLocation getId(MapCodec serializer) { - return MAP.inverse().get(serializer); + @Nullable + public static StreamCodec getStreamCodec(ResourceLocation id) { + return STREAM_MAP.get(id); + } + + public static ResourceLocation getId(MapCodec codec) { + return MAP.inverse().get(codec); + } + + public static ResourceLocation getId(StreamCodec streamCodec) { + return STREAM_MAP.inverse().get(streamCodec); } static { - register(MI.id("dimension"), DimensionProcessCondition.CODEC); - register(MI.id("adjacent_block"), AdjacentBlockProcessCondition.CODEC); - register(MI.id("biome"), BiomeProcessCondition.CODEC); - register(MI.id("custom"), CustomProcessCondition.CODEC); + register(MI.id("dimension"), DimensionProcessCondition.CODEC, DimensionProcessCondition.STREAM_CODEC); + register(MI.id("adjacent_block"), AdjacentBlockProcessCondition.CODEC, AdjacentBlockProcessCondition.STREAM_CODEC); + register(MI.id("biome"), BiomeProcessCondition.CODEC, BiomeProcessCondition.STREAM_CODEC); + register(MI.id("custom"), CustomProcessCondition.CODEC, CustomProcessCondition.STREAM_CODEC); } }