Skip to content

Commit 6dc308b

Browse files
authored
Add recipe handler bypass system (#3562)
1 parent ec17193 commit 6dc308b

7 files changed

Lines changed: 84 additions & 12 deletions

File tree

src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,4 +443,10 @@ public interface ICustomParallel {
443443
*/
444444
int limitFluidParallel(GTRecipe recipe, int multiplier, boolean tick);
445445
}
446+
447+
// Fluids should be respected for distinct checks
448+
@Override
449+
public boolean shouldBypassDistinct() {
450+
return false;
451+
}
446452
}

src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,4 +565,10 @@ public interface ICustomParallel {
565565
*/
566566
int limitItemParallel(GTRecipe recipe, int multiplier, boolean tick);
567567
}
568+
569+
// Items should be respected for distinct checks
570+
@Override
571+
public boolean shouldBypassDistinct() {
572+
return false;
573+
}
568574
}

src/main/java/com/gregtechceu/gtceu/api/capability/recipe/RecipeCapability.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,13 @@ public Object2IntMap<T> makeChanceCache() {
213213
public boolean isTickSlot(int index, IO io, GTRecipe recipe) {
214214
return index >= (io == IO.IN ? recipe.getInputContents(this) : recipe.getOutputContents(this)).size();
215215
}
216+
217+
/**
218+
* Should this RecipeCapability bypass distinct checks?
219+
* E.g. should this bus be added to all recipe checks on a multi, even distinct ones like ME Pattern buffers.
220+
* for example: energy hatches, soul hatches, other "global per multi" hatches.
221+
*/
222+
public boolean shouldBypassDistinct() {
223+
return true;
224+
}
216225
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.gregtechceu.gtceu.api.machine.trait;
22

33
public enum RecipeHandlerGroupDistinctness implements RecipeHandlerGroup {
4-
BUS_DISTINCT
4+
BUS_DISTINCT,
5+
BYPASS_DISTINCT
56
}

src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,20 @@ public boolean hasCapability(RecipeCapability<?> cap) {
143143
return getHandlerMap().getOrDefault(cap, Collections.emptyList());
144144
}
145145

146+
public @NotNull Set<RecipeCapability<?>> getCapabilities() {
147+
return getHandlerMap().keySet();
148+
}
149+
150+
/**
151+
* @return whether any of the capabilities in this RHL should bypass distinct checks
152+
*/
153+
public boolean doesCapabilityBypassDistinct() {
154+
for (var capability : getCapabilities()) {
155+
if (capability.shouldBypassDistinct()) return true;
156+
}
157+
return false;
158+
}
159+
146160
public boolean isValid(IO extIO) {
147161
if (this == NO_DATA || handlerIO == IO.NONE) return false;
148162
return (extIO == IO.BOTH || handlerIO == IO.BOTH || extIO == handlerIO);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,11 @@ public static Map<RecipeCapability<?>, List<Content>> doTrim(Map<RecipeCapabilit
348348

349349
public static void addToRecipeHandlerMap(RecipeHandlerGroup key, RecipeHandlerList handler,
350350
Map<RecipeHandlerGroup, List<RecipeHandlerList>> map) {
351+
// If they should bypass this system, add them to the BYPASS_DISTINCT group.
352+
if (handler.doesCapabilityBypassDistinct()) {
353+
map.computeIfAbsent(RecipeHandlerGroupDistinctness.BYPASS_DISTINCT, $ -> new ArrayList<>()).add(handler);
354+
return;
355+
}
351356
// Add undyed RHL's to every group that's not distinct, and also the undyed group itself.
352357
if (key.equals(RecipeHandlerGroupColor.UNDYED)) {
353358
for (var entry : map.entrySet()) {

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

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,14 @@ private void fillContentMatchList(Map<RecipeCapability<?>, List<Content>> entrie
105105
}
106106

107107
private ActionResult handleContents() {
108-
var result = handleContentsInternal(io);
109-
return result;
110-
}
111-
112-
private ActionResult handleContentsInternal(IO capIO) {
113108
if (recipeContents.isEmpty()) return ActionResult.SUCCESS;
114-
if (!capabilityProxies.containsKey(capIO)) {
109+
if (!capabilityProxies.containsKey(io)) {
115110
return ActionResult.FAIL_NO_CAPABILITIES;
116111
}
117112

118-
List<RecipeHandlerList> handlers = capabilityProxies.getOrDefault(capIO, Collections.emptyList());
113+
List<RecipeHandlerList> handlers = capabilityProxies.getOrDefault(io, Collections.emptyList());
119114
// Only sort for non-tick outputs
120-
if (!isTick && capIO.support(IO.OUT)) {
115+
if (!isTick && io.support(IO.OUT)) {
121116
handlers.sort(RecipeHandlerList.COMPARATOR.reversed());
122117
}
123118

@@ -128,46 +123,82 @@ private ActionResult handleContentsInternal(IO capIO) {
128123
// Specifically check distinct handlers first
129124
for (RecipeHandlerList handler : handlerGroups.getOrDefault(RecipeHandlerGroupDistinctness.BUS_DISTINCT,
130125
Collections.emptyList())) {
126+
// Handle the contents of this handler and also all the bypassed handlers
131127
var res = handler.handleRecipe(io, recipe, searchRecipeContents, true);
128+
for (RecipeHandlerList bypass_handler : handlerGroups.getOrDefault(
129+
RecipeHandlerGroupDistinctness.BYPASS_DISTINCT,
130+
Collections.emptyList())) {
131+
res = bypass_handler.handleRecipe(io, recipe, res, true);
132+
}
132133
if (res.isEmpty()) {
133134
if (!simulated) {
135+
// Actually consume the contents of this handler and also all the bypassed handlers
134136
handler.handleRecipe(io, recipe, recipeContents, false);
137+
for (RecipeHandlerList bypass_handler : handlerGroups.getOrDefault(
138+
RecipeHandlerGroupDistinctness.BYPASS_DISTINCT,
139+
Collections.emptyList())) {
140+
res = bypass_handler.handleRecipe(io, recipe, res, false);
141+
}
135142
}
136143
recipeContents.clear();
137144
return ActionResult.SUCCESS;
138145
}
139146
}
140147

141-
// Check the others
148+
// Check the other groups. For every group, try consuming the ingredients,
149+
// see if it succeeds.
142150
for (Map.Entry<RecipeHandlerGroup, List<RecipeHandlerList>> handlerListEntry : handlerGroups.entrySet()) {
143151
if (handlerListEntry.getKey() == RecipeHandlerGroupDistinctness.BUS_DISTINCT) continue;
144152

145153
// List to keep track of the remaining items for this RecipeHandlerGroup
146154
Map<RecipeCapability<?>, List<Object>> copiedRecipeContents = searchRecipeContents;
147155
boolean found = false;
156+
148157
for (RecipeHandlerList handler : handlerListEntry.getValue()) {
149158
copiedRecipeContents = handler.handleRecipe(io, recipe, copiedRecipeContents, true);
150159
if (copiedRecipeContents.isEmpty()) {
151160
found = true;
152161
break;
153162
}
154163
}
164+
for (RecipeHandlerList bypass_handler : handlerGroups.getOrDefault(
165+
RecipeHandlerGroupDistinctness.BYPASS_DISTINCT,
166+
Collections.emptyList())) {
167+
copiedRecipeContents = bypass_handler.handleRecipe(io, recipe, copiedRecipeContents, true);
168+
if (copiedRecipeContents.isEmpty()) {
169+
found = true;
170+
break;
171+
}
172+
}
173+
155174
if (!found) continue;
156175
if (simulated) return ActionResult.SUCCESS;
157-
// Start actually removing items, keep track of the remaining items for this RecipeHandlerGroup
176+
// Start actually removing items.
177+
// Keep track of the remaining items for this RecipeHandlerGroup
158178
copiedRecipeContents = recipeContents;
179+
// First go through the handlers of the group
159180
for (RecipeHandlerList handler : handlerListEntry.getValue()) {
160181
copiedRecipeContents = handler.handleRecipe(io, recipe, copiedRecipeContents, false);
161182
if (copiedRecipeContents.isEmpty()) {
162183
recipeContents.clear();
163184
return ActionResult.SUCCESS;
164185
}
165186
}
187+
// Then go through the handlers that bypass the distinctness system and empty those
188+
for (RecipeHandlerList bypass_handler : handlerGroups.getOrDefault(
189+
RecipeHandlerGroupDistinctness.BYPASS_DISTINCT,
190+
Collections.emptyList())) {
191+
copiedRecipeContents = bypass_handler.handleRecipe(io, recipe, copiedRecipeContents, false);
192+
if (copiedRecipeContents.isEmpty()) {
193+
recipeContents.clear();
194+
return ActionResult.SUCCESS;
195+
}
196+
}
166197
}
167198

168199
for (var entry : recipeContents.entrySet()) {
169200
if (entry.getValue() != null && !entry.getValue().isEmpty()) {
170-
return ActionResult.fail(null, entry.getKey(), capIO);
201+
return ActionResult.fail(null, entry.getKey(), io);
171202
}
172203
}
173204

0 commit comments

Comments
 (0)