[ANGRY PIXEL] The Betweenlands

[ANGRY PIXEL] The Betweenlands

24M Downloads

Dummy recipes causing mod incompatibility

LordMonoxide opened this issue ยท 4 comments

commented

Versions

Betweenlands version:

3.4.11

Forge version:

2838

Singleplayer or Multiplayer:

Either

Installed mods:

My own mod, Gradient

Description of the problem

It appears The Betweenlands wraps some recipes in its own dummy recipe class to disable them. I use custom IRecipe implementations for the different machines in my mod so that I can take advantage of the json loading mechanism. I override the default matches(InventoryCrafting, World) method to always return false, so that they can never be crafted on the crafting table, and use my own matches methods instead.

For example, I have a FuelRecipe, which controls what fuels are burnable in my firepit/furnace, their heat, and how long they burn for. The Betweenlands is disabling my plankWood and logWood fuels.

I'm assuming you're inspecting the input ingredients to decide what recipes to replace. Perhaps before replacing a recipe, you could matches(InventoryCrafting, World) to ensure that the recipes you're replacing do, in fact, match?

(ps. I am aware of override_any_conflicting_recipes and am currently using that as a workaround.)

For reference, here is an example of one of my IRecipe implementations:

public class FuelRecipe extends IForgeRegistryEntry.Impl<IRecipe> implements IRecipe {
  private final String group;
  public final int duration;
  public final float ignitionTemp;
  public final float burnTemp;
  public final float heatPerSec;
  private final Ingredient input;
  private final NonNullList<Ingredient> inputs;

  public FuelRecipe(final String group, final int duration, final float ignitionTemp, final float burnTemp, final float heatPerSec, final Ingredient input) {
    this.group = group;
    this.duration = duration;
    this.ignitionTemp = ignitionTemp;
    this.burnTemp = burnTemp;
    this.heatPerSec = heatPerSec;
    this.input = input;
    this.inputs = NonNullList.from(Ingredient.EMPTY, input);
  }

  @Override
  public String getGroup() {
    return this.group;
  }

  @Override
  @Deprecated
  public boolean matches(final InventoryCrafting inv, final World world) {
    return false;
  }

  public boolean matches(final ItemStack stack) {
    return this.input.apply(stack);
  }

  @Override
  @Deprecated
  public ItemStack getCraftingResult(final InventoryCrafting inv) {
    return ItemStack.EMPTY;
  }

  @Override
  public boolean canFit(final int width, final int height) {
    return width * height >= this.inputs.size();
  }

  @Override
  public ItemStack getRecipeOutput() {
    return ItemStack.EMPTY;
  }

  @Override
  public NonNullList<Ingredient> getIngredients() {
    return this.inputs;
  }
}
commented

Hmm, this is a bit tricky. The reason we're doing this is that people wanted us to oredict our materials, but that then broke our recipes because some oredict recipes take priority over our own. So we had to wrap conflicting recipes and disable them if our own recipe is valid so that it wouldn't be overwritten.
I did suspect that there might be some incompatibilities with other mods, but until now I haven't seen any except for yours. And for that case I've added the config option to disable this somewhat hacky fix ;)

I'm assuming you're inspecting the input ingredients to decide what recipes to replace. Perhaps before replacing a recipe, you could matches(InventoryCrafting, World) to ensure that the recipes you're replacing do, in fact, match?

That's not possible unfortunately because this must be done when recipes are initialized, i.e. before a world is loaded. So there's no world and no inventory to call this method with.

I don't think the recipe registry should be used for anything other than crafting table recipes in the first place, so I think the best solution would be for you to create a custom registry.
You can very easily create custom registries for custom objects specifically for a use case like this, see https://mcforge.readthedocs.io/en/latest/concepts/registries/#creating-registries.

commented

I might just add a class check that compares the recipe class and only wraps the recipe if it is either a vanilla or forge oredict recipe. And probably add a config option that is off by default that wraps all confliciting recipes like it does right now.

commented

I appreciate the suggestion for a custom registry and don't totally disagree with your position on the recipe registry, but using the recipe system allows me to load all recipes for my mod from json files and from the same place much more easily. 1.13+ also has a rewritten recipe system which does actually support different types of recipes properly, so I don't think I'm going to bother switching it up on my end since my mod is still in private beta and most likely won't even see a full release for 1.12.

Thanks for your help and feel free to close this issue if you see fit.

PS. A class check seems reasonable to me, or perhaps even a configurable blacklist

commented

Ah right, missed the part with the jsons.