@shipload/sdk 1.0.0-next.19 → 1.0.0-next.20

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.
@@ -16,8 +16,10 @@ import {
16
16
  RECIPE_NOT_FOUND,
17
17
  ENTITY_CARGO_NOT_LOADED,
18
18
  } from '../errors'
19
- import {getRecipe, type RecipeInput} from '../data/recipes-runtime'
20
- import {getItem} from '../data/catalog'
19
+ import {getEntityLayout, getRecipe, type RecipeInput} from '../data/recipes-runtime'
20
+ import {computeEntityCapabilities} from '../derivation/capabilities'
21
+ import {decodeCraftedItemStats} from '../derivation/crafting'
22
+ import {packedModulesToInstalled, type InstalledModule} from '../entities/slot-multiplier'
21
23
  import {distanceBetweenCoordinates, lerp} from '../travel/travel'
22
24
  import {
23
25
  calcStacksMass,
@@ -63,19 +65,74 @@ export interface Projectable extends ScheduleData {
63
65
  cargo: ServerContract.Types.cargo_item[]
64
66
  cargomass: UInt32
65
67
  owner?: Name
68
+ stats?: bigint
69
+ item_id?: number | UInt16
70
+ modules?: ServerContract.Types.module_entry[] | InstalledModule[]
66
71
  }
67
72
 
68
- function getHullMass(entity: Projectable): UInt32 {
69
- return UInt32.from(entity.hullmass ?? 0)
73
+ function toInstalledModules(
74
+ modules: ServerContract.Types.module_entry[] | InstalledModule[]
75
+ ): InstalledModule[] {
76
+ if (modules.length > 0 && 'itemId' in modules[0]) {
77
+ return modules as InstalledModule[]
78
+ }
79
+ return packedModulesToInstalled(modules as ServerContract.Types.module_entry[])
80
+ }
81
+
82
+ interface ProjectedCaps {
83
+ hullmass?: UInt32
84
+ capacity?: UInt32
85
+ engines?: ServerContract.Types.movement_stats
86
+ generator?: ServerContract.Types.energy_stats
87
+ loaders?: ServerContract.Types.loader_stats
88
+ hauler?: ServerContract.Types.hauler_stats
89
+ }
90
+
91
+ function recomputeCaps(entity: Projectable): ProjectedCaps | undefined {
92
+ if (
93
+ entity.item_id === undefined ||
94
+ entity.modules === undefined ||
95
+ entity.stats === undefined
96
+ ) {
97
+ return undefined
98
+ }
99
+
100
+ const itemId = Number(
101
+ typeof entity.item_id === 'number' ? entity.item_id : entity.item_id.value
102
+ )
103
+ const hullStats = decodeCraftedItemStats(itemId, entity.stats)
104
+ const layout = getEntityLayout(itemId)?.slots ?? []
105
+ const installed = toInstalledModules(entity.modules)
106
+ const caps = computeEntityCapabilities(hullStats, itemId, installed, layout)
107
+
108
+ return {
109
+ hullmass: UInt32.from(caps.hullmass),
110
+ capacity: UInt32.from(caps.capacity),
111
+ engines: caps.engines ? ServerContract.Types.movement_stats.from(caps.engines) : undefined,
112
+ generator: caps.generator
113
+ ? ServerContract.Types.energy_stats.from(caps.generator)
114
+ : undefined,
115
+ loaders: caps.loaders ? ServerContract.Types.loader_stats.from(caps.loaders) : undefined,
116
+ hauler: caps.hauler ? ServerContract.Types.hauler_stats.from(caps.hauler) : undefined,
117
+ }
70
118
  }
71
119
 
72
120
  export function createProjectedEntity(entity: Projectable): ProjectedEntity {
73
- const shipMass = getHullMass(entity)
74
- const loaders = entity.loaders
75
- const engines = entity.engines
76
- const generator = entity.generator
77
- const hauler = entity.hauler
78
- const capacity = entity.capacity
121
+ const needsRecompute =
122
+ entity.hullmass === undefined ||
123
+ entity.loaders === undefined ||
124
+ entity.engines === undefined ||
125
+ entity.generator === undefined ||
126
+ entity.hauler === undefined ||
127
+ entity.capacity === undefined
128
+ const caps = needsRecompute ? recomputeCaps(entity) : undefined
129
+
130
+ const shipMass = UInt32.from(entity.hullmass ?? caps?.hullmass ?? 0)
131
+ const loaders = entity.loaders ?? caps?.loaders
132
+ const engines = entity.engines ?? caps?.engines
133
+ const generator = entity.generator ?? caps?.generator
134
+ const hauler = entity.hauler ?? caps?.hauler
135
+ const capacity = entity.capacity ?? caps?.capacity
79
136
 
80
137
  const cargo: CargoStack[] = entity.cargo.map(cargoItemToStack)
81
138
 
@@ -344,19 +401,10 @@ function validateCraftTask(task: ServerContract.Types.task, projected: Projected
344
401
  let matched = false
345
402
  for (let ri = 0; ri < recipe.length; ri++) {
346
403
  const req = recipe[ri]
347
- if ('itemId' in req) {
348
- if (input.item_id.toNumber() === req.itemId) {
349
- groupedInputs[ri].push(input)
350
- matched = true
351
- break
352
- }
353
- } else {
354
- const item = getItem(input.item_id)
355
- if (item.category === req.category && item.tier === req.tier) {
356
- groupedInputs[ri].push(input)
357
- matched = true
358
- break
359
- }
404
+ if (input.item_id.toNumber() === req.itemId) {
405
+ groupedInputs[ri].push(input)
406
+ matched = true
407
+ break
360
408
  }
361
409
  }
362
410
  if (!matched) throw new Error(RECIPE_INPUTS_INVALID)