Posted June 30, 20223 yr I am trying to add conditions to my recipes based on values from my config file. I have gotten it to work for a single config value. I set the value to false, and the condition disables the recipe. I have a lot of recipes I'd like to handle this way, so I'd like to make my ICondition implementation more generic now, so I could pass in something that would tell it which config option to check. But I can't figure out how. Something roughly like this, I think: Spoiler public class ConfigValueCondition implements ICondition { public static final ConfigValueCondition INSTANCE = new ConfigValueCondition(); private static final ResourceLocation NAME = new ResourceLocation("primallib", "config_value"); SomeParameter p; public ConfigValueCondition(SomeParameter p) { this.p = p; } @Override public ResourceLocation getID() { return NAME; } @Override public boolean test() { [Use p to look up which config option to evaluate] SomeFunction(p) = someConfigOption; return Config.[someConfigOption].get(); } @Override public String toString() { return NAME.toString(); } public static class Serializer implements IConditionSerializer<ConfigValueCondition> { public static final ConfigValueCondition.Serializer INSTANCE = new ConfigValueCondition.Serializer(); @Override public void write(JsonObject json, ConfigValueCondition value) { [Some function to serialize p] } @Override public ConfigValueCondition read(JsonObject json) { return [some function to deserialize p]; } @Override public ResourceLocation getID() { return ConfigValueCondition.NAME; } } } Each config option is a ForgeConfigSpec, and I found a function to look up the config options path, but I haven't found a way to do the reverse - given a path, get the value or maybe grab the corresponding ForgeConfigSpec so I can do ForgeConfigSpec#get. Another idea I found is to create a manual Map or maybe an enum to associate a String with each relevant config option. Then I could pass in the String to look up the appropriate config option. But that just feels like a lot of extra work and manual maintenance Edited June 30, 20223 yr by Daeruin Fill out title
June 30, 20223 yr Author Well, I think it's easier for users to type "false" into a config file than create a datapack. But also my mod is modular. If the user doesn't want to use a certain part of my mod, they can disable it, and it affects multiple things. I need to stop certain items from dropping when blocks are broken in addition to disabling various recipes. It doesn't make sense to me to make the user create a datapack to fully disable this part of my mod.
June 30, 20223 yr Author You may need to (re)read my original post to see more about what I'm trying to do. I have the process working for a single "module" but would like to make it more generic so I don't have to create a whole bunch of IConditions for all the modules. With how conditions work in data generation, I'm not sure how to achieve that.
June 30, 20223 yr Don't you have your config as a singleton in your mod for use at runtime? You could just make your ICondition implementation reference a map like you say, except it would be a map of strings to "getters" for your config. Something like: public class MyMod { public static YourConfig configSingleton; public static final Map<String, BooleanSupplier> conditions = new HashMap<>(); static { conditions.put("option1", configSingleton::isOption1); conditions.put("option2", () -> somethingMoreComplicated()); } } Maybe I am misunderstanding the problem? Boilerplate: If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one. If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install Large files should be posted to a file sharing site like https://gist.github.com You should also read the support forum sticky post.
July 5, 20223 yr Author On 6/30/2022 at 1:14 PM, warjort said: Don't you have your config as a singleton in your mod for use at runtime? Maybe I am misunderstanding the problem? Yeah, something like you suggested would work. I just thought that maybe I could use some existing methods from Forge's existing config code instead of making a manual map. I poked around for a while, couldn't figure out anything elegant, and finally figured I'd ask for ideas. Eventually I figured it out. My ICondition class takes a ForgeConfigSpec.Boolean parameter, so I can pass in a config option and save it as a field in ICondition. I can then reference it directly in the ICondition#test method. Spoiler public class ConfigValueCondition implements ICondition { private final ForgeConfigSpec.BooleanValue configOption; public ConfigValueCondition(ForgeConfigSpec.BooleanValue configOption) { this.configOption = configOption; } @Override public boolean test() { return configOption.get(); } } In my Serializer, I write that to JSON by using ConfigValue#getPath and turning the resulting list into a period separated string. I deserialize the period separated string using ForgeConfigSpec#getValues#get which returns the same ForgeConfigSpec.Boolean. Spoiler @Override public void write(JsonObject json, ConfigValueCondition value) { // Get the config path to the relevant config option List<String> configOptionPath = value.configOption.getPath(); String pathAsString = ""; // Convert config path list to period separated string - format "Category.config_option" for (int i = 0; i < configOptionPath.size(); i++) { pathAsString = pathAsString.concat(configOptionPath.get(i)); if (i < configOptionPath.size() - 1) // Don't add period after last item in path { pathAsString = pathAsString.concat("."); } } // Write path string to JSON recipe json.addProperty("config_value", pathAsString); } @Override public ConfigValueCondition read(JsonObject json) { // Get path to config option as a string from the JSON recipe String pathAsString = GsonHelper.getAsString(json, "config_value"); // Get the config option itself from the config using path ForgeConfigSpec.BooleanValue configOption = PrimalConfig.config.getValues().get(pathAsString); return new ConfigValueCondition(configOption); } The thing I like about this solution is that I can now use data generation to make any recipe conditional on my config without manually updating some map. So my instinct was right, I just got frustrated too early and posted here hoping someone had already solved this kind of issue. I guess with datapacks people aren't doing as much of this kind of thing anymore.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.