@shipload/sdk 1.0.0-next.69 → 1.0.0-next.70

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.
@@ -20,7 +20,7 @@ import {
20
20
  popcount5,
21
21
  } from './demand'
22
22
  import {findDecomp, DECOMP_REGISTRY} from './decomp'
23
- import {depotTransferDuration, contributeDuration} from './duration'
23
+ import {civicDropoffDuration, depotTransferDuration, contributeDuration} from './duration'
24
24
  import {getStatCount, statsSumSq} from './quality'
25
25
  import {pricingFromWeights, valueCargoItem, valueContribution} from './valuation'
26
26
  import {citizenryName, citizenryPatternCount} from './citizenry'
@@ -382,3 +382,69 @@ describe('depot transfer duration', () => {
382
382
  expect(depotTransferDuration(params({cargoMass: 1}))).toBeGreaterThanOrEqual(1)
383
383
  })
384
384
  })
385
+
386
+ describe('civic drop-off duration', () => {
387
+ type ModuleEntry = ServerContract.Types.module_entry
388
+ const DEPOT_ITEM = 10219
389
+ const WORKSHOP_ITEM = 10208
390
+ const LOADER_T1 = 10103
391
+
392
+ function makeModuleEntry(itemId: number, stats: bigint): ModuleEntry {
393
+ return {
394
+ type: UInt8.from(0),
395
+ installed: {item_id: UInt16.from(itemId), stats: UInt64.from(stats)},
396
+ } as unknown as ModuleEntry
397
+ }
398
+ function emptySlot(): ModuleEntry {
399
+ return {type: UInt8.from(0)} as unknown as ModuleEntry
400
+ }
401
+
402
+ const withLoader = () => ({
403
+ buildingModules: [makeModuleEntry(LOADER_T1, packStats(500)), emptySlot()],
404
+ buildingItemId: DEPOT_ITEM,
405
+ buildingKind: 'depot',
406
+ buildingZ: 0,
407
+ shipKind: 'ship',
408
+ shipZ: 400,
409
+ cargoMass: 100,
410
+ })
411
+ const withoutLoader = () => ({
412
+ buildingModules: [] as ModuleEntry[],
413
+ buildingItemId: WORKSHOP_ITEM,
414
+ buildingKind: 'workshop',
415
+ buildingZ: 0,
416
+ shipKind: 'ship',
417
+ shipZ: 400,
418
+ cargoMass: 100,
419
+ })
420
+
421
+ test('a building with a slot-0 loader prices off that loader', () => {
422
+ const p = withLoader()
423
+ expect(civicDropoffDuration(p)).toBe(
424
+ depotTransferDuration({
425
+ depotModules: p.buildingModules,
426
+ depotItemId: p.buildingItemId,
427
+ depotKind: p.buildingKind,
428
+ depotZ: p.buildingZ,
429
+ shipKind: p.shipKind,
430
+ shipZ: p.shipZ,
431
+ cargoMass: p.cargoMass,
432
+ })
433
+ )
434
+ })
435
+
436
+ test('a building with no loader falls back to the civic loader', () => {
437
+ const p = withoutLoader()
438
+ expect(civicDropoffDuration(p)).toBe(contributeDuration(p.cargoMass, p.shipZ))
439
+ expect(civicDropoffDuration(p)).toBeGreaterThan(0)
440
+ })
441
+
442
+ test('grows with cargo mass on both paths', () => {
443
+ expect(civicDropoffDuration({...withLoader(), cargoMass: 10_000})).toBeGreaterThan(
444
+ civicDropoffDuration(withLoader())
445
+ )
446
+ expect(civicDropoffDuration({...withoutLoader(), cargoMass: 10_000})).toBeGreaterThan(
447
+ civicDropoffDuration(withoutLoader())
448
+ )
449
+ })
450
+ })
@@ -562,14 +562,6 @@ export class ActionsManager extends BaseManager {
562
562
  return this.server.action('claimcraft', params)
563
563
  }
564
564
 
565
- cancelcraft(jobId: UInt64Type, shipId: UInt64Type): Action {
566
- const params: ServerContract.ActionParams.cancelcraft = {
567
- job_id: UInt64.from(jobId),
568
- ship_id: UInt64.from(shipId),
569
- }
570
- return this.server.action('cancelcraft', params)
571
- }
572
-
573
565
  buildjob(
574
566
  targetId: UInt64Type,
575
567
  dockId: UInt64Type,
@@ -15,7 +15,7 @@ const row = (over: Record<string, unknown> = {}) => ({
15
15
  recipe_id: {toNumber: () => 10001},
16
16
  quantity: {toNumber: () => 5},
17
17
  energy_paid: {toNumber: () => 0},
18
- cargo: [{item: 'in'}, {item: 'out'}],
18
+ cargo: [{item: 'out'}],
19
19
  ...over,
20
20
  })
21
21
 
@@ -26,7 +26,7 @@ function managerWith(queryImpl: () => Promise<unknown[]>, allImpl: () => Promise
26
26
  }
27
27
 
28
28
  describe('JobsManager.getOwnedJobs', () => {
29
- it('parses owner rows: output = last cargo, inputs = rest, status derived', async () => {
29
+ it('parses a landed row: cargo is the output, no inputs, status derived', async () => {
30
30
  const m = managerWith(
31
31
  async () => [row()],
32
32
  async () => []
@@ -36,6 +36,24 @@ describe('JobsManager.getOwnedJobs', () => {
36
36
  expect(jobs[0]).toMatchObject({id: 7, building: 42, quantity: 5, status: 'ready'})
37
37
  expect(jobs[0].coords).toEqual({x: 12, y: 34})
38
38
  expect(jobs[0].output).toEqual({item: 'out'} as never)
39
+ expect(jobs[0].inputs).toEqual([] as never)
40
+ })
41
+
42
+ it('reports a job In Line rather than ready, whatever its zero window says', async () => {
43
+ const inLine = row({
44
+ starts_at: {toDate: () => new Date(0)},
45
+ completes_at: {toDate: () => new Date(0)},
46
+ deposited: false,
47
+ cargo: [{item: 'in'}],
48
+ })
49
+ const m = managerWith(
50
+ async () => [inLine],
51
+ async () => []
52
+ )
53
+ const jobs = await m.getOwnedJobs(OWNER, {now: new Date('2026-07-26T11:30:00Z')})
54
+ expect(jobs[0].status).toBe('inline')
55
+ expect(jobs[0].deposited).toBe(false)
56
+ expect(jobs[0].output).toBeNull()
39
57
  expect(jobs[0].inputs).toEqual([{item: 'in'}] as never)
40
58
  })
41
59
 
@@ -1,6 +1,6 @@
1
1
  import {Name, type NameType} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
- import {jobStatus, splitJobCargo, type OwnedJob} from '../scheduling/jobs'
3
+ import {jobDeposited, jobStatus, splitJobCargo, type OwnedJob} from '../scheduling/jobs'
4
4
  import type {ServerContract} from '../contracts'
5
5
 
6
6
  type JobRow = ServerContract.Types.craftjob_row
@@ -32,7 +32,8 @@ export class JobsManager extends BaseManager {
32
32
  private parseOwnedJob(r: JobRow, now: Date): OwnedJob {
33
33
  const startsAt = r.starts_at.toDate()
34
34
  const completesAt = r.completes_at.toDate()
35
- const {output, inputs} = splitJobCargo(r.cargo)
35
+ const deposited = jobDeposited(r.deposited)
36
+ const {output, inputs} = splitJobCargo(r.cargo, deposited)
36
37
  return {
37
38
  id: r.id.toNumber(),
38
39
  building: r.building.toNumber(),
@@ -43,7 +44,8 @@ export class JobsManager extends BaseManager {
43
44
  completesAt,
44
45
  recipeId: r.recipe_id.toNumber(),
45
46
  quantity: r.quantity.toNumber(),
46
- status: jobStatus({startsAt, completesAt}, now),
47
+ status: jobStatus({startsAt, completesAt, deposited}, now),
48
+ deposited,
47
49
  output,
48
50
  inputs,
49
51
  outputStats: output?.stats === undefined ? undefined : BigInt(output.stats.toString()),
@@ -0,0 +1,22 @@
1
+ import {Serializer} from '@wharfkit/antelope'
2
+ import {ServerContract} from './contracts'
3
+
4
+ export type BookingReceipt = ServerContract.Types.booking_receipt
5
+
6
+ export function decodeBookingReceipt(data: unknown): BookingReceipt {
7
+ if (data === null || data === undefined) {
8
+ throw new Error('decodeBookingReceipt: no return value')
9
+ }
10
+ if (data instanceof Uint8Array || typeof data === 'string') {
11
+ return Serializer.decode({data, type: ServerContract.Types.booking_receipt})
12
+ }
13
+ return ServerContract.Types.booking_receipt.from(data as ServerContract.Types.booking_receipt)
14
+ }
15
+
16
+ export function bookingReceiptLandsAtMs(receipt: BookingReceipt): number {
17
+ return receipt.lands_at.toMilliseconds()
18
+ }
19
+
20
+ export function bookingReceiptRuntimeSeconds(receipt: BookingReceipt): number {
21
+ return Number(receipt.runtime)
22
+ }
@@ -223,13 +223,13 @@ describe('taskCargoEffect task coverage', () => {
223
223
  })
224
224
 
225
225
  test('a depot store removes its cargo', () => {
226
- const effect = taskCargoEffect(simpleTask(TaskType.DEPOT_STORE))
226
+ const effect = taskCargoEffect(simpleTask(TaskType.CIVIC_DEPOSIT))
227
227
  expect(effect.removed).toHaveLength(1)
228
228
  expect(effect.added).toHaveLength(0)
229
229
  })
230
230
 
231
231
  test('a depot take adds its cargo', () => {
232
- const effect = taskCargoEffect(simpleTask(TaskType.DEPOT_TAKE))
232
+ const effect = taskCargoEffect(simpleTask(TaskType.CIVIC_WITHDRAW))
233
233
  expect(effect.added).toHaveLength(1)
234
234
  expect(effect.removed).toHaveLength(0)
235
235
  })
@@ -1,5 +1,5 @@
1
1
  import {describe, expect, it} from 'bun:test'
2
- import {jobStatus, splitJobCargo} from './jobs'
2
+ import {jobStatus, jobStatusLabel, splitJobCargo} from './jobs'
3
3
 
4
4
  const at = (s: string) => new Date(s)
5
5
 
@@ -15,18 +15,35 @@ describe('jobStatus', () => {
15
15
  expect(jobStatus(job, at('2026-07-26T11:00:00Z'))).toBe('ready')
16
16
  expect(jobStatus(job, at('2026-07-26T12:00:00Z'))).toBe('ready')
17
17
  })
18
+ it('is inline while the drop-off is still in the air', () => {
19
+ const booked = {
20
+ startsAt: at('1970-01-01T00:00:00Z'),
21
+ completesAt: at('1970-01-01T00:00:00Z'),
22
+ }
23
+ expect(jobStatus({...booked, deposited: false}, at('2026-07-26T10:00:00Z'))).toBe('inline')
24
+ expect(jobStatus({...job, deposited: true}, at('2026-07-26T10:30:00Z'))).toBe('crafting')
25
+ })
26
+ it('labels every state', () => {
27
+ expect(jobStatusLabel('inline')).toBe('In Line')
28
+ expect(jobStatusLabel('ready')).toBe('Ready for Pickup')
29
+ })
18
30
  })
19
31
 
20
32
  describe('splitJobCargo', () => {
21
- it('takes the last element as output, the rest as inputs', () => {
22
- const cargo = [{n: 'a'}, {n: 'b'}, {n: 'out'}] as unknown as Parameters<
23
- typeof splitJobCargo
24
- >[0]
25
- const {output, inputs} = splitJobCargo(cargo)
26
- expect(output).toEqual({n: 'out'} as never)
33
+ it('reads an In Line row as inputs with no output', () => {
34
+ const cargo = [{n: 'a'}, {n: 'b'}] as unknown as Parameters<typeof splitJobCargo>[0]
35
+ const {output, inputs} = splitJobCargo(cargo, false)
36
+ expect(output).toBeNull()
27
37
  expect(inputs).toEqual([{n: 'a'}, {n: 'b'}] as never)
28
38
  })
39
+ it('reads a landed row as the output with no inputs', () => {
40
+ const cargo = [{n: 'out'}] as unknown as Parameters<typeof splitJobCargo>[0]
41
+ const {output, inputs} = splitJobCargo(cargo, true)
42
+ expect(output).toEqual({n: 'out'} as never)
43
+ expect(inputs).toEqual([] as never)
44
+ })
29
45
  it('returns null output for empty cargo', () => {
30
- expect(splitJobCargo([])).toEqual({output: null, inputs: []})
46
+ expect(splitJobCargo([], true)).toEqual({output: null, inputs: []})
47
+ expect(splitJobCargo([], false)).toEqual({output: null, inputs: []})
31
48
  })
32
49
  })
@@ -10,6 +10,8 @@ export interface JobWindow {
10
10
  completesAt: Date
11
11
  recipeId: number
12
12
  quantity: number
13
+ /** False while the job is In Line: booked, with its inputs still in transit to the building. */
14
+ deposited: boolean
13
15
  /** Packed stat roll of the job's output, when the source carried the job's cargo. */
14
16
  outputStats?: bigint
15
17
  }
@@ -76,18 +78,44 @@ export function pickFabricator(
76
78
  return best
77
79
  }
78
80
 
79
- export type JobStatus = 'waiting' | 'crafting' | 'ready'
81
+ export type JobStatus = 'inline' | 'waiting' | 'crafting' | 'ready'
80
82
 
81
- export function jobStatus(job: {startsAt: Date; completesAt: Date}, now: Date): JobStatus {
83
+ // A job In Line has no window yet, so the window alone would read it as long since ready.
84
+ export function jobStatus(
85
+ job: {startsAt: Date; completesAt: Date; deposited?: boolean},
86
+ now: Date
87
+ ): JobStatus {
88
+ if (job.deposited === false) return 'inline'
82
89
  if (now < job.startsAt) return 'waiting'
83
90
  if (now < job.completesAt) return 'crafting'
84
91
  return 'ready'
85
92
  }
86
93
 
87
- // Generic in the element so raw chain JSON (readonly actions) splits by the same rule as decoded rows.
88
- export function splitJobCargo<T>(cargo: readonly T[]): {output: T | null; inputs: T[]} {
94
+ const JOB_STATUS_LABELS: Record<JobStatus, string> = {
95
+ inline: 'In Line',
96
+ waiting: 'Waiting',
97
+ crafting: 'Crafting',
98
+ ready: 'Ready for Pickup',
99
+ }
100
+
101
+ export function jobStatusLabel(status: JobStatus): string {
102
+ return JOB_STATUS_LABELS[status]
103
+ }
104
+
105
+ // A row written before the deposited flag existed reads as undefined; those jobs were all deposited.
106
+ export function jobDeposited(value: unknown): boolean {
107
+ if (value === undefined || value === null) return true
108
+ return Boolean(value)
109
+ }
110
+
111
+ // A job row holds the inputs while In Line and the output once its drop-off has landed.
112
+ export function splitJobCargo<T>(
113
+ cargo: readonly T[],
114
+ deposited: boolean
115
+ ): {output: T | null; inputs: T[]} {
89
116
  if (cargo.length === 0) return {output: null, inputs: []}
90
- return {output: cargo[cargo.length - 1], inputs: cargo.slice(0, -1)}
117
+ if (!deposited) return {output: null, inputs: [...cargo]}
118
+ return {output: cargo[0], inputs: []}
91
119
  }
92
120
 
93
121
  export interface OwnedJob {
@@ -101,6 +129,7 @@ export interface OwnedJob {
101
129
  recipeId: number
102
130
  quantity: number
103
131
  status: JobStatus
132
+ deposited: boolean
104
133
  output: CargoItem | null
105
134
  inputs: CargoItem[]
106
135
  /** Packed stat roll of `output`, so every job shape answers this the same way. */
@@ -405,9 +405,19 @@ function applyTask(projected: ProjectedEntity, task: ServerContract.Types.task):
405
405
  break
406
406
  case TaskType.LOAD:
407
407
  case TaskType.UNWRAP:
408
+ case TaskType.CIVIC_WITHDRAW:
408
409
  applyAddCargoTask(projected, task)
409
410
  break
410
411
  case TaskType.UNLOAD:
412
+ case TaskType.CONTRIBUTE:
413
+ applyRemoveCargoTask(projected, task)
414
+ break
415
+ case TaskType.CIVIC_DEPOSIT:
416
+ applyEnergyCost(projected, task)
417
+ applyRemoveCargoTask(projected, task)
418
+ break
419
+ case TaskType.UPGRADE:
420
+ applyEnergyCost(projected, task)
411
421
  applyRemoveCargoTask(projected, task)
412
422
  break
413
423
  case TaskType.GATHER:
@@ -417,6 +427,8 @@ function applyTask(projected: ProjectedEntity, task: ServerContract.Types.task):
417
427
  applyCraftTask(projected, task)
418
428
  break
419
429
  case TaskType.UNDEPLOY:
430
+ applyAddCargoTask(projected, task)
431
+ break
420
432
  case TaskType.DEMOLISH:
421
433
  break
422
434
  }
@@ -426,16 +438,8 @@ export interface ProjectionOptions {
426
438
  upToTaskIndex?: number
427
439
  }
428
440
 
429
- // Mirrors the contract's completed_task_count_at: inclusive at the anchor.
430
441
  function anchoredSkipCount(entity: Projectable, ordered: readonly schedule.OrderedTask[]): number {
431
- const anchor = entity.projected_at
432
- if (anchor === undefined) return 0
433
- const anchorMs = Number(anchor.toMilliseconds())
434
- let count = 0
435
- for (const {completesAt} of ordered) {
436
- if (completesAt.getTime() <= anchorMs) count++
437
- }
438
- return count
442
+ return schedule.appliedTaskCount(entity, ordered)
439
443
  }
440
444
 
441
445
  export function projectEntity(entity: Projectable, options?: ProjectionOptions): ProjectedEntity {
@@ -573,21 +577,8 @@ export function projectEntityAt(entity: Projectable, now: Date): ProjectedEntity
573
577
  case TaskType.TRANSIT:
574
578
  applyFlightTask(projected, task, {complete: taskComplete, progress})
575
579
  break
576
- case TaskType.LOAD:
577
- case TaskType.UNWRAP:
578
- if (taskComplete) applyAddCargoTask(projected, task)
579
- break
580
- case TaskType.UNLOAD:
581
- if (taskComplete) applyRemoveCargoTask(projected, task)
582
- break
583
- case TaskType.GATHER:
584
- if (taskComplete) applyGatherTask(projected, task, {complete: true})
585
- break
586
- case TaskType.CRAFT:
587
- if (taskComplete) applyCraftTask(projected, task)
588
- break
589
- case TaskType.UNDEPLOY:
590
- case TaskType.DEMOLISH:
580
+ default:
581
+ if (taskComplete) applyTask(projected, task)
591
582
  break
592
583
  }
593
584
  }
@@ -1,6 +1,13 @@
1
1
  import {describe, expect, test} from 'bun:test'
2
2
  import {ServerContract, TaskType} from '../index-module'
3
- import {hasPendingCapper, hasResolvable, isCapperTaskType} from './schedule'
3
+ import {
4
+ appliedTaskCount,
5
+ hasPendingCapper,
6
+ hasResolvable,
7
+ isCapperTaskType,
8
+ orderedTasks,
9
+ unappliedTasks,
10
+ } from './schedule'
4
11
 
5
12
  const T0 = '2026-06-19T00:00:00'
6
13
  const NOW = new Date('2026-06-19T00:01:00.000Z')
@@ -118,3 +125,39 @@ describe('hasResolvable — capper gating', () => {
118
125
  expect(hasResolvable(e, NOW)).toBe(false)
119
126
  })
120
127
  })
128
+
129
+ function anchoredEntity(anchorISO: string) {
130
+ const e = entity([
131
+ task({type: TaskType.TRAVEL, duration: 30}),
132
+ task({type: TaskType.TRAVEL, duration: 30}),
133
+ task({type: TaskType.TRAVEL, duration: 30}),
134
+ ])
135
+ return ServerContract.Types.entity_info.from({
136
+ ...ServerContract.Types.entity_info.from(e),
137
+ projected_at: anchorISO,
138
+ })
139
+ }
140
+
141
+ describe('appliedTaskCount / unappliedTasks', () => {
142
+ test('no anchor leaves every task unapplied', () => {
143
+ const e = entity([task({duration: 30}), task({duration: 30})])
144
+ expect(appliedTaskCount({lanes: e.lanes}, orderedTasks(e))).toBe(0)
145
+ expect(unappliedTasks({lanes: e.lanes})).toHaveLength(2)
146
+ })
147
+
148
+ test('tasks completed at or before the anchor are already applied', () => {
149
+ const e = anchoredEntity('2026-06-19T00:01:00')
150
+ expect(appliedTaskCount(e, orderedTasks(e))).toBe(2)
151
+ expect(unappliedTasks(e)).toHaveLength(1)
152
+ })
153
+
154
+ test('the anchor is inclusive, mirroring completed_task_count_at', () => {
155
+ const e = anchoredEntity('2026-06-19T00:00:30')
156
+ expect(appliedTaskCount(e, orderedTasks(e))).toBe(1)
157
+ })
158
+
159
+ test('a whole schedule finished before the anchor leaves nothing unapplied', () => {
160
+ const e = anchoredEntity('2026-06-19T12:00:00')
161
+ expect(unappliedTasks(e)).toHaveLength(0)
162
+ })
163
+ })
@@ -1,3 +1,4 @@
1
+ import type {TimePoint} from '@wharfkit/antelope'
1
2
  import type {ServerContract} from '../contracts'
2
3
  import {TaskType} from '../types'
3
4
  import * as core from './lane-core'
@@ -15,6 +16,10 @@ export interface ScheduleData {
15
16
  holds?: Hold[]
16
17
  }
17
18
 
19
+ export interface AnchoredScheduleData extends ScheduleData {
20
+ projected_at?: TimePoint
21
+ }
22
+
18
23
  export interface LaneView {
19
24
  laneKey: number
20
25
  schedule: Schedule
@@ -240,6 +245,27 @@ export function orderedTasks(entity: ScheduleData): OrderedTask[] {
240
245
  return out
241
246
  }
242
247
 
248
+ // Mirrors the contract's completed_task_count_at: inclusive at the anchor.
249
+ export function appliedTaskCount(
250
+ entity: AnchoredScheduleData,
251
+ ordered: readonly OrderedTask[]
252
+ ): number {
253
+ const anchor = entity.projected_at
254
+ if (anchor === undefined) return 0
255
+ const anchorMs = Number(anchor.toMilliseconds())
256
+ let count = 0
257
+ for (const {completesAt} of ordered) {
258
+ if (completesAt.getTime() <= anchorMs) count++
259
+ }
260
+ return count
261
+ }
262
+
263
+ // Tasks an entity_info snapshot has NOT yet folded into its cargo and state.
264
+ export function unappliedTasks(entity: AnchoredScheduleData): OrderedTask[] {
265
+ const ordered = orderedTasks(entity)
266
+ return ordered.slice(appliedTaskCount(entity, ordered))
267
+ }
268
+
243
269
  export function laneRemainingOf(entity: ScheduleData, laneKey: number, now: Date): number {
244
270
  const lane = getLane(entity, laneKey)
245
271
  return lane ? core.laneRemaining(lane.schedule, now) : 0
@@ -44,9 +44,14 @@ describe('taskCargoChanges', () => {
44
44
  })
45
45
 
46
46
  describe('TaskType', () => {
47
- test('covers the depot task types the contract defines', () => {
48
- expect(TaskType.DEPOT_STORE).toBe(21)
49
- expect(TaskType.DEPOT_TAKE).toBe(22)
47
+ test('covers the civic transfer task types the contract defines', () => {
48
+ expect(TaskType.CIVIC_DEPOSIT).toBe(21)
49
+ expect(TaskType.CIVIC_WITHDRAW).toBe(22)
50
+ })
51
+
52
+ test('keeps the former depot names as aliases of the civic transfer types', () => {
53
+ expect(TaskType.DEPOT_STORE).toBe(TaskType.CIVIC_DEPOSIT)
54
+ expect(TaskType.DEPOT_TAKE).toBe(TaskType.CIVIC_WITHDRAW)
50
55
  })
51
56
  })
52
57
 
@@ -62,13 +67,13 @@ function simpleTask(type: number) {
62
67
 
63
68
  describe('taskCargoChanges task coverage', () => {
64
69
  test('a depot store moves cargo out of the entity', () => {
65
- const changes = taskCargoChanges(simpleTask(TaskType.DEPOT_STORE))
70
+ const changes = taskCargoChanges(simpleTask(TaskType.CIVIC_DEPOSIT))
66
71
  expect(changes).toHaveLength(1)
67
72
  expect(changes[0].direction).toBe('out')
68
73
  })
69
74
 
70
75
  test('a depot take moves cargo into the entity', () => {
71
- const changes = taskCargoChanges(simpleTask(TaskType.DEPOT_TAKE))
76
+ const changes = taskCargoChanges(simpleTask(TaskType.CIVIC_WITHDRAW))
72
77
  expect(changes).toHaveLength(1)
73
78
  expect(changes[0].direction).toBe('in')
74
79
  })
@@ -88,7 +93,7 @@ describe('taskCargoChanges task coverage', () => {
88
93
 
89
94
  describe('taskCargoChangesChecked', () => {
90
95
  test('reports a known task type with its changes', () => {
91
- const result = taskCargoChangesChecked(simpleTask(TaskType.DEPOT_TAKE))
96
+ const result = taskCargoChangesChecked(simpleTask(TaskType.CIVIC_WITHDRAW))
92
97
  expect(result.known).toBe(true)
93
98
  if (result.known) expect(result.changes[0].direction).toBe('in')
94
99
  })
@@ -7,13 +7,13 @@ describe('taskCargoRule', () => {
7
7
  expect(taskCargoRule(TaskType.UNLOAD)).toBe('all-out')
8
8
  expect(taskCargoRule(TaskType.UPGRADE)).toBe('all-out')
9
9
  expect(taskCargoRule(TaskType.CONTRIBUTE)).toBe('all-out')
10
- expect(taskCargoRule(TaskType.DEPOT_STORE)).toBe('all-out')
10
+ expect(taskCargoRule(TaskType.CIVIC_DEPOSIT)).toBe('all-out')
11
11
  })
12
12
 
13
13
  test('maps the task types that move cargo into the entity', () => {
14
14
  expect(taskCargoRule(TaskType.LOAD)).toBe('all-in')
15
15
  expect(taskCargoRule(TaskType.UNWRAP)).toBe('all-in')
16
- expect(taskCargoRule(TaskType.DEPOT_TAKE)).toBe('all-in')
16
+ expect(taskCargoRule(TaskType.CIVIC_WITHDRAW)).toBe('all-in')
17
17
  })
18
18
 
19
19
  test('maps the conditional task types to their own rules', () => {
@@ -19,11 +19,11 @@ export const TASK_CARGO_EFFECTS: ReadonlyMap<number, TaskCargoRule> = new Map<
19
19
  [TaskType.SHUTTLE, 'none'],
20
20
  [TaskType.LOAD, 'all-in'],
21
21
  [TaskType.UNWRAP, 'all-in'],
22
- [TaskType.DEPOT_TAKE, 'all-in'],
22
+ [TaskType.CIVIC_WITHDRAW, 'all-in'],
23
23
  [TaskType.UNLOAD, 'all-out'],
24
24
  [TaskType.UPGRADE, 'all-out'],
25
25
  [TaskType.CONTRIBUTE, 'all-out'],
26
- [TaskType.DEPOT_STORE, 'all-out'],
26
+ [TaskType.CIVIC_DEPOSIT, 'all-out'],
27
27
  [TaskType.GATHER, 'gather'],
28
28
  [TaskType.CRAFT, 'craft'],
29
29
  [TaskType.UNDEPLOY, 'undeploy'],
package/src/types.ts CHANGED
@@ -74,8 +74,12 @@ export enum TaskType {
74
74
  SHUTTLE = 18,
75
75
  REFIT = 19,
76
76
  CONTRIBUTE = 20,
77
+ /** @deprecated Renamed to CIVIC_DEPOSIT. */
77
78
  DEPOT_STORE = 21,
79
+ /** @deprecated Renamed to CIVIC_WITHDRAW. */
78
80
  DEPOT_TAKE = 22,
81
+ CIVIC_DEPOSIT = 21,
82
+ CIVIC_WITHDRAW = 22,
79
83
  }
80
84
 
81
85
  export enum RefitOp {