@shipload/sdk 1.0.0-next.7 → 1.0.0-next.70

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 (203) hide show
  1. package/lib/scan.d.ts +52 -0
  2. package/lib/scan.js +162 -0
  3. package/lib/scan.js.map +1 -0
  4. package/lib/scan.m.js +152 -0
  5. package/lib/scan.m.js.map +1 -0
  6. package/lib/shipload.d.ts +5696 -1503
  7. package/lib/shipload.js +20294 -5200
  8. package/lib/shipload.js.map +1 -1
  9. package/lib/shipload.m.js +20371 -5683
  10. package/lib/shipload.m.js.map +1 -1
  11. package/lib/testing.d.ts +1648 -0
  12. package/lib/testing.js +6980 -0
  13. package/lib/testing.js.map +1 -0
  14. package/lib/testing.m.js +6974 -0
  15. package/lib/testing.m.js.map +1 -0
  16. package/package.json +20 -2
  17. package/src/capabilities/craftable.test.ts +82 -0
  18. package/src/capabilities/craftable.ts +82 -0
  19. package/src/capabilities/crafting.test.ts +80 -0
  20. package/src/capabilities/crafting.ts +50 -8
  21. package/src/capabilities/gathering.test.ts +29 -0
  22. package/src/capabilities/gathering.ts +38 -20
  23. package/src/capabilities/hauling.ts +0 -5
  24. package/src/capabilities/index.ts +0 -1
  25. package/src/capabilities/modules.ts +27 -30
  26. package/src/capabilities/movement.ts +1 -1
  27. package/src/capabilities/storage.test.ts +26 -0
  28. package/src/capabilities/storage.ts +22 -7
  29. package/src/contracts/fund.ts +306 -0
  30. package/src/contracts/platform.ts +312 -3
  31. package/src/contracts/server.ts +2661 -466
  32. package/src/contracts/token.ts +170 -0
  33. package/src/contracts.ts +2 -0
  34. package/src/coordinates/address.ts +88 -0
  35. package/src/coordinates/constants.test.ts +15 -0
  36. package/src/coordinates/constants.ts +23 -0
  37. package/src/coordinates/index.ts +15 -0
  38. package/src/coordinates/memo.test.ts +47 -0
  39. package/src/coordinates/memo.ts +20 -0
  40. package/src/coordinates/permutation.ts +77 -0
  41. package/src/coordinates/regions.ts +48 -0
  42. package/src/coordinates/sectors.ts +115 -0
  43. package/src/data/capabilities.ts +49 -18
  44. package/src/data/capability-formulas.ts +26 -14
  45. package/src/data/catalog.test.ts +19 -0
  46. package/src/data/catalog.ts +13 -3
  47. package/src/data/charters.json +396 -0
  48. package/src/data/citizenry-adjectives.json +42 -0
  49. package/src/data/citizenry-nouns.json +50 -0
  50. package/src/data/colors.ts +14 -32
  51. package/src/data/entities.json +421 -15
  52. package/src/data/item-ids.ts +53 -13
  53. package/src/data/items.json +330 -77
  54. package/src/data/kind-registry.json +212 -0
  55. package/src/data/kind-registry.ts +192 -0
  56. package/src/data/metadata.ts +312 -51
  57. package/src/data/recipes-runtime.ts +6 -23
  58. package/src/data/recipes.json +2173 -173
  59. package/src/data/tiers.ts +9 -6
  60. package/src/derivation/build-methods.test.ts +71 -0
  61. package/src/derivation/build-methods.ts +50 -0
  62. package/src/derivation/capabilities.test.ts +348 -0
  63. package/src/derivation/capabilities.ts +707 -0
  64. package/src/derivation/capability-mappings.ts +60 -16
  65. package/src/derivation/crafting.test.ts +17 -0
  66. package/src/derivation/crafting.ts +57 -34
  67. package/src/derivation/index.ts +27 -2
  68. package/src/derivation/recipe-usage.test.ts +88 -0
  69. package/src/derivation/recipe-usage.ts +141 -0
  70. package/src/derivation/reserve-regen.ts +34 -0
  71. package/src/derivation/resources.ts +9 -1
  72. package/src/derivation/rollups.test.ts +55 -0
  73. package/src/derivation/rollups.ts +72 -0
  74. package/src/derivation/stars.test.ts +67 -0
  75. package/src/derivation/stars.ts +25 -0
  76. package/src/derivation/stat-scaling.ts +12 -0
  77. package/src/derivation/stats.ts +6 -6
  78. package/src/derivation/strata.ts +5 -3
  79. package/src/derivation/stratum.ts +26 -22
  80. package/src/derivation/tiers.ts +40 -7
  81. package/src/derivation/upgrades.ts +14 -0
  82. package/src/derivation/wormhole.ts +154 -0
  83. package/src/entities/entity.ts +102 -0
  84. package/src/entities/gamestate.ts +3 -28
  85. package/src/entities/makers.ts +144 -136
  86. package/src/entities/slot-multiplier.ts +43 -0
  87. package/src/entity/hydrate.test.ts +156 -0
  88. package/src/entity/hydrate.ts +86 -0
  89. package/src/errors.ts +21 -16
  90. package/src/format.ts +42 -9
  91. package/src/index-module.ts +411 -32
  92. package/src/influence/ballot.test.ts +103 -0
  93. package/src/influence/ballot.ts +98 -0
  94. package/src/influence/categories.ts +32 -0
  95. package/src/influence/charter-metadata.test.ts +136 -0
  96. package/src/influence/charter-metadata.ts +236 -0
  97. package/src/influence/charters.test.ts +112 -0
  98. package/src/influence/charters.ts +150 -0
  99. package/src/influence/citizenry.ts +38 -0
  100. package/src/influence/civic-shuttle.test.ts +202 -0
  101. package/src/influence/civic-shuttle.ts +142 -0
  102. package/src/influence/civic.test.ts +287 -0
  103. package/src/influence/civic.ts +269 -0
  104. package/src/influence/constants.ts +84 -0
  105. package/src/influence/decay.ts +20 -0
  106. package/src/influence/decomp.ts +95 -0
  107. package/src/influence/demand.ts +106 -0
  108. package/src/influence/duration.ts +101 -0
  109. package/src/influence/index.ts +118 -0
  110. package/src/influence/influence.test.ts +450 -0
  111. package/src/influence/quality.ts +25 -0
  112. package/src/influence/valuation.ts +154 -0
  113. package/src/managers/actions.ts +940 -93
  114. package/src/managers/balances.test.ts +161 -0
  115. package/src/managers/balances.ts +93 -0
  116. package/src/managers/base.ts +10 -2
  117. package/src/managers/cluster.test.ts +39 -0
  118. package/src/managers/cluster.ts +53 -0
  119. package/src/managers/construction-types.ts +80 -0
  120. package/src/managers/construction.ts +453 -0
  121. package/src/managers/context.ts +58 -1
  122. package/src/managers/coordinates.ts +14 -0
  123. package/src/managers/entities.ts +35 -63
  124. package/src/managers/epochs.ts +72 -1
  125. package/src/managers/index.ts +38 -1
  126. package/src/managers/influence.test.ts +56 -0
  127. package/src/managers/influence.ts +425 -0
  128. package/src/managers/jobs.test.ts +80 -0
  129. package/src/managers/jobs.ts +54 -0
  130. package/src/managers/locations.ts +25 -29
  131. package/src/managers/nft.test.ts +21 -0
  132. package/src/managers/nft.ts +110 -0
  133. package/src/managers/players.ts +25 -0
  134. package/src/managers/plot.ts +122 -0
  135. package/src/nft/atomicassets.abi.json +1342 -0
  136. package/src/nft/atomicassets.ts +237 -0
  137. package/src/nft/atomicdata.ts +130 -0
  138. package/src/nft/buildImmutableData.ts +388 -0
  139. package/src/nft/description.ts +222 -100
  140. package/src/nft/index.ts +3 -0
  141. package/src/planner/index.ts +296 -0
  142. package/src/planner/planner.test.ts +459 -0
  143. package/src/receipts.ts +22 -0
  144. package/src/resolution/describe-module.ts +43 -25
  145. package/src/resolution/display-name.ts +39 -11
  146. package/src/resolution/resolve-item.test.ts +48 -0
  147. package/src/resolution/resolve-item.ts +112 -58
  148. package/src/scan/index.ts +244 -0
  149. package/src/scan/scan-wasm.base64.ts +2 -0
  150. package/src/scheduling/accessor.ts +65 -23
  151. package/src/scheduling/availability.test.ts +320 -0
  152. package/src/scheduling/availability.ts +251 -0
  153. package/src/scheduling/cancel.test.ts +550 -0
  154. package/src/scheduling/cancel.ts +254 -0
  155. package/src/scheduling/cluster-stock.test.ts +31 -0
  156. package/src/scheduling/cluster-stock.ts +15 -0
  157. package/src/scheduling/energy.ts +47 -0
  158. package/src/scheduling/epoch.ts +1 -0
  159. package/src/scheduling/idle-resolve.ts +45 -0
  160. package/src/scheduling/jobs.test.ts +49 -0
  161. package/src/scheduling/jobs.ts +137 -0
  162. package/src/scheduling/lane-core.ts +128 -0
  163. package/src/scheduling/lanes.test.ts +250 -0
  164. package/src/scheduling/lanes.ts +227 -0
  165. package/src/scheduling/projection.ts +265 -149
  166. package/src/scheduling/schedule.test.ts +163 -0
  167. package/src/scheduling/schedule.ts +282 -116
  168. package/src/scheduling/task-cargo.test.ts +110 -0
  169. package/src/scheduling/task-cargo.ts +62 -0
  170. package/src/scheduling/task-effects.test.ts +35 -0
  171. package/src/scheduling/task-effects.ts +34 -0
  172. package/src/scheduling/unwrap.test.ts +86 -0
  173. package/src/scheduling/unwrap.ts +190 -0
  174. package/src/shipload.ts +63 -4
  175. package/src/subscriptions/manager.cluster.test.ts +51 -0
  176. package/src/subscriptions/manager.ts +245 -172
  177. package/src/subscriptions/mappers.ts +5 -8
  178. package/src/subscriptions/types.ts +28 -3
  179. package/src/testing/catalog-hash.ts +19 -0
  180. package/src/testing/index.ts +2 -0
  181. package/src/testing/projection-parity.ts +167 -0
  182. package/src/travel/reach.test.ts +86 -0
  183. package/src/travel/reach.ts +34 -0
  184. package/src/travel/route-build.test.ts +63 -0
  185. package/src/travel/route-build.ts +60 -0
  186. package/src/travel/route-planner.ts +288 -0
  187. package/src/travel/route-simulator.ts +170 -0
  188. package/src/travel/travel.ts +190 -123
  189. package/src/types/capabilities.ts +37 -8
  190. package/src/types/entity.ts +3 -3
  191. package/src/types/index.ts +0 -1
  192. package/src/types.ts +81 -23
  193. package/src/utils/cargo.test.ts +14 -0
  194. package/src/utils/cargo.ts +2 -0
  195. package/src/utils/display-name.ts +70 -0
  196. package/src/utils/hash.ts +22 -2
  197. package/src/utils/system.ts +24 -5
  198. package/src/capabilities/loading.ts +0 -8
  199. package/src/entities/container.ts +0 -123
  200. package/src/entities/ship-deploy.ts +0 -295
  201. package/src/entities/ship.ts +0 -221
  202. package/src/entities/warehouse.ts +0 -127
  203. package/src/types/entity-traits.ts +0 -69
@@ -0,0 +1,388 @@
1
+ import {Serializer} from '@wharfkit/antelope'
2
+ import {getItem} from '../data/catalog'
3
+ import {
4
+ getModuleCapabilityType,
5
+ MODULE_BATTERY,
6
+ MODULE_BUILDER,
7
+ MODULE_CRAFTER,
8
+ MODULE_ENGINE,
9
+ MODULE_GATHERER,
10
+ MODULE_GENERATOR,
11
+ MODULE_HAULER,
12
+ MODULE_LOADER,
13
+ MODULE_STORAGE,
14
+ MODULE_WARP,
15
+ } from '../capabilities/modules'
16
+ import {decodeStat, decodeCraftedItemStats} from '../derivation/crafting'
17
+ import {computeGathererYield} from '../derivation/capabilities'
18
+ import {computeEffectiveModuleStat} from '../derivation/stat-scaling'
19
+ import {getStatDefinitions} from '../derivation/stats'
20
+ import type {ResourceCategory} from '../types'
21
+ import {Types as ServerTypes} from '../contracts/server'
22
+ import {
23
+ buildEntityDescription,
24
+ computeBuilderDrain,
25
+ computeBuilderSpeed,
26
+ computeCrafterDrain,
27
+ computeCrafterSpeed,
28
+ computeEngineDrain,
29
+ computeEngineThrust,
30
+ computeGathererDepth,
31
+ computeGathererDrain,
32
+ computeGeneratorCap,
33
+ computeGeneratorRech,
34
+ computeCargoBayCapacity,
35
+ computeCargoBayDrain,
36
+ computeBatteryBankCapacity,
37
+ computeHaulerCapacity,
38
+ computeHaulerDrain,
39
+ computeHaulerEfficiency,
40
+ computeLoaderMass,
41
+ computeLoaderThrust,
42
+ computeWarpRange,
43
+ } from './description'
44
+
45
+ export type AtomicAttributeType =
46
+ | 'string'
47
+ | 'uint8'
48
+ | 'uint16'
49
+ | 'uint32'
50
+ | 'uint64'
51
+ | 'int32'
52
+ | 'image'
53
+ | 'ipfs'
54
+ | 'UINT16_VEC'
55
+ | 'UINT64_VEC'
56
+
57
+ export interface ImmutableEntry {
58
+ first: string
59
+ second: [AtomicAttributeType, unknown]
60
+ }
61
+
62
+ export interface ImmutableModuleSlot {
63
+ type?: number | string | bigint
64
+ installed?: {item_id: number | string | bigint; stats: number | string | bigint}
65
+ }
66
+
67
+ export function moduleSlotsForImmutable(
68
+ modules: ServerTypes.module_entry[]
69
+ ): ImmutableModuleSlot[] {
70
+ return modules.map((m) => ({
71
+ type: Number(m.type.toString()),
72
+ installed: m.installed
73
+ ? {
74
+ item_id: Number(m.installed.item_id.toString()),
75
+ stats: BigInt(m.installed.stats.toString()),
76
+ }
77
+ : undefined,
78
+ }))
79
+ }
80
+
81
+ const IMAGE_HOST_URL = 'https://item.shiploadgame.com/item'
82
+
83
+ function toWholeEnergy(milli: number): number {
84
+ return Math.floor((milli + 500) / 1000)
85
+ }
86
+
87
+ function bytesToBase64Url(bytes: Uint8Array): string {
88
+ let binary = ''
89
+ for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]!)
90
+ const b64 = btoa(binary)
91
+ return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
92
+ }
93
+
94
+ export function computeNftImageUrl(
95
+ item: {item_id: number; stats: bigint; modules: ImmutableModuleSlot[]; quantity: number},
96
+ originX: number,
97
+ originY: number
98
+ ): string {
99
+ const payload = ServerTypes.nft_item_payload.from({
100
+ item: {
101
+ item_id: item.item_id,
102
+ stats: String(item.stats),
103
+ modules: item.modules,
104
+ quantity: item.quantity,
105
+ },
106
+ location: {x: String(originX), y: String(originY)},
107
+ })
108
+ const bytes = Serializer.encode({object: payload}).array
109
+ return `${IMAGE_HOST_URL}/${bytesToBase64Url(bytes)}.png`
110
+ }
111
+
112
+ function commonBaseImmutable(
113
+ quantity: number,
114
+ stats: bigint,
115
+ originX: number,
116
+ originY: number,
117
+ img: string
118
+ ): ImmutableEntry[] {
119
+ return [
120
+ {first: 'quantity', second: ['uint32', quantity]},
121
+ {first: 'stats', second: ['uint64', String(stats)]},
122
+ {first: 'origin_x', second: ['int32', originX]},
123
+ {first: 'origin_y', second: ['int32', originY]},
124
+ {first: 'img', second: ['string', img]},
125
+ {first: 'deposit_amount', second: ['uint64', '0']},
126
+ {first: 'deposit_token', second: ['uint64', '0']},
127
+ {first: 'deposit_symbol', second: ['uint64', '0']},
128
+ ]
129
+ }
130
+
131
+ export function buildResourceImmutable(
132
+ itemId: number,
133
+ quantity: number,
134
+ stats: bigint,
135
+ originX: number,
136
+ originY: number
137
+ ): ImmutableEntry[] {
138
+ const item = getItem(itemId)
139
+ const cat = item.category
140
+ if (!cat) throw new Error(`Resource item ${itemId} has no category`)
141
+ const definitions = getStatDefinitions(cat as ResourceCategory)
142
+ const img = computeNftImageUrl(
143
+ {item_id: itemId, stats, modules: [], quantity},
144
+ originX,
145
+ originY
146
+ )
147
+ const base = commonBaseImmutable(quantity, stats, originX, originY, img)
148
+ base.push({first: definitions[0].key, second: ['uint16', decodeStat(stats, 0)]})
149
+ base.push({first: definitions[1].key, second: ['uint16', decodeStat(stats, 1)]})
150
+ base.push({first: definitions[2].key, second: ['uint16', decodeStat(stats, 2)]})
151
+ return base
152
+ }
153
+
154
+ export function buildComponentImmutable(
155
+ itemId: number,
156
+ quantity: number,
157
+ stats: bigint,
158
+ originX: number,
159
+ originY: number
160
+ ): ImmutableEntry[] {
161
+ const img = computeNftImageUrl(
162
+ {item_id: itemId, stats, modules: [], quantity},
163
+ originX,
164
+ originY
165
+ )
166
+ const base = commonBaseImmutable(quantity, stats, originX, originY, img)
167
+ const decoded = decodeCraftedItemStats(itemId, stats)
168
+ for (const [key, value] of Object.entries(decoded)) {
169
+ base.push({first: key, second: ['uint16', value]})
170
+ }
171
+ return base
172
+ }
173
+
174
+ export function buildModuleImmutable(
175
+ itemId: number,
176
+ quantity: number,
177
+ stats: bigint,
178
+ originX: number,
179
+ originY: number
180
+ ): ImmutableEntry[] {
181
+ const img = computeNftImageUrl(
182
+ {item_id: itemId, stats, modules: [], quantity},
183
+ originX,
184
+ originY
185
+ )
186
+ const base = commonBaseImmutable(quantity, stats, originX, originY, img)
187
+ const subtype = getModuleCapabilityType(itemId)
188
+ const item = getItem(itemId)
189
+ switch (subtype) {
190
+ case MODULE_ENGINE: {
191
+ const vol = decodeStat(stats, 0)
192
+ const thm = decodeStat(stats, 1)
193
+ base.push({first: 'volatility', second: ['uint16', vol]})
194
+ base.push({first: 'thermal', second: ['uint16', thm]})
195
+ base.push({
196
+ first: 'thrust',
197
+ second: ['uint32', computeEngineThrust(computeEffectiveModuleStat(vol), item.tier)],
198
+ })
199
+ base.push({
200
+ first: 'drain',
201
+ second: ['uint16', computeEngineDrain(computeEffectiveModuleStat(thm))],
202
+ })
203
+ break
204
+ }
205
+ case MODULE_GENERATOR: {
206
+ const res = decodeStat(stats, 0)
207
+ const ref = decodeStat(stats, 1)
208
+ base.push({first: 'resonance', second: ['uint16', res]})
209
+ base.push({first: 'reflectivity', second: ['uint16', ref]})
210
+ base.push({
211
+ first: 'capacity',
212
+ second: [
213
+ 'uint16',
214
+ toWholeEnergy(computeGeneratorCap(computeEffectiveModuleStat(res), item.tier)),
215
+ ],
216
+ })
217
+ base.push({
218
+ first: 'recharge',
219
+ second: [
220
+ 'uint16',
221
+ toWholeEnergy(computeGeneratorRech(computeEffectiveModuleStat(ref), item.tier)),
222
+ ],
223
+ })
224
+ break
225
+ }
226
+ case MODULE_GATHERER: {
227
+ const str = decodeStat(stats, 0)
228
+ const hrd = decodeStat(stats, 1)
229
+ const sat = decodeStat(stats, 2)
230
+ base.push({first: 'strength', second: ['uint16', str]})
231
+ base.push({first: 'hardness', second: ['uint16', hrd]})
232
+ base.push({first: 'saturation', second: ['uint16', sat]})
233
+ base.push({
234
+ first: 'yield',
235
+ second: ['uint16', computeGathererYield(str, item.tier)],
236
+ })
237
+ base.push({
238
+ first: 'drain',
239
+ second: ['uint16', toWholeEnergy(computeGathererDrain(sat))],
240
+ })
241
+ base.push({first: 'depth', second: ['uint16', computeGathererDepth(hrd, item.tier)]})
242
+ break
243
+ }
244
+ case MODULE_LOADER: {
245
+ const fin = decodeStat(stats, 0)
246
+ const pla = decodeStat(stats, 1)
247
+ base.push({first: 'fineness', second: ['uint16', fin]})
248
+ base.push({first: 'plasticity', second: ['uint16', pla]})
249
+ base.push({first: 'mass', second: ['uint32', computeLoaderMass(fin)]})
250
+ base.push({first: 'thrust', second: ['uint16', computeLoaderThrust(pla, item.tier)]})
251
+ break
252
+ }
253
+ case MODULE_WARP: {
254
+ const ref = decodeStat(stats, 0)
255
+ base.push({first: 'reflectivity', second: ['uint16', ref]})
256
+ base.push({first: 'range', second: ['uint32', computeWarpRange(ref, item.tier)]})
257
+ break
258
+ }
259
+ case MODULE_CRAFTER: {
260
+ const fin = decodeStat(stats, 0)
261
+ const con = decodeStat(stats, 1)
262
+ base.push({first: 'fineness', second: ['uint16', fin]})
263
+ base.push({first: 'conductivity', second: ['uint16', con]})
264
+ base.push({first: 'speed', second: ['uint16', computeCrafterSpeed(fin, item.tier)]})
265
+ base.push({first: 'drain', second: ['uint16', toWholeEnergy(computeCrafterDrain(con))]})
266
+ break
267
+ }
268
+ case MODULE_BUILDER: {
269
+ const res = decodeStat(stats, 0)
270
+ const fin = decodeStat(stats, 1)
271
+ base.push({first: 'resonance', second: ['uint16', res]})
272
+ base.push({first: 'fineness', second: ['uint16', fin]})
273
+ base.push({first: 'speed', second: ['uint16', computeBuilderSpeed(res, item.tier)]})
274
+ base.push({first: 'drain', second: ['uint16', toWholeEnergy(computeBuilderDrain(fin))]})
275
+ break
276
+ }
277
+ case MODULE_STORAGE: {
278
+ const str = decodeStat(stats, 0)
279
+ const den = decodeStat(stats, 1)
280
+ const hrd = decodeStat(stats, 2)
281
+ const com = decodeStat(stats, 3)
282
+ base.push({first: 'strength', second: ['uint16', str]})
283
+ base.push({first: 'density', second: ['uint16', den]})
284
+ base.push({first: 'hardness', second: ['uint16', hrd]})
285
+ base.push({first: 'cohesion', second: ['uint16', com]})
286
+ base.push({
287
+ first: 'capacity',
288
+ second: ['uint32', computeCargoBayCapacity(str, den, hrd, item.tier)],
289
+ })
290
+ base.push({
291
+ first: 'drain',
292
+ second: ['uint16', toWholeEnergy(computeCargoBayDrain(com, item.tier))],
293
+ })
294
+ break
295
+ }
296
+ case MODULE_BATTERY: {
297
+ const vol = decodeStat(stats, 0)
298
+ const thm = decodeStat(stats, 1)
299
+ const pla = decodeStat(stats, 2)
300
+ const ins = decodeStat(stats, 3)
301
+ base.push({first: 'volatility', second: ['uint16', vol]})
302
+ base.push({first: 'thermal', second: ['uint16', thm]})
303
+ base.push({first: 'plasticity', second: ['uint16', pla]})
304
+ base.push({first: 'insulation', second: ['uint16', ins]})
305
+ base.push({
306
+ first: 'capacity',
307
+ second: [
308
+ 'uint32',
309
+ toWholeEnergy(computeBatteryBankCapacity(vol, thm, pla, ins, item.tier)),
310
+ ],
311
+ })
312
+ break
313
+ }
314
+ case MODULE_HAULER: {
315
+ const res = decodeStat(stats, 0)
316
+ const pla = decodeStat(stats, 1)
317
+ const con = decodeStat(stats, 2)
318
+ base.push({first: 'resonance', second: ['uint16', res]})
319
+ base.push({first: 'plasticity', second: ['uint16', pla]})
320
+ base.push({first: 'conductivity', second: ['uint16', con]})
321
+ base.push({first: 'capacity', second: ['uint8', computeHaulerCapacity(res, item.tier)]})
322
+ base.push({first: 'efficiency', second: ['uint16', computeHaulerEfficiency(pla)]})
323
+ base.push({
324
+ first: 'drain',
325
+ second: ['uint16', toWholeEnergy(computeHaulerDrain(con, item.tier))],
326
+ })
327
+ break
328
+ }
329
+ }
330
+ return base
331
+ }
332
+
333
+ export function buildEntityImmutable(
334
+ itemId: number,
335
+ quantity: number,
336
+ stats: bigint,
337
+ originX: number,
338
+ originY: number,
339
+ modules: ImmutableModuleSlot[]
340
+ ): ImmutableEntry[] {
341
+ const moduleItems: number[] = []
342
+ const moduleStats: string[] = []
343
+ for (const m of modules) {
344
+ if (m.installed) {
345
+ moduleItems.push(Number(m.installed.item_id))
346
+ moduleStats.push(String(m.installed.stats))
347
+ } else {
348
+ moduleItems.push(0)
349
+ moduleStats.push('0')
350
+ }
351
+ }
352
+ const img = computeNftImageUrl({item_id: itemId, stats, modules, quantity}, originX, originY)
353
+ const base = commonBaseImmutable(quantity, stats, originX, originY, img)
354
+ base.push({first: 'module_items', second: ['UINT16_VEC', moduleItems]})
355
+ base.push({first: 'module_stats', second: ['UINT64_VEC', moduleStats]})
356
+ const description = buildEntityDescription(
357
+ itemId,
358
+ stats,
359
+ moduleItems,
360
+ moduleStats.map((s) => BigInt(s))
361
+ )
362
+ base.push({first: 'description', second: ['string', description]})
363
+ return base
364
+ }
365
+
366
+ export function buildImmutableData(
367
+ itemId: number,
368
+ quantity: number,
369
+ stats: bigint,
370
+ originX: number,
371
+ originY: number,
372
+ modules: ImmutableModuleSlot[] = []
373
+ ): ImmutableEntry[] {
374
+ const item = getItem(itemId)
375
+ if (item.type === 'resource') {
376
+ return buildResourceImmutable(itemId, quantity, stats, originX, originY)
377
+ }
378
+ if (item.type === 'component') {
379
+ return buildComponentImmutable(itemId, quantity, stats, originX, originY)
380
+ }
381
+ if (item.type === 'module') {
382
+ return buildModuleImmutable(itemId, quantity, stats, originX, originY)
383
+ }
384
+ if (item.type === 'entity') {
385
+ return buildEntityImmutable(itemId, quantity, stats, originX, originY, modules)
386
+ }
387
+ throw new Error(`Unsupported item type for wrap: ${item.type}`)
388
+ }