Jump to content

Recommended Posts

Posted (edited)

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
  • Daeruin changed the title to [1.18.2] ICondition to look up config values
Posted

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.

Posted

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.

Posted

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.

Posted
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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.

Announcements



×
×
  • Create New...

Important Information

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