Skip to content

Commit 26e236c

Browse files
authored
Research station logic improvement (GregTechCEu#2097)
1 parent 1e2be60 commit 26e236c

File tree

20 files changed

+356
-178
lines changed

20 files changed

+356
-178
lines changed

src/main/java/gregtech/api/capability/impl/ComputationRecipeLogic.java

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController;
66
import gregtech.api.recipes.Recipe;
77
import gregtech.api.recipes.recipeproperties.ComputationProperty;
8+
import gregtech.api.recipes.recipeproperties.TotalComputationProperty;
89
import net.minecraft.nbt.NBTTagCompound;
910
import org.jetbrains.annotations.NotNull;
1011

@@ -16,8 +17,16 @@
1617
public class ComputationRecipeLogic extends MultiblockRecipeLogic {
1718

1819
private final ComputationType type;
20+
/*
21+
* Whether recipe duration should be treated as a total CWU value (so, incremented by the CWU/t used each tick),
22+
* or normally (increase by 1 for each successful draw of CWU/t). If this value is true, the logic will attempt
23+
* to draw as much CWU/t as possible to try and accelerate the computation process, and CWU/t is treated as a
24+
* minimum value instead of a static cost.
25+
*/
26+
private boolean isDurationTotalCWU;
1927
private int recipeCWUt;
2028
private boolean hasNotEnoughComputation;
29+
private int currentDrawnCWUt;
2130

2231
public ComputationRecipeLogic(RecipeMapMultiblockController metaTileEntity, ComputationType type) {
2332
super(metaTileEntity);
@@ -50,6 +59,7 @@ public boolean checkRecipe(@NotNull Recipe recipe) {
5059
protected void setupRecipe(Recipe recipe) {
5160
super.setupRecipe(recipe);
5261
this.recipeCWUt = recipe.getProperty(ComputationProperty.getInstance(), 0);
62+
this.isDurationTotalCWU = recipe.hasProperty(TotalComputationProperty.getInstance());
5363
}
5464

5565
@Override
@@ -63,15 +73,24 @@ protected void updateRecipeProgress() {
6373
drawEnergy(recipeEUt, false);
6474

6575
IOpticalComputationProvider provider = getComputationProvider();
66-
int availableCWUt = provider.requestCWUt(recipeCWUt, true);
76+
int availableCWUt = provider.requestCWUt(Integer.MAX_VALUE, true);
6777
if (availableCWUt >= recipeCWUt) {
6878
// carry on as normal
6979
this.hasNotEnoughComputation = false;
70-
provider.requestCWUt(recipeCWUt, false);
71-
if (++progressTime > maxProgressTime) {
80+
if (isDurationTotalCWU) {
81+
// draw as much CWU as possible, and increase progress by this amount
82+
currentDrawnCWUt = provider.requestCWUt(availableCWUt, false);
83+
progressTime += currentDrawnCWUt;
84+
} else {
85+
// draw only the recipe CWU/t, and increase progress by 1
86+
provider.requestCWUt(recipeCWUt, false);
87+
progressTime++;
88+
}
89+
if (progressTime > maxProgressTime) {
7290
completeRecipe();
7391
}
7492
} else {
93+
currentDrawnCWUt = 0;
7594
this.hasNotEnoughComputation = true;
7695
// only decrement progress for low CWU/t if we need a steady supply
7796
if (type == ComputationType.STEADY) {
@@ -91,13 +110,19 @@ protected void updateRecipeProgress() {
91110
protected void completeRecipe() {
92111
super.completeRecipe();
93112
this.recipeCWUt = 0;
113+
this.isDurationTotalCWU = false;
94114
this.hasNotEnoughComputation = false;
115+
this.currentDrawnCWUt = 0;
95116
}
96117

97118
public int getRecipeCWUt() {
98119
return recipeCWUt;
99120
}
100121

122+
public int getCurrentDrawnCWUt() {
123+
return isDurationTotalCWU ? currentDrawnCWUt : recipeCWUt;
124+
}
125+
101126
public boolean isHasNotEnoughComputation() {
102127
return hasNotEnoughComputation;
103128
}
@@ -108,6 +133,7 @@ public NBTTagCompound serializeNBT() {
108133
NBTTagCompound compound = super.serializeNBT();
109134
if (this.progressTime > 0) {
110135
compound.setInteger("RecipeCWUt", recipeCWUt);
136+
compound.setBoolean("IsDurationTotalCWU", isDurationTotalCWU);
111137
}
112138
return compound;
113139
}
@@ -117,9 +143,18 @@ public void deserializeNBT(@NotNull NBTTagCompound compound) {
117143
super.deserializeNBT(compound);
118144
if (this.progressTime > 0) {
119145
recipeCWUt = compound.getInteger("RecipeCWUt");
146+
isDurationTotalCWU = compound.getBoolean("IsDurationTotalCWU");
120147
}
121148
}
122149

150+
151+
/**
152+
* @return Whether TOP / WAILA should show the recipe progress as duration or as total computation.
153+
*/
154+
public boolean shouldShowDuration() {
155+
return !isDurationTotalCWU;
156+
}
157+
123158
public enum ComputationType {
124159
/**
125160
* CWU/t works like EU/t. If there is not enough, recipe reverts progress/halts

src/main/java/gregtech/api/recipes/RecipeMap.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,9 +926,12 @@ private VirtualizedRecipeMap getGroovyScriptRecipeMap() {
926926

927927
/**
928928
* This height is used to determine Y position to start drawing info on JEI.
929+
* @deprecated remove overrides, this method is no longer used in any way.
929930
*/
931+
@Deprecated
932+
@ApiStatus.ScheduledForRemoval(inVersion = "2.9")
930933
public int getPropertyListHeight(Recipe recipe) {
931-
return (recipe.getUnhiddenPropertyCount() + 3) * 10 - 3; // GTRecipeWrapper#LINE_HEIGHT
934+
return 0;
932935
}
933936

934937
/**

src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java

Lines changed: 20 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package gregtech.api.recipes.builders;
22

3-
import gregtech.api.GTValues;
4-
import gregtech.api.items.metaitem.MetaItem;
53
import gregtech.api.items.metaitem.stats.IDataItem;
6-
import gregtech.api.items.metaitem.stats.IItemBehaviour;
74
import gregtech.api.recipes.Recipe;
85
import gregtech.api.recipes.RecipeBuilder;
96
import gregtech.api.recipes.RecipeMap;
@@ -12,7 +9,6 @@
129
import gregtech.api.util.AssemblyLineManager;
1310
import gregtech.api.util.EnumValidationResult;
1411
import gregtech.api.util.GTLog;
15-
import gregtech.api.util.GTStringUtils;
1612
import gregtech.common.ConfigHolder;
1713
import net.minecraft.item.ItemStack;
1814

@@ -24,11 +20,6 @@
2420

2521
public class AssemblyLineRecipeBuilder extends RecipeBuilder<AssemblyLineRecipeBuilder> {
2622

27-
public static final int DEFAULT_SCANNER_DURATION = 1200; // 60 secs
28-
public static final int DEFAULT_SCANNER_EUT = GTValues.VA[GTValues.HV];
29-
public static final int DEFAULT_STATION_DURATION = 4000; // 200 secs
30-
public static final int DEFAULT_STATION_EUT = GTValues.VA[GTValues.LuV];
31-
3223
private final Collection<ResearchRecipeEntry> recipeEntries = new ArrayList<>();
3324

3425
private boolean generatingRecipes = true;
@@ -55,7 +46,7 @@ public AssemblyLineRecipeBuilder copy() {
5546
public boolean applyProperty(@Nonnull String key, @Nullable Object value) {
5647
if (key.equals(ResearchProperty.KEY)) {
5748
if (value instanceof ItemStack itemStack) {
58-
research(itemStack);
49+
scannerResearch(itemStack);
5950
return true;
6051
}
6152
}
@@ -115,22 +106,36 @@ public AssemblyLineRecipeBuilder researchWithoutRecipe(@Nonnull String researchI
115106
return this;
116107
}
117108

118-
public AssemblyLineRecipeBuilder research(UnaryOperator<ResearchBuilder> research) {
119-
ResearchRecipeEntry entry = research.apply(new ResearchBuilder()).build();
109+
/**
110+
* Generates a research recipe for the Scanner.
111+
*/
112+
public AssemblyLineRecipeBuilder scannerResearch(UnaryOperator<ResearchRecipeBuilder.ScannerRecipeBuilder> research) {
113+
ResearchRecipeEntry entry = research.apply(new ResearchRecipeBuilder.ScannerRecipeBuilder()).build();
120114
if (applyResearchProperty(new ResearchPropertyData.ResearchEntry(entry.researchId, entry.dataStack))) {
121115
this.recipeEntries.add(entry);
122116
}
123117
return this;
124118
}
125119

126120
/**
127-
* Generates a research recipe.
121+
* Generates a research recipe for the Scanner. All values are defaults other than the research stack.
128122
*
129123
* @param researchStack the stack to use for research
130124
* @return this
131125
*/
132-
public AssemblyLineRecipeBuilder research(@Nonnull ItemStack researchStack) {
133-
return research(b -> new ResearchBuilder().researchStack(researchStack));
126+
public AssemblyLineRecipeBuilder scannerResearch(@Nonnull ItemStack researchStack) {
127+
return scannerResearch(b -> new ResearchRecipeBuilder.ScannerRecipeBuilder().researchStack(researchStack));
128+
}
129+
130+
/**
131+
* Generates a research recipe for the Research Station.
132+
*/
133+
public AssemblyLineRecipeBuilder stationResearch(UnaryOperator<ResearchRecipeBuilder.StationRecipeBuilder> research) {
134+
ResearchRecipeEntry entry = research.apply(new ResearchRecipeBuilder.StationRecipeBuilder()).build();
135+
if (applyResearchProperty(new ResearchPropertyData.ResearchEntry(entry.researchId, entry.dataStack))) {
136+
this.recipeEntries.add(entry);
137+
}
138+
return this;
134139
}
135140

136141
@Nonnull
@@ -194,95 +199,4 @@ public int getCWUt() {
194199
return CWUt;
195200
}
196201
}
197-
198-
public static class ResearchBuilder {
199-
200-
private ItemStack researchStack;
201-
private ItemStack dataStack;
202-
private String researchId;
203-
private int duration;
204-
private int eut;
205-
private int cwut;
206-
207-
private ResearchBuilder() {/**/}
208-
209-
public ResearchBuilder researchStack(@Nonnull ItemStack researchStack) {
210-
if (!researchStack.isEmpty()) {
211-
this.researchStack = researchStack;
212-
}
213-
return this;
214-
}
215-
216-
public ResearchBuilder dataStack(@Nonnull ItemStack dataStack) {
217-
if (!dataStack.isEmpty()) {
218-
this.dataStack = dataStack;
219-
}
220-
return this;
221-
}
222-
223-
public ResearchBuilder researchId(String researchId) {
224-
this.researchId = researchId;
225-
return this;
226-
}
227-
228-
public ResearchBuilder duration(int duration) {
229-
this.duration = duration;
230-
return this;
231-
}
232-
233-
public ResearchBuilder EUt(int eut) {
234-
this.eut = eut;
235-
return this;
236-
}
237-
238-
/** If this value is greater than zero, then this recipe will be done in the Research Station instead of the Scanner */
239-
public ResearchBuilder CWUt(int cwut) {
240-
this.cwut = cwut;
241-
return this;
242-
}
243-
244-
private ResearchRecipeEntry build() {
245-
if (researchStack == null) {
246-
throw new IllegalArgumentException("Research stack cannot be null or empty!");
247-
}
248-
249-
if (researchId == null) {
250-
researchId = GTStringUtils.itemStackToString(researchStack);
251-
}
252-
253-
if (dataStack == null) {
254-
dataStack = cwut > 0
255-
? AssemblyLineManager.getDefaultResearchStationItem(cwut)
256-
: AssemblyLineManager.getDefaultScannerItem();
257-
}
258-
259-
boolean foundBehavior = false;
260-
if (dataStack.getItem() instanceof MetaItem<?> metaItem) {
261-
for (IItemBehaviour behaviour : metaItem.getBehaviours(dataStack)) {
262-
if (behaviour instanceof IDataItem) {
263-
foundBehavior = true;
264-
dataStack = dataStack.copy();
265-
dataStack.setCount(1);
266-
break;
267-
}
268-
}
269-
}
270-
if (!foundBehavior) {
271-
throw new IllegalArgumentException("Data ItemStack must have the IDataItem behavior");
272-
}
273-
274-
if (duration <= 0) {
275-
duration = cwut > 0
276-
? DEFAULT_STATION_DURATION
277-
: DEFAULT_SCANNER_DURATION;
278-
}
279-
280-
if (eut <= 0) {
281-
eut = cwut > 0
282-
? DEFAULT_STATION_EUT
283-
: DEFAULT_SCANNER_EUT;
284-
}
285-
return new ResearchRecipeEntry(researchId, researchStack, dataStack, duration, eut, cwut);
286-
}
287-
}
288202
}

src/main/java/gregtech/api/recipes/builders/ComputationRecipeBuilder.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import gregtech.api.recipes.RecipeBuilder;
55
import gregtech.api.recipes.RecipeMap;
66
import gregtech.api.recipes.recipeproperties.ComputationProperty;
7+
import gregtech.api.recipes.recipeproperties.TotalComputationProperty;
78
import gregtech.api.util.EnumValidationResult;
89
import gregtech.api.util.GTLog;
910
import org.jetbrains.annotations.NotNull;
@@ -31,6 +32,10 @@ public boolean applyProperty(@NotNull String key, Object value) {
3132
this.CWUt(((Number) value).intValue());
3233
return true;
3334
}
35+
if (key.equals(TotalComputationProperty.KEY)) {
36+
this.totalCWU(((Number) value).intValue());
37+
return true;
38+
}
3439
return super.applyProperty(key, value);
3540
}
3641

@@ -42,4 +47,16 @@ public ComputationRecipeBuilder CWUt(int cwut) {
4247
this.applyProperty(ComputationProperty.getInstance(), cwut);
4348
return this;
4449
}
50+
51+
/**
52+
* The total computation for this recipe. If desired, this should be used instead of a call to duration().
53+
*/
54+
public ComputationRecipeBuilder totalCWU(int totalCWU) {
55+
if (totalCWU < 0) {
56+
GTLog.logger.error("Total CWU cannot be less than 0", new IllegalArgumentException());
57+
recipeStatus = EnumValidationResult.INVALID;
58+
}
59+
this.applyProperty(TotalComputationProperty.getInstance(), totalCWU);
60+
return duration(totalCWU);
61+
}
4562
}

0 commit comments

Comments
 (0)