@shipload/sdk 1.0.0-next.10 → 1.0.0-next.12

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 (39) hide show
  1. package/lib/shipload.d.ts +759 -868
  2. package/lib/shipload.js +2463 -2588
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +2432 -2557
  5. package/lib/shipload.m.js.map +1 -1
  6. package/package.json +1 -1
  7. package/src/data/entities.json +13 -0
  8. package/src/data/item-ids.ts +1 -0
  9. package/src/data/items.json +6 -0
  10. package/src/data/kind-registry.json +78 -0
  11. package/src/data/kind-registry.ts +133 -0
  12. package/src/data/metadata.ts +6 -0
  13. package/src/data/recipes.json +57 -0
  14. package/src/derivation/capabilities.ts +397 -0
  15. package/src/derivation/crafting.ts +1 -1
  16. package/src/entities/entity.ts +98 -0
  17. package/src/entities/makers.ts +76 -170
  18. package/src/errors.ts +10 -13
  19. package/src/index-module.ts +39 -22
  20. package/src/managers/entities.ts +18 -80
  21. package/src/managers/index.ts +1 -1
  22. package/src/nft/atomicdata.ts +5 -0
  23. package/src/nft/description.ts +1 -1
  24. package/src/resolution/resolve-item.ts +3 -2
  25. package/src/scheduling/projection.ts +2 -2
  26. package/src/subscriptions/manager.ts +3 -5
  27. package/src/subscriptions/mappers.ts +3 -8
  28. package/src/subscriptions/types.ts +2 -2
  29. package/src/testing/catalog-hash.ts +19 -0
  30. package/src/testing/index.ts +2 -0
  31. package/src/testing/projection-parity.ts +143 -0
  32. package/src/types/index.ts +0 -1
  33. package/src/types.ts +0 -9
  34. package/src/entities/container.ts +0 -123
  35. package/src/entities/extractor.ts +0 -144
  36. package/src/entities/ship-deploy.ts +0 -316
  37. package/src/entities/ship.ts +0 -221
  38. package/src/entities/warehouse.ts +0 -136
  39. package/src/types/entity-traits.ts +0 -132
@@ -1,48 +1,54 @@
1
1
  import {Name, UInt16, UInt32, UInt64, UInt8} from '@wharfkit/antelope'
2
+ import type {NameType, UInt64Type} from '@wharfkit/antelope'
2
3
  import {ServerContract} from '../contracts'
3
- import {type PackedModuleInput, Ship, type ShipStateInput} from './ship'
4
- import {computeWarehouseCapabilities, Warehouse, type WarehouseStateInput} from './warehouse'
5
- import {Container, type ContainerStateInput} from './container'
6
- import {Extractor, computeExtractorCapabilities, type ExtractorStateInput} from './extractor'
7
- import {
8
- ITEM_EXTRACTOR_T1_PACKED,
9
- ITEM_SHIP_T1_PACKED,
10
- ITEM_WAREHOUSE_T1_PACKED,
11
- } from '../data/item-ids'
12
- import {getEntityLayout, type EntitySlot} from '../data/recipes-runtime'
4
+ import {Entity} from './entity'
5
+ import {getKindMeta, getTemplateMeta} from '../data/kind-registry'
6
+ import type {EntityTypeName} from '../data/kind-registry'
7
+ import {getEntityLayout} from '../data/recipes-runtime'
8
+ import type {EntitySlot} from '../data/recipes-runtime'
13
9
  import {itemMetadata} from '../data/metadata'
14
10
  import {getItem} from '../data/catalog'
15
- import {
16
- getModuleCapabilityType,
17
- MODULE_STORAGE,
18
- moduleAccepts,
19
- moduleSlotTypeToCode,
20
- } from '../capabilities/modules'
21
- import {computeShipCapabilities, computeStorageCapabilities} from './ship-deploy'
11
+ import {getModuleCapabilityType, moduleAccepts, moduleSlotTypeToCode} from '../capabilities/modules'
12
+ import {computeEntityCapabilities} from '../derivation/capabilities'
22
13
  import type {InstalledModule} from './slot-multiplier'
23
- import {decodeCraftedItemStats} from '../derivation/crafting'
14
+
15
+ export interface PackedModuleInput {
16
+ itemId: number
17
+ stats: bigint
18
+ }
19
+
20
+ export interface EntityStateInput {
21
+ id: UInt64Type
22
+ owner: NameType
23
+ name: string
24
+ coordinates: {x: number; y: number; z?: number}
25
+ hullmass?: number
26
+ capacity?: number
27
+ cargomass?: number
28
+ energy?: number
29
+ modules?: PackedModuleInput[]
30
+ schedule?: ServerContract.Types.schedule
31
+ cargo?: ServerContract.Types.cargo_item[]
32
+ }
24
33
 
25
34
  function assignModulesToSlots(
26
- packedEntityItemId: number,
35
+ slots: EntitySlot[],
27
36
  modules: PackedModuleInput[],
28
37
  entityLabel: string
29
38
  ): ServerContract.Types.module_entry[] {
30
- const layout = getEntityLayout(packedEntityItemId)
31
- const slots = layout?.slots ?? []
32
39
  const result: Array<{type: number; installed?: ServerContract.Types.packed_module}> = slots.map(
33
40
  (s) => ({type: moduleSlotTypeToCode(s.type), installed: undefined})
34
41
  )
35
42
 
36
43
  for (const mod of modules) {
37
- const itemId = Number(UInt16.from(mod.itemId).value.toString())
38
- const modType = getModuleCapabilityType(itemId)
44
+ const modType = getModuleCapabilityType(mod.itemId)
39
45
  const slotIdx = result.findIndex((r) => !r.installed && moduleAccepts(r.type, modType))
40
46
  if (slotIdx === -1) {
41
47
  let modName: string
42
48
  try {
43
- modName = getItem(itemId).name
49
+ modName = getItem(mod.itemId).name
44
50
  } catch {
45
- modName = itemMetadata[itemId]?.name ?? `item ${itemId}`
51
+ modName = itemMetadata[mod.itemId]?.name ?? `item ${mod.itemId}`
46
52
  }
47
53
  throw new Error(
48
54
  `No compatible slot for module ${modName} (type ${modType}) on ${entityLabel}`
@@ -68,180 +74,80 @@ function toInstalledModules(entries: ServerContract.Types.module_entry[]): Insta
68
74
  if (!entry.installed) return
69
75
  installed.push({
70
76
  slotIndex,
71
- itemId: Number(UInt16.from(entry.installed.item_id).value.toString()),
72
- stats: BigInt(UInt64.from(entry.installed.stats).toString()),
77
+ itemId: Number(entry.installed.item_id.value),
78
+ stats: BigInt(entry.installed.stats.toString()),
73
79
  })
74
80
  })
75
81
  return installed
76
82
  }
77
83
 
78
- function computeStorageBonus(modules: InstalledModule[], baseCapacity: number): number {
79
- let totalBonus = 0
80
- for (const m of modules) {
81
- if (getModuleCapabilityType(m.itemId) !== MODULE_STORAGE) continue
82
- const stats = decodeCraftedItemStats(m.itemId, m.stats)
83
- const {capacityBonus} = computeStorageCapabilities(stats, baseCapacity)
84
- totalBonus += capacityBonus
85
- }
86
- return totalBonus
84
+ const ZERO_HULL_STATS: Record<string, number> = {
85
+ density: 0,
86
+ strength: 0,
87
+ hardness: 0,
88
+ saturation: 0,
87
89
  }
88
90
 
89
- function deriveShipFromModules(
90
- moduleEntries: ServerContract.Types.module_entry[],
91
- layout: EntitySlot[],
92
- baseCapacity: number
93
- ): {
94
- capabilities: ReturnType<typeof computeShipCapabilities>
95
- finalCapacity: number
96
- } {
97
- const installed = toInstalledModules(moduleEntries)
98
- const capabilities = computeShipCapabilities(installed, layout)
99
- const totalBonus = computeStorageBonus(installed, baseCapacity)
100
- return {capabilities, finalCapacity: baseCapacity + totalBonus}
101
- }
102
-
103
- export function makeShip(state: ShipStateInput): Ship {
104
- const info: Record<string, unknown> = {
105
- type: Name.from('ship'),
106
- id: UInt64.from(state.id),
107
- owner: Name.from(state.owner),
108
- entity_name: state.name,
109
- coordinates: ServerContract.Types.coordinates.from(state.coordinates),
110
- cargomass: UInt32.from(0),
111
- cargo: state.cargo || [],
112
- is_idle: !state.schedule,
113
- current_task_elapsed: UInt32.from(0),
114
- current_task_remaining: UInt32.from(0),
115
- pending_tasks: [],
116
- }
117
- if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
118
- if (state.energy !== undefined) info.energy = UInt16.from(state.energy)
119
- if (state.schedule) info.schedule = state.schedule
120
-
121
- let moduleEntries: ServerContract.Types.module_entry[] = []
122
- const shipLayout = getEntityLayout(ITEM_SHIP_T1_PACKED)?.slots ?? []
123
- if (state.modules && state.modules.length > 0) {
124
- moduleEntries = assignModulesToSlots(ITEM_SHIP_T1_PACKED, state.modules, 'Ship T1')
125
- const {capabilities, finalCapacity} = deriveShipFromModules(
126
- moduleEntries,
127
- shipLayout,
128
- state.capacity ?? 0
129
- )
130
- if (capabilities.engines) info.engines = capabilities.engines
131
- if (capabilities.generator) info.generator = capabilities.generator
132
- if (capabilities.gatherer) info.gatherer = capabilities.gatherer
133
- if (capabilities.hauler) info.hauler = capabilities.hauler
134
- if (capabilities.loaders) info.loaders = capabilities.loaders
135
- if (capabilities.crafter) info.crafter = capabilities.crafter
136
- if (state.capacity !== undefined) info.capacity = UInt32.from(finalCapacity)
137
- } else {
138
- moduleEntries = assignModulesToSlots(ITEM_SHIP_T1_PACKED, [], 'Ship T1')
139
- if (state.capacity !== undefined) info.capacity = UInt32.from(state.capacity)
91
+ export function makeEntity(packedItemId: number, state: EntityStateInput): Entity {
92
+ const template = getTemplateMeta(packedItemId)
93
+ if (!template) {
94
+ throw new Error(`Unknown packed entity item ID: ${packedItemId}`)
140
95
  }
141
96
 
142
- info.modules = moduleEntries
143
-
144
- const entityInfo = ServerContract.Types.entity_info.from(info)
145
- return new Ship(entityInfo)
146
- }
97
+ const kind = template.kind.toString() as EntityTypeName
98
+ const layout = getEntityLayout(packedItemId)?.slots ?? []
99
+ const mods = state.modules ?? []
147
100
 
148
- export function makeWarehouse(state: WarehouseStateInput): Warehouse {
149
101
  const info: Record<string, unknown> = {
150
- type: Name.from('warehouse'),
102
+ type: template.kind,
151
103
  id: UInt64.from(state.id),
152
104
  owner: Name.from(state.owner),
153
105
  entity_name: state.name,
154
106
  coordinates: ServerContract.Types.coordinates.from(state.coordinates),
155
- capacity: UInt32.from(state.capacity),
156
- cargomass: UInt32.from(0),
107
+ cargomass: UInt32.from(state.cargomass ?? 0),
157
108
  cargo: state.cargo || [],
158
109
  is_idle: !state.schedule,
159
110
  current_task_elapsed: UInt32.from(0),
160
111
  current_task_remaining: UInt32.from(0),
161
112
  pending_tasks: [],
162
113
  }
163
- if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
164
- if (state.schedule) info.schedule = state.schedule
165
114
 
166
- let moduleEntries: ServerContract.Types.module_entry[] = []
167
- const warehouseLayout = getEntityLayout(ITEM_WAREHOUSE_T1_PACKED)?.slots ?? []
168
- if (state.modules && state.modules.length > 0) {
169
- moduleEntries = assignModulesToSlots(
170
- ITEM_WAREHOUSE_T1_PACKED,
171
- state.modules,
172
- 'Warehouse T1'
173
- )
174
- const installed = toInstalledModules(moduleEntries)
175
- const capabilities = computeWarehouseCapabilities(installed, warehouseLayout)
176
- if (capabilities.loaders) info.loaders = capabilities.loaders
115
+ if (state.energy !== undefined) info.energy = UInt16.from(state.energy)
116
+ if (state.schedule) info.schedule = state.schedule
177
117
 
178
- const totalBonus = computeStorageBonus(installed, state.capacity)
179
- info.capacity = UInt32.from(state.capacity + totalBonus)
118
+ if (kind === 'container') {
119
+ info.modules = []
120
+ if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
121
+ if (state.capacity !== undefined) info.capacity = UInt32.from(state.capacity)
180
122
  } else {
181
- moduleEntries = assignModulesToSlots(ITEM_WAREHOUSE_T1_PACKED, [], 'Warehouse T1')
182
- }
123
+ const entityLabel = getKindMeta(template.kind)?.defaultLabel ?? kind
124
+ const moduleEntries = assignModulesToSlots(layout, mods, entityLabel)
125
+ info.modules = moduleEntries
183
126
 
184
- info.modules = moduleEntries
127
+ const installed = toInstalledModules(moduleEntries)
128
+ const caps = computeEntityCapabilities(ZERO_HULL_STATS, packedItemId, installed, layout)
185
129
 
186
- const entityInfo = ServerContract.Types.entity_info.from(info)
187
- return new Warehouse(entityInfo)
188
- }
130
+ if (state.hullmass !== undefined) {
131
+ info.hullmass = UInt32.from(state.hullmass)
132
+ } else if (installed.length > 0) {
133
+ info.hullmass = UInt32.from(caps.hullmass)
134
+ }
189
135
 
190
- export function makeExtractor(state: ExtractorStateInput): Extractor {
191
- const info: Record<string, unknown> = {
192
- type: Name.from('extractor'),
193
- id: UInt64.from(state.id),
194
- owner: Name.from(state.owner),
195
- entity_name: state.name,
196
- coordinates: ServerContract.Types.coordinates.from(state.coordinates),
197
- cargomass: UInt32.from(0),
198
- cargo: state.cargo || [],
199
- is_idle: !state.schedule,
200
- current_task_elapsed: UInt32.from(0),
201
- current_task_remaining: UInt32.from(0),
202
- pending_tasks: [],
203
- }
204
- if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
205
- if (state.energy !== undefined) info.energy = UInt16.from(state.energy)
206
- if (state.schedule) info.schedule = state.schedule
207
- if (state.capacity !== undefined) info.capacity = UInt32.from(state.capacity)
136
+ if (state.capacity !== undefined) {
137
+ info.capacity = UInt32.from(state.capacity)
138
+ } else {
139
+ info.capacity = UInt32.from(caps.capacity)
140
+ }
208
141
 
209
- const moduleEntries = assignModulesToSlots(
210
- ITEM_EXTRACTOR_T1_PACKED,
211
- state.modules ?? [],
212
- 'Extractor T1'
213
- )
214
- if (state.modules && state.modules.length > 0) {
215
- const layout = getEntityLayout(ITEM_EXTRACTOR_T1_PACKED)?.slots ?? []
216
- const installed = toInstalledModules(moduleEntries)
217
- const capabilities = computeExtractorCapabilities(installed, layout)
218
- if (capabilities.generator) info.generator = capabilities.generator
219
- if (capabilities.gatherer) info.gatherer = capabilities.gatherer
142
+ if (caps.engines) info.engines = caps.engines
143
+ if (caps.generator) info.generator = caps.generator
144
+ if (caps.gatherer) info.gatherer = caps.gatherer
145
+ if (caps.loaders) info.loaders = caps.loaders
146
+ if (caps.crafter) info.crafter = caps.crafter
147
+ if (caps.hauler) info.hauler = caps.hauler
148
+ if (caps.warp) info.warp = caps.warp
220
149
  }
221
150
 
222
- info.modules = moduleEntries
223
-
224
151
  const entityInfo = ServerContract.Types.entity_info.from(info)
225
- return new Extractor(entityInfo)
226
- }
227
-
228
- export function makeContainer(state: ContainerStateInput): Container {
229
- const entityInfo = ServerContract.Types.entity_info.from({
230
- type: Name.from('container'),
231
- id: UInt64.from(state.id),
232
- owner: Name.from(state.owner),
233
- entity_name: state.name,
234
- coordinates: ServerContract.Types.coordinates.from(state.coordinates),
235
- hullmass: UInt32.from(state.hullmass),
236
- capacity: UInt32.from(state.capacity),
237
- cargomass: UInt32.from(state.cargomass || 0),
238
- cargo: state.cargo || [],
239
- modules: [],
240
- is_idle: !state.schedule,
241
- current_task_elapsed: UInt32.from(0),
242
- current_task_remaining: UInt32.from(0),
243
- pending_tasks: [],
244
- schedule: state.schedule,
245
- })
246
- return new Container(entityInfo)
152
+ return new Entity(entityInfo)
247
153
  }
package/src/errors.ts CHANGED
@@ -18,18 +18,18 @@ export const PLAYER_NOT_JOINED = 'Player has not joined the game.'
18
18
  export const PLAYER_NOT_FOUND = 'Cannot find player for given account name.'
19
19
  export const STARTER_ALREADY_CLAIMED =
20
20
  'Starter ship already claimed; destroy existing ships to re-claim.'
21
- export const SHIP_ALREADY_THERE = 'Ship cannot travel to the location its already at.'
21
+ export const ENTITY_ALREADY_THERE = 'Entity cannot travel to the location it is already at.'
22
22
  export const SHIP_ALREADY_TRAVELING = 'Ship is already traveling.'
23
23
  export const SHIP_CANNOT_BUY_TRAVELING = 'Ship cannot buy goods while traveling.'
24
24
  export const SHIP_CANNOT_UPDATE_TRAVELING = 'Ship cannot be updated while traveling.'
25
- export const SHIP_INVALID_DESTINATION = 'Ship cannot travel, no system at specified destination.'
26
- export const SHIP_INVALID_TRAVEL_DURATION =
25
+ export const ENTITY_INVALID_DESTINATION = 'Cannot travel: no system at specified destination.'
26
+ export const ENTITY_INVALID_TRAVEL_DURATION =
27
27
  'This trip cannot be made as it would exceed the maximum travel duration.'
28
28
  export const SHIP_NOT_ARRIVED = 'Ship has not yet arrived at its destination.'
29
- export const SHIP_NOT_ENOUGH_ENERGY =
30
- 'Ship does not have enough energy to travel to the destination.'
31
- export const SHIP_NOT_ENOUGH_ENERGY_CAPACITY =
32
- 'Ship does not have enough energy capacity to travel.'
29
+ export const ENTITY_NOT_ENOUGH_ENERGY =
30
+ 'Entity does not have enough energy to travel to the destination.'
31
+ export const ENTITY_NOT_ENOUGH_ENERGY_CAPACITY =
32
+ 'Entity does not have enough energy capacity to travel.'
33
33
  export const SHIP_NOT_FOUND = 'Cannot find ship for given account.'
34
34
  export const SHIP_NOT_OWNED = 'Ship is not owned by this account.'
35
35
  export const NO_SCHEDULE = 'No scheduled tasks.'
@@ -38,16 +38,13 @@ export const SHIP_NO_COMPLETED_TASKS = 'No completed tasks to resolve.'
38
38
  export const RESOLVE_COUNT_EXCEEDS_COMPLETED = 'Requested resolve count exceeds completed tasks.'
39
39
  export const SHIP_CANNOT_CANCEL_TASK = 'Cannot cancel task that is immutable or in progress.'
40
40
  export const SHIP_NO_TASKS_TO_CANCEL = 'No tasks to cancel.'
41
- export const SHIP_INVALID_CARGO = 'Invalid cargo specified for load/unload.'
42
- export const SHIP_CARGO_NOT_OWNED = 'Cannot load cargo that is not owned.'
43
- export const SHIP_CARGO_NOT_LOADED = 'Cannot unload cargo that is not loaded.'
44
- export const SHIP_CAPACITY_EXCEEDED = 'Ship cargo capacity would be exceeded.'
41
+ export const ENTITY_INVALID_CARGO = 'Invalid cargo specified for load/unload.'
42
+ export const ENTITY_CARGO_NOT_OWNED = 'Cannot load cargo that is not owned.'
43
+ export const ENTITY_CARGO_NOT_LOADED = 'Cannot unload cargo that is not loaded.'
45
44
  export const ENTITY_CAPACITY_EXCEEDED = 'Entity cargo capacity would be exceeded.'
46
45
  export const WAREHOUSE_NOT_FOUND = 'Cannot find warehouse for given id.'
47
46
  export const WAREHOUSE_ALREADY_AT_LOCATION = 'Warehouse already exists at this location.'
48
- export const WAREHOUSE_CAPACITY_EXCEEDED = 'Warehouse capacity would be exceeded.'
49
47
  export const CONTAINER_NOT_FOUND = 'Cannot find container for given id.'
50
- export const CONTAINER_CAPACITY_EXCEEDED = 'Container capacity would be exceeded.'
51
48
  export const DESTINATION_CAPACITY_EXCEEDED =
52
49
  'Destination entity does not have enough capacity for the gather.'
53
50
  export const CANCEL_PAIRED_HAS_PENDING = 'Cannot cancel transfer, paired entity has pending tasks.'
@@ -10,17 +10,19 @@ export {Types as ServerTypes} from './contracts/server'
10
10
  export {Types as PlatformTypes} from './contracts/platform'
11
11
 
12
12
  import type {ServerContract} from './contracts'
13
+ import type {Entity as EntityType} from './entities/entity'
13
14
 
14
15
  export {Shipload} from './shipload'
15
- export {Ship} from './entities/ship'
16
- export type {ShipStateInput, PackedModuleInput} from './entities/ship'
17
- export {Warehouse, computeWarehouseCapabilities} from './entities/warehouse'
18
- export type {WarehouseStateInput} from './entities/warehouse'
19
- export {Extractor, computeExtractorCapabilities} from './entities/extractor'
20
- export type {ExtractorStateInput, ExtractorCapabilities} from './entities/extractor'
21
- export {Container} from './entities/container'
22
- export type {ContainerStateInput} from './entities/container'
23
- export {makeShip, makeWarehouse, makeExtractor, makeContainer} from './entities/makers'
16
+ export {Entity} from './entities/entity'
17
+ export type Ship = EntityType
18
+ export type Warehouse = EntityType
19
+ export type Container = EntityType
20
+ export type Extractor = EntityType
21
+ export type Factory = EntityType
22
+ export type Nexus = EntityType
23
+ export {makeEntity} from './entities/makers'
24
+ export type {EntityStateInput, PackedModuleInput} from './entities/makers'
25
+ export type {InstalledModule} from './entities/slot-multiplier'
24
26
 
25
27
  export type movement_stats = ServerContract.Types.movement_stats
26
28
  export type energy_stats = ServerContract.Types.energy_stats
@@ -46,7 +48,7 @@ export {
46
48
  EpochsManager,
47
49
  ActionsManager,
48
50
  } from './managers'
49
- export type {EntityType, LocationStratum} from './managers'
51
+ export type {LocationStratum} from './managers'
50
52
  export type {EntityRefInput} from './managers/actions'
51
53
 
52
54
  export {
@@ -190,20 +192,26 @@ export {
190
192
  ENTITY_SHIP,
191
193
  ENTITY_WAREHOUSE,
192
194
  ENTITY_EXTRACTOR,
195
+ ENTITY_FACTORY,
193
196
  ENTITY_CONTAINER,
194
- shipTraits,
195
- warehouseTraits,
196
- extractorTraits,
197
- containerTraits,
197
+ ENTITY_NEXUS,
198
198
  getEntityClass,
199
199
  getPackedEntityType,
200
- getEntityTraits,
200
+ getKindMeta,
201
+ getTemplateMeta,
202
+ kindCan,
203
+ CAP_WRAP,
204
+ CAP_UNDEPLOY,
205
+ CAP_DEMOLISH,
206
+ CAP_MODULES,
201
207
  isShip,
202
208
  isWarehouse,
203
209
  isExtractor,
210
+ isFactory,
204
211
  isContainer,
205
- } from './types/entity-traits'
206
- export type {EntityTraits, EntityTypeName} from './types/entity-traits'
212
+ isNexus,
213
+ } from './data/kind-registry'
214
+ export type {EntityTypeName, KindMeta, TemplateMeta} from './data/kind-registry'
207
215
  export * from './capabilities'
208
216
 
209
217
  export {
@@ -260,8 +268,6 @@ export {
260
268
  } from './derivation/crafting'
261
269
  export type {StackInput, CategoryStacks, RecipeSlotInput} from './derivation/crafting'
262
270
 
263
- export {computeContainerCapabilities, computeContainerT2Capabilities} from './entities/container'
264
-
265
271
  export {
266
272
  computeShipHullCapabilities,
267
273
  computeEngineCapabilities,
@@ -272,12 +278,16 @@ export {
272
278
  computeCrafterCapabilities,
273
279
  computeWarehouseHullCapabilities,
274
280
  computeStorageCapabilities,
275
- computeShipCapabilities,
281
+ computeContainerCapabilities,
282
+ computeContainerT2Capabilities,
283
+ computeWarpCapabilities,
284
+ computeBaseCapacity,
285
+ computeEntityCapabilities,
276
286
  GATHERER_DEPTH_TABLE,
277
287
  GATHERER_DEPTH_MAX_TIER,
278
288
  gathererDepthForTier,
279
- } from './entities/ship-deploy'
280
- export type {ShipCapabilities, GathererDepthParams} from './entities/ship-deploy'
289
+ } from './derivation/capabilities'
290
+ export type {GathererDepthParams, ComputedCapabilities} from './derivation/capabilities'
281
291
 
282
292
  export {resolveItem} from './resolution/resolve-item'
283
293
  export type {
@@ -359,3 +369,10 @@ export {displayName, describeItem} from './resolution/display-name'
359
369
  export type {DescribeOptions} from './resolution/display-name'
360
370
 
361
371
  export * from './subscriptions'
372
+
373
+ export {assertProjectionEquals} from './testing/projection-parity'
374
+ export type {
375
+ ContractProjectedState,
376
+ ProjectionComparisonOptions,
377
+ } from './testing/projection-parity'
378
+ export {CATALOG_FILES_REL, computeCatalogHash} from './testing/catalog-hash'
@@ -1,113 +1,51 @@
1
1
  import {Name, type NameType, type UInt64Type} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
- import {Ship} from '../entities/ship'
4
- import {Warehouse} from '../entities/warehouse'
5
- import {Container} from '../entities/container'
6
- import {Extractor} from '../entities/extractor'
3
+ import {Entity} from '../entities/entity'
4
+ import type {EntityTypeName} from '../data/kind-registry'
7
5
  import type {ServerContract} from '../contracts'
8
6
 
9
- export type EntityType = 'ship' | 'warehouse' | 'extractor' | 'container'
7
+ export type {EntityTypeName} from '../data/kind-registry'
10
8
 
11
9
  export class EntitiesManager extends BaseManager {
12
- async getEntity(id: UInt64Type): Promise<Ship | Warehouse | Extractor | Container> {
10
+ async getEntity(id: UInt64Type): Promise<Entity> {
13
11
  const result = await this.server.readonly('getentity', {
14
12
  entity_id: id,
15
13
  })
16
- const entityInfo = result as ServerContract.Types.entity_info
17
- return this.wrapEntity(entityInfo)
14
+ return new Entity(result as ServerContract.Types.entity_info)
15
+ }
16
+
17
+ async getProjection(id: UInt64Type, taskCount?: number): Promise<unknown> {
18
+ return this.server.readonly('getprojstate', {
19
+ entity_id: id,
20
+ task_count: taskCount,
21
+ })
18
22
  }
19
23
 
20
24
  async getEntities(
21
25
  owner: NameType | ServerContract.Types.player_row,
22
- type?: EntityType
23
- ): Promise<(Ship | Warehouse | Extractor | Container)[]> {
26
+ kind?: EntityTypeName
27
+ ): Promise<Entity[]> {
24
28
  const ownerName = this.resolveOwner(owner)
25
29
  const result = await this.server.readonly('getentities', {
26
30
  owner: ownerName,
27
- entity_type: type,
31
+ entity_type: kind,
28
32
  })
29
33
  const entities = result as ServerContract.Types.entity_info[]
30
- return entities.map((entity) => this.wrapEntity(entity))
34
+ return entities.map((e) => new Entity(e))
31
35
  }
32
36
 
33
37
  async getSummaries(
34
38
  owner: NameType | ServerContract.Types.player_row,
35
- type?: EntityType
39
+ kind?: EntityTypeName
36
40
  ): Promise<ServerContract.Types.entity_summary[]> {
37
41
  const ownerName = this.resolveOwner(owner)
38
42
  const result = await this.server.readonly('getsummaries', {
39
43
  owner: ownerName,
40
- entity_type: type,
44
+ entity_type: kind,
41
45
  })
42
46
  return result as ServerContract.Types.entity_summary[]
43
47
  }
44
48
 
45
- async getShip(id: UInt64Type): Promise<Ship> {
46
- return (await this.getEntity(id)) as Ship
47
- }
48
-
49
- async getWarehouse(id: UInt64Type): Promise<Warehouse> {
50
- return (await this.getEntity(id)) as Warehouse
51
- }
52
-
53
- async getContainer(id: UInt64Type): Promise<Container> {
54
- return (await this.getEntity(id)) as Container
55
- }
56
-
57
- async getExtractor(id: UInt64Type): Promise<Extractor> {
58
- return (await this.getEntity(id)) as Extractor
59
- }
60
-
61
- async getShips(owner: NameType | ServerContract.Types.player_row): Promise<Ship[]> {
62
- return (await this.getEntities(owner, 'ship')) as Ship[]
63
- }
64
-
65
- async getWarehouses(owner: NameType | ServerContract.Types.player_row): Promise<Warehouse[]> {
66
- return (await this.getEntities(owner, 'warehouse')) as Warehouse[]
67
- }
68
-
69
- async getContainers(owner: NameType | ServerContract.Types.player_row): Promise<Container[]> {
70
- return (await this.getEntities(owner, 'container')) as Container[]
71
- }
72
-
73
- async getExtractors(owner: NameType | ServerContract.Types.player_row): Promise<Extractor[]> {
74
- return (await this.getEntities(owner, 'extractor')) as Extractor[]
75
- }
76
-
77
- async getShipSummaries(
78
- owner: NameType | ServerContract.Types.player_row
79
- ): Promise<ServerContract.Types.entity_summary[]> {
80
- return this.getSummaries(owner, 'ship')
81
- }
82
-
83
- async getWarehouseSummaries(
84
- owner: NameType | ServerContract.Types.player_row
85
- ): Promise<ServerContract.Types.entity_summary[]> {
86
- return this.getSummaries(owner, 'warehouse')
87
- }
88
-
89
- async getContainerSummaries(
90
- owner: NameType | ServerContract.Types.player_row
91
- ): Promise<ServerContract.Types.entity_summary[]> {
92
- return this.getSummaries(owner, 'container')
93
- }
94
-
95
- async getExtractorSummaries(
96
- owner: NameType | ServerContract.Types.player_row
97
- ): Promise<ServerContract.Types.entity_summary[]> {
98
- return this.getSummaries(owner, 'extractor')
99
- }
100
-
101
- private wrapEntity(
102
- entity: ServerContract.Types.entity_info
103
- ): Ship | Warehouse | Extractor | Container {
104
- if (entity.type.equals('ship')) return new Ship(entity)
105
- if (entity.type.equals('warehouse')) return new Warehouse(entity)
106
- if (entity.type.equals('extractor')) return new Extractor(entity)
107
- if (entity.type.equals('container')) return new Container(entity)
108
- throw new Error(`unknown entity type: ${entity.type}`)
109
- }
110
-
111
49
  private resolveOwner(owner: NameType | ServerContract.Types.player_row): Name {
112
50
  if (typeof owner === 'object' && owner !== null && 'owner' in owner) {
113
51
  return owner.owner
@@ -1,7 +1,7 @@
1
1
  export {GameContext} from './context'
2
2
  export {BaseManager} from './base'
3
3
  export {EntitiesManager} from './entities'
4
- export type {EntityType} from './entities'
4
+ export type {EntityTypeName} from './entities'
5
5
  export {PlayersManager} from './players'
6
6
  export {LocationsManager} from './locations'
7
7
  export type {LocationStratum} from './locations'
@@ -96,10 +96,15 @@ export function deserializeAtomicData(
96
96
  case 'uint64':
97
97
  result[field.name] = readVarint64()
98
98
  break
99
+ case 'int32':
100
+ result[field.name] = readZigzagInt64()
101
+ break
99
102
  case 'int64':
100
103
  result[field.name] = readZigzagInt64()
101
104
  break
102
105
  case 'string':
106
+ case 'image':
107
+ case 'ipfs':
103
108
  result[field.name] = readString()
104
109
  break
105
110
  case 'uint16[]': {
@@ -25,7 +25,7 @@ import {
25
25
  ITEM_WARP_T1,
26
26
  } from '../data/item-ids'
27
27
  import {decodeStat} from '../derivation/crafting'
28
- import {gathererDepthForTier} from '../entities/ship-deploy'
28
+ import {gathererDepthForTier} from '../derivation/capabilities'
29
29
  import {getItem} from '../data/catalog'
30
30
 
31
31
  function idiv(a: number, b: number): number {
@@ -26,8 +26,9 @@ import {
26
26
  computeLoaderCapabilities,
27
27
  computeShipHullCapabilities,
28
28
  computeWarehouseHullCapabilities,
29
- } from '../entities/ship-deploy'
30
- import {computeContainerCapabilities, computeContainerT2Capabilities} from '../entities/container'
29
+ computeContainerCapabilities,
30
+ computeContainerT2Capabilities,
31
+ } from '../derivation/capabilities'
31
32
  import {
32
33
  categoryColors,
33
34
  categoryIcons,