@shipload/sdk 2.0.0-rc11 → 2.0.0-rc13

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.
@@ -8,21 +8,30 @@ import {
8
8
  EntityCapabilities,
9
9
  EntityState,
10
10
  } from '../types/capabilities'
11
+ import {ENTITY_CAPACITY_EXCEEDED} from '../errors'
11
12
  import {distanceBetweenCoordinates, lerp} from '../travel/travel'
12
- import {calcCargoItemMass, calcCargoMass} from '../capabilities/storage'
13
+ import {
14
+ calcStacksMass,
15
+ cargoItemToStack,
16
+ CargoStack,
17
+ mergeStacks,
18
+ removeFromStacks,
19
+ stackToCargoItem,
20
+ } from '../capabilities/storage'
13
21
  import * as schedule from './schedule'
14
22
  import {ScheduleData} from './schedule'
15
23
 
16
24
  export interface ProjectedEntity {
17
25
  location: Coordinates
18
26
  energy: UInt16
19
- cargoMass: UInt64
27
+ cargo: CargoStack[]
20
28
  shipMass: UInt32
21
29
  capacity?: UInt64
22
30
  engines?: ServerContract.Types.movement_stats
23
31
  loaders?: ServerContract.Types.loader_stats
24
32
  generator?: ServerContract.Types.energy_stats
25
33
  hauler?: ServerContract.Types.hauler_stats
34
+ readonly cargoMass: UInt64
26
35
  readonly totalMass: UInt64
27
36
 
28
37
  hasMovement(): boolean
@@ -52,7 +61,6 @@ function getHullMass(entity: Projectable): UInt32 {
52
61
  }
53
62
 
54
63
  export function createProjectedEntity(entity: Projectable): ProjectedEntity {
55
- const cargoMass = calcCargoMass(entity)
56
64
  const shipMass = getHullMass(entity)
57
65
  const loaders = entity.loaders
58
66
  const engines = entity.engines
@@ -60,10 +68,12 @@ export function createProjectedEntity(entity: Projectable): ProjectedEntity {
60
68
  const hauler = entity.hauler
61
69
  const capacity = entity.capacity
62
70
 
71
+ const cargo: CargoStack[] = entity.cargo.map(cargoItemToStack)
72
+
63
73
  const projected: ProjectedEntity = {
64
74
  location: Coordinates.from(entity.coordinates),
65
75
  energy: UInt16.from(entity.energy ?? 0),
66
- cargoMass,
76
+ cargo,
67
77
  shipMass,
68
78
  capacity: capacity ? UInt64.from(capacity) : undefined,
69
79
  engines,
@@ -71,6 +81,10 @@ export function createProjectedEntity(entity: Projectable): ProjectedEntity {
71
81
  hauler,
72
82
  loaders,
73
83
 
84
+ get cargoMass() {
85
+ return calcStacksMass(this.cargo)
86
+ },
87
+
74
88
  get totalMass() {
75
89
  let mass = UInt64.from(this.shipMass).adding(this.cargoMass)
76
90
  if (this.loaders) {
@@ -107,7 +121,7 @@ export function createProjectedEntity(entity: Projectable): ProjectedEntity {
107
121
  location: ServerContract.Types.coordinates.from(this.location),
108
122
  energy: this.energy,
109
123
  cargomass: UInt32.from(this.cargoMass),
110
- cargo: entity.cargo,
124
+ cargo: this.cargo.map(stackToCargoItem),
111
125
  }
112
126
  },
113
127
  }
@@ -162,18 +176,23 @@ function applyFlightTask(
162
176
  }
163
177
  }
164
178
 
165
- function applyLoadTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
179
+ function addCargoItem(projected: ProjectedEntity, item: ServerContract.Types.cargo_item): void {
180
+ projected.cargo = mergeStacks(projected.cargo, cargoItemToStack(item))
181
+ }
182
+
183
+ function removeCargoItem(projected: ProjectedEntity, item: ServerContract.Types.cargo_item): void {
184
+ projected.cargo = removeFromStacks(projected.cargo, cargoItemToStack(item))
185
+ }
186
+
187
+ function applyAddCargoTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
166
188
  for (const item of task.cargo) {
167
- projected.cargoMass = projected.cargoMass.adding(calcCargoItemMass(item))
189
+ addCargoItem(projected, item)
168
190
  }
169
191
  }
170
192
 
171
- function applyUnloadTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
193
+ function applyRemoveCargoTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
172
194
  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)
195
+ removeCargoItem(projected, item)
177
196
  }
178
197
  }
179
198
 
@@ -191,75 +210,85 @@ function applyGatherTask(
191
210
  options: {complete: boolean}
192
211
  ): void {
193
212
  if (!options.complete) return
194
-
195
213
  applyEnergyCost(projected, task)
196
-
197
- for (const item of task.cargo) {
198
- projected.cargoMass = projected.cargoMass.adding(calcCargoItemMass(item))
199
- }
214
+ applyAddCargoTask(projected, task)
200
215
  }
201
216
 
202
217
  function applyCraftTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
203
218
  applyEnergyCost(projected, task)
219
+ if (task.cargo.length === 0) return
204
220
 
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))
221
+ for (let i = 0; i < task.cargo.length - 1; i++) {
222
+ removeCargoItem(projected, task.cargo[i])
214
223
  }
224
+ addCargoItem(projected, task.cargo[task.cargo.length - 1])
215
225
  }
216
226
 
217
227
  function applyDeployTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
218
228
  applyEnergyCost(projected, task)
219
-
220
229
  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)
230
+ removeCargoItem(projected, task.cargo[0])
231
+ }
232
+ }
233
+
234
+ function applyTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
235
+ switch (task.type.toNumber()) {
236
+ case TaskType.RECHARGE:
237
+ applyRechargeTask(projected, task, {complete: true})
238
+ break
239
+ case TaskType.TRAVEL:
240
+ applyFlightTask(projected, task, {complete: true})
241
+ break
242
+ case TaskType.LOAD:
243
+ case TaskType.UNWRAP:
244
+ applyAddCargoTask(projected, task)
245
+ break
246
+ case TaskType.UNLOAD:
247
+ case TaskType.WRAP:
248
+ applyRemoveCargoTask(projected, task)
249
+ break
250
+ case TaskType.GATHER:
251
+ applyGatherTask(projected, task, {complete: true})
252
+ break
253
+ case TaskType.CRAFT:
254
+ applyCraftTask(projected, task)
255
+ break
256
+ case TaskType.DEPLOY:
257
+ applyDeployTask(projected, task)
258
+ break
225
259
  }
226
260
  }
227
261
 
228
- export function projectEntity(entity: Projectable): ProjectedEntity {
262
+ export interface ProjectionOptions {
263
+ upToTaskIndex?: number
264
+ }
265
+
266
+ export function projectEntity(entity: Projectable, options?: ProjectionOptions): ProjectedEntity {
229
267
  const projected = createProjectedEntity(entity)
268
+ if (!entity.schedule || entity.schedule.tasks.length === 0) return projected
230
269
 
231
- if (!entity.schedule) {
232
- return projected
270
+ const tasks = entity.schedule.tasks
271
+ const taskCount =
272
+ options?.upToTaskIndex !== undefined
273
+ ? Math.max(0, Math.min(options.upToTaskIndex, tasks.length))
274
+ : tasks.length
275
+
276
+ for (let i = 0; i < taskCount; i++) {
277
+ applyTask(projected, tasks[i])
233
278
  }
279
+ return projected
280
+ }
281
+
282
+ export function validateSchedule(entity: Projectable): void {
283
+ if (!entity.schedule || entity.schedule.tasks.length === 0) return
234
284
 
285
+ const projected = createProjectedEntity(entity)
235
286
  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.GATHER:
250
- applyGatherTask(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
287
+ applyTask(projected, task)
288
+ if (projected.capacity && projected.cargoMass.gt(projected.capacity)) {
289
+ throw new Error(ENTITY_CAPACITY_EXCEEDED)
259
290
  }
260
291
  }
261
-
262
- return projected
263
292
  }
264
293
 
265
294
  export function projectEntityAt(entity: Projectable, now: Date): ProjectedEntity {
@@ -290,30 +319,21 @@ export function projectEntityAt(entity: Projectable, now: Date): ProjectedEntity
290
319
  applyFlightTask(projected, task, {complete: taskComplete, progress})
291
320
  break
292
321
  case TaskType.LOAD:
293
- if (taskComplete) {
294
- applyLoadTask(projected, task)
295
- }
322
+ case TaskType.UNWRAP:
323
+ if (taskComplete) applyAddCargoTask(projected, task)
296
324
  break
297
325
  case TaskType.UNLOAD:
298
- if (taskComplete) {
299
- applyUnloadTask(projected, task)
300
- }
326
+ case TaskType.WRAP:
327
+ if (taskComplete) applyRemoveCargoTask(projected, task)
301
328
  break
302
329
  case TaskType.GATHER:
303
- if (taskComplete) {
304
- applyGatherTask(projected, task, {complete: true})
305
- }
330
+ if (taskComplete) applyGatherTask(projected, task, {complete: true})
306
331
  break
307
332
  case TaskType.CRAFT:
308
- if (taskComplete) {
309
- applyCraftTask(projected, task)
310
- }
333
+ if (taskComplete) applyCraftTask(projected, task)
311
334
  break
312
335
  case TaskType.DEPLOY:
313
- case TaskType.DEPLOY_SHIP:
314
- if (taskComplete) {
315
- applyDeployTask(projected, task)
316
- }
336
+ if (taskComplete) applyDeployTask(projected, task)
317
337
  break
318
338
  }
319
339
  }
package/src/types.ts CHANGED
@@ -53,7 +53,8 @@ export enum TaskType {
53
53
  WARP = 6,
54
54
  CRAFT = 7,
55
55
  DEPLOY = 8,
56
- DEPLOY_SHIP = 9,
56
+ WRAP = 9,
57
+ UNWRAP = 10,
57
58
  }
58
59
 
59
60
  export enum LocationType {
@@ -36,10 +36,14 @@ export function isGatherableLocation(locationType: LocationType): boolean {
36
36
 
37
37
  export function getLocationTypeName(type: LocationType): string {
38
38
  switch (type) {
39
- case LocationType.EMPTY: return 'Empty'
40
- case LocationType.PLANET: return 'Planet'
41
- case LocationType.ASTEROID: return 'Asteroid'
42
- case LocationType.NEBULA: return 'Nebula'
39
+ case LocationType.EMPTY:
40
+ return 'Empty'
41
+ case LocationType.PLANET:
42
+ return 'Planet'
43
+ case LocationType.ASTEROID:
44
+ return 'Asteroid'
45
+ case LocationType.NEBULA:
46
+ return 'Nebula'
43
47
  }
44
48
  }
45
49