@shipload/sdk 1.0.0-next.3 → 1.0.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/shipload.d.ts +14 -7
- package/lib/shipload.js +192 -380
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +190 -380
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -1
- package/src/data/capabilities.ts +5 -330
- package/src/data/capability-formulas.ts +68 -0
- package/src/data/recipes.json +6 -16
- package/src/derivation/capability-mappings.ts +120 -0
- package/src/entities/container.ts +8 -8
- package/src/entities/ship-deploy.ts +36 -35
- package/src/index-module.ts +9 -3
- package/src/nft/description.ts +4 -4
- package/src/resolution/resolve-item.ts +5 -4
package/package.json
CHANGED
package/src/data/capabilities.ts
CHANGED
|
@@ -8,7 +8,6 @@ export interface StatMapping {
|
|
|
8
8
|
stat: string
|
|
9
9
|
capability: string
|
|
10
10
|
attribute: string
|
|
11
|
-
rationale: string
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
export const capabilityNames: string[] = [
|
|
@@ -27,6 +26,11 @@ export const capabilityNames: string[] = [
|
|
|
27
26
|
export const capabilityAttributes: CapabilityAttribute[] = [
|
|
28
27
|
{capability: 'Hull', attribute: 'mass', description: 'Total mass of the hull'},
|
|
29
28
|
{capability: 'Storage', attribute: 'capacity', description: 'Maximum mass that can be stored'},
|
|
29
|
+
{
|
|
30
|
+
capability: 'Storage',
|
|
31
|
+
attribute: 'bonus',
|
|
32
|
+
description: 'Capacity bonus added by an installed Storage module',
|
|
33
|
+
},
|
|
30
34
|
{capability: 'Movement', attribute: 'thrust', description: 'Propulsion force'},
|
|
31
35
|
{capability: 'Movement', attribute: 'drain', description: 'Energy consumed per movement'},
|
|
32
36
|
{capability: 'Energy', attribute: 'capacity', description: 'Maximum energy storage'},
|
|
@@ -65,323 +69,6 @@ export const capabilityAttributes: CapabilityAttribute[] = [
|
|
|
65
69
|
},
|
|
66
70
|
]
|
|
67
71
|
|
|
68
|
-
export const statMappings: StatMapping[] = [
|
|
69
|
-
{
|
|
70
|
-
stat: 'Strength',
|
|
71
|
-
capability: 'Gathering',
|
|
72
|
-
attribute: 'yield',
|
|
73
|
-
rationale: 'Raw mechanical force drives faster gathering',
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
stat: 'Strength',
|
|
77
|
-
capability: 'Storage',
|
|
78
|
-
attribute: 'capacity',
|
|
79
|
-
rationale: 'Stronger walls hold more capacity per mass',
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
stat: 'Strength',
|
|
83
|
-
capability: 'Launch',
|
|
84
|
-
attribute: 'capacity',
|
|
85
|
-
rationale: 'Stronger housing handles larger launch loads',
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
stat: 'Tolerance',
|
|
89
|
-
capability: 'Movement',
|
|
90
|
-
attribute: 'thrust',
|
|
91
|
-
rationale: 'Engine components that tolerate more can push harder',
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
stat: 'Tolerance',
|
|
95
|
-
capability: 'Energy',
|
|
96
|
-
attribute: 'recharge',
|
|
97
|
-
rationale: 'Generator housing withstands stress for faster recharge',
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
stat: 'Tolerance',
|
|
101
|
-
capability: 'Gathering',
|
|
102
|
-
attribute: 'depth',
|
|
103
|
-
rationale: 'Housing withstands pressure/heat at extreme depths',
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
stat: 'Tolerance',
|
|
107
|
-
capability: 'Warp',
|
|
108
|
-
attribute: 'range',
|
|
109
|
-
rationale: 'Warp drive housing withstands extreme forces',
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
stat: 'Density',
|
|
113
|
-
capability: 'Hull',
|
|
114
|
-
attribute: 'mass',
|
|
115
|
-
rationale: 'Lighter metal = lighter hull',
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
stat: 'Density',
|
|
119
|
-
capability: 'Loader',
|
|
120
|
-
attribute: 'mass',
|
|
121
|
-
rationale: 'Lighter metal = lighter loader units',
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
stat: 'Density',
|
|
125
|
-
capability: 'Movement',
|
|
126
|
-
attribute: 'drain',
|
|
127
|
-
rationale: 'Lighter components require less energy to move',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
stat: 'Conductivity',
|
|
131
|
-
capability: 'Movement',
|
|
132
|
-
attribute: 'drain',
|
|
133
|
-
rationale: 'Efficient energy transfer reduces movement energy cost',
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
stat: 'Conductivity',
|
|
137
|
-
capability: 'Gathering',
|
|
138
|
-
attribute: 'drain',
|
|
139
|
-
rationale: 'Efficient energy transfer reduces gathering energy cost',
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
stat: 'Conductivity',
|
|
143
|
-
capability: 'Crafter',
|
|
144
|
-
attribute: 'drain',
|
|
145
|
-
rationale: 'Efficient energy transfer reduces crafting energy cost',
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
stat: 'Conductivity',
|
|
149
|
-
capability: 'Energy',
|
|
150
|
-
attribute: 'recharge',
|
|
151
|
-
rationale: 'Better conductivity speeds energy flow during recharge',
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
stat: 'Ductility',
|
|
155
|
-
capability: 'Crafter',
|
|
156
|
-
attribute: 'quality',
|
|
157
|
-
rationale: 'Precise shaping enables tighter crafting tolerances',
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
stat: 'Ductility',
|
|
161
|
-
capability: 'Gathering',
|
|
162
|
-
attribute: 'yield',
|
|
163
|
-
rationale: 'Precisely shaped conduit components gather faster',
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
stat: 'Ductility',
|
|
167
|
-
capability: 'Storage',
|
|
168
|
-
attribute: 'capacity',
|
|
169
|
-
rationale: 'Precision-formed container walls maximize volume',
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
stat: 'Ductility',
|
|
173
|
-
capability: 'Loader',
|
|
174
|
-
attribute: 'mass',
|
|
175
|
-
rationale: 'Precision-formed precious metal reduces loader unit mass',
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
stat: 'Reflectivity',
|
|
179
|
-
capability: 'Gathering',
|
|
180
|
-
attribute: 'depth',
|
|
181
|
-
rationale: 'Reflective heat shielding protects equipment at depth',
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
stat: 'Reflectivity',
|
|
185
|
-
capability: 'Launch',
|
|
186
|
-
attribute: 'range',
|
|
187
|
-
rationale: 'Reflective surfaces focus electromagnetic launch energy',
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
stat: 'Volatility',
|
|
191
|
-
capability: 'Gathering',
|
|
192
|
-
attribute: 'yield',
|
|
193
|
-
rationale: 'Energy release powers faster gathering',
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
stat: 'Volatility',
|
|
197
|
-
capability: 'Movement',
|
|
198
|
-
attribute: 'thrust',
|
|
199
|
-
rationale: 'Energy release drives propulsion force',
|
|
200
|
-
},
|
|
201
|
-
{
|
|
202
|
-
stat: 'Volatility',
|
|
203
|
-
capability: 'Loader',
|
|
204
|
-
attribute: 'thrust',
|
|
205
|
-
rationale: 'Energy release powers loader motors',
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
stat: 'Volatility',
|
|
209
|
-
capability: 'Launch',
|
|
210
|
-
attribute: 'capacity',
|
|
211
|
-
rationale: 'Energy release enables launching heavier payloads',
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
stat: 'Reactivity',
|
|
215
|
-
capability: 'Crafter',
|
|
216
|
-
attribute: 'speed',
|
|
217
|
-
rationale: 'Reactive gases accelerate chemical/thermal processing',
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
stat: 'Reactivity',
|
|
221
|
-
capability: 'Gathering',
|
|
222
|
-
attribute: 'speed',
|
|
223
|
-
rationale: 'Reactive gases manage heat/friction during gathering',
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
stat: 'Reactivity',
|
|
227
|
-
capability: 'Launch',
|
|
228
|
-
attribute: 'drain',
|
|
229
|
-
rationale: 'Reactive gas medium reduces electromagnetic resistance',
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
stat: 'Thermal',
|
|
233
|
-
capability: 'Crafter',
|
|
234
|
-
attribute: 'quality',
|
|
235
|
-
rationale: 'Precise thermal control during fabrication',
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
stat: 'Thermal',
|
|
239
|
-
capability: 'Gathering',
|
|
240
|
-
attribute: 'drain',
|
|
241
|
-
rationale: 'Thermal management reduces energy waste during gathering',
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
stat: 'Thermal',
|
|
245
|
-
capability: 'Energy',
|
|
246
|
-
attribute: 'capacity',
|
|
247
|
-
rationale: 'Thermal management enables denser energy storage',
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
stat: 'Resonance',
|
|
251
|
-
capability: 'Energy',
|
|
252
|
-
attribute: 'capacity',
|
|
253
|
-
rationale: 'Resonating crystals store energy in fields',
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
stat: 'Resonance',
|
|
257
|
-
capability: 'Warp',
|
|
258
|
-
attribute: 'range',
|
|
259
|
-
rationale: 'Resonant crystals amplify warp field projection',
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
stat: 'Resonance',
|
|
263
|
-
capability: 'Launch',
|
|
264
|
-
attribute: 'range',
|
|
265
|
-
rationale: 'Resonant crystals focus electromagnetic launch field',
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
stat: 'Resonance',
|
|
269
|
-
capability: 'Launch',
|
|
270
|
-
attribute: 'capacity',
|
|
271
|
-
rationale: 'Stronger resonant field launches heavier payloads',
|
|
272
|
-
},
|
|
273
|
-
{
|
|
274
|
-
stat: 'Hardness',
|
|
275
|
-
capability: 'Crafter',
|
|
276
|
-
attribute: 'speed',
|
|
277
|
-
rationale: 'Hard tooling surfaces cut and shape materials faster',
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
stat: 'Hardness',
|
|
281
|
-
capability: 'Launch',
|
|
282
|
-
attribute: 'drain',
|
|
283
|
-
rationale: 'Hard rail surfaces reduce friction, less energy wasted',
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
stat: 'Clarity',
|
|
287
|
-
capability: 'Energy',
|
|
288
|
-
attribute: 'recharge',
|
|
289
|
-
rationale: 'Flawless crystals enable smoother energy flow during recharge',
|
|
290
|
-
},
|
|
291
|
-
{
|
|
292
|
-
stat: 'Clarity',
|
|
293
|
-
capability: 'Crafter',
|
|
294
|
-
attribute: 'quality',
|
|
295
|
-
rationale: 'Precision optics for calibration during fabrication',
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
stat: 'Clarity',
|
|
299
|
-
capability: 'Crafter',
|
|
300
|
-
attribute: 'drain',
|
|
301
|
-
rationale: 'Precision computing optimizes energy routing in factory',
|
|
302
|
-
},
|
|
303
|
-
{
|
|
304
|
-
stat: 'Plasticity',
|
|
305
|
-
capability: 'Crafter',
|
|
306
|
-
attribute: 'speed',
|
|
307
|
-
rationale: 'Easily reshaped materials speed up processing',
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
stat: 'Plasticity',
|
|
311
|
-
capability: 'Movement',
|
|
312
|
-
attribute: 'thrust',
|
|
313
|
-
rationale: 'Flexible polymer seals reduce friction in propulsion',
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
stat: 'Plasticity',
|
|
317
|
-
capability: 'Loader',
|
|
318
|
-
attribute: 'thrust',
|
|
319
|
-
rationale: 'Flexible joints improve loader force transfer',
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
stat: 'Insulation',
|
|
323
|
-
capability: 'Movement',
|
|
324
|
-
attribute: 'drain',
|
|
325
|
-
rationale: 'Better insulation reduces energy loss during movement',
|
|
326
|
-
},
|
|
327
|
-
{
|
|
328
|
-
stat: 'Insulation',
|
|
329
|
-
capability: 'Gathering',
|
|
330
|
-
attribute: 'drain',
|
|
331
|
-
rationale: 'Better insulation reduces energy loss during gathering',
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
stat: 'Insulation',
|
|
335
|
-
capability: 'Crafter',
|
|
336
|
-
attribute: 'drain',
|
|
337
|
-
rationale: 'Better insulation reduces energy loss during crafting',
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
stat: 'Insulation',
|
|
341
|
-
capability: 'Launch',
|
|
342
|
-
attribute: 'drain',
|
|
343
|
-
rationale: 'Better insulation reduces energy loss during launch',
|
|
344
|
-
},
|
|
345
|
-
{
|
|
346
|
-
stat: 'Purity',
|
|
347
|
-
capability: 'Storage',
|
|
348
|
-
attribute: 'capacity',
|
|
349
|
-
rationale: 'Purer composites make better containers',
|
|
350
|
-
},
|
|
351
|
-
{
|
|
352
|
-
stat: 'Purity',
|
|
353
|
-
capability: 'Gathering',
|
|
354
|
-
attribute: 'speed',
|
|
355
|
-
rationale: 'Purer bio-lubricants reduce friction during gathering',
|
|
356
|
-
},
|
|
357
|
-
{
|
|
358
|
-
stat: 'Purity',
|
|
359
|
-
capability: 'Energy',
|
|
360
|
-
attribute: 'capacity',
|
|
361
|
-
rationale: 'Purer organic electrolytes store more charge',
|
|
362
|
-
},
|
|
363
|
-
{
|
|
364
|
-
stat: 'Resonance',
|
|
365
|
-
capability: 'Hauler',
|
|
366
|
-
attribute: 'capacity',
|
|
367
|
-
rationale:
|
|
368
|
-
'Resonant field strength determines how many targets the haul beam can lock onto simultaneously.',
|
|
369
|
-
},
|
|
370
|
-
{
|
|
371
|
-
stat: 'Conductivity',
|
|
372
|
-
capability: 'Hauler',
|
|
373
|
-
attribute: 'efficiency',
|
|
374
|
-
rationale: 'Energy-transfer efficiency reduces the thrust penalty from each hauled target.',
|
|
375
|
-
},
|
|
376
|
-
{
|
|
377
|
-
stat: 'Clarity',
|
|
378
|
-
capability: 'Hauler',
|
|
379
|
-
attribute: 'drain',
|
|
380
|
-
rationale:
|
|
381
|
-
'Clarity-focused energy routing reduces per-target drain during haul-beam operation.',
|
|
382
|
-
},
|
|
383
|
-
]
|
|
384
|
-
|
|
385
72
|
const invertedAttributes = new Set(['drain', 'mass'])
|
|
386
73
|
|
|
387
74
|
export function isInvertedAttribute(attribute: string): boolean {
|
|
@@ -394,15 +81,3 @@ export function getCapabilityAttributes(capability?: string): CapabilityAttribut
|
|
|
394
81
|
}
|
|
395
82
|
return capabilityAttributes
|
|
396
83
|
}
|
|
397
|
-
|
|
398
|
-
export function getStatMappings(): StatMapping[] {
|
|
399
|
-
return statMappings
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
export function getStatMappingsForStat(stat: string): StatMapping[] {
|
|
403
|
-
return statMappings.filter((m) => m.stat === stat)
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
export function getStatMappingsForCapability(capability: string): StatMapping[] {
|
|
407
|
-
return statMappings.filter((m) => m.capability === capability)
|
|
408
|
-
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export interface SlotConsumer {
|
|
2
|
+
capability: string
|
|
3
|
+
attribute: string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export type SlotConsumerKind =
|
|
7
|
+
| 'engine'
|
|
8
|
+
| 'generator'
|
|
9
|
+
| 'gatherer'
|
|
10
|
+
| 'loader'
|
|
11
|
+
| 'crafter'
|
|
12
|
+
| 'storage'
|
|
13
|
+
| 'hauler'
|
|
14
|
+
| 'warp'
|
|
15
|
+
| 'ship-t1'
|
|
16
|
+
| 'container-t1'
|
|
17
|
+
| 'warehouse-t1'
|
|
18
|
+
| 'container-t2'
|
|
19
|
+
|
|
20
|
+
const ENTITY_HULL_SLOTS: Record<number, SlotConsumer> = {
|
|
21
|
+
0: {capability: 'Storage', attribute: 'capacity'},
|
|
22
|
+
1: {capability: 'Hull', attribute: 'mass'},
|
|
23
|
+
2: {capability: 'Storage', attribute: 'capacity'},
|
|
24
|
+
3: {capability: 'Storage', attribute: 'capacity'},
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const SLOT_FORMULAS: Record<SlotConsumerKind, Record<number, SlotConsumer>> = {
|
|
28
|
+
engine: {
|
|
29
|
+
0: {capability: 'Movement', attribute: 'thrust'},
|
|
30
|
+
1: {capability: 'Movement', attribute: 'drain'},
|
|
31
|
+
},
|
|
32
|
+
generator: {
|
|
33
|
+
0: {capability: 'Energy', attribute: 'capacity'},
|
|
34
|
+
1: {capability: 'Energy', attribute: 'recharge'},
|
|
35
|
+
},
|
|
36
|
+
gatherer: {
|
|
37
|
+
0: {capability: 'Gathering', attribute: 'yield'},
|
|
38
|
+
1: {capability: 'Gathering', attribute: 'depth'},
|
|
39
|
+
3: {capability: 'Gathering', attribute: 'drain'},
|
|
40
|
+
4: {capability: 'Gathering', attribute: 'speed'},
|
|
41
|
+
},
|
|
42
|
+
loader: {
|
|
43
|
+
0: {capability: 'Loader', attribute: 'mass'},
|
|
44
|
+
1: {capability: 'Loader', attribute: 'thrust'},
|
|
45
|
+
},
|
|
46
|
+
crafter: {
|
|
47
|
+
0: {capability: 'Crafter', attribute: 'speed'},
|
|
48
|
+
1: {capability: 'Crafter', attribute: 'drain'},
|
|
49
|
+
},
|
|
50
|
+
storage: {
|
|
51
|
+
0: {capability: 'Storage', attribute: 'bonus'},
|
|
52
|
+
1: {capability: 'Storage', attribute: 'bonus'},
|
|
53
|
+
2: {capability: 'Storage', attribute: 'bonus'},
|
|
54
|
+
3: {capability: 'Storage', attribute: 'bonus'},
|
|
55
|
+
},
|
|
56
|
+
hauler: {
|
|
57
|
+
0: {capability: 'Hauler', attribute: 'capacity'},
|
|
58
|
+
1: {capability: 'Hauler', attribute: 'efficiency'},
|
|
59
|
+
2: {capability: 'Hauler', attribute: 'drain'},
|
|
60
|
+
},
|
|
61
|
+
warp: {
|
|
62
|
+
0: {capability: 'Warp', attribute: 'range'},
|
|
63
|
+
},
|
|
64
|
+
'ship-t1': ENTITY_HULL_SLOTS,
|
|
65
|
+
'container-t1': ENTITY_HULL_SLOTS,
|
|
66
|
+
'warehouse-t1': ENTITY_HULL_SLOTS,
|
|
67
|
+
'container-t2': ENTITY_HULL_SLOTS,
|
|
68
|
+
}
|
package/src/data/recipes.json
CHANGED
|
@@ -393,12 +393,7 @@
|
|
|
393
393
|
]
|
|
394
394
|
},
|
|
395
395
|
{
|
|
396
|
-
"sources": [
|
|
397
|
-
{
|
|
398
|
-
"inputIndex": 1,
|
|
399
|
-
"statIndex": 1
|
|
400
|
-
}
|
|
401
|
-
]
|
|
396
|
+
"sources": []
|
|
402
397
|
},
|
|
403
398
|
{
|
|
404
399
|
"sources": [
|
|
@@ -436,8 +431,8 @@
|
|
|
436
431
|
{
|
|
437
432
|
"sources": [
|
|
438
433
|
{
|
|
439
|
-
"inputIndex":
|
|
440
|
-
"statIndex":
|
|
434
|
+
"inputIndex": 1,
|
|
435
|
+
"statIndex": 1
|
|
441
436
|
}
|
|
442
437
|
]
|
|
443
438
|
},
|
|
@@ -552,7 +547,7 @@
|
|
|
552
547
|
"sources": [
|
|
553
548
|
{
|
|
554
549
|
"inputIndex": 0,
|
|
555
|
-
"statIndex":
|
|
550
|
+
"statIndex": 1
|
|
556
551
|
}
|
|
557
552
|
]
|
|
558
553
|
},
|
|
@@ -568,17 +563,12 @@
|
|
|
568
563
|
"sources": [
|
|
569
564
|
{
|
|
570
565
|
"inputIndex": 0,
|
|
571
|
-
"statIndex":
|
|
566
|
+
"statIndex": 0
|
|
572
567
|
}
|
|
573
568
|
]
|
|
574
569
|
},
|
|
575
570
|
{
|
|
576
|
-
"sources": [
|
|
577
|
-
{
|
|
578
|
-
"inputIndex": 1,
|
|
579
|
-
"statIndex": 1
|
|
580
|
-
}
|
|
581
|
-
]
|
|
571
|
+
"sources": []
|
|
582
572
|
}
|
|
583
573
|
],
|
|
584
574
|
"blendWeights": []
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {SLOT_FORMULAS, type SlotConsumerKind} from '../data/capability-formulas'
|
|
2
|
+
import {getStatDefinitions, type StatDefinition} from './stats'
|
|
3
|
+
import {
|
|
4
|
+
getRecipe,
|
|
5
|
+
type Recipe,
|
|
6
|
+
type RecipeInput,
|
|
7
|
+
type RecipeInputCategory,
|
|
8
|
+
} from '../data/recipes-runtime'
|
|
9
|
+
import {
|
|
10
|
+
ITEM_ENGINE_T1,
|
|
11
|
+
ITEM_GENERATOR_T1,
|
|
12
|
+
ITEM_GATHERER_T1,
|
|
13
|
+
ITEM_LOADER_T1,
|
|
14
|
+
ITEM_CRAFTER_T1,
|
|
15
|
+
ITEM_STORAGE_T1,
|
|
16
|
+
ITEM_HAULER_T1,
|
|
17
|
+
ITEM_WARP_T1,
|
|
18
|
+
ITEM_SHIP_T1_PACKED,
|
|
19
|
+
ITEM_CONTAINER_T1_PACKED,
|
|
20
|
+
ITEM_WAREHOUSE_T1_PACKED,
|
|
21
|
+
ITEM_CONTAINER_T2_PACKED,
|
|
22
|
+
} from '../data/item-ids'
|
|
23
|
+
import type {StatMapping} from '../data/capabilities'
|
|
24
|
+
|
|
25
|
+
export const KIND_TO_ITEM_ID: Record<SlotConsumerKind, number> = {
|
|
26
|
+
engine: ITEM_ENGINE_T1,
|
|
27
|
+
generator: ITEM_GENERATOR_T1,
|
|
28
|
+
gatherer: ITEM_GATHERER_T1,
|
|
29
|
+
loader: ITEM_LOADER_T1,
|
|
30
|
+
crafter: ITEM_CRAFTER_T1,
|
|
31
|
+
storage: ITEM_STORAGE_T1,
|
|
32
|
+
hauler: ITEM_HAULER_T1,
|
|
33
|
+
warp: ITEM_WARP_T1,
|
|
34
|
+
'ship-t1': ITEM_SHIP_T1_PACKED,
|
|
35
|
+
'container-t1': ITEM_CONTAINER_T1_PACKED,
|
|
36
|
+
'warehouse-t1': ITEM_WAREHOUSE_T1_PACKED,
|
|
37
|
+
'container-t2': ITEM_CONTAINER_T2_PACKED,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isCategoryInput(input: RecipeInput): input is RecipeInputCategory {
|
|
41
|
+
return 'category' in input
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Walk a recipe's slot source down to the raw category stat that ultimately
|
|
46
|
+
* lands in that slot. Returns the StatDefinition or undefined if the trace
|
|
47
|
+
* dead-ends (unknown sub-component, missing slot, etc.).
|
|
48
|
+
*
|
|
49
|
+
* Multi-source sub-slots collapse to `sources[0]`; top-level multi-source slots
|
|
50
|
+
* are expanded by the caller (`deriveStatMappings`).
|
|
51
|
+
*/
|
|
52
|
+
function traceToRawCategoryStat(
|
|
53
|
+
recipe: Recipe,
|
|
54
|
+
source: {inputIndex: number; statIndex: number},
|
|
55
|
+
visited: Set<number> = new Set()
|
|
56
|
+
): StatDefinition | undefined {
|
|
57
|
+
const input = recipe.inputs[source.inputIndex]
|
|
58
|
+
if (!input) return undefined
|
|
59
|
+
if (isCategoryInput(input)) {
|
|
60
|
+
const defs = getStatDefinitions(input.category)
|
|
61
|
+
return defs[source.statIndex]
|
|
62
|
+
}
|
|
63
|
+
if (visited.has(input.itemId)) return undefined
|
|
64
|
+
const subRecipe = getRecipe(input.itemId)
|
|
65
|
+
if (!subRecipe) return undefined
|
|
66
|
+
const subSlot = subRecipe.statSlots[source.statIndex]
|
|
67
|
+
if (!subSlot) return undefined
|
|
68
|
+
const subSource = subSlot.sources[0]
|
|
69
|
+
if (!subSource) return undefined
|
|
70
|
+
const nextVisited = new Set(visited)
|
|
71
|
+
nextVisited.add(input.itemId)
|
|
72
|
+
return traceToRawCategoryStat(subRecipe, subSource, nextVisited)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let cached: StatMapping[] | undefined
|
|
76
|
+
|
|
77
|
+
export function deriveStatMappings(): StatMapping[] {
|
|
78
|
+
if (cached) return cached
|
|
79
|
+
const out: StatMapping[] = []
|
|
80
|
+
const seen = new Set<string>()
|
|
81
|
+
for (const [kind, slots] of Object.entries(SLOT_FORMULAS) as [
|
|
82
|
+
SlotConsumerKind,
|
|
83
|
+
Record<number, {capability: string; attribute: string}>,
|
|
84
|
+
][]) {
|
|
85
|
+
const itemId = KIND_TO_ITEM_ID[kind]
|
|
86
|
+
const recipe = getRecipe(itemId)
|
|
87
|
+
if (!recipe) continue
|
|
88
|
+
for (const [slotIdxStr, consumer] of Object.entries(slots)) {
|
|
89
|
+
const slotIdx = Number(slotIdxStr)
|
|
90
|
+
const slot = recipe.statSlots[slotIdx]
|
|
91
|
+
if (!slot) continue
|
|
92
|
+
for (const source of slot.sources) {
|
|
93
|
+
const stat = traceToRawCategoryStat(recipe, source)
|
|
94
|
+
if (!stat) continue
|
|
95
|
+
const key = `${stat.label}|${consumer.capability}|${consumer.attribute}`
|
|
96
|
+
if (seen.has(key)) continue
|
|
97
|
+
seen.add(key)
|
|
98
|
+
out.push({
|
|
99
|
+
stat: stat.label,
|
|
100
|
+
capability: consumer.capability,
|
|
101
|
+
attribute: consumer.attribute,
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
cached = out
|
|
107
|
+
return out
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function getStatMappings(): StatMapping[] {
|
|
111
|
+
return deriveStatMappings()
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function getStatMappingsForStat(stat: string): StatMapping[] {
|
|
115
|
+
return deriveStatMappings().filter((m) => m.stat === stat)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function getStatMappingsForCapability(capability: string): StatMapping[] {
|
|
119
|
+
return deriveStatMappings().filter((m) => m.capability === capability)
|
|
120
|
+
}
|
|
@@ -75,10 +75,10 @@ export function computeContainerCapabilities(stats: Record<string, number>): {
|
|
|
75
75
|
hullmass: number
|
|
76
76
|
capacity: number
|
|
77
77
|
} {
|
|
78
|
-
const density = stats
|
|
79
|
-
const strength = stats
|
|
80
|
-
const hardness = stats
|
|
81
|
-
const saturation = stats
|
|
78
|
+
const density = stats.density
|
|
79
|
+
const strength = stats.strength
|
|
80
|
+
const hardness = stats.hardness
|
|
81
|
+
const saturation = stats.saturation
|
|
82
82
|
|
|
83
83
|
const hullmass = 25000 + 75 * density
|
|
84
84
|
|
|
@@ -93,10 +93,10 @@ export function computeContainerT2Capabilities(stats: Record<string, number>): {
|
|
|
93
93
|
hullmass: number
|
|
94
94
|
capacity: number
|
|
95
95
|
} {
|
|
96
|
-
const strength = stats
|
|
97
|
-
const density = stats
|
|
98
|
-
const hardness = stats
|
|
99
|
-
const saturation = stats
|
|
96
|
+
const strength = stats.strength
|
|
97
|
+
const density = stats.density
|
|
98
|
+
const hardness = stats.hardness
|
|
99
|
+
const saturation = stats.saturation
|
|
100
100
|
|
|
101
101
|
const hullmass = 20000 + 50 * density
|
|
102
102
|
|