@shipload/sdk 1.0.0-next.43 → 1.0.0-next.44
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 +141 -172
- package/lib/shipload.js +503 -300
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +500 -302
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +50 -67
- package/lib/testing.js +168 -208
- package/lib/testing.js.map +1 -1
- package/lib/testing.m.js +169 -209
- package/lib/testing.m.js.map +1 -1
- package/package.json +1 -1
- package/src/contracts/server.ts +126 -214
- package/src/data/capabilities.ts +14 -14
- package/src/data/capability-formulas.ts +7 -7
- package/src/data/entities.json +4 -0
- package/src/data/item-ids.ts +1 -0
- package/src/data/items.json +6 -0
- package/src/data/kind-registry.json +18 -6
- package/src/data/kind-registry.ts +7 -0
- package/src/data/metadata.ts +22 -15
- package/src/data/recipes.json +170 -19
- package/src/derivation/build-methods.test.ts +13 -0
- package/src/derivation/build-methods.ts +5 -2
- package/src/derivation/capabilities.ts +8 -8
- package/src/index-module.ts +5 -0
- package/src/managers/actions.ts +25 -8
- package/src/managers/cluster.test.ts +39 -0
- package/src/managers/cluster.ts +53 -0
- package/src/managers/context.ts +9 -0
- package/src/managers/index.ts +2 -0
- package/src/nft/buildImmutableData.ts +15 -17
- package/src/nft/description.ts +8 -8
- package/src/resolution/describe-module.ts +6 -6
- package/src/resolution/resolve-item.ts +3 -3
- package/src/shipload.ts +5 -0
- package/src/subscriptions/manager.cluster.test.ts +46 -0
- package/src/subscriptions/manager.ts +22 -0
- package/src/subscriptions/types.ts +16 -0
- package/src/types.ts +7 -0
package/src/data/recipes.json
CHANGED
|
@@ -24,6 +24,14 @@
|
|
|
24
24
|
"statIndex": 2
|
|
25
25
|
}
|
|
26
26
|
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"sources": [
|
|
30
|
+
{
|
|
31
|
+
"inputIndex": 0,
|
|
32
|
+
"statIndex": 1
|
|
33
|
+
}
|
|
34
|
+
]
|
|
27
35
|
}
|
|
28
36
|
],
|
|
29
37
|
"blendWeights": []
|
|
@@ -57,6 +65,22 @@
|
|
|
57
65
|
"statIndex": 0
|
|
58
66
|
}
|
|
59
67
|
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"sources": [
|
|
71
|
+
{
|
|
72
|
+
"inputIndex": 0,
|
|
73
|
+
"statIndex": 2
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"sources": [
|
|
79
|
+
{
|
|
80
|
+
"inputIndex": 1,
|
|
81
|
+
"statIndex": 2
|
|
82
|
+
}
|
|
83
|
+
]
|
|
60
84
|
}
|
|
61
85
|
],
|
|
62
86
|
"blendWeights": []
|
|
@@ -86,6 +110,14 @@
|
|
|
86
110
|
"statIndex": 2
|
|
87
111
|
}
|
|
88
112
|
]
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"sources": [
|
|
116
|
+
{
|
|
117
|
+
"inputIndex": 0,
|
|
118
|
+
"statIndex": 1
|
|
119
|
+
}
|
|
120
|
+
]
|
|
89
121
|
}
|
|
90
122
|
],
|
|
91
123
|
"blendWeights": []
|
|
@@ -119,6 +151,14 @@
|
|
|
119
151
|
"statIndex": 2
|
|
120
152
|
}
|
|
121
153
|
]
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"sources": [
|
|
157
|
+
{
|
|
158
|
+
"inputIndex": 0,
|
|
159
|
+
"statIndex": 0
|
|
160
|
+
}
|
|
161
|
+
]
|
|
122
162
|
}
|
|
123
163
|
],
|
|
124
164
|
"blendWeights": []
|
|
@@ -152,6 +192,14 @@
|
|
|
152
192
|
"statIndex": 1
|
|
153
193
|
}
|
|
154
194
|
]
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"sources": [
|
|
198
|
+
{
|
|
199
|
+
"inputIndex": 0,
|
|
200
|
+
"statIndex": 2
|
|
201
|
+
}
|
|
202
|
+
]
|
|
155
203
|
}
|
|
156
204
|
],
|
|
157
205
|
"blendWeights": []
|
|
@@ -181,6 +229,14 @@
|
|
|
181
229
|
"statIndex": 2
|
|
182
230
|
}
|
|
183
231
|
]
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"sources": [
|
|
235
|
+
{
|
|
236
|
+
"inputIndex": 0,
|
|
237
|
+
"statIndex": 1
|
|
238
|
+
}
|
|
239
|
+
]
|
|
184
240
|
}
|
|
185
241
|
],
|
|
186
242
|
"blendWeights": []
|
|
@@ -210,6 +266,14 @@
|
|
|
210
266
|
"statIndex": 1
|
|
211
267
|
}
|
|
212
268
|
]
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"sources": [
|
|
272
|
+
{
|
|
273
|
+
"inputIndex": 0,
|
|
274
|
+
"statIndex": 2
|
|
275
|
+
}
|
|
276
|
+
]
|
|
213
277
|
}
|
|
214
278
|
],
|
|
215
279
|
"blendWeights": []
|
|
@@ -272,6 +336,22 @@
|
|
|
272
336
|
"statIndex": 2
|
|
273
337
|
}
|
|
274
338
|
]
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"sources": [
|
|
342
|
+
{
|
|
343
|
+
"inputIndex": 1,
|
|
344
|
+
"statIndex": 2
|
|
345
|
+
}
|
|
346
|
+
]
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
"sources": [
|
|
350
|
+
{
|
|
351
|
+
"inputIndex": 1,
|
|
352
|
+
"statIndex": 0
|
|
353
|
+
}
|
|
354
|
+
]
|
|
275
355
|
}
|
|
276
356
|
],
|
|
277
357
|
"blendWeights": []
|
|
@@ -305,6 +385,14 @@
|
|
|
305
385
|
"statIndex": 0
|
|
306
386
|
}
|
|
307
387
|
]
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"sources": [
|
|
391
|
+
{
|
|
392
|
+
"inputIndex": 0,
|
|
393
|
+
"statIndex": 1
|
|
394
|
+
}
|
|
395
|
+
]
|
|
308
396
|
}
|
|
309
397
|
],
|
|
310
398
|
"blendWeights": []
|
|
@@ -324,6 +412,10 @@
|
|
|
324
412
|
{
|
|
325
413
|
"inputIndex": 0,
|
|
326
414
|
"statIndex": 0
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"inputIndex": 0,
|
|
418
|
+
"statIndex": 2
|
|
327
419
|
}
|
|
328
420
|
]
|
|
329
421
|
},
|
|
@@ -336,7 +428,9 @@
|
|
|
336
428
|
]
|
|
337
429
|
}
|
|
338
430
|
],
|
|
339
|
-
"blendWeights": [
|
|
431
|
+
"blendWeights": [
|
|
432
|
+
1
|
|
433
|
+
]
|
|
340
434
|
},
|
|
341
435
|
{
|
|
342
436
|
"outputItemId": 10101,
|
|
@@ -353,6 +447,10 @@
|
|
|
353
447
|
{
|
|
354
448
|
"inputIndex": 0,
|
|
355
449
|
"statIndex": 0
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"inputIndex": 0,
|
|
453
|
+
"statIndex": 2
|
|
356
454
|
}
|
|
357
455
|
]
|
|
358
456
|
},
|
|
@@ -365,7 +463,9 @@
|
|
|
365
463
|
]
|
|
366
464
|
}
|
|
367
465
|
],
|
|
368
|
-
"blendWeights": [
|
|
466
|
+
"blendWeights": [
|
|
467
|
+
1
|
|
468
|
+
]
|
|
369
469
|
},
|
|
370
470
|
{
|
|
371
471
|
"outputItemId": 10102,
|
|
@@ -376,7 +476,7 @@
|
|
|
376
476
|
"quantity": 300
|
|
377
477
|
},
|
|
378
478
|
{
|
|
379
|
-
"itemId":
|
|
479
|
+
"itemId": 10002,
|
|
380
480
|
"quantity": 300
|
|
381
481
|
}
|
|
382
482
|
],
|
|
@@ -386,14 +486,10 @@
|
|
|
386
486
|
{
|
|
387
487
|
"inputIndex": 0,
|
|
388
488
|
"statIndex": 0
|
|
389
|
-
}
|
|
390
|
-
]
|
|
391
|
-
},
|
|
392
|
-
{
|
|
393
|
-
"sources": [
|
|
489
|
+
},
|
|
394
490
|
{
|
|
395
491
|
"inputIndex": 0,
|
|
396
|
-
"statIndex":
|
|
492
|
+
"statIndex": 2
|
|
397
493
|
}
|
|
398
494
|
]
|
|
399
495
|
},
|
|
@@ -402,6 +498,10 @@
|
|
|
402
498
|
{
|
|
403
499
|
"inputIndex": 1,
|
|
404
500
|
"statIndex": 0
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
"inputIndex": 0,
|
|
504
|
+
"statIndex": 1
|
|
405
505
|
}
|
|
406
506
|
]
|
|
407
507
|
},
|
|
@@ -409,12 +509,15 @@
|
|
|
409
509
|
"sources": [
|
|
410
510
|
{
|
|
411
511
|
"inputIndex": 1,
|
|
412
|
-
"statIndex":
|
|
512
|
+
"statIndex": 3
|
|
413
513
|
}
|
|
414
514
|
]
|
|
415
515
|
}
|
|
416
516
|
],
|
|
417
|
-
"blendWeights": [
|
|
517
|
+
"blendWeights": [
|
|
518
|
+
1,
|
|
519
|
+
1
|
|
520
|
+
]
|
|
418
521
|
},
|
|
419
522
|
{
|
|
420
523
|
"outputItemId": 10103,
|
|
@@ -439,11 +542,17 @@
|
|
|
439
542
|
{
|
|
440
543
|
"inputIndex": 0,
|
|
441
544
|
"statIndex": 0
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
"inputIndex": 0,
|
|
548
|
+
"statIndex": 2
|
|
442
549
|
}
|
|
443
550
|
]
|
|
444
551
|
}
|
|
445
552
|
],
|
|
446
|
-
"blendWeights": [
|
|
553
|
+
"blendWeights": [
|
|
554
|
+
1
|
|
555
|
+
]
|
|
447
556
|
},
|
|
448
557
|
{
|
|
449
558
|
"outputItemId": 10104,
|
|
@@ -463,7 +572,11 @@
|
|
|
463
572
|
"sources": [
|
|
464
573
|
{
|
|
465
574
|
"inputIndex": 0,
|
|
466
|
-
"statIndex":
|
|
575
|
+
"statIndex": 2
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
"inputIndex": 0,
|
|
579
|
+
"statIndex": 3
|
|
467
580
|
}
|
|
468
581
|
]
|
|
469
582
|
},
|
|
@@ -476,7 +589,10 @@
|
|
|
476
589
|
]
|
|
477
590
|
}
|
|
478
591
|
],
|
|
479
|
-
"blendWeights": [
|
|
592
|
+
"blendWeights": [
|
|
593
|
+
1,
|
|
594
|
+
1
|
|
595
|
+
]
|
|
480
596
|
},
|
|
481
597
|
{
|
|
482
598
|
"outputItemId": 10105,
|
|
@@ -546,6 +662,10 @@
|
|
|
546
662
|
{
|
|
547
663
|
"inputIndex": 0,
|
|
548
664
|
"statIndex": 0
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
"inputIndex": 0,
|
|
668
|
+
"statIndex": 1
|
|
549
669
|
}
|
|
550
670
|
]
|
|
551
671
|
},
|
|
@@ -561,12 +681,15 @@
|
|
|
561
681
|
"sources": [
|
|
562
682
|
{
|
|
563
683
|
"inputIndex": 0,
|
|
564
|
-
"statIndex":
|
|
684
|
+
"statIndex": 2
|
|
565
685
|
}
|
|
566
686
|
]
|
|
567
687
|
}
|
|
568
688
|
],
|
|
569
|
-
"blendWeights": [
|
|
689
|
+
"blendWeights": [
|
|
690
|
+
1,
|
|
691
|
+
1
|
|
692
|
+
]
|
|
570
693
|
},
|
|
571
694
|
{
|
|
572
695
|
"outputItemId": 10107,
|
|
@@ -586,11 +709,11 @@
|
|
|
586
709
|
"sources": [
|
|
587
710
|
{
|
|
588
711
|
"inputIndex": 0,
|
|
589
|
-
"statIndex":
|
|
712
|
+
"statIndex": 1
|
|
590
713
|
},
|
|
591
714
|
{
|
|
592
|
-
"inputIndex":
|
|
593
|
-
"statIndex":
|
|
715
|
+
"inputIndex": 0,
|
|
716
|
+
"statIndex": 2
|
|
594
717
|
}
|
|
595
718
|
]
|
|
596
719
|
}
|
|
@@ -875,5 +998,33 @@
|
|
|
875
998
|
}
|
|
876
999
|
],
|
|
877
1000
|
"blendWeights": []
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
"outputItemId": 10207,
|
|
1004
|
+
"outputMass": 2400000,
|
|
1005
|
+
"inputs": [
|
|
1006
|
+
{
|
|
1007
|
+
"itemId": 10005,
|
|
1008
|
+
"quantity": 200
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
"itemId": 10010,
|
|
1012
|
+
"quantity": 200
|
|
1013
|
+
}
|
|
1014
|
+
],
|
|
1015
|
+
"statSlots": [
|
|
1016
|
+
{
|
|
1017
|
+
"sources": []
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
"sources": [
|
|
1021
|
+
{
|
|
1022
|
+
"inputIndex": 1,
|
|
1023
|
+
"statIndex": 1
|
|
1024
|
+
}
|
|
1025
|
+
]
|
|
1026
|
+
}
|
|
1027
|
+
],
|
|
1028
|
+
"blendWeights": []
|
|
878
1029
|
}
|
|
879
1030
|
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {describe, expect, test} from 'bun:test'
|
|
2
|
+
import {availableBuildMethods} from './build-methods'
|
|
3
|
+
import {ITEM_HUB_T1_PACKED, ITEM_WAREHOUSE_T1_PACKED} from '../data/item-ids'
|
|
4
|
+
|
|
5
|
+
describe('availableBuildMethods', () => {
|
|
6
|
+
test('orbital structures build via craft+deploy or plot', () => {
|
|
7
|
+
expect(availableBuildMethods(ITEM_WAREHOUSE_T1_PACKED)).toEqual(['craft+deploy', 'plot'])
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test('hub is craft+deploy only — excluded from the plot path', () => {
|
|
11
|
+
expect(availableBuildMethods(ITEM_HUB_T1_PACKED)).toEqual(['craft+deploy'])
|
|
12
|
+
})
|
|
13
|
+
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {EntityClass, getKindMeta, getTemplateMeta} from '../data/kind-registry'
|
|
1
|
+
import {ENTITY_HUB, EntityClass, getKindMeta, getTemplateMeta} from '../data/kind-registry'
|
|
2
2
|
import {getRecipe} from '../data/recipes-runtime'
|
|
3
3
|
import {getItems} from '../data/catalog'
|
|
4
4
|
import type {Item} from '../types'
|
|
@@ -15,7 +15,10 @@ export function availableBuildMethods(itemId: number): BuildMethod[] {
|
|
|
15
15
|
const kindMeta = getKindMeta(template.kind)
|
|
16
16
|
if (!kindMeta) return ['craft+deploy']
|
|
17
17
|
|
|
18
|
-
if (
|
|
18
|
+
if (
|
|
19
|
+
kindMeta.classification === EntityClass.OrbitalStructure &&
|
|
20
|
+
!kindMeta.kind.equals(ENTITY_HUB)
|
|
21
|
+
) {
|
|
19
22
|
return ['craft+deploy', 'plot']
|
|
20
23
|
}
|
|
21
24
|
return ['craft+deploy']
|
|
@@ -78,12 +78,12 @@ export function computeGathererCapabilities(
|
|
|
78
78
|
} {
|
|
79
79
|
const str = stats.strength
|
|
80
80
|
const con = stats.saturation
|
|
81
|
-
const
|
|
81
|
+
const hrd = stats.hardness
|
|
82
82
|
|
|
83
83
|
return {
|
|
84
84
|
yield: 200 + str,
|
|
85
85
|
drain: 2 * Math.max(250, 1250 - Math.floor((con * 25) / 20)),
|
|
86
|
-
depth: gathererDepthForTier(
|
|
86
|
+
depth: gathererDepthForTier(hrd, tier),
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -106,11 +106,11 @@ export function computeCrafterCapabilities(stats: Record<string, number>): {
|
|
|
106
106
|
speed: number
|
|
107
107
|
drain: number
|
|
108
108
|
} {
|
|
109
|
-
const
|
|
109
|
+
const fin = stats.fineness
|
|
110
110
|
const con = stats.conductivity
|
|
111
111
|
|
|
112
112
|
return {
|
|
113
|
-
speed: 100 + Math.floor((
|
|
113
|
+
speed: 100 + Math.floor((fin * 4) / 5),
|
|
114
114
|
drain: Math.max(5, 30 - Math.floor(con / 33)),
|
|
115
115
|
}
|
|
116
116
|
}
|
|
@@ -122,12 +122,12 @@ export function computeHaulerCapabilities(stats: Record<string, number>): {
|
|
|
122
122
|
} {
|
|
123
123
|
const resonance = stats.resonance
|
|
124
124
|
const plasticity = stats.plasticity
|
|
125
|
-
const
|
|
125
|
+
const conductivity = stats.conductivity
|
|
126
126
|
|
|
127
127
|
return {
|
|
128
128
|
capacity: Math.max(1, 1 + Math.floor(resonance / 400)),
|
|
129
129
|
efficiency: 2000 + plasticity * 6,
|
|
130
|
-
drain: Math.max(3, 15 - Math.floor(
|
|
130
|
+
drain: Math.max(3, 15 - Math.floor(conductivity / 80)),
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -224,8 +224,8 @@ export function computeBaseCapacity(itemId: number, stats: Record<string, number
|
|
|
224
224
|
export function computeWarpCapabilities(stats: Record<string, number>): {
|
|
225
225
|
range: number
|
|
226
226
|
} {
|
|
227
|
-
const
|
|
228
|
-
return {range: 100 +
|
|
227
|
+
const reflectivity = stats.reflectivity
|
|
228
|
+
return {range: 100 + reflectivity * 3}
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
export function computeWarehouseHullCapabilities(stats: Record<string, number>): {
|
package/src/index-module.ts
CHANGED
|
@@ -46,9 +46,12 @@ export {
|
|
|
46
46
|
LocationsManager,
|
|
47
47
|
EpochsManager,
|
|
48
48
|
ActionsManager,
|
|
49
|
+
ClusterManager,
|
|
50
|
+
computeFreeCells,
|
|
49
51
|
NftManager,
|
|
50
52
|
ConstructionManager,
|
|
51
53
|
} from './managers'
|
|
54
|
+
export type {GridCell, ClusterCell, Cluster} from './managers'
|
|
52
55
|
export type {
|
|
53
56
|
PlayerRosterEntry,
|
|
54
57
|
LocationStratum,
|
|
@@ -315,6 +318,7 @@ export {
|
|
|
315
318
|
ENTITY_FACTORY,
|
|
316
319
|
ENTITY_CONTAINER,
|
|
317
320
|
ENTITY_NEXUS,
|
|
321
|
+
ENTITY_HUB,
|
|
318
322
|
getEntityClass,
|
|
319
323
|
getPackedEntityType,
|
|
320
324
|
getKindMeta,
|
|
@@ -332,6 +336,7 @@ export {
|
|
|
332
336
|
isContainer,
|
|
333
337
|
isNexus,
|
|
334
338
|
isPlot,
|
|
339
|
+
isHub,
|
|
335
340
|
} from './data/kind-registry'
|
|
336
341
|
export type {EntityTypeName, KindMeta, TemplateMeta} from './data/kind-registry'
|
|
337
342
|
export * from './capabilities'
|
package/src/managers/actions.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
type UInt64Type,
|
|
18
18
|
} from '@wharfkit/antelope'
|
|
19
19
|
import {BaseManager} from './base'
|
|
20
|
-
import {Coordinates, PRECISION, type CoordinatesType} from '../types'
|
|
20
|
+
import {Coordinates, PRECISION, type ClusterSlotType, type CoordinatesType} from '../types'
|
|
21
21
|
import {ServerContract} from '../contracts'
|
|
22
22
|
import {ATOMICASSETS_ABI, SHIPLOAD_COLLECTION} from '../nft/atomicassets'
|
|
23
23
|
import {getItem} from '../data/catalog'
|
|
@@ -435,22 +435,39 @@ export class ActionsManager extends BaseManager {
|
|
|
435
435
|
})
|
|
436
436
|
}
|
|
437
437
|
|
|
438
|
-
deploy(
|
|
438
|
+
deploy(
|
|
439
|
+
entityId: UInt64Type,
|
|
440
|
+
ref: ServerContract.ActionParams.Type.cargo_ref,
|
|
441
|
+
slot?: ClusterSlotType
|
|
442
|
+
): Action {
|
|
439
443
|
return this.server.action('deploy', {
|
|
440
444
|
id: UInt64.from(entityId),
|
|
441
445
|
ref,
|
|
446
|
+
slot: slot ? {hub: UInt64.from(slot.hub), gx: slot.gx, gy: slot.gy} : undefined,
|
|
442
447
|
})
|
|
443
448
|
}
|
|
444
449
|
|
|
445
|
-
claimplot(
|
|
446
|
-
entityId: UInt64Type,
|
|
447
|
-
targetItemId: UInt16Type,
|
|
448
|
-
coords: ServerContract.ActionParams.Type.coordinates
|
|
449
|
-
): Action {
|
|
450
|
+
claimplot(entityId: UInt64Type, targetItemId: UInt16Type, slot: ClusterSlotType): Action {
|
|
450
451
|
return this.server.action('claimplot', {
|
|
451
452
|
builder_id: UInt64.from(entityId),
|
|
452
453
|
target_item_id: UInt16.from(targetItemId),
|
|
453
|
-
|
|
454
|
+
slot: {hub: UInt64.from(slot.hub), gx: slot.gx, gy: slot.gy},
|
|
455
|
+
})
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
movetile(
|
|
459
|
+
hubId: UInt64Type,
|
|
460
|
+
fromGx: number,
|
|
461
|
+
fromGy: number,
|
|
462
|
+
toGx: number,
|
|
463
|
+
toGy: number
|
|
464
|
+
): Action {
|
|
465
|
+
return this.server.action('movetile', {
|
|
466
|
+
hub_id: UInt64.from(hubId),
|
|
467
|
+
from_gx: fromGx,
|
|
468
|
+
from_gy: fromGy,
|
|
469
|
+
to_gx: toGx,
|
|
470
|
+
to_gy: toGy,
|
|
454
471
|
})
|
|
455
472
|
}
|
|
456
473
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {describe, expect, test} from 'bun:test'
|
|
2
|
+
import {computeFreeCells} from './cluster'
|
|
3
|
+
|
|
4
|
+
describe('computeFreeCells', () => {
|
|
5
|
+
test('returns footprint cells that are not occupied', () => {
|
|
6
|
+
const footprint = [
|
|
7
|
+
{gx: 2, gy: 0},
|
|
8
|
+
{gx: 0, gy: 2},
|
|
9
|
+
{gx: 1, gy: 1},
|
|
10
|
+
]
|
|
11
|
+
const occupied = [{gx: 2, gy: 0, entity: 7}]
|
|
12
|
+
expect(computeFreeCells(footprint, occupied)).toEqual([
|
|
13
|
+
{gx: 0, gy: 2},
|
|
14
|
+
{gx: 1, gy: 1},
|
|
15
|
+
])
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('matches occupancy on signed coordinates', () => {
|
|
19
|
+
const footprint = [
|
|
20
|
+
{gx: -2, gy: 0},
|
|
21
|
+
{gx: 0, gy: -2},
|
|
22
|
+
{gx: -1, gy: 1},
|
|
23
|
+
]
|
|
24
|
+
const occupied = [{gx: 0, gy: -2, entity: 9}]
|
|
25
|
+
expect(computeFreeCells(footprint, occupied)).toEqual([
|
|
26
|
+
{gx: -2, gy: 0},
|
|
27
|
+
{gx: -1, gy: 1},
|
|
28
|
+
])
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('empty footprint yields no free cells', () => {
|
|
32
|
+
expect(computeFreeCells([], [])).toEqual([])
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('fully occupied footprint yields no free cells', () => {
|
|
36
|
+
const footprint = [{gx: 1, gy: 1}]
|
|
37
|
+
expect(computeFreeCells(footprint, [{gx: 1, gy: 1, entity: 3}])).toEqual([])
|
|
38
|
+
})
|
|
39
|
+
})
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {UInt16, type UInt16Type, UInt64, type UInt64Type} from '@wharfkit/antelope'
|
|
2
|
+
import {BaseManager} from './base'
|
|
3
|
+
import type {ServerContract} from '../contracts'
|
|
4
|
+
|
|
5
|
+
export interface GridCell {
|
|
6
|
+
gx: number
|
|
7
|
+
gy: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ClusterCell extends GridCell {
|
|
11
|
+
entity: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface Cluster {
|
|
15
|
+
root: number
|
|
16
|
+
cells: ClusterCell[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function computeFreeCells(footprint: GridCell[], occupied: ClusterCell[]): GridCell[] {
|
|
20
|
+
const taken = new Set(occupied.map((c) => `${c.gx},${c.gy}`))
|
|
21
|
+
return footprint.filter((c) => !taken.has(`${c.gx},${c.gy}`))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class ClusterManager extends BaseManager {
|
|
25
|
+
async getFootprint(itemId: UInt16Type): Promise<GridCell[]> {
|
|
26
|
+
const res = (await this.server.readonly('getfootprint', {
|
|
27
|
+
item_id: UInt16.from(itemId),
|
|
28
|
+
})) as ServerContract.Types.footprint_result
|
|
29
|
+
return res.cells.map((c) => ({gx: Number(c.gx), gy: Number(c.gy)}))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async getCluster(hubId: UInt64Type): Promise<Cluster> {
|
|
33
|
+
const res = (await this.server.readonly('getcluster', {
|
|
34
|
+
hub_id: UInt64.from(hubId),
|
|
35
|
+
})) as ServerContract.Types.cluster_row
|
|
36
|
+
return {
|
|
37
|
+
root: Number(res.root),
|
|
38
|
+
cells: res.cells.map((c) => ({
|
|
39
|
+
gx: Number(c.gx),
|
|
40
|
+
gy: Number(c.gy),
|
|
41
|
+
entity: Number(c.entity),
|
|
42
|
+
})),
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async freeCells(hubId: UInt64Type, hubItemId: UInt16Type): Promise<GridCell[]> {
|
|
47
|
+
const [footprint, cluster] = await Promise.all([
|
|
48
|
+
this.getFootprint(hubItemId),
|
|
49
|
+
this.getCluster(hubId),
|
|
50
|
+
])
|
|
51
|
+
return computeFreeCells(footprint, cluster.cells)
|
|
52
|
+
}
|
|
53
|
+
}
|
package/src/managers/context.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {LocationsManager} from './locations'
|
|
|
9
9
|
import {CoordinatesManager} from './coordinates'
|
|
10
10
|
import {EpochsManager} from './epochs'
|
|
11
11
|
import {ActionsManager} from './actions'
|
|
12
|
+
import {ClusterManager} from './cluster'
|
|
12
13
|
import {NftManager} from './nft'
|
|
13
14
|
import {SubscriptionsManager} from '../subscriptions/manager'
|
|
14
15
|
|
|
@@ -19,6 +20,7 @@ export class GameContext {
|
|
|
19
20
|
private _coordinates?: CoordinatesManager
|
|
20
21
|
private _epochs?: EpochsManager
|
|
21
22
|
private _actions?: ActionsManager
|
|
23
|
+
private _clusters?: ClusterManager
|
|
22
24
|
private _nft?: NftManager
|
|
23
25
|
private _subscriptions?: SubscriptionsManager
|
|
24
26
|
private _subscriptionsUrl?: string
|
|
@@ -75,6 +77,13 @@ export class GameContext {
|
|
|
75
77
|
return this._actions
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
get clusters(): ClusterManager {
|
|
81
|
+
if (!this._clusters) {
|
|
82
|
+
this._clusters = new ClusterManager(this)
|
|
83
|
+
}
|
|
84
|
+
return this._clusters
|
|
85
|
+
}
|
|
86
|
+
|
|
78
87
|
get nft(): NftManager {
|
|
79
88
|
if (!this._nft) {
|
|
80
89
|
this._nft = new NftManager(this)
|
package/src/managers/index.ts
CHANGED
|
@@ -8,6 +8,8 @@ export {LocationsManager} from './locations'
|
|
|
8
8
|
export type {LocationStratum} from './locations'
|
|
9
9
|
export {EpochsManager} from './epochs'
|
|
10
10
|
export {ActionsManager} from './actions'
|
|
11
|
+
export {ClusterManager, computeFreeCells} from './cluster'
|
|
12
|
+
export type {GridCell, ClusterCell, Cluster} from './cluster'
|
|
11
13
|
export {NftManager} from './nft'
|
|
12
14
|
export type {NftConfigForItem} from './nft'
|
|
13
15
|
export {PlotManager} from './plot'
|