@shipload/sdk 1.0.0-next.7 → 1.0.0-next.70
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.
- package/lib/scan.d.ts +52 -0
- package/lib/scan.js +162 -0
- package/lib/scan.js.map +1 -0
- package/lib/scan.m.js +152 -0
- package/lib/scan.m.js.map +1 -0
- package/lib/shipload.d.ts +5696 -1503
- package/lib/shipload.js +20294 -5200
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +20371 -5683
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +1648 -0
- package/lib/testing.js +6980 -0
- package/lib/testing.js.map +1 -0
- package/lib/testing.m.js +6974 -0
- package/lib/testing.m.js.map +1 -0
- package/package.json +20 -2
- package/src/capabilities/craftable.test.ts +82 -0
- package/src/capabilities/craftable.ts +82 -0
- package/src/capabilities/crafting.test.ts +80 -0
- package/src/capabilities/crafting.ts +50 -8
- package/src/capabilities/gathering.test.ts +29 -0
- package/src/capabilities/gathering.ts +38 -20
- package/src/capabilities/hauling.ts +0 -5
- package/src/capabilities/index.ts +0 -1
- package/src/capabilities/modules.ts +27 -30
- package/src/capabilities/movement.ts +1 -1
- package/src/capabilities/storage.test.ts +26 -0
- package/src/capabilities/storage.ts +22 -7
- package/src/contracts/fund.ts +306 -0
- package/src/contracts/platform.ts +312 -3
- package/src/contracts/server.ts +2661 -466
- package/src/contracts/token.ts +170 -0
- package/src/contracts.ts +2 -0
- package/src/coordinates/address.ts +88 -0
- package/src/coordinates/constants.test.ts +15 -0
- package/src/coordinates/constants.ts +23 -0
- package/src/coordinates/index.ts +15 -0
- package/src/coordinates/memo.test.ts +47 -0
- package/src/coordinates/memo.ts +20 -0
- package/src/coordinates/permutation.ts +77 -0
- package/src/coordinates/regions.ts +48 -0
- package/src/coordinates/sectors.ts +115 -0
- package/src/data/capabilities.ts +49 -18
- package/src/data/capability-formulas.ts +26 -14
- package/src/data/catalog.test.ts +19 -0
- package/src/data/catalog.ts +13 -3
- package/src/data/charters.json +396 -0
- package/src/data/citizenry-adjectives.json +42 -0
- package/src/data/citizenry-nouns.json +50 -0
- package/src/data/colors.ts +14 -32
- package/src/data/entities.json +421 -15
- package/src/data/item-ids.ts +53 -13
- package/src/data/items.json +330 -77
- package/src/data/kind-registry.json +212 -0
- package/src/data/kind-registry.ts +192 -0
- package/src/data/metadata.ts +312 -51
- package/src/data/recipes-runtime.ts +6 -23
- package/src/data/recipes.json +2173 -173
- package/src/data/tiers.ts +9 -6
- package/src/derivation/build-methods.test.ts +71 -0
- package/src/derivation/build-methods.ts +50 -0
- package/src/derivation/capabilities.test.ts +348 -0
- package/src/derivation/capabilities.ts +707 -0
- package/src/derivation/capability-mappings.ts +60 -16
- package/src/derivation/crafting.test.ts +17 -0
- package/src/derivation/crafting.ts +57 -34
- package/src/derivation/index.ts +27 -2
- package/src/derivation/recipe-usage.test.ts +88 -0
- package/src/derivation/recipe-usage.ts +141 -0
- package/src/derivation/reserve-regen.ts +34 -0
- package/src/derivation/resources.ts +9 -1
- package/src/derivation/rollups.test.ts +55 -0
- package/src/derivation/rollups.ts +72 -0
- package/src/derivation/stars.test.ts +67 -0
- package/src/derivation/stars.ts +25 -0
- package/src/derivation/stat-scaling.ts +12 -0
- package/src/derivation/stats.ts +6 -6
- package/src/derivation/strata.ts +5 -3
- package/src/derivation/stratum.ts +26 -22
- package/src/derivation/tiers.ts +40 -7
- package/src/derivation/upgrades.ts +14 -0
- package/src/derivation/wormhole.ts +154 -0
- package/src/entities/entity.ts +102 -0
- package/src/entities/gamestate.ts +3 -28
- package/src/entities/makers.ts +144 -136
- package/src/entities/slot-multiplier.ts +43 -0
- package/src/entity/hydrate.test.ts +156 -0
- package/src/entity/hydrate.ts +86 -0
- package/src/errors.ts +21 -16
- package/src/format.ts +42 -9
- package/src/index-module.ts +411 -32
- package/src/influence/ballot.test.ts +103 -0
- package/src/influence/ballot.ts +98 -0
- package/src/influence/categories.ts +32 -0
- package/src/influence/charter-metadata.test.ts +136 -0
- package/src/influence/charter-metadata.ts +236 -0
- package/src/influence/charters.test.ts +112 -0
- package/src/influence/charters.ts +150 -0
- package/src/influence/citizenry.ts +38 -0
- package/src/influence/civic-shuttle.test.ts +202 -0
- package/src/influence/civic-shuttle.ts +142 -0
- package/src/influence/civic.test.ts +287 -0
- package/src/influence/civic.ts +269 -0
- package/src/influence/constants.ts +84 -0
- package/src/influence/decay.ts +20 -0
- package/src/influence/decomp.ts +95 -0
- package/src/influence/demand.ts +106 -0
- package/src/influence/duration.ts +101 -0
- package/src/influence/index.ts +118 -0
- package/src/influence/influence.test.ts +450 -0
- package/src/influence/quality.ts +25 -0
- package/src/influence/valuation.ts +154 -0
- package/src/managers/actions.ts +940 -93
- package/src/managers/balances.test.ts +161 -0
- package/src/managers/balances.ts +93 -0
- package/src/managers/base.ts +10 -2
- package/src/managers/cluster.test.ts +39 -0
- package/src/managers/cluster.ts +53 -0
- package/src/managers/construction-types.ts +80 -0
- package/src/managers/construction.ts +453 -0
- package/src/managers/context.ts +58 -1
- package/src/managers/coordinates.ts +14 -0
- package/src/managers/entities.ts +35 -63
- package/src/managers/epochs.ts +72 -1
- package/src/managers/index.ts +38 -1
- package/src/managers/influence.test.ts +56 -0
- package/src/managers/influence.ts +425 -0
- package/src/managers/jobs.test.ts +80 -0
- package/src/managers/jobs.ts +54 -0
- package/src/managers/locations.ts +25 -29
- package/src/managers/nft.test.ts +21 -0
- package/src/managers/nft.ts +110 -0
- package/src/managers/players.ts +25 -0
- package/src/managers/plot.ts +122 -0
- package/src/nft/atomicassets.abi.json +1342 -0
- package/src/nft/atomicassets.ts +237 -0
- package/src/nft/atomicdata.ts +130 -0
- package/src/nft/buildImmutableData.ts +388 -0
- package/src/nft/description.ts +222 -100
- package/src/nft/index.ts +3 -0
- package/src/planner/index.ts +296 -0
- package/src/planner/planner.test.ts +459 -0
- package/src/receipts.ts +22 -0
- package/src/resolution/describe-module.ts +43 -25
- package/src/resolution/display-name.ts +39 -11
- package/src/resolution/resolve-item.test.ts +48 -0
- package/src/resolution/resolve-item.ts +112 -58
- package/src/scan/index.ts +244 -0
- package/src/scan/scan-wasm.base64.ts +2 -0
- package/src/scheduling/accessor.ts +65 -23
- package/src/scheduling/availability.test.ts +320 -0
- package/src/scheduling/availability.ts +251 -0
- package/src/scheduling/cancel.test.ts +550 -0
- package/src/scheduling/cancel.ts +254 -0
- package/src/scheduling/cluster-stock.test.ts +31 -0
- package/src/scheduling/cluster-stock.ts +15 -0
- package/src/scheduling/energy.ts +47 -0
- package/src/scheduling/epoch.ts +1 -0
- package/src/scheduling/idle-resolve.ts +45 -0
- package/src/scheduling/jobs.test.ts +49 -0
- package/src/scheduling/jobs.ts +137 -0
- package/src/scheduling/lane-core.ts +128 -0
- package/src/scheduling/lanes.test.ts +250 -0
- package/src/scheduling/lanes.ts +227 -0
- package/src/scheduling/projection.ts +265 -149
- package/src/scheduling/schedule.test.ts +163 -0
- package/src/scheduling/schedule.ts +282 -116
- package/src/scheduling/task-cargo.test.ts +110 -0
- package/src/scheduling/task-cargo.ts +62 -0
- package/src/scheduling/task-effects.test.ts +35 -0
- package/src/scheduling/task-effects.ts +34 -0
- package/src/scheduling/unwrap.test.ts +86 -0
- package/src/scheduling/unwrap.ts +190 -0
- package/src/shipload.ts +63 -4
- package/src/subscriptions/manager.cluster.test.ts +51 -0
- package/src/subscriptions/manager.ts +245 -172
- package/src/subscriptions/mappers.ts +5 -8
- package/src/subscriptions/types.ts +28 -3
- package/src/testing/catalog-hash.ts +19 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/projection-parity.ts +167 -0
- package/src/travel/reach.test.ts +86 -0
- package/src/travel/reach.ts +34 -0
- package/src/travel/route-build.test.ts +63 -0
- package/src/travel/route-build.ts +60 -0
- package/src/travel/route-planner.ts +288 -0
- package/src/travel/route-simulator.ts +170 -0
- package/src/travel/travel.ts +190 -123
- package/src/types/capabilities.ts +37 -8
- package/src/types/entity.ts +3 -3
- package/src/types/index.ts +0 -1
- package/src/types.ts +81 -23
- package/src/utils/cargo.test.ts +14 -0
- package/src/utils/cargo.ts +2 -0
- package/src/utils/display-name.ts +70 -0
- package/src/utils/hash.ts +22 -2
- package/src/utils/system.ts +24 -5
- package/src/capabilities/loading.ts +0 -8
- package/src/entities/container.ts +0 -123
- package/src/entities/ship-deploy.ts +0 -295
- package/src/entities/ship.ts +0 -221
- package/src/entities/warehouse.ts +0 -127
- 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
|
+
}
|
package/src/managers/base.ts
CHANGED
|
@@ -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
|
+
}
|