@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.
- package/lib/shipload.d.ts +81 -33
- package/lib/shipload.js +262 -163
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +261 -163
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +21 -10
- package/lib/testing.js +90 -51
- package/lib/testing.js.map +1 -1
- package/lib/testing.m.js +90 -51
- package/lib/testing.m.js.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/gathering.ts +20 -10
- package/src/contracts/server.ts +64 -33
- package/src/data/items.json +19 -19
- package/src/data/recipes.json +29 -29
- package/src/derivation/capabilities.ts +1 -1
- package/src/entities/makers.ts +1 -0
- package/src/errors.ts +0 -1
- package/src/index-module.ts +5 -0
- package/src/managers/actions.ts +26 -17
- package/src/managers/construction.ts +50 -37
- package/src/managers/nft.test.ts +14 -0
- package/src/managers/nft.ts +43 -1
- package/src/managers/plot.ts +0 -3
- package/src/nft/description.ts +1 -1
- package/src/scheduling/energy.ts +1 -2
- package/src/scheduling/idle-resolve.ts +44 -0
- package/src/scheduling/lane-core.ts +1 -3
- package/src/scheduling/projection.ts +1 -2
- package/src/scheduling/schedule.ts +10 -9
- package/src/subscriptions/mappers.ts +2 -0
- package/src/types.ts +8 -2
package/src/data/items.json
CHANGED
|
@@ -357,7 +357,7 @@
|
|
|
357
357
|
},
|
|
358
358
|
{
|
|
359
359
|
"id": 10002,
|
|
360
|
-
"mass":
|
|
360
|
+
"mass": 4000,
|
|
361
361
|
"type": "component",
|
|
362
362
|
"tier": 1
|
|
363
363
|
},
|
|
@@ -369,13 +369,13 @@
|
|
|
369
369
|
},
|
|
370
370
|
{
|
|
371
371
|
"id": 10004,
|
|
372
|
-
"mass":
|
|
372
|
+
"mass": 4000,
|
|
373
373
|
"type": "component",
|
|
374
374
|
"tier": 1
|
|
375
375
|
},
|
|
376
376
|
{
|
|
377
377
|
"id": 10005,
|
|
378
|
-
"mass":
|
|
378
|
+
"mass": 4000,
|
|
379
379
|
"type": "component",
|
|
380
380
|
"tier": 1
|
|
381
381
|
},
|
|
@@ -399,106 +399,106 @@
|
|
|
399
399
|
},
|
|
400
400
|
{
|
|
401
401
|
"id": 10009,
|
|
402
|
-
"mass":
|
|
402
|
+
"mass": 4000,
|
|
403
403
|
"type": "component",
|
|
404
404
|
"tier": 1
|
|
405
405
|
},
|
|
406
406
|
{
|
|
407
407
|
"id": 10010,
|
|
408
|
-
"mass":
|
|
408
|
+
"mass": 4000,
|
|
409
409
|
"type": "component",
|
|
410
410
|
"tier": 1
|
|
411
411
|
},
|
|
412
412
|
{
|
|
413
413
|
"id": 10100,
|
|
414
|
-
"mass":
|
|
414
|
+
"mass": 960000,
|
|
415
415
|
"type": "module",
|
|
416
416
|
"tier": 1,
|
|
417
417
|
"subtype": "engine"
|
|
418
418
|
},
|
|
419
419
|
{
|
|
420
420
|
"id": 10101,
|
|
421
|
-
"mass":
|
|
421
|
+
"mass": 960000,
|
|
422
422
|
"type": "module",
|
|
423
423
|
"tier": 1,
|
|
424
424
|
"subtype": "generator"
|
|
425
425
|
},
|
|
426
426
|
{
|
|
427
427
|
"id": 10102,
|
|
428
|
-
"mass":
|
|
428
|
+
"mass": 960000,
|
|
429
429
|
"type": "module",
|
|
430
430
|
"tier": 1,
|
|
431
431
|
"subtype": "gatherer"
|
|
432
432
|
},
|
|
433
433
|
{
|
|
434
434
|
"id": 10103,
|
|
435
|
-
"mass":
|
|
435
|
+
"mass": 960000,
|
|
436
436
|
"type": "module",
|
|
437
437
|
"tier": 1,
|
|
438
438
|
"subtype": "loader"
|
|
439
439
|
},
|
|
440
440
|
{
|
|
441
441
|
"id": 10104,
|
|
442
|
-
"mass":
|
|
442
|
+
"mass": 960000,
|
|
443
443
|
"type": "module",
|
|
444
444
|
"tier": 1,
|
|
445
445
|
"subtype": "crafter"
|
|
446
446
|
},
|
|
447
447
|
{
|
|
448
448
|
"id": 10105,
|
|
449
|
-
"mass":
|
|
449
|
+
"mass": 960000,
|
|
450
450
|
"type": "module",
|
|
451
451
|
"tier": 1,
|
|
452
452
|
"subtype": "storage"
|
|
453
453
|
},
|
|
454
454
|
{
|
|
455
455
|
"id": 10106,
|
|
456
|
-
"mass":
|
|
456
|
+
"mass": 960000,
|
|
457
457
|
"type": "module",
|
|
458
458
|
"tier": 1,
|
|
459
459
|
"subtype": "hauler"
|
|
460
460
|
},
|
|
461
461
|
{
|
|
462
462
|
"id": 10107,
|
|
463
|
-
"mass":
|
|
463
|
+
"mass": 960000,
|
|
464
464
|
"type": "module",
|
|
465
465
|
"tier": 1,
|
|
466
466
|
"subtype": "warp"
|
|
467
467
|
},
|
|
468
468
|
{
|
|
469
469
|
"id": 10108,
|
|
470
|
-
"mass":
|
|
470
|
+
"mass": 960000,
|
|
471
471
|
"type": "module",
|
|
472
472
|
"tier": 1,
|
|
473
473
|
"subtype": "battery"
|
|
474
474
|
},
|
|
475
475
|
{
|
|
476
476
|
"id": 10200,
|
|
477
|
-
"mass":
|
|
477
|
+
"mass": 1300000,
|
|
478
478
|
"type": "entity",
|
|
479
479
|
"tier": 1
|
|
480
480
|
},
|
|
481
481
|
{
|
|
482
482
|
"id": 10201,
|
|
483
|
-
"mass":
|
|
483
|
+
"mass": 1900000,
|
|
484
484
|
"type": "entity",
|
|
485
485
|
"tier": 1
|
|
486
486
|
},
|
|
487
487
|
{
|
|
488
488
|
"id": 10202,
|
|
489
|
-
"mass":
|
|
489
|
+
"mass": 4800000,
|
|
490
490
|
"type": "entity",
|
|
491
491
|
"tier": 1
|
|
492
492
|
},
|
|
493
493
|
{
|
|
494
494
|
"id": 10203,
|
|
495
|
-
"mass":
|
|
495
|
+
"mass": 3700000,
|
|
496
496
|
"type": "entity",
|
|
497
497
|
"tier": 1
|
|
498
498
|
},
|
|
499
499
|
{
|
|
500
500
|
"id": 10204,
|
|
501
|
-
"mass":
|
|
501
|
+
"mass": 4600000,
|
|
502
502
|
"type": "entity",
|
|
503
503
|
"tier": 1
|
|
504
504
|
},
|
package/src/data/recipes.json
CHANGED
|
@@ -30,15 +30,15 @@
|
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
"outputItemId": 10002,
|
|
33
|
-
"outputMass":
|
|
33
|
+
"outputMass": 4000,
|
|
34
34
|
"inputs": [
|
|
35
35
|
{
|
|
36
36
|
"itemId": 401,
|
|
37
|
-
"quantity":
|
|
37
|
+
"quantity": 5
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"itemId": 501,
|
|
41
|
-
"quantity":
|
|
41
|
+
"quantity": 5
|
|
42
42
|
}
|
|
43
43
|
],
|
|
44
44
|
"statSlots": [
|
|
@@ -92,15 +92,15 @@
|
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
94
|
"outputItemId": 10004,
|
|
95
|
-
"outputMass":
|
|
95
|
+
"outputMass": 4000,
|
|
96
96
|
"inputs": [
|
|
97
97
|
{
|
|
98
98
|
"itemId": 201,
|
|
99
|
-
"quantity":
|
|
99
|
+
"quantity": 5
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
"itemId": 101,
|
|
103
|
-
"quantity":
|
|
103
|
+
"quantity": 5
|
|
104
104
|
}
|
|
105
105
|
],
|
|
106
106
|
"statSlots": [
|
|
@@ -125,15 +125,15 @@
|
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
"outputItemId": 10005,
|
|
128
|
-
"outputMass":
|
|
128
|
+
"outputMass": 4000,
|
|
129
129
|
"inputs": [
|
|
130
130
|
{
|
|
131
131
|
"itemId": 101,
|
|
132
|
-
"quantity":
|
|
132
|
+
"quantity": 5
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
135
|
"itemId": 301,
|
|
136
|
-
"quantity":
|
|
136
|
+
"quantity": 5
|
|
137
137
|
}
|
|
138
138
|
],
|
|
139
139
|
"statSlots": [
|
|
@@ -245,15 +245,15 @@
|
|
|
245
245
|
},
|
|
246
246
|
{
|
|
247
247
|
"outputItemId": 10009,
|
|
248
|
-
"outputMass":
|
|
248
|
+
"outputMass": 4000,
|
|
249
249
|
"inputs": [
|
|
250
250
|
{
|
|
251
251
|
"itemId": 301,
|
|
252
|
-
"quantity":
|
|
252
|
+
"quantity": 5
|
|
253
253
|
},
|
|
254
254
|
{
|
|
255
255
|
"itemId": 401,
|
|
256
|
-
"quantity":
|
|
256
|
+
"quantity": 5
|
|
257
257
|
}
|
|
258
258
|
],
|
|
259
259
|
"statSlots": [
|
|
@@ -278,15 +278,15 @@
|
|
|
278
278
|
},
|
|
279
279
|
{
|
|
280
280
|
"outputItemId": 10010,
|
|
281
|
-
"outputMass":
|
|
281
|
+
"outputMass": 4000,
|
|
282
282
|
"inputs": [
|
|
283
283
|
{
|
|
284
284
|
"itemId": 501,
|
|
285
|
-
"quantity":
|
|
285
|
+
"quantity": 5
|
|
286
286
|
},
|
|
287
287
|
{
|
|
288
288
|
"itemId": 201,
|
|
289
|
-
"quantity":
|
|
289
|
+
"quantity": 5
|
|
290
290
|
}
|
|
291
291
|
],
|
|
292
292
|
"statSlots": [
|
|
@@ -311,7 +311,7 @@
|
|
|
311
311
|
},
|
|
312
312
|
{
|
|
313
313
|
"outputItemId": 10100,
|
|
314
|
-
"outputMass":
|
|
314
|
+
"outputMass": 960000,
|
|
315
315
|
"inputs": [
|
|
316
316
|
{
|
|
317
317
|
"itemId": 10003,
|
|
@@ -340,7 +340,7 @@
|
|
|
340
340
|
},
|
|
341
341
|
{
|
|
342
342
|
"outputItemId": 10101,
|
|
343
|
-
"outputMass":
|
|
343
|
+
"outputMass": 960000,
|
|
344
344
|
"inputs": [
|
|
345
345
|
{
|
|
346
346
|
"itemId": 10004,
|
|
@@ -369,7 +369,7 @@
|
|
|
369
369
|
},
|
|
370
370
|
{
|
|
371
371
|
"outputItemId": 10102,
|
|
372
|
-
"outputMass":
|
|
372
|
+
"outputMass": 960000,
|
|
373
373
|
"inputs": [
|
|
374
374
|
{
|
|
375
375
|
"itemId": 10005,
|
|
@@ -418,7 +418,7 @@
|
|
|
418
418
|
},
|
|
419
419
|
{
|
|
420
420
|
"outputItemId": 10103,
|
|
421
|
-
"outputMass":
|
|
421
|
+
"outputMass": 960000,
|
|
422
422
|
"inputs": [
|
|
423
423
|
{
|
|
424
424
|
"itemId": 10007,
|
|
@@ -447,7 +447,7 @@
|
|
|
447
447
|
},
|
|
448
448
|
{
|
|
449
449
|
"outputItemId": 10104,
|
|
450
|
-
"outputMass":
|
|
450
|
+
"outputMass": 960000,
|
|
451
451
|
"inputs": [
|
|
452
452
|
{
|
|
453
453
|
"itemId": 10008,
|
|
@@ -480,7 +480,7 @@
|
|
|
480
480
|
},
|
|
481
481
|
{
|
|
482
482
|
"outputItemId": 10105,
|
|
483
|
-
"outputMass":
|
|
483
|
+
"outputMass": 960000,
|
|
484
484
|
"inputs": [
|
|
485
485
|
{
|
|
486
486
|
"itemId": 10001,
|
|
@@ -529,7 +529,7 @@
|
|
|
529
529
|
},
|
|
530
530
|
{
|
|
531
531
|
"outputItemId": 10106,
|
|
532
|
-
"outputMass":
|
|
532
|
+
"outputMass": 960000,
|
|
533
533
|
"inputs": [
|
|
534
534
|
{
|
|
535
535
|
"itemId": 10004,
|
|
@@ -570,7 +570,7 @@
|
|
|
570
570
|
},
|
|
571
571
|
{
|
|
572
572
|
"outputItemId": 10107,
|
|
573
|
-
"outputMass":
|
|
573
|
+
"outputMass": 960000,
|
|
574
574
|
"inputs": [
|
|
575
575
|
{
|
|
576
576
|
"itemId": 10004,
|
|
@@ -602,7 +602,7 @@
|
|
|
602
602
|
},
|
|
603
603
|
{
|
|
604
604
|
"outputItemId": 10108,
|
|
605
|
-
"outputMass":
|
|
605
|
+
"outputMass": 960000,
|
|
606
606
|
"inputs": [
|
|
607
607
|
{
|
|
608
608
|
"itemId": 10003,
|
|
@@ -651,7 +651,7 @@
|
|
|
651
651
|
},
|
|
652
652
|
{
|
|
653
653
|
"outputItemId": 10200,
|
|
654
|
-
"outputMass":
|
|
654
|
+
"outputMass": 1300000,
|
|
655
655
|
"inputs": [
|
|
656
656
|
{
|
|
657
657
|
"itemId": 10001,
|
|
@@ -700,7 +700,7 @@
|
|
|
700
700
|
},
|
|
701
701
|
{
|
|
702
702
|
"outputItemId": 10201,
|
|
703
|
-
"outputMass":
|
|
703
|
+
"outputMass": 1900000,
|
|
704
704
|
"inputs": [
|
|
705
705
|
{
|
|
706
706
|
"itemId": 10001,
|
|
@@ -749,7 +749,7 @@
|
|
|
749
749
|
},
|
|
750
750
|
{
|
|
751
751
|
"outputItemId": 10202,
|
|
752
|
-
"outputMass":
|
|
752
|
+
"outputMass": 4800000,
|
|
753
753
|
"inputs": [
|
|
754
754
|
{
|
|
755
755
|
"itemId": 10001,
|
|
@@ -798,7 +798,7 @@
|
|
|
798
798
|
},
|
|
799
799
|
{
|
|
800
800
|
"outputItemId": 10203,
|
|
801
|
-
"outputMass":
|
|
801
|
+
"outputMass": 3700000,
|
|
802
802
|
"inputs": [
|
|
803
803
|
{
|
|
804
804
|
"itemId": 10001,
|
|
@@ -847,7 +847,7 @@
|
|
|
847
847
|
},
|
|
848
848
|
{
|
|
849
849
|
"outputItemId": 10204,
|
|
850
|
-
"outputMass":
|
|
850
|
+
"outputMass": 4600000,
|
|
851
851
|
"inputs": [
|
|
852
852
|
{
|
|
853
853
|
"itemId": 10001,
|
|
@@ -97,7 +97,7 @@ export function computeLoaderCapabilities(stats: Record<string, number>): {
|
|
|
97
97
|
|
|
98
98
|
return {
|
|
99
99
|
mass: Math.max(200, 2000 - Math.floor(insulation * 2)),
|
|
100
|
-
thrust: 1 + Math.floor(plasticity /
|
|
100
|
+
thrust: 1 + Math.floor((plasticity * plasticity) / 10000),
|
|
101
101
|
quantity: 1,
|
|
102
102
|
}
|
|
103
103
|
}
|
package/src/entities/makers.ts
CHANGED
|
@@ -109,6 +109,7 @@ export function makeEntity(packedItemId: number, state: EntityStateInput): Entit
|
|
|
109
109
|
cargomass: UInt32.from(state.cargomass ?? 0),
|
|
110
110
|
cargo: state.cargo || [],
|
|
111
111
|
lanes,
|
|
112
|
+
holds: [],
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
if (state.energy !== undefined) info.energy = UInt16.from(state.energy)
|
package/src/errors.ts
CHANGED
|
@@ -45,7 +45,6 @@ export const WAREHOUSE_ALREADY_AT_LOCATION = 'Warehouse already exists at this l
|
|
|
45
45
|
export const CONTAINER_NOT_FOUND = 'Cannot find container for given id.'
|
|
46
46
|
export const DESTINATION_CAPACITY_EXCEEDED =
|
|
47
47
|
'Destination entity does not have enough capacity for the gather.'
|
|
48
|
-
export const CANCEL_PAIRED_HAS_PENDING = 'Cannot cancel transfer, paired entity has pending tasks.'
|
|
49
48
|
export const GROUP_EMPTY = 'Group travel requires at least one entity.'
|
|
50
49
|
export const GROUP_NO_THRUST = 'Group travel requires at least one entity with engines.'
|
|
51
50
|
export const GROUP_NOT_SAME_LOCATION = 'All entities must be at the same location for group travel.'
|
package/src/index-module.ts
CHANGED
|
@@ -65,6 +65,8 @@ export type {
|
|
|
65
65
|
Reservation,
|
|
66
66
|
} from './managers'
|
|
67
67
|
export type {EntityRefInput} from './managers/actions'
|
|
68
|
+
export type {WrapDeposit} from './managers/nft'
|
|
69
|
+
export {resolveLockedAmount} from './managers/nft'
|
|
68
70
|
|
|
69
71
|
export {
|
|
70
72
|
getItem,
|
|
@@ -227,6 +229,9 @@ export type {
|
|
|
227
229
|
export {taskCargoChanges} from './scheduling/task-cargo'
|
|
228
230
|
export type {TaskCargoChange, TaskCargoDirection} from './scheduling/task-cargo'
|
|
229
231
|
|
|
232
|
+
export {composeIdleResolve} from './scheduling/idle-resolve'
|
|
233
|
+
export type {CounterpartLookup, IdleResolveTarget} from './scheduling/idle-resolve'
|
|
234
|
+
|
|
230
235
|
export {
|
|
231
236
|
projectedCargoAvailableAt,
|
|
232
237
|
availableForItem,
|
package/src/managers/actions.ts
CHANGED
|
@@ -73,14 +73,6 @@ export class ActionsManager extends BaseManager {
|
|
|
73
73
|
})
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
retarget(sourceId: UInt64Type, taskIndex: UInt64Type, newDestId: UInt64Type): Action {
|
|
77
|
-
return this.server.action('retarget', {
|
|
78
|
-
source_id: UInt64.from(sourceId),
|
|
79
|
-
task_index: UInt64.from(taskIndex),
|
|
80
|
-
new_dest_id: UInt64.from(newDestId),
|
|
81
|
-
})
|
|
82
|
-
}
|
|
83
|
-
|
|
84
76
|
recharge(entityId: UInt64Type): Action {
|
|
85
77
|
return this.server.action('recharge', {
|
|
86
78
|
id: UInt64.from(entityId),
|
|
@@ -100,14 +92,26 @@ export class ActionsManager extends BaseManager {
|
|
|
100
92
|
})
|
|
101
93
|
}
|
|
102
94
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
95
|
+
load(
|
|
96
|
+
id: UInt64Type,
|
|
97
|
+
fromId: UInt64Type,
|
|
106
98
|
items: ServerContract.ActionParams.Type.cargo_item[]
|
|
107
99
|
): Action {
|
|
108
|
-
return this.server.action('
|
|
109
|
-
|
|
110
|
-
|
|
100
|
+
return this.server.action('load', {
|
|
101
|
+
id: UInt64.from(id),
|
|
102
|
+
from_id: UInt64.from(fromId),
|
|
103
|
+
items,
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
unload(
|
|
108
|
+
id: UInt64Type,
|
|
109
|
+
toId: UInt64Type,
|
|
110
|
+
items: ServerContract.ActionParams.Type.cargo_item[]
|
|
111
|
+
): Action {
|
|
112
|
+
return this.server.action('unload', {
|
|
113
|
+
id: UInt64.from(id),
|
|
114
|
+
to_id: UInt64.from(toId),
|
|
111
115
|
items,
|
|
112
116
|
})
|
|
113
117
|
}
|
|
@@ -154,14 +158,19 @@ export class ActionsManager extends BaseManager {
|
|
|
154
158
|
entityId: UInt64Type,
|
|
155
159
|
recipeId: number,
|
|
156
160
|
quantity: number,
|
|
157
|
-
inputs: ServerContract.ActionParams.Type.cargo_item[]
|
|
161
|
+
inputs: ServerContract.ActionParams.Type.cargo_item[],
|
|
162
|
+
target?: UInt64Type
|
|
158
163
|
): Action {
|
|
159
|
-
|
|
164
|
+
const params: ServerContract.ActionParams.craft = {
|
|
160
165
|
id: UInt64.from(entityId),
|
|
161
166
|
recipe_id: UInt16.from(recipeId),
|
|
162
167
|
quantity: UInt32.from(quantity),
|
|
163
168
|
inputs,
|
|
164
|
-
}
|
|
169
|
+
}
|
|
170
|
+
if (target !== undefined) {
|
|
171
|
+
params.target = UInt64.from(target)
|
|
172
|
+
}
|
|
173
|
+
return this.server.action('craft', params)
|
|
165
174
|
}
|
|
166
175
|
|
|
167
176
|
blend(entityId: UInt64Type, inputs: ServerContract.ActionParams.Type.cargo_item[]): Action {
|
|
@@ -5,7 +5,7 @@ import {PlotManager} from './plot'
|
|
|
5
5
|
import {getItem} from '../data/catalog'
|
|
6
6
|
import {calc_craft_duration} from '../capabilities/crafting'
|
|
7
7
|
import {getLanes, getTasks} from '../scheduling/schedule'
|
|
8
|
-
import {TaskType} from '../types'
|
|
8
|
+
import {HoldKind, TaskType} from '../types'
|
|
9
9
|
import type {
|
|
10
10
|
BuildableTarget,
|
|
11
11
|
FinalizerEntityRef,
|
|
@@ -102,7 +102,7 @@ export class ConstructionManager extends BaseManager {
|
|
|
102
102
|
let cumulativeSec = 0
|
|
103
103
|
for (const task of lane.schedule.tasks) {
|
|
104
104
|
cumulativeSec += task.duration.toNumber()
|
|
105
|
-
if (!
|
|
105
|
+
if (!isPushTask(task)) continue
|
|
106
106
|
if (!task.entitytarget) continue
|
|
107
107
|
const projectedEndMs = startedMs + cumulativeSec * 1000
|
|
108
108
|
if (projectedEndMs < nowMs) continue
|
|
@@ -145,51 +145,53 @@ export class ConstructionManager extends BaseManager {
|
|
|
145
145
|
|
|
146
146
|
private plotReservation(
|
|
147
147
|
plot: ServerContract.Types.entity_info,
|
|
148
|
+
builder: ServerContract.Types.entity_info | undefined,
|
|
148
149
|
now: Date
|
|
149
150
|
): {
|
|
150
151
|
builderId: UInt64
|
|
151
|
-
group?: UInt64
|
|
152
152
|
startsAt: number
|
|
153
153
|
completesAt: number
|
|
154
154
|
hasStarted: boolean
|
|
155
155
|
} | null {
|
|
156
|
-
|
|
156
|
+
const hold = plot.holds.find((h) => h.kind.toNumber() === HoldKind.BUILD)
|
|
157
|
+
if (!hold) return null
|
|
158
|
+
const builderId = hold.counterpart.entity_id
|
|
159
|
+
const completesAt = hold.until.toDate().getTime()
|
|
160
|
+
const startsAt = this.builderBuildStart(builder, plot.id) ?? completesAt
|
|
161
|
+
return {
|
|
162
|
+
builderId,
|
|
163
|
+
startsAt,
|
|
164
|
+
completesAt,
|
|
165
|
+
hasStarted: startsAt <= now.getTime(),
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private builderBuildStart(
|
|
170
|
+
builder: ServerContract.Types.entity_info | undefined,
|
|
171
|
+
plotId: UInt64
|
|
172
|
+
): number | undefined {
|
|
173
|
+
if (!builder) return undefined
|
|
174
|
+
for (const lane of getLanes(builder)) {
|
|
157
175
|
const startedMs = lane.schedule.started.toDate().getTime()
|
|
158
176
|
let startSec = 0
|
|
159
177
|
for (const task of lane.schedule.tasks) {
|
|
160
|
-
if (task
|
|
161
|
-
if (!task.entitytarget) return null
|
|
162
|
-
const startsAt = startedMs + startSec * 1000
|
|
163
|
-
const completesAt = startsAt + task.duration.toNumber() * 1000
|
|
164
|
-
return {
|
|
165
|
-
builderId: task.entitytarget.entity_id,
|
|
166
|
-
group: task.entitygroup ?? undefined,
|
|
167
|
-
startsAt,
|
|
168
|
-
completesAt,
|
|
169
|
-
hasStarted: startsAt <= now.getTime(),
|
|
170
|
-
}
|
|
171
|
-
}
|
|
178
|
+
if (isBuildOfPlot(task, plotId)) return startedMs + startSec * 1000
|
|
172
179
|
startSec += task.duration.toNumber()
|
|
173
180
|
}
|
|
174
181
|
}
|
|
175
|
-
return
|
|
182
|
+
return undefined
|
|
176
183
|
}
|
|
177
184
|
|
|
178
185
|
private builderCancelability(
|
|
179
186
|
builder: ServerContract.Types.entity_info | undefined,
|
|
180
|
-
|
|
187
|
+
plotId: UInt64
|
|
181
188
|
): {cancelable: boolean; blockingTaskCount: number} {
|
|
182
|
-
if (!builder
|
|
189
|
+
if (!builder) {
|
|
183
190
|
return {cancelable: false, blockingTaskCount: 0}
|
|
184
191
|
}
|
|
185
192
|
for (const lane of getLanes(builder)) {
|
|
186
193
|
const tasks = lane.schedule.tasks
|
|
187
|
-
const buildIdx = tasks.findIndex(
|
|
188
|
-
(t) =>
|
|
189
|
-
t.type.toNumber() === TaskType.BUILDPLOT &&
|
|
190
|
-
t.entitygroup !== undefined &&
|
|
191
|
-
t.entitygroup.equals(group)
|
|
192
|
-
)
|
|
194
|
+
const buildIdx = tasks.findIndex((t) => isBuildOfPlot(t, plotId))
|
|
193
195
|
if (buildIdx < 0) continue
|
|
194
196
|
const trailing = tasks.length - 1 - buildIdx
|
|
195
197
|
return {cancelable: trailing === 0, blockingTaskCount: trailing}
|
|
@@ -200,14 +202,14 @@ export class ConstructionManager extends BaseManager {
|
|
|
200
202
|
private buildFromReservation(
|
|
201
203
|
res: {
|
|
202
204
|
builderId: UInt64
|
|
203
|
-
group?: UInt64
|
|
204
205
|
startsAt: number
|
|
205
206
|
completesAt: number
|
|
206
207
|
hasStarted: boolean
|
|
207
208
|
},
|
|
209
|
+
plotId: UInt64,
|
|
208
210
|
builder: ServerContract.Types.entity_info | undefined
|
|
209
211
|
): ScheduledBuild {
|
|
210
|
-
const {cancelable, blockingTaskCount} = this.builderCancelability(builder,
|
|
212
|
+
const {cancelable, blockingTaskCount} = this.builderCancelability(builder, plotId)
|
|
211
213
|
return {
|
|
212
214
|
shipId: res.builderId,
|
|
213
215
|
shipName: builder?.entity_name || res.builderId.toString(),
|
|
@@ -224,10 +226,12 @@ export class ConstructionManager extends BaseManager {
|
|
|
224
226
|
entities: ServerContract.Types.entity_info[],
|
|
225
227
|
now: Date
|
|
226
228
|
): ScheduledBuild | null {
|
|
227
|
-
const
|
|
229
|
+
const hold = plot.holds.find((h) => h.kind.toNumber() === HoldKind.BUILD)
|
|
230
|
+
if (!hold) return null
|
|
231
|
+
const builder = entities.find((e) => e.id.equals(hold.counterpart.entity_id))
|
|
232
|
+
const res = this.plotReservation(plot, builder, now)
|
|
228
233
|
if (!res) return null
|
|
229
|
-
|
|
230
|
-
return this.buildFromReservation(res, builder)
|
|
234
|
+
return this.buildFromReservation(res, plot.id, builder)
|
|
231
235
|
}
|
|
232
236
|
|
|
233
237
|
scheduledBuildsByTarget(
|
|
@@ -238,10 +242,12 @@ export class ConstructionManager extends BaseManager {
|
|
|
238
242
|
const out = new Map<string, ScheduledBuild>()
|
|
239
243
|
for (const entity of entities) {
|
|
240
244
|
if (entity.type.toString() !== 'plot') continue
|
|
241
|
-
const
|
|
245
|
+
const hold = entity.holds.find((h) => h.kind.toNumber() === HoldKind.BUILD)
|
|
246
|
+
if (!hold) continue
|
|
247
|
+
const builder = byId.get(hold.counterpart.entity_id.toString())
|
|
248
|
+
const res = this.plotReservation(entity, builder, now)
|
|
242
249
|
if (!res) continue
|
|
243
|
-
|
|
244
|
-
out.set(entity.id.toString(), this.buildFromReservation(res, builder))
|
|
250
|
+
out.set(entity.id.toString(), this.buildFromReservation(res, entity.id, builder))
|
|
245
251
|
}
|
|
246
252
|
return out
|
|
247
253
|
}
|
|
@@ -354,15 +360,22 @@ function partitionSources(
|
|
|
354
360
|
return {eligible, unreachable}
|
|
355
361
|
}
|
|
356
362
|
|
|
357
|
-
function
|
|
358
|
-
|
|
359
|
-
|
|
363
|
+
function isPushTask(task: ServerContract.Types.task): boolean {
|
|
364
|
+
return task.type.toNumber() === TaskType.UNLOAD
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function isBuildOfPlot(task: ServerContract.Types.task, plotId: UInt64): boolean {
|
|
368
|
+
return (
|
|
369
|
+
task.type.toNumber() === TaskType.BUILDPLOT &&
|
|
370
|
+
task.entitytarget !== undefined &&
|
|
371
|
+
task.entitytarget.entity_id.equals(plotId)
|
|
372
|
+
)
|
|
360
373
|
}
|
|
361
374
|
|
|
362
375
|
function reservationsOf(source: ServerContract.Types.entity_info): Reservation[] {
|
|
363
376
|
const out = new Map<string, Reservation>()
|
|
364
377
|
for (const task of getTasks(source)) {
|
|
365
|
-
if (!
|
|
378
|
+
if (!isPushTask(task)) continue
|
|
366
379
|
if (!task.entitytarget) continue
|
|
367
380
|
const targetType = task.entitytarget.entity_type
|
|
368
381
|
const targetId = task.entitytarget.entity_id
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {describe, expect, test} from 'bun:test'
|
|
2
|
+
import {resolveLockedAmount} from './nft'
|
|
3
|
+
|
|
4
|
+
describe('resolveLockedAmount', () => {
|
|
5
|
+
test('no fee refunds the full cost', () => {
|
|
6
|
+
expect(resolveLockedAmount(5_0000n, 0)).toBe(5_0000n)
|
|
7
|
+
})
|
|
8
|
+
test('2% fee floors the fee and refunds the remainder', () => {
|
|
9
|
+
expect(resolveLockedAmount(5_0000n, 200)).toBe(4_9000n)
|
|
10
|
+
})
|
|
11
|
+
test('rounding floors the fee (contract uses integer division)', () => {
|
|
12
|
+
expect(resolveLockedAmount(101n, 250)).toBe(99n) // fee = floor(101*250/10000)=2
|
|
13
|
+
})
|
|
14
|
+
})
|