From 7d7bf54ee4a2e08283ded2c1bd1b27d6945fcefe Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Thu, 7 Nov 2024 13:57:06 -0700 Subject: [PATCH] Recipe Categories (#2274) --- settings.gradle | 6 +- .../resources/assets/gtceu/lang/en_ud.json | 3 + .../resources/assets/gtceu/lang/en_us.json | 3 + .../gtceu/api/gui/GuiTextures.java | 9 ++ .../gtceu/api/recipe/GTRecipe.java | 16 +- .../gtceu/api/recipe/GTRecipeSerializer.java | 18 ++- .../gtceu/api/recipe/GTRecipeType.java | 10 ++ .../api/recipe/category/GTRecipeCategory.java | 82 ++++++++++ .../api/recipe/lookup/GTRecipeLookup.java | 16 +- .../gtceu/api/recipe/ui/GTRecipeTypeUI.java | 20 +-- .../gtceu/api/registry/GTRegistries.java | 3 + .../gtceu/common/data/GTRecipeCategories.java | 28 ++++ .../gtceu/common/data/GTRecipeTypes.java | 8 +- .../generator/LargeTurbineMachine.java | 2 +- .../gregtechceu/gtceu/data/lang/ItemLang.java | 6 + .../data/recipe/builder/GTRecipeBuilder.java | 26 +++- .../data/recipe/misc/RecyclingRecipes.java | 35 ++++- .../gtceu/integration/emi/GTEMIPlugin.java | 14 +- .../integration/emi/recipe/GTEmiRecipe.java | 4 +- .../emi/recipe/GTRecipeEMICategory.java | 116 ++++++++++++++ .../emi/recipe/GTRecipeTypeEmiCategory.java | 77 --------- .../gtceu/integration/jei/GTJEIPlugin.java | 14 +- .../jei/recipe/GTRecipeJEICategory.java | 147 ++++++++++++++++++ .../jei/recipe/GTRecipeTypeCategory.java | 112 ------------- .../gtceu/integration/rei/GTREIPlugin.java | 15 +- .../rei/recipe/GTRecipeDisplay.java | 9 +- ...Category.java => GTRecipeREICategory.java} | 66 ++++++-- .../gui/icon/arc_furnace_recycling.png | Bin 0 -> 553 bytes .../textures/gui/icon/extractor_recycling.png | Bin 0 -> 410 bytes .../textures/gui/icon/macerator_recycling.png | Bin 0 -> 308 bytes 30 files changed, 613 insertions(+), 252 deletions(-) create mode 100644 src/main/java/com/gregtechceu/gtceu/api/recipe/category/GTRecipeCategory.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeCategories.java create mode 100644 src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeEMICategory.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeTypeEmiCategory.java create mode 100644 src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeJEICategory.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeTypeCategory.java rename src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/{GTRecipeTypeDisplayCategory.java => GTRecipeREICategory.java} (51%) create mode 100644 src/main/resources/assets/gtceu/textures/gui/icon/arc_furnace_recycling.png create mode 100644 src/main/resources/assets/gtceu/textures/gui/icon/extractor_recycling.png create mode 100644 src/main/resources/assets/gtceu/textures/gui/icon/macerator_recycling.png diff --git a/settings.gradle b/settings.gradle index d40f49dc90..2cce3bf268 100644 --- a/settings.gradle +++ b/settings.gradle @@ -25,8 +25,8 @@ dependencyResolutionManagement { // Mod Dependencies Versions // Common - def jeiVersion = "15.12.1.46" - def reiVersion = "12.1.725" + def jeiVersion = "15.20.0.105" + def reiVersion = "12.1.785" def emiVersion = "1.1.13" def ae2Version = "15.0.18" def kjsVersion = "2001.6.4-build.120" @@ -62,7 +62,7 @@ dependencyResolutionManagement { def vineFlowerVersion = "1.+" def macheteVersion = "1.+" def configurationVersion = "2.2.0" - def ldLibVersion = "1.0.30.a" + def ldLibVersion = "1.0.31" def mixinextrasVersion = "0.2.0" def shimmerVersion = "0.2.4" def lombokPluginVersion = "8.7.1" diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index 0f22fc1c07..3df1a5450f 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -3855,6 +3855,9 @@ "gtceu.primitive_blast_furnace": "ǝɔɐuɹnℲ ʇsɐןᗺ ǝʌıʇıɯıɹԀ", "gtceu.pyrolyse_oven": "uǝʌO ǝsʎןoɹʎԀ", "gtceu.recipe.amperage": "%s :ǝbɐɹǝdɯⱯ", + "gtceu.recipe.category.arc_furnace_recycling": "buıddɐɹɔS ɐɯsɐןԀ", + "gtceu.recipe.category.extractor_recycling": "buıʇןǝɯǝᴚ dɐɹɔS", + "gtceu.recipe.category.macerator_recycling": "buıpuıɹ⅁ ʇɹɐԀ", "gtceu.recipe.chance": "ɹǝıʇ/%s+ %s :ǝɔuɐɥƆ", "gtceu.recipe.cleanroom": "%s sǝɹınbǝᴚ", "gtceu.recipe.cleanroom.display_name": "ɯooɹuɐǝןƆ", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 5832d3f780..329286dfea 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -3855,6 +3855,9 @@ "gtceu.primitive_blast_furnace": "Primitive Blast Furnace", "gtceu.pyrolyse_oven": "Pyrolyse Oven", "gtceu.recipe.amperage": "Amperage: %s", + "gtceu.recipe.category.arc_furnace_recycling": "Plasma Scrapping", + "gtceu.recipe.category.extractor_recycling": "Scrap Remelting", + "gtceu.recipe.category.macerator_recycling": "Part Grinding", "gtceu.recipe.chance": "Chance: %s +%s/tier", "gtceu.recipe.cleanroom": "Requires %s", "gtceu.recipe.cleanroom.display_name": "Cleanroom", diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/GuiTextures.java b/src/main/java/com/gregtechceu/gtceu/api/gui/GuiTextures.java index a114e933d7..7ee60a2c0a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/gui/GuiTextures.java +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/GuiTextures.java @@ -3,6 +3,8 @@ import com.lowdragmc.lowdraglib.gui.texture.ResourceBorderTexture; import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; +import net.minecraft.resources.ResourceLocation; + import lombok.val; /** @@ -486,6 +488,13 @@ public class GuiTextures { public static final ResourceTexture MULTIBLOCK_CATEGORY = new ResourceTexture( "gtceu:textures/gui/icon/coke_oven.png"); + public static final ResourceTexture ARC_FURNACE_RECYCLING_CATEGORY = new ResourceTexture( + new ResourceLocation("gtceu:textures/gui/icon/arc_furnace_recycling.png"), 0, 0, 16, 16); + public static final ResourceTexture MACERATOR_RECYCLING_CATEGORY = new ResourceTexture( + new ResourceLocation("gtceu:textures/gui/icon/macerator_recycling.png"), 0, 0, 16, 16); + public static final ResourceTexture EXTRACTOR_RECYCLING_CATEGORY = new ResourceTexture( + new ResourceLocation("gtceu:textures/gui/icon/extractor_recycling.png"), 0, 0, 16, 16); + // Covers public static final ResourceTexture COVER_MACHINE_CONTROLLER = new ResourceTexture( "gtceu:textures/items/metaitems/cover.controller.png"); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java index e9f18c0ab2..9e359b157a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java @@ -3,6 +3,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.*; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; import com.gregtechceu.gtceu.api.recipe.content.Content; @@ -62,6 +63,7 @@ public class GTRecipe implements net.minecraft.world.item.crafting.Recipe ingredientActions, @NotNull CompoundTag data, int duration, - boolean isFuel) { + boolean isFuel, + @NotNull GTRecipeCategory recipeCategory) { this(recipeType, null, inputs, outputs, tickInputs, tickOutputs, inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics, - conditions, ingredientActions, data, duration, isFuel); + conditions, ingredientActions, data, duration, isFuel, recipeCategory); } public GTRecipe(GTRecipeType recipeType, @@ -98,7 +101,8 @@ public GTRecipe(GTRecipeType recipeType, List ingredientActions, @NotNull CompoundTag data, int duration, - boolean isFuel) { + boolean isFuel, + @NotNull GTRecipeCategory recipeCategory) { this.recipeType = recipeType; this.id = id; @@ -117,6 +121,7 @@ public GTRecipe(GTRecipeType recipeType, this.data = data; this.duration = duration; this.isFuel = isFuel; + this.recipeCategory = recipeCategory; } public Map, List> copyContents(Map, List> contents, @@ -142,7 +147,8 @@ public GTRecipe copy() { copyContents(tickInputs, null), copyContents(tickOutputs, null), new HashMap<>(inputChanceLogics), new HashMap<>(outputChanceLogics), new HashMap<>(tickInputChanceLogics), new HashMap<>(tickOutputChanceLogics), - new ArrayList<>(conditions), new ArrayList<>(ingredientActions), data, duration, isFuel); + new ArrayList<>(conditions), new ArrayList<>(ingredientActions), data, duration, isFuel, + recipeCategory); } public GTRecipe copy(ContentModifier modifier) { @@ -156,7 +162,7 @@ public GTRecipe copy(ContentModifier modifier, boolean modifyDuration) { new HashMap<>(inputChanceLogics), new HashMap<>(outputChanceLogics), new HashMap<>(tickInputChanceLogics), new HashMap<>(tickOutputChanceLogics), new ArrayList<>(conditions), - new ArrayList<>(ingredientActions), data, duration, isFuel); + new ArrayList<>(ingredientActions), data, duration, isFuel, recipeCategory); if (modifyDuration) { copied.duration = modifier.apply(this.duration).intValue(); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java index 1450800669..c2725b197b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.registry.GTRegistries; @@ -138,11 +139,15 @@ public GTRecipe fromNetwork(@NotNull ResourceLocation id, @NotNull FriendlyByteB data = new CompoundTag(); } boolean isFuel = buf.readBoolean(); + ResourceLocation categoryLoc = buf.readResourceLocation(); + GTRecipeType type = (GTRecipeType) BuiltInRegistries.RECIPE_TYPE.get(recipeType); + GTRecipeCategory category = GTRegistries.RECIPE_CATEGORIES.get(categoryLoc); + GTRecipe recipe = new GTRecipe(type, id, inputs, outputs, tickInputs, tickOutputs, inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics, - conditions, ingredientActions, data, duration, isFuel); + conditions, ingredientActions, data, duration, isFuel, category); // a little special piece of code for loading all the research entries into the recipe type's list on the // client. @@ -184,6 +189,7 @@ public void toNetwork(FriendlyByteBuf buf, GTRecipe recipe) { } buf.writeNbt(recipe.data); buf.writeBoolean(recipe.isFuel); + buf.writeResourceLocation(recipe.recipeCategory.getResourceLocation()); } private static Codec makeCodec(boolean isKubeLoaded) { @@ -206,14 +212,15 @@ private static Codec makeCodec(boolean isKubeLoaded) { RecipeCondition.CODEC.listOf().optionalFieldOf("recipeConditions", List.of()).forGetter(val -> val.conditions), CompoundTag.CODEC.optionalFieldOf("data", new CompoundTag()).forGetter(val -> val.data), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("duration").forGetter(val -> val.duration), - Codec.BOOL.optionalFieldOf("isFuel", false).forGetter(val -> val.isFuel)) + Codec.BOOL.optionalFieldOf("isFuel", false).forGetter(val -> val.isFuel), + GTRegistries.RECIPE_CATEGORIES.codec().fieldOf("category").forGetter(val -> val.recipeCategory)) .apply(instance, (type, inputs, outputs, tickInputs, tickOutputs, inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics, - conditions, data, duration, isFuel) -> + conditions, data, duration, isFuel, recipeCategory) -> new GTRecipe(type, inputs, outputs, tickInputs, tickOutputs, inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics, - conditions, List.of(), data, duration, isFuel))); + conditions, List.of(), data, duration, isFuel, recipeCategory))); } else { return RecordCodecBuilder.create(instance -> instance.group( GTRegistries.RECIPE_TYPES.codec().fieldOf("type").forGetter(val -> val.recipeType), @@ -233,7 +240,8 @@ private static Codec makeCodec(boolean isKubeLoaded) { KJSCallWrapper.INGREDIENT_ACTION_CODEC.optionalFieldOf("kubejs:actions", List.of()).forGetter(val -> (List) val.ingredientActions), CompoundTag.CODEC.optionalFieldOf("data", new CompoundTag()).forGetter(val -> val.data), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("duration").forGetter(val -> val.duration), - Codec.BOOL.optionalFieldOf("isFuel", false).forGetter(val -> val.isFuel)) + Codec.BOOL.optionalFieldOf("isFuel", false).forGetter(val -> val.isFuel), + GTRegistries.RECIPE_CATEGORIES.codec().fieldOf("category").forGetter(val -> val.recipeCategory)) .apply(instance, GTRecipe::new)); } // @formatter:on diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java index d986c87c85..029a871fc9 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.capability.recipe.*; import com.gregtechceu.gtceu.api.data.chemical.material.stack.UnificationEntry; import com.gregtechceu.gtceu.api.gui.SteamTexture; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.chance.boost.ChanceBoostFunction; import com.gregtechceu.gtceu.api.recipe.lookup.GTRecipeLookup; import com.gregtechceu.gtceu.api.recipe.ui.GTRecipeTypeUI; @@ -91,6 +92,8 @@ public class GTRecipeType implements RecipeType { protected boolean hasResearchSlot; @Getter protected final Map, List> proxyRecipes; + @Getter + private final Map> recipeByCategory = new Object2ObjectOpenHashMap<>(); private CompoundTag customUICache; @Getter private final GTRecipeLookup lookup = new GTRecipeLookup(this); @@ -108,6 +111,8 @@ public GTRecipeType(ResourceLocation registryName, String group, RecipeType.. this.registryName = registryName; this.group = group; recipeBuilder = new GTRecipeBuilder(registryName, this); + recipeBuilder.category( + GTRecipeCategory.of(GTCEu.MOD_ID, registryName.getPath(), registryName.toLanguageKey(), this)); // must be linked to stop json contents from shuffling Map, List> map = new Object2ObjectLinkedOpenHashMap<>(); for (RecipeType proxyRecipe : proxyRecipes) { @@ -336,6 +341,11 @@ public GTRecipe toGTrecipe(ResourceLocation id, Recipe recipe) { return recipes; } + @NotNull + public Map> getRecipesByCategory() { + return Collections.unmodifiableMap(recipeByCategory); + } + public interface ICustomRecipeLogic { /** diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/category/GTRecipeCategory.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/category/GTRecipeCategory.java new file mode 100644 index 0000000000..9e55886d66 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/category/GTRecipeCategory.java @@ -0,0 +1,82 @@ +package com.gregtechceu.gtceu.api.recipe.category; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.registry.GTRegistries; + +import net.minecraft.resources.ResourceLocation; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +import javax.annotation.Nullable; + +public class GTRecipeCategory { + + private static final Map categories = new Object2ObjectOpenHashMap<>(); + + @Getter + private final String modid; + @Getter + private final String name; + @Getter + private final String uniqueID; + @Getter + private final String translation; + @Getter + private final GTRecipeType recipeType; + @Nullable + @Getter + private Object icon = null; + @Getter + private ResourceLocation resourceLocation; + + public static GTRecipeCategory of(@NotNull String modID, @NotNull String categoryName, + @NotNull String translationKey, @NotNull GTRecipeType recipeType) { + return categories.computeIfAbsent(categoryName, + (k) -> new GTRecipeCategory(modID, categoryName, translationKey, recipeType)); + } + + public static GTRecipeCategory of(@NotNull GTRecipeType recipeType) { + return of(GTCEu.MOD_ID, recipeType.registryName.getPath(), recipeType.registryName.toLanguageKey(), recipeType); + } + + private GTRecipeCategory(@NotNull String modID, @NotNull String categoryName, @NotNull String translationKey, + @NotNull GTRecipeType recipeType) { + this.modid = modID; + this.name = categoryName; + this.uniqueID = modID + ":" + this.name; + this.translation = translationKey; + this.recipeType = recipeType; + this.resourceLocation = new ResourceLocation(modID, categoryName); + GTRegistries.RECIPE_CATEGORIES.register(resourceLocation, this); + } + + public GTRecipeCategory setIcon(@Nullable Object icon) { + this.icon = icon; + return this; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + + GTRecipeCategory that = (GTRecipeCategory) obj; + + return getUniqueID().equals(that.getUniqueID()); + } + + @Override + public int hashCode() { + return getUniqueID().hashCode(); + } + + @Override + public String toString() { + return "GTRecipeCategory{" + uniqueID + "}"; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index 82f45c7484..0560801307 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.capability.recipe.*; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; import com.gregtechceu.gtceu.common.data.GTRecipeTypes; @@ -451,6 +452,7 @@ protected List> fromHolder(@NotNull IRecipeCapabilit public void removeAllRecipes() { this.lookup.getNodes().clear(); this.lookup.getSpecialNodes().clear(); + this.recipeType.getRecipeByCategory().clear(); } /** @@ -463,6 +465,10 @@ public boolean addRecipe(GTRecipe recipe) { if (recipe == null) { return false; } + if (recipe.recipeCategory == null) { + recipe.recipeCategory = GTRecipeCategory.of(GTCEu.MOD_ID, recipe.recipeType.registryName.getPath(), + recipe.recipeType.registryName.toLanguageKey(), recipe.recipeType); + } // Add combustion fuels to the Powerless Jetpack if (recipe.getType() == GTRecipeTypes.COMBUSTION_GENERATOR_FUELS) { Content content = recipe.getInputContents(FluidRecipeCapability.CAP).get(0); @@ -470,7 +476,15 @@ public boolean addRecipe(GTRecipe recipe) { PowerlessJetpack.FUELS.put(fluid, recipe.duration); } List> items = fromRecipe(recipe); - return recurseIngredientTreeAdd(recipe, items, lookup, 0, 0); + if (recurseIngredientTreeAdd(recipe, items, lookup, 0, 0)) { + recipeType.getRecipeByCategory().compute(recipe.recipeCategory, (k, v) -> { + if (v == null) v = new ArrayList<>(); + v.add(recipe); + return v; + }); + return true; + } + return false; } /** diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ui/GTRecipeTypeUI.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ui/GTRecipeTypeUI.java index 5587306ee6..eeaee0dab5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ui/GTRecipeTypeUI.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ui/GTRecipeTypeUI.java @@ -14,9 +14,9 @@ import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.recipe.RecipeCondition; -import com.gregtechceu.gtceu.integration.emi.recipe.GTRecipeTypeEmiCategory; -import com.gregtechceu.gtceu.integration.jei.recipe.GTRecipeTypeCategory; -import com.gregtechceu.gtceu.integration.rei.recipe.GTRecipeTypeDisplayCategory; +import com.gregtechceu.gtceu.integration.emi.recipe.GTRecipeEMICategory; +import com.gregtechceu.gtceu.integration.jei.recipe.GTRecipeJEICategory; +import com.gregtechceu.gtceu.integration.rei.recipe.GTRecipeREICategory; import com.lowdragmc.lowdraglib.LDLib; import com.lowdragmc.lowdraglib.Platform; @@ -247,15 +247,17 @@ public IEditableUI createEditableUITemplate(final boo widget.getSize().width, widget.getSize().height, IGuiTexture.EMPTY, cd -> { if (cd.isRemote) { if (LDLib.isReiLoaded()) { - ViewSearchBuilder.builder() - .addCategory(GTRecipeTypeDisplayCategory.CATEGORIES.apply(recipeType)) - .open(); + recipeType.getRecipesByCategory().keySet() + .forEach(e -> ViewSearchBuilder.builder() + .addCategory(GTRecipeREICategory.CATEGORIES.apply(e)).open()); } else if (LDLib.isJeiLoaded()) { JEIPlugin.jeiRuntime.getRecipesGui() - .showTypes(List.of(GTRecipeTypeCategory.TYPES.apply(recipeType))); + .showTypes(new ArrayList<>(recipeType.getRecipesByCategory().keySet() + .stream().map(GTRecipeJEICategory.TYPES).toList())); } else if (LDLib.isEmiLoaded()) { - EmiApi.displayRecipeCategory( - GTRecipeTypeEmiCategory.CATEGORIES.apply(recipeType)); + recipeType.getRecipesByCategory().keySet() + .forEach(e -> EmiApi + .displayRecipeCategory(GTRecipeEMICategory.getCategoryFor(e))); } } }).setHoverTooltips("gtceu.recipe_type.show_recipes")); diff --git a/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java b/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java index 570ed47518..be7b13bd64 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java +++ b/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java @@ -10,6 +10,7 @@ import com.gregtechceu.gtceu.api.data.worldgen.bedrockore.BedrockOreDefinition; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; import com.gregtechceu.gtceu.api.registry.registrate.CompassNode; @@ -47,6 +48,8 @@ public final class GTRegistries { public static final GTRegistry.String ELEMENTS = new GTRegistry.String<>(GTCEu.id("element")); public static final GTRegistry.RL RECIPE_TYPES = new GTRegistry.RL<>(GTCEu.id("recipe_type")); + public static final GTRegistry.RL RECIPE_CATEGORIES = new GTRegistry.RL<>( + GTCEu.id("recipe_category")); public static final GTRegistry.RL COVERS = new GTRegistry.RL<>(GTCEu.id("cover")); public static final GTRegistry.RL MACHINES = new GTRegistry.RL<>(GTCEu.id("machine")); diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeCategories.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeCategories.java new file mode 100644 index 0000000000..23b1594372 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeCategories.java @@ -0,0 +1,28 @@ +package com.gregtechceu.gtceu.common.data; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.gui.GuiTextures; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; + +public class GTRecipeCategories { + + public static final GTRecipeCategory ARC_FURNACE_RECYCLING = GTRecipeCategory + .of(GTCEu.MOD_ID, "arc_furnace_recycling", + "gtceu.recipe.category.arc_furnace_recycling", + GTRecipeTypes.ARC_FURNACE_RECIPES) + .setIcon(GuiTextures.ARC_FURNACE_RECYCLING_CATEGORY); + + public static final GTRecipeCategory MACERATOR_RECYCLING = GTRecipeCategory + .of(GTCEu.MOD_ID, "macerator_recycling", + "gtceu.recipe.category.macerator_recycling", + GTRecipeTypes.MACERATOR_RECIPES) + .setIcon(GuiTextures.MACERATOR_RECYCLING_CATEGORY); + + public static final GTRecipeCategory EXTRACTOR_RECYCLING = GTRecipeCategory + .of(GTCEu.MOD_ID, "extractor_recycling", + "gtceu.recipe.category.extractor_recycling", + GTRecipeTypes.EXTRACTOR_RECIPES) + .setIcon(GuiTextures.EXTRACTOR_RECYCLING_CATEGORY); + + private GTRecipeCategories() {} +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeTypes.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeTypes.java index c36498308b..642b068bf8 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeTypes.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeTypes.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; import com.gregtechceu.gtceu.api.gui.widget.TankWidget; import com.gregtechceu.gtceu.api.recipe.*; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; import com.gregtechceu.gtceu.api.registry.GTRegistries; @@ -68,6 +69,7 @@ public class GTRecipeTypes { static { GTRegistries.RECIPE_TYPES.unfreeze(); + GTRegistries.RECIPE_CATEGORIES.unfreeze(); } ////////////////////////////////////// @@ -80,7 +82,8 @@ public class GTRecipeTypes { // remove the * 12 if SteamBoilerMachine:240 is uncommented var duration = (builder.duration / 12 / 80); // copied for large boiler if (duration > 0) { - GTRecipeTypes.LARGE_BOILER_RECIPES.copyFrom(builder).duration(duration).save(provider); + GTRecipeTypes.LARGE_BOILER_RECIPES.copyFrom(builder).duration(duration) + .category(GTRecipeCategory.of(GTRecipeTypes.LARGE_BOILER_RECIPES)).save(provider); } }) .setMaxTooltips(1) @@ -195,6 +198,7 @@ public class GTRecipeTypes { .setSound(GTValues.FOOLS.get() ? GTSoundEntries.SCIENCE : GTSoundEntries.CHEMICAL) .setMaxTooltips(4) .onRecipeBuild((recipeBuilder, provider) -> GTRecipeTypes.LARGE_CHEMICAL_RECIPES.copyFrom(recipeBuilder) + .category(GTRecipeCategory.of(GTRecipeTypes.LARGE_CHEMICAL_RECIPES)) .save(provider)); public final static GTRecipeType COMPRESSOR_RECIPES = register("compressor", ELECTRIC).setMaxIOSize(1, 1, 0, 0) @@ -709,6 +713,7 @@ public static void init() { CREATE_MIXER_RECIPES.copyFrom(builder) .duration(Math.max((builder.duration / 2), 1)) .rpm(64) + .category(GTRecipeCategory.of(CREATE_MIXER_RECIPES)) .save(provider); }); } @@ -717,6 +722,7 @@ public static void init() { } ModLoader.get().postEvent(new GTCEuAPI.RegisterEvent<>(GTRegistries.RECIPE_TYPES, GTRecipeType.class)); GTRegistries.RECIPE_TYPES.freeze(); + ModLoader.get().postEvent(new GTCEuAPI.RegisterEvent<>(GTRegistries.RECIPE_CATEGORIES, GTRecipeCategory.class)); GTRegistries.register(BuiltInRegistries.RECIPE_SERIALIZER, GTCEu.id("machine"), GTRecipeSerializer.SERIALIZER); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeTurbineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeTurbineMachine.java index f9bcb9dee0..88329d7a6e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeTurbineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeTurbineMachine.java @@ -121,7 +121,7 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec recipe.tickInputs, recipe.tickOutputs, recipe.inputChanceLogics, recipe.outputChanceLogics, recipe.tickInputChanceLogics, recipe.tickOutputChanceLogics, recipe.conditions, recipe.ingredientActions, - recipe.data, recipe.duration, recipe.isFuel); + recipe.data, recipe.duration, recipe.isFuel, recipe.recipeCategory); result.init(-eut, recipe.duration, 1, params.getOcAmount()); diff --git a/src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java b/src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java index c6d7acd271..873df52956 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java +++ b/src/main/java/com/gregtechceu/gtceu/data/lang/ItemLang.java @@ -22,6 +22,12 @@ private static void initGeneratedNames(RegistrateLangProvider provider) { for (var recipeType : GTRegistries.RECIPE_TYPES) { provider.add(recipeType.registryName.toLanguageKey(), toEnglishName(recipeType.registryName.getPath())); } + + // Recipe Categories + provider.add("gtceu.recipe.category.arc_furnace_recycling", "Plasma Scrapping"); + provider.add("gtceu.recipe.category.macerator_recycling", "Part Grinding"); + provider.add("gtceu.recipe.category.extractor_recycling", "Scrap Remelting"); + // TagPrefix for (TagPrefix tagPrefix : TagPrefix.values()) { provider.add(tagPrefix.getUnlocalizedName(), tagPrefix.langValue); diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java index 127426551c..b208b075c1 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.multiblock.CleanroomType; import com.gregtechceu.gtceu.api.recipe.*; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; @@ -98,6 +99,7 @@ public class GTRecipeBuilder { public int tierChanceBoost = 0; @Setter public boolean isFuel = false; + public GTRecipeCategory recipeCategory; @Setter public BiConsumer> onSave; @Getter @@ -107,6 +109,7 @@ public class GTRecipeBuilder { public GTRecipeBuilder(ResourceLocation id, GTRecipeType recipeType) { this.id = id; this.recipeType = recipeType; + this.recipeCategory = GTRecipeCategory.of(recipeType); } public GTRecipeBuilder(GTRecipe toCopy, GTRecipeType recipeType) { @@ -124,6 +127,7 @@ public GTRecipeBuilder(GTRecipe toCopy, GTRecipeType recipeType) { this.data = toCopy.data.copy(); this.duration = toCopy.duration; this.isFuel = toCopy.isFuel; + this.recipeCategory = toCopy.recipeCategory; } public static GTRecipeBuilder of(ResourceLocation id, GTRecipeType recipeType) { @@ -1065,6 +1069,11 @@ public GTRecipeBuilder stationResearch(UnaryOperator consumer) { this.recipeType.addDataStickEntry(entry.getResearchId(), buildRawRecipe()); } } + + if (recipeType != null) { + if (recipeCategory == null) { + GTCEu.LOGGER.error("Recipes must have a category", new IllegalArgumentException()); + } else if (recipeCategory.getRecipeType() != this.recipeType) { + GTCEu.LOGGER.error("Cannot apply Category with incompatible RecipeType", + new IllegalArgumentException()); + } + } + consumer.accept(build()); } public GTRecipe buildRawRecipe() { - return new GTRecipe(recipeType, id.withPrefix(recipeType.registryName.getPath() + "/"), + var recipe = new GTRecipe(recipeType, id.withPrefix(recipeType.registryName.getPath() + "/"), input, output, tickInput, tickOutput, inputChanceLogic, outputChanceLogic, tickInputChanceLogic, tickOutputChanceLogic, - conditions, List.of(), data, duration, isFuel); + conditions, List.of(), data, duration, isFuel, recipeCategory); + return recipe; } ////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/RecyclingRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/RecyclingRecipes.java index d5f92a683c..084beb7417 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/RecyclingRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/RecyclingRecipes.java @@ -11,6 +11,7 @@ import com.gregtechceu.gtceu.api.data.chemical.material.stack.UnificationEntry; import com.gregtechceu.gtceu.api.data.tag.TagPrefix; import com.gregtechceu.gtceu.common.data.GTMaterials; +import com.gregtechceu.gtceu.common.data.GTRecipeCategories; import com.gregtechceu.gtceu.common.data.GTRecipeTypes; import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; import com.gregtechceu.gtceu.utils.GTUtil; @@ -125,7 +126,8 @@ private static void registerMaceratorRecycling(Consumer provider GTRecipeBuilder builder = GTRecipeTypes.MACERATOR_RECIPES.recipeBuilder("macerate_" + itemPath.getPath()) .outputItems(outputs.toArray(ItemStack[]::new)) .duration(calculateDuration(outputs)) - .EUt(2L * multiplier); + .EUt(2L * multiplier) + .category(GTRecipeCategories.MACERATOR_RECYCLING); if (inputTag == null) { builder.inputItems(input.copy()); } else { @@ -164,7 +166,8 @@ private static void registerExtractorRecycling(Consumer provider GTRecipeBuilder builder = GTRecipeTypes.EXTRACTOR_RECIPES.recipeBuilder("extract_" + itemPath.getPath()) .outputFluids(m.getFluid((int) (ms.amount() * L / M))) .duration((int) Math.max(1, ms.amount() * ms.material().getMass() / M)) - .EUt((long) GTValues.VA[GTValues.LV] * multiplier); + .EUt((long) GTValues.VA[GTValues.LV] * multiplier) + .category(GTRecipeCategories.EXTRACTOR_RECYCLING); if (inputTag == null) { builder.inputItems(input.copy()); } else { @@ -201,7 +204,8 @@ private static void registerExtractorRecycling(Consumer provider .recipeBuilder("extract_" + itemPath.getPath()) .outputFluids(fluidMs.material().getFluid((int) (fluidMs.amount() * L / M))) .duration((int) duration) - .EUt((long) GTValues.VA[GTValues.LV] * multiplier); + .EUt((long) GTValues.VA[GTValues.LV] * multiplier) + .category(GTRecipeCategories.EXTRACTOR_RECYCLING); if (inputTag == null) { extractorBuilder.inputItems(input.copy()); @@ -248,6 +252,11 @@ private static void registerArcRecycling(Consumer provider, Item } else { builder.inputItems(inputTag); } + + if (ms.material().hasFlag(IS_MAGNETIC) || + ms.material() == ms.material().getProperty(PropertyKey.INGOT).getArcSmeltingInto()) { + builder.category(GTRecipeCategories.ARC_FURNACE_RECYCLING); + } builder.save(provider); } return; @@ -282,9 +291,29 @@ private static void registerArcRecycling(Consumer provider, Item builder.inputItems(inputTag); } + if (needsRecyclingCategory(prefix, ms, outputs)) { + builder.category(GTRecipeCategories.ARC_FURNACE_RECYCLING); + } + builder.save(provider); } + private static boolean needsRecyclingCategory(@Nullable TagPrefix prefix, @Nullable MaterialStack inputStack, + @NotNull List outputs) { + if (prefix == TagPrefix.nugget || prefix == TagPrefix.ingot || prefix == TagPrefix.block) { + if (outputs.size() == 1) { + UnificationEntry entry = ChemicalHelper.getUnificationEntry(outputs.get(0).getItem()); + if (entry != null && inputStack != null) { + Material mat = inputStack.material(); + if (mat.hasFlag(IS_MAGNETIC) && mat.hasProperty(PropertyKey.INGOT)) { + return mat.getProperty(PropertyKey.INGOT).getArcSmeltingInto() != entry.material; + } + } + } + } + return true; + } + private static MaterialStack getArcSmeltingResult(MaterialStack materialStack) { Material material = materialStack.material(); long amount = materialStack.amount(); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/emi/GTEMIPlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/emi/GTEMIPlugin.java index ac6add6ce7..a88d433fc3 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/emi/GTEMIPlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/emi/GTEMIPlugin.java @@ -4,7 +4,9 @@ import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.common.data.GTMachines; +import com.gregtechceu.gtceu.common.data.GTRecipeTypes; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.integration.emi.multipage.MultiblockInfoEmiCategory; import com.gregtechceu.gtceu.integration.emi.oreprocessing.GTOreProcessingEmiCategory; @@ -13,7 +15,7 @@ import com.gregtechceu.gtceu.integration.emi.orevein.GTOreVeinEmiCategory; import com.gregtechceu.gtceu.integration.emi.recipe.Ae2PatternTerminalHandler; import com.gregtechceu.gtceu.integration.emi.recipe.GTEmiRecipeHandler; -import com.gregtechceu.gtceu.integration.emi.recipe.GTRecipeTypeEmiCategory; +import com.gregtechceu.gtceu.integration.emi.recipe.GTRecipeEMICategory; import com.lowdragmc.lowdraglib.LDLib; import com.lowdragmc.lowdraglib.Platform; @@ -50,7 +52,9 @@ public void register(EmiRegistry registry) { for (RecipeType recipeType : BuiltInRegistries.RECIPE_TYPE) { if (recipeType instanceof GTRecipeType gtRecipeType) { if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { - registry.addCategory(GTRecipeTypeEmiCategory.CATEGORIES.apply(gtRecipeType)); + for (GTRecipeCategory category : gtRecipeType.getRecipesByCategory().keySet()) { + registry.addCategory(new GTRecipeEMICategory(gtRecipeType, category)); + } } } } @@ -65,7 +69,7 @@ public void register(EmiRegistry registry) { try { MultiblockInfoEmiCategory.registerDisplays(registry); } catch (NullPointerException ignored) {} - GTRecipeTypeEmiCategory.registerDisplays(registry); + GTRecipeEMICategory.registerDisplays(registry); if (!ConfigHolder.INSTANCE.compat.hideOreProcessingDiagrams) GTOreProcessingEmiCategory.registerDisplays(registry); GTOreVeinEmiCategory.registerDisplays(registry); @@ -73,7 +77,7 @@ public void register(EmiRegistry registry) { if (ConfigHolder.INSTANCE.machines.doBedrockOres) GTBedrockOreEmiCategory.registerDisplays(registry); // workstations - GTRecipeTypeEmiCategory.registerWorkStations(registry); + GTRecipeEMICategory.registerWorkStations(registry); if (!ConfigHolder.INSTANCE.compat.hideOreProcessingDiagrams) GTOreProcessingEmiCategory.registerWorkStations(registry); GTOreVeinEmiCategory.registerWorkStations(registry); @@ -91,5 +95,7 @@ public void register(EmiRegistry registry) { EmiStack.of(GTMachines.STEAM_FURNACE.right().asStack())); registry.addWorkstation(VanillaEmiRecipeCategories.SMELTING, EmiStack.of(GTMachines.STEAM_OVEN.asStack())); registry.addWorkstation(VanillaEmiRecipeCategories.SMELTING, EmiStack.of(GTMachines.MULTI_SMELTER.asStack())); + registry.addWorkstation(GTRecipeEMICategory.getCategoryFor(GTRecipeCategory.of(GTRecipeTypes.CHEMICAL_RECIPES)), + EmiStack.of(GTMachines.LARGE_CHEMICAL_REACTOR.asStack())); } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTEmiRecipe.java b/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTEmiRecipe.java index 6a97f1abc8..07ee39688c 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTEmiRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTEmiRecipe.java @@ -13,10 +13,10 @@ public class GTEmiRecipe extends ModularEmiRecipe { - final GTRecipeTypeEmiCategory category; + final GTRecipeEMICategory category; final GTRecipe recipe; - public GTEmiRecipe(GTRecipeTypeEmiCategory category, GTRecipe recipe) { + public GTEmiRecipe(GTRecipeEMICategory category, GTRecipe recipe) { super(() -> new GTRecipeWidget(recipe)); this.category = category; this.recipe = recipe; diff --git a/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeEMICategory.java b/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeEMICategory.java new file mode 100644 index 0000000000..0dfa76ac27 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeEMICategory.java @@ -0,0 +1,116 @@ +package com.gregtechceu.gtceu.integration.emi.recipe; + +import com.gregtechceu.gtceu.api.machine.MachineDefinition; +import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; +import com.gregtechceu.gtceu.api.registry.GTRegistries; + +import com.lowdragmc.lowdraglib.Platform; +import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; + +import net.minecraft.Util; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.RecipeType; + +import dev.emi.emi.api.EmiRegistry; +import dev.emi.emi.api.recipe.EmiRecipeCategory; +import dev.emi.emi.api.render.EmiRenderable; +import dev.emi.emi.api.render.EmiTexture; +import dev.emi.emi.api.stack.EmiStack; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +public class GTRecipeEMICategory extends EmiRecipeCategory { + + public static final Function> CATEGORIES = Util + .memoize(category1 -> new ArrayList<>()); + public final GTRecipeType recipeType; + + private final GTRecipeCategory category; + private static final Map gtCategories = new Object2ObjectOpenHashMap<>(); + private static final Map, List> recipeTypeCategories = new Object2ObjectOpenHashMap<>(); + + public GTRecipeEMICategory(GTRecipeType recipeType, @NotNull GTRecipeCategory category) { + super(recipeType.registryName, getDrawable(category), getDrawable(category)); + this.recipeType = recipeType; + this.category = category; + gtCategories.put(category, this); + recipeTypeCategories.compute(recipeType, (k, v) -> { + if (v == null) v = new ArrayList<>(); + v.add(this); + return v; + }); + } + + public static EmiRenderable getDrawable(GTRecipeCategory category) { + if (category.getIcon() instanceof ResourceTexture tex) { + return new EmiTexture(tex.imageLocation, 0, 0, 16, 16, + (int) tex.imageWidth, (int) tex.imageHeight, (int) tex.imageWidth, (int) tex.imageHeight); + } else if (category.getRecipeType().getIconSupplier() != null) + return EmiStack.of(category.getRecipeType().getIconSupplier().get()); + else + return EmiStack.of(Items.BARRIER); + } + + public static void registerDisplays(EmiRegistry registry) { + for (RecipeType recipeType : BuiltInRegistries.RECIPE_TYPE) { + if (recipeType instanceof GTRecipeType gtRecipeType) { + if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { + for (Map.Entry> entry : gtRecipeType.getRecipesByCategory() + .entrySet()) { + entry.getValue().stream() + .map(recipe -> new GTEmiRecipe(gtCategories.get(entry.getKey()), recipe)) + .forEach(registry::addRecipe); + + if (gtRecipeType.isScanner()) { + List scannerRecipes = gtRecipeType.getRepresentativeRecipes(); + if (!scannerRecipes.isEmpty()) { + scannerRecipes.stream() + .map(recipe -> new GTEmiRecipe(gtCategories.get(entry.getKey()), recipe)) + .forEach(registry::addRecipe); + } + } + } + } + } + } + } + + public static void registerWorkStations(EmiRegistry registry) { + for (GTRecipeType gtRecipeType : GTRegistries.RECIPE_TYPES) { + if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { + for (MachineDefinition machine : GTRegistries.MACHINES) { + if (machine.getRecipeTypes() != null) { + for (GTRecipeType type : machine.getRecipeTypes()) { + for (GTRecipeCategory category : type.getRecipeByCategory().keySet()) { + var emiCategory = GTRecipeEMICategory.getCategoryFor(category); + if (emiCategory != null) { + if (type == gtRecipeType) { + registry.addWorkstation(emiCategory, EmiStack.of(machine.asStack())); + } + } + } + } + } + } + } + } + } + + public static GTRecipeEMICategory getCategoryFor(GTRecipeCategory category) { + return gtCategories.get(category); + } + + @Override + public Component getName() { + return Component.translatable(category.getTranslation()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeTypeEmiCategory.java b/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeTypeEmiCategory.java deleted file mode 100644 index aa18621599..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeTypeEmiCategory.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.gregtechceu.gtceu.integration.emi.recipe; - -import com.gregtechceu.gtceu.api.machine.MachineDefinition; -import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.GTRecipeType; -import com.gregtechceu.gtceu.api.registry.GTRegistries; - -import com.lowdragmc.lowdraglib.Platform; - -import net.minecraft.Util; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.network.chat.Component; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.crafting.RecipeType; - -import dev.emi.emi.api.EmiRegistry; -import dev.emi.emi.api.recipe.EmiRecipeCategory; -import dev.emi.emi.api.stack.EmiStack; - -import java.util.List; -import java.util.function.Function; - -public class GTRecipeTypeEmiCategory extends EmiRecipeCategory { - - public static final Function CATEGORIES = Util - .memoize(GTRecipeTypeEmiCategory::new); - public final GTRecipeType recipeType; - - public GTRecipeTypeEmiCategory(GTRecipeType recipeType) { - super(recipeType.registryName, recipeType.getIconSupplier() != null ? - EmiStack.of(recipeType.getIconSupplier().get()) : EmiStack.of(Items.BARRIER)); - this.recipeType = recipeType; - } - - public static void registerDisplays(EmiRegistry registry) { - for (RecipeType recipeType : BuiltInRegistries.RECIPE_TYPE) { - if (recipeType instanceof GTRecipeType gtRecipeType) { - if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { - registry.getRecipeManager().getAllRecipesFor(gtRecipeType).stream() - .map(recipe -> new GTEmiRecipe(CATEGORIES.apply(gtRecipeType), recipe)) - .forEach(registry::addRecipe); - - if (gtRecipeType.isScanner()) { - List scannerRecipes = gtRecipeType.getRepresentativeRecipes(); - if (!scannerRecipes.isEmpty()) { - scannerRecipes.stream() - .map(recipe -> new GTEmiRecipe(CATEGORIES.apply(gtRecipeType), recipe)) - .forEach(registry::addRecipe); - } - } - } - } - } - } - - public static void registerWorkStations(EmiRegistry registry) { - for (GTRecipeType gtRecipeType : GTRegistries.RECIPE_TYPES) { - if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { - for (MachineDefinition machine : GTRegistries.MACHINES) { - if (machine.getRecipeTypes() != null) { - for (GTRecipeType type : machine.getRecipeTypes()) { - if (type == gtRecipeType) { - registry.addWorkstation(GTRecipeTypeEmiCategory.CATEGORIES.apply(gtRecipeType), - EmiStack.of(machine.asStack())); - } - } - } - } - } - } - } - - @Override - public Component getName() { - return Component.translatable(recipeType.registryName.toLanguageKey()); - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jei/GTJEIPlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/jei/GTJEIPlugin.java index 5bac1d295f..3136428c83 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jei/GTJEIPlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jei/GTJEIPlugin.java @@ -3,14 +3,16 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.common.data.GTMachines; +import com.gregtechceu.gtceu.common.data.GTRecipeTypes; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.integration.jei.multipage.MultiblockInfoCategory; import com.gregtechceu.gtceu.integration.jei.oreprocessing.GTOreProcessingInfoCategory; import com.gregtechceu.gtceu.integration.jei.orevein.GTBedrockFluidInfoCategory; import com.gregtechceu.gtceu.integration.jei.orevein.GTBedrockOreInfoCategory; import com.gregtechceu.gtceu.integration.jei.orevein.GTOreVeinInfoCategory; -import com.gregtechceu.gtceu.integration.jei.recipe.GTRecipeTypeCategory; +import com.gregtechceu.gtceu.integration.jei.recipe.GTRecipeJEICategory; import com.lowdragmc.lowdraglib.LDLib; import com.lowdragmc.lowdraglib.Platform; @@ -59,7 +61,9 @@ public void registerCategories(@NotNull IRecipeCategoryRegistration registry) { for (RecipeType recipeType : BuiltInRegistries.RECIPE_TYPE) { if (recipeType instanceof GTRecipeType gtRecipeType) { if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { - registry.addRecipeCategories(new GTRecipeTypeCategory(jeiHelpers, gtRecipeType)); + for (GTRecipeCategory category : gtRecipeType.getRecipesByCategory().keySet()) { + registry.addRecipeCategories(new GTRecipeJEICategory(jeiHelpers, gtRecipeType, category)); + } } } } @@ -68,7 +72,7 @@ public void registerCategories(@NotNull IRecipeCategoryRegistration registry) { @Override public void registerRecipeCatalysts(@NotNull IRecipeCatalystRegistration registration) { if (LDLib.isReiLoaded() || LDLib.isEmiLoaded()) return; - GTRecipeTypeCategory.registerRecipeCatalysts(registration); + GTRecipeJEICategory.registerRecipeCatalysts(registration); if (!ConfigHolder.INSTANCE.compat.hideOreProcessingDiagrams) GTOreProcessingInfoCategory.registerRecipeCatalysts(registration); GTOreVeinInfoCategory.registerRecipeCatalysts(registration); @@ -84,6 +88,8 @@ public void registerRecipeCatalysts(@NotNull IRecipeCatalystRegistration registr registration.addRecipeCatalyst(GTMachines.STEAM_FURNACE.right().asStack(), RecipeTypes.SMELTING); registration.addRecipeCatalyst(GTMachines.STEAM_OVEN.asStack(), RecipeTypes.SMELTING); registration.addRecipeCatalyst(GTMachines.MULTI_SMELTER.asStack(), RecipeTypes.SMELTING); + registration.addRecipeCatalyst(GTMachines.LARGE_CHEMICAL_REACTOR.asStack(), + GTRecipeJEICategory.TYPES.apply(GTRecipeCategory.of(GTRecipeTypes.CHEMICAL_RECIPES))); } @Override @@ -91,7 +97,7 @@ public void registerRecipes(@NotNull IRecipeRegistration registration) { if (LDLib.isReiLoaded() || LDLib.isEmiLoaded()) return; GTCEu.LOGGER.info("JEI register"); MultiblockInfoCategory.registerRecipes(registration); - GTRecipeTypeCategory.registerRecipes(registration); + GTRecipeJEICategory.registerRecipes(registration); if (!ConfigHolder.INSTANCE.compat.hideOreProcessingDiagrams) GTOreProcessingInfoCategory.registerRecipes(registration); GTOreVeinInfoCategory.registerRecipes(registration); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeJEICategory.java b/src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeJEICategory.java new file mode 100644 index 0000000000..3818d30a4e --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeJEICategory.java @@ -0,0 +1,147 @@ +package com.gregtechceu.gtceu.integration.jei.recipe; + +import com.gregtechceu.gtceu.api.machine.MachineDefinition; +import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; +import com.gregtechceu.gtceu.api.registry.GTRegistries; + +import com.lowdragmc.lowdraglib.Platform; +import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; +import com.lowdragmc.lowdraglib.jei.ModularUIRecipeCategory; + +import net.minecraft.Util; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Items; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import lombok.Getter; +import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.helpers.IJeiHelpers; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.registration.IRecipeCatalystRegistration; +import mezz.jei.api.registration.IRecipeRegistration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class GTRecipeJEICategory extends ModularUIRecipeCategory { + + public static final Function> TYPES = Util + .memoize(category1 -> new RecipeType<>(category1.getResourceLocation(), GTRecipeWrapper.class)); + + private final GTRecipeCategory category; + @Getter + private final IDrawable background; + @Getter + private IDrawable icon; + + private static final Map gtCategories = new Object2ObjectOpenHashMap<>(); + private static final Map, List> recipeTypeCategories = new Object2ObjectOpenHashMap<>(); + + public GTRecipeJEICategory(IJeiHelpers helpers, @NotNull GTRecipeType recipeType, + @NotNull GTRecipeCategory category) { + this.category = category; + IGuiHelper guiHelper = helpers.getGuiHelper(); + var size = recipeType.getRecipeUI().getJEISize(); + this.background = guiHelper.createBlankDrawable(size.width, size.height); + + Object icon1 = category.getIcon(); + if (icon1 instanceof ResourceTexture tex) { + this.icon = helpers.getGuiHelper() + .drawableBuilder(tex.imageLocation, 0, 0, (int) tex.imageWidth, (int) tex.imageHeight) + .setTextureSize(16, 16).build(); + } else if (recipeType.getIconSupplier() != null) { + this.icon = helpers.getGuiHelper().createDrawableItemStack(recipeType.getIconSupplier().get()); + } else { + this.icon = helpers.getGuiHelper().createDrawableItemStack(Items.BARRIER.getDefaultInstance()); + } + + gtCategories.put(category, this); + recipeTypeCategories.compute(recipeType, (k, v) -> { + if (v == null) v = new ArrayList<>(); + v.add(this); + return v; + }); + } + + @Override + @NotNull + public RecipeType getRecipeType() { + return TYPES.apply(category); + } + + @NotNull + @Override + public Component getTitle() { + return Component.translatable(category.getTranslation()); + } + + public static void registerRecipes(IRecipeRegistration registration) { + for (net.minecraft.world.item.crafting.RecipeType recipeType : BuiltInRegistries.RECIPE_TYPE) { + if (recipeType instanceof GTRecipeType gtRecipeType) { + if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { + for (Map.Entry> entry : gtRecipeType.getRecipesByCategory() + .entrySet()) { + registration.addRecipes(GTRecipeJEICategory.TYPES.apply(entry.getKey()), + entry.getValue().stream().map(GTRecipeWrapper::new).collect(Collectors.toList())); + + if (gtRecipeType.isScanner()) { + List scannerRecipes = gtRecipeType.getRepresentativeRecipes(); + if (!scannerRecipes.isEmpty()) { + registration.addRecipes(GTRecipeJEICategory.TYPES.apply(entry.getKey()), + scannerRecipes.stream() + .map(GTRecipeWrapper::new) + .collect(Collectors.toList())); + } + } + } + } + } + } + } + + public static void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { + for (GTRecipeType gtRecipeType : GTRegistries.RECIPE_TYPES) { + if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { + for (MachineDefinition machine : GTRegistries.MACHINES) { + if (machine.getRecipeTypes() != null) { + for (GTRecipeType type : machine.getRecipeTypes()) { + for (GTRecipeCategory category : type.getRecipeByCategory().keySet()) { + var jeiCategory = GTRecipeJEICategory.getCategoryFor(category); + if (jeiCategory != null) { + if (type == gtRecipeType) { + registration.addRecipeCatalyst(machine.asStack(), + GTRecipeJEICategory.TYPES.apply(jeiCategory.category)); + } + } + } + } + } + } + } + } + } + + @Override + public @Nullable ResourceLocation getRegistryName(@NotNull GTRecipeWrapper wrapper) { + return wrapper.recipe.id; + } + + public static GTRecipeJEICategory getCategoryFor(GTRecipeCategory category) { + return gtCategories.get(category); + } + + public static Collection getCategoriesFor(GTRecipeType recipeType) { + return recipeTypeCategories.get(recipeType); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeTypeCategory.java b/src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeTypeCategory.java deleted file mode 100644 index 73e2472263..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeTypeCategory.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.gregtechceu.gtceu.integration.jei.recipe; - -import com.gregtechceu.gtceu.api.machine.MachineDefinition; -import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.GTRecipeType; -import com.gregtechceu.gtceu.api.registry.GTRegistries; - -import com.lowdragmc.lowdraglib.Platform; -import com.lowdragmc.lowdraglib.jei.ModularUIRecipeCategory; - -import net.minecraft.Util; -import net.minecraft.client.Minecraft; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Items; - -import lombok.Getter; -import mezz.jei.api.gui.drawable.IDrawable; -import mezz.jei.api.helpers.IGuiHelper; -import mezz.jei.api.helpers.IJeiHelpers; -import mezz.jei.api.recipe.RecipeType; -import mezz.jei.api.registration.IRecipeCatalystRegistration; -import mezz.jei.api.registration.IRecipeRegistration; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class GTRecipeTypeCategory extends ModularUIRecipeCategory { - - public static final Function> TYPES = Util - .memoize(recipeMap -> new RecipeType<>(recipeMap.registryName, GTRecipeWrapper.class)); - - private final GTRecipeType recipeType; - @Getter - private final IDrawable background; - @Getter - private final IDrawable icon; - - public GTRecipeTypeCategory(IJeiHelpers helpers, GTRecipeType recipeType) { - this.recipeType = recipeType; - IGuiHelper guiHelper = helpers.getGuiHelper(); - var size = recipeType.getRecipeUI().getJEISize(); - this.background = guiHelper.createBlankDrawable(size.width, size.height); - if (recipeType.getIconSupplier() != null) { - icon = helpers.getGuiHelper().createDrawableItemStack(recipeType.getIconSupplier().get()); - } else { - icon = helpers.getGuiHelper().createDrawableItemStack(Items.BARRIER.getDefaultInstance()); - } - } - - @Override - @NotNull - public RecipeType getRecipeType() { - return TYPES.apply(recipeType); - } - - @NotNull - @Override - public Component getTitle() { - return Component.translatable(recipeType.registryName.toLanguageKey()); - } - - public static void registerRecipes(IRecipeRegistration registration) { - for (net.minecraft.world.item.crafting.RecipeType recipeType : BuiltInRegistries.RECIPE_TYPE) { - if (recipeType instanceof GTRecipeType gtRecipeType) { - if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { - registration.addRecipes(GTRecipeTypeCategory.TYPES.apply(gtRecipeType), - Minecraft.getInstance().getConnection().getRecipeManager().getAllRecipesFor(gtRecipeType) - .stream() - .map(GTRecipeWrapper::new) - .collect(Collectors.toList())); - - if (gtRecipeType.isScanner()) { - List scannerRecipes = gtRecipeType.getRepresentativeRecipes(); - if (!scannerRecipes.isEmpty()) { - registration.addRecipes(GTRecipeTypeCategory.TYPES.apply(gtRecipeType), - scannerRecipes.stream() - .map(GTRecipeWrapper::new) - .collect(Collectors.toList())); - } - } - } - } - } - } - - public static void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { - for (GTRecipeType gtRecipeType : GTRegistries.RECIPE_TYPES) { - if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { - for (MachineDefinition machine : GTRegistries.MACHINES) { - if (machine.getRecipeTypes() != null) { - for (GTRecipeType type : machine.getRecipeTypes()) { - if (type == gtRecipeType) { - registration.addRecipeCatalyst(machine.asStack(), - GTRecipeTypeCategory.TYPES.apply(gtRecipeType)); - } - } - } - } - } - } - } - - @Override - public @Nullable ResourceLocation getRegistryName(@NotNull GTRecipeWrapper wrapper) { - return wrapper.recipe.id; - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/rei/GTREIPlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/rei/GTREIPlugin.java index 3b7c0d2a6b..31422b153a 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/rei/GTREIPlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/rei/GTREIPlugin.java @@ -5,15 +5,17 @@ import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.common.data.GTBlocks; import com.gregtechceu.gtceu.common.data.GTMachines; +import com.gregtechceu.gtceu.common.data.GTRecipeTypes; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.integration.rei.multipage.MultiblockInfoDisplayCategory; import com.gregtechceu.gtceu.integration.rei.oreprocessing.GTOreProcessingDisplayCategory; import com.gregtechceu.gtceu.integration.rei.orevein.GTBedrockFluidDisplayCategory; import com.gregtechceu.gtceu.integration.rei.orevein.GTBedrockOreDisplayCategory; import com.gregtechceu.gtceu.integration.rei.orevein.GTOreVeinDisplayCategory; -import com.gregtechceu.gtceu.integration.rei.recipe.GTRecipeTypeDisplayCategory; +import com.gregtechceu.gtceu.integration.rei.recipe.GTRecipeREICategory; import com.lowdragmc.lowdraglib.Platform; @@ -56,12 +58,14 @@ public void registerCategories(CategoryRegistry registry) { for (RecipeType recipeType : BuiltInRegistries.RECIPE_TYPE) { if (recipeType instanceof GTRecipeType gtRecipeType) { if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { - registry.add(new GTRecipeTypeDisplayCategory(gtRecipeType)); + for (GTRecipeCategory category : gtRecipeType.getRecipesByCategory().keySet()) { + registry.add(new GTRecipeREICategory(gtRecipeType, category)); + } } } } // workstations - GTRecipeTypeDisplayCategory.registerWorkStations(registry); + GTRecipeREICategory.registerWorkStations(registry); if (!ConfigHolder.INSTANCE.compat.hideOreProcessingDiagrams) GTOreProcessingDisplayCategory.registerWorkstations(registry); GTOreVeinDisplayCategory.registerWorkstations(registry); @@ -77,11 +81,14 @@ public void registerCategories(CategoryRegistry registry) { registry.addWorkstations(SMELTING, EntryStacks.of(GTMachines.STEAM_FURNACE.right().asStack())); registry.addWorkstations(SMELTING, EntryStacks.of(GTMachines.STEAM_OVEN.asStack())); registry.addWorkstations(SMELTING, EntryStacks.of(GTMachines.MULTI_SMELTER.asStack())); + registry.addWorkstations( + GTRecipeREICategory.CATEGORIES.apply(GTRecipeCategory.of(GTRecipeTypes.CHEMICAL_RECIPES)), + EntryStacks.of(GTMachines.LARGE_CHEMICAL_REACTOR.asStack())); } @Override public void registerDisplays(DisplayRegistry registry) { - GTRecipeTypeDisplayCategory.registerDisplays(registry); + GTRecipeREICategory.registerDisplays(registry); MultiblockInfoDisplayCategory.registerDisplays(registry); if (!ConfigHolder.INSTANCE.compat.hideOreProcessingDiagrams) GTOreProcessingDisplayCategory.registerDisplays(registry); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeDisplay.java b/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeDisplay.java index f7acc0429f..207f887bbb 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeDisplay.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeDisplay.java @@ -8,14 +8,19 @@ import net.minecraft.resources.ResourceLocation; +import lombok.Getter; + import java.util.Optional; public class GTRecipeDisplay extends ModularDisplay { + @Getter + private final GTRecipeREICategory category; private final GTRecipe recipe; - public GTRecipeDisplay(GTRecipe recipe) { - super(() -> new GTRecipeWidget(recipe), GTRecipeTypeDisplayCategory.CATEGORIES.apply(recipe.recipeType)); + public GTRecipeDisplay(GTRecipeREICategory category, GTRecipe recipe) { + super(() -> new GTRecipeWidget(recipe), GTRecipeREICategory.CATEGORIES.apply(recipe.recipeCategory)); + this.category = category; this.recipe = recipe; } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeTypeDisplayCategory.java b/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeREICategory.java similarity index 51% rename from src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeTypeDisplayCategory.java rename to src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeREICategory.java index ff659d661f..626d963420 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeTypeDisplayCategory.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeREICategory.java @@ -3,10 +3,12 @@ import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.lowdragmc.lowdraglib.Platform; import com.lowdragmc.lowdraglib.gui.texture.ItemStackTexture; +import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; import com.lowdragmc.lowdraglib.rei.IGui2Renderer; import com.lowdragmc.lowdraglib.rei.ModularUIDisplayCategory; import com.lowdragmc.lowdraglib.utils.Size; @@ -17,6 +19,7 @@ import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.RecipeType; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import me.shedaniel.rei.api.client.gui.Renderer; import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; @@ -25,34 +28,50 @@ import me.shedaniel.rei.api.common.util.EntryStacks; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.function.Function; -public class GTRecipeTypeDisplayCategory extends ModularUIDisplayCategory { +public class GTRecipeREICategory extends ModularUIDisplayCategory { - public static final Function> CATEGORIES = Util - .memoize(recipeType -> CategoryIdentifier.of(recipeType.registryName)); + public static final Function> CATEGORIES = Util + .memoize(recipeCategory -> CategoryIdentifier.of(recipeCategory.getResourceLocation())); private final GTRecipeType recipeType; + + private final GTRecipeCategory category; + private static final Map gtCategories = new Object2ObjectOpenHashMap<>(); + private static final Map, List> recipeTypeCategories = new Object2ObjectOpenHashMap<>(); @Getter private final Renderer icon; @Getter private final Size size; - public GTRecipeTypeDisplayCategory(GTRecipeType recipeType) { + public GTRecipeREICategory(GTRecipeType recipeType, @NotNull GTRecipeCategory category) { this.recipeType = recipeType; + this.category = category; var size = recipeType.getRecipeUI().getJEISize(); this.size = new Size(size.width + 8, size.height + 8); - if (recipeType.getIconSupplier() != null) { + if (category.getIcon() instanceof ResourceTexture tex) { + icon = IGui2Renderer.toDrawable(tex); + } else if (recipeType.getIconSupplier() != null) { icon = IGui2Renderer.toDrawable(new ItemStackTexture(recipeType.getIconSupplier().get())); } else { icon = IGui2Renderer.toDrawable(new ItemStackTexture(Items.BARRIER.getDefaultInstance())); } + + gtCategories.put(category, this); + recipeTypeCategories.compute(recipeType, (k, v) -> { + if (v == null) v = new ArrayList<>(); + v.add(this); + return v; + }); } @Override public CategoryIdentifier getCategoryIdentifier() { - return CATEGORIES.apply(recipeType); + return CATEGORIES.apply(category); } @Override @@ -75,14 +94,18 @@ public static void registerDisplays(DisplayRegistry registry) { for (RecipeType recipeType : BuiltInRegistries.RECIPE_TYPE) { if (recipeType instanceof GTRecipeType gtRecipeType) { if (Platform.isDevEnv() || gtRecipeType.getRecipeUI().isXEIVisible()) { - registry.registerRecipeFiller(GTRecipe.class, gtRecipeType, GTRecipeDisplay::new); - - if (gtRecipeType.isScanner()) { - List scannerRecipes = gtRecipeType.getRepresentativeRecipes(); - if (!scannerRecipes.isEmpty()) { - scannerRecipes.stream() - .map(GTRecipeDisplay::new) - .forEach(registry::add); + for (Map.Entry> entry : gtRecipeType.getRecipesByCategory() + .entrySet()) { + registry.registerRecipeFiller(GTRecipe.class, gtRecipeType, + recipe -> new GTRecipeDisplay(gtCategories.get(entry.getKey()), recipe)); + + if (gtRecipeType.isScanner()) { + List scannerRecipes = gtRecipeType.getRepresentativeRecipes(); + if (!scannerRecipes.isEmpty()) { + scannerRecipes.stream() + .map(recipe -> new GTRecipeDisplay(gtCategories.get(entry.getKey()), recipe)) + .forEach(registry::add); + } } } } @@ -96,9 +119,14 @@ public static void registerWorkStations(CategoryRegistry registry) { for (MachineDefinition machine : GTRegistries.MACHINES) { if (machine.getRecipeTypes() != null) { for (GTRecipeType type : machine.getRecipeTypes()) { - if (type == gtRecipeType) { - registry.addWorkstations(GTRecipeTypeDisplayCategory.CATEGORIES.apply(gtRecipeType), - EntryStacks.of(machine.asStack())); + for (GTRecipeCategory category : type.getRecipeByCategory().keySet()) { + var reiCategory = GTRecipeREICategory.getCategoryFor(category); + if (reiCategory != null) { + if (type == gtRecipeType) { + registry.addWorkstations(GTRecipeREICategory.CATEGORIES.apply(category), + EntryStacks.of(machine.asStack())); + } + } } } } @@ -106,4 +134,8 @@ public static void registerWorkStations(CategoryRegistry registry) { } } } + + public static GTRecipeREICategory getCategoryFor(GTRecipeCategory category) { + return gtCategories.get(category); + } } diff --git a/src/main/resources/assets/gtceu/textures/gui/icon/arc_furnace_recycling.png b/src/main/resources/assets/gtceu/textures/gui/icon/arc_furnace_recycling.png new file mode 100644 index 0000000000000000000000000000000000000000..3e76683be0e7d801ce840790e7afc945d4eb12c9 GIT binary patch literal 553 zcmV+^0@nSBP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TC`SPeBwYJc{tfNeGT| z+#QZhYyyn5y1l#I*`4*7pa)#nWq})_QmG{3m0;~cCX-=2IM_w#kgk@TkUT*kl0DCp zew>7WVX@>g*H(j*9|(AISDO(DgP{==Y>KJeF9ZSNBt)kK`5_g>A%a}99^CXM5a^JQ zg_%h z!hcCbRXT1%$qt}htD|-6N1suU6x>NH&rXDr&X3mF+0GI>Su1|&wbGm<2coCA_3<(U zR7M6+d0kUsI9Quz<&`|3bG?QLtjYWSy$X5NC{qj#?HfJiPmTF+zv_yoTDe;tI% r0h|B;01jnXNoGw=04e|g00;m8000000Mb*F00000NkvXXu0mjfW2)o$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gtceu/textures/gui/icon/extractor_recycling.png b/src/main/resources/assets/gtceu/textures/gui/icon/extractor_recycling.png new file mode 100644 index 0000000000000000000000000000000000000000..74f4669ad83c7ae6e084342b284b267e1a9305a8 GIT binary patch literal 410 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1engQ%yAV~B-+?<7ON!wv$j|D_lie{$&+FQ!8U!7^pJS9~8e%#L0(ZL-8?4xez9!c|{5 zIc_~!!yUTigw~6{**#VgAv!VlC%$x>ba!e&vHzC83cGq-jx_*aY!)c8^(JkxxA8MJ_G4j=}BOTm*tl&7no%Q~loCICGyqv!wt literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gtceu/textures/gui/icon/macerator_recycling.png b/src/main/resources/assets/gtceu/textures/gui/icon/macerator_recycling.png new file mode 100644 index 0000000000000000000000000000000000000000..a741e627e9828feb2633b84c546a04511b600540 GIT binary patch literal 308 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enaJ{FCV~B-+??i8*BMKZYi?i21_{)Dx^p3UD zO}=N(kVTD59ZHV3LJcQA=$2S;^9f_UZ^Qp}g6bacmp{x)6DwMG zaNgqAH}Zqdw51=)x^K42_=@KtQPpbuv>4{IuluG>^qI5qnd!^4PLoSN{+yWP!n;6q t(I;j}39l0z4E(-8r}L#oc&7RKGH3zW96$^Lmx3pQC{I^Emvv4FO#rO%a}EFi literal 0 HcmV?d00001