@shipload/sdk 1.0.0-next.19 → 1.0.0-next.20

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.
@@ -1,4 +1,4 @@
1
- import {Checksum256, Int64, type UInt64} from '@wharfkit/antelope'
1
+ import {Checksum256, Int64, UInt64} from '@wharfkit/antelope'
2
2
  import {type PlatformContract, ServerContract} from '../contracts'
3
3
  import {type EpochInfo, getCurrentEpoch, getEpochInfo} from '../scheduling/epoch'
4
4
  import {hasSystem} from '../utils/system'
@@ -34,7 +34,7 @@ export class GameState extends ServerContract.Types.state_row {
34
34
  * Get the current epoch number from the state
35
35
  */
36
36
  get currentEpoch(): UInt64 {
37
- return this.epoch
37
+ return UInt64.from(this.epoch.toString())
38
38
  }
39
39
 
40
40
  /**
@@ -58,20 +58,6 @@ export class GameState extends ServerContract.Types.state_row {
58
58
  return this.enabled
59
59
  }
60
60
 
61
- /**
62
- * Get the current salt value (used for random number generation)
63
- */
64
- get currentSalt(): UInt64 {
65
- return this.salt
66
- }
67
-
68
- /**
69
- * Get the commit hash for the next epoch
70
- */
71
- get nextEpochCommit(): Checksum256 {
72
- return this.commit
73
- }
74
-
75
61
  /**
76
62
  * Calculate the current epoch from game config (if game is set)
77
63
  * This might differ from state.epoch if the blockchain hasn't advanced yet
@@ -90,7 +76,7 @@ export class GameState extends ServerContract.Types.state_row {
90
76
  if (!this._game) {
91
77
  return undefined
92
78
  }
93
- return getEpochInfo(this._game, this.epoch)
79
+ return getEpochInfo(this._game, this.currentEpoch)
94
80
  }
95
81
 
96
82
  /**
@@ -131,13 +117,11 @@ export class GameState extends ServerContract.Types.state_row {
131
117
  enabled: boolean
132
118
  epoch: string
133
119
  hasSeed: boolean
134
- hasCommit: boolean
135
120
  } {
136
121
  return {
137
122
  enabled: this.enabled,
138
123
  epoch: this.epoch.toString(),
139
124
  hasSeed: !this.seed.equals(Checksum256.from('0'.repeat(64))),
140
- hasCommit: !this.commit.equals(Checksum256.from('0'.repeat(64))),
141
125
  }
142
126
  }
143
127
  }
@@ -10,7 +10,7 @@ import {itemMetadata} from '../data/metadata'
10
10
  import {getItem} from '../data/catalog'
11
11
  import {getModuleCapabilityType, moduleAccepts, moduleSlotTypeToCode} from '../capabilities/modules'
12
12
  import {computeEntityCapabilities} from '../derivation/capabilities'
13
- import type {InstalledModule} from './slot-multiplier'
13
+ import {packedModulesToInstalled} from './slot-multiplier'
14
14
 
15
15
  export interface PackedModuleInput {
16
16
  itemId: number
@@ -69,19 +69,6 @@ function assignModulesToSlots(
69
69
  )
70
70
  }
71
71
 
72
- function toInstalledModules(entries: ServerContract.Types.module_entry[]): InstalledModule[] {
73
- const installed: InstalledModule[] = []
74
- entries.forEach((entry, slotIndex) => {
75
- if (!entry.installed) return
76
- installed.push({
77
- slotIndex,
78
- itemId: Number(entry.installed.item_id.value),
79
- stats: BigInt(entry.installed.stats.toString()),
80
- })
81
- })
82
- return installed
83
- }
84
-
85
72
  const ZERO_HULL_STATS: Record<string, number> = {
86
73
  density: 0,
87
74
  strength: 0,
@@ -126,7 +113,7 @@ export function makeEntity(packedItemId: number, state: EntityStateInput): Entit
126
113
  const moduleEntries = assignModulesToSlots(layout, mods, entityLabel)
127
114
  info.modules = moduleEntries
128
115
 
129
- const installed = toInstalledModules(moduleEntries)
116
+ const installed = packedModulesToInstalled(moduleEntries)
130
117
  const caps = computeEntityCapabilities(ZERO_HULL_STATS, packedItemId, installed, layout)
131
118
 
132
119
  if (state.hullmass !== undefined) {
@@ -1,4 +1,5 @@
1
1
  import type {EntitySlot} from '../data/recipes-runtime'
2
+ import type {ServerContract} from '../contracts'
2
3
 
3
4
  export const U16_MAX = 65535
4
5
 
@@ -8,6 +9,21 @@ export interface InstalledModule {
8
9
  stats: bigint
9
10
  }
10
11
 
12
+ export function packedModulesToInstalled(
13
+ entries: ServerContract.Types.module_entry[]
14
+ ): InstalledModule[] {
15
+ const installed: InstalledModule[] = []
16
+ entries.forEach((entry, slotIndex) => {
17
+ if (!entry.installed) return
18
+ installed.push({
19
+ slotIndex,
20
+ itemId: Number(entry.installed.item_id.value),
21
+ stats: BigInt(entry.installed.stats.toString()),
22
+ })
23
+ })
24
+ return installed
25
+ }
26
+
11
27
  export function clampUint16(value: number): number {
12
28
  return Math.min(value, U16_MAX)
13
29
  }
package/src/errors.ts CHANGED
@@ -16,8 +16,6 @@ export const REQUIRES_POSITIVE_VALUE = 'Value must be greater than zero.'
16
16
  export const PLAYER_ALREADY_JOINED = 'Player has already joined the game.'
17
17
  export const PLAYER_NOT_JOINED = 'Player has not joined the game.'
18
18
  export const PLAYER_NOT_FOUND = 'Cannot find player for given account name.'
19
- export const STARTER_ALREADY_CLAIMED =
20
- 'Starter ship already claimed; destroy existing ships to re-claim.'
21
19
  export const ENTITY_ALREADY_THERE = 'Entity cannot travel to the location it is already at.'
22
20
  export const SHIP_ALREADY_TRAVELING = 'Ship is already traveling.'
23
21
  export const SHIP_CANNOT_BUY_TRAVELING = 'Ship cannot buy goods while traveling.'
@@ -228,6 +228,7 @@ export {
228
228
  isFactory,
229
229
  isContainer,
230
230
  isNexus,
231
+ isPlot,
231
232
  } from './data/kind-registry'
232
233
  export type {EntityTypeName, KindMeta, TemplateMeta} from './data/kind-registry'
233
234
  export * from './capabilities'
@@ -422,7 +423,7 @@ export {
422
423
 
423
424
  export {formatMass, formatMassDelta, formatMassScaled, formatLocation} from './format'
424
425
 
425
- export {displayName, describeItem} from './resolution/display-name'
426
+ export {displayName, baseName, describeItem} from './resolution/display-name'
426
427
  export type {DescribeOptions} from './resolution/display-name'
427
428
 
428
429
  export * from './subscriptions'
@@ -1,8 +1,12 @@
1
1
  import {
2
- type Action,
2
+ Action,
3
+ Checksum256,
4
+ type Checksum256Type,
3
5
  Int64,
4
6
  Name,
5
7
  type NameType,
8
+ UInt8,
9
+ type UInt8Type,
6
10
  UInt16,
7
11
  type UInt16Type,
8
12
  UInt32,
@@ -13,12 +17,6 @@ import {
13
17
  import {BaseManager} from './base'
14
18
  import type {CoordinatesType} from '../types'
15
19
  import {ServerContract} from '../contracts'
16
- import {
17
- buildImmutableData,
18
- type ImmutableModuleSlot,
19
- moduleSlotsForImmutable,
20
- } from '../nft/buildImmutableData'
21
- import {buildMintAssetAction, SHIPLOAD_COLLECTION} from '../nft/atomicassets'
22
20
 
23
21
  export type EntityRefInput = {
24
22
  entityType: NameType
@@ -169,7 +167,7 @@ export class ActionsManager extends BaseManager {
169
167
  coords: ServerContract.ActionParams.Type.coordinates
170
168
  ): Action {
171
169
  return this.server.action('claimplot', {
172
- id: UInt64.from(entityId),
170
+ builder_id: UInt64.from(entityId),
173
171
  target_item_id: UInt16.from(targetItemId),
174
172
  coords,
175
173
  })
@@ -177,7 +175,7 @@ export class ActionsManager extends BaseManager {
177
175
 
178
176
  buildplot(entityId: UInt64Type, plotId: UInt64Type): Action {
179
177
  return this.server.action('buildplot', {
180
- id: UInt64.from(entityId),
178
+ builder_id: UInt64.from(entityId),
181
179
  plot_id: UInt64.from(plotId),
182
180
  })
183
181
  }
@@ -208,37 +206,6 @@ export class ActionsManager extends BaseManager {
208
206
  })
209
207
  }
210
208
 
211
- private async buildPairedMintAction(args: {
212
- owner: NameType
213
- itemId: number
214
- quantity: number
215
- stats: bigint
216
- originX: number
217
- originY: number
218
- moduleSlots: ImmutableModuleSlot[]
219
- }): Promise<Action> {
220
- const nftCfg = await this.context.nft.getNftConfigForItem(args.itemId)
221
- if (!nftCfg) {
222
- throw new Error(`item ${args.itemId} has no nftconfig`)
223
- }
224
- const immutableData = buildImmutableData(
225
- args.itemId,
226
- args.quantity,
227
- args.stats,
228
- args.originX,
229
- args.originY,
230
- args.moduleSlots
231
- )
232
- return buildMintAssetAction({
233
- authorizedMinter: Name.from(args.owner),
234
- collectionName: SHIPLOAD_COLLECTION,
235
- schemaName: nftCfg.schemaName,
236
- templateId: nftCfg.templateId,
237
- newAssetOwner: Name.from(args.owner),
238
- immutableData,
239
- })
240
- }
241
-
242
209
  async wrap(
243
210
  owner: NameType,
244
211
  entityId: UInt64Type,
@@ -246,42 +213,15 @@ export class ActionsManager extends BaseManager {
246
213
  cargoId: UInt64Type,
247
214
  quantity: UInt64Type
248
215
  ): Promise<Action[]> {
249
- const cargoIdKey = UInt64.from(cargoId)
250
- const entityIdKey = UInt64.from(entityId)
251
- const [cargoRow, entityRow] = (await Promise.all([
252
- this.server.table('cargo').get(cargoIdKey),
253
- this.server.table('entity').get(entityIdKey),
254
- ])) as [
255
- ServerContract.Types.cargo_row | undefined,
256
- ServerContract.Types.entity_row | undefined,
257
- ]
258
- if (!cargoRow) {
259
- throw new Error(`cargo row ${cargoIdKey} not found`)
260
- }
261
- if (!entityRow) {
262
- throw new Error(`entity ${entityIdKey} not found`)
263
- }
264
-
265
- const quantityValue = UInt64.from(quantity)
266
- const mintAction = await this.buildPairedMintAction({
267
- owner,
268
- itemId: Number(cargoRow.item_id.toString()),
269
- quantity: Number(quantityValue.toString()),
270
- stats: BigInt(cargoRow.stats.toString()),
271
- originX: Number(entityRow.coordinates.x.toString()),
272
- originY: Number(entityRow.coordinates.y.toString()),
273
- moduleSlots: moduleSlotsForImmutable(cargoRow.modules),
274
- })
275
-
276
216
  return [
277
- this.server.action('wrap', {
217
+ this.platform.action('wrapcargo', {
218
+ game: this.server.account,
278
219
  owner: Name.from(owner),
279
220
  entity_id: UInt64.from(entityId),
280
221
  nexus_id: UInt64.from(nexusId),
281
- cargo_id: cargoIdKey,
282
- quantity: quantityValue,
222
+ cargo_id: UInt64.from(cargoId),
223
+ quantity: UInt64.from(quantity),
283
224
  }),
284
- mintAction,
285
225
  ]
286
226
  }
287
227
 
@@ -297,49 +237,66 @@ export class ActionsManager extends BaseManager {
297
237
  entityId: UInt64Type,
298
238
  nexusId: UInt64Type
299
239
  ): Promise<Action[]> {
300
- const entityIdKey = UInt64.from(entityId)
301
- const entityRow = (await this.server.table('entity').get(entityIdKey)) as
302
- | ServerContract.Types.entity_row
303
- | undefined
304
- if (!entityRow) {
305
- throw new Error(`entity ${entityIdKey} not found`)
306
- }
307
-
308
- const mintAction = await this.buildPairedMintAction({
309
- owner,
310
- itemId: Number(entityRow.item_id.toString()),
311
- quantity: 1,
312
- stats: BigInt(entityRow.stats.toString()),
313
- originX: Number(entityRow.coordinates.x.toString()),
314
- originY: Number(entityRow.coordinates.y.toString()),
315
- moduleSlots: moduleSlotsForImmutable(entityRow.modules),
316
- })
317
-
318
240
  return [
319
- this.server.action('wrapentity', {
320
- entity_id: entityIdKey,
241
+ this.platform.action('wrapentity', {
242
+ game: this.server.account,
243
+ owner: Name.from(owner),
244
+ entity_id: UInt64.from(entityId),
321
245
  nexus_id: UInt64.from(nexusId),
322
246
  }),
323
- mintAction,
324
247
  ]
325
248
  }
326
249
 
327
- deploynft(owner: NameType, assetId: UInt64Type, targetNexusId: UInt64Type): Action {
328
- const params: ServerContract.ActionParams.deploynft = {
250
+ placecargo(owner: NameType, hostId: UInt64Type, assetId: UInt64Type): Action {
251
+ return this.server.action('placecargo', {
329
252
  owner: Name.from(owner),
253
+ host_id: UInt64.from(hostId),
330
254
  asset_id: UInt64.from(assetId),
331
- target_nexus_id: UInt64.from(targetNexusId),
332
- }
333
- return this.server.action('deploynft', params)
255
+ })
334
256
  }
335
257
 
336
- unwrapnft(owner: NameType, assetId: UInt64Type, hostId: UInt64Type): Action {
337
- const params: ServerContract.ActionParams.unwrapnft = {
258
+ placeentity(owner: NameType, assetId: UInt64Type, targetNexusId: UInt64Type): Action {
259
+ return this.server.action('placeentity', {
338
260
  owner: Name.from(owner),
339
261
  asset_id: UInt64.from(assetId),
340
- host_id: UInt64.from(hostId),
341
- }
342
- return this.server.action('unwrapnft', params)
262
+ target_nexus_id: UInt64.from(targetNexusId),
263
+ })
264
+ }
265
+
266
+ transferForUnwrap(owner: NameType, assetId: UInt64Type): Action {
267
+ return Action.from({
268
+ account: 'atomicassets',
269
+ name: 'transfer',
270
+ authorization: [{actor: Name.from(owner), permission: 'active'}],
271
+ data: {
272
+ from: Name.from(owner),
273
+ to: this.platform.account,
274
+ asset_ids: [UInt64.from(assetId)],
275
+ memo: 'unwrap',
276
+ },
277
+ })
278
+ }
279
+
280
+ // Two top-level actions the wallet signs to unwrap an NFT into a host's cargo.
281
+ unwrapCargoTx(owner: NameType, assetId: UInt64Type, hostId: UInt64Type): Action[] {
282
+ return [this.transferForUnwrap(owner, assetId), this.placecargo(owner, hostId, assetId)]
283
+ }
284
+
285
+ // Two top-level actions the wallet signs to place an entity NFT at a nexus.
286
+ unwrapEntityTx(owner: NameType, assetId: UInt64Type, targetNexusId: UInt64Type): Action[] {
287
+ return [
288
+ this.transferForUnwrap(owner, assetId),
289
+ this.placeentity(owner, assetId, targetNexusId),
290
+ ]
291
+ }
292
+
293
+ setRamPayer(newPayer: NameType, assetId: UInt64Type): Action {
294
+ return Action.from({
295
+ account: 'atomicassets',
296
+ name: 'setrampayer',
297
+ authorization: [{actor: Name.from(newPayer), permission: 'active'}],
298
+ data: {new_payer: Name.from(newPayer), asset_id: UInt64.from(assetId)},
299
+ })
343
300
  }
344
301
 
345
302
  demolish(entityId: UInt64Type): Action {
@@ -351,4 +308,45 @@ export class ActionsManager extends BaseManager {
351
308
  joinGame(account: NameType, companyName: string): Action[] {
352
309
  return [this.foundCompany(account, companyName), this.join(account)]
353
310
  }
311
+
312
+ commit(oracleId: NameType, epoch: UInt64Type, commit: Checksum256Type): Action {
313
+ return this.server.action('commit', {
314
+ oracle_id: Name.from(oracleId),
315
+ epoch: UInt64.from(epoch),
316
+ commit: Checksum256.from(commit),
317
+ })
318
+ }
319
+
320
+ reveal(oracleId: NameType, epoch: UInt64Type, reveal: Checksum256Type): Action {
321
+ return this.server.action('reveal', {
322
+ oracle_id: Name.from(oracleId),
323
+ epoch: UInt64.from(epoch),
324
+ reveal: Checksum256.from(reveal),
325
+ })
326
+ }
327
+
328
+ addoracle(oracleId: NameType): Action {
329
+ return this.server.action('addoracle', {
330
+ oracle_id: Name.from(oracleId),
331
+ })
332
+ }
333
+
334
+ removeoracle(oracleId: NameType): Action {
335
+ return this.server.action('removeoracle', {
336
+ oracle_id: Name.from(oracleId),
337
+ })
338
+ }
339
+
340
+ setthreshold(threshold: UInt8Type): Action {
341
+ return this.server.action('setthreshold', {
342
+ threshold: UInt8.from(threshold),
343
+ })
344
+ }
345
+
346
+ cleanrsvp(epoch: UInt64Type, maxRows: UInt64Type): Action {
347
+ return this.server.action('cleanrsvp', {
348
+ epoch: UInt64.from(epoch),
349
+ max_rows: UInt64.from(maxRows),
350
+ })
351
+ }
354
352
  }
@@ -19,7 +19,7 @@ export abstract class BaseManager {
19
19
  return this.context.getGame()
20
20
  }
21
21
 
22
- protected async getState() {
23
- return this.context.getState()
22
+ protected async getState(reload = false) {
23
+ return this.context.getState(reload)
24
24
  }
25
25
  }
@@ -30,7 +30,7 @@ export class ConstructionManager extends BaseManager {
30
30
 
31
31
  eligibleSources(
32
32
  target: BuildableTarget,
33
- entities: ServerContract.Types.entity_row[],
33
+ entities: ServerContract.Types.entity_info[],
34
34
  cargo: ServerContract.Types.cargo_row[]
35
35
  ): SourceEntityRef[] {
36
36
  return partitionSources(target, entities, cargo).eligible
@@ -38,7 +38,7 @@ export class ConstructionManager extends BaseManager {
38
38
 
39
39
  unreachableSources(
40
40
  target: BuildableTarget,
41
- entities: ServerContract.Types.entity_row[],
41
+ entities: ServerContract.Types.entity_info[],
42
42
  cargo: ServerContract.Types.cargo_row[]
43
43
  ): SourceEntityRef[] {
44
44
  return partitionSources(target, entities, cargo).unreachable
@@ -46,7 +46,7 @@ export class ConstructionManager extends BaseManager {
46
46
 
47
47
  partitionSources(
48
48
  target: BuildableTarget,
49
- entities: ServerContract.Types.entity_row[],
49
+ entities: ServerContract.Types.entity_info[],
50
50
  cargo: ServerContract.Types.cargo_row[]
51
51
  ): {eligible: SourceEntityRef[]; unreachable: SourceEntityRef[]} {
52
52
  return partitionSources(target, entities, cargo)
@@ -54,7 +54,7 @@ export class ConstructionManager extends BaseManager {
54
54
 
55
55
  eligibleFinalizers(
56
56
  target: BuildableTarget,
57
- entities: ServerContract.Types.entity_row[]
57
+ entities: ServerContract.Types.entity_info[]
58
58
  ): FinalizerEntityRef[] {
59
59
  const out: FinalizerEntityRef[] = []
60
60
  for (const entity of entities) {
@@ -91,7 +91,7 @@ function coordsEqual(
91
91
  }
92
92
 
93
93
  function matchRelevantCargo(
94
- entity: ServerContract.Types.entity_row,
94
+ entity: ServerContract.Types.entity_info,
95
95
  target: BuildableTarget,
96
96
  cargo: ServerContract.Types.cargo_row[]
97
97
  ): SourceCargoStack[] {
@@ -119,7 +119,7 @@ function matchRelevantCargo(
119
119
 
120
120
  function partitionSources(
121
121
  target: BuildableTarget,
122
- entities: ServerContract.Types.entity_row[],
122
+ entities: ServerContract.Types.entity_info[],
123
123
  cargo: ServerContract.Types.cargo_row[]
124
124
  ): {eligible: SourceEntityRef[]; unreachable: SourceEntityRef[]} {
125
125
  const eligible: SourceEntityRef[] = []
@@ -1,6 +1,7 @@
1
1
  import {UInt64, type UInt64Type} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
3
  import {type EpochInfo, getCurrentEpoch, getEpochInfo} from '../scheduling/epoch'
4
+ import type {ServerContract} from '../contracts'
4
5
 
5
6
  export class EpochsManager extends BaseManager {
6
7
  async getCurrentHeight(): Promise<UInt64> {
@@ -8,6 +9,11 @@ export class EpochsManager extends BaseManager {
8
9
  return getCurrentEpoch(game)
9
10
  }
10
11
 
12
+ async getFinalizedEpoch(reload = false): Promise<UInt64> {
13
+ const state = await this.getState(reload)
14
+ return state.currentEpoch
15
+ }
16
+
11
17
  async getCurrent(): Promise<EpochInfo> {
12
18
  const game = await this.getGame()
13
19
  const epoch = await this.getCurrentHeight()
@@ -44,4 +50,38 @@ export class EpochsManager extends BaseManager {
44
50
  const remaining = await this.getTimeRemaining()
45
51
  return durationMs <= remaining
46
52
  }
53
+
54
+ async getEpochRow(epoch: UInt64Type): Promise<ServerContract.Types.epoch_row | undefined> {
55
+ const target = UInt64.from(epoch)
56
+ return this.server.table('epoch').get(target)
57
+ }
58
+
59
+ async getActiveEpochInfo(): Promise<ServerContract.Types.epoch_row | undefined> {
60
+ const rows = await this.server.table('epoch').all()
61
+ if (rows.length === 0) {
62
+ return undefined
63
+ }
64
+ return rows[rows.length - 1]
65
+ }
66
+
67
+ async getOracles(): Promise<ServerContract.Types.oracle_row[]> {
68
+ return this.server.table('oracles').all()
69
+ }
70
+
71
+ async getThreshold(): Promise<number> {
72
+ const cfg = await this.server.table('oraclecfg').get()
73
+ return cfg ? Number(cfg.threshold) : 0
74
+ }
75
+
76
+ async getCommitsFor(epoch: UInt64Type): Promise<ServerContract.Types.commit_row[]> {
77
+ const target = UInt64.from(epoch)
78
+ const rows = await this.server.table('commit').all()
79
+ return rows.filter((r) => r.epoch.equals(target))
80
+ }
81
+
82
+ async getRevealsFor(epoch: UInt64Type): Promise<ServerContract.Types.reveal_row[]> {
83
+ const target = UInt64.from(epoch)
84
+ const rows = await this.server.table('reveal').all()
85
+ return rows.filter((r) => r.epoch.equals(target))
86
+ }
47
87
  }
@@ -1,6 +1,6 @@
1
1
  import {Name} from '@wharfkit/antelope'
2
2
  import {getItem} from '../data/catalog'
3
- import {getRecipe, resolveRecipeInputItemId} from '../data/recipes-runtime'
3
+ import {getRecipe} from '../data/recipes-runtime'
4
4
  import {computeInputMass} from '../derivation/crafting'
5
5
  import {calc_craft_duration} from '../capabilities/crafting'
6
6
  import {TaskType} from '../types'
@@ -47,7 +47,7 @@ export class PlotManager extends BaseManager {
47
47
  }
48
48
 
49
49
  const rows: PlotProgressInputRow[] = recipe.inputs.map((input) => {
50
- const itemId = resolveRecipeInputItemId(input)
50
+ const itemId = input.itemId
51
51
  const required = input.quantity
52
52
  const provided = quantityByItemId.get(itemId) ?? 0
53
53
  const missing = Math.max(0, required - provided)
@@ -112,7 +112,7 @@ export class PlotManager extends BaseManager {
112
112
  }
113
113
 
114
114
  timeToComplete(
115
- plot: ServerContract.Types.entity_row,
115
+ plot: ServerContract.Types.entity_info,
116
116
  crafter: ServerContract.Types.crafter_stats
117
117
  ): number {
118
118
  const capacity = Number(plot.capacity?.toString() ?? '0')
@@ -110,6 +110,9 @@ function commonBaseImmutable(
110
110
  {first: 'origin_x', second: ['int32', originX]},
111
111
  {first: 'origin_y', second: ['int32', originY]},
112
112
  {first: 'img', second: ['string', img]},
113
+ {first: 'deposit_amount', second: ['uint64', '0']},
114
+ {first: 'deposit_token', second: ['uint64', '0']},
115
+ {first: 'deposit_symbol', second: ['uint64', '0']},
113
116
  ]
114
117
  }
115
118
 
@@ -39,12 +39,12 @@ export function computeBaseHullmass(stats: bigint): number {
39
39
 
40
40
  export function computeBaseCapacityShip(stats: bigint): number {
41
41
  const s = decodeStat(stats, 0) + decodeStat(stats, 2) + decodeStat(stats, 3)
42
- return Math.floor(5_000_000 * 10 ** (s / 2997))
42
+ return Math.floor(5_000_000 * 6 ** (s / 2997))
43
43
  }
44
44
 
45
45
  export function computeBaseCapacityWarehouse(stats: bigint): number {
46
46
  const s = decodeStat(stats, 0) + decodeStat(stats, 2) + decodeStat(stats, 3)
47
- return Math.floor(100_000_000 * 10 ** (s / 2997))
47
+ return Math.floor(100_000_000 * 6 ** (s / 2997))
48
48
  }
49
49
 
50
50
  export const computeEngineThrust = (vol: number): number => 400 + idiv(vol * 3, 4)
@@ -30,15 +30,21 @@ function tierPrefix(item: DisplayNameInput): string | null {
30
30
  return null
31
31
  }
32
32
 
33
- function baseName(item: DisplayNameInput): string {
33
+ function rootName(item: DisplayNameInput): string {
34
34
  if (itemTypeOf(item) !== 'resource') return item.name
35
35
  return item.category ? CATEGORY_LABELS[item.category] : 'Resource'
36
36
  }
37
37
 
38
- export function displayName(item: DisplayNameInput): string {
38
+ // Tier-free display name: includes the resource tier adjective / component-module
39
+ // prefix, but no "(T#)" suffix. Use this when the tier is shown separately.
40
+ export function baseName(item: DisplayNameInput): string {
39
41
  const prefix = tierPrefix(item)
40
- const head = prefix ? `${prefix} ${baseName(item)}` : baseName(item)
41
- return `${head} (T${item.tier})`
42
+ const root = rootName(item)
43
+ return prefix ? `${prefix} ${root}` : root
44
+ }
45
+
46
+ export function displayName(item: DisplayNameInput): string {
47
+ return `${baseName(item)} (T${item.tier})`
42
48
  }
43
49
 
44
50
  export interface DescribeOptions {