Jump to content

[1.18.2] [SOLVED] Disable crafting recipes from config files


CrackedScreen

Recommended Posts

Late reply, but tried implementing ICondition and copying some code over from ModLoadedCondition:

Spoiler
public class RecipeCondition implements ICondition {

    private static final ResourceLocation NAME = new ResourceLocation(MusketMod.MOD_ID, "recipe_enabled");
    private final boolean loaded;

    public RecipeCondition(Boolean loaded) {
        this.loaded = loaded;
    }

    public ResourceLocation getID() {
        return NAME;
    }

    @Override
    public boolean test(IContext context) {
        return ICondition.super.test(context);
    }

    @Override
    public boolean test() {
        return false;
    }

    public static class Serializer implements IConditionSerializer<RecipeCondition>
    {
        public static final RecipeCondition.Serializer INSTANCE = new RecipeCondition.Serializer();

        @Override
        public void write(JsonObject json, RecipeCondition value)
        {
            json.addProperty("recipe_enabled", value.loaded);
        }

        @Override
        public RecipeCondition read(JsonObject json)
        {
            return new RecipeCondition(GsonHelper.getAsBoolean(json, "recipe_enabled"));
        }

        @Override
        public ResourceLocation getID()
        {
            return RecipeCondition.NAME;
        }
    }
}

 

Getting an error for including the test() method since it is marked as deprecated, but forge still requires it to be implemented. Using Forge 1.18.2-40.1.51, if I'm missing anything let me know.

EDIT:
The mod will still compile and run fine since this isn't actually an error, but will need to know how to pass existing datagen recipes through the serializer since forge does not come with any functional examples by itself. Would still appreciate an answer on how to get rid of the deprecated method in case I am missing something obvious.

Edited by CrackedScreen
Changed post.
Link to comment
Share on other sites

8 hours ago, CrackedScreen said:

The mod will still compile and run fine since this isn't actually an error, but will need to know how to pass existing datagen recipes through the serializer since forge does not come with any functional examples by itself.

I give you, a Forge provided functional example: https://github.com/MinecraftForge/MinecraftForge/blob/1.19.x/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java#L165-L204

8 hours ago, CrackedScreen said:

Would still appreciate an answer on how to get rid of the deprecated method in case I am missing something obvious.

Essentially, the method is removed in 1.19 due to the context parameter addition. However, changing how the method is implemented would induce a breaking change. As such, older versions need to have it implemented until they update to the next version.

Link to comment
Share on other sites

Used the following to create the recipe:

Spoiler
ResourceLocation ID = new ResourceLocation(MOD_ID, moddedItem.toString());

ConditionalRecipe.builder().addCondition(
	new RecipeCondition(Config.ENABLED_CRAFTING.get())
).addRecipe(
	ShapedRecipeBuilder.shaped(moddedItem, amount)
		// .define ingredients here
).build(consumer, ID);

 

Condition/Serializer class:

Spoiler
public class RecipeCondition implements ICondition {

    private static final ResourceLocation NAME = new ResourceLocation(MOD_ID, "recipe_enabled");
    private final boolean loaded;

    public RecipeCondition(Boolean loaded) {
        this.loaded = loaded;
    }

    public ResourceLocation getID() {
        return NAME;
    }

    @Override
    public boolean test(IContext context) {
        return loaded;
    }

    @Override
    public boolean test() {
        return false;
    }

    public static class Serializer implements IConditionSerializer<RecipeCondition>
    {
        public static final Serializer INSTANCE = new Serializer();

        @Override
        public void write(JsonObject json, RecipeCondition value)
        {
            json.addProperty("recipe_enabled", value.loaded);
        }

        @Override
        public RecipeCondition read(JsonObject json)
        {
            return new RecipeCondition(GsonHelper.getAsBoolean(json, "recipe_enabled"));
        }

        @Override
        public ResourceLocation getID()
        {
            return RecipeCondition.NAME;
        }
    }
}

 

Registered the serializer class in RegistryEvents class:

Spoiler
@SubscribeEvent
public void registerSerializers(RegistryEvent.Register<RecipeSerializer<?>> event) {
	CraftingHelper.register(RecipeCondition.Serializer.INSTANCE);
}

 

 

Currently getting an "Unknown condition type" error when using the runData task which likely means the condition wasn't registered correctly, but don't know how this is the case.

Spoiler
Caused by: com.google.gson.JsonSyntaxException: Unknown condition type: mod_id:recipe_enabled

 

Edited by CrackedScreen
Changed text
Link to comment
Share on other sites

I've already tried pulling the value directly from configs, this does not change the result.

Spoiler
public class RecipeCondition implements ICondition {

    public static final RecipeCondition INSTANCE = new RecipeCondition();
    private static final ResourceLocation NAME = new ResourceLocation(MOD_ID, "recipe_enabled");

    public RecipeCondition() {
    }

    public ResourceLocation getID() {
        return NAME;
    }

    @Override
    public boolean test(IContext context) {
        return Config.ENABLED_CRAFTING.get();
    }

    @Override
    public boolean test() {
        return false;
    }

    public static class Serializer implements IConditionSerializer<RecipeCondition>
    {
        public static final Serializer INSTANCE = new Serializer();

        @Override
        public void write(JsonObject json, RecipeCondition value)
        {
            json.addProperty("recipe_enabled", Config.ENABLED_CRAFTING.get());
        }

        @Override
        public RecipeCondition read(JsonObject json)
        {
            return RecipeCondition.INSTANCE;
        }

        @Override
        public ResourceLocation getID()
        {
            return RecipeCondition.NAME;
        }
    }
}

 

The recipes aren't being loaded as the serializer is returning null after using /reload, the problem is likely the read() method but I'm not sure what it should return since the examples provided by forge return a new condition with constructor. Would also prefer to reload datapacks from code whenever the world/server is loaded, if possible.

Edited by CrackedScreen
Link to comment
Share on other sites

57 minutes ago, CrackedScreen said:

The recipes aren't being loaded as the serializer is returning null after using /reload

That would mean the serializer is null.

58 minutes ago, CrackedScreen said:

the problem is likely the read() method but I'm not sure what it should return since the examples provided by forge return a new condition with constructor

Not really an issue with read, though you don't need to write anything and the single boolean test needs to return the config value as well.

58 minutes ago, CrackedScreen said:

Would also prefer to reload datapacks from code whenever the world/server is loaded, if possible.

You can look at the `ReloadCommand` to learn how to do this, but it should generally be avoided unless the cached config value changes.

Link to comment
Share on other sites

3 hours ago, ChampionAsh5357 said:

That would mean the serializer is null.

You'll have to elaborate on why this is the case since I don't see any immediate issues. I created the condition almost the exact same way the builtin forge conditions are.

Edit: The recipes are disabled if the config value is set to false, but only after manually reloading. Will need a fix for the serializer issue and best practices for forcing a reload upon entering a world if the serializer fix doesn't correct this behavior.

Edited by CrackedScreen
Update
Link to comment
Share on other sites

44 minutes ago, CrackedScreen said:

You'll have to elaborate on why this is the case since I don't see any immediate issues.

I wouldn't know the reasoning. There's no inclination in the code provided that there would be an issue. The only thing I can think of is the event listener where you register things, which you would need to show the entire class for. Anything else might result from a separate issue.

Link to comment
Share on other sites

Registry class:

Spoiler
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
    public static class RegistryEvents {
  
	@SubscribeEvent
	public static void registerSerializers(RegistryEvent.Register<RecipeSerializer<?>> event) {
		CraftingHelper.register(RecipeCondition.Serializer.INSTANCE);
	}
}

 

I could try registering this outside of event bus in a non-static context.

Link to comment
Share on other sites

Adding modid = MOD_ID to my event bus subscriber didn't have any effect. The serializer only has the null issue when the config value is set to false for some reason, if I return true/false directly in the condition class or leave the config value as true there aren't any issues with loading/blocking the recipe.

Edited by CrackedScreen
Link to comment
Share on other sites

3 hours ago, CrackedScreen said:

The serializer only has the null issue when the config value is set to false for some reason, if I return true/false directly in the condition class or leave the config value as true there aren't any issues with loading/blocking the recipe.

Ah, so it's a defaulting issue. Well, the way to fix that is to either give your config a default, or to cache the value into a boolean and change the boolean when the config is loaded and reloaded using (ConfigEvent$Loading and ConfigEvent$Reloading).

Link to comment
Share on other sites

The test value that I'm using already has a default value set:

Spoiler
public static ForgeConfigSpec.BooleanValue ENABLED_CRAFTING;

public static void registerConfig() {
	ForgeConfigSpec.Builder CONFIG_BUILDER = new ForgeConfigSpec.Builder();

	ENABLED_CRAFTING = CONFIG_BUILDER
		.define("Test value", true);

	ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, CONFIG_BUILDER.build());
}

 

Will look into using booleans, but I may have tried this + reloading before with no success using something similar:

Spoiler
@SubscribeEvent
public static void onConfigLoad(ModConfigEvent.Loading event) {
	((CommentedFileConfig)event.getConfig().getConfigData()).load();
}

 

 

Edited by CrackedScreen
Link to comment
Share on other sites

On 10/19/2022 at 2:45 PM, CrackedScreen said:
	((CommentedFileConfig)event.getConfig().getConfigData()).load();

Yeah, that looks like it may cause a infinite loop. The events are called because the data has finished loading and reloading and are now within the config values. These are for if you want to know when those values are changed.

Link to comment
Share on other sites

  • CrackedScreen changed the title to [1.18.2] [SOLVED] Disable crafting recipes from config files

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • when I just started up the game, I had this one splash on the menu. then I joined a world. I left. but when I exited the world to menu, it said the exact same splash it showed that I started up the game! 😠 and it won't change until I restart the whole game all over again. and I am using my custom splash texture pack, but it was not like that before even when I had it enabled. ugh! what even am I doing wrong? my whole game is ruined!! https://mclo.gs/LRDITtP
    • before I updated my pack I made for paintings++ mod, i noticed and saw that only modded paintings and vanilla ones move one block each time I re-enter my world! is there something wrong? what the hell is even going on? why is there a ghost living in my house?! the modded paintings even phase through blocks which is super weird!! help! here is my painting mod list: Paintings++ Dark paintings Macaw's paintings Joy of painting Immersive paintings My custom paintings++ resource pack
    • Error: java.lang.NullPointerException: Cannot invoke "me.codexadrian.tempad.TempadClientConfig.renderBlur()" because the return value of "me.codexadrian.tempad.TempadClient.getClientConfig()" is null I keep having this error while trying to launch a modpack through the forge modloader, any suggestions? https://docs.google.com/document/d/1CRKUoSiu2e_mDvDTVYpIA5wqD3w-BsCycxBu1_vQ4OA/edit?usp=sharing Crash Report ^^^^
    • I'm trying to start a server with the latest installer, but running the run.bat file doesn't generate new files. It shows the following in the cmd prompt.
    • One of my players is suddenly unable to join a locally hosted MC Eternal server. We have been playing on this server for about 2-3 weeks now. I have tried erasing his player files and his reputation file, and now it just coughs up this and kicks him out: [User Authenticator #5/INFO] [minecraft/NetHandlerLoginServer]: UUID of player EthosTheGod is 7692d8db-02c3-424f-a4ab-0e4e259b106b [20:25:36] [User Authenticator #4/INFO] [minecraft/NetHandlerLoginServer]: UUID of player EthosTheGod is 7692d8db-02c3-424f-a4ab-0e4e259b106b [20:29:35] [Server thread/WARN] [minecraft/MinecraftServer]: Can't keep up! Did the system time change, or is the server overloaded? Running 575849ms behind, skipping 11516 tick(s) [20:29:35] [Server thread/INFO] [minecraft/NetHandlerLoginServer]: com.mojang.authlib.GameProfile@4a6c63f1[id=7692d8db-02c3-424f-a4ab-0e4e259b106b,name=EthosTheGod,properties={textures=[com.mojang.authlib.properties.Property@241ea89e]},legacy=false] (/IP.ADDRESS) lost connection: Disconnected [20:29:35] [Server thread/INFO] [minecraft/NetHandlerLoginServer]: com.mojang.authlib.GameProfile@6ab6c661[id=7692d8db-02c3-424f-a4ab-0e4e259b106b,name=EthosTheGod,properties={textures=[com.mojang.authlib.properties.Property@7f19aae3]},legacy=false] (/IP.ADDRESS) lost connection: Disconnected It just says "connection timed out" on his end. Any ideas?
  • Topics

×
×
  • Create New...

Important Information

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