@shipload/sdk 1.0.0-next.31 → 1.0.0-next.33

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,12 +1,26 @@
1
1
  import {UInt64, type UInt64Type} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
- import type {ServerContract} from '../contracts'
3
+ import type {PlatformContract, ServerContract} from '../contracts'
4
4
 
5
5
  export interface NftConfigForItem {
6
6
  templateId: number
7
7
  schemaName: string
8
8
  }
9
9
 
10
+ export interface WrapDeposit {
11
+ cost: bigint
12
+ refund: bigint
13
+ feePct: number
14
+ symbol: string
15
+ precision: number
16
+ tokenContract: string
17
+ }
18
+
19
+ export function resolveLockedAmount(cost: bigint, feePctBasisPoints: number): bigint {
20
+ const fee = (cost * BigInt(feePctBasisPoints)) / 10_000n
21
+ return cost - fee
22
+ }
23
+
10
24
  export class NftManager extends BaseManager {
11
25
  private cache = new Map<string, NftConfigForItem | null>()
12
26
 
@@ -25,4 +39,32 @@ export class NftManager extends BaseManager {
25
39
  this.cache.set(key, result)
26
40
  return result ?? undefined
27
41
  }
42
+
43
+ async getWrapDeposit(itemType: number, tier: number): Promise<WrapDeposit | null> {
44
+ const key = UInt64.from((BigInt(itemType) << 8n) | BigInt(tier))
45
+ const costRow = (await this.server.table('wrapcost').get(key)) as
46
+ | ServerContract.Types.wrapcost_row
47
+ | undefined
48
+ const cost = costRow ? BigInt(costRow.amount.toString()) : 0n
49
+ if (cost === 0n) return null
50
+
51
+ const cfg = (await this.server.table('wrapconfig').get()) as
52
+ | ServerContract.Types.wrapconfig_row
53
+ | undefined
54
+ const feePctBasisPoints = cfg ? Number(cfg.fee_pct) : 0
55
+
56
+ const depositCfg = (await this.platform.table('depositcfg').get()) as
57
+ | PlatformContract.Types.depositcfg_row
58
+ | undefined
59
+ if (!depositCfg) return null
60
+
61
+ return {
62
+ cost,
63
+ refund: resolveLockedAmount(cost, feePctBasisPoints),
64
+ feePct: feePctBasisPoints / 100,
65
+ symbol: depositCfg.token_symbol.code.toString(),
66
+ precision: depositCfg.token_symbol.precision,
67
+ tokenContract: depositCfg.token_contract.toString(),
68
+ }
69
+ }
28
70
  }
@@ -79,13 +79,10 @@ export class PlotManager extends BaseManager {
79
79
  }
80
80
 
81
81
  let state: BuildableTarget['state']
82
- const taskType = activeTask?.type.toNumber()
83
82
  if (scheduledBuild?.hasStarted) {
84
83
  state = 'finalizing'
85
84
  } else if (scheduledBuild) {
86
85
  state = 'scheduled'
87
- } else if (taskType === TaskType.CLAIMPLOT) {
88
- state = 'initializing'
89
86
  } else if (progress.isComplete) {
90
87
  state = 'ready'
91
88
  } else {
@@ -57,7 +57,7 @@ export const computeGathererDrain = (con: number): number =>
57
57
  export const computeGathererDepth = (tol: number, tier: number): number =>
58
58
  gathererDepthForTier(tol, tier)
59
59
  export const computeLoaderMass = (ins: number): number => Math.max(200, 2000 - ins * 2)
60
- export const computeLoaderThrust = (pla: number): number => 1 + idiv(pla, 500)
60
+ export const computeLoaderThrust = (pla: number): number => 1 + idiv(pla * pla, 10000)
61
61
  export const computeCrafterSpeed = (rea: number): number => 100 + idiv(rea * 4, 5)
62
62
  export const computeCrafterDrain = (fin: number): number => Math.max(5, 30 - idiv(fin, 33))
63
63
  export const computeHaulerCapacity = (fin: number): number => Math.max(1, 1 + idiv(fin, 400))
@@ -20,12 +20,11 @@ export function energyAtTime(entity: Projectable, now: Date): number {
20
20
 
21
21
  for (const {task, startsAt} of ordered) {
22
22
  const duration = task.duration.toNumber()
23
- const isReserved = task.type.toNumber() === TaskType.RESERVED
24
23
  const elapsed = Math.min(
25
24
  Math.max(0, Math.floor((nowMs - startsAt.getTime()) / 1000)),
26
25
  duration
27
26
  )
28
- const complete = !isReserved && elapsed >= duration
27
+ const complete = elapsed >= duration
29
28
  const inProgress = !complete && elapsed > 0 && elapsed < duration
30
29
 
31
30
  if (!complete && !inProgress) continue
@@ -0,0 +1,44 @@
1
+ import type {Action, UInt64} from '@wharfkit/antelope'
2
+ import type {ServerContract} from '../contracts'
3
+ import type {ActionsManager} from '../managers/actions'
4
+ import {hasResolvable, type ScheduleData} from './schedule'
5
+
6
+ type EntityInfo = ServerContract.Types.entity_info
7
+
8
+ export type CounterpartLookup = (entityId: UInt64) => EntityInfo | undefined
9
+
10
+ export type IdleResolveTarget = ScheduleData & {id: UInt64}
11
+
12
+ // A hold's driving task lives on its counterpart, so a hold resolves the counterpart, never the blocker.
13
+ export function composeIdleResolve(
14
+ blocker: IdleResolveTarget,
15
+ action: Action,
16
+ actions: ActionsManager,
17
+ now: Date,
18
+ lookupCounterpart?: CounterpartLookup
19
+ ): Action[] {
20
+ const ids: UInt64[] = []
21
+ const seen = new Set<string>()
22
+
23
+ const add = (id: UInt64) => {
24
+ const key = id.toString()
25
+ if (seen.has(key)) return
26
+ seen.add(key)
27
+ ids.push(id)
28
+ }
29
+
30
+ if (hasResolvable(blocker, now)) {
31
+ add(blocker.id)
32
+ }
33
+
34
+ for (const hold of blocker.holds ?? []) {
35
+ const counterpartId = hold.counterpart.entity_id
36
+ if (lookupCounterpart) {
37
+ const counterpart = lookupCounterpart(counterpartId)
38
+ if (!counterpart || !hasResolvable(counterpart, now)) continue
39
+ }
40
+ add(counterpartId)
41
+ }
42
+
43
+ return [...ids.map((id) => actions.resolve(id)), action]
44
+ }
@@ -1,5 +1,5 @@
1
1
  import type {ServerContract} from '../contracts'
2
- import {TaskType} from '../types'
2
+ import type {TaskType} from '../types'
3
3
 
4
4
  type Schedule = ServerContract.Types.schedule
5
5
  type Task = ServerContract.Types.task
@@ -27,7 +27,6 @@ export function laneRemaining(schedule: Schedule, now: Date): number {
27
27
 
28
28
  export function laneComplete(schedule: Schedule, now: Date): boolean {
29
29
  if (schedule.tasks.length === 0) return false
30
- if (schedule.tasks.some((t) => t.type.toNumber() === TaskType.RESERVED)) return false
31
30
  return laneRemaining(schedule, now) === 0
32
31
  }
33
32
 
@@ -87,7 +86,6 @@ export function laneTaskRemaining(schedule: Schedule, index: number, now: Date):
87
86
 
88
87
  export function laneTaskComplete(schedule: Schedule, index: number, now: Date): boolean {
89
88
  if (index < 0 || index >= schedule.tasks.length) return false
90
- if (schedule.tasks[index].type.toNumber() === TaskType.RESERVED) return false
91
89
  const taskDuration = schedule.tasks[index].duration.toNumber()
92
90
  return laneTaskElapsed(schedule, index, now) >= taskDuration
93
91
  }
@@ -442,12 +442,11 @@ export function projectEntityAt(entity: Projectable, now: Date): ProjectedEntity
442
442
 
443
443
  for (const {task, startsAt} of ordered) {
444
444
  const duration = task.duration.toNumber()
445
- const isReserved = task.type.toNumber() === TaskType.RESERVED
446
445
  const elapsed = Math.min(
447
446
  Math.max(0, Math.floor((nowMs - startsAt.getTime()) / 1000)),
448
447
  duration
449
448
  )
450
- const taskComplete = !isReserved && elapsed >= duration
449
+ const taskComplete = elapsed >= duration
451
450
  const taskInProgress = elapsed > 0 && elapsed < duration
452
451
 
453
452
  if (!taskComplete && !taskInProgress) {
@@ -5,12 +5,14 @@ import * as core from './lane-core'
5
5
  type Schedule = ServerContract.Types.schedule
6
6
  type Task = ServerContract.Types.task
7
7
  type Lane = ServerContract.Types.lane
8
+ type Hold = ServerContract.Types.hold
8
9
 
9
10
  export const LANE_MOBILITY = 0
10
11
  export const LANE_BARRIER = 255
11
12
 
12
13
  export interface ScheduleData {
13
14
  lanes?: Lane[]
15
+ holds?: Hold[]
14
16
  }
15
17
 
16
18
  export interface LaneView {
@@ -52,11 +54,17 @@ export function hasSchedule(entity: ScheduleData): boolean {
52
54
  return lanes.some((l) => l.schedule.tasks.length > 0)
53
55
  }
54
56
 
57
+ export function hasHolds(entity: ScheduleData): boolean {
58
+ const holds = entity.holds
59
+ return !!holds && holds.length > 0
60
+ }
61
+
55
62
  export function isIdle(entity: ScheduleData): boolean {
56
- return !hasSchedule(entity)
63
+ return !hasSchedule(entity) && !hasHolds(entity)
57
64
  }
58
65
 
59
66
  export function isEntityIdle(entity: ScheduleData, now: Date): boolean {
67
+ if (hasHolds(entity)) return false
60
68
  const lanes = entity.lanes
61
69
  if (!lanes) return true
62
70
  return lanes.every((l) => core.currentTaskIndexForLane(l.schedule, now) < 0)
@@ -106,13 +114,7 @@ export function scheduleComplete(entity: ScheduleData, now: Date): boolean {
106
114
  let hasAnyTask = false
107
115
  let remaining = 0
108
116
  for (const l of lanes) {
109
- const tasks = l.schedule.tasks
110
- if (tasks.length > 0) {
111
- hasAnyTask = true
112
- for (const t of tasks) {
113
- if (t.type.toNumber() === TaskType.RESERVED) return false
114
- }
115
- }
117
+ if (l.schedule.tasks.length > 0) hasAnyTask = true
116
118
  remaining = Math.max(remaining, core.laneRemaining(l.schedule, now))
117
119
  }
118
120
  if (!hasAnyTask) return false
@@ -186,7 +188,6 @@ export function resolveOrder(entity: ScheduleData, now: Date): ResolvedEvent[] {
186
188
  const task = l.schedule.tasks[i]
187
189
  endSec += task.duration.toNumber()
188
190
  const completesAt = new Date(startedMs + endSec * 1000)
189
- if (task.type.toNumber() === TaskType.RESERVED) break
190
191
  if (completesAt.getTime() > now.getTime()) break
191
192
  events.push({laneKey, taskIndex: i, task, completesAt})
192
193
  }
@@ -19,5 +19,7 @@ export function parseWireEntity(raw: WireEntity): ServerContract.Types.entity_in
19
19
  }
20
20
  delete shaped.name
21
21
 
22
+ if (shaped.holds === undefined) shaped.holds = []
23
+
22
24
  return ServerContract.Types.entity_info.from(shaped)
23
25
  }
package/src/types.ts CHANGED
@@ -23,7 +23,7 @@ export const MAX_ORBITAL_ALTITUDE = 3000
23
23
  export const BASE_ORBITAL_MASS = 100000
24
24
 
25
25
  export const MIN_TRANSFER_DISTANCE_PLANETARY_STRUCTURE = 100
26
- export const MIN_TRANSFER_DISTANCE_ORBITAL_VESSEL = 300
26
+ export const MIN_TRANSFER_DISTANCE_ORBITAL_VESSEL = 200
27
27
 
28
28
  export interface ShipLike {
29
29
  coordinates: ServerContract.Types.coordinates
@@ -56,7 +56,13 @@ export enum TaskType {
56
56
  DEMOLISH = 13,
57
57
  CLAIMPLOT = 14,
58
58
  BUILDPLOT = 15,
59
- RESERVED = 16,
59
+ }
60
+
61
+ export enum HoldKind {
62
+ PULL = 1,
63
+ PUSH = 2,
64
+ GATHER = 3,
65
+ BUILD = 4,
60
66
  }
61
67
 
62
68
  export enum LocationType {