@shipload/sdk 1.0.0-next.7 → 1.0.0-next.71

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 (203) hide show
  1. package/lib/scan.d.ts +52 -0
  2. package/lib/scan.js +162 -0
  3. package/lib/scan.js.map +1 -0
  4. package/lib/scan.m.js +152 -0
  5. package/lib/scan.m.js.map +1 -0
  6. package/lib/shipload.d.ts +5822 -1484
  7. package/lib/shipload.js +20838 -5419
  8. package/lib/shipload.js.map +1 -1
  9. package/lib/shipload.m.js +20674 -5669
  10. package/lib/shipload.m.js.map +1 -1
  11. package/lib/testing.d.ts +1691 -0
  12. package/lib/testing.js +7109 -0
  13. package/lib/testing.js.map +1 -0
  14. package/lib/testing.m.js +7103 -0
  15. package/lib/testing.m.js.map +1 -0
  16. package/package.json +20 -2
  17. package/src/capabilities/craftable.test.ts +82 -0
  18. package/src/capabilities/craftable.ts +82 -0
  19. package/src/capabilities/crafting.test.ts +80 -0
  20. package/src/capabilities/crafting.ts +50 -8
  21. package/src/capabilities/gathering.test.ts +29 -0
  22. package/src/capabilities/gathering.ts +38 -20
  23. package/src/capabilities/hauling.ts +0 -5
  24. package/src/capabilities/index.ts +0 -1
  25. package/src/capabilities/modules.ts +27 -30
  26. package/src/capabilities/movement.ts +1 -1
  27. package/src/capabilities/storage.test.ts +26 -0
  28. package/src/capabilities/storage.ts +22 -7
  29. package/src/contracts/fund.ts +306 -0
  30. package/src/contracts/platform.ts +312 -3
  31. package/src/contracts/server.ts +2793 -478
  32. package/src/contracts/token.ts +170 -0
  33. package/src/contracts.ts +2 -0
  34. package/src/coordinates/address.ts +88 -0
  35. package/src/coordinates/constants.test.ts +15 -0
  36. package/src/coordinates/constants.ts +23 -0
  37. package/src/coordinates/index.ts +15 -0
  38. package/src/coordinates/memo.test.ts +47 -0
  39. package/src/coordinates/memo.ts +20 -0
  40. package/src/coordinates/permutation.ts +77 -0
  41. package/src/coordinates/regions.ts +48 -0
  42. package/src/coordinates/sectors.ts +115 -0
  43. package/src/data/capabilities.ts +49 -18
  44. package/src/data/capability-formulas.ts +26 -14
  45. package/src/data/catalog.test.ts +19 -0
  46. package/src/data/catalog.ts +13 -3
  47. package/src/data/charters.json +396 -0
  48. package/src/data/citizenry-adjectives.json +42 -0
  49. package/src/data/citizenry-nouns.json +50 -0
  50. package/src/data/colors.ts +14 -32
  51. package/src/data/entities.json +421 -15
  52. package/src/data/item-ids.ts +53 -13
  53. package/src/data/items.json +330 -77
  54. package/src/data/kind-registry.json +212 -0
  55. package/src/data/kind-registry.ts +192 -0
  56. package/src/data/metadata.ts +312 -51
  57. package/src/data/recipes-runtime.ts +6 -23
  58. package/src/data/recipes.json +2173 -173
  59. package/src/data/tiers.ts +9 -6
  60. package/src/derivation/build-methods.test.ts +71 -0
  61. package/src/derivation/build-methods.ts +50 -0
  62. package/src/derivation/capabilities.test.ts +348 -0
  63. package/src/derivation/capabilities.ts +707 -0
  64. package/src/derivation/capability-mappings.ts +60 -16
  65. package/src/derivation/crafting.test.ts +17 -0
  66. package/src/derivation/crafting.ts +57 -34
  67. package/src/derivation/index.ts +27 -2
  68. package/src/derivation/recipe-usage.test.ts +88 -0
  69. package/src/derivation/recipe-usage.ts +141 -0
  70. package/src/derivation/reserve-regen.ts +34 -0
  71. package/src/derivation/resources.ts +9 -1
  72. package/src/derivation/rollups.test.ts +55 -0
  73. package/src/derivation/rollups.ts +72 -0
  74. package/src/derivation/stars.test.ts +67 -0
  75. package/src/derivation/stars.ts +25 -0
  76. package/src/derivation/stat-scaling.ts +12 -0
  77. package/src/derivation/stats.ts +6 -6
  78. package/src/derivation/strata.ts +5 -3
  79. package/src/derivation/stratum.ts +26 -22
  80. package/src/derivation/tiers.ts +40 -7
  81. package/src/derivation/upgrades.ts +14 -0
  82. package/src/derivation/wormhole.ts +154 -0
  83. package/src/entities/entity.ts +102 -0
  84. package/src/entities/gamestate.ts +3 -28
  85. package/src/entities/makers.ts +144 -136
  86. package/src/entities/slot-multiplier.ts +43 -0
  87. package/src/entity/hydrate.test.ts +156 -0
  88. package/src/entity/hydrate.ts +86 -0
  89. package/src/errors.ts +21 -16
  90. package/src/format.ts +42 -9
  91. package/src/index-module.ts +425 -32
  92. package/src/influence/ballot.test.ts +103 -0
  93. package/src/influence/ballot.ts +98 -0
  94. package/src/influence/categories.ts +32 -0
  95. package/src/influence/charter-metadata.test.ts +136 -0
  96. package/src/influence/charter-metadata.ts +236 -0
  97. package/src/influence/charters.test.ts +112 -0
  98. package/src/influence/charters.ts +150 -0
  99. package/src/influence/citizenry.ts +38 -0
  100. package/src/influence/civic-shuttle.test.ts +202 -0
  101. package/src/influence/civic-shuttle.ts +142 -0
  102. package/src/influence/civic.test.ts +287 -0
  103. package/src/influence/civic.ts +269 -0
  104. package/src/influence/constants.ts +84 -0
  105. package/src/influence/decay.ts +20 -0
  106. package/src/influence/decomp.ts +95 -0
  107. package/src/influence/demand.ts +106 -0
  108. package/src/influence/duration.ts +101 -0
  109. package/src/influence/index.ts +118 -0
  110. package/src/influence/influence.test.ts +450 -0
  111. package/src/influence/quality.ts +25 -0
  112. package/src/influence/valuation.ts +154 -0
  113. package/src/managers/actions.ts +950 -93
  114. package/src/managers/balances.test.ts +161 -0
  115. package/src/managers/balances.ts +93 -0
  116. package/src/managers/base.ts +10 -2
  117. package/src/managers/cluster.test.ts +39 -0
  118. package/src/managers/cluster.ts +53 -0
  119. package/src/managers/construction-types.ts +80 -0
  120. package/src/managers/construction.ts +453 -0
  121. package/src/managers/context.ts +58 -1
  122. package/src/managers/coordinates.ts +14 -0
  123. package/src/managers/entities.ts +35 -63
  124. package/src/managers/epochs.ts +72 -1
  125. package/src/managers/index.ts +38 -1
  126. package/src/managers/influence.test.ts +56 -0
  127. package/src/managers/influence.ts +425 -0
  128. package/src/managers/jobs.test.ts +96 -0
  129. package/src/managers/jobs.ts +58 -0
  130. package/src/managers/locations.ts +25 -29
  131. package/src/managers/nft.test.ts +21 -0
  132. package/src/managers/nft.ts +110 -0
  133. package/src/managers/players.ts +25 -0
  134. package/src/managers/plot.ts +122 -0
  135. package/src/nft/atomicassets.abi.json +1342 -0
  136. package/src/nft/atomicassets.ts +237 -0
  137. package/src/nft/atomicdata.ts +130 -0
  138. package/src/nft/buildImmutableData.ts +388 -0
  139. package/src/nft/description.ts +222 -100
  140. package/src/nft/index.ts +3 -0
  141. package/src/planner/index.ts +296 -0
  142. package/src/planner/planner.test.ts +459 -0
  143. package/src/receipts.ts +22 -0
  144. package/src/resolution/describe-module.ts +43 -25
  145. package/src/resolution/display-name.ts +39 -11
  146. package/src/resolution/resolve-item.test.ts +48 -0
  147. package/src/resolution/resolve-item.ts +112 -58
  148. package/src/scan/index.ts +244 -0
  149. package/src/scan/scan-wasm.base64.ts +2 -0
  150. package/src/scheduling/accessor.ts +65 -23
  151. package/src/scheduling/availability.test.ts +320 -0
  152. package/src/scheduling/availability.ts +251 -0
  153. package/src/scheduling/cancel.test.ts +550 -0
  154. package/src/scheduling/cancel.ts +254 -0
  155. package/src/scheduling/cluster-stock.test.ts +31 -0
  156. package/src/scheduling/cluster-stock.ts +15 -0
  157. package/src/scheduling/energy.ts +47 -0
  158. package/src/scheduling/epoch.ts +1 -0
  159. package/src/scheduling/idle-resolve.ts +45 -0
  160. package/src/scheduling/jobs.test.ts +448 -0
  161. package/src/scheduling/jobs.ts +343 -0
  162. package/src/scheduling/lane-core.ts +128 -0
  163. package/src/scheduling/lanes.test.ts +250 -0
  164. package/src/scheduling/lanes.ts +279 -0
  165. package/src/scheduling/projection.ts +265 -149
  166. package/src/scheduling/schedule.test.ts +163 -0
  167. package/src/scheduling/schedule.ts +282 -116
  168. package/src/scheduling/task-cargo.test.ts +110 -0
  169. package/src/scheduling/task-cargo.ts +62 -0
  170. package/src/scheduling/task-effects.test.ts +35 -0
  171. package/src/scheduling/task-effects.ts +34 -0
  172. package/src/scheduling/unwrap.test.ts +86 -0
  173. package/src/scheduling/unwrap.ts +190 -0
  174. package/src/shipload.ts +63 -4
  175. package/src/subscriptions/manager.cluster.test.ts +51 -0
  176. package/src/subscriptions/manager.ts +245 -172
  177. package/src/subscriptions/mappers.ts +5 -8
  178. package/src/subscriptions/types.ts +28 -3
  179. package/src/testing/catalog-hash.ts +19 -0
  180. package/src/testing/index.ts +2 -0
  181. package/src/testing/projection-parity.ts +167 -0
  182. package/src/travel/reach.test.ts +86 -0
  183. package/src/travel/reach.ts +34 -0
  184. package/src/travel/route-build.test.ts +63 -0
  185. package/src/travel/route-build.ts +60 -0
  186. package/src/travel/route-planner.ts +288 -0
  187. package/src/travel/route-simulator.ts +170 -0
  188. package/src/travel/travel.ts +190 -123
  189. package/src/types/capabilities.ts +37 -8
  190. package/src/types/entity.ts +3 -3
  191. package/src/types/index.ts +0 -1
  192. package/src/types.ts +81 -23
  193. package/src/utils/cargo.test.ts +14 -0
  194. package/src/utils/cargo.ts +2 -0
  195. package/src/utils/display-name.ts +70 -0
  196. package/src/utils/hash.ts +22 -2
  197. package/src/utils/system.ts +24 -5
  198. package/src/capabilities/loading.ts +0 -8
  199. package/src/entities/container.ts +0 -123
  200. package/src/entities/ship-deploy.ts +0 -295
  201. package/src/entities/ship.ts +0 -221
  202. package/src/entities/warehouse.ts +0 -127
  203. package/src/types/entity-traits.ts +0 -69
@@ -0,0 +1,161 @@
1
+ import {describe, expect, test} from 'bun:test'
2
+ import {Asset, type Name} from '@wharfkit/antelope'
3
+ import {BalancesManager} from './balances'
4
+ import type {GameContext} from './context'
5
+ import {PlatformContract} from '../contracts'
6
+
7
+ interface StubOptions {
8
+ depositConfig?: {token_contract: string; token_symbol: string} | null
9
+ balances?: {token_contract: string; balance: string}[] | null
10
+ wallet?: string[]
11
+ }
12
+
13
+ function stubContext(options: StubOptions = {}) {
14
+ const counts = {depositcfg: 0, balance: 0, currency: 0}
15
+ const rows = (options.balances ?? []).map((row) => PlatformContract.Types.balance_row.from(row))
16
+ const platform = {
17
+ table(name: string) {
18
+ if (name === 'depositcfg') {
19
+ return {
20
+ get: async () => {
21
+ counts.depositcfg++
22
+ return options.depositConfig
23
+ ? PlatformContract.Types.depositcfg_row.from(options.depositConfig)
24
+ : undefined
25
+ },
26
+ }
27
+ }
28
+ return {
29
+ get: async (key: Name) => {
30
+ counts.balance++
31
+ return rows.find((row) => row.token_contract.equals(key))
32
+ },
33
+ all: async () => {
34
+ counts.balance++
35
+ return rows
36
+ },
37
+ }
38
+ },
39
+ }
40
+ const client = {
41
+ v1: {
42
+ chain: {
43
+ get_currency_balance: async () => {
44
+ counts.currency++
45
+ return (options.wallet ?? []).map((value) => Asset.from(value))
46
+ },
47
+ },
48
+ },
49
+ }
50
+ const context = {platform, client} as unknown as GameContext
51
+ return {manager: new BalancesManager(context), counts}
52
+ }
53
+
54
+ const SCRAP = {token_contract: 'scrap.gm', token_symbol: '0,SCRAP'}
55
+
56
+ describe('getDepositConfig', () => {
57
+ test('reads the configured deposit token', async () => {
58
+ const {manager} = stubContext({depositConfig: SCRAP})
59
+ const config = await manager.getDepositConfig()
60
+ expect(String(config?.tokenContract)).toBe('scrap.gm')
61
+ expect(String(config?.symbol)).toBe('0,SCRAP')
62
+ })
63
+
64
+ test('caches the config across calls', async () => {
65
+ const {manager, counts} = stubContext({depositConfig: SCRAP})
66
+ await manager.getDepositConfig()
67
+ await manager.getDepositConfig()
68
+ expect(counts.depositcfg).toBe(1)
69
+ await manager.getDepositConfig(true)
70
+ expect(counts.depositcfg).toBe(2)
71
+ })
72
+
73
+ test('caches a missing config as null without refetching', async () => {
74
+ const {manager, counts} = stubContext({depositConfig: null})
75
+ expect(await manager.getDepositConfig()).toBeNull()
76
+ expect(await manager.getDepositConfig()).toBeNull()
77
+ expect(counts.depositcfg).toBe(1)
78
+ })
79
+ })
80
+
81
+ describe('getPlatformBalance', () => {
82
+ test('returns null when the owner has never opened a row', async () => {
83
+ const {manager} = stubContext({depositConfig: SCRAP, balances: []})
84
+ expect(await manager.getPlatformBalance('alice')).toBeNull()
85
+ })
86
+
87
+ test('returns a zero balance for an opened but empty row', async () => {
88
+ const {manager} = stubContext({
89
+ depositConfig: SCRAP,
90
+ balances: [{token_contract: 'scrap.gm', balance: '0 SCRAP'}],
91
+ })
92
+ const balance = await manager.getPlatformBalance('alice')
93
+ expect(balance).not.toBeNull()
94
+ expect(String(balance?.balance)).toBe('0 SCRAP')
95
+ expect(balance?.balance.units.toNumber()).toBe(0)
96
+ expect(balance?.balance.symbol.precision).toBe(0)
97
+ expect(String(balance?.owner)).toBe('alice')
98
+ })
99
+
100
+ test('defaults to the deposit token and honours an explicit contract', async () => {
101
+ const {manager} = stubContext({
102
+ depositConfig: SCRAP,
103
+ balances: [
104
+ {token_contract: 'scrap.gm', balance: '12 SCRAP'},
105
+ {token_contract: 'eosio.token', balance: '3.0000 EOS'},
106
+ ],
107
+ })
108
+ expect(String((await manager.getPlatformBalance('alice'))?.balance)).toBe('12 SCRAP')
109
+ expect(String((await manager.getPlatformBalance('alice', 'eosio.token'))?.balance)).toBe(
110
+ '3.0000 EOS'
111
+ )
112
+ })
113
+
114
+ test('returns null when no deposit token is configured', async () => {
115
+ const {manager, counts} = stubContext({depositConfig: null})
116
+ expect(await manager.getPlatformBalance('alice')).toBeNull()
117
+ expect(counts.balance).toBe(0)
118
+ })
119
+ })
120
+
121
+ describe('getPlatformBalances', () => {
122
+ test('returns every row the owner holds', async () => {
123
+ const {manager} = stubContext({
124
+ depositConfig: SCRAP,
125
+ balances: [
126
+ {token_contract: 'scrap.gm', balance: '12 SCRAP'},
127
+ {token_contract: 'eosio.token', balance: '3.0000 EOS'},
128
+ ],
129
+ })
130
+ const balances = await manager.getPlatformBalances('alice')
131
+ expect(balances.map((row) => String(row.balance))).toEqual(['12 SCRAP', '3.0000 EOS'])
132
+ expect(balances.map((row) => String(row.tokenContract))).toEqual([
133
+ 'scrap.gm',
134
+ 'eosio.token',
135
+ ])
136
+ })
137
+
138
+ test('returns an empty array for an owner with no rows', async () => {
139
+ const {manager} = stubContext({depositConfig: SCRAP, balances: []})
140
+ expect(await manager.getPlatformBalances('alice')).toEqual([])
141
+ })
142
+ })
143
+
144
+ describe('getWalletBalance', () => {
145
+ test('reads the wallet balance for the deposit token', async () => {
146
+ const {manager} = stubContext({depositConfig: SCRAP, wallet: ['500 SCRAP']})
147
+ const balance = await manager.getWalletBalance('alice')
148
+ expect(String(balance?.balance)).toBe('500 SCRAP')
149
+ expect(String(balance?.tokenContract)).toBe('scrap.gm')
150
+ })
151
+
152
+ test('returns null when the account holds none of the token', async () => {
153
+ const {manager} = stubContext({depositConfig: SCRAP, wallet: []})
154
+ expect(await manager.getWalletBalance('alice')).toBeNull()
155
+ })
156
+
157
+ test('ignores balances of other symbols on the same contract', async () => {
158
+ const {manager} = stubContext({depositConfig: SCRAP, wallet: ['1.0000 OTHER']})
159
+ expect(await manager.getWalletBalance('alice')).toBeNull()
160
+ })
161
+ })
@@ -0,0 +1,93 @@
1
+ import {Asset, Name, type NameType} from '@wharfkit/antelope'
2
+ import {BaseManager} from './base'
3
+ import type {PlatformContract} from '../contracts'
4
+
5
+ export interface DepositConfig {
6
+ tokenContract: Name
7
+ symbol: Asset.Symbol
8
+ }
9
+
10
+ export interface PlatformBalance {
11
+ owner: Name
12
+ tokenContract: Name
13
+ balance: Asset
14
+ }
15
+
16
+ export interface TokenBalance {
17
+ account: Name
18
+ tokenContract: Name
19
+ balance: Asset
20
+ }
21
+
22
+ export class BalancesManager extends BaseManager {
23
+ private depositConfig?: DepositConfig | null
24
+
25
+ async getDepositConfig(reload = false): Promise<DepositConfig | null> {
26
+ if (!reload && this.depositConfig !== undefined) {
27
+ return this.depositConfig
28
+ }
29
+ const row = (await this.platform.table('depositcfg').get()) as
30
+ | PlatformContract.Types.depositcfg_row
31
+ | undefined
32
+ this.depositConfig = row
33
+ ? {tokenContract: row.token_contract, symbol: row.token_symbol}
34
+ : null
35
+ return this.depositConfig
36
+ }
37
+
38
+ private async resolveTokenContract(tokenContract?: NameType): Promise<Name | null> {
39
+ if (tokenContract) return Name.from(tokenContract)
40
+ const config = await this.getDepositConfig()
41
+ return config ? config.tokenContract : null
42
+ }
43
+
44
+ async getPlatformBalances(owner: NameType): Promise<PlatformBalance[]> {
45
+ const account = Name.from(owner)
46
+ const rows = (await this.platform
47
+ .table('balance', account)
48
+ .all()) as PlatformContract.Types.balance_row[]
49
+ return rows.map((row) => ({
50
+ owner: account,
51
+ tokenContract: row.token_contract,
52
+ balance: row.balance,
53
+ }))
54
+ }
55
+
56
+ // Null means no balance row at all: deposits abort until `open`. A zero row is a valid state.
57
+ async getPlatformBalance(
58
+ owner: NameType,
59
+ tokenContract?: NameType
60
+ ): Promise<PlatformBalance | null> {
61
+ const contract = await this.resolveTokenContract(tokenContract)
62
+ if (!contract) return null
63
+ const account = Name.from(owner)
64
+ const row = (await this.platform.table('balance', account).get(contract)) as
65
+ | PlatformContract.Types.balance_row
66
+ | undefined
67
+ if (!row) return null
68
+ return {owner: account, tokenContract: row.token_contract, balance: row.balance}
69
+ }
70
+
71
+ async getWalletBalance(
72
+ account: NameType,
73
+ tokenContract?: NameType,
74
+ symbolCode?: Asset.SymbolCodeType
75
+ ): Promise<TokenBalance | null> {
76
+ const contract = await this.resolveTokenContract(tokenContract)
77
+ if (!contract) return null
78
+ let code = symbolCode ? Asset.SymbolCode.from(symbolCode) : undefined
79
+ if (!code) {
80
+ const config = await this.getDepositConfig()
81
+ code = config?.symbol.code
82
+ }
83
+ const holder = Name.from(account)
84
+ const balances = await this.client.v1.chain.get_currency_balance(
85
+ contract,
86
+ holder,
87
+ code ? String(code) : undefined
88
+ )
89
+ const balance = balances.find((asset) => !code || asset.symbol.code.equals(code))
90
+ if (!balance) return null
91
+ return {account: holder, tokenContract: contract, balance}
92
+ }
93
+ }
@@ -15,11 +15,19 @@ export abstract class BaseManager {
15
15
  return this.context.platform
16
16
  }
17
17
 
18
+ protected get fund() {
19
+ return this.context.fund
20
+ }
21
+
22
+ protected get atomicAssetsAccount() {
23
+ return this.context.atomicAssetsAccount
24
+ }
25
+
18
26
  protected async getGame() {
19
27
  return this.context.getGame()
20
28
  }
21
29
 
22
- protected async getState() {
23
- return this.context.getState()
30
+ protected async getState(reload = false) {
31
+ return this.context.getState(reload)
24
32
  }
25
33
  }
@@ -0,0 +1,39 @@
1
+ import {describe, expect, test} from 'bun:test'
2
+ import {computeFreeCells} from './cluster'
3
+
4
+ describe('computeFreeCells', () => {
5
+ test('returns footprint cells that are not occupied', () => {
6
+ const footprint = [
7
+ {gx: 2, gy: 0},
8
+ {gx: 0, gy: 2},
9
+ {gx: 1, gy: 1},
10
+ ]
11
+ const occupied = [{gx: 2, gy: 0, entity: 7}]
12
+ expect(computeFreeCells(footprint, occupied)).toEqual([
13
+ {gx: 0, gy: 2},
14
+ {gx: 1, gy: 1},
15
+ ])
16
+ })
17
+
18
+ test('matches occupancy on signed coordinates', () => {
19
+ const footprint = [
20
+ {gx: -2, gy: 0},
21
+ {gx: 0, gy: -2},
22
+ {gx: -1, gy: 1},
23
+ ]
24
+ const occupied = [{gx: 0, gy: -2, entity: 9}]
25
+ expect(computeFreeCells(footprint, occupied)).toEqual([
26
+ {gx: -2, gy: 0},
27
+ {gx: -1, gy: 1},
28
+ ])
29
+ })
30
+
31
+ test('empty footprint yields no free cells', () => {
32
+ expect(computeFreeCells([], [])).toEqual([])
33
+ })
34
+
35
+ test('fully occupied footprint yields no free cells', () => {
36
+ const footprint = [{gx: 1, gy: 1}]
37
+ expect(computeFreeCells(footprint, [{gx: 1, gy: 1, entity: 3}])).toEqual([])
38
+ })
39
+ })
@@ -0,0 +1,53 @@
1
+ import {UInt16, type UInt16Type, UInt64, type UInt64Type} from '@wharfkit/antelope'
2
+ import {BaseManager} from './base'
3
+ import type {ServerContract} from '../contracts'
4
+
5
+ export interface GridCell {
6
+ gx: number
7
+ gy: number
8
+ }
9
+
10
+ export interface ClusterCell extends GridCell {
11
+ entity: number
12
+ }
13
+
14
+ export interface Cluster {
15
+ root: number
16
+ cells: ClusterCell[]
17
+ }
18
+
19
+ export function computeFreeCells(footprint: GridCell[], occupied: ClusterCell[]): GridCell[] {
20
+ const taken = new Set(occupied.map((c) => `${c.gx},${c.gy}`))
21
+ return footprint.filter((c) => !taken.has(`${c.gx},${c.gy}`))
22
+ }
23
+
24
+ export class ClusterManager extends BaseManager {
25
+ async getFootprint(itemId: UInt16Type): Promise<GridCell[]> {
26
+ const res = (await this.server.readonly('getfootprint', {
27
+ item_id: UInt16.from(itemId),
28
+ })) as ServerContract.Types.footprint_result
29
+ return res.cells.map((c) => ({gx: Number(c.gx), gy: Number(c.gy)}))
30
+ }
31
+
32
+ async getCluster(hubId: UInt64Type): Promise<Cluster> {
33
+ const res = (await this.server.readonly('getcluster', {
34
+ hub_id: UInt64.from(hubId),
35
+ })) as ServerContract.Types.cluster_row
36
+ return {
37
+ root: Number(res.root),
38
+ cells: res.cells.map((c) => ({
39
+ gx: Number(c.gx),
40
+ gy: Number(c.gy),
41
+ entity: Number(c.entity),
42
+ })),
43
+ }
44
+ }
45
+
46
+ async freeCells(hubId: UInt64Type, hubItemId: UInt16Type): Promise<GridCell[]> {
47
+ const [footprint, cluster] = await Promise.all([
48
+ this.getFootprint(hubItemId),
49
+ this.getCluster(hubId),
50
+ ])
51
+ return computeFreeCells(footprint, cluster.cells)
52
+ }
53
+ }
@@ -0,0 +1,80 @@
1
+ import type {Name, UInt32, UInt64} from '@wharfkit/antelope'
2
+ import type {ServerContract} from '../contracts'
3
+ import type {Item} from '../types'
4
+ import type {Recipe} from '../data/recipes-runtime'
5
+ import type {PlotProgress} from './plot'
6
+
7
+ export type BuildState = 'initializing' | 'accepting' | 'ready' | 'scheduled' | 'finalizing'
8
+
9
+ export type FinalizerCapability = 'builder'
10
+
11
+ export interface BuildableTarget {
12
+ entityId: UInt64
13
+ ownerName: Name
14
+ coordinates: ServerContract.Types.coordinates
15
+ targetItemId: number
16
+ targetItem: Item
17
+ state: BuildState
18
+ recipe: Recipe
19
+ progress: PlotProgress
20
+ finalizeAction: Name
21
+ finalizerCapability: FinalizerCapability
22
+ activeTask?: ServerContract.Types.task
23
+ scheduledBuild?: ScheduledBuild
24
+ }
25
+
26
+ export interface SourceEntityRef {
27
+ entityId: UInt64
28
+ name: string
29
+ hasLoaders: boolean
30
+ loaderCount: number
31
+ loaderTotalMass: number
32
+ relevantCargo: SourceCargoStack[]
33
+ }
34
+
35
+ export interface SourceCargoStack {
36
+ key: string
37
+ rowId: UInt64
38
+ itemId: number
39
+ item: Item
40
+ stats: UInt64
41
+ modules: ServerContract.Types.module_entry[]
42
+ available: number
43
+ plotNeeds: number
44
+ reserved: number
45
+ }
46
+
47
+ export interface FinalizerEntityRef {
48
+ entityId: UInt64
49
+ entityType: Name
50
+ name: string
51
+ capability: FinalizerCapability
52
+ builderSpeed: number
53
+ estimatedDuration: UInt32
54
+ }
55
+
56
+ export interface InboundTransfer {
57
+ sourceEntityId: UInt64
58
+ sourceEntityType: Name
59
+ sourceName: string
60
+ itemId: number
61
+ quantity: number
62
+ etaSeconds: number
63
+ }
64
+
65
+ export interface ScheduledBuild {
66
+ shipId: UInt64
67
+ shipName: string
68
+ hasStarted: boolean
69
+ startsAt: number
70
+ completesAt: number
71
+ cancelable: boolean
72
+ blockingTaskCount: number
73
+ }
74
+
75
+ export interface Reservation {
76
+ targetEntityId: UInt64
77
+ targetEntityType: Name
78
+ itemId: number
79
+ quantity: number
80
+ }