Recipe requirements WIP

This commit is contained in:
2025-03-10 11:49:56 +01:00
parent b6a34986ce
commit ece5555f75
14 changed files with 134 additions and 148 deletions

View File

@@ -2,6 +2,7 @@ package com.oierbravo.mechanical_lemon_lib;
import com.mojang.logging.LogUtils;
import com.oierbravo.mechanical_lemon_lib.register.LemonCreativeModeTabs;
import com.oierbravo.mechanical_lemon_lib.register.MechanicalLemonRegistries;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModContainer;
@@ -18,7 +19,7 @@ public class MechanicalLemonLib {
public MechanicalLemonLib(IEventBus modEventBus, ModContainer modContainer) {
LemonCreativeModeTabs.register(modEventBus);
//MechanicalLemonRegistries.init();
MechanicalLemonRegistries.init();
//modEventBus.addListener(MechanicalLemonRegistries::init);
}

View File

@@ -76,7 +76,7 @@ public class RecipeRequirementsBehaviour<R extends IRecipeWithRequirements> exte
}
private boolean checkRequirements(R pRecipe, Level pLevel, RecipeRequirementsSpecifics<R> pSpecifics){
boolean result = true;
for (Map.Entry<RecipeRequirementType<?>, RecipeRequirement> entry : pRecipe.getRecipeRequirements().entrySet()) {
for (Map.Entry<RecipeRequirementType, RecipeRequirement<?>> entry : pRecipe.getRecipeRequirements().entrySet()) {
if(!checkRequirement(entry.getValue(), pLevel, (BlockEntity) pSpecifics)){
missingRequirements.add(entry.getKey().getId());
result = false;

View File

@@ -7,12 +7,8 @@ import net.minecraft.world.item.crafting.RecipeInput;
import net.neoforged.neoforge.common.conditions.ICondition;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.swing.text.html.Option;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
@@ -20,12 +16,11 @@ public abstract class BaseRecipe<T extends RecipeInput, P extends BaseRecipePara
protected ResourceLocation id;
protected HashMap<RecipeRequirementType<?>, RecipeRequirement> recipeRequirements = new HashMap<>();
protected static List<RecipeRequirementType<?>> enabledRecipeRequirements = List.of();
protected HashMap<RecipeRequirementType<?>, RecipeRequirement<?>> recipeRequirements = new HashMap<>();
protected List<ICondition> conditions;
abstract public List<RecipeRequirementType<?>> getEnabledRequirements();
public BaseRecipe(P params){
this.id = params.id;
@@ -35,13 +30,7 @@ public abstract class BaseRecipe<T extends RecipeInput, P extends BaseRecipePara
);
this.conditions = params.conditions;
}
public List<RecipeRequirementType<?>> getEnabledRequirements() {
return enabledRecipeRequirements;
}
public Map<RecipeRequirementType<?>, RecipeRequirement> getRecipeRequirements(){
return recipeRequirements;
}
public List<ICondition> getConditions(){
return conditions;
}

View File

@@ -8,7 +8,7 @@ import java.util.List;
public abstract class BaseRecipeParams implements IBaseRecipeParams {
public ResourceLocation id;
public ArrayList<RecipeRequirement> recipeRequirements;
public ArrayList<RecipeRequirement<?>> recipeRequirements;
protected List<ICondition> conditions;
protected BaseRecipeParams(ResourceLocation id) {

View File

@@ -17,36 +17,4 @@ public abstract class BaseRecipeSerializer<R extends BaseRecipe<?,?>, B extends
public BaseRecipeSerializer(List<RecipeRequirementType<?>> pEnabledRecipeRequirements) {
this.enabledRecipeRequirements = pEnabledRecipeRequirements;
}
protected abstract B readFromJson(ResourceLocation recipeId, JsonObject json);
protected abstract B readFromBuffer(ResourceLocation recipeId, FriendlyByteBuf buffer);
protected abstract void writeToJson(JsonObject json, R recipe);
protected abstract void writeToBuffer(FriendlyByteBuf buffer, R recipe);
public final void write(JsonObject json, R recipe) {
writeToJson(json, recipe);
}
//public abstract @NotNull MapCodec<R> codec();
/*@Override
public @NotNull R fromJson(@NotNull ResourceLocation pRecipeId, @NotNull JsonObject pSerializedRecipe) {
return readFromJson(pRecipeId, pSerializedRecipe)
.withRequirements(RecipeRequirementsUtils.fromJson(pSerializedRecipe, enabledRecipeRequirements))
.build();
}
@Override
public @Nullable R fromNetwork(@NotNull ResourceLocation pRecipeId, @NotNull FriendlyByteBuf pBuffer) {
return readFromBuffer(pRecipeId, pBuffer).build();
}
@Override
public void toNetwork(@NotNull FriendlyByteBuf pBuffer, @NotNull R pRecipe) {
writeToBuffer(pBuffer, pRecipe);
}*/
}

View File

@@ -0,0 +1,7 @@
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
import com.mojang.serialization.MapCodec;
public interface IRecipeRequirementCodec<RR extends RecipeRequirement<?>> {
public MapCodec<RR> codec();
}

View File

@@ -0,0 +1,4 @@
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
public interface IRecipeRequirementType {
}

View File

@@ -1,19 +1,26 @@
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
import com.mojang.serialization.Codec;
import com.oierbravo.mechanical_lemon_lib.register.MechanicalLemonRegistries;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
public interface IRecipeWithRequirements {
Codec<IRecipeRequirementType> CODEC = MechanicalLemonRegistries.RECIPE_REQUIREMENT_TYPES.byNameCodec().dispatch(t -> RecipeRequirementType.codec(t), Function.identity());
Codec<? extends List<?>> LIST_CODEC = CODEC.listOf();
Map<RecipeRequirementType<?>, RecipeRequirement> getRecipeRequirements();
Map<RecipeRequirementType<?>, RecipeRequirement<?>> getRecipeRequirements();
List<RecipeRequirementType<?>> getEnabledRequirements();
default <T extends RecipeRequirement> T getRequirement(RecipeRequirementType<T> type) {
return (T) getRecipeRequirements().get(type);
default <RRT extends RecipeRequirementType<?>> RecipeRequirement<?> getRequirement(RRT type) {
return getRecipeRequirements().get(type);
}
boolean checkRequirements(Level pLevel, BlockEntity pBlockEntity);
}

View File

@@ -1,32 +1,40 @@
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.oierbravo.mechanical_lemon_lib.register.MechanicalLemonRegistries;
import com.oierbravo.mechanical_lemon_lib.utility.LibLang;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import java.util.List;
import java.util.function.Function;
import java.util.Optional;
public abstract class RecipeRequirement<V>{
//public static Codec<RecipeRequirement<>> CODEC = MechanicalLemonRegistries.RECIPE_REQUIREMENT_SERIALIZERS.byNameCodec().dispatch(RecipeRequirement::codec, Function.identity());
// public static Codec<? extends List<?>> LIST_CODEC = CODEC.listOf();
public abstract RecipeRequirementType<?> getType();
public abstract boolean test(Level pLevel, BlockEntity pBlockEntity);
public abstract V getValue();
public abstract Optional<V> getValue();
public abstract boolean isPresent();
public abstract String toString();
public Component toRequirementComponent(){
public boolean isProcessBlocker(){
return this instanceof IProcessBlockingRequirement;
}
public Component toTooltipComponent(){
return LibLang.translate("ui.recipe_requirement." + getType().getId() + ".tooltip", toString()).component();
};
public Component toMissingComponent(){
return LibLang.translate("ui.recipe_requirement." + getType().getId() + ".missing", toString()).component();
}
public abstract MapCodec<? extends RecipeRequirement<V>> codec();
/*public static MapCodec<? extends RecipeRequirement<?>> typeCodec() {
}*/
public static MapCodec<? extends RecipeRequirementType<?>> typeCodec(RecipeRequirementType<?> recipeRequirementType) {
}
}

View File

@@ -1,34 +1,32 @@
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.oierbravo.mechanical_lemon_lib.register.MechanicalLemonRegistries;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import java.util.function.Function;
public abstract class RecipeRequirementType<RR extends RecipeRequirement> {
public abstract class RecipeRequirementType<RR extends RecipeRequirement<?>> {
private final String id;
public RecipeRequirementType(String id) {
this.id = id;
}
public String getId() {
return id;
}
public abstract RR fromJson(JsonObject pJson);
public abstract JsonObject toJson(JsonObject pJson, RecipeRequirement pRecipeRequirement);
public abstract void toNetwork(FriendlyByteBuf buffer, RecipeRequirement<?> recipeRequirement);
public abstract RR fromNetwork(FriendlyByteBuf buffer);
public abstract void toNetwork(FriendlyByteBuf buffer, RecipeRequirement pRecipeRequirement);
public boolean isProcessBlocker(){
return this instanceof IProcessBlockingRequirement;
public MapCodec<RR> codec(IRecipeRequirementType t) {
return RR.typeCodec(this);
}
public StreamCodec<RegistryFriendlyByteBuf, RR> streamCodec(){
return StreamCodec.of(this::toNetwork, this::fromNetwork);
};
public String toString() {
return getId();
}
public abstract MapCodec<RR> codec();
}

View File

@@ -10,7 +10,7 @@ import java.util.List;
import java.util.Map;
public class RecipeRequirementsUtils {
public static ArrayList<RecipeRequirement> fromJson(JsonObject json, List<RecipeRequirementType<?>> enabledRecipeRequirements){
/*public static ArrayList<RecipeRequirement<?>> fromJson(JsonObject json, List<RecipeRequirementType<?>> enabledRecipeRequirements){
ArrayList<RecipeRequirement> recipeRequirements = new ArrayList<>();
enabledRecipeRequirements.forEach(recipeRequirementType -> {
@@ -19,9 +19,9 @@ public class RecipeRequirementsUtils {
}
});
return recipeRequirements;
}
public static ArrayList<RecipeRequirement> fromBuffer(FriendlyByteBuf buffer, List<RecipeRequirementType<?>> enabledRecipeRequirements){
ArrayList<RecipeRequirement> recipeRequirements = new ArrayList<>();
}*/
public static ArrayList<RecipeRequirement<?>> fromBuffer(FriendlyByteBuf buffer, List<RecipeRequirementType<?>> enabledRecipeRequirements){
ArrayList<RecipeRequirement<?>> recipeRequirements = new ArrayList<>();
enabledRecipeRequirements.forEach(recipeRequirementType -> {
recipeRequirements.add(recipeRequirementType.fromNetwork(buffer));
});
@@ -29,21 +29,21 @@ public class RecipeRequirementsUtils {
return recipeRequirements;
}
public static JsonObject toJson(JsonObject pJson, Map<RecipeRequirementType<?>, RecipeRequirement> pRecipeRequirements){
/*public static JsonObject toJson(JsonObject pJson, Map<RecipeRequirementType<?>, RecipeRequirement> pRecipeRequirements){
for (Map.Entry<RecipeRequirementType<?>, RecipeRequirement> entry : pRecipeRequirements.entrySet()) {
pJson = entry.getKey().toJson(pJson, entry.getValue());
}
return pJson;
}
*/
public static void toBuffer(FriendlyByteBuf buffer, IRecipeWithRequirements pRecipe){
public static <RRT extends RecipeRequirementType<?>> void toBuffer(FriendlyByteBuf buffer, IRecipeWithRequirements pRecipe){
pRecipe.getEnabledRequirements().forEach(recipeRequirementType -> {
recipeRequirementType.toNetwork(buffer,pRecipe.getRequirement(recipeRequirementType));
});
}
public static ArrayList<String> checkRequirements(Map<RecipeRequirementType<?>, RecipeRequirement> pRecipeRequirements, BlockEntity pBlockEntity){
public static ArrayList<String> checkRequirements(Map<RecipeRequirementType<?>, RecipeRequirement<?>> pRecipeRequirements, BlockEntity pBlockEntity){
ArrayList<String> missingRequirements = new ArrayList<>();
pRecipeRequirements.forEach((recipeRequirementType, recipeRequirement) -> {
if(!recipeRequirement.test(pBlockEntity.getLevel(),pBlockEntity))

View File

@@ -1,6 +1,5 @@
package com.oierbravo.mechanical_lemon_lib.foundation.recipe.requirements;
import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
@@ -8,23 +7,29 @@ import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirement;
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirementType;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.util.GsonHelper;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.neoforged.neoforge.common.conditions.ModLoadedCondition;
public class SpeedRequirement extends RecipeRequirement<Float>{
public static final RecipeRequirementType<?> TYPE = new SpeedRequirementType();
import java.util.Optional;
public class SpeedRequirement extends RecipeRequirement<Float> {
public static final RecipeRequirementType TYPE = new SpeedRequirementType();
public static final SpeedRequirement EMPTY = new SpeedRequirement();
private Float value;
public SpeedRequirement() {
}
public SpeedRequirement(Float value) {
this.value = value;
}
public SpeedRequirement(float pValue) {
value = pValue;
public SpeedRequirement(Optional<Float> value) {
this(value.get());
}
@@ -48,13 +53,11 @@ public class SpeedRequirement extends RecipeRequirement<Float>{
return value.toString();
}
@Override
public MapCodec<? extends RecipeRequirement<Float>> codec() {
return null;
}
public Float getValue() {
return value;
public Optional<Float> getValue() {
if(value == null)
return Optional.empty();
return Optional.of(value);
}
public static SpeedRequirement of(float pValue) {
@@ -67,53 +70,26 @@ public class SpeedRequirement extends RecipeRequirement<Float>{
return TYPE;
}
private static class SpeedRequirementType extends RecipeRequirementType<SpeedRequirement> {
public static MapCodec<SpeedRequirement> CODEC = RecordCodecBuilder.mapCodec((builder) -> builder.group(Codec.FLOAT.optionalFieldOf("min_speed").forGetter(SpeedRequirement::getValue)).apply(builder,SpeedRequirement::new));
private static class SpeedRequirementType extends RecipeRequirementType<SpeedRequirement>{
public static MapCodec<SpeedRequirement> CODEC = RecordCodecBuilder.mapCodec((builder) -> builder.group(Codec.FLOAT.fieldOf("min_speed").forGetter(SpeedRequirement::getValue)).apply(builder,SpeedRequirement::new));
public SpeedRequirementType(String id) {
super(id);
}
public SpeedRequirementType() {
super("min_speed");
}
@Override
public SpeedRequirement fromJson(JsonObject pJson) {
if (GsonHelper.isValidNode(pJson, this.getId())) {
return of(pJson.get(this.getId()).getAsFloat());
}
return EMPTY;
}
public void toNetwork(FriendlyByteBuf buffer, RecipeRequirement<?> recipeRequirement) {
@Override
public JsonObject toJson(JsonObject pJson, RecipeRequirement pRecipeRequirement) {
if(!pRecipeRequirement.isPresent())
return pJson;
pJson.addProperty(this.getId(), pRecipeRequirement.toString());
return pJson;
}
@Override
public SpeedRequirement fromNetwork(FriendlyByteBuf buffer) {
boolean hasRequirement = buffer.readBoolean();
if(hasRequirement) {
return of(buffer.readFloat());
}
return SpeedRequirement.EMPTY;
}
@Override
public void toNetwork(FriendlyByteBuf buffer, RecipeRequirement pRecipeRequirement) {
if(pRecipeRequirement == null)
pRecipeRequirement = new SpeedRequirement();
if(pRecipeRequirement instanceof SpeedRequirement){
buffer.writeBoolean(pRecipeRequirement.isPresent());
if(pRecipeRequirement.isPresent())
buffer.writeFloat(((SpeedRequirement) pRecipeRequirement).getValue());
return null;
}
public SpeedRequirementType() {
super("min_speed");
}
@Override
@@ -121,5 +97,12 @@ public class SpeedRequirement extends RecipeRequirement<Float>{
return CODEC;
}
@Override
public StreamCodec<RegistryFriendlyByteBuf, SpeedRequirement> streamCodec() {
return null;
}
}
}

View File

@@ -0,0 +1,12 @@
package com.oierbravo.mechanical_lemon_lib.register;
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.requirements.SpeedRequirement;
public class LemonRecipeRequirementTypes {
public static void register() {
IRecipeRequirement.REGISTRY.register(SpeedRequirement.TYPE,SpeedRequirement.);
}
}

View File

@@ -2,34 +2,29 @@ package com.oierbravo.mechanical_lemon_lib.register;
import com.mojang.serialization.MapCodec;
import com.oierbravo.mechanical_lemon_lib.MechanicalLemonLib;
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirement;
import com.simibubi.create.Create;
import net.minecraft.core.RegistrationInfo;
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.IRecipeRequirementType;
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirementType;
import net.minecraft.core.Registry;
import net.minecraft.core.WritableRegistry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceKey;
import net.neoforged.neoforge.common.conditions.ICondition;
import net.neoforged.neoforge.registries.RegistryBuilder;
public class MechanicalLemonRegistries {
public static final Registry<MapCodec<? extends RecipeRequirement>> RECIPE_REQUIREMENT_SERIALIZERS = simple(key("recipe_requirement_serializer")) ;
//public static final Registry<MapCodec<? extends RecipeRequirementType<?>>> RECIPE_REQUIREMENT_TYPES = simple(key("requirements")) ;
public static final Registry<MapCodec<? extends IRecipeRequirementType>> RECIPE_REQUIREMENT_TYPES = (new RegistryBuilder(Keys.RECIPE_REQUIREMENT_TYPES)).create();
private static <T> Registry<T> simple(ResourceKey<Registry<T>> key) {
return register(key, false);
}
/*private static <T> Registry<T> simple(ResourceKey<Registry<T>> key) {
return register(key);
}*/
private static <T> Registry<T> withIntrusiveHolders(ResourceKey<Registry<T>> key) {
/*private static <T> Registry<T> withIntrusiveHolders(ResourceKey<Registry<T>> key) {
return register(key, true);
}
}*/
@SuppressWarnings({"deprecation", "unchecked", "rawtypes"})
private static <T> Registry<T> register(ResourceKey<Registry<T>> key, boolean hasIntrusiveHolders) {
/*private static <T> Registry<T> register(ResourceKey<Registry<T>> key) {
RegistryBuilder<T> builder = new RegistryBuilder<>(key)
.sync(true);
if (hasIntrusiveHolders)
builder.withIntrusiveHolders();
Registry<T> registry = builder.create();
((WritableRegistry) BuiltInRegistries.REGISTRY)
@@ -38,10 +33,24 @@ public class MechanicalLemonRegistries {
}
private static <T> ResourceKey<Registry<T>> key(String name) {
return ResourceKey.createRegistryKey(MechanicalLemonLib.asResource(name));
}*/
public MechanicalLemonRegistries() {
}
static {
RECIPE_REQUIREMENT_TYPES = (new RegistryBuilder(MechanicalLemonRegistries.Keys.RECIPE_REQUIREMENT_TYPES)).create();
}
public static final class Keys {
public static final ResourceKey<Registry<MapCodec<? extends RecipeRequirementType<?>>>> RECIPE_REQUIREMENT_TYPES = key("requirements");
public Keys() {
}
private static <T> ResourceKey<Registry<T>> key(String name) {
return ResourceKey.createRegistryKey(MechanicalLemonLib.asResource(name));
}
}
public static void init() {
// make sure the class is loaded.
// this method is called at the tail of BuiltInRegistries, injected by BuiltInRegistriesMixin.
}
}