@shipload/sdk 1.0.0-next.4 → 1.0.0-next.41

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 (134) hide show
  1. package/lib/scan.d.ts +34 -0
  2. package/lib/scan.js +136 -0
  3. package/lib/scan.js.map +1 -0
  4. package/lib/scan.m.js +129 -0
  5. package/lib/scan.m.js.map +1 -0
  6. package/lib/shipload.d.ts +2473 -973
  7. package/lib/shipload.js +11529 -5211
  8. package/lib/shipload.js.map +1 -1
  9. package/lib/shipload.m.js +11338 -5162
  10. package/lib/shipload.m.js.map +1 -1
  11. package/lib/testing.d.ts +970 -0
  12. package/lib/testing.js +4013 -0
  13. package/lib/testing.js.map +1 -0
  14. package/lib/testing.m.js +4007 -0
  15. package/lib/testing.m.js.map +1 -0
  16. package/package.json +20 -2
  17. package/src/capabilities/craftable.ts +51 -0
  18. package/src/capabilities/crafting.test.ts +7 -0
  19. package/src/capabilities/crafting.ts +5 -6
  20. package/src/capabilities/gathering.test.ts +16 -0
  21. package/src/capabilities/gathering.ts +35 -18
  22. package/src/capabilities/index.ts +0 -1
  23. package/src/capabilities/modules.ts +9 -0
  24. package/src/capabilities/storage.ts +16 -1
  25. package/src/contracts/platform.ts +231 -3
  26. package/src/contracts/server.ts +1021 -481
  27. package/src/coordinates/address.ts +88 -0
  28. package/src/coordinates/constants.test.ts +15 -0
  29. package/src/coordinates/constants.ts +23 -0
  30. package/src/coordinates/index.ts +15 -0
  31. package/src/coordinates/memo.test.ts +47 -0
  32. package/src/coordinates/memo.ts +20 -0
  33. package/src/coordinates/permutation.ts +77 -0
  34. package/src/coordinates/regions.ts +48 -0
  35. package/src/coordinates/sectors.ts +115 -0
  36. package/src/data/capabilities.ts +12 -5
  37. package/src/data/capability-formulas.ts +14 -7
  38. package/src/data/catalog.ts +0 -5
  39. package/src/data/colors.ts +14 -47
  40. package/src/data/entities.json +76 -10
  41. package/src/data/item-ids.ts +18 -12
  42. package/src/data/items.json +321 -38
  43. package/src/data/kind-registry.json +109 -0
  44. package/src/data/kind-registry.ts +165 -0
  45. package/src/data/metadata.ts +119 -33
  46. package/src/data/recipes-runtime.ts +3 -23
  47. package/src/data/recipes.json +238 -117
  48. package/src/derivation/build-methods.ts +45 -0
  49. package/src/derivation/capabilities.test.ts +151 -0
  50. package/src/derivation/capabilities.ts +512 -0
  51. package/src/derivation/capability-mappings.ts +9 -12
  52. package/src/derivation/crafting.ts +23 -24
  53. package/src/derivation/index.ts +25 -2
  54. package/src/derivation/recipe-usage.test.ts +78 -0
  55. package/src/derivation/recipe-usage.ts +141 -0
  56. package/src/derivation/reserve-regen.ts +34 -0
  57. package/src/derivation/resources.ts +125 -38
  58. package/src/derivation/rollups.test.ts +55 -0
  59. package/src/derivation/rollups.ts +56 -0
  60. package/src/derivation/stars.test.ts +51 -0
  61. package/src/derivation/stars.ts +15 -0
  62. package/src/derivation/stats.ts +6 -6
  63. package/src/derivation/stratum.ts +17 -20
  64. package/src/derivation/tiers.ts +40 -7
  65. package/src/derivation/wormhole.ts +136 -0
  66. package/src/entities/entity.ts +98 -0
  67. package/src/entities/gamestate.ts +3 -28
  68. package/src/entities/makers.ts +124 -134
  69. package/src/entities/slot-multiplier.ts +43 -0
  70. package/src/errors.ts +12 -16
  71. package/src/format.ts +26 -4
  72. package/src/index-module.ts +267 -47
  73. package/src/managers/actions.ts +528 -95
  74. package/src/managers/base.ts +6 -2
  75. package/src/managers/construction-types.ts +80 -0
  76. package/src/managers/construction.ts +412 -0
  77. package/src/managers/context.ts +20 -1
  78. package/src/managers/coordinates.ts +14 -0
  79. package/src/managers/entities.ts +18 -66
  80. package/src/managers/epochs.ts +40 -0
  81. package/src/managers/index.ts +17 -1
  82. package/src/managers/locations.ts +25 -29
  83. package/src/managers/nft.test.ts +14 -0
  84. package/src/managers/nft.ts +70 -0
  85. package/src/managers/plot.ts +122 -0
  86. package/src/nft/atomicassets.abi.json +1342 -0
  87. package/src/nft/atomicassets.ts +237 -0
  88. package/src/nft/atomicdata.ts +130 -0
  89. package/src/nft/buildImmutableData.ts +338 -0
  90. package/src/nft/description.ts +98 -24
  91. package/src/nft/index.ts +3 -0
  92. package/src/planner/index.ts +127 -0
  93. package/src/planner/planner.test.ts +319 -0
  94. package/src/resolution/describe-module.ts +18 -13
  95. package/src/resolution/display-name.ts +38 -10
  96. package/src/resolution/resolve-item.test.ts +37 -0
  97. package/src/resolution/resolve-item.ts +55 -24
  98. package/src/scan/index.ts +180 -0
  99. package/src/scan/scan-wasm.base64.ts +2 -0
  100. package/src/scheduling/accessor.ts +68 -22
  101. package/src/scheduling/availability.ts +108 -0
  102. package/src/scheduling/cancel.test.ts +348 -0
  103. package/src/scheduling/cancel.ts +209 -0
  104. package/src/scheduling/energy.ts +47 -0
  105. package/src/scheduling/idle-resolve.ts +45 -0
  106. package/src/scheduling/lane-core.ts +128 -0
  107. package/src/scheduling/lanes.test.ts +249 -0
  108. package/src/scheduling/lanes.ts +198 -0
  109. package/src/scheduling/projection.ts +209 -105
  110. package/src/scheduling/schedule.ts +241 -104
  111. package/src/scheduling/task-cargo.ts +46 -0
  112. package/src/shipload.ts +21 -1
  113. package/src/subscriptions/manager.ts +229 -142
  114. package/src/subscriptions/mappers.ts +5 -8
  115. package/src/subscriptions/types.ts +11 -3
  116. package/src/testing/catalog-hash.ts +19 -0
  117. package/src/testing/index.ts +2 -0
  118. package/src/testing/projection-parity.ts +167 -0
  119. package/src/travel/reach.ts +23 -0
  120. package/src/travel/route-planner.ts +196 -0
  121. package/src/travel/travel.ts +200 -112
  122. package/src/types/capabilities.ts +29 -6
  123. package/src/types/entity.ts +3 -3
  124. package/src/types/index.ts +0 -1
  125. package/src/types.ts +28 -13
  126. package/src/utils/cargo.ts +27 -0
  127. package/src/utils/display-name.ts +70 -0
  128. package/src/utils/system.ts +36 -24
  129. package/src/capabilities/loading.ts +0 -8
  130. package/src/entities/container.ts +0 -108
  131. package/src/entities/ship-deploy.ts +0 -259
  132. package/src/entities/ship.ts +0 -204
  133. package/src/entities/warehouse.ts +0 -119
  134. package/src/types/entity-traits.ts +0 -69
@@ -1,179 +1,316 @@
1
1
  import type {ServerContract} from '../contracts'
2
2
  import {TaskType} from '../types'
3
+ import * as core from './lane-core'
3
4
 
4
5
  type Schedule = ServerContract.Types.schedule
5
6
  type Task = ServerContract.Types.task
7
+ type Lane = ServerContract.Types.lane
8
+ type Hold = ServerContract.Types.hold
9
+
10
+ export const LANE_MOBILITY = 0
11
+ export const LANE_BARRIER = 255
6
12
 
7
13
  export interface ScheduleData {
8
- schedule?: Schedule
9
- }
10
-
11
- export interface Scheduleable extends ScheduleData {
12
- hasSchedule: boolean
13
- isIdle: boolean
14
- tasks: Task[]
15
- scheduleDuration(): number
16
- scheduleElapsed(now: Date): number
17
- scheduleRemaining(now: Date): number
18
- scheduleComplete(now: Date): boolean
19
- currentTaskIndex(now: Date): number
20
- currentTask(now: Date): Task | undefined
21
- currentTaskType(now: Date): TaskType | undefined
22
- getTaskStartTime(index: number): number
23
- getTaskElapsed(index: number, now: Date): number
24
- getTaskRemaining(index: number, now: Date): number
25
- isTaskComplete(index: number, now: Date): boolean
26
- isTaskInProgress(index: number, now: Date): boolean
27
- currentTaskProgress(now: Date): number
28
- scheduleProgress(now: Date): number
14
+ lanes?: Lane[]
15
+ holds?: Hold[]
16
+ }
17
+
18
+ export interface LaneView {
19
+ laneKey: number
20
+ schedule: Schedule
21
+ }
22
+
23
+ export {
24
+ laneStartsIn,
25
+ currentTaskIndexForLane,
26
+ laneTaskComplete,
27
+ laneTaskInProgress,
28
+ laneCompletesAt,
29
+ currentTaskProgressFloatForLane,
30
+ } from './lane-core'
31
+
32
+ export function getLanes(entity: ScheduleData): LaneView[] {
33
+ const lanes = entity.lanes
34
+ if (!lanes || lanes.length === 0) return []
35
+ return lanes.map((l) => ({laneKey: l.lane_key.toNumber(), schedule: l.schedule}))
36
+ }
37
+
38
+ export function getLane(entity: ScheduleData, laneKey: number): LaneView | undefined {
39
+ const lanes = entity.lanes
40
+ if (!lanes) return undefined
41
+ for (const l of lanes) {
42
+ if (l.lane_key.toNumber() === laneKey) return {laneKey, schedule: l.schedule}
43
+ }
44
+ return undefined
45
+ }
46
+
47
+ export function mobilityLane(entity: ScheduleData): LaneView | undefined {
48
+ return getLane(entity, LANE_MOBILITY)
29
49
  }
30
50
 
31
51
  export function hasSchedule(entity: ScheduleData): boolean {
32
- return !!entity.schedule && entity.schedule.tasks.length > 0
52
+ const lanes = entity.lanes
53
+ if (!lanes) return false
54
+ return lanes.some((l) => l.schedule.tasks.length > 0)
55
+ }
56
+
57
+ export function hasHolds(entity: ScheduleData): boolean {
58
+ const holds = entity.holds
59
+ return !!holds && holds.length > 0
33
60
  }
34
61
 
35
62
  export function isIdle(entity: ScheduleData): boolean {
36
- return !hasSchedule(entity)
63
+ return !hasSchedule(entity) && !hasHolds(entity)
64
+ }
65
+
66
+ export function isEntityIdle(entity: ScheduleData, now: Date): boolean {
67
+ if (hasHolds(entity)) return false
68
+ const lanes = entity.lanes
69
+ if (!lanes) return true
70
+ return lanes.every((l) => core.currentTaskIndexForLane(l.schedule, now) < 0)
71
+ }
72
+
73
+ export function entityIdleAt(entity: ScheduleData, _now: Date): Date | undefined {
74
+ const lanes = entity.lanes
75
+ if (!lanes) return undefined
76
+ let maxMs: number | undefined
77
+ for (const l of lanes) {
78
+ if (l.schedule.tasks.length === 0) continue
79
+ const endMs = l.schedule.started.toDate().getTime() + core.laneDuration(l.schedule) * 1000
80
+ if (maxMs === undefined || endMs > maxMs) maxMs = endMs
81
+ }
82
+ return maxMs === undefined ? undefined : new Date(maxMs)
37
83
  }
38
84
 
39
85
  export function getTasks(entity: ScheduleData): Task[] {
40
- return entity.schedule?.tasks || []
86
+ const lanes = entity.lanes
87
+ if (!lanes) return []
88
+ return lanes.flatMap((l) => l.schedule.tasks)
41
89
  }
42
90
 
43
91
  export function scheduleDuration(entity: ScheduleData): number {
44
- if (!entity.schedule) return 0
45
- return entity.schedule.tasks.reduce((sum, task) => sum + task.duration.toNumber(), 0)
92
+ let max = 0
93
+ for (const l of entity.lanes ?? []) max = Math.max(max, core.laneDuration(l.schedule))
94
+ return max
46
95
  }
47
96
 
48
97
  export function scheduleElapsed(entity: ScheduleData, now: Date): number {
49
- if (!entity.schedule) return 0
50
- const started = entity.schedule.started.toDate()
51
- const elapsed = Math.floor((now.getTime() - started.getTime()) / 1000)
52
- return Math.max(0, elapsed)
98
+ let max = 0
99
+ for (const l of entity.lanes ?? []) max = Math.max(max, core.laneElapsed(l.schedule, now))
100
+ return max
53
101
  }
54
102
 
55
103
  export function scheduleRemaining(entity: ScheduleData, now: Date): number {
56
- if (!entity.schedule) return 0
57
- const duration = scheduleDuration(entity)
58
- const elapsed = scheduleElapsed(entity, now)
59
- return Math.max(0, duration - elapsed)
104
+ let remaining = 0
105
+ for (const l of entity.lanes ?? []) {
106
+ remaining = Math.max(remaining, core.laneRemaining(l.schedule, now))
107
+ }
108
+ return remaining
60
109
  }
61
110
 
62
111
  export function scheduleComplete(entity: ScheduleData, now: Date): boolean {
63
- return hasSchedule(entity) && scheduleRemaining(entity, now) === 0
112
+ const lanes = entity.lanes
113
+ if (!lanes) return false
114
+ let hasAnyTask = false
115
+ let remaining = 0
116
+ for (const l of lanes) {
117
+ if (l.schedule.tasks.length > 0) hasAnyTask = true
118
+ remaining = Math.max(remaining, core.laneRemaining(l.schedule, now))
119
+ }
120
+ if (!hasAnyTask) return false
121
+ return remaining === 0
64
122
  }
65
123
 
66
- export function currentTaskIndex(entity: ScheduleData, now: Date): number {
67
- if (!entity.schedule || entity.schedule.tasks.length === 0) return -1
124
+ // Mirrors contract lane_front_complete: any lane whose front task is complete and non-reserved.
125
+ export function hasResolvable(entity: ScheduleData, now: Date): boolean {
126
+ for (const l of entity.lanes ?? []) {
127
+ if (core.laneTaskComplete(l.schedule, 0, now)) return true
128
+ }
129
+ return false
130
+ }
68
131
 
69
- const elapsed = scheduleElapsed(entity, now)
70
- let timeAccum = 0
132
+ export function currentTaskForLane(
133
+ entity: ScheduleData,
134
+ laneKey: number,
135
+ now: Date
136
+ ): Task | undefined {
137
+ const lane = getLane(entity, laneKey)
138
+ return lane ? core.currentTask(lane.schedule, now) : undefined
139
+ }
71
140
 
72
- for (let i = 0; i < entity.schedule.tasks.length; i++) {
73
- const taskDuration = entity.schedule.tasks[i].duration.toNumber()
74
- if (elapsed < timeAccum + taskDuration) {
75
- return i
76
- }
77
- timeAccum += taskDuration
78
- }
141
+ export function currentTaskTypeForLane(
142
+ entity: ScheduleData,
143
+ laneKey: number,
144
+ now: Date
145
+ ): TaskType | undefined {
146
+ const lane = getLane(entity, laneKey)
147
+ return lane ? core.currentTaskType(lane.schedule, now) : undefined
148
+ }
79
149
 
80
- return entity.schedule.tasks.length - 1
150
+ export function activeTasks(entity: ScheduleData, now: Date): Task[] {
151
+ const out: Task[] = []
152
+ for (const l of entity.lanes ?? []) {
153
+ const idx = core.currentTaskIndexForLane(l.schedule, now)
154
+ if (idx >= 0) out.push(l.schedule.tasks[idx])
155
+ }
156
+ return out
81
157
  }
82
158
 
83
- export function currentTask(entity: ScheduleData, now: Date): Task | undefined {
84
- const index = currentTaskIndex(entity, now)
85
- if (index < 0 || !entity.schedule) return undefined
86
- return entity.schedule.tasks[index]
159
+ export interface ResolvedEvent {
160
+ laneKey: number
161
+ taskIndex: number
162
+ task: Task
163
+ completesAt: Date
87
164
  }
88
165
 
89
- export function currentTaskType(entity: ScheduleData, now: Date): TaskType | undefined {
90
- const task = currentTask(entity, now)
91
- if (!task) return undefined
92
- return task.type.toNumber() as TaskType
166
+ // Canonical lane-front order (mirrors contract front_precedes): completion, then RECHARGE-last, then lane key.
167
+ function frontPrecedes(
168
+ a: {completesAt: Date; task: Task; laneKey: number},
169
+ b: {completesAt: Date; task: Task; laneKey: number}
170
+ ): number {
171
+ if (a.completesAt.getTime() !== b.completesAt.getTime()) {
172
+ return a.completesAt.getTime() - b.completesAt.getTime()
173
+ }
174
+ const aRecharge = a.task.type.toNumber() === TaskType.RECHARGE
175
+ const bRecharge = b.task.type.toNumber() === TaskType.RECHARGE
176
+ if (aRecharge !== bRecharge) return aRecharge ? 1 : -1
177
+ return a.laneKey - b.laneKey
93
178
  }
94
179
 
95
- export function getTaskStartTime(entity: ScheduleData, index: number): number {
96
- if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length) return 0
97
- let timeAccum = 0
98
- for (let i = 0; i < index; i++) {
99
- timeAccum += entity.schedule.tasks[i].duration.toNumber()
180
+ // Completed lane-fronts in canonical order (mirrors contract front_precedes).
181
+ export function resolveOrder(entity: ScheduleData, now: Date): ResolvedEvent[] {
182
+ const events: ResolvedEvent[] = []
183
+ for (const l of entity.lanes ?? []) {
184
+ const laneKey = l.lane_key.toNumber()
185
+ const startedMs = l.schedule.started.toDate().getTime()
186
+ let endSec = 0
187
+ for (let i = 0; i < l.schedule.tasks.length; i++) {
188
+ const task = l.schedule.tasks[i]
189
+ endSec += task.duration.toNumber()
190
+ const completesAt = new Date(startedMs + endSec * 1000)
191
+ if (completesAt.getTime() > now.getTime()) break
192
+ events.push({laneKey, taskIndex: i, task, completesAt})
193
+ }
100
194
  }
101
- return timeAccum
195
+ events.sort(frontPrecedes)
196
+ return events
102
197
  }
103
198
 
104
- export function getTaskElapsed(entity: ScheduleData, index: number, now: Date): number {
105
- if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length) return 0
199
+ export interface OrderedTask {
200
+ laneKey: number
201
+ taskIndex: number
202
+ task: Task
203
+ startsAt: Date
204
+ completesAt: Date
205
+ }
106
206
 
107
- const elapsed = scheduleElapsed(entity, now)
108
- const taskStart = getTaskStartTime(entity, index)
109
- const taskDuration = entity.schedule.tasks[index].duration.toNumber()
207
+ // Every task across all lanes in canonical order (mirrors contract front_precedes).
208
+ export function orderedTasks(entity: ScheduleData): OrderedTask[] {
209
+ const out: OrderedTask[] = []
210
+ for (const l of entity.lanes ?? []) {
211
+ const laneKey = l.lane_key.toNumber()
212
+ const startedMs = l.schedule.started.toDate().getTime()
213
+ let endSec = 0
214
+ for (let i = 0; i < l.schedule.tasks.length; i++) {
215
+ const task = l.schedule.tasks[i]
216
+ const startsAt = new Date(startedMs + endSec * 1000)
217
+ endSec += task.duration.toNumber()
218
+ const completesAt = new Date(startedMs + endSec * 1000)
219
+ out.push({laneKey, taskIndex: i, task, startsAt, completesAt})
220
+ }
221
+ }
222
+ out.sort(frontPrecedes)
223
+ return out
224
+ }
110
225
 
111
- if (elapsed <= taskStart) return 0
112
- const elapsedInTask = elapsed - taskStart
113
- return Math.min(elapsedInTask, taskDuration)
226
+ export function laneRemainingOf(entity: ScheduleData, laneKey: number, now: Date): number {
227
+ const lane = getLane(entity, laneKey)
228
+ return lane ? core.laneRemaining(lane.schedule, now) : 0
114
229
  }
115
230
 
116
- export function getTaskRemaining(entity: ScheduleData, index: number, now: Date): number {
117
- if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length) return 0
231
+ export function laneStartsInOf(entity: ScheduleData, laneKey: number, now: Date): number {
232
+ const lane = getLane(entity, laneKey)
233
+ return lane ? core.laneStartsIn(lane.schedule, now) : 0
234
+ }
118
235
 
119
- const taskDuration = entity.schedule.tasks[index].duration.toNumber()
120
- const taskElapsed = getTaskElapsed(entity, index, now)
121
- return Math.max(0, taskDuration - taskElapsed)
236
+ export function laneCompleteOf(entity: ScheduleData, laneKey: number, now: Date): boolean {
237
+ const lane = getLane(entity, laneKey)
238
+ return lane ? core.laneComplete(lane.schedule, now) : false
122
239
  }
123
240
 
124
- export function isTaskComplete(entity: ScheduleData, index: number, now: Date): boolean {
125
- if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length) return false
241
+ export function laneProgressOf(entity: ScheduleData, laneKey: number, now: Date): number {
242
+ const lane = getLane(entity, laneKey)
243
+ return lane ? core.laneProgress(lane.schedule, now) : 0
244
+ }
126
245
 
127
- const taskDuration = entity.schedule.tasks[index].duration.toNumber()
128
- const taskElapsed = getTaskElapsed(entity, index, now)
129
- return taskElapsed >= taskDuration
246
+ export function laneTaskElapsedOf(
247
+ entity: ScheduleData,
248
+ laneKey: number,
249
+ index: number,
250
+ now: Date
251
+ ): number {
252
+ const lane = getLane(entity, laneKey)
253
+ return lane ? core.laneTaskElapsed(lane.schedule, index, now) : 0
130
254
  }
131
255
 
132
- export function isTaskInProgress(entity: ScheduleData, index: number, now: Date): boolean {
133
- if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length) return false
256
+ export function laneTaskRemainingOf(
257
+ entity: ScheduleData,
258
+ laneKey: number,
259
+ index: number,
260
+ now: Date
261
+ ): number {
262
+ const lane = getLane(entity, laneKey)
263
+ return lane ? core.laneTaskRemaining(lane.schedule, index, now) : 0
264
+ }
134
265
 
135
- const taskElapsed = getTaskElapsed(entity, index, now)
136
- const taskDuration = entity.schedule.tasks[index].duration.toNumber()
137
- return taskElapsed > 0 && taskElapsed < taskDuration
266
+ export function laneTaskCompleteOf(
267
+ entity: ScheduleData,
268
+ laneKey: number,
269
+ index: number,
270
+ now: Date
271
+ ): boolean {
272
+ const lane = getLane(entity, laneKey)
273
+ return lane ? core.laneTaskComplete(lane.schedule, index, now) : false
138
274
  }
139
275
 
140
- export function currentTaskProgress(entity: ScheduleData, now: Date): number {
141
- const task = currentTask(entity, now)
142
- if (!task) return 0
143
- const index = currentTaskIndex(entity, now)
144
- const elapsed = getTaskElapsed(entity, index, now)
145
- const duration = task.duration.toNumber()
146
- if (duration === 0) return 1
147
- return Math.min(1, elapsed / duration)
276
+ export function laneTaskInProgressOf(
277
+ entity: ScheduleData,
278
+ laneKey: number,
279
+ index: number,
280
+ now: Date
281
+ ): boolean {
282
+ const lane = getLane(entity, laneKey)
283
+ return lane ? core.laneTaskInProgress(lane.schedule, index, now) : false
148
284
  }
149
285
 
150
- export function scheduleProgress(entity: ScheduleData, now: Date): number {
151
- const duration = scheduleDuration(entity)
152
- if (duration === 0) return hasSchedule(entity) ? 1 : 0
153
- const elapsed = scheduleElapsed(entity, now)
154
- return Math.min(1, elapsed / duration)
286
+ export function currentTaskIndexOf(entity: ScheduleData, laneKey: number, now: Date): number {
287
+ const lane = getLane(entity, laneKey)
288
+ return lane ? core.currentTaskIndexForLane(lane.schedule, now) : -1
155
289
  }
156
290
 
157
- export function isTaskType(entity: ScheduleData, taskType: TaskType, now: Date): boolean {
158
- return currentTaskType(entity, now) === taskType
291
+ function entityDoesTaskType(entity: ScheduleData, taskType: TaskType, now: Date): boolean {
292
+ return activeTasks(entity, now).some((t) => t.type.toNumber() === taskType)
159
293
  }
160
294
 
161
295
  export function isInFlight(entity: ScheduleData, now: Date): boolean {
162
- return isTaskType(entity, TaskType.TRAVEL, now)
296
+ const lane = mobilityLane(entity)
297
+ if (!lane) return false
298
+ const t = core.currentTaskType(lane.schedule, now)
299
+ return t === TaskType.TRAVEL || t === TaskType.TRANSIT
163
300
  }
164
301
 
165
302
  export function isRecharging(entity: ScheduleData, now: Date): boolean {
166
- return isTaskType(entity, TaskType.RECHARGE, now)
303
+ return entityDoesTaskType(entity, TaskType.RECHARGE, now)
167
304
  }
168
305
 
169
306
  export function isLoading(entity: ScheduleData, now: Date): boolean {
170
- return isTaskType(entity, TaskType.LOAD, now)
307
+ return entityDoesTaskType(entity, TaskType.LOAD, now)
171
308
  }
172
309
 
173
310
  export function isUnloading(entity: ScheduleData, now: Date): boolean {
174
- return isTaskType(entity, TaskType.UNLOAD, now)
311
+ return entityDoesTaskType(entity, TaskType.UNLOAD, now)
175
312
  }
176
313
 
177
314
  export function isGathering(entity: ScheduleData, now: Date): boolean {
178
- return isTaskType(entity, TaskType.GATHER, now)
315
+ return entityDoesTaskType(entity, TaskType.GATHER, now)
179
316
  }
@@ -0,0 +1,46 @@
1
+ import type {ServerContract} from '../contracts'
2
+ import {TaskType} from '../types'
3
+
4
+ export type TaskCargoDirection = 'in' | 'out'
5
+
6
+ export interface TaskCargoChange {
7
+ direction: TaskCargoDirection
8
+ item_id: number
9
+ stats: bigint
10
+ modules: ServerContract.Types.module_entry[]
11
+ quantity: number
12
+ }
13
+
14
+ function toChange(
15
+ item: ServerContract.Types.cargo_item,
16
+ direction: TaskCargoDirection
17
+ ): TaskCargoChange {
18
+ return {
19
+ direction,
20
+ item_id: Number(item.item_id),
21
+ stats: BigInt(item.stats.toString()),
22
+ modules: item.modules ?? [],
23
+ quantity: Number(item.quantity),
24
+ }
25
+ }
26
+
27
+ export function taskCargoChanges(task: ServerContract.Types.task): TaskCargoChange[] {
28
+ const items = task.cargo ?? []
29
+ if (items.length === 0) return []
30
+ switch (Number(task.type)) {
31
+ case TaskType.LOAD:
32
+ case TaskType.UNWRAP:
33
+ return items.map((i) => toChange(i, 'in'))
34
+ case TaskType.GATHER:
35
+ return task.entitytarget ? [] : items.map((i) => toChange(i, 'in'))
36
+ case TaskType.UNLOAD:
37
+ return items.map((i) => toChange(i, 'out'))
38
+ case TaskType.CRAFT:
39
+ return [
40
+ ...items.slice(0, -1).map((i) => toChange(i, 'out')),
41
+ toChange(items[items.length - 1], 'in'),
42
+ ]
43
+ default:
44
+ return []
45
+ }
46
+ }
package/src/shipload.ts CHANGED
@@ -7,8 +7,10 @@ import {GameContext} from './managers/context'
7
7
  import type {EntitiesManager} from './managers/entities'
8
8
  import type {PlayersManager} from './managers/players'
9
9
  import type {LocationsManager} from './managers/locations'
10
+ import type {CoordinatesManager} from './managers/coordinates'
10
11
  import type {EpochsManager} from './managers/epochs'
11
12
  import type {ActionsManager} from './managers/actions'
13
+ import type {NftManager} from './managers/nft'
12
14
  import type {SubscriptionsManager} from './subscriptions/manager'
13
15
  import type {GameState} from './entities/gamestate'
14
16
 
@@ -17,6 +19,7 @@ interface ShiploadOptions {
17
19
  serverContractName?: string
18
20
  client?: APIClient
19
21
  subscriptionsUrl?: string
22
+ atomicAssetsAccount?: string
20
23
  }
21
24
 
22
25
  interface ShiploadConstructorOptions extends ShiploadOptions {
@@ -39,7 +42,12 @@ export class Shipload {
39
42
  ? serverContract
40
43
  : new ServerContract.Contract({client: apiClient})
41
44
 
42
- this._context = new GameContext(apiClient, server, platform)
45
+ this._context = new GameContext(
46
+ apiClient,
47
+ server,
48
+ platform,
49
+ constructorOptions?.atomicAssetsAccount ?? 'atomicassets'
50
+ )
43
51
 
44
52
  if (constructorOptions?.subscriptionsUrl) {
45
53
  this._context.setSubscriptionsUrl(constructorOptions.subscriptionsUrl)
@@ -79,6 +87,10 @@ export class Shipload {
79
87
  return this._context.client
80
88
  }
81
89
 
90
+ get atomicAssetsAccount(): string {
91
+ return this._context.atomicAssetsAccount
92
+ }
93
+
82
94
  get server(): Contract {
83
95
  return this._context.server
84
96
  }
@@ -99,6 +111,10 @@ export class Shipload {
99
111
  return this._context.locations
100
112
  }
101
113
 
114
+ get coordinates(): CoordinatesManager {
115
+ return this._context.coordinates
116
+ }
117
+
102
118
  get epochs(): EpochsManager {
103
119
  return this._context.epochs
104
120
  }
@@ -107,6 +123,10 @@ export class Shipload {
107
123
  return this._context.actions
108
124
  }
109
125
 
126
+ get nft(): NftManager {
127
+ return this._context.nft
128
+ }
129
+
110
130
  get subscriptions(): SubscriptionsManager {
111
131
  return this._context.subscriptions
112
132
  }