Skip to content

Commit 78a456b

Browse files
Merge pull request #1 from KalWantsPizza/codex/review-and-optimize-specified-classes
Refine engine sequenced assembly generation
2 parents 193bd4d + d8ca2a7 commit 78a456b

File tree

4 files changed

+155
-97
lines changed

4 files changed

+155
-97
lines changed

src/main/java/com/rae/creatingspace/content/datagen/recipe/engine/EngineSequencedAssemblyProvider.java

Lines changed: 34 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,13 @@ public EngineSequencedAssemblyProvider(PackOutput output) {
4242
public CompletableFuture<?> run(CachedOutput cache) {
4343
List<CompletableFuture<?>> futures = new ArrayList<>();
4444

45-
// Material-dependent recipes
46-
for (MaterialLevel mat : MaterialLevel.values()) {
47-
for (EnginePartType type : EnginePartType.values()) {
48-
if (!type.isMaterialDependent()) continue;
49-
50-
try {
51-
JsonObject json = buildRecipe(type, mat);
52-
Path path = recipePath(type, mat);
53-
futures.add(saveJson(cache, json, path));
54-
} catch (Exception e) {
55-
throw new RuntimeException("Failed generating recipe for " + type.name() + " at " + mat.key(), e);
56-
}
57-
}
58-
}
59-
60-
// Non-material recipes
6145
for (EnginePartType type : EnginePartType.values()) {
62-
if (type.isMaterialDependent()) continue;
63-
64-
try {
65-
JsonObject json = buildRecipe(type, null);
66-
Path path = recipePath(type, null);
67-
futures.add(saveJson(cache, json, path));
68-
} catch (Exception e) {
69-
throw new RuntimeException("Failed generating static recipe for " + type.name(), e);
46+
type.applicableMaterials()
47+
.map(mat -> scheduleRecipe(cache, type, mat))
48+
.forEach(futures::add);
49+
50+
if (!type.isMaterialDependent()) {
51+
futures.add(scheduleRecipe(cache, type, null));
7052
}
7153
}
7254

@@ -81,35 +63,20 @@ private JsonObject buildRecipe(EnginePartType type, MaterialLevel mat) {
8163
EngineSAJson.Builder b = EngineSAJson.builder()
8264
.loops(type.loops());
8365

84-
// --------------------------------------------------------------------
85-
// Material-dependent recipes
86-
// --------------------------------------------------------------------
87-
if (type.isMaterialDependent() && mat != null) {
66+
if (type.isMaterialDependent()) {
67+
if (mat == null) {
68+
throw new IllegalArgumentException("Material-dependent recipe requires material level for " + type.name());
69+
}
70+
8871
// Add proper ingredient with materialLevel in custom data
8972
b.blueprintIngredient(mat.level());
90-
91-
// Result item — same name as the recipe file
92-
String partName = type.recipeSubPath()
93-
.substring(type.recipeSubPath().lastIndexOf('/') + 1);
94-
b.result(getResultItemId(type, mat));
95-
96-
// Transitional item naming rules
97-
b.transitionalItem(getTransitionalItemId(type, mat));
98-
99-
100-
// --------------------------------------------------------------------
101-
// Non-material recipes (engine, duplicate_blueprint)
102-
// --------------------------------------------------------------------
10373
} else {
104-
b.result("creatingspace:" + type.recipeSubPath());
105-
b.transitionalItem("creatingspace:engine_blueprint");
106-
107-
// simple ingredient reference to avoid {}
108-
JsonObject ing = new JsonObject();
109-
ing.addProperty("item", "creatingspace:engine_blueprint");
110-
b.rawIngredient(ing);
74+
b.rawIngredient(EngineSAJson.Builder.itemIngredient("creatingspace:engine_blueprint"));
11175
}
11276

77+
b.result(type.resultItemId(mat));
78+
b.transitionalItem(type.transitionalItemId(mat));
79+
11380
// --------------------------------------------------------------------
11481
// Extra data & sequence definition
11582
// --------------------------------------------------------------------
@@ -128,15 +95,16 @@ private JsonObject buildRecipe(EnginePartType type, MaterialLevel mat) {
12895
// ------------------------------------------------------------------------
12996

13097
private Path recipePath(EnginePartType type, MaterialLevel mat) {
131-
StringBuilder sb = new StringBuilder("data/creatingspace/recipe/");
132-
sb.append(type.baseFolder()).append("/");
133-
134-
if (type.isMaterialDependent() && mat != null) {
135-
sb.append(mat.folderName()).append("/");
98+
Path base = Path.of("data", "creatingspace", "recipe", type.baseFolder());
99+
if (type.isMaterialDependent()) {
100+
if (mat == null) {
101+
throw new IllegalArgumentException("Material-dependent recipe requires material level for " + type.name());
102+
}
103+
base = base.resolve(mat.folderName());
136104
}
137105

138-
sb.append(type.recipeSubPath()).append(".json");
139-
return output.getOutputFolder().resolve(Path.of(sb.toString()));
106+
Path file = Path.of(type.recipeSubPath() + ".json");
107+
return output.getOutputFolder().resolve(base).resolve(file);
140108
}
141109

142110
// ------------------------------------------------------------------------
@@ -148,40 +116,17 @@ private static CompletableFuture<?> saveJson(CachedOutput cache, JsonObject json
148116
return DataProvider.saveStable(cache, GSON.toJsonTree(json), path);
149117
}
150118

151-
private static String getResultItemId(EnginePartType part, MaterialLevel mat) {
152-
// These parts always produce generic item IDs (no material prefix)
153-
return switch (part) {
154-
case COMBUSTION_CHAMBER -> "creatingspace:combustion_chamber";
155-
case BELL_NOZZLE -> "creatingspace:bell_nozzle";
156-
case AEROSPIKE_PLUG -> "creatingspace:aerospike_plug";
157-
case FUEL_RICH_STAGED_CYCLE, FULL_FLOW_STAGED_CYCLE, OPEN_CYCLE, OX_RICH_STAGED_CYCLE -> "creatingspace:power_pack";
158-
case DUPLICATE_BLUEPRINT -> "creatingspace:duplicate_blueprint";
159-
case ENGINE -> "creatingspace:engine";
160-
default -> mat.itemId(
161-
part.recipeSubPath().substring(part.recipeSubPath().lastIndexOf('/') + 1)
162-
);
163-
};
164-
}
165-
166-
private static String getTransitionalItemId(EnginePartType type, MaterialLevel mat) {
167-
return switch (type) {
168-
// Exhaust pack members all use a shared transitional
169-
case COMBUSTION_CHAMBER -> "creatingspace:incomplete_combustion_chamber";
170-
case BELL_NOZZLE -> "creatingspace:incomplete_bell_nozzle";
171-
case AEROSPIKE_PLUG -> "creatingspace:incomplete_aerospike_plug";
172-
case FUEL_RICH_STAGED_CYCLE, FULL_FLOW_STAGED_CYCLE, OPEN_CYCLE, OX_RICH_STAGED_CYCLE -> "creatingspace:incomplete_power_pack";
173-
case DUPLICATE_BLUEPRINT -> "creatingspace:engine_blueprint";
174-
case ENGINE -> "creatingspace:engine_blueprint";
175-
176-
// Default material-dependent transitional logic
177-
default -> {
178-
String partName = type.recipeSubPath()
179-
.substring(type.recipeSubPath().lastIndexOf('/') + 1);
180-
if (partName.equals("injector_grid") || partName.equals("turbine"))
181-
yield EngineSAJson.Builder.incompleteMaterialItemId(mat, partName);
182-
yield EngineSAJson.Builder.incompleteItemId(partName);
183-
}
184-
};
119+
private CompletableFuture<?> scheduleRecipe(CachedOutput cache, EnginePartType type, MaterialLevel mat) {
120+
try {
121+
JsonObject json = buildRecipe(type, mat);
122+
Path path = recipePath(type, mat);
123+
return saveJson(cache, json, path);
124+
} catch (Exception e) {
125+
String context = type.isMaterialDependent()
126+
? " at " + (mat != null ? mat.key() : "<missing material>")
127+
: " (static)";
128+
throw new RuntimeException("Failed generating recipe for " + type.name() + context, e);
129+
}
185130
}
186131

187132
@Override

src/main/java/com/rae/creatingspace/content/datagen/recipe/engine/model/EnginePartType.java

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import com.rae.creatingspace.content.datagen.recipe.engine.util.EngineSAJson;
44

5+
import java.util.Arrays;
6+
import java.util.stream.Stream;
7+
58
import static com.rae.creatingspace.CreatingSpace.resource;
69

710
/**
@@ -41,9 +44,7 @@ public void buildSequence(EngineSAJson.Builder b, MaterialLevel mat) {
4144
public void buildSequence(EngineSAJson.Builder b, MaterialLevel mat) {
4245
String base = EngineSAJson.Builder.incompleteItemId("bell_nozzle");
4346
b.deploy(base, mat.itemId("rib"));
44-
b.deploy(base, mat.itemId("engine_wall"));
45-
b.deploy(base, mat.itemId("engine_wall"));
46-
b.deploy(base, mat.itemId("engine_wall"));
47+
repeatDeploy(b, base, mat.itemId("engine_wall"), 3);
4748
b.deploy(base, mat.itemId("rib"));
4849
}
4950

@@ -109,6 +110,16 @@ public void buildSequence(EngineSAJson.Builder b, MaterialLevel mat) {
109110
public void appendExtraEngineData(EngineSAJson.Builder b) {
110111
b.putInEngineRecipeData("powerPackType", resource("fuel_rich_staged_cycle").toString());
111112
}
113+
114+
@Override
115+
public String resultItemId(MaterialLevel mat) {
116+
return "creatingspace:power_pack";
117+
}
118+
119+
@Override
120+
public String transitionalItemId(MaterialLevel mat) {
121+
return EngineSAJson.Builder.incompleteItemId("power_pack");
122+
}
112123
},
113124

114125
FULL_FLOW_STAGED_CYCLE(
@@ -124,6 +135,16 @@ public void buildSequence(EngineSAJson.Builder b, MaterialLevel mat) {
124135
public void appendExtraEngineData(EngineSAJson.Builder b) {
125136
b.putInEngineRecipeData("powerPackType", resource("full_flow_staged_cycle").toString());
126137
}
138+
139+
@Override
140+
public String resultItemId(MaterialLevel mat) {
141+
return "creatingspace:power_pack";
142+
}
143+
144+
@Override
145+
public String transitionalItemId(MaterialLevel mat) {
146+
return EngineSAJson.Builder.incompleteItemId("power_pack");
147+
}
127148
},
128149

129150
OPEN_CYCLE(
@@ -140,6 +161,16 @@ public void buildSequence(EngineSAJson.Builder b, MaterialLevel mat) {
140161
public void appendExtraEngineData(EngineSAJson.Builder b) {
141162
b.putInEngineRecipeData("powerPackType", resource("open_cycle").toString());
142163
}
164+
165+
@Override
166+
public String resultItemId(MaterialLevel mat) {
167+
return "creatingspace:power_pack";
168+
}
169+
170+
@Override
171+
public String transitionalItemId(MaterialLevel mat) {
172+
return EngineSAJson.Builder.incompleteItemId("power_pack");
173+
}
143174
},
144175

145176
OX_RICH_STAGED_CYCLE(
@@ -155,6 +186,16 @@ public void buildSequence(EngineSAJson.Builder b, MaterialLevel mat) {
155186
public void appendExtraEngineData(EngineSAJson.Builder b) {
156187
b.putInEngineRecipeData("powerPackType", resource("ox_rich_staged_cycle").toString());
157188
}
189+
190+
@Override
191+
public String resultItemId(MaterialLevel mat) {
192+
return "creatingspace:power_pack";
193+
}
194+
195+
@Override
196+
public String transitionalItemId(MaterialLevel mat) {
197+
return EngineSAJson.Builder.incompleteItemId("power_pack");
198+
}
158199
},
159200

160201
// ---------- Non-material recipes ----------
@@ -184,18 +225,61 @@ public void buildSequence(EngineSAJson.Builder b, MaterialLevel mat) {
184225
private final String recipeSubPath;
185226
private final boolean materialDependent;
186227
private final int loops;
228+
private final String recipeLeafName;
187229

188230
EnginePartType(String baseFolder, String recipeSubPath, boolean materialDependent, int loops) {
189231
this.baseFolder = baseFolder;
190232
this.recipeSubPath = recipeSubPath;
191233
this.materialDependent = materialDependent;
192234
this.loops = loops;
235+
int slashIndex = recipeSubPath.lastIndexOf('/');
236+
this.recipeLeafName = slashIndex == -1 ? recipeSubPath : recipeSubPath.substring(slashIndex + 1);
193237
}
194238

195239
public String baseFolder() { return baseFolder; }
196240
public String recipeSubPath() { return recipeSubPath; }
197241
public boolean isMaterialDependent() { return materialDependent; }
198242
public int loops() { return loops; }
243+
public String recipeLeafName() { return recipeLeafName; }
244+
245+
/** Returns the default result item ID for this part at the given material level. */
246+
public String resultItemId(MaterialLevel mat) {
247+
if (!materialDependent) {
248+
return "creatingspace:" + recipeLeafName;
249+
}
250+
251+
if (mat == null) {
252+
throw new IllegalArgumentException("Material-dependent recipe requires material level for " + name());
253+
}
254+
255+
return switch (this) {
256+
case COMBUSTION_CHAMBER -> "creatingspace:combustion_chamber";
257+
case BELL_NOZZLE -> "creatingspace:bell_nozzle";
258+
case AEROSPIKE_PLUG -> "creatingspace:aerospike_plug";
259+
default -> mat.itemId(recipeLeafName);
260+
};
261+
}
262+
263+
/** Returns the transitional item ID for this part at the given material level. */
264+
public String transitionalItemId(MaterialLevel mat) {
265+
if (!materialDependent) {
266+
return "creatingspace:engine_blueprint";
267+
}
268+
269+
if (mat == null) {
270+
throw new IllegalArgumentException("Material-dependent recipe requires material level for " + name());
271+
}
272+
273+
return switch (recipeLeafName) {
274+
case "injector_grid", "turbine" -> EngineSAJson.Builder.incompleteMaterialItemId(mat, recipeLeafName);
275+
default -> EngineSAJson.Builder.incompleteItemId(recipeLeafName);
276+
};
277+
}
278+
279+
/** Stream of material levels that this part should generate recipes for. */
280+
public Stream<MaterialLevel> applicableMaterials() {
281+
return materialDependent ? Arrays.stream(MaterialLevel.values()) : Stream.empty();
282+
}
199283

200284
/** Override this to append additional data fields into engineRecipeData. */
201285
public void appendExtraEngineData(EngineSAJson.Builder b) {}
@@ -209,4 +293,11 @@ protected static void addPowerPackSteps(EngineSAJson.Builder b, MaterialLevel ma
209293
b.deployMach(base, mat.itemId("turbine"));
210294
b.deployMach(base, mat.itemId("injector_grid"));
211295
}
296+
297+
/** Utility to add the same deploying step multiple times. */
298+
protected static void repeatDeploy(EngineSAJson.Builder b, String base, String addition, int times) {
299+
for (int i = 0; i < times; i++) {
300+
b.deploy(base, addition);
301+
}
302+
}
212303
}

src/main/java/com/rae/creatingspace/content/datagen/recipe/engine/model/MaterialLevel.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@ public enum MaterialLevel {
2727
private final String key;
2828
private final String folderName;
2929
private final ResourceLocation basePrefix;
30+
private final String prefix;
3031

3132
MaterialLevel(int level, String key) {
3233
this.level = level;
3334
this.key = key;
3435
this.folderName = "lvl" + level;
35-
this.basePrefix = resource( key + "_");
36+
this.basePrefix = resource(key + "_");
37+
this.prefix = this.basePrefix.getNamespace() + ":" + this.basePrefix.getPath();
3638
}
3739

3840
/** The numeric material level (used in engineRecipeData.materialLevel). */
@@ -45,7 +47,7 @@ public String key() {
4547
return key;
4648
}
4749

48-
/** Folder segment (e.g., "level1-iron"). */
50+
/** Folder segment (e.g., "lvl1"). */
4951
public String folderName() {
5052
return folderName;
5153
}
@@ -55,8 +57,13 @@ public ResourceLocation basePrefix() {
5557
return basePrefix;
5658
}
5759

60+
/** Cached string form of the namespaced prefix (e.g., "creatingspace:iron_"). */
61+
public String prefix() {
62+
return prefix;
63+
}
64+
5865
/** Returns a namespaced item ID with this material’s prefix. */
5966
public String itemId(String suffix) {
60-
return basePrefix.getNamespace() + ":" + basePrefix.getPath() + suffix;
67+
return prefix + suffix;
6168
}
6269
}

0 commit comments

Comments
 (0)