[Feature] Disable any Recipe using a dataPack file.

You can add a new File `bclib/config/recipes.json` to your datapack with the following content to disable any recipe (by Id):

```json
{
  "disable": [
    "minecraft:jungle_chest_boat",
    "bclib:test_star"
  ]
}
```
This commit is contained in:
Frank 2023-04-13 17:33:42 +02:00
parent 48a0049faf
commit 5f92964f9d
2 changed files with 53 additions and 15 deletions

View file

@ -3,16 +3,20 @@ package org.betterx.bclib.mixin.common;
import org.betterx.bclib.recipes.BCLRecipeManager;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.Container;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.Level;
import com.google.gson.JsonElement;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Map;
@ -32,4 +36,15 @@ public abstract class RecipeManagerMixin {
) {
info.setReturnValue(BCLRecipeManager.getSortedRecipe(type, inventory, level, this::byType));
}
@Inject(method = "apply(Ljava/util/Map;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/util/profiling/ProfilerFiller;)V", at = @At("HEAD"))
public void bcl_interceptApply(
Map<ResourceLocation, JsonElement> map,
ResourceManager resourceManager,
ProfilerFiller profiler,
CallbackInfo info
) {
BCLRecipeManager.removeDisabledRecipes(resourceManager, map);
}
}

View file

@ -1,10 +1,14 @@
package org.betterx.bclib.recipes;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.config.Configs;
import org.betterx.bclib.util.CollectionsUtil;
import org.betterx.worlds.together.util.DatapackConfigs;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.world.Container;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.Recipe;
@ -15,10 +19,14 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import com.google.common.collect.Maps;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.Function;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
public class BCLRecipeManager {
private static final Map<?, ? extends Map<?, ?>> _RECIPES = Maps.newHashMap();
@ -54,15 +62,6 @@ public class BCLRecipeManager {
return recipes.stream().filter(recipe -> recipe.matches(inventory, level)).findFirst();
}
public static <C extends Container, T extends Recipe<C>> void addRecipe(RecipeType<T> type, T recipe) {
Map<ResourceLocation, T> list = BCLRecipeManager.<C, T>RECIPES().computeIfAbsent(type, i -> Maps.newHashMap());
list.put(recipe.getId(), recipe);
}
public static <C extends Container, T extends Recipe<C>> T getRecipe(RecipeType<T> type, ResourceLocation id) {
Map<ResourceLocation, T> map = BCLRecipeManager.<C, T>RECIPES().get(type);
return map != null ? map.get(id) : null;
}
public static <C extends Container, T extends Recipe<C>> Map<RecipeType<T>, Map<ResourceLocation, T>> getMap(
Map<RecipeType<T>, Map<ResourceLocation, T>> recipes
@ -124,12 +123,36 @@ public class BCLRecipeManager {
}
}
public static boolean exists(ItemLike... items) {
for (ItemLike item : items) {
if (!exists(item)) {
return false;
}
private final static HashSet<ResourceLocation> disabledRecipes = new HashSet<>();
private static void clearRecipeConfig() {
disabledRecipes.clear();
}
private static void processRecipeConfig(@NotNull ResourceLocation sourceId, @NotNull JsonObject root) {
if (root.has("disable")) {
root
.getAsJsonArray("disable")
.asList()
.stream()
.map(el -> ResourceLocation.tryParse(el.getAsString()))
.filter(id -> id != null)
.forEach(disabledRecipes::add);
}
}
@ApiStatus.Internal
public static void removeDisabledRecipes(ResourceManager manager, Map<ResourceLocation, JsonElement> map) {
clearRecipeConfig();
DatapackConfigs
.instance()
.runForResources(manager, BCLib.MOD_ID, "recipes.json", BCLRecipeManager::processRecipeConfig);
for (ResourceLocation id : disabledRecipes) {
if (Configs.MAIN_CONFIG.verboseLogging()) {
BCLib.LOGGER.info("Disabling Recipe: {}", id);
}
map.remove(id);
}
return true;
}
}