@shipload/sdk 2.0.0-rc1 → 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 (42) hide show
  1. package/README.md +349 -1
  2. package/lib/shipload.d.ts +609 -248
  3. package/lib/shipload.js +1683 -1031
  4. package/lib/shipload.js.map +1 -1
  5. package/lib/shipload.m.js +1613 -1047
  6. package/lib/shipload.m.js.map +1 -1
  7. package/package.json +1 -2
  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 +340 -136
  15. package/src/data/goods.json +2 -2
  16. package/src/entities/cargo-utils.ts +96 -1
  17. package/src/entities/container.ts +70 -0
  18. package/src/entities/inventory-accessor.ts +46 -0
  19. package/src/entities/location.ts +22 -8
  20. package/src/entities/makers.ts +69 -0
  21. package/src/entities/player.ts +2 -1
  22. package/src/entities/ship.ts +86 -437
  23. package/src/entities/warehouse.ts +28 -144
  24. package/src/index-module.ts +34 -1
  25. package/src/managers/actions.ts +60 -28
  26. package/src/managers/entities.ts +22 -5
  27. package/src/managers/locations.ts +28 -9
  28. package/src/managers/trades.ts +2 -2
  29. package/src/market/market.ts +3 -4
  30. package/src/scheduling/accessor.ts +82 -0
  31. package/src/scheduling/projection.ts +125 -53
  32. package/src/scheduling/schedule.ts +24 -0
  33. package/src/trading/collect.ts +0 -1
  34. package/src/trading/deal.ts +0 -1
  35. package/src/travel/travel.ts +63 -2
  36. package/src/types/capabilities.ts +79 -0
  37. package/src/types/entity-traits.ts +70 -0
  38. package/src/types/entity.ts +36 -0
  39. package/src/types/index.ts +3 -0
  40. package/src/types.ts +75 -8
  41. package/src/utils/hash.ts +1 -1
  42. package/src/utils/system.ts +132 -4
@@ -1,166 +1,65 @@
1
- import {Name, NameType, UInt32, UInt64, UInt64Type} from '@wharfkit/antelope'
1
+ import {UInt64, UInt64Type} from '@wharfkit/antelope'
2
2
  import {ServerContract} from '../contracts'
3
- import {Coordinates, CoordinatesType, TaskType} from '../types'
3
+ import {CoordinatesType} from '../types'
4
4
  import {Location} from './location'
5
- import {getGood} from '../market/goods'
6
- import * as schedule from '../scheduling/schedule'
7
- import {Scheduleable} from '../scheduling/schedule'
5
+ import {ScheduleAccessor} from '../scheduling/accessor'
6
+ import {InventoryAccessor} from './inventory-accessor'
8
7
  import {EntityInventory} from './entity-inventory'
8
+ import * as schedule from '../scheduling/schedule'
9
9
 
10
10
  export interface WarehouseStateInput {
11
11
  id: UInt64Type
12
- owner: NameType
12
+ owner: string
13
13
  name: string
14
- location: CoordinatesType | {x: number; y: number; z?: number}
14
+ coordinates: CoordinatesType | {x: number; y: number; z?: number}
15
15
  capacity: number
16
16
  loaders: ServerContract.Types.loader_stats
17
17
  schedule?: ServerContract.Types.schedule
18
18
  cargo?: ServerContract.Types.cargo_item[]
19
19
  }
20
20
 
21
- export class Warehouse extends ServerContract.Types.entity_info implements Scheduleable {
22
- static fromState(state: WarehouseStateInput): Warehouse {
23
- const entityInfo = ServerContract.Types.entity_info.from({
24
- type: Name.from('warehouse'),
25
- id: UInt64.from(state.id),
26
- owner: Name.from(state.owner),
27
- entity_name: state.name,
28
- location: ServerContract.Types.coordinates.from(state.location),
29
- capacity: UInt32.from(state.capacity),
30
- cargomass: UInt32.from(0),
31
- cargo: state.cargo || [],
32
- loaders: state.loaders,
33
- is_idle: !state.schedule,
34
- current_task_elapsed: UInt32.from(0),
35
- current_task_remaining: UInt32.from(0),
36
- pending_tasks: [],
37
- schedule: state.schedule,
38
- mass: UInt32.from(0),
39
- energy: 0,
40
- engines: ServerContract.Types.movement_stats.from({
41
- thrust: 0,
42
- drain: 0,
43
- maxmass: 0,
44
- }),
45
- generator: ServerContract.Types.energy_stats.from({
46
- capacity: 0,
47
- recharge: 0,
48
- }),
49
- })
50
- return new Warehouse(entityInfo)
51
- }
52
-
53
- private _location?: Location
54
- private _inventory?: EntityInventory[]
21
+ export class Warehouse extends ServerContract.Types.entity_info {
22
+ private _sched?: ScheduleAccessor
23
+ private _inv?: InventoryAccessor
55
24
 
56
25
  get name(): string {
57
26
  return this.entity_name
58
27
  }
59
28
 
29
+ get inv(): InventoryAccessor {
30
+ return (this._inv ??= new InventoryAccessor(this))
31
+ }
32
+
60
33
  get inventory(): EntityInventory[] {
61
- if (!this._inventory) {
62
- this._inventory = this.cargo.map((item) => new EntityInventory(item))
63
- }
64
- return this._inventory
34
+ return this.inv.items
65
35
  }
66
36
 
67
- get hasSchedule(): boolean {
68
- return schedule.hasSchedule(this)
37
+ get sched(): ScheduleAccessor {
38
+ return (this._sched ??= new ScheduleAccessor(this))
69
39
  }
70
40
 
71
41
  get isIdle(): boolean {
72
42
  return this.is_idle
73
43
  }
74
44
 
75
- get tasks(): ServerContract.Types.task[] {
76
- return schedule.getTasks(this)
77
- }
78
-
79
- scheduleDuration(): number {
80
- return schedule.scheduleDuration(this)
81
- }
82
-
83
- scheduleElapsed(now: Date): number {
84
- return schedule.scheduleElapsed(this, now)
85
- }
86
-
87
- scheduleRemaining(now: Date): number {
88
- return schedule.scheduleRemaining(this, now)
89
- }
90
-
91
- scheduleComplete(now: Date): boolean {
92
- return schedule.scheduleComplete(this, now)
93
- }
94
-
95
- currentTaskIndex(now: Date): number {
96
- return schedule.currentTaskIndex(this, now)
97
- }
98
-
99
- currentTask(now: Date): ServerContract.Types.task | undefined {
100
- return schedule.currentTask(this, now)
101
- }
102
-
103
- currentTaskType(now: Date): TaskType | undefined {
104
- return schedule.currentTaskType(this, now)
105
- }
106
-
107
- getTaskStartTime(index: number): number {
108
- return schedule.getTaskStartTime(this, index)
109
- }
110
-
111
- getTaskElapsed(index: number, now: Date): number {
112
- return schedule.getTaskElapsed(this, index, now)
113
- }
114
-
115
- getTaskRemaining(index: number, now: Date): number {
116
- return schedule.getTaskRemaining(this, index, now)
117
- }
118
-
119
- isTaskComplete(index: number, now: Date): boolean {
120
- return schedule.isTaskComplete(this, index, now)
121
- }
122
-
123
- isTaskInProgress(index: number, now: Date): boolean {
124
- return schedule.isTaskInProgress(this, index, now)
125
- }
126
-
127
- currentTaskProgress(now: Date): number {
128
- return schedule.currentTaskProgress(this, now)
129
- }
130
-
131
- scheduleProgress(now: Date): number {
132
- return schedule.scheduleProgress(this, now)
133
- }
134
-
135
45
  isLoading(now: Date): boolean {
136
- const taskType = this.currentTaskType(now)
137
- return taskType === TaskType.LOAD
46
+ return schedule.isLoading(this, now)
138
47
  }
139
48
 
140
49
  isUnloading(now: Date): boolean {
141
- const taskType = this.currentTaskType(now)
142
- return taskType === TaskType.UNLOAD
143
- }
144
-
145
- calcCargoMass(): UInt64 {
146
- let mass = UInt64.from(0)
147
- for (const item of this.cargo) {
148
- const good = getGood(item.good_id)
149
- mass = mass.adding(good.mass.multiplying(item.quantity))
150
- }
151
- return mass
50
+ return schedule.isUnloading(this, now)
152
51
  }
153
52
 
154
- get currentLocation(): Coordinates {
155
- return this.location
53
+ get location(): Location {
54
+ return Location.from(this.coordinates)
156
55
  }
157
56
 
158
57
  get totalCargoMass(): UInt64 {
159
- return this.inventory.reduce((sum, c) => sum.adding(c.totalMass), UInt64.from(0))
58
+ return this.inv.totalMass
160
59
  }
161
60
 
162
61
  get cargoValue(): UInt64 {
163
- return this.inventory.reduce((sum, c) => sum.adding(c.totalCost), UInt64.from(0))
62
+ return this.inv.totalValue
164
63
  }
165
64
 
166
65
  get maxCapacity(): UInt64 {
@@ -168,38 +67,23 @@ export class Warehouse extends ServerContract.Types.entity_info implements Sched
168
67
  }
169
68
 
170
69
  get availableCapacity(): UInt64 {
171
- if (this.totalCargoMass.gte(this.maxCapacity)) {
172
- return UInt64.from(0)
173
- }
174
- return this.maxCapacity.subtracting(this.totalCargoMass)
70
+ const cargo = this.totalCargoMass
71
+ return cargo.gte(this.maxCapacity) ? UInt64.from(0) : this.maxCapacity.subtracting(cargo)
175
72
  }
176
73
 
177
74
  hasSpace(goodMass: UInt64, quantity: number): boolean {
178
- const additionalMass = goodMass.multiplying(quantity)
179
- const newTotal = this.totalCargoMass.adding(additionalMass)
180
- return newTotal.lte(this.maxCapacity)
75
+ return this.totalCargoMass.adding(goodMass.multiplying(quantity)).lte(this.maxCapacity)
181
76
  }
182
77
 
183
78
  get isFull(): boolean {
184
79
  return this.totalCargoMass.gte(this.maxCapacity)
185
80
  }
186
81
 
187
- get locationObject(): Location {
188
- if (!this._location) {
189
- this._location = Location.from(this.location)
190
- }
191
- return this._location
192
- }
193
-
194
- setLocation(location: Location): void {
195
- this._location = location
196
- }
197
-
198
82
  getCargoForGood(goodId: UInt64Type): EntityInventory | undefined {
199
- return this.inventory.find((c) => c.good_id.equals(goodId))
83
+ return this.inv.forGood(goodId)
200
84
  }
201
85
 
202
86
  get orbitalAltitude(): number {
203
- return this.location.z?.toNumber() || 0
87
+ return this.coordinates.z?.toNumber() || 0
204
88
  }
205
89
  }
@@ -8,6 +8,10 @@ export {Shipload} from './shipload'
8
8
  export {Ship} from './entities/ship'
9
9
  export type {ShipStateInput} from './entities/ship'
10
10
  export {Warehouse} from './entities/warehouse'
11
+ export type {WarehouseStateInput} from './entities/warehouse'
12
+ export {Container} from './entities/container'
13
+ export type {ContainerStateInput} from './entities/container'
14
+ export {makeShip, makeWarehouse, makeContainer} from './entities/makers'
11
15
 
12
16
  export type movement_stats = ServerContract.Types.movement_stats
13
17
  export type energy_stats = ServerContract.Types.energy_stats
@@ -16,6 +20,14 @@ export type schedule = ServerContract.Types.schedule
16
20
  export type task = ServerContract.Types.task
17
21
  export type cargo_item = ServerContract.Types.cargo_item
18
22
  export type warehouse_row = ServerContract.Types.warehouse_row
23
+ export type container_row = ServerContract.Types.container_row
24
+ export type extractor_stats = ServerContract.Types.extractor_stats
25
+ export type mixture_info = ServerContract.Types.mixture_info
26
+ export type mixture_component = ServerContract.Types.mixture_component
27
+ export type location_static = ServerContract.Types.location_static
28
+ export type location_epoch = ServerContract.Types.location_epoch
29
+ export type location_derived = ServerContract.Types.location_derived
30
+ export type location_row = ServerContract.Types.location_row
19
31
  export {Player} from './entities/player'
20
32
  export type {PlayerStateInput} from './entities/player'
21
33
  export {EntityInventory} from './entities/entity-inventory'
@@ -31,13 +43,23 @@ export {
31
43
  ActionsManager,
32
44
  } from './managers'
33
45
  export type {EntityType} from './managers'
46
+ export type {EntityRefInput} from './managers/actions'
34
47
 
35
48
  export {getGood, getGoods, goodIds} from './market/goods'
36
49
  export {getCurrentEpoch, getEpochInfo} from './scheduling/epoch'
37
50
  export type {EpochInfo} from './scheduling/epoch'
38
51
  export {marketPrice, marketPrices, getRarity, Rarities} from './market/market'
39
52
  export type {Rarity} from './market/market'
40
- export {getSystemName, hasSystem} from './utils/system'
53
+ export {
54
+ getSystemName,
55
+ hasSystem,
56
+ getLocationType,
57
+ isExtractableLocation,
58
+ deriveLocationStatic,
59
+ deriveLocationEpoch,
60
+ deriveLocation,
61
+ deriveLocationMixture,
62
+ } from './utils/system'
41
63
 
42
64
  export {hash, hash512} from './utils/hash'
43
65
 
@@ -91,12 +113,16 @@ export {
91
113
  estimateTravelTime,
92
114
  estimateDealTravelTime,
93
115
  hasEnergyForDistance,
116
+ getFlightOrigin,
117
+ getDestinationLocation,
118
+ getPositionAt,
94
119
  } from './travel/travel'
95
120
  export type {
96
121
  LoadTimeBreakdown,
97
122
  EstimatedTravelTime,
98
123
  EstimateTravelTimeOptions,
99
124
  TransferEntity,
125
+ HasScheduleAndLocation,
100
126
  } from './travel/travel'
101
127
 
102
128
  export {
@@ -114,9 +140,16 @@ export type {TradeCalculation, TradeProfitResult} from './trading/trade'
114
140
 
115
141
  export * as schedule from './scheduling/schedule'
116
142
  export type {Scheduleable, ScheduleData} from './scheduling/schedule'
143
+ export {ScheduleAccessor, createScheduleAccessor} from './scheduling/accessor'
144
+ export {InventoryAccessor, createInventoryAccessor} from './entities/inventory-accessor'
145
+ export type {HasCargo} from './entities/inventory-accessor'
117
146
 
118
147
  export * as cargoUtils from './entities/cargo-utils'
119
148
  export type {CargoData} from './entities/cargo-utils'
120
149
 
121
150
  export {projectEntity, projectEntityAt, createProjectedEntity} from './scheduling/projection'
122
151
  export type {Projectable, ProjectedEntity} from './scheduling/projection'
152
+
153
+ export * from './types/capabilities'
154
+ export * from './types/entity'
155
+ export * from './capabilities'
@@ -10,10 +10,9 @@ interface SellableCargo {
10
10
  hasCargo: boolean
11
11
  }
12
12
 
13
- export type CargoItemInput = {
14
- goodId: UInt64Type
15
- quantity: UInt64Type
16
- unitCost?: UInt64Type
13
+ export type EntityRefInput = {
14
+ entityType: EntityTypeName
15
+ entityId: UInt64Type
17
16
  }
18
17
 
19
18
  export class ActionsManager extends BaseManager {
@@ -30,6 +29,24 @@ export class ActionsManager extends BaseManager {
30
29
  })
31
30
  }
32
31
 
32
+ grouptravel(entities: EntityRefInput[], destination: CoordinatesType, recharge = true): Action {
33
+ const entityRefs = entities.map((e) =>
34
+ ServerContract.Types.entity_ref.from({
35
+ entity_type: e.entityType,
36
+ entity_id: UInt64.from(e.entityId),
37
+ })
38
+ )
39
+ const x = Int64.from(destination.x)
40
+ const y = Int64.from(destination.y)
41
+
42
+ return this.server.action('grouptravel', {
43
+ entities: entityRefs,
44
+ x,
45
+ y,
46
+ recharge,
47
+ })
48
+ }
49
+
33
50
  resolve(entityId: UInt64Type, entityType: EntityTypeName = EntityType.SHIP): Action {
34
51
  return this.server.action('resolve', {
35
52
  entity_type: entityType,
@@ -61,37 +78,44 @@ export class ActionsManager extends BaseManager {
61
78
  sourceId: UInt64Type,
62
79
  destType: EntityTypeName,
63
80
  destId: UInt64Type,
64
- cargo: CargoItemInput[]
81
+ goodId: UInt64Type,
82
+ quantity: UInt64Type
65
83
  ): Action {
66
- const cargoItems = cargo.map((c) =>
67
- ServerContract.Types.cargo_item.from({
68
- good_id: UInt16.from(c.goodId),
69
- quantity: UInt32.from(c.quantity),
70
- unit_cost: UInt64.from(c.unitCost || 0),
71
- })
72
- )
73
84
  return this.server.action('transfer', {
74
85
  source_type: sourceType,
75
86
  source_id: UInt64.from(sourceId),
76
87
  dest_type: destType,
77
88
  dest_id: UInt64.from(destId),
78
- cargo: cargoItems,
89
+ good_id: UInt16.from(goodId),
90
+ quantity: UInt32.from(quantity),
79
91
  })
80
92
  }
81
93
 
82
- buyGoods(shipId: UInt64Type, goodId: UInt64Type, quantity: UInt64Type): Action {
94
+ buyGoods(
95
+ entityId: UInt64Type,
96
+ goodId: UInt64Type,
97
+ quantity: UInt64Type,
98
+ entityType: EntityTypeName = EntityType.SHIP
99
+ ): Action {
83
100
  return this.server.action('buygoods', {
84
- ship_id: UInt64.from(shipId),
85
- good_id: UInt64.from(goodId),
86
- quantity: UInt64.from(quantity),
101
+ entity_type: entityType,
102
+ id: UInt64.from(entityId),
103
+ good_id: UInt16.from(goodId),
104
+ quantity: UInt32.from(quantity),
87
105
  })
88
106
  }
89
107
 
90
- sellGoods(shipId: UInt64Type, goodId: UInt64Type, quantity: UInt64Type): Action {
108
+ sellGoods(
109
+ entityId: UInt64Type,
110
+ goodId: UInt64Type,
111
+ quantity: UInt64Type,
112
+ entityType: EntityTypeName = EntityType.SHIP
113
+ ): Action {
91
114
  return this.server.action('sellgoods', {
92
- ship_id: UInt64.from(shipId),
93
- good_id: UInt64.from(goodId),
94
- quantity: UInt64.from(quantity),
115
+ entity_type: entityType,
116
+ id: UInt64.from(entityId),
117
+ good_id: UInt16.from(goodId),
118
+ quantity: UInt32.from(quantity),
95
119
  })
96
120
  }
97
121
 
@@ -110,6 +134,14 @@ export class ActionsManager extends BaseManager {
110
134
  })
111
135
  }
112
136
 
137
+ buyContainer(account: NameType, shipId: UInt64Type, name: string): Action {
138
+ return this.server.action('buycontainer', {
139
+ account: Name.from(account),
140
+ ship_id: UInt64.from(shipId),
141
+ name,
142
+ })
143
+ }
144
+
113
145
  takeLoan(account: NameType, amount: UInt64Type): Action {
114
146
  return this.server.action('takeloan', {
115
147
  account: Name.from(account),
@@ -137,6 +169,12 @@ export class ActionsManager extends BaseManager {
137
169
  })
138
170
  }
139
171
 
172
+ extract(shipId: UInt64Type): Action {
173
+ return this.server.action('extract', {
174
+ ship_id: UInt64.from(shipId),
175
+ })
176
+ }
177
+
140
178
  joinGame(account: NameType, companyName: string): Action[] {
141
179
  return [this.foundCompany(account, companyName), this.join(account)]
142
180
  }
@@ -157,12 +195,6 @@ export class ActionsManager extends BaseManager {
157
195
 
158
196
  return shipCargo
159
197
  .filter((c) => c.hasCargo)
160
- .map((c) =>
161
- this.server.action('sellgoods', {
162
- ship_id: shipId,
163
- good_id: c.good_id,
164
- quantity: c.quantity,
165
- })
166
- )
198
+ .map((c) => this.sellGoods(shipId, c.good_id, c.quantity, EntityType.SHIP))
167
199
  }
168
200
  }
@@ -2,12 +2,13 @@ import {Name, NameType, UInt64Type} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
3
  import {Ship} from '../entities/ship'
4
4
  import {Warehouse} from '../entities/warehouse'
5
+ import {Container} from '../entities/container'
5
6
  import {ServerContract} from '../contracts'
6
7
 
7
- export type EntityType = 'ship' | 'warehouse'
8
+ export type EntityType = 'ship' | 'warehouse' | 'container' | 'location'
8
9
 
9
10
  export class EntitiesManager extends BaseManager {
10
- async getEntity(type: EntityType, id: UInt64Type): Promise<Ship | Warehouse> {
11
+ async getEntity(type: EntityType, id: UInt64Type): Promise<Ship | Warehouse | Container> {
11
12
  const result = await this.server.readonly('getentity', {
12
13
  entity_type: Name.from(type),
13
14
  entity_id: id,
@@ -19,7 +20,7 @@ export class EntitiesManager extends BaseManager {
19
20
  async getEntities(
20
21
  owner: NameType | ServerContract.Types.player_row,
21
22
  type?: EntityType
22
- ): Promise<(Ship | Warehouse)[]> {
23
+ ): Promise<(Ship | Warehouse | Container)[]> {
23
24
  const ownerName = this.resolveOwner(owner)
24
25
  const result = await this.server.readonly('getentities', {
25
26
  owner: ownerName,
@@ -49,6 +50,10 @@ export class EntitiesManager extends BaseManager {
49
50
  return (await this.getEntity('warehouse', id)) as Warehouse
50
51
  }
51
52
 
53
+ async getContainer(id: UInt64Type): Promise<Container> {
54
+ return (await this.getEntity('container', id)) as Container
55
+ }
56
+
52
57
  async getShips(owner: NameType | ServerContract.Types.player_row): Promise<Ship[]> {
53
58
  return (await this.getEntities(owner, 'ship')) as Ship[]
54
59
  }
@@ -57,6 +62,10 @@ export class EntitiesManager extends BaseManager {
57
62
  return (await this.getEntities(owner, 'warehouse')) as Warehouse[]
58
63
  }
59
64
 
65
+ async getContainers(owner: NameType | ServerContract.Types.player_row): Promise<Container[]> {
66
+ return (await this.getEntities(owner, 'container')) as Container[]
67
+ }
68
+
60
69
  async getShipSummaries(
61
70
  owner: NameType | ServerContract.Types.player_row
62
71
  ): Promise<ServerContract.Types.entity_summary[]> {
@@ -69,11 +78,19 @@ export class EntitiesManager extends BaseManager {
69
78
  return this.getSummaries(owner, 'warehouse')
70
79
  }
71
80
 
72
- private wrapEntity(entity: ServerContract.Types.entity_info): Ship | Warehouse {
81
+ async getContainerSummaries(
82
+ owner: NameType | ServerContract.Types.player_row
83
+ ): Promise<ServerContract.Types.entity_summary[]> {
84
+ return this.getSummaries(owner, 'container')
85
+ }
86
+
87
+ private wrapEntity(entity: ServerContract.Types.entity_info): Ship | Warehouse | Container {
73
88
  if (entity.type.equals('ship')) {
74
89
  return new Ship(entity)
75
- } else {
90
+ } else if (entity.type.equals('warehouse')) {
76
91
  return new Warehouse(entity)
92
+ } else {
93
+ return new Container(entity)
77
94
  }
78
95
  }
79
96
 
@@ -1,10 +1,11 @@
1
- import {Bytes, Checksum256, UInt16Type, UInt64} from '@wharfkit/antelope'
1
+ import {Bytes, Checksum256, UInt16Type, UInt64, UInt64Type} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
- import {CoordinatesType, Distance, GoodPrice} from '../types'
3
+ import {CoordinatesType, coordsToLocationId, Distance, GoodPrice} from '../types'
4
4
  import {marketPrice, marketPrices} from '../market/market'
5
5
  import {hasSystem} from '../utils/system'
6
6
  import {findNearbyPlanets} from '../travel/travel'
7
7
  import {Location, toLocation} from '../entities/location'
8
+ import {ServerContract} from '../contracts'
8
9
 
9
10
  export class LocationsManager extends BaseManager {
10
11
  async getMarketPrice(location: CoordinatesType, goodId: number): Promise<GoodPrice> {
@@ -20,16 +21,16 @@ export class LocationsManager extends BaseManager {
20
21
  }
21
22
 
22
23
  async getMarketPricesWithSupply(location: CoordinatesType): Promise<GoodPrice[]> {
23
- const [game, state, locationRows] = await Promise.all([
24
+ const [game, state, supplyRows] = await Promise.all([
24
25
  this.getGame(),
25
26
  this.getState(),
26
- this.getLocation(location),
27
+ this.getSupplyRows(location),
27
28
  ])
28
29
 
29
30
  const prices = marketPrices(location, game.config.seed, state)
30
31
 
31
32
  const supplyMap = new Map<number, number>()
32
- for (const row of locationRows) {
33
+ for (const row of supplyRows) {
33
34
  if (UInt64.from(row.epoch).equals(state.epoch)) {
34
35
  supplyMap.set(Number(row.good_id), Number(row.supply))
35
36
  }
@@ -62,9 +63,9 @@ export class LocationsManager extends BaseManager {
62
63
  return findNearbyPlanets(game.config.seed, origin, maxDistance)
63
64
  }
64
65
 
65
- async getLocation(location: CoordinatesType) {
66
+ async getSupplyRows(location: CoordinatesType) {
66
67
  const hash = Checksum256.hash(Bytes.from(`${location.x}-${location.y}`, 'utf8'))
67
- return this.server.table('location').all({
68
+ return this.server.table('supply').all({
68
69
  index_position: 'secondary',
69
70
  from: hash,
70
71
  to: hash,
@@ -81,7 +82,7 @@ export class LocationsManager extends BaseManager {
81
82
  async getLocationWithSupply(coords: CoordinatesType): Promise<Location> {
82
83
  const location = toLocation(coords)
83
84
  const [rows, state] = await Promise.all([
84
- this.getLocation(location.coordinates),
85
+ this.getSupplyRows(location.coordinates),
85
86
  this.getState(),
86
87
  ])
87
88
  location.setLocationRows(rows, state.epoch)
@@ -92,7 +93,7 @@ export class LocationsManager extends BaseManager {
92
93
  const location = toLocation(coords)
93
94
  const [prices, rows, state] = await Promise.all([
94
95
  this.getMarketPrices(location.coordinates),
95
- this.getLocation(location.coordinates),
96
+ this.getSupplyRows(location.coordinates),
96
97
  this.getState(),
97
98
  ])
98
99
 
@@ -100,4 +101,22 @@ export class LocationsManager extends BaseManager {
100
101
  location.setLocationRows(rows, state.epoch)
101
102
  return location
102
103
  }
104
+
105
+ async getLocationEntity(
106
+ id: UInt64Type
107
+ ): Promise<ServerContract.Types.location_row | undefined> {
108
+ const row = await this.server.table('location').get(UInt64.from(id))
109
+ return row ?? undefined
110
+ }
111
+
112
+ async getLocationEntityAt(
113
+ coords: CoordinatesType
114
+ ): Promise<ServerContract.Types.location_row | undefined> {
115
+ const id = coordsToLocationId(coords)
116
+ return this.getLocationEntity(id)
117
+ }
118
+
119
+ async getAllLocationEntities(): Promise<ServerContract.Types.location_row[]> {
120
+ return this.server.table('location').all()
121
+ }
103
122
  }
@@ -83,7 +83,7 @@ export class TradesManager extends BaseManager {
83
83
  originLocation?: Coordinates,
84
84
  options: FindDealsOptions = {}
85
85
  ): Promise<Deal[]> {
86
- const origin = originLocation || ship.currentLocation
86
+ const origin = originLocation || Coordinates.from(ship.coordinates)
87
87
  const callbacks = await this.createCallbacks()
88
88
 
89
89
  const deals = await findDealsForShip(
@@ -111,7 +111,7 @@ export class TradesManager extends BaseManager {
111
111
  arrivedAt?: Coordinates,
112
112
  options: CollectAnalysisOptions = {}
113
113
  ): Promise<CollectAnalysis> {
114
- const location = arrivedAt || ship.currentLocation
114
+ const location = arrivedAt || Coordinates.from(ship.coordinates)
115
115
  const callbacks = await this.createCallbacks()
116
116
 
117
117
  return analyzeCollectOptions(ship, location, callbacks, options)
@@ -163,11 +163,10 @@ export function getSupply(
163
163
  const r = roll(gameSeed, seed)
164
164
  const percent = r / 65535
165
165
  const epoch = 1 + Number(state.epoch) / 90
166
- // NOTE: Contract has bug where 1/3 is integer division = 0, so pow(ships, 0) = 1
167
- // TODO: Update this when contract is fixed to use (double)1/(double)3
168
- const ship = Math.pow(Number(state.ships), 0)
166
+ const ship = 1
169
167
  const goodIdNum = Number(goodId)
170
- return Math.floor((128 / goodIdNum) * percent * ship * epoch)
168
+ const base = Math.floor(128 / goodIdNum)
169
+ return Math.floor(base * percent * ship * epoch)
171
170
  }
172
171
 
173
172
  export function marketPrice(