@shipload/sdk 1.0.0-next.62 → 1.0.0-next.63
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/shipload.d.ts +1172 -29
- package/lib/shipload.js +3877 -1294
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +3781 -1298
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +391 -13
- package/lib/testing.js +1554 -114
- package/lib/testing.js.map +1 -1
- package/lib/testing.m.js +1555 -115
- package/lib/testing.m.js.map +1 -1
- package/package.json +2 -2
- package/src/contracts/fund.ts +201 -0
- package/src/contracts/platform.ts +73 -1
- package/src/contracts/server.ts +946 -26
- package/src/contracts.ts +1 -0
- package/src/data/charters.json +198 -0
- package/src/data/entities.json +36 -0
- package/src/data/item-ids.ts +2 -0
- package/src/data/items.json +12 -0
- package/src/data/kind-registry.json +20 -3
- package/src/data/kind-registry.ts +5 -0
- package/src/data/metadata.ts +14 -0
- package/src/data/recipes.json +0 -48
- package/src/derivation/capabilities.ts +14 -0
- package/src/derivation/recipe-usage.test.ts +0 -2
- package/src/format.ts +9 -0
- package/src/index-module.ts +24 -1
- package/src/influence/categories.ts +32 -0
- package/src/influence/charters.test.ts +126 -0
- package/src/influence/charters.ts +120 -0
- package/src/influence/citizenry.ts +31 -0
- package/src/influence/constants.ts +63 -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 +36 -0
- package/src/influence/index.ts +63 -0
- package/src/influence/influence.test.ts +291 -0
- package/src/influence/quality.ts +25 -0
- package/src/influence/valuation.ts +154 -0
- package/src/managers/actions.ts +135 -0
- package/src/managers/construction.ts +11 -1
- package/src/managers/context.ts +9 -0
- package/src/managers/entities.ts +11 -0
- package/src/managers/index.ts +12 -0
- package/src/managers/influence.test.ts +58 -0
- package/src/managers/influence.ts +347 -0
- package/src/nft/description.ts +7 -0
- package/src/scheduling/task-cargo.ts +1 -0
- package/src/shipload.ts +5 -0
- package/src/types.ts +23 -4
package/src/managers/index.ts
CHANGED
|
@@ -13,6 +13,18 @@ export type {GridCell, ClusterCell, Cluster} from './cluster'
|
|
|
13
13
|
export {NftManager} from './nft'
|
|
14
14
|
export type {NftConfigForItem} from './nft'
|
|
15
15
|
export {JobsManager} from './jobs'
|
|
16
|
+
export {InfluenceManager} from './influence'
|
|
17
|
+
export type {
|
|
18
|
+
CharterProgress,
|
|
19
|
+
ContributePreview,
|
|
20
|
+
ContributePreviewRow,
|
|
21
|
+
FoundedWorld,
|
|
22
|
+
InfluenceStanding,
|
|
23
|
+
PendingBallot,
|
|
24
|
+
VoteCast,
|
|
25
|
+
VoteOption,
|
|
26
|
+
VoteStandings,
|
|
27
|
+
} from './influence'
|
|
16
28
|
export {PlotManager} from './plot'
|
|
17
29
|
export type {PlotProgress, PlotProgressInputRow} from './plot'
|
|
18
30
|
export {ConstructionManager} from './construction'
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {describe, expect, it} from 'bun:test'
|
|
2
|
+
import {Name, UInt64} from '@wharfkit/antelope'
|
|
3
|
+
import {InfluenceManager} from './influence'
|
|
4
|
+
import {coordsToLocationId} from '../types'
|
|
5
|
+
|
|
6
|
+
const LOCATION = {x: 12, y: 34}
|
|
7
|
+
|
|
8
|
+
function managerWith(rowsByTable: Record<string, unknown[]>) {
|
|
9
|
+
const calls: {table: string; scope: unknown}[] = []
|
|
10
|
+
const table = (name: string, scope: unknown) => {
|
|
11
|
+
calls.push({table: name, scope})
|
|
12
|
+
return {all: async () => rowsByTable[name] ?? []}
|
|
13
|
+
}
|
|
14
|
+
const ctx = {server: {table}} as never
|
|
15
|
+
return {manager: new InfluenceManager(ctx), calls}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe('InfluenceManager scoped table reads', () => {
|
|
19
|
+
it('getVoteCasts scopes infvote by location and maps fields', async () => {
|
|
20
|
+
const {manager, calls} = managerWith({
|
|
21
|
+
infvote: [{account: Name.from('eggmaple.gm'), epoch: 5, node_id: 2, weight: '100'}],
|
|
22
|
+
})
|
|
23
|
+
const rows = await manager.getVoteCasts(LOCATION)
|
|
24
|
+
expect(calls).toHaveLength(1)
|
|
25
|
+
expect(calls[0].table).toBe('infvote')
|
|
26
|
+
expect(UInt64.from(calls[0].scope as never).equals(coordsToLocationId(LOCATION))).toBe(true)
|
|
27
|
+
expect(rows).toEqual([
|
|
28
|
+
{account: Name.from('eggmaple.gm'), epoch: 5, nodeId: 2, weight: 100n},
|
|
29
|
+
])
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('getVoteTallies scopes inftally by location and maps fields', async () => {
|
|
33
|
+
const {manager, calls} = managerWith({
|
|
34
|
+
inftally: [{node_id: 3, total: '250'}],
|
|
35
|
+
})
|
|
36
|
+
const rows = await manager.getVoteTallies(LOCATION)
|
|
37
|
+
expect(calls[0].table).toBe('inftally')
|
|
38
|
+
expect(UInt64.from(calls[0].scope as never).equals(coordsToLocationId(LOCATION))).toBe(true)
|
|
39
|
+
expect(rows).toEqual([{nodeId: 3, total: 250n}])
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('getBuiltCharters scopes charters by location and maps fields', async () => {
|
|
43
|
+
const {manager, calls} = managerWith({
|
|
44
|
+
charters: [{node_id: 1, entity_id: '9001'}],
|
|
45
|
+
})
|
|
46
|
+
const rows = await manager.getBuiltCharters(LOCATION)
|
|
47
|
+
expect(calls[0].table).toBe('charters')
|
|
48
|
+
expect(UInt64.from(calls[0].scope as never).equals(coordsToLocationId(LOCATION))).toBe(true)
|
|
49
|
+
expect(rows).toEqual([{nodeId: 1, entityId: 9001n}])
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('returns an empty array when the scope has no rows', async () => {
|
|
53
|
+
const {manager} = managerWith({})
|
|
54
|
+
expect(await manager.getVoteCasts(LOCATION)).toEqual([])
|
|
55
|
+
expect(await manager.getVoteTallies(LOCATION)).toEqual([])
|
|
56
|
+
expect(await manager.getBuiltCharters(LOCATION)).toEqual([])
|
|
57
|
+
})
|
|
58
|
+
})
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import {Int64, Name, type NameType, UInt64} from '@wharfkit/antelope'
|
|
2
|
+
import {BaseManager} from './base'
|
|
3
|
+
import type {ServerContract} from '../contracts'
|
|
4
|
+
import {coordsToLocationId, locationIdToCoords, type CoordinatesType} from '../types'
|
|
5
|
+
import {
|
|
6
|
+
type BuiltCharter,
|
|
7
|
+
citizenryName,
|
|
8
|
+
contributeDuration,
|
|
9
|
+
decayActive,
|
|
10
|
+
deriveDemand,
|
|
11
|
+
pricingFromWeights,
|
|
12
|
+
valueCargoItem,
|
|
13
|
+
type DemandTriple,
|
|
14
|
+
type DemandView,
|
|
15
|
+
type ValuedItem,
|
|
16
|
+
} from '../influence'
|
|
17
|
+
import {getItem} from '../data/catalog'
|
|
18
|
+
|
|
19
|
+
export interface InfluenceStanding {
|
|
20
|
+
epoch: number
|
|
21
|
+
playerLifetime: bigint
|
|
22
|
+
playerActive: bigint
|
|
23
|
+
standingLifetime: bigint
|
|
24
|
+
standingActive: bigint
|
|
25
|
+
locationLifetime: bigint
|
|
26
|
+
locationActive: bigint
|
|
27
|
+
watermark: bigint
|
|
28
|
+
mandate: number
|
|
29
|
+
founder: Name
|
|
30
|
+
founded: number
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface CharterProgress {
|
|
34
|
+
locationId: bigint
|
|
35
|
+
lifetime: bigint
|
|
36
|
+
watermark: bigint
|
|
37
|
+
surplus: bigint
|
|
38
|
+
mandate: number
|
|
39
|
+
nextCost: bigint
|
|
40
|
+
prereqsMet: boolean
|
|
41
|
+
buildable: boolean
|
|
42
|
+
epoch: number
|
|
43
|
+
built: {nodeId: number; completedEpoch: number; entityId: bigint}[]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface ContributePreviewRow {
|
|
47
|
+
itemId: number
|
|
48
|
+
quantity: number
|
|
49
|
+
stats: bigint
|
|
50
|
+
valueAtomic: bigint
|
|
51
|
+
massKg: number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ContributePreview {
|
|
55
|
+
rows: ContributePreviewRow[]
|
|
56
|
+
totalAtomic: bigint
|
|
57
|
+
totalMassKg: number
|
|
58
|
+
durationSeconds: number
|
|
59
|
+
demand: DemandView
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface FoundedWorld {
|
|
63
|
+
locationId: bigint
|
|
64
|
+
x: number
|
|
65
|
+
y: number
|
|
66
|
+
lifetime: bigint
|
|
67
|
+
active: bigint
|
|
68
|
+
watermark: bigint
|
|
69
|
+
chosen: number
|
|
70
|
+
chosenEpoch: number
|
|
71
|
+
mandate: number | undefined
|
|
72
|
+
founder: Name
|
|
73
|
+
founded: number
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface VoteOption {
|
|
77
|
+
nodeId: number
|
|
78
|
+
cost: bigint
|
|
79
|
+
eligible: boolean
|
|
80
|
+
total: bigint | undefined
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface VoteStandings {
|
|
84
|
+
locationId: bigint
|
|
85
|
+
epoch: number
|
|
86
|
+
chosen: number
|
|
87
|
+
chosenEpoch: number
|
|
88
|
+
mandate: number
|
|
89
|
+
ballotEpoch: number | undefined
|
|
90
|
+
talliesSuppressed: boolean
|
|
91
|
+
options: VoteOption[]
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface VoteCast {
|
|
95
|
+
account: Name
|
|
96
|
+
epoch: number
|
|
97
|
+
nodeId: number
|
|
98
|
+
weight: bigint
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface PendingBallot {
|
|
102
|
+
locationId: bigint
|
|
103
|
+
x: number
|
|
104
|
+
y: number
|
|
105
|
+
epoch: number
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function big(value: unknown): bigint {
|
|
109
|
+
return BigInt(String(value))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export class InfluenceManager extends BaseManager {
|
|
113
|
+
async getStanding(owner: NameType, location: CoordinatesType): Promise<InfluenceStanding> {
|
|
114
|
+
const result = (await this.server.readonly('getinfluence', {
|
|
115
|
+
owner: Name.from(owner),
|
|
116
|
+
x: Int64.from(location.x),
|
|
117
|
+
y: Int64.from(location.y),
|
|
118
|
+
})) as ServerContract.Types.influence_totals
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
epoch: Number(result.epoch),
|
|
122
|
+
playerLifetime: big(result.player_lifetime),
|
|
123
|
+
playerActive: big(result.player_active),
|
|
124
|
+
standingLifetime: big(result.standing_lifetime),
|
|
125
|
+
standingActive: big(result.standing_active),
|
|
126
|
+
locationLifetime: big(result.location_lifetime),
|
|
127
|
+
locationActive: big(result.location_active),
|
|
128
|
+
watermark: big(result.watermark),
|
|
129
|
+
mandate: Number(result.mandate),
|
|
130
|
+
founder: Name.from(result.founder),
|
|
131
|
+
founded: Number(result.founded),
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async getDemandConfig(): Promise<DemandTriple> {
|
|
136
|
+
const row = (await this.server.table('infdemand').get()) as
|
|
137
|
+
| ServerContract.Types.infdemand_row
|
|
138
|
+
| undefined
|
|
139
|
+
if (!row) throw new Error('influence demand config is unset')
|
|
140
|
+
return {peak: big(row.peak), base: big(row.base), floor: big(row.floor)}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async getQualityDivisor(): Promise<number> {
|
|
144
|
+
const row = (await this.server.table('infquality').get()) as
|
|
145
|
+
| ServerContract.Types.infquality_row
|
|
146
|
+
| undefined
|
|
147
|
+
if (!row) throw new Error('influence quality config is unset')
|
|
148
|
+
return Number(row.d1)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async getWeights(): Promise<ServerContract.Types.infweight_row[]> {
|
|
152
|
+
return (await this.server.table('infweight').all()) as ServerContract.Types.infweight_row[]
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async getDemand(location: CoordinatesType): Promise<DemandView> {
|
|
156
|
+
const game = await this.getGame()
|
|
157
|
+
const state = await this.getState()
|
|
158
|
+
const triple = await this.getDemandConfig()
|
|
159
|
+
return deriveDemand({
|
|
160
|
+
gameSeed: game.config.seed,
|
|
161
|
+
epochSeed: state.epochSeed,
|
|
162
|
+
coordinates: location,
|
|
163
|
+
triple,
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async getCitizenryName(location: CoordinatesType): Promise<string | undefined> {
|
|
168
|
+
const game = await this.getGame()
|
|
169
|
+
return citizenryName(game.config.seed, location)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async previewContribution(
|
|
173
|
+
location: CoordinatesType,
|
|
174
|
+
bundle: ValuedItem[],
|
|
175
|
+
opts: {altitudeZ?: number} = {}
|
|
176
|
+
): Promise<ContributePreview> {
|
|
177
|
+
const [demand, d1, weights] = await Promise.all([
|
|
178
|
+
this.getDemand(location),
|
|
179
|
+
this.getQualityDivisor(),
|
|
180
|
+
this.getWeights(),
|
|
181
|
+
])
|
|
182
|
+
const pricing = pricingFromWeights(
|
|
183
|
+
d1,
|
|
184
|
+
weights.map((w) => ({
|
|
185
|
+
category: Number(w.category),
|
|
186
|
+
tier: Number(w.tier),
|
|
187
|
+
weightFp: big(w.weight_fp),
|
|
188
|
+
}))
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
let totalAtomic = 0n
|
|
192
|
+
let totalMassKg = 0
|
|
193
|
+
const rows = bundle.map((item) => {
|
|
194
|
+
const valueAtomic = valueCargoItem(item, demand, pricing)
|
|
195
|
+
const massKg = getItem(item.itemId).mass * item.quantity
|
|
196
|
+
totalAtomic += valueAtomic
|
|
197
|
+
totalMassKg += massKg
|
|
198
|
+
return {...item, valueAtomic, massKg}
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
rows,
|
|
203
|
+
totalAtomic,
|
|
204
|
+
totalMassKg,
|
|
205
|
+
durationSeconds: contributeDuration(totalMassKg, opts.altitudeZ ?? 0),
|
|
206
|
+
demand,
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async getCharter(location: CoordinatesType): Promise<CharterProgress> {
|
|
211
|
+
const result = (await this.server.readonly('getcharter', {
|
|
212
|
+
x: Int64.from(location.x),
|
|
213
|
+
y: Int64.from(location.y),
|
|
214
|
+
})) as ServerContract.Types.charter_result
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
locationId: big(result.location_id),
|
|
218
|
+
lifetime: big(result.lifetime),
|
|
219
|
+
watermark: big(result.watermark),
|
|
220
|
+
surplus: big(result.surplus),
|
|
221
|
+
mandate: Number(result.mandate),
|
|
222
|
+
nextCost: big(result.next_cost),
|
|
223
|
+
prereqsMet: Boolean(result.prereqs_met),
|
|
224
|
+
buildable: Boolean(result.buildable),
|
|
225
|
+
epoch: Number(result.epoch),
|
|
226
|
+
built: result.built.map((b) => ({
|
|
227
|
+
nodeId: Number(b.node_id),
|
|
228
|
+
completedEpoch: Number(b.completed_epoch),
|
|
229
|
+
entityId: big(b.entity_id),
|
|
230
|
+
})),
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async getPools(): Promise<ServerContract.Types.pool_view[]> {
|
|
235
|
+
const result = (await this.server.readonly('getpools')) as ServerContract.Types.pools_result
|
|
236
|
+
return result.pools
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async getPool(category: number, tier: number): Promise<ServerContract.Types.pool_pair_result> {
|
|
240
|
+
return (await this.server.readonly('getpool', {
|
|
241
|
+
category,
|
|
242
|
+
tier,
|
|
243
|
+
})) as ServerContract.Types.pool_pair_result
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async getMintConfig(): Promise<ServerContract.Types.mintcfg_result> {
|
|
247
|
+
return (await this.server.readonly('getmintcfg')) as ServerContract.Types.mintcfg_result
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async getVotes(location: CoordinatesType): Promise<VoteStandings> {
|
|
251
|
+
const result = (await this.server.readonly('getvotes', {
|
|
252
|
+
x: Int64.from(location.x),
|
|
253
|
+
y: Int64.from(location.y),
|
|
254
|
+
})) as ServerContract.Types.vote_result
|
|
255
|
+
|
|
256
|
+
const epoch = Number(result.epoch)
|
|
257
|
+
const rawBallotEpoch = Number(result.ballot_epoch)
|
|
258
|
+
const ballotEpoch = rawBallotEpoch === 0 ? undefined : rawBallotEpoch
|
|
259
|
+
const talliesSuppressed = ballotEpoch !== undefined && ballotEpoch < epoch
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
locationId: big(result.location_id),
|
|
263
|
+
epoch,
|
|
264
|
+
chosen: Number(result.chosen),
|
|
265
|
+
chosenEpoch: Number(result.chosen_epoch),
|
|
266
|
+
mandate: Number(result.effective),
|
|
267
|
+
ballotEpoch,
|
|
268
|
+
talliesSuppressed,
|
|
269
|
+
options: result.options.map((option) => ({
|
|
270
|
+
nodeId: Number(option.node_id),
|
|
271
|
+
cost: big(option.cost),
|
|
272
|
+
eligible: Boolean(option.eligible),
|
|
273
|
+
total: talliesSuppressed ? undefined : big(option.total),
|
|
274
|
+
})),
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async getVoteCasts(location: CoordinatesType): Promise<VoteCast[]> {
|
|
279
|
+
const rows = (await this.server
|
|
280
|
+
.table('infvote', coordsToLocationId(location))
|
|
281
|
+
.all()) as ServerContract.Types.infvote_row[]
|
|
282
|
+
return rows.map((row) => ({
|
|
283
|
+
account: Name.from(row.account),
|
|
284
|
+
epoch: Number(row.epoch),
|
|
285
|
+
nodeId: Number(row.node_id),
|
|
286
|
+
weight: big(row.weight),
|
|
287
|
+
}))
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
async getVoteTallies(location: CoordinatesType): Promise<{nodeId: number; total: bigint}[]> {
|
|
291
|
+
const rows = (await this.server
|
|
292
|
+
.table('inftally', coordsToLocationId(location))
|
|
293
|
+
.all()) as ServerContract.Types.inftally_row[]
|
|
294
|
+
return rows.map((row) => ({nodeId: Number(row.node_id), total: big(row.total)}))
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async getBuiltCharters(location: CoordinatesType): Promise<BuiltCharter[]> {
|
|
298
|
+
const rows = (await this.server
|
|
299
|
+
.table('charters', coordsToLocationId(location))
|
|
300
|
+
.all()) as ServerContract.Types.charters_row[]
|
|
301
|
+
return rows.map((row) => ({nodeId: Number(row.node_id), entityId: big(row.entity_id)}))
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
async getBallotQueue(): Promise<PendingBallot[]> {
|
|
305
|
+
const rows = (await this.server
|
|
306
|
+
.table('infballot')
|
|
307
|
+
.all()) as ServerContract.Types.infballot_row[]
|
|
308
|
+
return rows.map((row) => ({
|
|
309
|
+
locationId: big(row.location_id),
|
|
310
|
+
...locationIdToCoords(row.location_id),
|
|
311
|
+
epoch: Number(row.epoch),
|
|
312
|
+
}))
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async getFoundedWorlds(opts: {withMandate?: boolean} = {}): Promise<FoundedWorld[]> {
|
|
316
|
+
const rows = (await this.server.table('infloc').all()) as ServerContract.Types.infloc_row[]
|
|
317
|
+
const epoch = (await this.getState()).epoch
|
|
318
|
+
const worlds = rows.map((row) => ({
|
|
319
|
+
locationId: big(row.location_id),
|
|
320
|
+
...locationIdToCoords(row.location_id),
|
|
321
|
+
lifetime: big(row.lifetime),
|
|
322
|
+
active: decayActive(
|
|
323
|
+
big(row.active),
|
|
324
|
+
Math.max(0, Number(epoch) - Number(row.last_update_epoch))
|
|
325
|
+
),
|
|
326
|
+
watermark: big(row.watermark),
|
|
327
|
+
chosen: Number(row.chosen),
|
|
328
|
+
chosenEpoch: Number(row.chosen_epoch),
|
|
329
|
+
mandate: undefined as number | undefined,
|
|
330
|
+
founder: Name.from(row.founder),
|
|
331
|
+
founded: Number(row.founded),
|
|
332
|
+
}))
|
|
333
|
+
|
|
334
|
+
if (!opts.withMandate) return worlds
|
|
335
|
+
|
|
336
|
+
for (const world of worlds) {
|
|
337
|
+
world.mandate = (await this.getCharter({x: world.x, y: world.y})).mandate
|
|
338
|
+
}
|
|
339
|
+
return worlds
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async isFounded(location: CoordinatesType): Promise<boolean> {
|
|
343
|
+
const id = coordsToLocationId(location)
|
|
344
|
+
const row = await this.server.table('infloc').get(UInt64.from(id))
|
|
345
|
+
return row !== undefined
|
|
346
|
+
}
|
|
347
|
+
}
|
package/src/nft/description.ts
CHANGED
|
@@ -85,6 +85,11 @@ export function computeBaseCapacityWorkshop(stats: bigint): number {
|
|
|
85
85
|
return Math.floor(5_000_000 * 6 ** (s / 1998))
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
export function computeBaseCapacityDepot(stats: bigint): number {
|
|
89
|
+
const s = decodeStat(stats, 0) + decodeStat(stats, 2)
|
|
90
|
+
return Math.floor(50_000_000 * 6 ** (s / 1998))
|
|
91
|
+
}
|
|
92
|
+
|
|
88
93
|
const CAPACITY_FN_BY_KIND: Record<string, (stats: bigint) => number> = {
|
|
89
94
|
ship: computeBaseCapacityShip,
|
|
90
95
|
warehouse: computeBaseCapacityWarehouse,
|
|
@@ -95,6 +100,8 @@ const CAPACITY_FN_BY_KIND: Record<string, (stats: bigint) => number> = {
|
|
|
95
100
|
mdriver: computeBaseCapacityContainer,
|
|
96
101
|
mcatcher: computeBaseCapacityContainer,
|
|
97
102
|
container: computeBaseCapacityContainer,
|
|
103
|
+
nexus: computeBaseCapacityContainer,
|
|
104
|
+
depot: computeBaseCapacityDepot,
|
|
98
105
|
}
|
|
99
106
|
|
|
100
107
|
export function computeBaseCapacityForEntity(itemId: number, stats: bigint): number {
|
|
@@ -34,6 +34,7 @@ export function taskCargoChanges(task: ServerContract.Types.task): TaskCargoChan
|
|
|
34
34
|
case TaskType.GATHER:
|
|
35
35
|
return task.couplings.length > 0 ? [] : items.map((i) => toChange(i, 'in'))
|
|
36
36
|
case TaskType.UNLOAD:
|
|
37
|
+
case TaskType.CONTRIBUTE:
|
|
37
38
|
return items.map((i) => toChange(i, 'out'))
|
|
38
39
|
case TaskType.CRAFT:
|
|
39
40
|
return [
|
package/src/shipload.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type {ActionsManager} from './managers/actions'
|
|
|
13
13
|
import type {ClusterManager} from './managers/cluster'
|
|
14
14
|
import type {NftManager} from './managers/nft'
|
|
15
15
|
import type {JobsManager} from './managers/jobs'
|
|
16
|
+
import type {InfluenceManager} from './managers/influence'
|
|
16
17
|
import type {SubscriptionsManager} from './subscriptions/manager'
|
|
17
18
|
import type {GameState} from './entities/gamestate'
|
|
18
19
|
|
|
@@ -137,6 +138,10 @@ export class Shipload {
|
|
|
137
138
|
return this._context.jobs
|
|
138
139
|
}
|
|
139
140
|
|
|
141
|
+
get influence(): InfluenceManager {
|
|
142
|
+
return this._context.influence
|
|
143
|
+
}
|
|
144
|
+
|
|
140
145
|
get subscriptions(): SubscriptionsManager {
|
|
141
146
|
return this._context.subscriptions
|
|
142
147
|
}
|
package/src/types.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type UInt64Type,
|
|
9
9
|
} from '@wharfkit/antelope'
|
|
10
10
|
import {ServerContract} from './contracts'
|
|
11
|
+
import {COORD_MAX, COORD_MIN} from './coordinates/constants'
|
|
11
12
|
|
|
12
13
|
export const PRECISION = 10000
|
|
13
14
|
export const CRAFT_ENERGY_DIVISOR = 150000
|
|
@@ -70,6 +71,7 @@ export enum TaskType {
|
|
|
70
71
|
UPGRADE = 17,
|
|
71
72
|
SHUTTLE = 18,
|
|
72
73
|
REFIT = 19,
|
|
74
|
+
CONTRIBUTE = 20,
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
export enum RefitOp {
|
|
@@ -124,13 +126,30 @@ export class Coordinates extends ServerContract.Types.coordinates {
|
|
|
124
126
|
|
|
125
127
|
export function coordsToLocationId(coords: CoordinatesType): UInt64 {
|
|
126
128
|
const c = Coordinates.from(coords)
|
|
127
|
-
const
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
const x = BigInt(c.x.toString())
|
|
130
|
+
const y = BigInt(c.y.toString())
|
|
131
|
+
if (
|
|
132
|
+
x < BigInt(COORD_MIN) ||
|
|
133
|
+
x > BigInt(COORD_MAX) ||
|
|
134
|
+
y < BigInt(COORD_MIN) ||
|
|
135
|
+
y > BigInt(COORD_MAX)
|
|
136
|
+
) {
|
|
137
|
+
throw new Error('coordinate out of int32 bounds')
|
|
138
|
+
}
|
|
139
|
+
const offset = BigInt(2147483648)
|
|
140
|
+
const id = ((x + offset) << BigInt(32)) | (y + offset)
|
|
131
141
|
return UInt64.from(id)
|
|
132
142
|
}
|
|
133
143
|
|
|
144
|
+
export function locationIdToCoords(id: UInt64Type): {x: number; y: number} {
|
|
145
|
+
const value = BigInt(UInt64.from(id).toString())
|
|
146
|
+
const offset = BigInt(2147483648)
|
|
147
|
+
return {
|
|
148
|
+
x: Number((value >> BigInt(32)) - offset),
|
|
149
|
+
y: Number((value & BigInt('0xffffffff')) - offset),
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
134
153
|
export interface Distance {
|
|
135
154
|
origin: ServerContract.ActionParams.Type.coordinates
|
|
136
155
|
destination: ServerContract.ActionParams.Type.coordinates
|