@shipload/sdk 2.0.0-rc1 → 2.0.0-rc10

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 (74) hide show
  1. package/lib/shipload.d.ts +1591 -1101
  2. package/lib/shipload.js +6735 -3491
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +6421 -3275
  5. package/lib/shipload.m.js.map +1 -1
  6. package/package.json +6 -6
  7. package/src/capabilities/crafting.ts +26 -0
  8. package/src/capabilities/extraction.ts +36 -0
  9. package/src/capabilities/guards.ts +38 -0
  10. package/src/capabilities/hauling.ts +22 -0
  11. package/src/capabilities/index.ts +8 -0
  12. package/src/capabilities/loading.ts +8 -0
  13. package/src/capabilities/modules.ts +57 -0
  14. package/src/capabilities/movement.ts +29 -0
  15. package/src/capabilities/storage.ts +72 -0
  16. package/src/contracts/server.ts +890 -309
  17. package/src/data/capabilities.ts +408 -0
  18. package/src/data/categories.ts +58 -0
  19. package/src/data/colors.ts +52 -0
  20. package/src/data/items.json +17 -0
  21. package/src/data/locations.ts +53 -0
  22. package/src/data/nebula-adjectives.json +211 -0
  23. package/src/data/nebula-nouns.json +151 -0
  24. package/src/data/recipes.ts +571 -0
  25. package/src/data/syllables.json +1386 -780
  26. package/src/data/tiers.ts +45 -0
  27. package/src/derivation/crafting.ts +197 -0
  28. package/src/derivation/index.ts +28 -0
  29. package/src/derivation/location-size.ts +15 -0
  30. package/src/derivation/resources.ts +142 -0
  31. package/src/derivation/stats.ts +146 -0
  32. package/src/derivation/stratum.ts +118 -0
  33. package/src/entities/cargo-utils.ts +46 -9
  34. package/src/entities/container.ts +106 -0
  35. package/src/entities/entity-inventory.ts +13 -13
  36. package/src/entities/inventory-accessor.ts +42 -0
  37. package/src/entities/location.ts +7 -188
  38. package/src/entities/makers.ts +72 -0
  39. package/src/entities/player.ts +1 -273
  40. package/src/entities/ship-deploy.ts +263 -0
  41. package/src/entities/ship.ts +93 -453
  42. package/src/entities/warehouse.ts +34 -148
  43. package/src/errors.ts +4 -4
  44. package/src/index-module.ts +225 -42
  45. package/src/managers/actions.ts +107 -78
  46. package/src/managers/context.ts +0 -9
  47. package/src/managers/entities.ts +22 -5
  48. package/src/managers/index.ts +0 -1
  49. package/src/managers/locations.ts +15 -79
  50. package/src/market/items.ts +30 -0
  51. package/src/nft/description.ts +175 -0
  52. package/src/nft/deserializers.ts +81 -0
  53. package/src/nft/index.ts +2 -0
  54. package/src/resolution/resolve-item.ts +313 -0
  55. package/src/scheduling/accessor.ts +82 -0
  56. package/src/scheduling/projection.ts +158 -54
  57. package/src/scheduling/schedule.ts +24 -0
  58. package/src/shipload.ts +0 -5
  59. package/src/travel/travel.ts +93 -19
  60. package/src/types/capabilities.ts +71 -0
  61. package/src/types/entity-traits.ts +69 -0
  62. package/src/types/entity.ts +39 -0
  63. package/src/types/index.ts +3 -0
  64. package/src/types.ts +76 -33
  65. package/src/utils/hash.ts +1 -1
  66. package/src/utils/system.ts +139 -11
  67. package/src/data/goods.json +0 -23
  68. package/src/managers/trades.ts +0 -119
  69. package/src/market/goods.ts +0 -31
  70. package/src/market/market.ts +0 -209
  71. package/src/market/rolls.ts +0 -8
  72. package/src/trading/collect.ts +0 -939
  73. package/src/trading/deal.ts +0 -208
  74. package/src/trading/trade.ts +0 -203
@@ -1,19 +1,11 @@
1
1
  import {Action, Int64, Name, NameType, UInt16, UInt32, UInt64, UInt64Type} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
- import {Ship} from '../entities/ship'
4
3
  import {CoordinatesType, EntityType, EntityTypeName} from '../types'
5
4
  import {ServerContract} from '../contracts'
6
5
 
7
- interface SellableCargo {
8
- good_id: {toNumber(): number} | number
9
- quantity: {toNumber(): number} | number
10
- hasCargo: boolean
11
- }
12
-
13
- export type CargoItemInput = {
14
- goodId: UInt64Type
15
- quantity: UInt64Type
16
- unitCost?: UInt64Type
6
+ export type EntityRefInput = {
7
+ entityType: EntityTypeName
8
+ entityId: UInt64Type
17
9
  }
18
10
 
19
11
  export class ActionsManager extends BaseManager {
@@ -30,6 +22,24 @@ export class ActionsManager extends BaseManager {
30
22
  })
31
23
  }
32
24
 
25
+ grouptravel(entities: EntityRefInput[], destination: CoordinatesType, recharge = true): Action {
26
+ const entityRefs = entities.map((e) =>
27
+ ServerContract.Types.entity_ref.from({
28
+ entity_type: e.entityType,
29
+ entity_id: UInt64.from(e.entityId),
30
+ })
31
+ )
32
+ const x = Int64.from(destination.x)
33
+ const y = Int64.from(destination.y)
34
+
35
+ return this.server.action('grouptravel', {
36
+ entities: entityRefs,
37
+ x,
38
+ y,
39
+ recharge,
40
+ })
41
+ }
42
+
33
43
  resolve(entityId: UInt64Type, entityType: EntityTypeName = EntityType.SHIP): Action {
34
44
  return this.server.action('resolve', {
35
45
  entity_type: entityType,
@@ -61,108 +71,127 @@ export class ActionsManager extends BaseManager {
61
71
  sourceId: UInt64Type,
62
72
  destType: EntityTypeName,
63
73
  destId: UInt64Type,
64
- cargo: CargoItemInput[]
74
+ goodId: UInt64Type,
75
+ quantity: UInt64Type
65
76
  ): 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
77
  return this.server.action('transfer', {
74
78
  source_type: sourceType,
75
79
  source_id: UInt64.from(sourceId),
76
80
  dest_type: destType,
77
81
  dest_id: UInt64.from(destId),
78
- cargo: cargoItems,
82
+ item_id: UInt16.from(goodId),
83
+ quantity: UInt32.from(quantity),
79
84
  })
80
85
  }
81
86
 
82
- buyGoods(shipId: UInt64Type, goodId: UInt64Type, quantity: UInt64Type): Action {
83
- return this.server.action('buygoods', {
84
- ship_id: UInt64.from(shipId),
85
- good_id: UInt64.from(goodId),
86
- quantity: UInt64.from(quantity),
87
+ foundCompany(account: NameType, name: string): Action {
88
+ return this.platform.action('foundcompany', {
89
+ account: Name.from(account),
90
+ name,
91
+ })
92
+ }
93
+
94
+ join(account: NameType): Action {
95
+ return this.server.action('join', {
96
+ account: Name.from(account),
87
97
  })
88
98
  }
89
99
 
90
- sellGoods(shipId: UInt64Type, goodId: UInt64Type, quantity: UInt64Type): Action {
91
- return this.server.action('sellgoods', {
100
+ extract(shipId: UInt64Type): Action {
101
+ return this.server.action('extract', {
92
102
  ship_id: UInt64.from(shipId),
93
- good_id: UInt64.from(goodId),
94
- quantity: UInt64.from(quantity),
95
103
  })
96
104
  }
97
105
 
98
- buyShip(account: NameType, name: string): Action {
99
- return this.server.action('buyship', {
100
- account: Name.from(account),
101
- name,
106
+ warp(shipId: UInt64Type, destination: CoordinatesType): Action {
107
+ const x = Int64.from(destination.x)
108
+ const y = Int64.from(destination.y)
109
+
110
+ return this.server.action('warp', {
111
+ entity_type: EntityType.SHIP,
112
+ id: UInt64.from(shipId),
113
+ x,
114
+ y,
102
115
  })
103
116
  }
104
117
 
105
- buyWarehouse(account: NameType, shipId: UInt64Type, name: string): Action {
106
- return this.server.action('buywarehouse', {
107
- account: Name.from(account),
108
- ship_id: UInt64.from(shipId),
109
- name,
118
+ craft(
119
+ entityType: EntityTypeName,
120
+ entityId: UInt64Type,
121
+ recipeId: number,
122
+ quantity: number,
123
+ inputs: ServerContract.ActionParams.Type.cargo_item[]
124
+ ): Action {
125
+ const cargoInputs = inputs.map((i) => ServerContract.Types.cargo_item.from(i))
126
+ return this.server.action('craft', {
127
+ entity_type: entityType,
128
+ id: UInt64.from(entityId),
129
+ recipe_id: UInt16.from(recipeId),
130
+ quantity: UInt32.from(quantity),
131
+ inputs: cargoInputs,
110
132
  })
111
133
  }
112
134
 
113
- takeLoan(account: NameType, amount: UInt64Type): Action {
114
- return this.server.action('takeloan', {
115
- account: Name.from(account),
116
- amount: UInt64.from(amount),
135
+ blend(
136
+ entityType: EntityTypeName,
137
+ entityId: UInt64Type,
138
+ inputs: ServerContract.ActionParams.Type.cargo_item[]
139
+ ): Action {
140
+ const cargoInputs = inputs.map((i) => ServerContract.Types.cargo_item.from(i))
141
+ return this.server.action('blend', {
142
+ entity_type: entityType,
143
+ id: UInt64.from(entityId),
144
+ inputs: cargoInputs,
117
145
  })
118
146
  }
119
147
 
120
- payLoan(account: NameType, amount: UInt64Type): Action {
121
- return this.server.action('payloan', {
122
- account: Name.from(account),
123
- amount: UInt64.from(amount),
148
+ deploy(
149
+ entityType: EntityTypeName,
150
+ entityId: UInt64Type,
151
+ packedItemId: number,
152
+ seed: bigint,
153
+ entityName: string
154
+ ): Action {
155
+ return this.server.action('deploy', {
156
+ entity_type: entityType,
157
+ id: UInt64.from(entityId),
158
+ packed_item_id: UInt16.from(packedItemId),
159
+ seed: UInt64.from(seed),
160
+ entity_name: entityName,
124
161
  })
125
162
  }
126
163
 
127
- foundCompany(account: NameType, name: string): Action {
128
- return this.platform.action('foundcompany', {
129
- account: Name.from(account),
130
- name,
164
+ addmodule(
165
+ entityType: EntityTypeName,
166
+ entityId: UInt64Type,
167
+ moduleIndex: number,
168
+ moduleCargoId: UInt64Type,
169
+ targetCargoId: UInt64Type = UInt64.from(0)
170
+ ): Action {
171
+ return this.server.action('addmodule', {
172
+ entity_type: entityType,
173
+ entity_id: UInt64.from(entityId),
174
+ module_index: moduleIndex,
175
+ module_cargo_id: UInt64.from(moduleCargoId),
176
+ target_cargo_id: UInt64.from(targetCargoId),
131
177
  })
132
178
  }
133
179
 
134
- join(account: NameType): Action {
135
- return this.server.action('join', {
136
- account: Name.from(account),
180
+ rmmodule(
181
+ entityType: EntityTypeName,
182
+ entityId: UInt64Type,
183
+ moduleIndex: number,
184
+ targetCargoId: UInt64Type = UInt64.from(0)
185
+ ): Action {
186
+ return this.server.action('rmmodule', {
187
+ entity_type: entityType,
188
+ entity_id: UInt64.from(entityId),
189
+ module_index: moduleIndex,
190
+ target_cargo_id: UInt64.from(targetCargoId),
137
191
  })
138
192
  }
139
193
 
140
194
  joinGame(account: NameType, companyName: string): Action[] {
141
195
  return [this.foundCompany(account, companyName), this.join(account)]
142
196
  }
143
-
144
- sellAllCargo(ship: Ship | UInt64Type, cargo?: SellableCargo[]): Action[] {
145
- let shipCargo: SellableCargo[]
146
-
147
- if (ship instanceof Ship) {
148
- shipCargo = cargo || ship.inventory
149
- } else {
150
- if (!cargo) {
151
- throw new Error('cargo parameter required when ship is a UInt64Type')
152
- }
153
- shipCargo = cargo
154
- }
155
-
156
- const shipId = ship instanceof Ship ? ship.id : UInt64.from(ship)
157
-
158
- return shipCargo
159
- .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
- )
167
- }
168
197
  }
@@ -6,7 +6,6 @@ import {GameState} from '../entities/gamestate'
6
6
  import {EntitiesManager} from './entities'
7
7
  import {PlayersManager} from './players'
8
8
  import {LocationsManager} from './locations'
9
- import {TradesManager} from './trades'
10
9
  import {EpochsManager} from './epochs'
11
10
  import {ActionsManager} from './actions'
12
11
 
@@ -14,7 +13,6 @@ export class GameContext {
14
13
  private _entities?: EntitiesManager
15
14
  private _players?: PlayersManager
16
15
  private _locations?: LocationsManager
17
- private _trades?: TradesManager
18
16
  private _epochs?: EpochsManager
19
17
  private _actions?: ActionsManager
20
18
 
@@ -48,13 +46,6 @@ export class GameContext {
48
46
  return this._locations
49
47
  }
50
48
 
51
- get trades(): TradesManager {
52
- if (!this._trades) {
53
- this._trades = new TradesManager(this)
54
- }
55
- return this._trades
56
- }
57
-
58
49
  get epochs(): EpochsManager {
59
50
  if (!this._epochs) {
60
51
  this._epochs = new EpochsManager(this)
@@ -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
 
@@ -4,6 +4,5 @@ export {EntitiesManager} from './entities'
4
4
  export type {EntityType} from './entities'
5
5
  export {PlayersManager} from './players'
6
6
  export {LocationsManager} from './locations'
7
- export {TradesManager} from './trades'
8
7
  export {EpochsManager} from './epochs'
9
8
  export {ActionsManager} from './actions'
@@ -1,54 +1,11 @@
1
- import {Bytes, Checksum256, UInt16Type, UInt64} from '@wharfkit/antelope'
1
+ import {UInt16Type, UInt64, UInt64Type} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
- import {CoordinatesType, Distance, GoodPrice} from '../types'
4
- import {marketPrice, marketPrices} from '../market/market'
3
+ import {CoordinatesType, coordsToLocationId, Distance} from '../types'
5
4
  import {hasSystem} from '../utils/system'
6
5
  import {findNearbyPlanets} from '../travel/travel'
7
- import {Location, toLocation} from '../entities/location'
6
+ import {ServerContract} from '../contracts'
8
7
 
9
8
  export class LocationsManager extends BaseManager {
10
- async getMarketPrice(location: CoordinatesType, goodId: number): Promise<GoodPrice> {
11
- const game = await this.getGame()
12
- const state = await this.getState()
13
- return marketPrice(location, goodId, game.config.seed, state)
14
- }
15
-
16
- async getMarketPrices(location: CoordinatesType): Promise<GoodPrice[]> {
17
- const game = await this.getGame()
18
- const state = await this.getState()
19
- return marketPrices(location, game.config.seed, state)
20
- }
21
-
22
- async getMarketPricesWithSupply(location: CoordinatesType): Promise<GoodPrice[]> {
23
- const [game, state, locationRows] = await Promise.all([
24
- this.getGame(),
25
- this.getState(),
26
- this.getLocation(location),
27
- ])
28
-
29
- const prices = marketPrices(location, game.config.seed, state)
30
-
31
- const supplyMap = new Map<number, number>()
32
- for (const row of locationRows) {
33
- if (UInt64.from(row.epoch).equals(state.epoch)) {
34
- supplyMap.set(Number(row.good_id), Number(row.supply))
35
- }
36
- }
37
-
38
- return prices.map((price) => {
39
- const actualSupply = supplyMap.get(Number(price.id))
40
- if (actualSupply !== undefined) {
41
- return GoodPrice.from({
42
- id: price.id,
43
- good: price.good,
44
- price: price.price,
45
- supply: UInt64.from(actualSupply),
46
- })
47
- }
48
- return price
49
- })
50
- }
51
-
52
9
  async hasSystem(location: CoordinatesType): Promise<boolean> {
53
10
  const game = await this.getGame()
54
11
  return hasSystem(game.config.seed, location)
@@ -62,42 +19,21 @@ export class LocationsManager extends BaseManager {
62
19
  return findNearbyPlanets(game.config.seed, origin, maxDistance)
63
20
  }
64
21
 
65
- async getLocation(location: CoordinatesType) {
66
- const hash = Checksum256.hash(Bytes.from(`${location.x}-${location.y}`, 'utf8'))
67
- return this.server.table('location').all({
68
- index_position: 'secondary',
69
- from: hash,
70
- to: hash,
71
- })
22
+ async getLocationEntity(
23
+ id: UInt64Type
24
+ ): Promise<ServerContract.Types.location_row | undefined> {
25
+ const row = await this.server.table('location').get(UInt64.from(id))
26
+ return row ?? undefined
72
27
  }
73
28
 
74
- async getLocationWithPrices(coords: CoordinatesType): Promise<Location> {
75
- const location = toLocation(coords)
76
- const prices = await this.getMarketPrices(location.coordinates)
77
- location.setMarketPrices(prices)
78
- return location
29
+ async getLocationEntityAt(
30
+ coords: CoordinatesType
31
+ ): Promise<ServerContract.Types.location_row | undefined> {
32
+ const id = coordsToLocationId(coords)
33
+ return this.getLocationEntity(id)
79
34
  }
80
35
 
81
- async getLocationWithSupply(coords: CoordinatesType): Promise<Location> {
82
- const location = toLocation(coords)
83
- const [rows, state] = await Promise.all([
84
- this.getLocation(location.coordinates),
85
- this.getState(),
86
- ])
87
- location.setLocationRows(rows, state.epoch)
88
- return location
89
- }
90
-
91
- async getLocationComplete(coords: CoordinatesType): Promise<Location> {
92
- const location = toLocation(coords)
93
- const [prices, rows, state] = await Promise.all([
94
- this.getMarketPrices(location.coordinates),
95
- this.getLocation(location.coordinates),
96
- this.getState(),
97
- ])
98
-
99
- location.setMarketPrices(prices)
100
- location.setLocationRows(rows, state.epoch)
101
- return location
36
+ async getAllLocationEntities(): Promise<ServerContract.Types.location_row[]> {
37
+ return this.server.table('location').all()
102
38
  }
103
39
  }
@@ -0,0 +1,30 @@
1
+ import {UInt16, UInt16Type} from '@wharfkit/antelope'
2
+ import {Item} from '../types'
3
+ import itemsData from '../data/items.json'
4
+
5
+ const items: Item[] = itemsData.map((g) =>
6
+ Item.from({
7
+ id: g.id,
8
+ name: g.name,
9
+ description: g.description,
10
+ mass: g.mass,
11
+ category: g.category,
12
+ tier: g.tier,
13
+ color: g.color,
14
+ })
15
+ )
16
+
17
+ export const itemIds = items.map((i) => i.id)
18
+
19
+ export function getItem(itemId: UInt16Type): Item {
20
+ const id = UInt16.from(itemId)
21
+ const item = items.find((i) => i.id.equals(id))
22
+ if (!item) {
23
+ throw new Error(`Item with id ${id} not found`)
24
+ }
25
+ return item
26
+ }
27
+
28
+ export function getItems(): Item[] {
29
+ return items
30
+ }
@@ -0,0 +1,175 @@
1
+ import {
2
+ getModuleCapabilityType,
3
+ ITEM_ENGINE_T1,
4
+ ITEM_EXTRACTOR_T1,
5
+ ITEM_GENERATOR_T1,
6
+ ITEM_LOADER_T1,
7
+ ITEM_MANUFACTURING_T1,
8
+ ITEM_STORAGE_T1,
9
+ MODULE_CRAFTER,
10
+ MODULE_ENGINE,
11
+ MODULE_EXTRACTOR,
12
+ MODULE_GENERATOR,
13
+ MODULE_LOADER,
14
+ MODULE_STORAGE,
15
+ } from '../capabilities/modules'
16
+ import {
17
+ ITEM_CONTAINER_T1_PACKED,
18
+ ITEM_CONTAINER_T2_PACKED,
19
+ ITEM_SHIP_T1_PACKED,
20
+ ITEM_WAREHOUSE_T1_PACKED,
21
+ } from '../data/recipes'
22
+ import {decodeStat} from '../derivation/crafting'
23
+
24
+ function idiv(a: number, b: number): number {
25
+ return Math.floor(a / b)
26
+ }
27
+
28
+ export function computeBaseHullmass(seed: bigint): number {
29
+ const density = decodeStat(seed, 1)
30
+ return 25000 + 75 * density
31
+ }
32
+
33
+ export function computeBaseCapacityShip(seed: bigint): number {
34
+ const s = decodeStat(seed, 0) + decodeStat(seed, 2) + decodeStat(seed, 3)
35
+ return Math.floor(1_000_000 * Math.pow(10, s / 2997))
36
+ }
37
+
38
+ export function computeBaseCapacityWarehouse(seed: bigint): number {
39
+ const s = decodeStat(seed, 0) + decodeStat(seed, 2) + decodeStat(seed, 3)
40
+ return Math.floor(20_000_000 * Math.pow(10, s / 2997))
41
+ }
42
+
43
+ export const computeEngineThrust = (vol: number): number => 400 + idiv(vol * 3, 4)
44
+ export const computeEngineDrain = (thm: number): number => Math.max(30, 50 - idiv(thm, 70))
45
+ export const computeGeneratorCap = (res: number): number => 300 + idiv(res, 6)
46
+ export const computeGeneratorRech = (clr: number): number => 5 + idiv(clr * 15, 1000)
47
+ export const computeExtractorRate = (str: number): number => 200 + str
48
+ export const computeExtractorDrain = (con: number): number => Math.max(10, 50 - idiv(con, 20))
49
+ export const computeExtractorDepth = (tol: number): number => 200 + idiv(tol * 3, 2)
50
+ export const computeExtractorDrill = (ref: number): number => 100 + idiv(ref * 4, 5)
51
+ export const computeLoaderMass = (duc: number): number => Math.max(200, 2000 - duc * 2)
52
+ export const computeLoaderThrust = (pla: number): number => 1 + idiv(pla, 500)
53
+ export const computeCrafterSpeed = (rea: number): number => 100 + idiv(rea * 4, 5)
54
+ export const computeCrafterDrain = (clr: number): number => Math.max(5, 30 - idiv(clr, 33))
55
+
56
+ export function entityDisplayName(itemId: number): string {
57
+ switch (itemId) {
58
+ case ITEM_SHIP_T1_PACKED:
59
+ return 'Ship T1'
60
+ case ITEM_WAREHOUSE_T1_PACKED:
61
+ return 'Warehouse T1'
62
+ case ITEM_CONTAINER_T1_PACKED:
63
+ return 'Container T1'
64
+ case ITEM_CONTAINER_T2_PACKED:
65
+ return 'Container T2'
66
+ default:
67
+ return 'Entity'
68
+ }
69
+ }
70
+
71
+ export function moduleDisplayName(itemId: number): string {
72
+ switch (itemId) {
73
+ case ITEM_ENGINE_T1:
74
+ return 'Engine T1'
75
+ case ITEM_GENERATOR_T1:
76
+ return 'Generator T1'
77
+ case ITEM_EXTRACTOR_T1:
78
+ return 'Extractor T1'
79
+ case ITEM_LOADER_T1:
80
+ return 'Loader T1'
81
+ case ITEM_MANUFACTURING_T1:
82
+ return 'Manufacturing T1'
83
+ case ITEM_STORAGE_T1:
84
+ return 'Storage T1'
85
+ default:
86
+ return 'Module'
87
+ }
88
+ }
89
+
90
+ export function formatModuleLine(slot: number, itemId: number, seed: bigint): string {
91
+ let out = `Slot ${slot} - `
92
+ if (itemId === 0) {
93
+ out += '(empty)'
94
+ return out
95
+ }
96
+
97
+ out += moduleDisplayName(itemId)
98
+ const subtype = getModuleCapabilityType(itemId)
99
+
100
+ switch (subtype) {
101
+ case MODULE_ENGINE: {
102
+ const vol = decodeStat(seed, 0)
103
+ const thm = decodeStat(seed, 1)
104
+ out += ` Thrust ${computeEngineThrust(vol)} Drain ${computeEngineDrain(thm)}`
105
+ break
106
+ }
107
+ case MODULE_GENERATOR: {
108
+ const res = decodeStat(seed, 0)
109
+ const clr = decodeStat(seed, 1)
110
+ out += ` Capacity ${computeGeneratorCap(res)} Recharge ${computeGeneratorRech(clr)}`
111
+ break
112
+ }
113
+ case MODULE_EXTRACTOR: {
114
+ const str = decodeStat(seed, 0)
115
+ const tol = decodeStat(seed, 1)
116
+ const con = decodeStat(seed, 3)
117
+ const ref = decodeStat(seed, 4)
118
+ out += ` Rate ${computeExtractorRate(str)} Depth ${computeExtractorDepth(
119
+ tol
120
+ )} Drill ${computeExtractorDrill(ref)} Drain ${computeExtractorDrain(con)}`
121
+ break
122
+ }
123
+ case MODULE_LOADER: {
124
+ const duc = decodeStat(seed, 0)
125
+ const pla = decodeStat(seed, 1)
126
+ out += ` Mass ${computeLoaderMass(duc)} Thrust ${computeLoaderThrust(pla)}`
127
+ break
128
+ }
129
+ case MODULE_CRAFTER: {
130
+ const rea = decodeStat(seed, 0)
131
+ const clr = decodeStat(seed, 1)
132
+ out += ` Speed ${computeCrafterSpeed(rea)} Drain ${computeCrafterDrain(clr)}`
133
+ break
134
+ }
135
+ case MODULE_STORAGE: {
136
+ const str = decodeStat(seed, 0)
137
+ const duc = decodeStat(seed, 1)
138
+ const pur = decodeStat(seed, 2)
139
+ const sum = str + duc + pur
140
+ const pct = 10 + idiv(sum * 10, 2997)
141
+ out += ` +${pct}% capacity`
142
+ break
143
+ }
144
+ }
145
+ return out
146
+ }
147
+
148
+ export function buildEntityDescription(
149
+ itemId: number,
150
+ hullSeed: bigint,
151
+ moduleItems: number[],
152
+ moduleSeeds: bigint[]
153
+ ): string {
154
+ const hullMass = computeBaseHullmass(hullSeed)
155
+ let baseCapacity = 0
156
+ if (itemId === ITEM_SHIP_T1_PACKED) {
157
+ baseCapacity = computeBaseCapacityShip(hullSeed)
158
+ } else if (itemId === ITEM_WAREHOUSE_T1_PACKED) {
159
+ baseCapacity = computeBaseCapacityWarehouse(hullSeed)
160
+ }
161
+
162
+ let out = entityDisplayName(itemId)
163
+ out += ` - Hull ${hullMass} mass`
164
+ if (baseCapacity > 0) {
165
+ out += ` * ${baseCapacity} capacity`
166
+ }
167
+ out += '\n\n'
168
+
169
+ for (let i = 0; i < moduleItems.length; i++) {
170
+ out += formatModuleLine(i, moduleItems[i], moduleSeeds[i] ?? 0n)
171
+ out += '\n'
172
+ }
173
+
174
+ return out
175
+ }