Skip to content

Commit e0604d8

Browse files
authored
Implement voiding mode (#3924)
1 parent 6319779 commit e0604d8

File tree

13 files changed

+144
-31
lines changed

13 files changed

+144
-31
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,10 +2424,10 @@
24242424
"gtceu.gui.me_bus.auto_pull_button": "ƎW ɯoɹɟ buıןןnd ɯǝʇı ɔıʇɐɯoʇnɐ ǝןbboʇ oʇ ʞɔıןƆ",
24252425
"gtceu.gui.me_network.offline": "ɹ§ǝuıןɟɟOㄣ§ :snʇɐʇS ʞɹoʍʇǝN",
24262426
"gtceu.gui.me_network.online": "ɹ§ǝuıןuOᄅ§ :snʇɐʇS ʞɹoʍʇǝN",
2427+
"gtceu.gui.multiblock_all_voiding.0": "ǝpoW buıpıoΛ",
2428+
"gtceu.gui.multiblock_all_voiding.1": "ןןⱯ buıpıoΛㄥ§",
24272429
"gtceu.gui.multiblock_fluid_voiding.0": "ǝpoW buıpıoΛ",
24282430
"gtceu.gui.multiblock_fluid_voiding.1": "spınןℲ6§ buıpıoΛㄥ§",
2429-
"gtceu.gui.multiblock_item_fluid_voiding.0": "ǝpoW buıpıoΛ",
2430-
"gtceu.gui.multiblock_item_fluid_voiding.1": "spınןℲ6§ puɐㄥ§ sɯǝʇI9§ buıpıoΛㄥ§",
24312431
"gtceu.gui.multiblock_item_voiding.0": "ǝpoW buıpıoΛ",
24322432
"gtceu.gui.multiblock_item_voiding.1": "sɯǝʇI9§ buıpıoΛㄥ§",
24332433
"gtceu.gui.multiblock_no_voiding.0": "ǝpoW buıpıoΛ",

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,10 +2424,10 @@
24242424
"gtceu.gui.me_bus.auto_pull_button": "Click to toggle automatic item pulling from ME",
24252425
"gtceu.gui.me_network.offline": "Network Status: §4Offline§r",
24262426
"gtceu.gui.me_network.online": "Network Status: §2Online§r",
2427+
"gtceu.gui.multiblock_all_voiding.0": "Voiding Mode",
2428+
"gtceu.gui.multiblock_all_voiding.1": "§7Voiding All",
24272429
"gtceu.gui.multiblock_fluid_voiding.0": "Voiding Mode",
24282430
"gtceu.gui.multiblock_fluid_voiding.1": "§7Voiding §9Fluids",
2429-
"gtceu.gui.multiblock_item_fluid_voiding.0": "Voiding Mode",
2430-
"gtceu.gui.multiblock_item_fluid_voiding.1": "§7Voiding §6Items §7and §9Fluids",
24312431
"gtceu.gui.multiblock_item_voiding.0": "Voiding Mode",
24322432
"gtceu.gui.multiblock_item_voiding.1": "§7Voiding §6Items",
24332433
"gtceu.gui.multiblock_no_voiding.0": "Voiding Mode",

src/main/java/com/gregtechceu/gtceu/api/gui/widget/EnumSelectorWidget.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ public interface SelectableEnum {
3737
IGuiTexture getIcon();
3838
}
3939

40-
private final CycleButtonWidget buttonWidget;
40+
public final CycleButtonWidget buttonWidget;
4141

42-
private final List<T> values;
43-
private final Consumer<T> onChanged;
42+
public final List<T> values;
43+
public final Consumer<T> onChanged;
4444

45-
private int selected = 0;
45+
public int selected = 0;
4646

4747
private BiFunction<T, IGuiTexture, IGuiTexture> textureSupplier = (value, texture) -> new GuiTextureGroup(
4848
GuiTextures.VANILLA_BUTTON, texture);
@@ -85,7 +85,7 @@ public T getCurrentValue() {
8585
return values.get(selected);
8686
}
8787

88-
private IGuiTexture getTexture(int selected) {
88+
public IGuiTexture getTexture(int selected) {
8989
var selectedValue = values.get(selected);
9090
return textureSupplier.apply(selectedValue, selectedValue.getIcon());
9191
}

src/main/java/com/gregtechceu/gtceu/api/machine/MachineDefinition.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
import net.minecraft.world.phys.shapes.Shapes;
2727
import net.minecraft.world.phys.shapes.VoxelShape;
2828

29-
import it.unimi.dsi.fastutil.objects.Object2IntMap;
30-
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
29+
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
30+
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
3131
import lombok.Getter;
3232
import lombok.Setter;
3333
import lombok.experimental.Accessors;
@@ -127,7 +127,7 @@ public class MachineDefinition implements Supplier<IMachineBlock> {
127127
private EditableMachineUI editableUI;
128128
@Getter
129129
@Setter
130-
private Object2IntMap<RecipeCapability<?>> recipeOutputLimits = new Object2IntOpenHashMap<>();
130+
private Reference2IntMap<RecipeCapability<?>> recipeOutputLimits = new Reference2IntOpenHashMap<>();
131131

132132
@Getter
133133
@Setter(onMethod_ = @ApiStatus.Internal)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.gregtechceu.gtceu.api.machine.fancyconfigurator;
2+
3+
import com.gregtechceu.gtceu.api.gui.fancy.IFancyConfiguratorButton;
4+
import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget;
5+
6+
import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture;
7+
import com.lowdragmc.lowdraglib.gui.util.ClickData;
8+
9+
import net.minecraft.network.chat.Component;
10+
11+
import lombok.Setter;
12+
import lombok.experimental.Accessors;
13+
14+
import java.util.Collections;
15+
import java.util.List;
16+
import java.util.function.Consumer;
17+
import java.util.function.Function;
18+
19+
public class FancySelectorConfigurator<T extends Enum<T> & EnumSelectorWidget.SelectableEnum>
20+
implements IFancyConfiguratorButton {
21+
22+
private final EnumSelectorWidget<T> widget;
23+
24+
@Setter
25+
@Accessors(chain = true)
26+
private Function<T, List<Component>> tooltip = t -> Collections.singletonList(Component.empty());
27+
28+
public FancySelectorConfigurator(T[] values, T initialValue, Consumer<T> onChanged) {
29+
this.widget = new EnumSelectorWidget<>(0, 0, 20, 20, values, initialValue, onChanged);
30+
}
31+
32+
@Override
33+
public IGuiTexture getIcon() {
34+
return widget.getTexture(widget.selected);
35+
}
36+
37+
@Override
38+
public List<Component> getTooltips() {
39+
return this.tooltip.apply(widget.getCurrentValue());
40+
}
41+
42+
@Override
43+
public void onClick(ClickData clickData) {
44+
++widget.selected;
45+
if (widget.selected >= widget.values.size()) {
46+
widget.selected = 0;
47+
}
48+
49+
widget.buttonWidget.setIndex(widget.selected);
50+
if (widget.onChanged != null) {
51+
widget.onChanged.accept(widget.getCurrentValue());
52+
}
53+
}
54+
}
Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,81 @@
11
package com.gregtechceu.gtceu.api.machine.feature;
22

3+
import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability;
4+
import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability;
35
import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability;
6+
import com.gregtechceu.gtceu.api.gui.GuiTextures;
7+
import com.gregtechceu.gtceu.api.gui.fancy.ConfiguratorPanel;
8+
import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget;
9+
import com.gregtechceu.gtceu.api.machine.fancyconfigurator.FancySelectorConfigurator;
10+
import com.gregtechceu.gtceu.data.lang.LangHandler;
11+
12+
import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture;
413

514
import net.minecraft.util.StringRepresentable;
615

7-
import it.unimi.dsi.fastutil.objects.Object2IntMap;
16+
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
17+
import lombok.Getter;
818
import org.jetbrains.annotations.NotNull;
919

20+
import java.util.List;
21+
import java.util.function.Predicate;
22+
1023
public interface IVoidable extends IMachineFeature {
1124

1225
default boolean canVoidRecipeOutputs(RecipeCapability<?> capability) {
13-
return self().getDefinition().getRecipeOutputLimits().containsKey(capability);
26+
return getVoidingMode().canVoid(capability) ||
27+
self().getDefinition().getRecipeOutputLimits().getOrDefault(capability, -1) == 0;
1428
}
1529

16-
default Object2IntMap<RecipeCapability<?>> getOutputLimits() {
30+
default Reference2IntMap<RecipeCapability<?>> getOutputLimits() {
1731
return self().getDefinition().getRecipeOutputLimits();
1832
}
1933

20-
enum VoidingMode implements StringRepresentable {
34+
default void setVoidingMode(VoidingMode mode) {}
35+
36+
default VoidingMode getVoidingMode() {
37+
return VoidingMode.VOID_NONE;
38+
}
39+
40+
static void attachConfigurators(ConfiguratorPanel configuratorPanel, IVoidable controller) {
41+
configuratorPanel
42+
.attachConfigurators(new FancySelectorConfigurator<>(VoidingMode.VALUES, controller.getVoidingMode(),
43+
controller::setVoidingMode).setTooltip(m -> (List) LangHandler.getMultiLang(m.localeName)));
44+
}
45+
46+
enum VoidingMode implements StringRepresentable, EnumSelectorWidget.SelectableEnum {
2147

22-
VOID_NONE("gtceu.gui.multiblock_no_voiding"),
23-
VOID_ITEMS("gtceu.gui.multiblock_item_voiding"),
24-
VOID_FLUIDS("gtceu.gui.multiblock_fluid_voiding"),
25-
VOID_BOTH("gtceu.gui.multiblock_item_fluid_voiding");
48+
VOID_NONE("gtceu.gui.multiblock_no_voiding", cap -> false),
49+
VOID_ITEMS("gtceu.gui.multiblock_item_voiding", cap -> cap == ItemRecipeCapability.CAP),
50+
VOID_FLUIDS("gtceu.gui.multiblock_fluid_voiding", cap -> cap == FluidRecipeCapability.CAP),
51+
VOID_ALL("gtceu.gui.multiblock_all_voiding", cap -> true);
2652

2753
public static final VoidingMode[] VALUES = values();
2854

29-
public final String localeName;
55+
private final String localeName;
56+
@Getter
57+
private final IGuiTexture icon;
58+
private final Predicate<RecipeCapability<?>> canVoid;
3059

31-
VoidingMode(String name) {
60+
VoidingMode(String name, Predicate<RecipeCapability<?>> canVoid) {
3261
this.localeName = name;
62+
this.canVoid = canVoid;
63+
this.icon = GuiTextures.BUTTON_VOID_MULTIBLOCK.getSubTexture(0, ordinal(), 1, 0.25);
64+
}
65+
66+
public boolean canVoid(RecipeCapability<?> capability) {
67+
return canVoid.test(capability);
3368
}
3469

3570
@NotNull
3671
@Override
3772
public String getSerializedName() {
3873
return localeName;
3974
}
75+
76+
@Override
77+
public @NotNull String getTooltip() {
78+
return localeName;
79+
}
4080
}
4181
}

src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine;
1313
import com.gregtechceu.gtceu.api.machine.feature.IOverclockMachine;
1414
import com.gregtechceu.gtceu.api.machine.feature.ITieredMachine;
15+
import com.gregtechceu.gtceu.api.machine.feature.IVoidable;
1516
import com.gregtechceu.gtceu.api.machine.feature.multiblock.IDisplayUIMachine;
1617
import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart;
1718
import com.gregtechceu.gtceu.api.misc.EnergyContainerList;
@@ -157,6 +158,7 @@ public List<IFancyUIProvider> getSubTabs() {
157158

158159
@Override
159160
public void attachConfigurators(ConfiguratorPanel configuratorPanel) {
161+
IVoidable.attachConfigurators(configuratorPanel, this);
160162
if (getDefinition().getRecipeModifier() instanceof RecipeModifierList list && Arrays.stream(list.getModifiers())
161163
.anyMatch(modifier -> modifier == GTRecipeModifiers.BATCH_MODE)) {
162164
configuratorPanel.attachConfigurators(new IFancyConfiguratorButton.Toggle(

src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ public abstract class WorkableMultiblockMachine extends MultiblockControllerMach
7878
@Getter
7979
protected LongSet activeBlocks;
8080

81+
@Getter
82+
@Persisted
83+
@DescSynced
84+
protected VoidingMode voidingMode = VoidingMode.VOID_NONE;
85+
8186
public WorkableMultiblockMachine(IMachineBlockEntity holder, Object... args) {
8287
super(holder);
8388
this.recipeTypes = getDefinition().getRecipeTypes();
@@ -312,4 +317,10 @@ public GTRecipeType getRecipeType() {
312317
public void setRecipeType(GTRecipeType newType) {
313318
recipeTypes[activeRecipeType] = newType;
314319
}
320+
321+
@Override
322+
public void setVoidingMode(VoidingMode mode) {
323+
voidingMode = mode;
324+
getRecipeLogic().updateTickSubscription();
325+
}
315326
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import net.minecraftforge.fluids.FluidStack;
2222

2323
import it.unimi.dsi.fastutil.objects.Object2IntMap;
24+
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
2425
import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap;
2526
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
2627
import org.jetbrains.annotations.Contract;
@@ -281,7 +282,7 @@ public static ActionResult checkConditions(GTRecipe recipe, @NotNull RecipeLogic
281282
* Returns the recipe itself if no valid trim limits are passed
282283
*/
283284
@Contract(pure = true)
284-
public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Object2IntMap<RecipeCapability<?>> trimLimits) {
285+
public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Reference2IntMap<RecipeCapability<?>> trimLimits) {
285286
// Fast return early if no trimming desired
286287
if (trimLimits.isEmpty() || trimLimits.values().intStream().allMatch(integer -> integer == -1)) {
287288
return recipe;
@@ -307,7 +308,7 @@ public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Object2IntMap<RecipeCa
307308
*/
308309
@Contract(pure = true)
309310
public static Map<RecipeCapability<?>, List<Content>> doTrim(Map<RecipeCapability<?>, List<Content>> current,
310-
Object2IntMap<RecipeCapability<?>> trimLimits) {
311+
Reference2IntMap<RecipeCapability<?>> trimLimits) {
311312
Map<RecipeCapability<?>, List<Content>> outputs = new Reference2ObjectOpenHashMap<>(current.size());
312313

313314
for (var entry : current.entrySet()) {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.gregtechceu.gtceu.api.capability.recipe.IO;
44
import com.gregtechceu.gtceu.api.capability.recipe.IRecipeCapabilityHolder;
55
import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability;
6+
import com.gregtechceu.gtceu.api.machine.feature.IVoidable;
67
import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerGroup;
78
import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList;
89
import com.gregtechceu.gtceu.api.recipe.chance.boost.ChanceBoostFunction;
@@ -18,6 +19,7 @@
1819
import java.util.HashMap;
1920
import java.util.List;
2021
import java.util.Map;
22+
import java.util.function.Predicate;
2123

2224
import static com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerGroupDistinctness.BUS_DISTINCT;
2325
import static com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerGroupDistinctness.BYPASS_DISTINCT;
@@ -33,6 +35,7 @@ public class RecipeRunner {
3335
private final boolean simulated;
3436
private Map<RecipeCapability<?>, List<Object>> recipeContents;
3537
private final Map<RecipeCapability<?>, List<Object>> searchRecipeContents;
38+
private final Predicate<RecipeCapability<?>> outputVoid;
3639

3740
public RecipeRunner(GTRecipe recipe, IO io, boolean isTick,
3841
IRecipeCapabilityHolder holder, Map<RecipeCapability<?>, Object2IntMap<?>> chanceCaches,
@@ -45,6 +48,7 @@ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick,
4548
this.recipeContents = new Reference2ObjectOpenHashMap<>();
4649
this.searchRecipeContents = simulated ? recipeContents : new Reference2ObjectOpenHashMap<>();
4750
this.simulated = simulated;
51+
this.outputVoid = cap -> holder instanceof IVoidable voidable && voidable.canVoidRecipeOutputs(cap);
4852
}
4953

5054
@NotNull
@@ -68,6 +72,7 @@ private void fillContentMatchList(Map<RecipeCapability<?>, List<Content>> entrie
6872
for (var entry : entries.entrySet()) {
6973
RecipeCapability<?> cap = entry.getKey();
7074
if (!cap.doMatchInRecipe()) continue;
75+
if (simulated && io == IO.OUT && outputVoid.test(cap)) continue;
7176

7277
ChanceLogic logic = recipe.getChanceLogicForCapability(cap, this.io, this.isTick);
7378
List<Content> chancedContents = new ArrayList<>();

0 commit comments

Comments
 (0)