Skip to content

Commit

Permalink
Fix machine process conditions (#793)
Browse files Browse the repository at this point in the history
- Change JSON key back to `process_conditions`.
- Fix KubeJS `itemIn` and `itemOut`.
- Rewrite process condition syncing to fix custom conditions.
  • Loading branch information
Technici4n authored Jul 22, 2024
1 parent ffb9bb2 commit b7303f6
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@
import net.neoforged.neoforge.common.crafting.SizedIngredient;

public final class MachineRecipeSchema {
private static final RecipeComponent<Integer> POSITIVE_INTEGER = NumberComponent.intRange(1, Integer.MAX_VALUE);
private static final RecipeComponent<Float> PROBABILITY = NumberComponent.floatRange(0, 1);

private static final RecipeComponent<MachineRecipe.ItemInput> ITEM_INPUT = new RecipeComponent<>() {
@Override
public Codec<MachineRecipe.ItemInput> codec() {
Expand Down Expand Up @@ -172,9 +169,10 @@ public void buildUniqueId(UniqueIdBuilder builder, MachineRecipe.ItemOutput valu

private static final RecipeKey<Integer> EU = NumberComponent.intRange(1, Integer.MAX_VALUE).key("eu", ComponentRole.OTHER);
private static final RecipeKey<Integer> DURATION = NumberComponent.intRange(1, Integer.MAX_VALUE).key("duration", ComponentRole.OTHER);
private static final RecipeKey<List<MachineRecipe.ItemInput>> ITEM_INPUTS = maybeList(ITEM_INPUT).key("item_inputs", ComponentRole.INPUT);
private static final RecipeKey<List<MachineRecipe.ItemOutput>> ITEM_OUTPUTS = maybeList(ITEM_OUTPUT).key("item_outputs",
ComponentRole.OUTPUT);
private static final RecipeKey<List<MachineRecipe.ItemInput>> ITEM_INPUTS = maybeList(ITEM_INPUT)
.key("item_inputs", ComponentRole.INPUT);
private static final RecipeKey<List<MachineRecipe.ItemOutput>> ITEM_OUTPUTS = maybeList(ITEM_OUTPUT)
.key("item_outputs", ComponentRole.OUTPUT);

private static <T> ListRecipeComponent<T> maybeList(RecipeComponent<T> component) {
// Don't use component.asListOrSelf() because we want to support conditions in list elements!
Expand Down Expand Up @@ -204,15 +202,20 @@ private MachineRecipeSchema() {
}

public static class MachineRecipeJS extends KubeRecipe implements ProcessConditionHelper {
private <T> void addToList(RecipeKey<List<T>> 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<T>() : 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;
}

Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public static MapCodec<MachineRecipe> 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<RegistryFriendlyByteBuf, AdjacentBlockProcessCondition> 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)));
Expand Down Expand Up @@ -67,9 +77,14 @@ public void appendDescription(List<Component> list) {
}

@Override
public MapCodec<? extends MachineProcessCondition> codec(boolean syncToClient) {
public MapCodec<? extends MachineProcessCondition> codec() {
return CODEC;
}

@Override
public StreamCodec<? super RegistryFriendlyByteBuf, ? extends MachineProcessCondition> streamCodec() {
return STREAM_CODEC;
}
}

enum RelativePosition implements StringRepresentable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,20 @@
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;

public record BiomeProcessCondition(ResourceKey<Biome> biome) implements MachineProcessCondition {
static final MapCodec<BiomeProcessCondition> CODEC = ResourceKey.codec(Registries.BIOME)
.fieldOf("biome")
.xmap(BiomeProcessCondition::new, BiomeProcessCondition::biome);
static final StreamCodec<RegistryFriendlyByteBuf, BiomeProcessCondition> STREAM_CODEC = StreamCodec.composite(
ResourceKey.streamCodec(Registries.BIOME),
BiomeProcessCondition::biome,
BiomeProcessCondition::new);

@Override
public boolean canProcessRecipe(Context context, MachineRecipe recipe) {
Expand All @@ -51,7 +57,12 @@ public void appendDescription(List<Component> list) {
}

@Override
public MapCodec<? extends MachineProcessCondition> codec(boolean syncToClient) {
public MapCodec<? extends MachineProcessCondition> codec() {
return CODEC;
}

@Override
public StreamCodec<? super RegistryFriendlyByteBuf, ? extends MachineProcessCondition> streamCodec() {
return STREAM_CODEC;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Definition> definitions = new HashMap<>();
Expand Down Expand Up @@ -75,8 +78,13 @@ private static MapCodec<CustomProcessCondition> makeCodec(boolean syncToClient)
.apply(g, (id, desc) -> desc.map(d -> new CustomProcessCondition(id, d)).orElseGet(() -> new CustomProcessCondition(id))));
}

static final MapCodec<CustomProcessCondition> CODEC = makeCodec(false);
private static final MapCodec<CustomProcessCondition> CODEC_FOR_SYNC = makeCodec(true);
static final MapCodec<CustomProcessCondition> CODEC = Codec.STRING.fieldOf("custom_id").xmap(CustomProcessCondition::new, c -> c.id);
static final StreamCodec<RegistryFriendlyByteBuf, CustomProcessCondition> 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);
Expand Down Expand Up @@ -106,7 +114,12 @@ public void appendDescription(List<Component> list) {
}

@Override
public MapCodec<? extends MachineProcessCondition> codec(boolean syncToClient) {
return syncToClient ? CODEC_FOR_SYNC : CODEC;
public MapCodec<? extends MachineProcessCondition> codec() {
return CODEC;
}

@Override
public StreamCodec<? super RegistryFriendlyByteBuf, ? extends MachineProcessCondition> streamCodec() {
return STREAM_CODEC;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -37,6 +39,11 @@ public record DimensionProcessCondition(ResourceKey<Level> dimension) implements
.fieldOf("dimension")
.xmap(DimensionProcessCondition::new, DimensionProcessCondition::dimension);

static final StreamCodec<RegistryFriendlyByteBuf, DimensionProcessCondition> 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;
Expand All @@ -50,7 +57,12 @@ public void appendDescription(List<Component> list) {
}

@Override
public MapCodec<? extends MachineProcessCondition> codec(boolean syncToClient) {
public MapCodec<? extends MachineProcessCondition> codec() {
return CODEC;
}

@Override
public StreamCodec<? super RegistryFriendlyByteBuf, ? extends MachineProcessCondition> streamCodec() {
return STREAM_CODEC;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<MachineProcessCondition> makeCodec(boolean syncToClient) {
return ResourceLocation.CODEC
.<MapCodec<? extends MachineProcessCondition>>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<MachineProcessCondition> CODEC = makeCodec(false);
StreamCodec<ByteBuf, MachineProcessCondition> STREAM_CODEC = ByteBufCodecs.fromCodec(makeCodec(true));
Codec<MachineProcessCondition> CODEC = ResourceLocation.CODEC
.<MapCodec<? extends MachineProcessCondition>>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<RegistryFriendlyByteBuf, MachineProcessCondition> STREAM_CODEC = ResourceLocation.STREAM_CODEC
.<RegistryFriendlyByteBuf>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<Component> list);

MapCodec<? extends MachineProcessCondition> codec(boolean syncToClient);
MapCodec<? extends MachineProcessCondition> codec();

StreamCodec<? super RegistryFriendlyByteBuf, ? extends MachineProcessCondition> streamCodec();

interface Context {
MachineBlockEntity getBlockEntity();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ResourceLocation, MapCodec<? extends MachineProcessCondition>> MAP = HashBiMap.create();
private static final BiMap<ResourceLocation, StreamCodec<? super RegistryFriendlyByteBuf, ? extends MachineProcessCondition>> STREAM_MAP = HashBiMap
.create();

public static void register(ResourceLocation id, MapCodec<? extends MachineProcessCondition> serializer) {
if (MAP.get(id) != null || MAP.inverse().get(serializer) != null) {
public static <T extends MachineProcessCondition> void register(
ResourceLocation id,
MapCodec<T> codec,
StreamCodec<? super RegistryFriendlyByteBuf, T> 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<? extends MachineProcessCondition> get(ResourceLocation id) {
public static MapCodec<? extends MachineProcessCondition> getCodec(ResourceLocation id) {
return MAP.get(id);
}

public static ResourceLocation getId(MapCodec<? extends MachineProcessCondition> serializer) {
return MAP.inverse().get(serializer);
@Nullable
public static StreamCodec<? super RegistryFriendlyByteBuf, ? extends MachineProcessCondition> getStreamCodec(ResourceLocation id) {
return STREAM_MAP.get(id);
}

public static ResourceLocation getId(MapCodec<? extends MachineProcessCondition> codec) {
return MAP.inverse().get(codec);
}

public static ResourceLocation getId(StreamCodec<? super RegistryFriendlyByteBuf, ? extends MachineProcessCondition> 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);
}
}

0 comments on commit b7303f6

Please sign in to comment.