@shipload/sdk 2.0.0-rc1 → 2.0.0-rc3

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 (52) hide show
  1. package/README.md +349 -1
  2. package/lib/shipload.d.ts +809 -314
  3. package/lib/shipload.js +2745 -1740
  4. package/lib/shipload.js.map +1 -1
  5. package/lib/shipload.m.js +2158 -1154
  6. package/lib/shipload.m.js.map +1 -1
  7. package/package.json +1 -2
  8. package/src/capabilities/extraction.ts +30 -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 +506 -183
  15. package/src/data/items.json +16 -0
  16. package/src/derivation/index.ts +25 -0
  17. package/src/derivation/location-size.ts +15 -0
  18. package/src/derivation/resources.ts +141 -0
  19. package/src/derivation/stratum.ts +116 -0
  20. package/src/entities/cargo-utils.ts +98 -3
  21. package/src/entities/container.ts +70 -0
  22. package/src/entities/entity-inventory.ts +13 -9
  23. package/src/entities/inventory-accessor.ts +46 -0
  24. package/src/entities/location.ts +31 -17
  25. package/src/entities/makers.ts +69 -0
  26. package/src/entities/player.ts +2 -1
  27. package/src/entities/ship.ts +93 -440
  28. package/src/entities/warehouse.ts +29 -145
  29. package/src/errors.ts +4 -4
  30. package/src/index-module.ts +62 -4
  31. package/src/managers/actions.ts +75 -31
  32. package/src/managers/entities.ts +22 -5
  33. package/src/managers/locations.ts +34 -15
  34. package/src/managers/trades.ts +7 -7
  35. package/src/market/items.ts +31 -0
  36. package/src/market/market.ts +12 -13
  37. package/src/scheduling/accessor.ts +82 -0
  38. package/src/scheduling/projection.ts +126 -54
  39. package/src/scheduling/schedule.ts +24 -0
  40. package/src/trading/collect.ts +25 -26
  41. package/src/trading/deal.ts +8 -9
  42. package/src/trading/trade.ts +9 -9
  43. package/src/travel/travel.ts +69 -8
  44. package/src/types/capabilities.ts +79 -0
  45. package/src/types/entity-traits.ts +70 -0
  46. package/src/types/entity.ts +36 -0
  47. package/src/types/index.ts +3 -0
  48. package/src/types.ts +92 -15
  49. package/src/utils/hash.ts +1 -1
  50. package/src/utils/system.ts +97 -4
  51. package/src/data/goods.json +0 -23
  52. package/src/market/goods.ts +0 -31
@@ -1,7 +1,7 @@
1
1
  import {Checksum256Type, Int64, UInt16, UInt32, UInt64} from '@wharfkit/antelope'
2
2
  import {Ship} from '../entities/ship'
3
3
  import {Location} from '../entities/location'
4
- import {Coordinates, GoodPrice, ShipLike} from '../types'
4
+ import {Coordinates, ItemPrice, ShipLike} from '../types'
5
5
  import {Deal, findDealsForShip} from './deal'
6
6
 
7
7
  import {EntityInventory} from '../entities/entity-inventory'
@@ -10,9 +10,8 @@ import {
10
10
  distanceBetweenCoordinates,
11
11
  EstimatedTravelTime,
12
12
  estimateTravelTime,
13
- hasEnergyForDistance,
14
13
  } from '../travel/travel'
15
- import {getGood, getGoods} from '../market/goods'
14
+ import {getItem, getItems} from '../market/items'
16
15
  import {getRarity, Rarities} from '../market/market'
17
16
  import {ServerContract} from '../contracts'
18
17
 
@@ -24,7 +23,7 @@ function calculateCargoMass(cargo: EntityInventory[]): UInt32 {
24
23
  let mass = UInt32.from(0)
25
24
  for (const c of cargo) {
26
25
  if (UInt64.from(c.quantity).gt(UInt64.zero)) {
27
- const goodMass = getGood(c.good_id).mass
26
+ const goodMass = getItem(c.item_id).mass
28
27
  mass = mass.adding(goodMass.multiplying(c.quantity))
29
28
  }
30
29
  }
@@ -103,7 +102,7 @@ export interface CollectOption {
103
102
  /** Detailed breakdown of travel time components */
104
103
  travelTimeBreakdown?: EstimatedTravelTime
105
104
  /** Info about a discounted good at the destination (for explore options) */
106
- discountedGood?: DiscountedGoodInfo
105
+ discountedGood?: DiscountedItemInfo
107
106
  /** Top potential deals available at destination (for explore options) */
108
107
  potentialDeals?: PotentialDeal[]
109
108
  /** Details of cargo being sold (if selling cargo) */
@@ -191,7 +190,7 @@ export function analyzeCargoSale(
191
190
  for (const c of cargo) {
192
191
  if (UInt64.from(c.quantity).equals(UInt64.zero)) continue
193
192
 
194
- const goodId = Number(c.good_id)
193
+ const goodId = Number(c.item_id)
195
194
  const salePrice = prices.get(goodId)
196
195
 
197
196
  if (salePrice) {
@@ -220,7 +219,7 @@ export function buildCargoSaleItems(
220
219
  for (const c of cargo) {
221
220
  if (UInt64.from(c.quantity).equals(UInt64.zero)) continue
222
221
 
223
- const goodId = Number(c.good_id)
222
+ const goodId = Number(c.item_id)
224
223
  const salePrice = prices.get(goodId)
225
224
  const pricePerUnit = salePrice ? UInt32.from(salePrice) : UInt32.zero
226
225
  const revenue = UInt64.from(pricePerUnit).multiplying(c.quantity)
@@ -228,8 +227,8 @@ export function buildCargoSaleItems(
228
227
  const profit = Int64.from(revenue).subtracting(cost)
229
228
 
230
229
  items.push({
231
- goodId: c.good_id,
232
- goodName: c.good?.name ?? `Good #${goodId}`,
230
+ goodId: c.item_id,
231
+ goodName: c.item?.name ?? `Item #${goodId}`,
233
232
  quantity: UInt32.from(c.quantity),
234
233
  pricePerUnit,
235
234
  revenue,
@@ -272,10 +271,10 @@ export function createSellAndTradeOption(
272
271
  : undefined
273
272
 
274
273
  return {
275
- id: `sell-trade-${deal.destination.coordinates.x}-${deal.destination.coordinates.y}-${deal.good.id}`,
274
+ id: `sell-trade-${deal.destination.coordinates.x}-${deal.destination.coordinates.y}-${deal.item.id}`,
276
275
  type: 'sell-and-trade',
277
- title: `Trade ${deal.good.good.name}`,
278
- description: `Sell cargo, buy ${deal.maxQuantity} ${deal.good.good.name}, deliver to (${deal.destination.coordinates.x}, ${deal.destination.coordinates.y})`,
276
+ title: `Trade ${deal.item.item.name}`,
277
+ description: `Sell cargo, buy ${deal.maxQuantity} ${deal.item.item.name}, deliver to (${deal.destination.coordinates.x}, ${deal.destination.coordinates.y})`,
279
278
  reason: `${deal.marginPercent.toFixed(0)}% margin, ${deal.profitPerSecond.toFixed(
280
279
  1
281
280
  )}/s profit rate`,
@@ -364,7 +363,7 @@ export function createSellAndRepositionOption(
364
363
  id: `sell-reposition-${reposition.location.coordinates.x}-${reposition.location.coordinates.y}`,
365
364
  type: 'sell-and-reposition',
366
365
  title: 'Sell & Move',
367
- description: `Sell cargo here, travel empty to buy ${deal.good.good.name}`,
366
+ description: `Sell cargo here, travel empty to buy ${deal.item.item.name}`,
368
367
  reason: `No good trades here — ${deal.marginPercent.toFixed(
369
368
  0
370
369
  )}% margin trade available at destination`,
@@ -456,7 +455,7 @@ export interface CargoSaleItem {
456
455
  /**
457
456
  * Info about a discounted good for explore options
458
457
  */
459
- export interface DiscountedGoodInfo {
458
+ export interface DiscountedItemInfo {
460
459
  goodId: number
461
460
  name: string
462
461
  rarity: string
@@ -480,7 +479,7 @@ export interface PotentialDeal {
480
479
  export function createExploreOption(
481
480
  destination: Location,
482
481
  travelTime?: UInt32,
483
- discountedGood?: DiscountedGoodInfo,
482
+ discountedGood?: DiscountedItemInfo,
484
483
  travelTimeBreakdown?: EstimatedTravelTime,
485
484
  potentialDeals?: PotentialDeal[]
486
485
  ): CollectOption {
@@ -537,7 +536,7 @@ export function createExploreOption(
537
536
  */
538
537
  export interface CollectAnalysisCallbacks {
539
538
  getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>
540
- getMarketPrices: (location: Coordinates) => Promise<GoodPrice[]>
539
+ getMarketPrices: (location: Coordinates) => Promise<ItemPrice[]>
541
540
  getGameSeed?: () => Checksum256Type
542
541
  getState?: () => ServerContract.Types.state_row
543
542
  }
@@ -583,10 +582,10 @@ export async function analyzeCollectOptions(
583
582
  )
584
583
 
585
584
  if (hasCargo && dealsAtOrigin.length > 0) {
586
- const cargoGoodIds = new Set(cargo.map((c) => Number(c.good_id)))
585
+ const cargoGoodIds = new Set(cargo.map((c) => Number(c.item_id)))
587
586
 
588
587
  for (const deal of dealsAtOrigin.slice(0, 3)) {
589
- const dealGoodId = Number(deal.good.id)
588
+ const dealGoodId = Number(deal.item.id)
590
589
  if (cargoGoodIds.has(dealGoodId)) {
591
590
  continue
592
591
  }
@@ -768,10 +767,10 @@ export async function analyzeCollectOptions(
768
767
  if (!hasCargo && dealsAtOrigin.length > 0) {
769
768
  for (const deal of dealsAtOrigin.slice(0, 3)) {
770
769
  const option: CollectOption = {
771
- id: `trade-${deal.destination.coordinates.x}-${deal.destination.coordinates.y}-${deal.good.id}`,
770
+ id: `trade-${deal.destination.coordinates.x}-${deal.destination.coordinates.y}-${deal.item.id}`,
772
771
  type: 'sell-and-trade',
773
- title: `Trade ${deal.good.good.name}`,
774
- description: `Buy ${deal.maxQuantity} ${deal.good.good.name}, deliver to (${deal.destination.coordinates.x}, ${deal.destination.coordinates.y})`,
772
+ title: `Trade ${deal.item.item.name}`,
773
+ description: `Buy ${deal.maxQuantity} ${deal.item.item.name}, deliver to (${deal.destination.coordinates.x}, ${deal.destination.coordinates.y})`,
775
774
  reason: `${deal.marginPercent.toFixed(0)}% margin, ${deal.profitPerSecond.toFixed(
776
775
  1
777
776
  )}/s profit rate`,
@@ -805,7 +804,7 @@ export async function analyzeCollectOptions(
805
804
  dest: Location
806
805
  travelTime: UInt32
807
806
  travelTimeBreakdown: EstimatedTravelTime
808
- discountedGood?: DiscountedGoodInfo
807
+ discountedGood?: DiscountedItemInfo
809
808
  bestDiscount: number
810
809
  potentialDeals?: PotentialDeal[]
811
810
  score: number
@@ -822,11 +821,11 @@ export async function analyzeCollectOptions(
822
821
  unloadMass,
823
822
  })
824
823
 
825
- let discountedGood: DiscountedGoodInfo | undefined
824
+ let discountedGood: DiscountedItemInfo | undefined
826
825
  let bestDiscount = 0
827
826
 
828
827
  if (gameSeed && state) {
829
- const allGoods = getGoods()
828
+ const allGoods = getItems()
830
829
  for (const good of allGoods) {
831
830
  const rarity = getRarity(gameSeed, state.seed, dest.coordinates, good.id)
832
831
  if (rarity.minMultiplier < 1.0) {
@@ -863,8 +862,8 @@ export async function analyzeCollectOptions(
863
862
  )
864
863
 
865
864
  const potentialDeals: PotentialDeal[] = destDeals.map((d) => ({
866
- goodId: Number(d.good.id),
867
- goodName: d.good.good.name,
865
+ goodId: Number(d.item.id),
866
+ goodName: d.item.item.name,
868
867
  destinationCoords: d.destination.coordinates,
869
868
  marginPercent: d.marginPercent,
870
869
  profitPerSecond: d.profitPerSecond,
@@ -1,12 +1,11 @@
1
1
  import {Int64, UInt16, UInt32, UInt64, UInt64Type} from '@wharfkit/antelope'
2
- import {Coordinates, GoodPrice, PRECISION, ShipLike} from '../types'
2
+ import {Coordinates, ItemPrice, PRECISION, ShipLike} from '../types'
3
3
  import {Location} from '../entities/location'
4
4
  import {Ship} from '../entities/ship'
5
5
  import {
6
6
  distanceBetweenCoordinates,
7
7
  type EstimatedTravelTime,
8
8
  estimateTravelTime,
9
- hasEnergyForDistance,
10
9
  } from '../travel/travel'
11
10
  import {calculateProfitPerSecond, calculateTradeProfit, isProfitable} from './trade'
12
11
 
@@ -18,8 +17,8 @@ export interface Deal {
18
17
  origin: Location
19
18
  /** Destination location */
20
19
  destination: Location
21
- /** Good to trade */
22
- good: GoodPrice
20
+ /** Item to trade */
21
+ item: ItemPrice
23
22
  /** Distance between origin and destination */
24
23
  distance: UInt64
25
24
  /** Available supply at origin */
@@ -69,7 +68,7 @@ export async function findDealsForShip(
69
68
  ship: Ship,
70
69
  originLocation: Coordinates,
71
70
  getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>,
72
- getMarketPrices: (location: Coordinates) => Promise<GoodPrice[]>,
71
+ getMarketPrices: (location: Coordinates) => Promise<ItemPrice[]>,
73
72
  options: FindDealsOptions = {}
74
73
  ): Promise<Deal[]> {
75
74
  const {
@@ -124,7 +123,7 @@ export async function findDealsForShip(
124
123
  balance !== undefined
125
124
  ? balance.dividing(originGood.price)
126
125
  : UInt64.from(Number.MAX_SAFE_INTEGER)
127
- const canHaul = effectiveAvailableMass.dividing(originGood.good.mass)
126
+ const canHaul = effectiveAvailableMass.dividing(originGood.item.mass)
128
127
  const supplyLimit = UInt64.from(originGood.supply)
129
128
 
130
129
  // Find minimum of canAfford, canHaul, supplyLimit
@@ -135,7 +134,7 @@ export async function findDealsForShip(
135
134
  if (maxQuantity.equals(UInt64.zero)) continue
136
135
 
137
136
  // Calculate travel time with cargo (includes recharge + load time)
138
- const cargoMass = originGood.good.mass.multiplying(maxQuantity)
137
+ const cargoMass = originGood.item.mass.multiplying(maxQuantity)
139
138
  const availableSpaceUInt = UInt64.from(availableSpace)
140
139
  const baseMass =
141
140
  availableSpace !== undefined
@@ -162,7 +161,7 @@ export async function findDealsForShip(
162
161
  deals.push({
163
162
  origin,
164
163
  destination: destLocation,
165
- good: originGood,
164
+ item: originGood,
166
165
  distance,
167
166
  supply: originGood.supply,
168
167
  buyPrice: originGood.price,
@@ -191,7 +190,7 @@ export async function findBestDeal(
191
190
  ship: Ship,
192
191
  originLocation: Coordinates,
193
192
  getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>,
194
- getMarketPrices: (location: Coordinates) => Promise<GoodPrice[]>,
193
+ getMarketPrices: (location: Coordinates) => Promise<ItemPrice[]>,
195
194
  options: FindDealsOptions = {}
196
195
  ): Promise<Deal | undefined> {
197
196
  const deals = await findDealsForShip(
@@ -1,7 +1,7 @@
1
1
  import {Int64, Int64Type, UInt32, UInt32Type, UInt64} from '@wharfkit/antelope'
2
2
  import {Ship} from '../entities/ship'
3
3
  import {Player} from '../entities/player'
4
- import {GoodPrice} from '../types'
4
+ import {ItemPrice} from '../types'
5
5
 
6
6
  /**
7
7
  * Trade calculation result
@@ -53,10 +53,10 @@ export function calculateUpdatedCargoCost(
53
53
  export function calculateMaxTradeQuantity(
54
54
  ship: Ship,
55
55
  player: Player,
56
- goodPrice: GoodPrice
56
+ goodPrice: ItemPrice
57
57
  ): TradeCalculation {
58
58
  const pricePerUnit = UInt32.from(goodPrice.price)
59
- const massPerUnit = UInt32.from(goodPrice.good.mass)
59
+ const massPerUnit = UInt32.from(goodPrice.item.mass)
60
60
 
61
61
  const spaceForQuantity = ship.availableCapacity.dividing(massPerUnit)
62
62
  const affordableQuantity = player.balance.dividing(pricePerUnit)
@@ -128,21 +128,21 @@ export function calculateProfitPerSecond(profit: Int64Type, travelTimeSeconds: U
128
128
  /**
129
129
  * Find the best good to trade between two locations
130
130
  */
131
- export function findBestGoodToTrade(
131
+ export function findBestItemToTrade(
132
132
  ship: Ship,
133
133
  player: Player,
134
- originPrices: GoodPrice[],
135
- destPrices: GoodPrice[],
134
+ originPrices: ItemPrice[],
135
+ destPrices: ItemPrice[],
136
136
  travelTimeSeconds: UInt32Type
137
137
  ): {
138
- good: GoodPrice
138
+ item: ItemPrice
139
139
  quantity: number
140
140
  profit: number
141
141
  profitPerSecond: number
142
142
  margin: number
143
143
  } | null {
144
144
  let bestTrade: {
145
- good: GoodPrice
145
+ item: ItemPrice
146
146
  quantity: number
147
147
  profit: number
148
148
  profitPerSecond: number
@@ -169,7 +169,7 @@ export function findBestGoodToTrade(
169
169
  if (profitPerSecond > bestProfitPerSecond) {
170
170
  bestProfitPerSecond = profitPerSecond
171
171
  bestTrade = {
172
- good: originPrice,
172
+ item: originPrice,
173
173
  quantity: calc.maxQuantity,
174
174
  profit: Number(tradeResult.profit),
175
175
  profitPerSecond,
@@ -29,8 +29,9 @@ import {
29
29
  MIN_ORBITAL_ALTITUDE,
30
30
  PRECISION,
31
31
  ShipLike,
32
+ TaskType,
32
33
  } from '../types'
33
- import {getGood} from '../market/goods'
34
+ import {getItem} from '../market/items'
34
35
  import {hasSystem} from '../utils/system'
35
36
 
36
37
  export function calc_orbital_altitude(mass: number): number {
@@ -133,7 +134,7 @@ export function calc_flighttime(distance: UInt64Type, acceleration: number): UIn
133
134
  }
134
135
 
135
136
  export function calc_loader_flighttime(ship: ShipLike, mass: UInt64, altitude?: number): UInt32 {
136
- const z = altitude ?? ship.location.z?.toNumber() ?? calc_orbital_altitude(Number(mass))
137
+ const z = altitude ?? ship.coordinates.z?.toNumber() ?? calc_orbital_altitude(Number(mass))
137
138
  return calc_flighttime(z, calc_loader_acceleration(ship, mass))
138
139
  }
139
140
 
@@ -157,14 +158,14 @@ export function calc_acceleration(thrust: number, mass: number): number {
157
158
  export function calc_ship_mass(ship: ShipLike, cargos: CargoMassInfo[]): UInt64 {
158
159
  const mass = UInt64.from(0)
159
160
 
160
- mass.add(ship.mass)
161
+ mass.add(ship.hullmass)
161
162
 
162
163
  if (ship.loaders.quantity.gt(UInt32.zero)) {
163
164
  mass.add(ship.loaders.mass.multiplying(ship.loaders.quantity))
164
165
  }
165
166
 
166
167
  for (const cargo of cargos) {
167
- mass.add(getGood(cargo.good_id).mass.multiplying(cargo.quantity))
168
+ mass.add(getItem(cargo.item_id).mass.multiplying(cargo.quantity))
168
169
  }
169
170
 
170
171
  return mass
@@ -182,9 +183,9 @@ export function calculateTransferTime(
182
183
  let mass = UInt64.from(0)
183
184
 
184
185
  for (const cargo of cargos) {
185
- const qty = quantities?.get(Number(cargo.good_id)) ?? 0
186
+ const qty = quantities?.get(Number(cargo.item_id)) ?? 0
186
187
  if (qty > 0) {
187
- const good_mass = getGood(cargo.good_id).mass
188
+ const good_mass = getItem(cargo.item_id).mass
188
189
  const cargo_mass = good_mass.multiplying(qty)
189
190
  mass = UInt64.from(mass).adding(cargo_mass)
190
191
  }
@@ -230,12 +231,12 @@ export function calculateLoadTimeBreakdown(
230
231
  let mass_load = UInt64.from(0)
231
232
 
232
233
  for (const cargo of cargos) {
233
- const goodId = Number(cargo.good_id)
234
+ const goodId = Number(cargo.item_id)
234
235
  const loadQty = loadQuantities?.get(goodId) ?? 0
235
236
  const unloadQty = unloadQuantities?.get(goodId) ?? 0
236
237
 
237
238
  if (loadQty > 0 || unloadQty > 0) {
238
- const good = getGood(cargo.good_id)
239
+ const good = getItem(cargo.item_id)
239
240
 
240
241
  if (loadQty > 0) {
241
242
  const cargo_mass = good.mass.multiplying(loadQty)
@@ -358,6 +359,66 @@ export interface TransferEntity {
358
359
  }
359
360
  }
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
+
361
422
  export function calc_transfer_duration(
362
423
  source: TransferEntity,
363
424
  dest: TransferEntity,
@@ -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'