Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.18.2] ICondition to look up config values


Daeruin
 Share

Recommended Posts

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 by Daeruin
Fill out title
Link to comment
Share on other sites

  • Daeruin changed the title to [1.18.2] ICondition to look up config values

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.