@shipload/sdk 1.0.0-next.50 → 1.0.0-next.52

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.
Files changed (58) hide show
  1. package/lib/shipload.d.ts +544 -149
  2. package/lib/shipload.js +2424 -448
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +2390 -447
  5. package/lib/shipload.m.js.map +1 -1
  6. package/lib/testing.d.ts +131 -7
  7. package/lib/testing.js +469 -11
  8. package/lib/testing.js.map +1 -1
  9. package/lib/testing.m.js +470 -12
  10. package/lib/testing.m.js.map +1 -1
  11. package/package.json +1 -1
  12. package/src/capabilities/crafting.ts +10 -1
  13. package/src/capabilities/gathering.ts +1 -1
  14. package/src/capabilities/hauling.ts +0 -5
  15. package/src/capabilities/modules.ts +6 -0
  16. package/src/capabilities/movement.ts +1 -1
  17. package/src/contracts/server.ts +315 -8
  18. package/src/data/capabilities.ts +11 -2
  19. package/src/data/entities.json +235 -20
  20. package/src/data/item-ids.ts +10 -0
  21. package/src/data/items.json +61 -0
  22. package/src/data/kind-registry.json +53 -1
  23. package/src/data/kind-registry.ts +5 -0
  24. package/src/data/metadata.ts +74 -5
  25. package/src/data/recipes-runtime.ts +1 -0
  26. package/src/data/recipes.json +887 -118
  27. package/src/derivation/capabilities.test.ts +81 -4
  28. package/src/derivation/capabilities.ts +162 -57
  29. package/src/derivation/crafting.ts +2 -0
  30. package/src/derivation/recipe-usage.test.ts +10 -7
  31. package/src/derivation/rollups.ts +16 -0
  32. package/src/derivation/stat-scaling.ts +12 -0
  33. package/src/entities/makers.ts +10 -1
  34. package/src/index-module.ts +33 -3
  35. package/src/managers/actions.ts +89 -44
  36. package/src/managers/construction-types.ts +2 -2
  37. package/src/managers/construction.ts +15 -15
  38. package/src/managers/plot.ts +1 -1
  39. package/src/nft/buildImmutableData.ts +55 -9
  40. package/src/nft/description.ts +99 -36
  41. package/src/planner/planner.test.ts +50 -41
  42. package/src/resolution/resolve-item.test.ts +1 -1
  43. package/src/resolution/resolve-item.ts +26 -11
  44. package/src/scheduling/availability.ts +7 -6
  45. package/src/scheduling/cancel.test.ts +40 -6
  46. package/src/scheduling/cancel.ts +21 -29
  47. package/src/scheduling/jobs.ts +71 -0
  48. package/src/scheduling/lanes.ts +29 -0
  49. package/src/scheduling/projection.ts +42 -25
  50. package/src/scheduling/task-cargo.ts +1 -1
  51. package/src/testing/projection-parity.ts +2 -2
  52. package/src/travel/reach.ts +4 -6
  53. package/src/travel/route-planner.ts +60 -49
  54. package/src/travel/route-simulator.ts +170 -0
  55. package/src/travel/travel.ts +40 -5
  56. package/src/types/capabilities.ts +9 -3
  57. package/src/types.ts +8 -3
  58. package/src/managers/flatten-gather-plan.test.ts +0 -80
@@ -29,6 +29,7 @@ export type energy_stats = ServerContract.Types.energy_stats
29
29
  export type schedule = ServerContract.Types.schedule
30
30
  export type lane = ServerContract.Types.lane
31
31
  export type task = ServerContract.Types.task
32
+ export type coupling = ServerContract.Types.coupling
32
33
  export type cargo_item = ServerContract.Types.cargo_item
33
34
  export type entity_row = ServerContract.Types.entity_row
34
35
 
@@ -177,6 +178,8 @@ export {
177
178
  calc_acceleration,
178
179
  calc_energyusage,
179
180
  calc_flighttime,
181
+ calc_travel_flighttime,
182
+ calc_group_flighttime,
180
183
  calc_loader_acceleration,
181
184
  calc_loader_flighttime,
182
185
  calc_onesided_duration,
@@ -214,7 +217,7 @@ export type {
214
217
  HasScheduleAndLocation,
215
218
  } from './travel/travel'
216
219
 
217
- export {planRoute, sdkSystemGraph, setScanProvider, MAX_LEGS} from './travel/route-planner'
220
+ export {planRoute, sdkSystemGraph, MAX_LEGS} from './travel/route-planner'
218
221
  export type {
219
222
  Coord,
220
223
  Neighbor,
@@ -225,11 +228,17 @@ export type {
225
228
  RouteResult,
226
229
  RouteFailureReason,
227
230
  PlanRouteParams,
231
+ RouteLegInput,
232
+ RouteLegCost,
233
+ RouteHeuristicCost,
228
234
  } from './travel/route-planner'
229
235
 
230
236
  export {computePerLegReach, computeGroupPerLegReach} from './travel/reach'
231
237
  export type {ReachStats} from './travel/reach'
232
238
 
239
+ export {simulateRoute} from './travel/route-simulator'
240
+ export type {RouteMoverInput, RouteLegSim, RouteSim} from './travel/route-simulator'
241
+
233
242
  export * as schedule from './scheduling/schedule'
234
243
  export {LANE_MOBILITY, LANE_BARRIER} from './scheduling/schedule'
235
244
  export type {
@@ -244,6 +253,7 @@ export {
244
253
  rawScheduleEnd,
245
254
  resolveLaneGatherer,
246
255
  resolveLaneCrafter,
256
+ resolveLaneBuilder,
247
257
  resolveLaneLoader,
248
258
  selectGatherLane,
249
259
  workerLaneKey,
@@ -278,6 +288,9 @@ export type {
278
288
  export {taskCargoChanges} from './scheduling/task-cargo'
279
289
  export type {TaskCargoChange, TaskCargoDirection} from './scheduling/task-cargo'
280
290
 
291
+ export {jobsToLanes, pickFabricator, socketTail, JOB_QUEUE_CAP} from './scheduling/jobs'
292
+ export type {JobWindow, JobLane, JobLaneEntry} from './scheduling/jobs'
293
+
281
294
  export {composeIdleResolve} from './scheduling/idle-resolve'
282
295
  export type {CounterpartLookup, IdleResolveTarget} from './scheduling/idle-resolve'
283
296
 
@@ -320,6 +333,7 @@ export {
320
333
  ENTITY_WAREHOUSE,
321
334
  ENTITY_EXTRACTOR,
322
335
  ENTITY_FACTORY,
336
+ ENTITY_WORKSHOP,
323
337
  ENTITY_CONTAINER,
324
338
  ENTITY_NEXUS,
325
339
  ENTITY_HUB,
@@ -337,6 +351,7 @@ export {
337
351
  isWarehouse,
338
352
  isExtractor,
339
353
  isFactory,
354
+ isWorkshop,
340
355
  isContainer,
341
356
  isNexus,
342
357
  isPlot,
@@ -424,6 +439,7 @@ export {
424
439
  computeHaulerCapabilities,
425
440
  computeLoaderCapabilities,
426
441
  computeCrafterCapabilities,
442
+ computeBuilderCapabilities,
427
443
  computeWarehouseHullCapabilities,
428
444
  computeStorageCapabilities,
429
445
  computeBatteryCapabilities,
@@ -432,6 +448,8 @@ export {
432
448
  computeLauncherCapabilities,
433
449
  computeBaseCapacity,
434
450
  computeEntityCapabilities,
451
+ getBaseHullmassFor,
452
+ DEFAULT_BASE_HULLMASS,
435
453
  CAPACITY_TIER_TABLE,
436
454
  capacityTierMultiplier,
437
455
  applyCapacityTier,
@@ -439,7 +457,11 @@ export {
439
457
  GATHERER_DEPTH_MAX_TIER,
440
458
  gathererDepthForTier,
441
459
  } from './derivation/capabilities'
442
- export type {GathererDepthParams, ComputedCapabilities} from './derivation/capabilities'
460
+ export type {
461
+ GathererDepthParams,
462
+ ComputedCapabilities,
463
+ TravelDrainBreakdown,
464
+ } from './derivation/capabilities'
443
465
 
444
466
  export {
445
467
  WH,
@@ -453,7 +475,7 @@ export {
453
475
  isValidWormholePair,
454
476
  } from './derivation/wormhole'
455
477
 
456
- export {rollupGatherer, rollupCrafter, rollupLoaders} from './derivation/rollups'
478
+ export {rollupGatherer, rollupCrafter, rollupBuilder, rollupLoaders} from './derivation/rollups'
457
479
 
458
480
  export {resolveItem} from './resolution/resolve-item'
459
481
  export type {
@@ -518,6 +540,11 @@ export {
518
540
  ATOMICASSETS_ACCOUNT,
519
541
  SHIPLOAD_COLLECTION,
520
542
  } from './nft/atomicassets'
543
+ export {
544
+ MODULE_STAT_SCALING_ANCHOR,
545
+ MODULE_STAT_SCALING_POST_ANCHOR_PERCENT,
546
+ computeEffectiveModuleStat,
547
+ } from './derivation/stat-scaling'
521
548
  export type {
522
549
  AtomicAssetRow,
523
550
  AtomicSchemaRow,
@@ -534,6 +561,7 @@ export {
534
561
  computeBaseHullmass,
535
562
  computeBaseCapacityShip,
536
563
  computeBaseCapacityWarehouse,
564
+ computeBaseCapacityContainer,
537
565
  computeEngineThrust,
538
566
  computeEngineDrain,
539
567
  computeTravelDrain,
@@ -549,6 +577,8 @@ export {
549
577
  computeLoaderThrust,
550
578
  computeCrafterSpeed,
551
579
  computeCrafterDrain,
580
+ computeBuilderSpeed,
581
+ computeBuilderDrain,
552
582
  computeHaulerCapacity,
553
583
  computeHaulerEfficiency,
554
584
  computeWarpRange,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  Action,
3
+ Bytes,
3
4
  Checksum256,
4
5
  type Checksum256Type,
5
6
  Int64,
6
7
  type Int64Type,
7
8
  Name,
8
9
  type NameType,
9
- Transaction,
10
10
  UInt8,
11
11
  type UInt8Type,
12
12
  UInt16,
@@ -21,7 +21,6 @@ import {Coordinates, PRECISION, type ClusterSlotType, type CoordinatesType} from
21
21
  import {ServerContract} from '../contracts'
22
22
  import {ATOMICASSETS_ABI, SHIPLOAD_COLLECTION} from '../nft/atomicassets'
23
23
  import {getItem} from '../data/catalog'
24
- import type {GatherPlan} from '../planner'
25
24
 
26
25
  const CHARGE_K = 1n
27
26
  const ENERGY_DIVISOR = 1_000_000n
@@ -162,6 +161,8 @@ export type EntityRefInput = {
162
161
  entityId: UInt64Type
163
162
  }
164
163
 
164
+ export type WaypointInput = {x: Int64Type; y: Int64Type}
165
+
165
166
  export class ActionsManager extends BaseManager {
166
167
  travel(shipId: UInt64Type, destination: CoordinatesType, recharge = true): Action {
167
168
  const x = Int64.from(destination.x)
@@ -197,6 +198,18 @@ export class ActionsManager extends BaseManager {
197
198
  })
198
199
  }
199
200
 
201
+ travelplan(entities: EntityRefInput[], waypoints: WaypointInput[], recharge = true): Action {
202
+ const entityRefs = this.entityRefs(entities)
203
+ const wps = waypoints.map((w) =>
204
+ ServerContract.Types.route_waypoint.from({x: Int64.from(w.x), y: Int64.from(w.y)})
205
+ )
206
+ return this.server.action('travelplan', {
207
+ entities: entityRefs,
208
+ waypoints: wps,
209
+ recharge,
210
+ })
211
+ }
212
+
200
213
  transit(shipId: UInt64Type, entrance: CoordinatesType, exit: CoordinatesType): Action {
201
214
  return this.server.action('transit', {
202
215
  id: UInt64.from(shipId),
@@ -302,6 +315,20 @@ export class ActionsManager extends BaseManager {
302
315
  })
303
316
  }
304
317
 
318
+ shuttle(
319
+ carrierId: UInt64Type,
320
+ fromId: UInt64Type,
321
+ toId: UInt64Type,
322
+ items: ServerContract.ActionParams.Type.cargo_item[]
323
+ ): Action {
324
+ return this.server.action('shuttle', {
325
+ carrier: UInt64.from(carrierId),
326
+ from_id: UInt64.from(fromId),
327
+ to_id: UInt64.from(toId),
328
+ items,
329
+ })
330
+ }
331
+
305
332
  launch(
306
333
  launcherId: UInt64Type,
307
334
  catcherId: UInt64Type,
@@ -374,48 +401,22 @@ export class ActionsManager extends BaseManager {
374
401
  return this.server.action('gather', params)
375
402
  }
376
403
 
377
- // Packs N gather actions into one Transaction; the wallet/session fills in TAPoS at sign time.
378
- bundleGather(
379
- gathers: {
380
- sourceId: UInt64Type
381
- destinationId: UInt64Type
382
- stratum: UInt16Type
383
- quantity: UInt32Type
384
- slot?: UInt8Type
385
- }[]
386
- ): Transaction {
387
- const actions = gathers.map(({sourceId, destinationId, stratum, quantity, slot}) =>
388
- this.gather(sourceId, destinationId, stratum, quantity, slot)
389
- )
390
- return Transaction.from({
391
- expiration: 0,
392
- ref_block_num: 0,
393
- ref_block_prefix: 0,
394
- actions,
395
- })
396
- }
397
-
398
- // Mirrors the contract's projected_energy walk: recharge (if due) then gathers, per cycle.
399
- flattenGatherPlan(
400
- plan: GatherPlan,
401
- ctx: {sourceId: UInt64Type; destinationId: UInt64Type; stratum: UInt16Type}
402
- ): Action[] {
403
- const actions: Action[] = []
404
- for (const cycle of plan.cycles) {
405
- if (cycle.rechargeBefore) actions.push(this.recharge(ctx.sourceId))
406
- for (const limpet of cycle.limpets) {
407
- actions.push(
408
- this.gather(
409
- ctx.sourceId,
410
- ctx.destinationId,
411
- ctx.stratum,
412
- limpet.quantity,
413
- limpet.slot
414
- )
415
- )
416
- }
417
- }
418
- return actions
404
+ gatherplan(
405
+ sourceId: UInt64Type,
406
+ destinationId: UInt64Type,
407
+ stratum: UInt16Type,
408
+ quantity: UInt32Type,
409
+ recharge = true,
410
+ slots: number[] = []
411
+ ): Action {
412
+ return this.server.action('gatherplan', {
413
+ source_id: UInt64.from(sourceId),
414
+ destination_id: UInt64.from(destinationId),
415
+ stratum: UInt16.from(stratum),
416
+ quantity: UInt32.from(quantity),
417
+ recharge,
418
+ slots: Bytes.from(slots),
419
+ })
419
420
  }
420
421
 
421
422
  warp(entityId: UInt64Type, destination: CoordinatesType): Action {
@@ -452,6 +453,50 @@ export class ActionsManager extends BaseManager {
452
453
  return this.server.action('craft', params)
453
454
  }
454
455
 
456
+ craftjob(
457
+ shipId: UInt64Type,
458
+ workshopId: UInt64Type,
459
+ slot: UInt8Type,
460
+ recipeId: UInt16Type,
461
+ quantity: UInt32Type,
462
+ inputs: ServerContract.ActionParams.Type.cargo_item[]
463
+ ): Action {
464
+ const params: ServerContract.ActionParams.craftjob = {
465
+ ship_id: UInt64.from(shipId),
466
+ workshop_id: UInt64.from(workshopId),
467
+ slot: UInt8.from(slot),
468
+ recipe_id: UInt16.from(recipeId),
469
+ quantity: UInt32.from(quantity),
470
+ inputs,
471
+ }
472
+ return this.server.action('craftjob', params)
473
+ }
474
+
475
+ claimjob(jobId: UInt64Type, shipId: UInt64Type): Action {
476
+ const params: ServerContract.ActionParams.claimjob = {
477
+ job_id: UInt64.from(jobId),
478
+ ship_id: UInt64.from(shipId),
479
+ }
480
+ return this.server.action('claimjob', params)
481
+ }
482
+
483
+ canceljob(jobId: UInt64Type, shipId: UInt64Type): Action {
484
+ const params: ServerContract.ActionParams.canceljob = {
485
+ job_id: UInt64.from(jobId),
486
+ ship_id: UInt64.from(shipId),
487
+ }
488
+ return this.server.action('canceljob', params)
489
+ }
490
+
491
+ setsocket(workshopId: UInt64Type, slot: UInt8Type, open: boolean): Action {
492
+ const params: ServerContract.ActionParams.setsocket = {
493
+ workshop_id: UInt64.from(workshopId),
494
+ slot: UInt8.from(slot),
495
+ open,
496
+ }
497
+ return this.server.action('setsocket', params)
498
+ }
499
+
455
500
  blend(entityId: UInt64Type, inputs: ServerContract.ActionParams.Type.cargo_item[]): Action {
456
501
  return this.server.action('blend', {
457
502
  id: UInt64.from(entityId),
@@ -6,7 +6,7 @@ import type {PlotProgress} from './plot'
6
6
 
7
7
  export type BuildState = 'initializing' | 'accepting' | 'ready' | 'scheduled' | 'finalizing'
8
8
 
9
- export type FinalizerCapability = 'crafter'
9
+ export type FinalizerCapability = 'builder'
10
10
 
11
11
  export interface BuildableTarget {
12
12
  entityId: UInt64
@@ -49,7 +49,7 @@ export interface FinalizerEntityRef {
49
49
  entityType: Name
50
50
  name: string
51
51
  capability: FinalizerCapability
52
- crafterSpeed: number
52
+ builderSpeed: number
53
53
  estimatedDuration: UInt32
54
54
  }
55
55
 
@@ -3,7 +3,7 @@ import {BaseManager} from './base'
3
3
  import type {ServerContract} from '../contracts'
4
4
  import {PlotManager} from './plot'
5
5
  import {getItem} from '../data/catalog'
6
- import {calc_craft_duration} from '../capabilities/crafting'
6
+ import {calc_build_duration} from '../capabilities/crafting'
7
7
  import {getLanes, getTasks} from '../scheduling/schedule'
8
8
  import {HoldKind, TaskType} from '../types'
9
9
  import type {
@@ -67,15 +67,15 @@ export class ConstructionManager extends BaseManager {
67
67
  if (!entity.owner.equals(target.ownerName)) continue
68
68
  if (entity.id.equals(target.entityId)) continue
69
69
  if (!coordsEqual(entity.coordinates, target.coordinates)) continue
70
- const crafterLanes = entity.crafter_lanes ?? []
71
- if (crafterLanes.length === 0) continue
72
- const speed = crafterLanes.reduce((s, l) => s + Number(l.speed), 0)
70
+ const builderLanes = entity.builder_lanes ?? []
71
+ if (builderLanes.length === 0) continue
72
+ const speed = builderLanes.reduce((s, l) => s + Number(l.speed), 0)
73
73
  out.push({
74
74
  entityId: entity.id,
75
75
  entityType: entity.type,
76
76
  name: entity.entity_name,
77
- capability: 'crafter',
78
- crafterSpeed: speed,
77
+ capability: 'builder',
78
+ builderSpeed: speed,
79
79
  estimatedDuration: this.estimateFinalizeDuration(target, speed),
80
80
  })
81
81
  }
@@ -105,10 +105,10 @@ export class ConstructionManager extends BaseManager {
105
105
  for (const task of lane.schedule.tasks) {
106
106
  cumulativeSec += task.duration.toNumber()
107
107
  if (!isPushTask(task)) continue
108
- if (!task.entitytarget) continue
108
+ if (task.couplings.length === 0) continue
109
109
  const projectedEndMs = startedMs + cumulativeSec * 1000
110
110
  if (projectedEndMs < nowMs) continue
111
- const targetIdStr = task.entitytarget.entity_id.toString()
111
+ const targetIdStr = task.couplings[0].counterpart.entity_id.toString()
112
112
  const etaSeconds = Math.max(0, Math.round((projectedEndMs - nowMs) / 1000))
113
113
  let perTarget = buckets.get(targetIdStr)
114
114
  if (!perTarget) {
@@ -263,8 +263,8 @@ export class ConstructionManager extends BaseManager {
263
263
  return reservationsOf(source)
264
264
  }
265
265
 
266
- estimateFinalizeDuration(target: BuildableTarget, crafterSpeed: number): UInt32 {
267
- return calc_craft_duration(crafterSpeed, target.progress.massRequired)
266
+ estimateFinalizeDuration(target: BuildableTarget, builderSpeed: number): UInt32 {
267
+ return calc_build_duration(builderSpeed, target.progress.massRequired)
268
268
  }
269
269
 
270
270
  static isConstructionKind(kind: string): boolean {
@@ -370,8 +370,8 @@ function isPushTask(task: ServerContract.Types.task): boolean {
370
370
  function isBuildOfPlot(task: ServerContract.Types.task, plotId: UInt64): boolean {
371
371
  return (
372
372
  task.type.toNumber() === TaskType.BUILDPLOT &&
373
- task.entitytarget !== undefined &&
374
- task.entitytarget.entity_id.equals(plotId)
373
+ task.couplings.length > 0 &&
374
+ task.couplings[0].counterpart.entity_id.equals(plotId)
375
375
  )
376
376
  }
377
377
 
@@ -379,9 +379,9 @@ function reservationsOf(source: ServerContract.Types.entity_info): Reservation[]
379
379
  const out = new Map<string, Reservation>()
380
380
  for (const task of getTasks(source)) {
381
381
  if (!isPushTask(task)) continue
382
- if (!task.entitytarget) continue
383
- const targetType = task.entitytarget.entity_type
384
- const targetId = task.entitytarget.entity_id
382
+ if (task.couplings.length === 0) continue
383
+ const targetType = task.couplings[0].counterpart.entity_type
384
+ const targetId = task.couplings[0].counterpart.entity_id
385
385
  for (const c of task.cargo) {
386
386
  const itemId = c.item_id.toNumber()
387
387
  const quantity = c.quantity.toNumber()
@@ -100,7 +100,7 @@ export class PlotManager extends BaseManager {
100
100
  recipe,
101
101
  progress,
102
102
  finalizeAction: Name.from('buildplot'),
103
- finalizerCapability: 'crafter',
103
+ finalizerCapability: 'builder',
104
104
  activeTask,
105
105
  scheduledBuild,
106
106
  }
@@ -3,6 +3,7 @@ import {getItem} from '../data/catalog'
3
3
  import {
4
4
  getModuleCapabilityType,
5
5
  MODULE_BATTERY,
6
+ MODULE_BUILDER,
6
7
  MODULE_CRAFTER,
7
8
  MODULE_ENGINE,
8
9
  MODULE_GATHERER,
@@ -13,11 +14,14 @@ import {
13
14
  MODULE_WARP,
14
15
  } from '../capabilities/modules'
15
16
  import {decodeStat, decodeCraftedItemStats} from '../derivation/crafting'
17
+ import {computeEffectiveModuleStat} from '../derivation/stat-scaling'
16
18
  import {getStatDefinitions} from '../derivation/stats'
17
19
  import type {ResourceCategory} from '../types'
18
20
  import {Types as ServerTypes} from '../contracts/server'
19
21
  import {
20
22
  buildEntityDescription,
23
+ computeBuilderDrain,
24
+ computeBuilderSpeed,
21
25
  computeCrafterDrain,
22
26
  computeCrafterSpeed,
23
27
  computeEngineDrain,
@@ -28,6 +32,7 @@ import {
28
32
  computeGeneratorCap,
29
33
  computeGeneratorRech,
30
34
  computeCargoBayCapacity,
35
+ computeCargoBayDrain,
31
36
  computeBatteryBankCapacity,
32
37
  computeHaulerCapacity,
33
38
  computeHaulerDrain,
@@ -75,6 +80,10 @@ export function moduleSlotsForImmutable(
75
80
 
76
81
  const IMAGE_HOST_URL = 'https://item.shiploadgame.com/item'
77
82
 
83
+ function toWholeEnergy(milli: number): number {
84
+ return Math.floor((milli + 500) / 1000)
85
+ }
86
+
78
87
  function bytesToBase64Url(bytes: Uint8Array): string {
79
88
  let binary = ''
80
89
  for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]!)
@@ -183,8 +192,14 @@ export function buildModuleImmutable(
183
192
  const thm = decodeStat(stats, 1)
184
193
  base.push({first: 'volatility', second: ['uint16', vol]})
185
194
  base.push({first: 'thermal', second: ['uint16', thm]})
186
- base.push({first: 'thrust', second: ['uint32', computeEngineThrust(vol)]})
187
- base.push({first: 'drain', second: ['uint16', computeEngineDrain(thm)]})
195
+ base.push({
196
+ first: 'thrust',
197
+ second: ['uint32', computeEngineThrust(computeEffectiveModuleStat(vol))],
198
+ })
199
+ base.push({
200
+ first: 'drain',
201
+ second: ['uint16', computeEngineDrain(computeEffectiveModuleStat(thm))],
202
+ })
188
203
  break
189
204
  }
190
205
  case MODULE_GENERATOR: {
@@ -192,8 +207,20 @@ export function buildModuleImmutable(
192
207
  const ref = decodeStat(stats, 1)
193
208
  base.push({first: 'resonance', second: ['uint16', res]})
194
209
  base.push({first: 'reflectivity', second: ['uint16', ref]})
195
- base.push({first: 'capacity', second: ['uint16', computeGeneratorCap(res)]})
196
- base.push({first: 'recharge', second: ['uint16', computeGeneratorRech(ref)]})
210
+ base.push({
211
+ first: 'capacity',
212
+ second: [
213
+ 'uint16',
214
+ toWholeEnergy(computeGeneratorCap(computeEffectiveModuleStat(res))),
215
+ ],
216
+ })
217
+ base.push({
218
+ first: 'recharge',
219
+ second: [
220
+ 'uint16',
221
+ toWholeEnergy(computeGeneratorRech(computeEffectiveModuleStat(ref))),
222
+ ],
223
+ })
197
224
  break
198
225
  }
199
226
  case MODULE_GATHERER: {
@@ -204,7 +231,10 @@ export function buildModuleImmutable(
204
231
  base.push({first: 'hardness', second: ['uint16', hrd]})
205
232
  base.push({first: 'saturation', second: ['uint16', sat]})
206
233
  base.push({first: 'yield', second: ['uint16', computeGathererYield(str)]})
207
- base.push({first: 'drain', second: ['uint16', computeGathererDrain(sat)]})
234
+ base.push({
235
+ first: 'drain',
236
+ second: ['uint16', toWholeEnergy(computeGathererDrain(sat))],
237
+ })
208
238
  base.push({first: 'depth', second: ['uint16', computeGathererDepth(hrd, item.tier)]})
209
239
  break
210
240
  }
@@ -229,7 +259,16 @@ export function buildModuleImmutable(
229
259
  base.push({first: 'fineness', second: ['uint16', fin]})
230
260
  base.push({first: 'conductivity', second: ['uint16', con]})
231
261
  base.push({first: 'speed', second: ['uint16', computeCrafterSpeed(fin)]})
232
- base.push({first: 'drain', second: ['uint16', computeCrafterDrain(con)]})
262
+ base.push({first: 'drain', second: ['uint16', toWholeEnergy(computeCrafterDrain(con))]})
263
+ break
264
+ }
265
+ case MODULE_BUILDER: {
266
+ const coh = decodeStat(stats, 0)
267
+ const tol = decodeStat(stats, 1)
268
+ base.push({first: 'cohesion', second: ['uint16', coh]})
269
+ base.push({first: 'tolerance', second: ['uint16', tol]})
270
+ base.push({first: 'speed', second: ['uint16', computeBuilderSpeed(coh)]})
271
+ base.push({first: 'drain', second: ['uint16', toWholeEnergy(computeBuilderDrain(tol))]})
233
272
  break
234
273
  }
235
274
  case MODULE_STORAGE: {
@@ -243,7 +282,11 @@ export function buildModuleImmutable(
243
282
  base.push({first: 'cohesion', second: ['uint16', com]})
244
283
  base.push({
245
284
  first: 'capacity',
246
- second: ['uint32', computeCargoBayCapacity(str, den, hrd, com)],
285
+ second: ['uint32', computeCargoBayCapacity(str, den, hrd)],
286
+ })
287
+ base.push({
288
+ first: 'drain',
289
+ second: ['uint16', toWholeEnergy(computeCargoBayDrain(com, item.tier))],
247
290
  })
248
291
  break
249
292
  }
@@ -258,7 +301,7 @@ export function buildModuleImmutable(
258
301
  base.push({first: 'insulation', second: ['uint16', ins]})
259
302
  base.push({
260
303
  first: 'capacity',
261
- second: ['uint32', computeBatteryBankCapacity(vol, thm, pla, ins)],
304
+ second: ['uint32', toWholeEnergy(computeBatteryBankCapacity(vol, thm, pla, ins))],
262
305
  })
263
306
  break
264
307
  }
@@ -271,7 +314,10 @@ export function buildModuleImmutable(
271
314
  base.push({first: 'conductivity', second: ['uint16', con]})
272
315
  base.push({first: 'capacity', second: ['uint8', computeHaulerCapacity(res, item.tier)]})
273
316
  base.push({first: 'efficiency', second: ['uint16', computeHaulerEfficiency(pla)]})
274
- base.push({first: 'drain', second: ['uint16', computeHaulerDrain(con)]})
317
+ base.push({
318
+ first: 'drain',
319
+ second: ['uint16', toWholeEnergy(computeHaulerDrain(con, item.tier))],
320
+ })
275
321
  break
276
322
  }
277
323
  }