@shipload/sdk 2.0.0-rc20 → 2.0.0-rc22
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 +193 -117
- package/lib/shipload.js +2992 -1945
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +2935 -1932
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/modules.ts +36 -7
- package/src/capabilities/storage.ts +1 -1
- package/src/contracts/server.ts +69 -1
- package/src/data/entities.json +50 -0
- package/src/data/item-ids.ts +75 -0
- package/src/data/items.json +250 -15
- package/src/data/metadata.ts +208 -0
- package/src/data/recipes-runtime.ts +65 -0
- package/src/data/recipes.json +878 -0
- package/src/derivation/crafting.ts +172 -111
- package/src/derivation/resources.ts +14 -38
- package/src/entities/container.ts +4 -4
- package/src/entities/entity-inventory.ts +2 -2
- package/src/entities/makers.ts +18 -10
- package/src/entities/ship-deploy.ts +8 -8
- package/src/entities/ship.ts +4 -4
- package/src/index-module.ts +10 -48
- package/src/market/items.ts +23 -75
- package/src/nft/description.ts +7 -7
- package/src/nft/deserializers.ts +6 -4
- package/src/resolution/display-name.ts +8 -4
- package/src/resolution/resolve-item.ts +80 -65
- package/src/scheduling/projection.ts +49 -29
- package/src/travel/travel.ts +8 -7
- package/src/types.ts +27 -33
- package/src/data/recipes.ts +0 -587
package/src/index-module.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export * from './contracts'
|
|
2
2
|
export * from './errors'
|
|
3
3
|
export * from './types'
|
|
4
|
+
export * from './data/item-ids'
|
|
5
|
+
export * from './data/recipes-runtime'
|
|
4
6
|
|
|
5
7
|
import {ServerContract} from './contracts'
|
|
6
8
|
|
|
@@ -141,9 +143,16 @@ export {
|
|
|
141
143
|
createProjectedEntity,
|
|
142
144
|
projectEntity,
|
|
143
145
|
projectEntityAt,
|
|
146
|
+
projectFromCurrentState,
|
|
147
|
+
projectFromCurrentStateAt,
|
|
144
148
|
validateSchedule,
|
|
145
149
|
} from './scheduling/projection'
|
|
146
|
-
export type {
|
|
150
|
+
export type {
|
|
151
|
+
Projectable,
|
|
152
|
+
ProjectableSnapshot,
|
|
153
|
+
ProjectedEntity,
|
|
154
|
+
ProjectionOptions,
|
|
155
|
+
} from './scheduling/projection'
|
|
147
156
|
|
|
148
157
|
export * from './types/capabilities'
|
|
149
158
|
export * from './types/entity'
|
|
@@ -182,51 +191,6 @@ export {
|
|
|
182
191
|
} from './data/capabilities'
|
|
183
192
|
export type {CapabilityAttribute, StatMapping} from './data/capabilities'
|
|
184
193
|
|
|
185
|
-
export {
|
|
186
|
-
components,
|
|
187
|
-
entityRecipes,
|
|
188
|
-
moduleRecipes,
|
|
189
|
-
getComponentById,
|
|
190
|
-
getEntityRecipe,
|
|
191
|
-
getEntityRecipeByItemId,
|
|
192
|
-
getModuleRecipe,
|
|
193
|
-
getModuleRecipeByItemId,
|
|
194
|
-
getAllCraftableItems,
|
|
195
|
-
getComponentsForCategory,
|
|
196
|
-
getComponentsForStat,
|
|
197
|
-
ITEM_HULL_PLATES,
|
|
198
|
-
ITEM_CARGO_LINING,
|
|
199
|
-
ITEM_CONTAINER_T1_PACKED,
|
|
200
|
-
ITEM_THRUSTER_CORE,
|
|
201
|
-
ITEM_POWER_CELL,
|
|
202
|
-
ITEM_ENGINE_T1,
|
|
203
|
-
ITEM_GENERATOR_T1,
|
|
204
|
-
ITEM_SHIP_T1_PACKED,
|
|
205
|
-
ITEM_WAREHOUSE_T1_PACKED,
|
|
206
|
-
ITEM_MATTER_CONDUIT,
|
|
207
|
-
ITEM_SURVEY_PROBE,
|
|
208
|
-
ITEM_CARGO_ARM,
|
|
209
|
-
ITEM_TOOL_BIT,
|
|
210
|
-
ITEM_REACTION_CHAMBER,
|
|
211
|
-
ITEM_GATHERER_T1,
|
|
212
|
-
ITEM_LOADER_T1,
|
|
213
|
-
ITEM_CRAFTER_T1,
|
|
214
|
-
ITEM_STORAGE_T1,
|
|
215
|
-
ITEM_HULL_PLATES_T2,
|
|
216
|
-
ITEM_CARGO_LINING_T2,
|
|
217
|
-
ITEM_CONTAINER_T2_PACKED,
|
|
218
|
-
ITEM_FOCUSING_ARRAY,
|
|
219
|
-
} from './data/recipes'
|
|
220
|
-
export type {
|
|
221
|
-
ComponentDefinition,
|
|
222
|
-
ComponentStat,
|
|
223
|
-
RecipeInput,
|
|
224
|
-
EntityRecipe,
|
|
225
|
-
ModuleRecipe,
|
|
226
|
-
ModuleSlot,
|
|
227
|
-
CraftableItem,
|
|
228
|
-
} from './data/recipes'
|
|
229
|
-
|
|
230
194
|
export {
|
|
231
195
|
encodeStats,
|
|
232
196
|
encodeGatheredCargoStats,
|
|
@@ -239,7 +203,6 @@ export {
|
|
|
239
203
|
computeEntityStats,
|
|
240
204
|
blendCargoStacks,
|
|
241
205
|
blendCrossGroup,
|
|
242
|
-
categoryItemMass,
|
|
243
206
|
computeInputMass,
|
|
244
207
|
computeCraftedOutputStats,
|
|
245
208
|
} from './derivation/crafting'
|
|
@@ -321,7 +284,6 @@ export {
|
|
|
321
284
|
computeCrafterDrain,
|
|
322
285
|
} from './nft/description'
|
|
323
286
|
|
|
324
|
-
export {getEntitySlotLayout} from './data/recipes'
|
|
325
287
|
export {
|
|
326
288
|
ITEM_TYPE_RESOURCE,
|
|
327
289
|
ITEM_TYPE_COMPONENT,
|
package/src/market/items.ts
CHANGED
|
@@ -1,93 +1,41 @@
|
|
|
1
1
|
import {UInt16, UInt16Type} from '@wharfkit/antelope'
|
|
2
|
+
import items from '../data/items.json'
|
|
3
|
+
import {itemMetadata} from '../data/metadata'
|
|
2
4
|
import {Item} from '../types'
|
|
3
|
-
import itemsData from '../data/items.json'
|
|
4
|
-
import {computeInputMass} from '../derivation/crafting'
|
|
5
|
-
import {getComponentById, getEntityRecipeByItemId, getModuleRecipeByItemId} from '../data/recipes'
|
|
6
5
|
|
|
7
|
-
const itemsById
|
|
8
|
-
const synthesizedCache: Map<number, Item> = new Map()
|
|
6
|
+
const itemsById = new Map<number, Item>()
|
|
9
7
|
|
|
10
|
-
for (const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
interface RecipeSource {
|
|
26
|
-
name: string
|
|
27
|
-
description: string
|
|
28
|
-
mass: number
|
|
29
|
-
color: string
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function synthesizeItem(id: number, source: RecipeSource): Item {
|
|
33
|
-
return Item.from({
|
|
34
|
-
id,
|
|
35
|
-
name: source.name,
|
|
36
|
-
description: source.description,
|
|
37
|
-
mass: source.mass,
|
|
38
|
-
category: 'ore',
|
|
39
|
-
tier: 't1',
|
|
40
|
-
color: source.color,
|
|
8
|
+
for (const raw of items as any[]) {
|
|
9
|
+
const meta = itemMetadata[raw.id]
|
|
10
|
+
if (!meta) {
|
|
11
|
+
throw new Error(`Missing metadata for item ${raw.id}. Add an entry to metadata.ts.`)
|
|
12
|
+
}
|
|
13
|
+
itemsById.set(raw.id, {
|
|
14
|
+
id: raw.id,
|
|
15
|
+
name: meta.name,
|
|
16
|
+
description: meta.description,
|
|
17
|
+
color: meta.color,
|
|
18
|
+
mass: raw.mass,
|
|
19
|
+
type: raw.type,
|
|
20
|
+
tier: raw.tier,
|
|
21
|
+
category: raw.category,
|
|
22
|
+
moduleType: raw.type === 'module' ? raw.subtype : undefined,
|
|
41
23
|
})
|
|
42
24
|
}
|
|
43
25
|
|
|
44
|
-
|
|
45
|
-
const component = getComponentById(id)
|
|
46
|
-
if (component) return synthesizeItem(id, component)
|
|
47
|
-
|
|
48
|
-
const entityRecipe = getEntityRecipeByItemId(id)
|
|
49
|
-
if (entityRecipe) {
|
|
50
|
-
return synthesizeItem(id, {
|
|
51
|
-
...entityRecipe,
|
|
52
|
-
mass: computeInputMass(entityRecipe.id, 'entity'),
|
|
53
|
-
})
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const moduleRecipe = getModuleRecipeByItemId(id)
|
|
57
|
-
if (moduleRecipe) {
|
|
58
|
-
return synthesizeItem(id, {
|
|
59
|
-
...moduleRecipe,
|
|
60
|
-
mass: computeInputMass(moduleRecipe.id, 'module'),
|
|
61
|
-
})
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return undefined
|
|
65
|
-
}
|
|
26
|
+
export const itemIds = Array.from(itemsById.keys())
|
|
66
27
|
|
|
67
28
|
export function getItem(itemId: UInt16Type): Item {
|
|
68
29
|
const id = UInt16.from(itemId).toNumber()
|
|
69
|
-
const
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
const synthesized = synthesizeFromRecipes(id)
|
|
73
|
-
if (synthesized) {
|
|
74
|
-
synthesizedCache.set(id, synthesized)
|
|
75
|
-
return synthesized
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
throw new Error(`Item with id ${id} not found`)
|
|
30
|
+
const item = itemsById.get(id)
|
|
31
|
+
if (!item) throw new Error(`Unknown item id: ${id}`)
|
|
32
|
+
return item
|
|
79
33
|
}
|
|
80
34
|
|
|
81
35
|
export function getItems(): Item[] {
|
|
82
36
|
return Array.from(itemsById.values())
|
|
83
37
|
}
|
|
84
38
|
|
|
85
|
-
/**
|
|
86
|
-
* @internal Test-only: registers an item into the in-memory map. Tests should
|
|
87
|
-
* use `test/item-mock.ts`'s `registerMockItem()` instead of calling this directly.
|
|
88
|
-
*/
|
|
89
39
|
export function __registerItemInternal(item: Item): void {
|
|
90
|
-
|
|
91
|
-
itemsById.set(id, item)
|
|
92
|
-
synthesizedCache.delete(id)
|
|
40
|
+
itemsById.set(item.id, item)
|
|
93
41
|
}
|
package/src/nft/description.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getModuleCapabilityType,
|
|
3
|
-
ITEM_CRAFTER_T1,
|
|
4
|
-
ITEM_ENGINE_T1,
|
|
5
|
-
ITEM_GATHERER_T1,
|
|
6
|
-
ITEM_GENERATOR_T1,
|
|
7
|
-
ITEM_LOADER_T1,
|
|
8
|
-
ITEM_STORAGE_T1,
|
|
9
3
|
MODULE_CRAFTER,
|
|
10
4
|
MODULE_ENGINE,
|
|
11
5
|
MODULE_GATHERER,
|
|
@@ -16,9 +10,15 @@ import {
|
|
|
16
10
|
import {
|
|
17
11
|
ITEM_CONTAINER_T1_PACKED,
|
|
18
12
|
ITEM_CONTAINER_T2_PACKED,
|
|
13
|
+
ITEM_CRAFTER_T1,
|
|
14
|
+
ITEM_ENGINE_T1,
|
|
15
|
+
ITEM_GATHERER_T1,
|
|
16
|
+
ITEM_GENERATOR_T1,
|
|
17
|
+
ITEM_LOADER_T1,
|
|
19
18
|
ITEM_SHIP_T1_PACKED,
|
|
19
|
+
ITEM_STORAGE_T1,
|
|
20
20
|
ITEM_WAREHOUSE_T1_PACKED,
|
|
21
|
-
} from '../data/
|
|
21
|
+
} from '../data/item-ids'
|
|
22
22
|
import {decodeStat} from '../derivation/crafting'
|
|
23
23
|
|
|
24
24
|
function idiv(a: number, b: number): number {
|
package/src/nft/deserializers.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {getEntityLayout} from '../data/recipes-runtime'
|
|
2
|
+
import {moduleSlotTypeToCode} from '../capabilities/modules'
|
|
2
3
|
import {
|
|
3
4
|
ITEM_TYPE_COMPONENT,
|
|
4
5
|
ITEM_TYPE_ENTITY,
|
|
@@ -53,10 +54,11 @@ export function deserializeEntity(data: Record<string, any>, itemId: number): NF
|
|
|
53
54
|
const base = readCommonBase(data)
|
|
54
55
|
const moduleItems: number[] = (data.module_items ?? []).map((v: any) => Number(v))
|
|
55
56
|
const moduleStats: string[] = (data.module_stats ?? []).map((v: any) => String(v))
|
|
56
|
-
const layout =
|
|
57
|
+
const layout = getEntityLayout(itemId)
|
|
58
|
+
const slots = layout?.slots ?? []
|
|
57
59
|
|
|
58
|
-
const modules: NFTModuleSlot[] =
|
|
59
|
-
type: slot.type,
|
|
60
|
+
const modules: NFTModuleSlot[] = slots.map((slot, i) => ({
|
|
61
|
+
type: moduleSlotTypeToCode(slot.type),
|
|
60
62
|
installed:
|
|
61
63
|
moduleItems[i] && moduleItems[i] !== 0
|
|
62
64
|
? {item_id: moduleItems[i], stats: moduleStats[i]}
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import type {ResolvedItem} from './resolve-item'
|
|
2
|
-
import type {ResourceCategory
|
|
2
|
+
import type {ResourceCategory} from '../types'
|
|
3
3
|
import {CATEGORY_LABELS, TIER_ADJECTIVES, tierNumber} from '../types'
|
|
4
4
|
import {formatMass as defaultFormatMass} from '../format'
|
|
5
5
|
|
|
6
6
|
export interface DisplayNameInput {
|
|
7
7
|
itemType: 'resource' | 'component' | 'module' | 'entity' | string
|
|
8
|
-
tier:
|
|
8
|
+
tier: number | string
|
|
9
9
|
category?: ResourceCategory
|
|
10
10
|
name: string
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
function asTierNumber(tier: number | string): number {
|
|
14
|
+
return typeof tier === 'number' ? tier : tierNumber(tier)
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
export function displayName(resolved: DisplayNameInput): string {
|
|
14
18
|
if (resolved.itemType === 'resource') {
|
|
15
|
-
const adj = TIER_ADJECTIVES[
|
|
19
|
+
const adj = TIER_ADJECTIVES[asTierNumber(resolved.tier)] ?? 'Unknown'
|
|
16
20
|
const cat = resolved.category ? CATEGORY_LABELS[resolved.category] : 'Resource'
|
|
17
21
|
return `${adj} ${cat}`
|
|
18
22
|
}
|
|
@@ -28,7 +32,7 @@ export interface DescribeOptions {
|
|
|
28
32
|
export function describeItem(resolved: ResolvedItem, opts?: DescribeOptions): string {
|
|
29
33
|
const massFmt = opts?.formatMass ?? defaultFormatMass
|
|
30
34
|
const mass = massFmt(resolved.mass)
|
|
31
|
-
const tier = `T${
|
|
35
|
+
const tier = `T${asTierNumber(resolved.tier)}`
|
|
32
36
|
if (resolved.itemType === 'resource') {
|
|
33
37
|
const cat = resolved.category ? CATEGORY_LABELS[resolved.category] : 'Resource'
|
|
34
38
|
const header = `${tier} ${cat}`
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {UInt16, UInt64} from '@wharfkit/antelope'
|
|
2
2
|
import type {UInt16Type, UInt64Type} from '@wharfkit/antelope'
|
|
3
|
-
import type {ResourceCategory
|
|
3
|
+
import type {ResourceCategory} from '../types'
|
|
4
4
|
import {getItem} from '../market/items'
|
|
5
|
-
import {
|
|
5
|
+
import {getEntityLayout} from '../data/recipes-runtime'
|
|
6
|
+
import {entityMetadata, itemMetadata} from '../data/metadata'
|
|
6
7
|
import {
|
|
7
8
|
getModuleCapabilityType,
|
|
8
9
|
isModuleItem,
|
|
@@ -35,6 +36,12 @@ import {
|
|
|
35
36
|
moduleIcon,
|
|
36
37
|
} from '../data/colors'
|
|
37
38
|
import {ServerContract} from '../contracts'
|
|
39
|
+
import {
|
|
40
|
+
ITEM_CONTAINER_T1_PACKED,
|
|
41
|
+
ITEM_CONTAINER_T2_PACKED,
|
|
42
|
+
ITEM_SHIP_T1_PACKED,
|
|
43
|
+
ITEM_WAREHOUSE_T1_PACKED,
|
|
44
|
+
} from '../data/item-ids'
|
|
38
45
|
|
|
39
46
|
export interface ResolvedItemStat {
|
|
40
47
|
key: string
|
|
@@ -42,7 +49,7 @@ export interface ResolvedItemStat {
|
|
|
42
49
|
abbreviation: string
|
|
43
50
|
value: number
|
|
44
51
|
color: string
|
|
45
|
-
category
|
|
52
|
+
category?: ResourceCategory
|
|
46
53
|
inverted?: boolean
|
|
47
54
|
}
|
|
48
55
|
|
|
@@ -65,7 +72,7 @@ export interface ResolvedItem {
|
|
|
65
72
|
icon: string
|
|
66
73
|
abbreviation: string | null
|
|
67
74
|
category?: ResourceCategory
|
|
68
|
-
tier:
|
|
75
|
+
tier: number
|
|
69
76
|
mass: number
|
|
70
77
|
itemType: ResolvedItemType
|
|
71
78
|
stats?: ResolvedItemStat[]
|
|
@@ -85,7 +92,7 @@ function resolveResource(id: number, stats?: UInt64Type): ResolvedItem {
|
|
|
85
92
|
const item = getItem(id)
|
|
86
93
|
const cat = item.category
|
|
87
94
|
let resolvedStats: ResolvedItemStat[] | undefined
|
|
88
|
-
if (stats !== undefined) {
|
|
95
|
+
if (stats !== undefined && cat) {
|
|
89
96
|
const bigStats = toBigStats(stats)
|
|
90
97
|
const defs = getStatDefinitions(cat)
|
|
91
98
|
const values = [decodeStat(bigStats, 0), decodeStat(bigStats, 1), decodeStat(bigStats, 2)]
|
|
@@ -101,19 +108,19 @@ function resolveResource(id: number, stats?: UInt64Type): ResolvedItem {
|
|
|
101
108
|
}
|
|
102
109
|
return {
|
|
103
110
|
itemId: id,
|
|
104
|
-
name: item.
|
|
105
|
-
icon: categoryIcons[cat]
|
|
111
|
+
name: item.name,
|
|
112
|
+
icon: cat ? categoryIcons[cat] : '⬡',
|
|
106
113
|
abbreviation: null,
|
|
107
114
|
category: cat,
|
|
108
115
|
tier: item.tier,
|
|
109
|
-
mass:
|
|
116
|
+
mass: item.mass,
|
|
110
117
|
itemType: 'resource',
|
|
111
118
|
stats: resolvedStats,
|
|
112
119
|
}
|
|
113
120
|
}
|
|
114
121
|
|
|
115
122
|
function resolveComponent(id: number, stats?: UInt64Type): ResolvedItem {
|
|
116
|
-
const
|
|
123
|
+
const item = getItem(id)
|
|
117
124
|
let resolvedStats: ResolvedItemStat[] | undefined
|
|
118
125
|
if (stats !== undefined) {
|
|
119
126
|
const decoded = decodeCraftedItemStats(id, toBigStats(stats))
|
|
@@ -124,26 +131,23 @@ function resolveComponent(id: number, stats?: UInt64Type): ResolvedItem {
|
|
|
124
131
|
.concat(getStatDefinitions('regolith'))
|
|
125
132
|
.concat(getStatDefinitions('biomass'))
|
|
126
133
|
const def = allDefs.find((d) => d.key === key)
|
|
127
|
-
const statDef = comp.stats.find((s) => s.key === key)
|
|
128
|
-
const cat = (statDef?.source ?? 'ore') as ResourceCategory
|
|
129
134
|
return {
|
|
130
135
|
key,
|
|
131
136
|
label: def?.label ?? key,
|
|
132
137
|
abbreviation: def?.abbreviation ?? key.slice(0, 3).toUpperCase(),
|
|
133
138
|
value,
|
|
134
|
-
color:
|
|
135
|
-
category: cat,
|
|
139
|
+
color: '#9BADB8',
|
|
136
140
|
inverted: def?.inverted,
|
|
137
141
|
}
|
|
138
142
|
})
|
|
139
143
|
}
|
|
140
144
|
return {
|
|
141
145
|
itemId: id,
|
|
142
|
-
name:
|
|
146
|
+
name: item.name,
|
|
143
147
|
icon: itemAbbreviations[id] ?? componentIcon,
|
|
144
148
|
abbreviation: itemAbbreviations[id] ?? null,
|
|
145
|
-
tier:
|
|
146
|
-
mass:
|
|
149
|
+
tier: item.tier,
|
|
150
|
+
mass: item.mass,
|
|
147
151
|
itemType: 'component',
|
|
148
152
|
stats: resolvedStats,
|
|
149
153
|
}
|
|
@@ -220,9 +224,9 @@ function computeCapabilityGroup(
|
|
|
220
224
|
}
|
|
221
225
|
case MODULE_STORAGE: {
|
|
222
226
|
const str = stats.strength ?? 500
|
|
223
|
-
const
|
|
227
|
+
const hrd = stats.hardness ?? 500
|
|
224
228
|
const sat = stats.saturation ?? 500
|
|
225
|
-
const statSum = str +
|
|
229
|
+
const statSum = str + hrd + sat
|
|
226
230
|
const pct = 10 + Math.floor((statSum * 10) / 2997)
|
|
227
231
|
return {capability: 'Storage', attributes: [{label: 'Capacity Bonus', value: pct}]}
|
|
228
232
|
}
|
|
@@ -232,7 +236,7 @@ function computeCapabilityGroup(
|
|
|
232
236
|
}
|
|
233
237
|
|
|
234
238
|
function resolveModule(id: number, stats?: UInt64Type): ResolvedItem {
|
|
235
|
-
const
|
|
239
|
+
const item = getItem(id)
|
|
236
240
|
let attributes: ResolvedAttributeGroup[] | undefined
|
|
237
241
|
if (stats !== undefined) {
|
|
238
242
|
const decoded = decodeCraftedItemStats(id, toBigStats(stats))
|
|
@@ -242,59 +246,64 @@ function resolveModule(id: number, stats?: UInt64Type): ResolvedItem {
|
|
|
242
246
|
}
|
|
243
247
|
return {
|
|
244
248
|
itemId: id,
|
|
245
|
-
name:
|
|
249
|
+
name: item.name,
|
|
246
250
|
icon: itemAbbreviations[id] ?? moduleIcon,
|
|
247
251
|
abbreviation: itemAbbreviations[id] ?? null,
|
|
248
|
-
tier:
|
|
249
|
-
mass:
|
|
252
|
+
tier: item.tier,
|
|
253
|
+
mass: item.mass,
|
|
250
254
|
itemType: 'module',
|
|
251
255
|
attributes,
|
|
252
256
|
}
|
|
253
257
|
}
|
|
254
258
|
|
|
259
|
+
function hullCapsForEntity(
|
|
260
|
+
itemId: number,
|
|
261
|
+
decoded: Record<string, number>
|
|
262
|
+
): {
|
|
263
|
+
hullmass: number
|
|
264
|
+
capacity: number
|
|
265
|
+
} {
|
|
266
|
+
switch (itemId) {
|
|
267
|
+
case ITEM_SHIP_T1_PACKED:
|
|
268
|
+
return computeShipHullCapabilities(decoded)
|
|
269
|
+
case ITEM_WAREHOUSE_T1_PACKED:
|
|
270
|
+
return computeWarehouseHullCapabilities(decoded)
|
|
271
|
+
case ITEM_CONTAINER_T1_PACKED:
|
|
272
|
+
return computeContainerCapabilities(decoded)
|
|
273
|
+
case ITEM_CONTAINER_T2_PACKED:
|
|
274
|
+
return computeContainerT2Capabilities(decoded)
|
|
275
|
+
default:
|
|
276
|
+
throw new Error(`resolveItem: no capacity formula wired for entity item ${itemId}`)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
255
280
|
function resolveEntity(
|
|
256
281
|
id: number,
|
|
257
282
|
stats?: UInt64Type,
|
|
258
283
|
modules?: ServerContract.Types.module_entry[]
|
|
259
284
|
): ResolvedItem {
|
|
260
|
-
const
|
|
285
|
+
const item = getItem(id)
|
|
286
|
+
const layout = getEntityLayout(id)
|
|
261
287
|
let attributes: ResolvedAttributeGroup[] | undefined
|
|
262
288
|
let moduleSlots: ResolvedModuleSlot[] | undefined
|
|
263
289
|
|
|
264
290
|
if (stats !== undefined) {
|
|
265
291
|
const decoded = decodeCraftedItemStats(id, toBigStats(stats))
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
case 'container':
|
|
277
|
-
hullCaps = computeContainerCapabilities(decoded)
|
|
278
|
-
break
|
|
279
|
-
case 'container-t2':
|
|
280
|
-
hullCaps = computeContainerT2Capabilities(decoded)
|
|
281
|
-
break
|
|
282
|
-
default:
|
|
283
|
-
throw new Error(
|
|
284
|
-
`resolveItem: no capacity formula wired for entity recipe "${recipe.id}"`
|
|
285
|
-
)
|
|
286
|
-
}
|
|
287
|
-
attributes.push({
|
|
288
|
-
capability: 'Hull',
|
|
289
|
-
attributes: [
|
|
290
|
-
{label: 'Mass', value: hullCaps.hullmass},
|
|
291
|
-
{label: 'Capacity', value: hullCaps.capacity},
|
|
292
|
-
],
|
|
293
|
-
})
|
|
292
|
+
const hullCaps = hullCapsForEntity(id, decoded)
|
|
293
|
+
attributes = [
|
|
294
|
+
{
|
|
295
|
+
capability: 'Hull',
|
|
296
|
+
attributes: [
|
|
297
|
+
{label: 'Mass', value: hullCaps.hullmass},
|
|
298
|
+
{label: 'Capacity', value: hullCaps.capacity},
|
|
299
|
+
],
|
|
300
|
+
},
|
|
301
|
+
]
|
|
294
302
|
}
|
|
295
303
|
|
|
296
|
-
if (
|
|
297
|
-
|
|
304
|
+
if (layout && layout.slots.length > 0) {
|
|
305
|
+
const slotLabels = entityMetadata[id]?.moduleSlotLabels ?? []
|
|
306
|
+
moduleSlots = layout.slots.map((slot, i) => {
|
|
298
307
|
const mod = modules?.[i]
|
|
299
308
|
if (mod?.installed) {
|
|
300
309
|
const modItemId = Number(mod.installed.item_id.value.toString())
|
|
@@ -302,24 +311,32 @@ function resolveEntity(
|
|
|
302
311
|
const decodedStats = decodeCraftedItemStats(modItemId, modStats)
|
|
303
312
|
const modType = getModuleCapabilityType(modItemId)
|
|
304
313
|
const group = computeCapabilityGroup(modType, decodedStats)
|
|
305
|
-
|
|
314
|
+
let modName = 'Module'
|
|
315
|
+
try {
|
|
316
|
+
modName = getItem(modItemId).name
|
|
317
|
+
} catch {
|
|
318
|
+
modName = itemMetadata[modItemId]?.name ?? 'Module'
|
|
319
|
+
}
|
|
306
320
|
return {
|
|
307
|
-
name:
|
|
321
|
+
name: modName,
|
|
308
322
|
installed: true,
|
|
309
323
|
attributes: group?.attributes,
|
|
310
324
|
}
|
|
311
325
|
}
|
|
312
|
-
return {
|
|
326
|
+
return {
|
|
327
|
+
name: slotLabels[i] ?? slot.type,
|
|
328
|
+
installed: false,
|
|
329
|
+
}
|
|
313
330
|
})
|
|
314
331
|
}
|
|
315
332
|
|
|
316
333
|
return {
|
|
317
334
|
itemId: id,
|
|
318
|
-
name:
|
|
335
|
+
name: item.name,
|
|
319
336
|
icon: itemAbbreviations[id] ?? componentIcon,
|
|
320
337
|
abbreviation: itemAbbreviations[id] ?? null,
|
|
321
|
-
tier:
|
|
322
|
-
mass:
|
|
338
|
+
tier: item.tier,
|
|
339
|
+
mass: item.mass,
|
|
323
340
|
itemType: 'entity',
|
|
324
341
|
attributes,
|
|
325
342
|
moduleSlots,
|
|
@@ -332,12 +349,10 @@ export function resolveItem(
|
|
|
332
349
|
modules?: ServerContract.Types.module_entry[]
|
|
333
350
|
): ResolvedItem {
|
|
334
351
|
const id = toNum(itemId)
|
|
352
|
+
const item = getItem(id)
|
|
335
353
|
|
|
336
|
-
if (isModuleItem(id)) return resolveModule(id, stats)
|
|
337
|
-
|
|
338
|
-
if (
|
|
339
|
-
|
|
340
|
-
if (getEntityRecipeByItemId(id)) return resolveEntity(id, stats, modules)
|
|
341
|
-
|
|
354
|
+
if (item.type === 'module' || isModuleItem(id)) return resolveModule(id, stats)
|
|
355
|
+
if (item.type === 'component') return resolveComponent(id, stats)
|
|
356
|
+
if (item.type === 'entity') return resolveEntity(id, stats, modules)
|
|
342
357
|
return resolveResource(id, stats)
|
|
343
358
|
}
|