@shipload/sdk 0.7.1 → 2.0.0-rc2

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 (62) hide show
  1. package/README.md +349 -1
  2. package/lib/shipload.d.ts +2016 -230
  3. package/lib/shipload.js +5733 -2094
  4. package/lib/shipload.js.map +1 -1
  5. package/lib/shipload.m.js +5425 -2012
  6. package/lib/shipload.m.js.map +1 -1
  7. package/package.json +5 -5
  8. package/src/capabilities/extraction.ts +37 -0
  9. package/src/capabilities/guards.ts +43 -0
  10. package/src/capabilities/index.ts +5 -0
  11. package/src/capabilities/loading.ts +8 -0
  12. package/src/capabilities/movement.ts +29 -0
  13. package/src/capabilities/storage.ts +67 -0
  14. package/src/contracts/server.ts +788 -202
  15. package/src/data/goods.json +23 -0
  16. package/src/data/syllables.json +1184 -0
  17. package/src/entities/cargo-utils.ts +142 -0
  18. package/src/entities/container.ts +70 -0
  19. package/src/entities/entity-inventory.ts +39 -0
  20. package/src/entities/gamestate.ts +152 -0
  21. package/src/entities/inventory-accessor.ts +46 -0
  22. package/src/entities/location.ts +255 -0
  23. package/src/entities/makers.ts +69 -0
  24. package/src/entities/player.ts +288 -0
  25. package/src/entities/ship.ts +208 -0
  26. package/src/entities/warehouse.ts +89 -0
  27. package/src/errors.ts +46 -9
  28. package/src/index-module.ts +152 -7
  29. package/src/managers/actions.ts +200 -0
  30. package/src/managers/base.ts +25 -0
  31. package/src/managers/context.ts +104 -0
  32. package/src/managers/entities.ts +103 -0
  33. package/src/managers/epochs.ts +47 -0
  34. package/src/managers/index.ts +9 -0
  35. package/src/managers/locations.ts +122 -0
  36. package/src/managers/players.ts +13 -0
  37. package/src/managers/trades.ts +119 -0
  38. package/src/market/goods.ts +31 -0
  39. package/src/{market.ts → market/market.ts} +31 -37
  40. package/src/{rolls.ts → market/rolls.ts} +3 -3
  41. package/src/scheduling/accessor.ts +82 -0
  42. package/src/{epoch.ts → scheduling/epoch.ts} +1 -1
  43. package/src/scheduling/projection.ts +290 -0
  44. package/src/scheduling/schedule.ts +179 -0
  45. package/src/shipload.ts +39 -157
  46. package/src/trading/collect.ts +938 -0
  47. package/src/trading/deal.ts +207 -0
  48. package/src/trading/trade.ts +203 -0
  49. package/src/travel/travel.ts +486 -0
  50. package/src/types/capabilities.ts +79 -0
  51. package/src/types/entity-traits.ts +70 -0
  52. package/src/types/entity.ts +36 -0
  53. package/src/types/index.ts +3 -0
  54. package/src/types.ts +127 -25
  55. package/src/{hash.ts → utils/hash.ts} +1 -1
  56. package/src/utils/system.ts +155 -0
  57. package/src/goods.ts +0 -124
  58. package/src/ship.ts +0 -36
  59. package/src/state.ts +0 -0
  60. package/src/syllables.ts +0 -1184
  61. package/src/system.ts +0 -37
  62. package/src/travel.ts +0 -259
@@ -0,0 +1,486 @@
1
+ /**
2
+ * Travel calculations for ship movement, energy usage, and flight times.
3
+ *
4
+ * Functions prefixed with `calc_` are contract-parity functions that mirror
5
+ * the C++ implementation in the server contract (schedule.cpp, ship.cpp).
6
+ * These use snake_case intentionally to match the contract naming convention
7
+ * and signal that they must produce identical results to the on-chain code.
8
+ *
9
+ * Functions prefixed with `calculate` are higher-level SDK helpers that may
10
+ * combine multiple contract calculations for convenience.
11
+ */
12
+
13
+ import {
14
+ Checksum256,
15
+ Int64,
16
+ Int64Type,
17
+ UInt32,
18
+ UInt32Type,
19
+ UInt64,
20
+ UInt64Type,
21
+ } from '@wharfkit/antelope'
22
+
23
+ import {ServerContract} from '../contracts'
24
+ import {
25
+ CargoMassInfo,
26
+ Distance,
27
+ INITIAL_SHIP_MASS,
28
+ MAX_ORBITAL_ALTITUDE,
29
+ MIN_ORBITAL_ALTITUDE,
30
+ PRECISION,
31
+ ShipLike,
32
+ TaskType,
33
+ } from '../types'
34
+ import {getGood} from '../market/goods'
35
+ import {hasSystem} from '../utils/system'
36
+
37
+ export function calc_orbital_altitude(mass: number): number {
38
+ if (mass <= INITIAL_SHIP_MASS) {
39
+ return MIN_ORBITAL_ALTITUDE
40
+ }
41
+
42
+ const ratio = mass / INITIAL_SHIP_MASS
43
+ const capRatio = 10.0
44
+ let scale = Math.log(ratio) / Math.log(capRatio)
45
+ scale = Math.min(scale, 1.0)
46
+
47
+ return MIN_ORBITAL_ALTITUDE + Math.floor((MAX_ORBITAL_ALTITUDE - MIN_ORBITAL_ALTITUDE) * scale)
48
+ }
49
+
50
+ export function distanceBetweenCoordinates(
51
+ origin: ServerContract.ActionParams.Type.coordinates,
52
+ destination: ServerContract.ActionParams.Type.coordinates
53
+ ): UInt64 {
54
+ return distanceBetweenPoints(origin.x, origin.y, destination.x, destination.y)
55
+ }
56
+
57
+ export function distanceBetweenPoints(
58
+ x1: Int64Type,
59
+ y1: Int64Type,
60
+ x2: Int64Type,
61
+ y2: Int64Type
62
+ ): UInt64 {
63
+ const x = Math.pow(x1 - x2, 2)
64
+ const y = Math.pow(y1 - y2, 2)
65
+ return UInt64.from(Math.sqrt(x + y) * PRECISION)
66
+ }
67
+
68
+ export function lerp(
69
+ origin: ServerContract.ActionParams.Type.coordinates,
70
+ destination: ServerContract.ActionParams.Type.coordinates,
71
+ time: number
72
+ ): ServerContract.ActionParams.Type.coordinates {
73
+ return {
74
+ x: (1 - time) * Number(origin.x) + time * Number(destination.x),
75
+ y: (1 - time) * Number(origin.y) + time * Number(destination.y),
76
+ }
77
+ }
78
+
79
+ export function rotation(
80
+ origin: ServerContract.ActionParams.Type.coordinates,
81
+ destination: ServerContract.ActionParams.Type.coordinates
82
+ ) {
83
+ return Math.atan2(destination.y - origin.y, destination.x - origin.x) * (180 / Math.PI) + 90
84
+ }
85
+
86
+ export function findNearbyPlanets(
87
+ seed: Checksum256,
88
+ origin: ServerContract.ActionParams.Type.coordinates,
89
+ maxDistance: UInt64Type = 20 * PRECISION
90
+ ): Distance[] {
91
+ const nearbySystems: Distance[] = []
92
+
93
+ const max = UInt64.from(maxDistance / PRECISION)
94
+ const xMin = Int64.from(origin.x).subtracting(max)
95
+ const xMax = Int64.from(origin.x).adding(max)
96
+ const yMin = Int64.from(origin.y).subtracting(max)
97
+ const yMax = Int64.from(origin.y).adding(max)
98
+
99
+ for (let x = Number(xMin); x <= Number(xMax); x++) {
100
+ for (let y = Number(yMin); y <= Number(yMax); y++) {
101
+ const samePlace = x === Number(origin.x) && y === Number(origin.y)
102
+ if (!samePlace) {
103
+ const distance = distanceBetweenPoints(origin.x, origin.y, x, y)
104
+ if (Number(distance) <= Number(maxDistance)) {
105
+ const system = hasSystem(seed, {x, y})
106
+ if (system) {
107
+ nearbySystems.push({origin, destination: {x, y}, distance})
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+
114
+ return nearbySystems
115
+ }
116
+
117
+ export function calc_rechargetime(
118
+ capacity: UInt32Type,
119
+ energy: UInt32Type,
120
+ recharge: UInt32Type
121
+ ): UInt32 {
122
+ const cap = UInt32.from(capacity)
123
+ const eng = UInt32.from(energy)
124
+ if (eng.gte(cap)) return UInt32.zero
125
+ return cap.subtracting(eng).dividing(recharge)
126
+ }
127
+
128
+ export function calc_ship_rechargetime(ship: ShipLike): UInt32 {
129
+ return calc_rechargetime(ship.generator.capacity, ship.energy, ship.generator.recharge)
130
+ }
131
+
132
+ export function calc_flighttime(distance: UInt64Type, acceleration: number): UInt32 {
133
+ return UInt32.from(2 * Math.sqrt(Number(distance) / acceleration))
134
+ }
135
+
136
+ export function calc_loader_flighttime(ship: ShipLike, mass: UInt64, altitude?: number): UInt32 {
137
+ const z = altitude ?? ship.coordinates.z?.toNumber() ?? calc_orbital_altitude(Number(mass))
138
+ return calc_flighttime(z, calc_loader_acceleration(ship, mass))
139
+ }
140
+
141
+ export function calc_loader_acceleration(ship: ShipLike, mass: UInt64): number {
142
+ return calc_acceleration(Number(ship.loaders.thrust), Number(mass) + Number(ship.loaders.mass))
143
+ }
144
+
145
+ export function calc_ship_flighttime(ship: ShipLike, mass: UInt64, distance: UInt64): UInt32 {
146
+ const acceleration = calc_ship_acceleration(ship, mass)
147
+ return calc_flighttime(distance, acceleration)
148
+ }
149
+
150
+ export function calc_ship_acceleration(ship: ShipLike, mass: UInt64): number {
151
+ return calc_acceleration(Number(ship.engines.thrust), Number(mass))
152
+ }
153
+
154
+ export function calc_acceleration(thrust: number, mass: number): number {
155
+ return (thrust / mass) * PRECISION
156
+ }
157
+
158
+ export function calc_ship_mass(ship: ShipLike, cargos: CargoMassInfo[]): UInt64 {
159
+ const mass = UInt64.from(0)
160
+
161
+ mass.add(ship.hullmass)
162
+
163
+ if (ship.loaders.quantity.gt(UInt32.zero)) {
164
+ mass.add(ship.loaders.mass.multiplying(ship.loaders.quantity))
165
+ }
166
+
167
+ for (const cargo of cargos) {
168
+ mass.add(getGood(cargo.good_id).mass.multiplying(cargo.quantity))
169
+ }
170
+
171
+ return mass
172
+ }
173
+
174
+ export function calc_energyusage(distance: UInt64Type, drain: UInt32Type): UInt32 {
175
+ return UInt64.from(distance).dividing(PRECISION).multiplying(drain)
176
+ }
177
+
178
+ export function calculateTransferTime(
179
+ ship: ShipLike,
180
+ cargos: CargoMassInfo[],
181
+ quantities?: Map<number, number>
182
+ ): UInt32 {
183
+ let mass = UInt64.from(0)
184
+
185
+ for (const cargo of cargos) {
186
+ const qty = quantities?.get(Number(cargo.good_id)) ?? 0
187
+ if (qty > 0) {
188
+ const good_mass = getGood(cargo.good_id).mass
189
+ const cargo_mass = good_mass.multiplying(qty)
190
+ mass = UInt64.from(mass).adding(cargo_mass)
191
+ }
192
+ }
193
+
194
+ if (mass.equals(UInt64.zero)) {
195
+ return UInt32.from(0)
196
+ }
197
+
198
+ mass = UInt64.from(mass).adding(ship.loaders.mass)
199
+ const transfer_time = calc_loader_flighttime(ship, mass)
200
+ return transfer_time.dividing(ship.loaders.quantity)
201
+ }
202
+
203
+ export function calculateRefuelingTime(ship: ShipLike): UInt32 {
204
+ return calc_ship_rechargetime(ship)
205
+ }
206
+
207
+ export function calculateFlightTime(
208
+ ship: ShipLike,
209
+ cargos: CargoMassInfo[],
210
+ distance: UInt64Type
211
+ ): UInt32 {
212
+ const mass = calc_ship_mass(ship, cargos)
213
+ return calc_ship_flighttime(ship, mass, distance)
214
+ }
215
+
216
+ export interface LoadTimeBreakdown {
217
+ unloadTime: number
218
+ loadTime: number
219
+ totalTime: number
220
+ unloadMass: number
221
+ loadMass: number
222
+ }
223
+
224
+ export function calculateLoadTimeBreakdown(
225
+ ship: ShipLike,
226
+ cargos: CargoMassInfo[],
227
+ loadQuantities?: Map<number, number>,
228
+ unloadQuantities?: Map<number, number>
229
+ ): LoadTimeBreakdown {
230
+ let mass_unload = UInt64.from(0)
231
+ let mass_load = UInt64.from(0)
232
+
233
+ for (const cargo of cargos) {
234
+ const goodId = Number(cargo.good_id)
235
+ const loadQty = loadQuantities?.get(goodId) ?? 0
236
+ const unloadQty = unloadQuantities?.get(goodId) ?? 0
237
+
238
+ if (loadQty > 0 || unloadQty > 0) {
239
+ const good = getGood(cargo.good_id)
240
+
241
+ if (loadQty > 0) {
242
+ const cargo_mass = good.mass.multiplying(loadQty)
243
+ mass_load = UInt64.from(mass_load).adding(cargo_mass)
244
+ }
245
+ if (unloadQty > 0) {
246
+ const cargo_mass = good.mass.multiplying(unloadQty)
247
+ mass_unload = UInt64.from(mass_unload).adding(cargo_mass)
248
+ }
249
+ }
250
+ }
251
+
252
+ let unloadTime = 0
253
+ let loadTime = 0
254
+
255
+ if (mass_unload.gt(UInt64.zero)) {
256
+ const totalMass = UInt64.from(mass_unload).adding(ship.loaders.mass)
257
+ unloadTime = Number(calc_loader_flighttime(ship, totalMass))
258
+ }
259
+
260
+ if (mass_load.gt(UInt64.zero)) {
261
+ const totalMass = UInt64.from(mass_load).adding(ship.loaders.mass)
262
+ loadTime = Number(calc_loader_flighttime(ship, totalMass))
263
+ }
264
+
265
+ const numLoaders = Number(ship.loaders.quantity)
266
+ const totalTime = numLoaders > 0 ? (unloadTime + loadTime) / numLoaders : 0
267
+ const unloadTimePerLoader = numLoaders > 0 ? unloadTime / numLoaders : 0
268
+ const loadTimePerLoader = numLoaders > 0 ? loadTime / numLoaders : 0
269
+
270
+ return {
271
+ unloadTime: unloadTimePerLoader,
272
+ loadTime: loadTimePerLoader,
273
+ totalTime,
274
+ unloadMass: Number(mass_unload),
275
+ loadMass: Number(mass_load),
276
+ }
277
+ }
278
+
279
+ export interface EstimatedTravelTime {
280
+ flightTime: UInt32
281
+ rechargeTime: UInt32
282
+ loadTime: UInt32
283
+ unloadTime: UInt32
284
+ total: UInt32
285
+ }
286
+
287
+ export interface EstimateTravelTimeOptions {
288
+ needsRecharge?: boolean
289
+ loadMass?: UInt32Type
290
+ unloadMass?: UInt32Type
291
+ }
292
+
293
+ export function estimateTravelTime(
294
+ ship: ShipLike,
295
+ travelMass: UInt64Type,
296
+ distance: UInt64Type,
297
+ options: EstimateTravelTimeOptions = {}
298
+ ): EstimatedTravelTime {
299
+ const {needsRecharge = false, loadMass, unloadMass} = options
300
+
301
+ const flightTime = calc_ship_flighttime(ship, UInt64.from(travelMass), UInt64.from(distance))
302
+ const rechargeTime = needsRecharge ? calc_ship_rechargetime(ship) : UInt32.zero
303
+
304
+ let loadTime = UInt32.zero
305
+ let unloadTime = UInt32.zero
306
+
307
+ if (
308
+ loadMass &&
309
+ UInt32.from(loadMass).gt(UInt32.zero) &&
310
+ ship.loaders.quantity.gt(UInt32.zero)
311
+ ) {
312
+ const totalMass = UInt64.from(loadMass).adding(ship.loaders.mass)
313
+ loadTime = calc_loader_flighttime(ship, totalMass).dividing(ship.loaders.quantity)
314
+ }
315
+
316
+ if (
317
+ unloadMass &&
318
+ UInt32.from(unloadMass).gt(UInt32.zero) &&
319
+ ship.loaders.quantity.gt(UInt32.zero)
320
+ ) {
321
+ const totalMass = UInt64.from(unloadMass).adding(ship.loaders.mass)
322
+ unloadTime = calc_loader_flighttime(ship, totalMass).dividing(ship.loaders.quantity)
323
+ }
324
+
325
+ return {
326
+ flightTime,
327
+ rechargeTime,
328
+ loadTime,
329
+ unloadTime,
330
+ total: flightTime.adding(rechargeTime).adding(loadTime).adding(unloadTime),
331
+ }
332
+ }
333
+
334
+ export function estimateDealTravelTime(
335
+ ship: ShipLike,
336
+ shipMass: UInt64Type,
337
+ distance: UInt64Type,
338
+ loadMass: UInt32Type
339
+ ): UInt32 {
340
+ const needsRecharge = !hasEnergyForDistance(ship, distance)
341
+ const estimate = estimateTravelTime(ship, shipMass, distance, {
342
+ needsRecharge,
343
+ loadMass,
344
+ })
345
+ return estimate.total
346
+ }
347
+
348
+ export function hasEnergyForDistance(ship: ShipLike, distance: UInt64Type): boolean {
349
+ const energyNeeded = UInt64.from(distance).dividing(PRECISION).multiplying(ship.engines.drain)
350
+ return UInt64.from(ship.energy).gte(energyNeeded)
351
+ }
352
+
353
+ export interface TransferEntity {
354
+ location: {z?: {toNumber(): number} | number}
355
+ loaders?: {
356
+ thrust: {toNumber(): number} | number
357
+ mass: {toNumber(): number} | number
358
+ quantity: {toNumber(): number} | number
359
+ }
360
+ }
361
+
362
+ export interface HasScheduleAndLocation {
363
+ coordinates: ServerContract.ActionParams.Type.coordinates
364
+ schedule?: ServerContract.Types.schedule
365
+ }
366
+
367
+ export function getFlightOrigin(
368
+ entity: HasScheduleAndLocation,
369
+ flightTaskIndex: number
370
+ ): ServerContract.ActionParams.Type.coordinates {
371
+ if (!entity.schedule) return entity.coordinates
372
+
373
+ let origin = entity.coordinates
374
+ for (let i = 0; i < flightTaskIndex && i < entity.schedule.tasks.length; i++) {
375
+ const task = entity.schedule.tasks[i]
376
+ if (task.type.equals(TaskType.TRAVEL) && task.coordinates) {
377
+ origin = task.coordinates
378
+ }
379
+ }
380
+ return origin
381
+ }
382
+
383
+ export function getDestinationLocation(
384
+ entity: HasScheduleAndLocation
385
+ ): ServerContract.ActionParams.Type.coordinates | undefined {
386
+ if (!entity.schedule) return undefined
387
+
388
+ for (let i = entity.schedule.tasks.length - 1; i >= 0; i--) {
389
+ const task = entity.schedule.tasks[i]
390
+ if (task.type.equals(TaskType.TRAVEL) && task.coordinates) {
391
+ return task.coordinates
392
+ }
393
+ }
394
+ return undefined
395
+ }
396
+
397
+ export function getPositionAt(
398
+ entity: HasScheduleAndLocation,
399
+ taskIndex: number,
400
+ taskProgress: number
401
+ ): ServerContract.ActionParams.Type.coordinates {
402
+ if (!entity.schedule || entity.schedule.tasks.length === 0 || taskIndex < 0) {
403
+ return entity.coordinates
404
+ }
405
+
406
+ const task = entity.schedule.tasks[taskIndex]
407
+
408
+ if (!task.type.equals(TaskType.TRAVEL) || !task.coordinates) {
409
+ return getFlightOrigin(entity, taskIndex)
410
+ }
411
+
412
+ const origin = getFlightOrigin(entity, taskIndex)
413
+ const destination = task.coordinates
414
+
415
+ const interpolated = lerp(origin, destination, taskProgress)
416
+ return {
417
+ x: Math.round(interpolated.x),
418
+ y: Math.round(interpolated.y),
419
+ }
420
+ }
421
+
422
+ export function calc_transfer_duration(
423
+ source: TransferEntity,
424
+ dest: TransferEntity,
425
+ cargoMass: number
426
+ ): number {
427
+ if (cargoMass === 0) {
428
+ return 0
429
+ }
430
+
431
+ let totalThrust = 0
432
+ let totalLoaderMass = 0
433
+ let totalQuantity = 0
434
+
435
+ if (source.loaders) {
436
+ const thrust =
437
+ typeof source.loaders.thrust === 'number'
438
+ ? source.loaders.thrust
439
+ : source.loaders.thrust.toNumber()
440
+ const mass =
441
+ typeof source.loaders.mass === 'number'
442
+ ? source.loaders.mass
443
+ : source.loaders.mass.toNumber()
444
+ const qty =
445
+ typeof source.loaders.quantity === 'number'
446
+ ? source.loaders.quantity
447
+ : source.loaders.quantity.toNumber()
448
+ totalThrust += thrust * qty
449
+ totalLoaderMass += mass * qty
450
+ totalQuantity += qty
451
+ }
452
+
453
+ if (dest.loaders) {
454
+ const thrust =
455
+ typeof dest.loaders.thrust === 'number'
456
+ ? dest.loaders.thrust
457
+ : dest.loaders.thrust.toNumber()
458
+ const mass =
459
+ typeof dest.loaders.mass === 'number' ? dest.loaders.mass : dest.loaders.mass.toNumber()
460
+ const qty =
461
+ typeof dest.loaders.quantity === 'number'
462
+ ? dest.loaders.quantity
463
+ : dest.loaders.quantity.toNumber()
464
+ totalThrust += thrust * qty
465
+ totalLoaderMass += mass * qty
466
+ totalQuantity += qty
467
+ }
468
+
469
+ if (totalThrust === 0 || totalQuantity === 0) {
470
+ return 0
471
+ }
472
+
473
+ const sourceZ =
474
+ typeof source.location.z === 'number'
475
+ ? source.location.z
476
+ : source.location.z?.toNumber() ?? 0
477
+ const destZ =
478
+ typeof dest.location.z === 'number' ? dest.location.z : dest.location.z?.toNumber() ?? 0
479
+ const distance = Math.abs(sourceZ - destZ)
480
+
481
+ const totalMass = cargoMass + totalLoaderMass
482
+ const acceleration = calc_acceleration(totalThrust, totalMass)
483
+ const flightTime = 2 * Math.sqrt(distance / acceleration)
484
+
485
+ return Math.floor(flightTime / totalQuantity)
486
+ }
@@ -0,0 +1,79 @@
1
+ import {Name, UInt16, UInt32} from '@wharfkit/antelope'
2
+ import {ServerContract} from '../contracts'
3
+
4
+ export interface MovementCapability {
5
+ engines: ServerContract.Types.movement_stats
6
+ generator: ServerContract.Types.energy_stats
7
+ }
8
+
9
+ export interface EnergyCapability {
10
+ energy: UInt16
11
+ }
12
+
13
+ export interface StorageCapability {
14
+ capacity: UInt32
15
+ cargomass: UInt32
16
+ cargo: ServerContract.Types.cargo_item[]
17
+ }
18
+
19
+ export interface LoaderCapability {
20
+ loaders: ServerContract.Types.loader_stats
21
+ }
22
+
23
+ export interface TradeCapability {
24
+ trade: ServerContract.Types.trade_stats
25
+ }
26
+
27
+ export interface ExtractorCapability {
28
+ extractor: ServerContract.Types.extractor_stats
29
+ }
30
+
31
+ export interface MassCapability {
32
+ hullmass: UInt32
33
+ }
34
+
35
+ export interface ScheduleCapability {
36
+ schedule?: ServerContract.Types.schedule
37
+ }
38
+
39
+ export interface EntityCapabilities {
40
+ hullmass?: UInt32
41
+ capacity?: UInt32
42
+ engines?: ServerContract.Types.movement_stats
43
+ generator?: ServerContract.Types.energy_stats
44
+ loaders?: ServerContract.Types.loader_stats
45
+ trade?: ServerContract.Types.trade_stats
46
+ extractor?: ServerContract.Types.extractor_stats
47
+ }
48
+
49
+ export interface EntityState {
50
+ owner: Name
51
+ location: ServerContract.Types.coordinates
52
+ energy?: UInt16
53
+ cargomass: UInt32
54
+ cargo: ServerContract.Types.cargo_item[]
55
+ }
56
+
57
+ export function capsHasMovement(caps: EntityCapabilities): boolean {
58
+ return caps.engines !== undefined && caps.generator !== undefined
59
+ }
60
+
61
+ export function capsHasStorage(caps: EntityCapabilities): boolean {
62
+ return caps.capacity !== undefined
63
+ }
64
+
65
+ export function capsHasLoaders(caps: EntityCapabilities): boolean {
66
+ return caps.loaders !== undefined
67
+ }
68
+
69
+ export function capsHasTrade(caps: EntityCapabilities): boolean {
70
+ return caps.trade !== undefined
71
+ }
72
+
73
+ export function capsHasExtractor(caps: EntityCapabilities): boolean {
74
+ return caps.extractor !== undefined
75
+ }
76
+
77
+ export function capsHasMass(caps: EntityCapabilities): boolean {
78
+ return caps.hullmass !== undefined
79
+ }
@@ -0,0 +1,70 @@
1
+ import {Name} from '@wharfkit/antelope'
2
+
3
+ export const ENTITY_SHIP = Name.from('ship')
4
+ export const ENTITY_WAREHOUSE = Name.from('warehouse')
5
+ export const ENTITY_CONTAINER = Name.from('container')
6
+
7
+ export type EntityTypeName = 'ship' | 'warehouse' | 'container'
8
+
9
+ export interface EntityTraits {
10
+ typeName: Name
11
+ isMovable: boolean
12
+ hasEnergy: boolean
13
+ hasLoaders: boolean
14
+ hasTrade: boolean
15
+ notFoundError: string
16
+ }
17
+
18
+ export const shipTraits: EntityTraits = {
19
+ typeName: ENTITY_SHIP,
20
+ isMovable: true,
21
+ hasEnergy: true,
22
+ hasLoaders: true,
23
+ hasTrade: true,
24
+ notFoundError: 'ship not found',
25
+ }
26
+
27
+ export const warehouseTraits: EntityTraits = {
28
+ typeName: ENTITY_WAREHOUSE,
29
+ isMovable: false,
30
+ hasEnergy: false,
31
+ hasLoaders: true,
32
+ hasTrade: false,
33
+ notFoundError: 'warehouse not found',
34
+ }
35
+
36
+ export const containerTraits: EntityTraits = {
37
+ typeName: ENTITY_CONTAINER,
38
+ isMovable: true,
39
+ hasEnergy: false,
40
+ hasLoaders: false,
41
+ hasTrade: false,
42
+ notFoundError: 'container not found',
43
+ }
44
+
45
+ export function getEntityTraits(entityType: Name | EntityTypeName): EntityTraits {
46
+ const typeName = typeof entityType === 'string' ? entityType : entityType.toString()
47
+
48
+ switch (typeName) {
49
+ case 'ship':
50
+ return shipTraits
51
+ case 'warehouse':
52
+ return warehouseTraits
53
+ case 'container':
54
+ return containerTraits
55
+ default:
56
+ throw new Error(`Unknown entity type: ${typeName}`)
57
+ }
58
+ }
59
+
60
+ export function isShip(entity: {type?: Name}): boolean {
61
+ return entity.type?.equals(ENTITY_SHIP) ?? false
62
+ }
63
+
64
+ export function isWarehouse(entity: {type?: Name}): boolean {
65
+ return entity.type?.equals(ENTITY_WAREHOUSE) ?? false
66
+ }
67
+
68
+ export function isContainer(entity: {type?: Name}): boolean {
69
+ return entity.type?.equals(ENTITY_CONTAINER) ?? false
70
+ }
@@ -0,0 +1,36 @@
1
+ import {Name, UInt64} from '@wharfkit/antelope'
2
+ import {ServerContract} from '../contracts'
3
+ import {Coordinates} from '../types'
4
+ import {
5
+ EnergyCapability,
6
+ LoaderCapability,
7
+ MassCapability,
8
+ MovementCapability,
9
+ ScheduleCapability,
10
+ StorageCapability,
11
+ } from './capabilities'
12
+
13
+ export interface Entity {
14
+ id: UInt64
15
+ type: Name
16
+ owner: Name
17
+ entity_name: string
18
+ location: Coordinates | ServerContract.Types.coordinates
19
+ }
20
+
21
+ export type ShipEntity = Entity &
22
+ MovementCapability &
23
+ EnergyCapability &
24
+ StorageCapability &
25
+ LoaderCapability &
26
+ MassCapability &
27
+ ScheduleCapability & {
28
+ trade?: ServerContract.Types.trade_stats
29
+ extractor?: ServerContract.Types.extractor_stats
30
+ }
31
+
32
+ export type WarehouseEntity = Entity & StorageCapability & LoaderCapability & ScheduleCapability
33
+
34
+ export type ContainerEntity = Entity & StorageCapability & MassCapability & ScheduleCapability
35
+
36
+ export type AnyEntity = ShipEntity | WarehouseEntity | ContainerEntity
@@ -0,0 +1,3 @@
1
+ export * from './capabilities'
2
+ export * from './entity'
3
+ export * from './entity-traits'