@shipload/sdk 1.0.0-next.16 → 1.0.0-next.17
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 +95 -24
- package/lib/shipload.js +3277 -2803
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +3255 -2791
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +0 -1
- package/lib/testing.js +35 -26
- package/lib/testing.js.map +1 -1
- package/lib/testing.m.js +35 -26
- package/lib/testing.m.js.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/gathering.ts +15 -6
- package/src/capabilities/modules.ts +6 -0
- package/src/contracts/server.ts +0 -3
- package/src/data/capabilities.ts +6 -1
- package/src/data/capability-formulas.ts +7 -1
- package/src/data/colors.ts +12 -12
- package/src/data/item-ids.ts +13 -12
- package/src/data/items.json +7 -0
- package/src/data/metadata.ts +36 -23
- package/src/data/recipes.json +49 -0
- package/src/derivation/capabilities.ts +18 -7
- package/src/derivation/capability-mappings.ts +2 -0
- package/src/derivation/stratum.ts +5 -9
- package/src/index-module.ts +18 -2
- package/src/managers/actions.ts +104 -12
- package/src/managers/context.ts +9 -0
- package/src/managers/index.ts +2 -0
- package/src/managers/nft.ts +28 -0
- package/src/nft/atomicassets.ts +124 -1
- package/src/nft/buildImmutableData.ts +316 -0
- package/src/nft/description.ts +1 -3
- package/src/nft/index.ts +1 -0
- package/src/resolution/describe-module.ts +3 -4
- package/src/resolution/resolve-item.ts +0 -1
- package/src/shipload.ts +5 -0
- package/src/types.ts +1 -0
package/src/data/capabilities.ts
CHANGED
|
@@ -21,6 +21,7 @@ export const capabilityNames: string[] = [
|
|
|
21
21
|
'Crafter',
|
|
22
22
|
'Launch',
|
|
23
23
|
'Hauler',
|
|
24
|
+
'Battery',
|
|
24
25
|
]
|
|
25
26
|
|
|
26
27
|
export const capabilityAttributes: CapabilityAttribute[] = [
|
|
@@ -40,7 +41,6 @@ export const capabilityAttributes: CapabilityAttribute[] = [
|
|
|
40
41
|
{capability: 'Gathering', attribute: 'yield', description: 'Mass gathered per second'},
|
|
41
42
|
{capability: 'Gathering', attribute: 'drain', description: 'Energy consumed per gather'},
|
|
42
43
|
{capability: 'Gathering', attribute: 'depth', description: 'Maximum gather depth'},
|
|
43
|
-
{capability: 'Gathering', attribute: 'speed', description: 'Gathering speed/penetration'},
|
|
44
44
|
{capability: 'Warp', attribute: 'range', description: 'Maximum warp distance'},
|
|
45
45
|
{capability: 'Crafter', attribute: 'speed', description: 'Crafting time per item'},
|
|
46
46
|
{
|
|
@@ -67,6 +67,11 @@ export const capabilityAttributes: CapabilityAttribute[] = [
|
|
|
67
67
|
attribute: 'drain',
|
|
68
68
|
description: 'Energy consumed per target during haul-beam operation',
|
|
69
69
|
},
|
|
70
|
+
{
|
|
71
|
+
capability: 'Battery',
|
|
72
|
+
attribute: 'bonus',
|
|
73
|
+
description: 'Energy capacity bonus added by an installed Battery module',
|
|
74
|
+
},
|
|
70
75
|
]
|
|
71
76
|
|
|
72
77
|
const invertedAttributes = new Set(['drain', 'mass'])
|
|
@@ -12,6 +12,7 @@ export type SlotConsumerKind =
|
|
|
12
12
|
| 'storage'
|
|
13
13
|
| 'hauler'
|
|
14
14
|
| 'warp'
|
|
15
|
+
| 'battery'
|
|
15
16
|
| 'ship-t1'
|
|
16
17
|
| 'container-t1'
|
|
17
18
|
| 'warehouse-t1'
|
|
@@ -38,7 +39,6 @@ export const SLOT_FORMULAS: Record<SlotConsumerKind, Record<number, SlotConsumer
|
|
|
38
39
|
0: {capability: 'Gathering', attribute: 'yield'},
|
|
39
40
|
1: {capability: 'Gathering', attribute: 'depth'},
|
|
40
41
|
3: {capability: 'Gathering', attribute: 'drain'},
|
|
41
|
-
4: {capability: 'Gathering', attribute: 'speed'},
|
|
42
42
|
},
|
|
43
43
|
loader: {
|
|
44
44
|
0: {capability: 'Loader', attribute: 'mass'},
|
|
@@ -62,6 +62,12 @@ export const SLOT_FORMULAS: Record<SlotConsumerKind, Record<number, SlotConsumer
|
|
|
62
62
|
warp: {
|
|
63
63
|
0: {capability: 'Warp', attribute: 'range'},
|
|
64
64
|
},
|
|
65
|
+
battery: {
|
|
66
|
+
0: {capability: 'Battery', attribute: 'bonus'},
|
|
67
|
+
1: {capability: 'Battery', attribute: 'bonus'},
|
|
68
|
+
2: {capability: 'Battery', attribute: 'bonus'},
|
|
69
|
+
3: {capability: 'Battery', attribute: 'bonus'},
|
|
70
|
+
},
|
|
65
71
|
'ship-t1': ENTITY_HULL_SLOTS,
|
|
66
72
|
'container-t1': ENTITY_HULL_SLOTS,
|
|
67
73
|
'warehouse-t1': ENTITY_HULL_SLOTS,
|
package/src/data/colors.ts
CHANGED
|
@@ -43,16 +43,16 @@ export const componentIcon = '▣'
|
|
|
43
43
|
export const moduleIcon = '⬢'
|
|
44
44
|
|
|
45
45
|
export const itemAbbreviations: Record<number, string> = {
|
|
46
|
-
10001: '
|
|
47
|
-
10002: '
|
|
48
|
-
10003: '
|
|
49
|
-
10004: '
|
|
50
|
-
10005: '
|
|
51
|
-
10006: '
|
|
52
|
-
10007: '
|
|
53
|
-
10008: '
|
|
54
|
-
10009: '
|
|
55
|
-
10010: '
|
|
46
|
+
10001: 'PL',
|
|
47
|
+
10002: 'FR',
|
|
48
|
+
10003: 'PC',
|
|
49
|
+
10004: 'RS',
|
|
50
|
+
10005: 'BM',
|
|
51
|
+
10006: 'SN',
|
|
52
|
+
10007: 'PM',
|
|
53
|
+
10008: 'CR',
|
|
54
|
+
10009: 'RX',
|
|
55
|
+
10010: 'EM',
|
|
56
56
|
10100: 'EN',
|
|
57
57
|
10101: 'GN',
|
|
58
58
|
10102: 'EX',
|
|
@@ -64,7 +64,7 @@ export const itemAbbreviations: Record<number, string> = {
|
|
|
64
64
|
10200: 'CT',
|
|
65
65
|
10201: 'SH',
|
|
66
66
|
10202: 'WH',
|
|
67
|
-
20001: '
|
|
68
|
-
20002: '
|
|
67
|
+
20001: 'PL',
|
|
68
|
+
20002: 'FR',
|
|
69
69
|
20200: 'CT',
|
|
70
70
|
}
|
package/src/data/item-ids.ts
CHANGED
|
@@ -50,16 +50,16 @@ export const ITEM_BIOMASS_T7 = 507
|
|
|
50
50
|
export const ITEM_BIOMASS_T8 = 508
|
|
51
51
|
export const ITEM_BIOMASS_T9 = 509
|
|
52
52
|
export const ITEM_BIOMASS_T10 = 510
|
|
53
|
-
export const
|
|
54
|
-
export const
|
|
55
|
-
export const
|
|
56
|
-
export const
|
|
57
|
-
export const
|
|
58
|
-
export const
|
|
59
|
-
export const
|
|
60
|
-
export const
|
|
61
|
-
export const
|
|
62
|
-
export const
|
|
53
|
+
export const ITEM_PLATE = 10001
|
|
54
|
+
export const ITEM_FRAME = 10002
|
|
55
|
+
export const ITEM_PLASMA_CELL = 10003
|
|
56
|
+
export const ITEM_RESONATOR = 10004
|
|
57
|
+
export const ITEM_BEAM = 10005
|
|
58
|
+
export const ITEM_SENSOR = 10006
|
|
59
|
+
export const ITEM_POLYMER = 10007
|
|
60
|
+
export const ITEM_CERAMIC = 10008
|
|
61
|
+
export const ITEM_REACTOR = 10009
|
|
62
|
+
export const ITEM_EMITTER = 10010
|
|
63
63
|
export const ITEM_ENGINE_T1 = 10100
|
|
64
64
|
export const ITEM_GENERATOR_T1 = 10101
|
|
65
65
|
export const ITEM_GATHERER_T1 = 10102
|
|
@@ -68,11 +68,12 @@ export const ITEM_CRAFTER_T1 = 10104
|
|
|
68
68
|
export const ITEM_STORAGE_T1 = 10105
|
|
69
69
|
export const ITEM_HAULER_T1 = 10106
|
|
70
70
|
export const ITEM_WARP_T1 = 10107
|
|
71
|
+
export const ITEM_BATTERY_T1 = 10108
|
|
71
72
|
export const ITEM_CONTAINER_T1_PACKED = 10200
|
|
72
73
|
export const ITEM_SHIP_T1_PACKED = 10201
|
|
73
74
|
export const ITEM_WAREHOUSE_T1_PACKED = 10202
|
|
74
75
|
export const ITEM_EXTRACTOR_T1_PACKED = 10203
|
|
75
76
|
export const ITEM_FACTORY_T1_PACKED = 10204
|
|
76
|
-
export const
|
|
77
|
-
export const
|
|
77
|
+
export const ITEM_PLATE_T2 = 20001
|
|
78
|
+
export const ITEM_FRAME_T2 = 20002
|
|
78
79
|
export const ITEM_CONTAINER_T2_PACKED = 20200
|
package/src/data/items.json
CHANGED
package/src/data/metadata.ts
CHANGED
|
@@ -109,56 +109,63 @@ export const itemMetadata: Record<number, ItemMetadata> = {
|
|
|
109
109
|
|
|
110
110
|
// === Components (T1) ===
|
|
111
111
|
10001: {
|
|
112
|
-
name: '
|
|
113
|
-
description:
|
|
112
|
+
name: 'Plate',
|
|
113
|
+
description:
|
|
114
|
+
'Structural plating formed from ore. Used in hulls, containers, and storage modules.',
|
|
114
115
|
color: '#7B8D9E',
|
|
115
116
|
},
|
|
116
117
|
10002: {
|
|
117
|
-
name: '
|
|
118
|
+
name: 'Frame',
|
|
118
119
|
description:
|
|
119
|
-
'Composite
|
|
120
|
+
'Composite framing formed from fine regolith bound in biomass polymer. Dense enough to seal cargo holds, flexible enough to absorb vibration.',
|
|
120
121
|
color: '#C4A57B',
|
|
121
122
|
},
|
|
122
123
|
10003: {
|
|
123
|
-
name: '
|
|
124
|
-
description:
|
|
124
|
+
name: 'Plasma Cell',
|
|
125
|
+
description:
|
|
126
|
+
'High-energy gaseous storage cell. Volatile gas held under controlled thermal conditions.',
|
|
125
127
|
color: '#E86344',
|
|
126
128
|
},
|
|
127
129
|
10004: {
|
|
128
|
-
name: '
|
|
130
|
+
name: 'Resonator',
|
|
129
131
|
description:
|
|
130
|
-
'Crystalline
|
|
132
|
+
'Crystalline resonance lattice. Stores and releases charge through coherent oscillation.',
|
|
131
133
|
color: '#4ADBFF',
|
|
132
134
|
},
|
|
133
135
|
10005: {
|
|
134
|
-
name: '
|
|
135
|
-
description:
|
|
136
|
+
name: 'Beam',
|
|
137
|
+
description:
|
|
138
|
+
'Heavy-duty structural beam machined from refined ore. Strong enough to bear load, tolerant enough to survive harsh environments.',
|
|
136
139
|
color: '#7B8D9E',
|
|
137
140
|
},
|
|
138
141
|
10006: {
|
|
139
|
-
name: '
|
|
140
|
-
description:
|
|
142
|
+
name: 'Sensor',
|
|
143
|
+
description:
|
|
144
|
+
'Crystal-lattice sensing element with conductive and reflective properties. Reads signal and surface alike.',
|
|
141
145
|
color: '#4ADBFF',
|
|
142
146
|
},
|
|
143
147
|
10007: {
|
|
144
|
-
name: '
|
|
145
|
-
description:
|
|
148
|
+
name: 'Polymer',
|
|
149
|
+
description:
|
|
150
|
+
'Pliable biomass-derived polymer with high insulation. Flexible, durable, electrically inert.',
|
|
146
151
|
color: '#5A8B3E',
|
|
147
152
|
},
|
|
148
153
|
10008: {
|
|
149
|
-
name: '
|
|
150
|
-
description:
|
|
154
|
+
name: 'Ceramic',
|
|
155
|
+
description:
|
|
156
|
+
'Hardened fine-grained ceramic refined from regolith. Hard enough to cut, fine enough to finish.',
|
|
151
157
|
color: '#C4A57B',
|
|
152
158
|
},
|
|
153
159
|
10009: {
|
|
154
|
-
name: '
|
|
155
|
-
description:
|
|
160
|
+
name: 'Reactor',
|
|
161
|
+
description:
|
|
162
|
+
'Gas-pressurized vessel for controlled reactions. Vents heat and contains volatility.',
|
|
156
163
|
color: '#B8E4A0',
|
|
157
164
|
},
|
|
158
165
|
10010: {
|
|
159
|
-
name: '
|
|
166
|
+
name: 'Emitter',
|
|
160
167
|
description:
|
|
161
|
-
|
|
168
|
+
'Precision-formed crystal emitter array. Routes energy efficiently to a target lock.',
|
|
162
169
|
color: '#4ADBFF',
|
|
163
170
|
},
|
|
164
171
|
|
|
@@ -206,6 +213,12 @@ export const itemMetadata: Record<number, ItemMetadata> = {
|
|
|
206
213
|
'Folds local space-time around the hull, projecting the ship across vast distances in a single discharge of the entire energy reserve.',
|
|
207
214
|
color: '#9be4ff',
|
|
208
215
|
},
|
|
216
|
+
10108: {
|
|
217
|
+
name: 'Battery',
|
|
218
|
+
description:
|
|
219
|
+
'Extends energy capacity. Stores additional charge produced by generators, letting builds chain more high-drain actions between recharges.',
|
|
220
|
+
color: '#4ADBFF',
|
|
221
|
+
},
|
|
209
222
|
|
|
210
223
|
// === Entities (packed, T1) ===
|
|
211
224
|
10200: {
|
|
@@ -237,14 +250,14 @@ export const itemMetadata: Record<number, ItemMetadata> = {
|
|
|
237
250
|
|
|
238
251
|
// === Components (T2) ===
|
|
239
252
|
20001: {
|
|
240
|
-
name: '
|
|
253
|
+
name: 'Plate',
|
|
241
254
|
description: 'Advanced structural plating reinforced with tier 2 ore.',
|
|
242
255
|
color: '#9BADB8',
|
|
243
256
|
},
|
|
244
257
|
20002: {
|
|
245
|
-
name: '
|
|
258
|
+
name: 'Frame',
|
|
246
259
|
description:
|
|
247
|
-
'Advanced composite
|
|
260
|
+
'Advanced composite framing reinforced with tier 2 regolith and biomass polymer.',
|
|
248
261
|
color: '#C4A57B',
|
|
249
262
|
},
|
|
250
263
|
|
package/src/data/recipes.json
CHANGED
|
@@ -605,6 +605,55 @@
|
|
|
605
605
|
1
|
|
606
606
|
]
|
|
607
607
|
},
|
|
608
|
+
{
|
|
609
|
+
"outputItemId": 10108,
|
|
610
|
+
"outputMass": 90000,
|
|
611
|
+
"inputs": [
|
|
612
|
+
{
|
|
613
|
+
"itemId": 10003,
|
|
614
|
+
"quantity": 4
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
"itemId": 10007,
|
|
618
|
+
"quantity": 3
|
|
619
|
+
}
|
|
620
|
+
],
|
|
621
|
+
"statSlots": [
|
|
622
|
+
{
|
|
623
|
+
"sources": [
|
|
624
|
+
{
|
|
625
|
+
"inputIndex": 0,
|
|
626
|
+
"statIndex": 0
|
|
627
|
+
}
|
|
628
|
+
]
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
"sources": [
|
|
632
|
+
{
|
|
633
|
+
"inputIndex": 0,
|
|
634
|
+
"statIndex": 1
|
|
635
|
+
}
|
|
636
|
+
]
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
"sources": [
|
|
640
|
+
{
|
|
641
|
+
"inputIndex": 1,
|
|
642
|
+
"statIndex": 0
|
|
643
|
+
}
|
|
644
|
+
]
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
"sources": [
|
|
648
|
+
{
|
|
649
|
+
"inputIndex": 1,
|
|
650
|
+
"statIndex": 1
|
|
651
|
+
}
|
|
652
|
+
]
|
|
653
|
+
}
|
|
654
|
+
],
|
|
655
|
+
"blendWeights": []
|
|
656
|
+
},
|
|
608
657
|
{
|
|
609
658
|
"outputItemId": 10200,
|
|
610
659
|
"outputMass": 80000,
|
|
@@ -75,18 +75,15 @@ export function computeGathererCapabilities(
|
|
|
75
75
|
yield: number
|
|
76
76
|
drain: number
|
|
77
77
|
depth: number
|
|
78
|
-
speed: number
|
|
79
78
|
} {
|
|
80
79
|
const str = stats.strength
|
|
81
80
|
const con = stats.conductivity
|
|
82
|
-
const ref = stats.reflectivity
|
|
83
81
|
const tol = stats.tolerance
|
|
84
82
|
|
|
85
83
|
return {
|
|
86
84
|
yield: 200 + str,
|
|
87
85
|
drain: Math.max(250, 1250 - Math.floor((con * 25) / 20)),
|
|
88
86
|
depth: gathererDepthForTier(tol, tier),
|
|
89
|
-
speed: 100 + Math.floor((ref * 4) / 5),
|
|
90
87
|
}
|
|
91
88
|
}
|
|
92
89
|
|
|
@@ -163,6 +160,7 @@ import {
|
|
|
163
160
|
} from '../data/item-ids'
|
|
164
161
|
import {
|
|
165
162
|
getModuleCapabilityType,
|
|
163
|
+
MODULE_BATTERY,
|
|
166
164
|
MODULE_ENGINE,
|
|
167
165
|
MODULE_GENERATOR,
|
|
168
166
|
MODULE_GATHERER,
|
|
@@ -222,7 +220,7 @@ export interface ComputedCapabilities {
|
|
|
222
220
|
capacity: number
|
|
223
221
|
engines?: {thrust: number; drain: number}
|
|
224
222
|
generator?: {capacity: number; recharge: number}
|
|
225
|
-
gatherer?: {yield: number; drain: number; depth: number
|
|
223
|
+
gatherer?: {yield: number; drain: number; depth: number}
|
|
226
224
|
loaders?: {mass: number; thrust: number; quantity: number}
|
|
227
225
|
crafter?: {speed: number; drain: number}
|
|
228
226
|
hauler?: {capacity: number; efficiency: number; drain: number}
|
|
@@ -251,7 +249,6 @@ export function computeEntityCapabilities(
|
|
|
251
249
|
let totalGathYield = 0
|
|
252
250
|
let totalGathDrain = 0
|
|
253
251
|
let maxGathDepth = 0
|
|
254
|
-
let totalGathSpeed = 0
|
|
255
252
|
let hasGatherer = false
|
|
256
253
|
|
|
257
254
|
let totalStorageBonus = 0
|
|
@@ -270,6 +267,9 @@ export function computeEntityCapabilities(
|
|
|
270
267
|
let totalWarpRange = 0
|
|
271
268
|
let hasWarp = false
|
|
272
269
|
|
|
270
|
+
let totalBatteryStatSum = 0
|
|
271
|
+
let batteryCount = 0
|
|
272
|
+
|
|
273
273
|
for (const mod of modules) {
|
|
274
274
|
const item = getItem(mod.itemId)
|
|
275
275
|
const modType = getModuleCapabilityType(mod.itemId)
|
|
@@ -294,7 +294,6 @@ export function computeEntityCapabilities(
|
|
|
294
294
|
totalGathYield += applySlotMultiplier(caps.yield, amp)
|
|
295
295
|
totalGathDrain += caps.drain
|
|
296
296
|
if (caps.depth > maxGathDepth) maxGathDepth = caps.depth
|
|
297
|
-
totalGathSpeed += applySlotMultiplier(caps.speed, amp)
|
|
298
297
|
} else if (modType === MODULE_LOADER) {
|
|
299
298
|
hasLoader = true
|
|
300
299
|
const caps = computeLoaderCapabilities(decodedStats)
|
|
@@ -320,9 +319,22 @@ export function computeEntityCapabilities(
|
|
|
320
319
|
hasWarp = true
|
|
321
320
|
const caps = computeWarpCapabilities(decodedStats)
|
|
322
321
|
totalWarpRange += applySlotMultiplier(caps.range, amp)
|
|
322
|
+
} else if (modType === MODULE_BATTERY) {
|
|
323
|
+
batteryCount++
|
|
324
|
+
const vol = decodedStats.volatility ?? 0
|
|
325
|
+
const thm = decodedStats.thermal ?? 0
|
|
326
|
+
const pla = decodedStats.plasticity ?? 0
|
|
327
|
+
const ins = decodedStats.insulation ?? 0
|
|
328
|
+
totalBatteryStatSum += vol + thm + pla + ins
|
|
323
329
|
}
|
|
324
330
|
}
|
|
325
331
|
|
|
332
|
+
if (hasGenerator && batteryCount > 0) {
|
|
333
|
+
const genCapBase = totalGenCapacity
|
|
334
|
+
const bonusPctNum = 10 * batteryCount + Math.floor((totalBatteryStatSum * 10) / 2997)
|
|
335
|
+
totalGenCapacity += Math.floor((genCapBase * bonusPctNum) / 100)
|
|
336
|
+
}
|
|
337
|
+
|
|
326
338
|
const result: ComputedCapabilities = {
|
|
327
339
|
hullmass: computeBaseHullmass(stats) + installedModuleMass,
|
|
328
340
|
capacity: baseCapacity + totalStorageBonus,
|
|
@@ -342,7 +354,6 @@ export function computeEntityCapabilities(
|
|
|
342
354
|
yield: clampUint16(totalGathYield),
|
|
343
355
|
drain: totalGathDrain,
|
|
344
356
|
depth: maxGathDepth,
|
|
345
|
-
speed: clampUint16(totalGathSpeed),
|
|
346
357
|
}
|
|
347
358
|
}
|
|
348
359
|
if (hasLoader) {
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
ITEM_STORAGE_T1,
|
|
17
17
|
ITEM_HAULER_T1,
|
|
18
18
|
ITEM_WARP_T1,
|
|
19
|
+
ITEM_BATTERY_T1,
|
|
19
20
|
ITEM_SHIP_T1_PACKED,
|
|
20
21
|
ITEM_CONTAINER_T1_PACKED,
|
|
21
22
|
ITEM_WAREHOUSE_T1_PACKED,
|
|
@@ -32,6 +33,7 @@ export const KIND_TO_ITEM_ID: Record<SlotConsumerKind, number> = {
|
|
|
32
33
|
storage: ITEM_STORAGE_T1,
|
|
33
34
|
hauler: ITEM_HAULER_T1,
|
|
34
35
|
warp: ITEM_WARP_T1,
|
|
36
|
+
battery: ITEM_BATTERY_T1,
|
|
35
37
|
'ship-t1': ITEM_SHIP_T1_PACKED,
|
|
36
38
|
'container-t1': ITEM_CONTAINER_T1_PACKED,
|
|
37
39
|
'warehouse-t1': ITEM_WAREHOUSE_T1_PACKED,
|
|
@@ -76,15 +76,11 @@ export function deriveStratum(
|
|
|
76
76
|
(BigInt(bytes[14]) << 8n) |
|
|
77
77
|
BigInt(bytes[15])
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (stratum > 1) {
|
|
85
|
-
depthBonus = (50 * Math.log(stratum)) / Math.log(65535)
|
|
86
|
-
}
|
|
87
|
-
const richness = Math.min(Math.floor(baseRichness + depthBonus), 1000)
|
|
79
|
+
let byteSum = 0
|
|
80
|
+
for (let i = 22; i <= 33; i++) byteSum += bytes[i]
|
|
81
|
+
const z = (byteSum - 1530) / 256
|
|
82
|
+
const roll = 500 + 100 * z
|
|
83
|
+
const richness = Math.max(1, Math.min(999, Math.round(roll)))
|
|
88
84
|
|
|
89
85
|
return {itemId: selectedItemId, seed: seedBigInt, richness, reserve}
|
|
90
86
|
}
|
package/src/index-module.ts
CHANGED
|
@@ -47,8 +47,9 @@ export {
|
|
|
47
47
|
LocationsManager,
|
|
48
48
|
EpochsManager,
|
|
49
49
|
ActionsManager,
|
|
50
|
+
NftManager,
|
|
50
51
|
} from './managers'
|
|
51
|
-
export type {LocationStratum} from './managers'
|
|
52
|
+
export type {LocationStratum, NftConfigForItem} from './managers'
|
|
52
53
|
export type {EntityRefInput} from './managers/actions'
|
|
53
54
|
|
|
54
55
|
export {
|
|
@@ -331,10 +332,25 @@ export type {
|
|
|
331
332
|
export {deserializeAtomicData} from './nft/atomicdata'
|
|
332
333
|
export type {SchemaField, RawData} from './nft/atomicdata'
|
|
333
334
|
|
|
335
|
+
export {
|
|
336
|
+
buildImmutableData,
|
|
337
|
+
buildResourceImmutable,
|
|
338
|
+
buildComponentImmutable,
|
|
339
|
+
buildModuleImmutable,
|
|
340
|
+
buildEntityImmutable,
|
|
341
|
+
computeNftImageUrl,
|
|
342
|
+
} from './nft/buildImmutableData'
|
|
343
|
+
export type {
|
|
344
|
+
AtomicAttributeType,
|
|
345
|
+
ImmutableEntry,
|
|
346
|
+
ImmutableModuleSlot,
|
|
347
|
+
} from './nft/buildImmutableData'
|
|
348
|
+
|
|
334
349
|
export {
|
|
335
350
|
fetchAtomicAssetsForOwner,
|
|
336
351
|
fetchAtomicSchemas,
|
|
337
352
|
decodeAtomicAsset,
|
|
353
|
+
buildMintAssetAction,
|
|
338
354
|
ATOMICASSETS_ACCOUNT,
|
|
339
355
|
SHIPLOAD_COLLECTION,
|
|
340
356
|
} from './nft/atomicassets'
|
|
@@ -343,6 +359,7 @@ export type {
|
|
|
343
359
|
AtomicSchemaRow,
|
|
344
360
|
DecodedAtomicAsset,
|
|
345
361
|
FetchAssetsOptions,
|
|
362
|
+
MintAssetParams,
|
|
346
363
|
} from './nft/atomicassets'
|
|
347
364
|
|
|
348
365
|
export {
|
|
@@ -360,7 +377,6 @@ export {
|
|
|
360
377
|
computeGathererYield,
|
|
361
378
|
computeGathererDrain,
|
|
362
379
|
computeGathererDepth,
|
|
363
|
-
computeGathererSpeed,
|
|
364
380
|
computeLoaderMass,
|
|
365
381
|
computeLoaderThrust,
|
|
366
382
|
computeCrafterSpeed,
|
package/src/managers/actions.ts
CHANGED
|
@@ -13,6 +13,12 @@ import {
|
|
|
13
13
|
import {BaseManager} from './base'
|
|
14
14
|
import type {CoordinatesType} from '../types'
|
|
15
15
|
import {ServerContract} from '../contracts'
|
|
16
|
+
import {
|
|
17
|
+
buildImmutableData,
|
|
18
|
+
type ImmutableModuleSlot,
|
|
19
|
+
moduleSlotsForImmutable,
|
|
20
|
+
} from '../nft/buildImmutableData'
|
|
21
|
+
import {buildMintAssetAction, SHIPLOAD_COLLECTION} from '../nft/atomicassets'
|
|
16
22
|
|
|
17
23
|
export type EntityRefInput = {
|
|
18
24
|
entityType: NameType
|
|
@@ -183,20 +189,81 @@ export class ActionsManager extends BaseManager {
|
|
|
183
189
|
})
|
|
184
190
|
}
|
|
185
191
|
|
|
186
|
-
|
|
192
|
+
private async buildPairedMintAction(args: {
|
|
193
|
+
owner: NameType
|
|
194
|
+
itemId: number
|
|
195
|
+
quantity: number
|
|
196
|
+
stats: bigint
|
|
197
|
+
originX: number
|
|
198
|
+
originY: number
|
|
199
|
+
moduleSlots: ImmutableModuleSlot[]
|
|
200
|
+
}): Promise<Action> {
|
|
201
|
+
const nftCfg = await this.context.nft.getNftConfigForItem(args.itemId)
|
|
202
|
+
if (!nftCfg) {
|
|
203
|
+
throw new Error(`item ${args.itemId} has no nftconfig`)
|
|
204
|
+
}
|
|
205
|
+
const immutableData = buildImmutableData(
|
|
206
|
+
args.itemId,
|
|
207
|
+
args.quantity,
|
|
208
|
+
args.stats,
|
|
209
|
+
args.originX,
|
|
210
|
+
args.originY,
|
|
211
|
+
args.moduleSlots
|
|
212
|
+
)
|
|
213
|
+
return buildMintAssetAction({
|
|
214
|
+
authorizedMinter: Name.from(args.owner),
|
|
215
|
+
collectionName: SHIPLOAD_COLLECTION,
|
|
216
|
+
schemaName: nftCfg.schemaName,
|
|
217
|
+
templateId: nftCfg.templateId,
|
|
218
|
+
newAssetOwner: Name.from(args.owner),
|
|
219
|
+
immutableData,
|
|
220
|
+
})
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async wrap(
|
|
187
224
|
owner: NameType,
|
|
188
225
|
entityId: UInt64Type,
|
|
189
226
|
nexusId: UInt64Type,
|
|
190
227
|
cargoId: UInt64Type,
|
|
191
228
|
quantity: UInt64Type
|
|
192
|
-
): Action {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
229
|
+
): Promise<Action[]> {
|
|
230
|
+
const cargoIdKey = UInt64.from(cargoId)
|
|
231
|
+
const entityIdKey = UInt64.from(entityId)
|
|
232
|
+
const [cargoRow, entityRow] = (await Promise.all([
|
|
233
|
+
this.server.table('cargo').get(cargoIdKey),
|
|
234
|
+
this.server.table('entity').get(entityIdKey),
|
|
235
|
+
])) as [
|
|
236
|
+
ServerContract.Types.cargo_row | undefined,
|
|
237
|
+
ServerContract.Types.entity_row | undefined,
|
|
238
|
+
]
|
|
239
|
+
if (!cargoRow) {
|
|
240
|
+
throw new Error(`cargo row ${cargoIdKey} not found`)
|
|
241
|
+
}
|
|
242
|
+
if (!entityRow) {
|
|
243
|
+
throw new Error(`entity ${entityIdKey} not found`)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const quantityValue = UInt64.from(quantity)
|
|
247
|
+
const mintAction = await this.buildPairedMintAction({
|
|
248
|
+
owner,
|
|
249
|
+
itemId: Number(cargoRow.item_id.toString()),
|
|
250
|
+
quantity: Number(quantityValue.toString()),
|
|
251
|
+
stats: BigInt(cargoRow.stats.toString()),
|
|
252
|
+
originX: Number(entityRow.coordinates.x.toString()),
|
|
253
|
+
originY: Number(entityRow.coordinates.y.toString()),
|
|
254
|
+
moduleSlots: moduleSlotsForImmutable(cargoRow.modules),
|
|
199
255
|
})
|
|
256
|
+
|
|
257
|
+
return [
|
|
258
|
+
this.server.action('wrap', {
|
|
259
|
+
owner: Name.from(owner),
|
|
260
|
+
entity_id: UInt64.from(entityId),
|
|
261
|
+
nexus_id: UInt64.from(nexusId),
|
|
262
|
+
cargo_id: cargoIdKey,
|
|
263
|
+
quantity: quantityValue,
|
|
264
|
+
}),
|
|
265
|
+
mintAction,
|
|
266
|
+
]
|
|
200
267
|
}
|
|
201
268
|
|
|
202
269
|
undeploy(hostId: UInt64Type, targetId: UInt64Type): Action {
|
|
@@ -206,11 +273,36 @@ export class ActionsManager extends BaseManager {
|
|
|
206
273
|
})
|
|
207
274
|
}
|
|
208
275
|
|
|
209
|
-
wrapEntity(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
276
|
+
async wrapEntity(
|
|
277
|
+
owner: NameType,
|
|
278
|
+
entityId: UInt64Type,
|
|
279
|
+
nexusId: UInt64Type
|
|
280
|
+
): Promise<Action[]> {
|
|
281
|
+
const entityIdKey = UInt64.from(entityId)
|
|
282
|
+
const entityRow = (await this.server.table('entity').get(entityIdKey)) as
|
|
283
|
+
| ServerContract.Types.entity_row
|
|
284
|
+
| undefined
|
|
285
|
+
if (!entityRow) {
|
|
286
|
+
throw new Error(`entity ${entityIdKey} not found`)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const mintAction = await this.buildPairedMintAction({
|
|
290
|
+
owner,
|
|
291
|
+
itemId: Number(entityRow.item_id.toString()),
|
|
292
|
+
quantity: 1,
|
|
293
|
+
stats: BigInt(entityRow.stats.toString()),
|
|
294
|
+
originX: Number(entityRow.coordinates.x.toString()),
|
|
295
|
+
originY: Number(entityRow.coordinates.y.toString()),
|
|
296
|
+
moduleSlots: moduleSlotsForImmutable(entityRow.modules),
|
|
213
297
|
})
|
|
298
|
+
|
|
299
|
+
return [
|
|
300
|
+
this.server.action('wrapentity', {
|
|
301
|
+
entity_id: entityIdKey,
|
|
302
|
+
nexus_id: UInt64.from(nexusId),
|
|
303
|
+
}),
|
|
304
|
+
mintAction,
|
|
305
|
+
]
|
|
214
306
|
}
|
|
215
307
|
|
|
216
308
|
deploynft(owner: NameType, assetId: UInt64Type, targetNexusId: UInt64Type): Action {
|
package/src/managers/context.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {PlayersManager} from './players'
|
|
|
8
8
|
import {LocationsManager} from './locations'
|
|
9
9
|
import {EpochsManager} from './epochs'
|
|
10
10
|
import {ActionsManager} from './actions'
|
|
11
|
+
import {NftManager} from './nft'
|
|
11
12
|
import {SubscriptionsManager} from '../subscriptions/manager'
|
|
12
13
|
|
|
13
14
|
export class GameContext {
|
|
@@ -16,6 +17,7 @@ export class GameContext {
|
|
|
16
17
|
private _locations?: LocationsManager
|
|
17
18
|
private _epochs?: EpochsManager
|
|
18
19
|
private _actions?: ActionsManager
|
|
20
|
+
private _nft?: NftManager
|
|
19
21
|
private _subscriptions?: SubscriptionsManager
|
|
20
22
|
private _subscriptionsUrl?: string
|
|
21
23
|
|
|
@@ -63,6 +65,13 @@ export class GameContext {
|
|
|
63
65
|
return this._actions
|
|
64
66
|
}
|
|
65
67
|
|
|
68
|
+
get nft(): NftManager {
|
|
69
|
+
if (!this._nft) {
|
|
70
|
+
this._nft = new NftManager(this)
|
|
71
|
+
}
|
|
72
|
+
return this._nft
|
|
73
|
+
}
|
|
74
|
+
|
|
66
75
|
setSubscriptionsUrl(url: string) {
|
|
67
76
|
this._subscriptionsUrl = url
|
|
68
77
|
}
|