@shipload/sdk 0.7.1 → 2.0.0-rc10

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 (79) hide show
  1. package/lib/shipload.d.ts +2203 -288
  2. package/lib/shipload.js +8441 -2210
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +8160 -2167
  5. package/lib/shipload.m.js.map +1 -1
  6. package/package.json +7 -6
  7. package/src/capabilities/crafting.ts +26 -0
  8. package/src/capabilities/extraction.ts +36 -0
  9. package/src/capabilities/guards.ts +38 -0
  10. package/src/capabilities/hauling.ts +22 -0
  11. package/src/capabilities/index.ts +8 -0
  12. package/src/capabilities/loading.ts +8 -0
  13. package/src/capabilities/modules.ts +57 -0
  14. package/src/capabilities/movement.ts +29 -0
  15. package/src/capabilities/storage.ts +72 -0
  16. package/src/contracts/server.ts +1217 -254
  17. package/src/data/capabilities.ts +408 -0
  18. package/src/data/categories.ts +58 -0
  19. package/src/data/colors.ts +52 -0
  20. package/src/data/items.json +17 -0
  21. package/src/data/locations.ts +53 -0
  22. package/src/data/nebula-adjectives.json +211 -0
  23. package/src/data/nebula-nouns.json +151 -0
  24. package/src/data/recipes.ts +571 -0
  25. package/src/data/syllables.json +1790 -0
  26. package/src/data/tiers.ts +45 -0
  27. package/src/derivation/crafting.ts +197 -0
  28. package/src/derivation/index.ts +28 -0
  29. package/src/derivation/location-size.ts +15 -0
  30. package/src/derivation/resources.ts +142 -0
  31. package/src/derivation/stats.ts +146 -0
  32. package/src/derivation/stratum.ts +118 -0
  33. package/src/entities/cargo-utils.ts +84 -0
  34. package/src/entities/container.ts +106 -0
  35. package/src/entities/entity-inventory.ts +39 -0
  36. package/src/entities/gamestate.ts +152 -0
  37. package/src/entities/inventory-accessor.ts +42 -0
  38. package/src/entities/location.ts +60 -0
  39. package/src/entities/makers.ts +72 -0
  40. package/src/entities/player.ts +15 -0
  41. package/src/entities/ship-deploy.ts +263 -0
  42. package/src/entities/ship.ts +199 -0
  43. package/src/entities/warehouse.ts +91 -0
  44. package/src/errors.ts +46 -9
  45. package/src/index-module.ts +302 -7
  46. package/src/managers/actions.ts +197 -0
  47. package/src/managers/base.ts +25 -0
  48. package/src/managers/context.ts +95 -0
  49. package/src/managers/entities.ts +103 -0
  50. package/src/managers/epochs.ts +47 -0
  51. package/src/managers/index.ts +8 -0
  52. package/src/managers/locations.ts +39 -0
  53. package/src/managers/players.ts +13 -0
  54. package/src/market/items.ts +30 -0
  55. package/src/nft/description.ts +175 -0
  56. package/src/nft/deserializers.ts +81 -0
  57. package/src/nft/index.ts +2 -0
  58. package/src/resolution/resolve-item.ts +313 -0
  59. package/src/scheduling/accessor.ts +82 -0
  60. package/src/{epoch.ts → scheduling/epoch.ts} +1 -1
  61. package/src/scheduling/projection.ts +322 -0
  62. package/src/scheduling/schedule.ts +179 -0
  63. package/src/shipload.ts +36 -159
  64. package/src/travel/travel.ts +499 -0
  65. package/src/types/capabilities.ts +71 -0
  66. package/src/types/entity-traits.ts +69 -0
  67. package/src/types/entity.ts +39 -0
  68. package/src/types/index.ts +3 -0
  69. package/src/types.ts +113 -35
  70. package/src/{hash.ts → utils/hash.ts} +1 -1
  71. package/src/utils/system.ts +155 -0
  72. package/src/goods.ts +0 -124
  73. package/src/market.ts +0 -214
  74. package/src/rolls.ts +0 -8
  75. package/src/ship.ts +0 -36
  76. package/src/state.ts +0 -0
  77. package/src/syllables.ts +0 -1184
  78. package/src/system.ts +0 -37
  79. package/src/travel.ts +0 -259
@@ -0,0 +1,322 @@
1
+ import {Name, UInt16, UInt32, UInt64} from '@wharfkit/antelope'
2
+ import {ServerContract} from '../contracts'
3
+ import {Coordinates, PRECISION, TaskType} from '../types'
4
+ import {
5
+ capsHasLoaders,
6
+ capsHasMovement,
7
+ capsHasStorage,
8
+ EntityCapabilities,
9
+ EntityState,
10
+ } from '../types/capabilities'
11
+ import {distanceBetweenCoordinates, lerp} from '../travel/travel'
12
+ import {calcCargoItemMass, calcCargoMass} from '../capabilities/storage'
13
+ import * as schedule from './schedule'
14
+ import {ScheduleData} from './schedule'
15
+
16
+ export interface ProjectedEntity {
17
+ location: Coordinates
18
+ energy: UInt16
19
+ cargoMass: UInt64
20
+ shipMass: UInt32
21
+ capacity?: UInt64
22
+ engines?: ServerContract.Types.movement_stats
23
+ loaders?: ServerContract.Types.loader_stats
24
+ generator?: ServerContract.Types.energy_stats
25
+ hauler?: ServerContract.Types.hauler_stats
26
+ readonly totalMass: UInt64
27
+
28
+ hasMovement(): boolean
29
+ hasStorage(): boolean
30
+ hasLoaders(): boolean
31
+
32
+ capabilities(): EntityCapabilities
33
+ state(): EntityState
34
+ }
35
+
36
+ export interface Projectable extends ScheduleData {
37
+ coordinates: Coordinates | ServerContract.Types.coordinates
38
+ energy?: UInt16
39
+ hullmass?: UInt32
40
+ generator?: ServerContract.Types.energy_stats
41
+ engines?: ServerContract.Types.movement_stats
42
+ loaders?: ServerContract.Types.loader_stats
43
+ hauler?: ServerContract.Types.hauler_stats
44
+ capacity?: UInt32
45
+ cargo: ServerContract.Types.cargo_item[]
46
+ cargomass: UInt32
47
+ owner?: Name
48
+ }
49
+
50
+ function getHullMass(entity: Projectable): UInt32 {
51
+ return UInt32.from(entity.hullmass ?? 0)
52
+ }
53
+
54
+ export function createProjectedEntity(entity: Projectable): ProjectedEntity {
55
+ const cargoMass = calcCargoMass(entity)
56
+ const shipMass = getHullMass(entity)
57
+ const loaders = entity.loaders
58
+ const engines = entity.engines
59
+ const generator = entity.generator
60
+ const hauler = entity.hauler
61
+ const capacity = entity.capacity
62
+
63
+ const projected: ProjectedEntity = {
64
+ location: Coordinates.from(entity.coordinates),
65
+ energy: UInt16.from(entity.energy ?? 0),
66
+ cargoMass,
67
+ shipMass,
68
+ capacity: capacity ? UInt64.from(capacity) : undefined,
69
+ engines,
70
+ generator,
71
+ hauler,
72
+ loaders,
73
+
74
+ get totalMass() {
75
+ let mass = UInt64.from(this.shipMass).adding(this.cargoMass)
76
+ if (this.loaders) {
77
+ mass = mass.adding(this.loaders.mass.multiplying(this.loaders.quantity))
78
+ }
79
+ return mass
80
+ },
81
+
82
+ hasMovement() {
83
+ return capsHasMovement(this.capabilities())
84
+ },
85
+
86
+ hasStorage() {
87
+ return capsHasStorage(this.capabilities())
88
+ },
89
+
90
+ hasLoaders() {
91
+ return capsHasLoaders(this.capabilities())
92
+ },
93
+
94
+ capabilities(): EntityCapabilities {
95
+ return {
96
+ hullmass: this.shipMass,
97
+ capacity: this.capacity ? UInt32.from(this.capacity) : undefined,
98
+ engines: this.engines,
99
+ generator: this.generator,
100
+ loaders: this.loaders,
101
+ }
102
+ },
103
+
104
+ state(): EntityState {
105
+ return {
106
+ owner: entity.owner ?? Name.from(''),
107
+ location: ServerContract.Types.coordinates.from(this.location),
108
+ energy: this.energy,
109
+ cargomass: UInt32.from(this.cargoMass),
110
+ cargo: entity.cargo,
111
+ }
112
+ },
113
+ }
114
+
115
+ return projected
116
+ }
117
+
118
+ function applyRechargeTask(
119
+ projected: ProjectedEntity,
120
+ _task: ServerContract.Types.task,
121
+ options: {complete: boolean; progress?: number}
122
+ ): void {
123
+ if (!projected.generator) return
124
+
125
+ if (options.complete) {
126
+ projected.energy = UInt16.from(projected.generator.capacity)
127
+ } else if (options.progress !== undefined) {
128
+ const capacity = Number(projected.generator.capacity)
129
+ const currentEnergy = Number(projected.energy)
130
+ const rechargeAmount = (capacity - currentEnergy) * options.progress
131
+ projected.energy = UInt16.from(Math.min(capacity, currentEnergy + rechargeAmount))
132
+ }
133
+ }
134
+
135
+ function applyFlightTask(
136
+ projected: ProjectedEntity,
137
+ task: ServerContract.Types.task,
138
+ options: {complete: boolean; progress?: number}
139
+ ): void {
140
+ if (!task.coordinates || !projected.engines) return
141
+
142
+ const origin = projected.location
143
+ const destination = Coordinates.from(task.coordinates)
144
+ const distance = distanceBetweenCoordinates(origin, task.coordinates)
145
+ const energyUsage = distance.dividing(PRECISION).multiplying(projected.engines.drain)
146
+
147
+ if (options.complete) {
148
+ projected.energy = projected.energy.gt(energyUsage)
149
+ ? UInt16.from(projected.energy.subtracting(energyUsage))
150
+ : UInt16.from(0)
151
+ projected.location = destination
152
+ } else if (options.progress !== undefined) {
153
+ const interpolated = lerp(origin, destination, options.progress)
154
+ projected.location = Coordinates.from({
155
+ x: Math.round(interpolated.x),
156
+ y: Math.round(interpolated.y),
157
+ })
158
+ const partialEnergy = UInt64.from(Math.floor(Number(energyUsage) * options.progress))
159
+ projected.energy = projected.energy.gt(partialEnergy)
160
+ ? UInt16.from(projected.energy.subtracting(partialEnergy))
161
+ : UInt16.from(0)
162
+ }
163
+ }
164
+
165
+ function applyLoadTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
166
+ for (const item of task.cargo) {
167
+ projected.cargoMass = projected.cargoMass.adding(calcCargoItemMass(item))
168
+ }
169
+ }
170
+
171
+ function applyUnloadTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
172
+ for (const item of task.cargo) {
173
+ const cargoMass = calcCargoItemMass(item)
174
+ projected.cargoMass = projected.cargoMass.gt(cargoMass)
175
+ ? projected.cargoMass.subtracting(cargoMass)
176
+ : UInt64.from(0)
177
+ }
178
+ }
179
+
180
+ function applyEnergyCost(projected: ProjectedEntity, task: ServerContract.Types.task): void {
181
+ if (!task.energy_cost) return
182
+ const energyCost = UInt16.from(task.energy_cost)
183
+ projected.energy = projected.energy.gt(energyCost)
184
+ ? UInt16.from(projected.energy.subtracting(energyCost))
185
+ : UInt16.from(0)
186
+ }
187
+
188
+ function applyExtractTask(
189
+ projected: ProjectedEntity,
190
+ task: ServerContract.Types.task,
191
+ options: {complete: boolean}
192
+ ): void {
193
+ if (!options.complete) return
194
+
195
+ applyEnergyCost(projected, task)
196
+
197
+ for (const item of task.cargo) {
198
+ projected.cargoMass = projected.cargoMass.adding(calcCargoItemMass(item))
199
+ }
200
+ }
201
+
202
+ function applyCraftTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
203
+ applyEnergyCost(projected, task)
204
+
205
+ if (task.cargo.length > 0) {
206
+ for (let i = 0; i < task.cargo.length - 1; i++) {
207
+ const inputMass = calcCargoItemMass(task.cargo[i])
208
+ projected.cargoMass = projected.cargoMass.gt(inputMass)
209
+ ? projected.cargoMass.subtracting(inputMass)
210
+ : UInt64.from(0)
211
+ }
212
+ const output = task.cargo[task.cargo.length - 1]
213
+ projected.cargoMass = projected.cargoMass.adding(calcCargoItemMass(output))
214
+ }
215
+ }
216
+
217
+ function applyDeployTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
218
+ applyEnergyCost(projected, task)
219
+
220
+ if (task.cargo.length > 0) {
221
+ const mass = calcCargoItemMass(task.cargo[0])
222
+ projected.cargoMass = projected.cargoMass.gt(mass)
223
+ ? projected.cargoMass.subtracting(mass)
224
+ : UInt64.from(0)
225
+ }
226
+ }
227
+
228
+ export function projectEntity(entity: Projectable): ProjectedEntity {
229
+ const projected = createProjectedEntity(entity)
230
+
231
+ if (!entity.schedule) {
232
+ return projected
233
+ }
234
+
235
+ for (const task of entity.schedule.tasks) {
236
+ switch (task.type.toNumber()) {
237
+ case TaskType.RECHARGE:
238
+ applyRechargeTask(projected, task, {complete: true})
239
+ break
240
+ case TaskType.TRAVEL:
241
+ applyFlightTask(projected, task, {complete: true})
242
+ break
243
+ case TaskType.LOAD:
244
+ applyLoadTask(projected, task)
245
+ break
246
+ case TaskType.UNLOAD:
247
+ applyUnloadTask(projected, task)
248
+ break
249
+ case TaskType.EXTRACT:
250
+ applyExtractTask(projected, task, {complete: true})
251
+ break
252
+ case TaskType.CRAFT:
253
+ applyCraftTask(projected, task)
254
+ break
255
+ case TaskType.DEPLOY:
256
+ case TaskType.DEPLOY_SHIP:
257
+ applyDeployTask(projected, task)
258
+ break
259
+ }
260
+ }
261
+
262
+ return projected
263
+ }
264
+
265
+ export function projectEntityAt(entity: Projectable, now: Date): ProjectedEntity {
266
+ const projected = createProjectedEntity(entity)
267
+
268
+ if (!entity.schedule || entity.schedule.tasks.length === 0) {
269
+ return projected
270
+ }
271
+
272
+ for (let i = 0; i < entity.schedule.tasks.length; i++) {
273
+ const task = entity.schedule.tasks[i]
274
+ const taskComplete = schedule.isTaskComplete(entity, i, now)
275
+ const taskInProgress = schedule.isTaskInProgress(entity, i, now)
276
+
277
+ if (!taskComplete && !taskInProgress) {
278
+ break
279
+ }
280
+
281
+ const progress = taskInProgress
282
+ ? schedule.getTaskElapsed(entity, i, now) / task.duration.toNumber()
283
+ : undefined
284
+
285
+ switch (task.type.toNumber()) {
286
+ case TaskType.RECHARGE:
287
+ applyRechargeTask(projected, task, {complete: taskComplete, progress})
288
+ break
289
+ case TaskType.TRAVEL:
290
+ applyFlightTask(projected, task, {complete: taskComplete, progress})
291
+ break
292
+ case TaskType.LOAD:
293
+ if (taskComplete) {
294
+ applyLoadTask(projected, task)
295
+ }
296
+ break
297
+ case TaskType.UNLOAD:
298
+ if (taskComplete) {
299
+ applyUnloadTask(projected, task)
300
+ }
301
+ break
302
+ case TaskType.EXTRACT:
303
+ if (taskComplete) {
304
+ applyExtractTask(projected, task, {complete: true})
305
+ }
306
+ break
307
+ case TaskType.CRAFT:
308
+ if (taskComplete) {
309
+ applyCraftTask(projected, task)
310
+ }
311
+ break
312
+ case TaskType.DEPLOY:
313
+ case TaskType.DEPLOY_SHIP:
314
+ if (taskComplete) {
315
+ applyDeployTask(projected, task)
316
+ }
317
+ break
318
+ }
319
+ }
320
+
321
+ return projected
322
+ }
@@ -0,0 +1,179 @@
1
+ import {ServerContract} from '../contracts'
2
+ import {TaskType} from '../types'
3
+
4
+ type Schedule = ServerContract.Types.schedule
5
+ type Task = ServerContract.Types.task
6
+
7
+ 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
29
+ }
30
+
31
+ export function hasSchedule(entity: ScheduleData): boolean {
32
+ return !!entity.schedule && entity.schedule.tasks.length > 0
33
+ }
34
+
35
+ export function isIdle(entity: ScheduleData): boolean {
36
+ return !hasSchedule(entity)
37
+ }
38
+
39
+ export function getTasks(entity: ScheduleData): Task[] {
40
+ return entity.schedule?.tasks || []
41
+ }
42
+
43
+ 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)
46
+ }
47
+
48
+ 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)
53
+ }
54
+
55
+ 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)
60
+ }
61
+
62
+ export function scheduleComplete(entity: ScheduleData, now: Date): boolean {
63
+ return hasSchedule(entity) && scheduleRemaining(entity, now) === 0
64
+ }
65
+
66
+ export function currentTaskIndex(entity: ScheduleData, now: Date): number {
67
+ if (!entity.schedule || entity.schedule.tasks.length === 0) return -1
68
+
69
+ const elapsed = scheduleElapsed(entity, now)
70
+ let timeAccum = 0
71
+
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
+ }
79
+
80
+ return entity.schedule.tasks.length - 1
81
+ }
82
+
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]
87
+ }
88
+
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
93
+ }
94
+
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()
100
+ }
101
+ return timeAccum
102
+ }
103
+
104
+ export function getTaskElapsed(entity: ScheduleData, index: number, now: Date): number {
105
+ if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length) return 0
106
+
107
+ const elapsed = scheduleElapsed(entity, now)
108
+ const taskStart = getTaskStartTime(entity, index)
109
+ const taskDuration = entity.schedule.tasks[index].duration.toNumber()
110
+
111
+ if (elapsed <= taskStart) return 0
112
+ const elapsedInTask = elapsed - taskStart
113
+ return Math.min(elapsedInTask, taskDuration)
114
+ }
115
+
116
+ export function getTaskRemaining(entity: ScheduleData, index: number, now: Date): number {
117
+ if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length) return 0
118
+
119
+ const taskDuration = entity.schedule.tasks[index].duration.toNumber()
120
+ const taskElapsed = getTaskElapsed(entity, index, now)
121
+ return Math.max(0, taskDuration - taskElapsed)
122
+ }
123
+
124
+ export function isTaskComplete(entity: ScheduleData, index: number, now: Date): boolean {
125
+ if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length) return false
126
+
127
+ const taskDuration = entity.schedule.tasks[index].duration.toNumber()
128
+ const taskElapsed = getTaskElapsed(entity, index, now)
129
+ return taskElapsed >= taskDuration
130
+ }
131
+
132
+ export function isTaskInProgress(entity: ScheduleData, index: number, now: Date): boolean {
133
+ if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length) return false
134
+
135
+ const taskElapsed = getTaskElapsed(entity, index, now)
136
+ const taskDuration = entity.schedule.tasks[index].duration.toNumber()
137
+ return taskElapsed > 0 && taskElapsed < taskDuration
138
+ }
139
+
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)
148
+ }
149
+
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)
155
+ }
156
+
157
+ export function isTaskType(entity: ScheduleData, taskType: TaskType, now: Date): boolean {
158
+ return currentTaskType(entity, now) === taskType
159
+ }
160
+
161
+ export function isInFlight(entity: ScheduleData, now: Date): boolean {
162
+ return isTaskType(entity, TaskType.TRAVEL, now)
163
+ }
164
+
165
+ export function isRecharging(entity: ScheduleData, now: Date): boolean {
166
+ return isTaskType(entity, TaskType.RECHARGE, now)
167
+ }
168
+
169
+ export function isLoading(entity: ScheduleData, now: Date): boolean {
170
+ return isTaskType(entity, TaskType.LOAD, now)
171
+ }
172
+
173
+ export function isUnloading(entity: ScheduleData, now: Date): boolean {
174
+ return isTaskType(entity, TaskType.UNLOAD, now)
175
+ }
176
+
177
+ export function isExtracting(entity: ScheduleData, now: Date): boolean {
178
+ return isTaskType(entity, TaskType.EXTRACT, now)
179
+ }