Skip to content

Commit 7d7bf54

Browse files
authored
Recipe Categories (GregTechCEu#2274)
1 parent d868b95 commit 7d7bf54

30 files changed

+613
-252
lines changed

settings.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ dependencyResolutionManagement {
2525

2626
// Mod Dependencies Versions
2727
// Common
28-
def jeiVersion = "15.12.1.46"
29-
def reiVersion = "12.1.725"
28+
def jeiVersion = "15.20.0.105"
29+
def reiVersion = "12.1.785"
3030
def emiVersion = "1.1.13"
3131
def ae2Version = "15.0.18"
3232
def kjsVersion = "2001.6.4-build.120"
@@ -62,7 +62,7 @@ dependencyResolutionManagement {
6262
def vineFlowerVersion = "1.+"
6363
def macheteVersion = "1.+"
6464
def configurationVersion = "2.2.0"
65-
def ldLibVersion = "1.0.30.a"
65+
def ldLibVersion = "1.0.31"
6666
def mixinextrasVersion = "0.2.0"
6767
def shimmerVersion = "0.2.4"
6868
def lombokPluginVersion = "8.7.1"

src/generated/resources/assets/gtceu/lang/en_ud.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3855,6 +3855,9 @@
38553855
"gtceu.primitive_blast_furnace": "ǝɔɐuɹnℲ ʇsɐןᗺ ǝʌıʇıɯıɹԀ",
38563856
"gtceu.pyrolyse_oven": "uǝʌO ǝsʎןoɹʎԀ",
38573857
"gtceu.recipe.amperage": "%s :ǝbɐɹǝdɯⱯ",
3858+
"gtceu.recipe.category.arc_furnace_recycling": "buıddɐɹɔS ɐɯsɐןԀ",
3859+
"gtceu.recipe.category.extractor_recycling": "buıʇןǝɯǝᴚ dɐɹɔS",
3860+
"gtceu.recipe.category.macerator_recycling": "buıpuıɹ⅁ ʇɹɐԀ",
38583861
"gtceu.recipe.chance": "ɹǝıʇ/%s+ %s :ǝɔuɐɥƆ",
38593862
"gtceu.recipe.cleanroom": "%s sǝɹınbǝᴚ",
38603863
"gtceu.recipe.cleanroom.display_name": "ɯooɹuɐǝןƆ",

src/generated/resources/assets/gtceu/lang/en_us.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3855,6 +3855,9 @@
38553855
"gtceu.primitive_blast_furnace": "Primitive Blast Furnace",
38563856
"gtceu.pyrolyse_oven": "Pyrolyse Oven",
38573857
"gtceu.recipe.amperage": "Amperage: %s",
3858+
"gtceu.recipe.category.arc_furnace_recycling": "Plasma Scrapping",
3859+
"gtceu.recipe.category.extractor_recycling": "Scrap Remelting",
3860+
"gtceu.recipe.category.macerator_recycling": "Part Grinding",
38583861
"gtceu.recipe.chance": "Chance: %s +%s/tier",
38593862
"gtceu.recipe.cleanroom": "Requires %s",
38603863
"gtceu.recipe.cleanroom.display_name": "Cleanroom",

src/main/java/com/gregtechceu/gtceu/api/gui/GuiTextures.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.lowdragmc.lowdraglib.gui.texture.ResourceBorderTexture;
44
import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture;
55

6+
import net.minecraft.resources.ResourceLocation;
7+
68
import lombok.val;
79

810
/**
@@ -486,6 +488,13 @@ public class GuiTextures {
486488
public static final ResourceTexture MULTIBLOCK_CATEGORY = new ResourceTexture(
487489
"gtceu:textures/gui/icon/coke_oven.png");
488490

491+
public static final ResourceTexture ARC_FURNACE_RECYCLING_CATEGORY = new ResourceTexture(
492+
new ResourceLocation("gtceu:textures/gui/icon/arc_furnace_recycling.png"), 0, 0, 16, 16);
493+
public static final ResourceTexture MACERATOR_RECYCLING_CATEGORY = new ResourceTexture(
494+
new ResourceLocation("gtceu:textures/gui/icon/macerator_recycling.png"), 0, 0, 16, 16);
495+
public static final ResourceTexture EXTRACTOR_RECYCLING_CATEGORY = new ResourceTexture(
496+
new ResourceLocation("gtceu:textures/gui/icon/extractor_recycling.png"), 0, 0, 16, 16);
497+
489498
// Covers
490499
public static final ResourceTexture COVER_MACHINE_CONTROLLER = new ResourceTexture(
491500
"gtceu:textures/items/metaitems/cover.controller.png");

src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.gregtechceu.gtceu.GTCEu;
44
import com.gregtechceu.gtceu.api.capability.recipe.*;
55
import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic;
6+
import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory;
67
import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic;
78
import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType;
89
import com.gregtechceu.gtceu.api.recipe.content.Content;
@@ -62,6 +63,7 @@ public class GTRecipe implements net.minecraft.world.item.crafting.Recipe<Contai
6263
public int duration;
6364
public int parallels = 1;
6465
public int ocTier = 0;
66+
public GTRecipeCategory recipeCategory = null;
6567
@Getter
6668
public boolean isFuel;
6769

@@ -78,10 +80,11 @@ public GTRecipe(GTRecipeType recipeType,
7880
List<?> ingredientActions,
7981
@NotNull CompoundTag data,
8082
int duration,
81-
boolean isFuel) {
83+
boolean isFuel,
84+
@NotNull GTRecipeCategory recipeCategory) {
8285
this(recipeType, null, inputs, outputs, tickInputs, tickOutputs,
8386
inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics,
84-
conditions, ingredientActions, data, duration, isFuel);
87+
conditions, ingredientActions, data, duration, isFuel, recipeCategory);
8588
}
8689

8790
public GTRecipe(GTRecipeType recipeType,
@@ -98,7 +101,8 @@ public GTRecipe(GTRecipeType recipeType,
98101
List<?> ingredientActions,
99102
@NotNull CompoundTag data,
100103
int duration,
101-
boolean isFuel) {
104+
boolean isFuel,
105+
@NotNull GTRecipeCategory recipeCategory) {
102106
this.recipeType = recipeType;
103107
this.id = id;
104108

@@ -117,6 +121,7 @@ public GTRecipe(GTRecipeType recipeType,
117121
this.data = data;
118122
this.duration = duration;
119123
this.isFuel = isFuel;
124+
this.recipeCategory = recipeCategory;
120125
}
121126

122127
public Map<RecipeCapability<?>, List<Content>> copyContents(Map<RecipeCapability<?>, List<Content>> contents,
@@ -142,7 +147,8 @@ public GTRecipe copy() {
142147
copyContents(tickInputs, null), copyContents(tickOutputs, null),
143148
new HashMap<>(inputChanceLogics), new HashMap<>(outputChanceLogics),
144149
new HashMap<>(tickInputChanceLogics), new HashMap<>(tickOutputChanceLogics),
145-
new ArrayList<>(conditions), new ArrayList<>(ingredientActions), data, duration, isFuel);
150+
new ArrayList<>(conditions), new ArrayList<>(ingredientActions), data, duration, isFuel,
151+
recipeCategory);
146152
}
147153

148154
public GTRecipe copy(ContentModifier modifier) {
@@ -156,7 +162,7 @@ public GTRecipe copy(ContentModifier modifier, boolean modifyDuration) {
156162
new HashMap<>(inputChanceLogics), new HashMap<>(outputChanceLogics),
157163
new HashMap<>(tickInputChanceLogics), new HashMap<>(tickOutputChanceLogics),
158164
new ArrayList<>(conditions),
159-
new ArrayList<>(ingredientActions), data, duration, isFuel);
165+
new ArrayList<>(ingredientActions), data, duration, isFuel, recipeCategory);
160166
if (modifyDuration) {
161167
copied.duration = modifier.apply(this.duration).intValue();
162168
}

src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.gregtechceu.gtceu.GTCEu;
44
import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability;
5+
import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory;
56
import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic;
67
import com.gregtechceu.gtceu.api.recipe.content.Content;
78
import com.gregtechceu.gtceu.api.registry.GTRegistries;
@@ -138,11 +139,15 @@ public GTRecipe fromNetwork(@NotNull ResourceLocation id, @NotNull FriendlyByteB
138139
data = new CompoundTag();
139140
}
140141
boolean isFuel = buf.readBoolean();
142+
ResourceLocation categoryLoc = buf.readResourceLocation();
143+
141144
GTRecipeType type = (GTRecipeType) BuiltInRegistries.RECIPE_TYPE.get(recipeType);
145+
GTRecipeCategory category = GTRegistries.RECIPE_CATEGORIES.get(categoryLoc);
146+
142147
GTRecipe recipe = new GTRecipe(type, id,
143148
inputs, outputs, tickInputs, tickOutputs,
144149
inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics,
145-
conditions, ingredientActions, data, duration, isFuel);
150+
conditions, ingredientActions, data, duration, isFuel, category);
146151

147152
// a little special piece of code for loading all the research entries into the recipe type's list on the
148153
// client.
@@ -184,6 +189,7 @@ public void toNetwork(FriendlyByteBuf buf, GTRecipe recipe) {
184189
}
185190
buf.writeNbt(recipe.data);
186191
buf.writeBoolean(recipe.isFuel);
192+
buf.writeResourceLocation(recipe.recipeCategory.getResourceLocation());
187193
}
188194

189195
private static Codec<GTRecipe> makeCodec(boolean isKubeLoaded) {
@@ -206,14 +212,15 @@ private static Codec<GTRecipe> makeCodec(boolean isKubeLoaded) {
206212
RecipeCondition.CODEC.listOf().optionalFieldOf("recipeConditions", List.of()).forGetter(val -> val.conditions),
207213
CompoundTag.CODEC.optionalFieldOf("data", new CompoundTag()).forGetter(val -> val.data),
208214
ExtraCodecs.NON_NEGATIVE_INT.fieldOf("duration").forGetter(val -> val.duration),
209-
Codec.BOOL.optionalFieldOf("isFuel", false).forGetter(val -> val.isFuel))
215+
Codec.BOOL.optionalFieldOf("isFuel", false).forGetter(val -> val.isFuel),
216+
GTRegistries.RECIPE_CATEGORIES.codec().fieldOf("category").forGetter(val -> val.recipeCategory))
210217
.apply(instance, (type,
211218
inputs, outputs, tickInputs, tickOutputs,
212219
inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics,
213-
conditions, data, duration, isFuel) ->
220+
conditions, data, duration, isFuel, recipeCategory) ->
214221
new GTRecipe(type, inputs, outputs, tickInputs, tickOutputs,
215222
inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics,
216-
conditions, List.of(), data, duration, isFuel)));
223+
conditions, List.of(), data, duration, isFuel, recipeCategory)));
217224
} else {
218225
return RecordCodecBuilder.create(instance -> instance.group(
219226
GTRegistries.RECIPE_TYPES.codec().fieldOf("type").forGetter(val -> val.recipeType),
@@ -233,7 +240,8 @@ private static Codec<GTRecipe> makeCodec(boolean isKubeLoaded) {
233240
KJSCallWrapper.INGREDIENT_ACTION_CODEC.optionalFieldOf("kubejs:actions", List.of()).forGetter(val -> (List<IngredientAction>) val.ingredientActions),
234241
CompoundTag.CODEC.optionalFieldOf("data", new CompoundTag()).forGetter(val -> val.data),
235242
ExtraCodecs.NON_NEGATIVE_INT.fieldOf("duration").forGetter(val -> val.duration),
236-
Codec.BOOL.optionalFieldOf("isFuel", false).forGetter(val -> val.isFuel))
243+
Codec.BOOL.optionalFieldOf("isFuel", false).forGetter(val -> val.isFuel),
244+
GTRegistries.RECIPE_CATEGORIES.codec().fieldOf("category").forGetter(val -> val.recipeCategory))
237245
.apply(instance, GTRecipe::new));
238246
}
239247
// @formatter:on

src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.gregtechceu.gtceu.api.capability.recipe.*;
55
import com.gregtechceu.gtceu.api.data.chemical.material.stack.UnificationEntry;
66
import com.gregtechceu.gtceu.api.gui.SteamTexture;
7+
import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory;
78
import com.gregtechceu.gtceu.api.recipe.chance.boost.ChanceBoostFunction;
89
import com.gregtechceu.gtceu.api.recipe.lookup.GTRecipeLookup;
910
import com.gregtechceu.gtceu.api.recipe.ui.GTRecipeTypeUI;
@@ -91,6 +92,8 @@ public class GTRecipeType implements RecipeType<GTRecipe> {
9192
protected boolean hasResearchSlot;
9293
@Getter
9394
protected final Map<RecipeType<?>, List<GTRecipe>> proxyRecipes;
95+
@Getter
96+
private final Map<GTRecipeCategory, List<GTRecipe>> recipeByCategory = new Object2ObjectOpenHashMap<>();
9497
private CompoundTag customUICache;
9598
@Getter
9699
private final GTRecipeLookup lookup = new GTRecipeLookup(this);
@@ -108,6 +111,8 @@ public GTRecipeType(ResourceLocation registryName, String group, RecipeType<?>..
108111
this.registryName = registryName;
109112
this.group = group;
110113
recipeBuilder = new GTRecipeBuilder(registryName, this);
114+
recipeBuilder.category(
115+
GTRecipeCategory.of(GTCEu.MOD_ID, registryName.getPath(), registryName.toLanguageKey(), this));
111116
// must be linked to stop json contents from shuffling
112117
Map<RecipeType<?>, List<GTRecipe>> map = new Object2ObjectLinkedOpenHashMap<>();
113118
for (RecipeType<?> proxyRecipe : proxyRecipes) {
@@ -336,6 +341,11 @@ public GTRecipe toGTrecipe(ResourceLocation id, Recipe<?> recipe) {
336341
return recipes;
337342
}
338343

344+
@NotNull
345+
public Map<GTRecipeCategory, List<GTRecipe>> getRecipesByCategory() {
346+
return Collections.unmodifiableMap(recipeByCategory);
347+
}
348+
339349
public interface ICustomRecipeLogic {
340350

341351
/**
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.gregtechceu.gtceu.api.recipe.category;
2+
3+
import com.gregtechceu.gtceu.GTCEu;
4+
import com.gregtechceu.gtceu.api.recipe.GTRecipeType;
5+
import com.gregtechceu.gtceu.api.registry.GTRegistries;
6+
7+
import net.minecraft.resources.ResourceLocation;
8+
9+
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
10+
import lombok.Getter;
11+
import org.jetbrains.annotations.NotNull;
12+
13+
import java.util.Map;
14+
15+
import javax.annotation.Nullable;
16+
17+
public class GTRecipeCategory {
18+
19+
private static final Map<String, GTRecipeCategory> categories = new Object2ObjectOpenHashMap<>();
20+
21+
@Getter
22+
private final String modid;
23+
@Getter
24+
private final String name;
25+
@Getter
26+
private final String uniqueID;
27+
@Getter
28+
private final String translation;
29+
@Getter
30+
private final GTRecipeType recipeType;
31+
@Nullable
32+
@Getter
33+
private Object icon = null;
34+
@Getter
35+
private ResourceLocation resourceLocation;
36+
37+
public static GTRecipeCategory of(@NotNull String modID, @NotNull String categoryName,
38+
@NotNull String translationKey, @NotNull GTRecipeType recipeType) {
39+
return categories.computeIfAbsent(categoryName,
40+
(k) -> new GTRecipeCategory(modID, categoryName, translationKey, recipeType));
41+
}
42+
43+
public static GTRecipeCategory of(@NotNull GTRecipeType recipeType) {
44+
return of(GTCEu.MOD_ID, recipeType.registryName.getPath(), recipeType.registryName.toLanguageKey(), recipeType);
45+
}
46+
47+
private GTRecipeCategory(@NotNull String modID, @NotNull String categoryName, @NotNull String translationKey,
48+
@NotNull GTRecipeType recipeType) {
49+
this.modid = modID;
50+
this.name = categoryName;
51+
this.uniqueID = modID + ":" + this.name;
52+
this.translation = translationKey;
53+
this.recipeType = recipeType;
54+
this.resourceLocation = new ResourceLocation(modID, categoryName);
55+
GTRegistries.RECIPE_CATEGORIES.register(resourceLocation, this);
56+
}
57+
58+
public GTRecipeCategory setIcon(@Nullable Object icon) {
59+
this.icon = icon;
60+
return this;
61+
}
62+
63+
@Override
64+
public boolean equals(Object obj) {
65+
if (this == obj) return true;
66+
if (obj == null || getClass() != obj.getClass()) return false;
67+
68+
GTRecipeCategory that = (GTRecipeCategory) obj;
69+
70+
return getUniqueID().equals(that.getUniqueID());
71+
}
72+
73+
@Override
74+
public int hashCode() {
75+
return getUniqueID().hashCode();
76+
}
77+
78+
@Override
79+
public String toString() {
80+
return "GTRecipeCategory{" + uniqueID + "}";
81+
}
82+
}

src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.gregtechceu.gtceu.api.capability.recipe.*;
55
import com.gregtechceu.gtceu.api.recipe.GTRecipe;
66
import com.gregtechceu.gtceu.api.recipe.GTRecipeType;
7+
import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory;
78
import com.gregtechceu.gtceu.api.recipe.content.Content;
89
import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient;
910
import com.gregtechceu.gtceu.common.data.GTRecipeTypes;
@@ -451,6 +452,7 @@ protected List<List<AbstractMapIngredient>> fromHolder(@NotNull IRecipeCapabilit
451452
public void removeAllRecipes() {
452453
this.lookup.getNodes().clear();
453454
this.lookup.getSpecialNodes().clear();
455+
this.recipeType.getRecipeByCategory().clear();
454456
}
455457

456458
/**
@@ -463,14 +465,26 @@ public boolean addRecipe(GTRecipe recipe) {
463465
if (recipe == null) {
464466
return false;
465467
}
468+
if (recipe.recipeCategory == null) {
469+
recipe.recipeCategory = GTRecipeCategory.of(GTCEu.MOD_ID, recipe.recipeType.registryName.getPath(),
470+
recipe.recipeType.registryName.toLanguageKey(), recipe.recipeType);
471+
}
466472
// Add combustion fuels to the Powerless Jetpack
467473
if (recipe.getType() == GTRecipeTypes.COMBUSTION_GENERATOR_FUELS) {
468474
Content content = recipe.getInputContents(FluidRecipeCapability.CAP).get(0);
469475
FluidIngredient fluid = FluidRecipeCapability.CAP.of(content.content);
470476
PowerlessJetpack.FUELS.put(fluid, recipe.duration);
471477
}
472478
List<List<AbstractMapIngredient>> items = fromRecipe(recipe);
473-
return recurseIngredientTreeAdd(recipe, items, lookup, 0, 0);
479+
if (recurseIngredientTreeAdd(recipe, items, lookup, 0, 0)) {
480+
recipeType.getRecipeByCategory().compute(recipe.recipeCategory, (k, v) -> {
481+
if (v == null) v = new ArrayList<>();
482+
v.add(recipe);
483+
return v;
484+
});
485+
return true;
486+
}
487+
return false;
474488
}
475489

476490
/**

src/main/java/com/gregtechceu/gtceu/api/recipe/ui/GTRecipeTypeUI.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
import com.gregtechceu.gtceu.api.recipe.GTRecipe;
1515
import com.gregtechceu.gtceu.api.recipe.GTRecipeType;
1616
import com.gregtechceu.gtceu.api.recipe.RecipeCondition;
17-
import com.gregtechceu.gtceu.integration.emi.recipe.GTRecipeTypeEmiCategory;
18-
import com.gregtechceu.gtceu.integration.jei.recipe.GTRecipeTypeCategory;
19-
import com.gregtechceu.gtceu.integration.rei.recipe.GTRecipeTypeDisplayCategory;
17+
import com.gregtechceu.gtceu.integration.emi.recipe.GTRecipeEMICategory;
18+
import com.gregtechceu.gtceu.integration.jei.recipe.GTRecipeJEICategory;
19+
import com.gregtechceu.gtceu.integration.rei.recipe.GTRecipeREICategory;
2020

2121
import com.lowdragmc.lowdraglib.LDLib;
2222
import com.lowdragmc.lowdraglib.Platform;
@@ -247,15 +247,17 @@ public IEditableUI<WidgetGroup, RecipeHolder> createEditableUITemplate(final boo
247247
widget.getSize().width, widget.getSize().height, IGuiTexture.EMPTY, cd -> {
248248
if (cd.isRemote) {
249249
if (LDLib.isReiLoaded()) {
250-
ViewSearchBuilder.builder()
251-
.addCategory(GTRecipeTypeDisplayCategory.CATEGORIES.apply(recipeType))
252-
.open();
250+
recipeType.getRecipesByCategory().keySet()
251+
.forEach(e -> ViewSearchBuilder.builder()
252+
.addCategory(GTRecipeREICategory.CATEGORIES.apply(e)).open());
253253
} else if (LDLib.isJeiLoaded()) {
254254
JEIPlugin.jeiRuntime.getRecipesGui()
255-
.showTypes(List.of(GTRecipeTypeCategory.TYPES.apply(recipeType)));
255+
.showTypes(new ArrayList<>(recipeType.getRecipesByCategory().keySet()
256+
.stream().map(GTRecipeJEICategory.TYPES).toList()));
256257
} else if (LDLib.isEmiLoaded()) {
257-
EmiApi.displayRecipeCategory(
258-
GTRecipeTypeEmiCategory.CATEGORIES.apply(recipeType));
258+
recipeType.getRecipesByCategory().keySet()
259+
.forEach(e -> EmiApi
260+
.displayRecipeCategory(GTRecipeEMICategory.getCategoryFor(e)));
259261
}
260262
}
261263
}).setHoverTooltips("gtceu.recipe_type.show_recipes"));

0 commit comments

Comments
 (0)