@shipload/sdk 2.0.0-rc6 → 2.0.0-rc8

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.
@@ -120,14 +120,10 @@ export class ActionsManager extends BaseManager {
120
120
  entityId: UInt64Type,
121
121
  recipeId: number,
122
122
  quantity: number,
123
- inputs: {itemId: number; quantity: number; seed?: bigint}[]
123
+ inputs: ServerContract.ActionParams.Type.cargo_item[]
124
124
  ): Action {
125
125
  const cargoInputs = inputs.map((i) =>
126
- ServerContract.Types.cargo_item.from({
127
- item_id: UInt16.from(i.itemId),
128
- quantity: UInt32.from(i.quantity),
129
- seed: i.seed !== undefined ? UInt64.from(i.seed) : null,
130
- })
126
+ ServerContract.Types.cargo_item.from(i)
131
127
  )
132
128
  return this.server.action('craft', {
133
129
  entity_type: entityType,
@@ -138,6 +134,21 @@ export class ActionsManager extends BaseManager {
138
134
  })
139
135
  }
140
136
 
137
+ blend(
138
+ entityType: EntityTypeName,
139
+ entityId: UInt64Type,
140
+ inputs: ServerContract.ActionParams.Type.cargo_item[]
141
+ ): Action {
142
+ const cargoInputs = inputs.map((i) =>
143
+ ServerContract.Types.cargo_item.from(i)
144
+ )
145
+ return this.server.action('blend', {
146
+ entity_type: entityType,
147
+ id: UInt64.from(entityId),
148
+ inputs: cargoInputs,
149
+ })
150
+ }
151
+
141
152
  deploy(
142
153
  entityType: EntityTypeName,
143
154
  entityId: UInt64Type,
@@ -154,6 +165,36 @@ export class ActionsManager extends BaseManager {
154
165
  })
155
166
  }
156
167
 
168
+ addmodule(
169
+ entityType: EntityTypeName,
170
+ entityId: UInt64Type,
171
+ moduleIndex: number,
172
+ moduleCargoId: UInt64Type,
173
+ targetCargoId: UInt64Type = UInt64.from(0)
174
+ ): Action {
175
+ return this.server.action('addmodule', {
176
+ entity_type: entityType,
177
+ entity_id: UInt64.from(entityId),
178
+ module_index: moduleIndex,
179
+ module_cargo_id: UInt64.from(moduleCargoId),
180
+ target_cargo_id: UInt64.from(targetCargoId),
181
+ })
182
+ }
183
+
184
+ rmmodule(
185
+ entityType: EntityTypeName,
186
+ entityId: UInt64Type,
187
+ moduleIndex: number,
188
+ targetCargoId: UInt64Type = UInt64.from(0)
189
+ ): Action {
190
+ return this.server.action('rmmodule', {
191
+ entity_type: entityType,
192
+ entity_id: UInt64.from(entityId),
193
+ module_index: moduleIndex,
194
+ target_cargo_id: UInt64.from(targetCargoId),
195
+ })
196
+ }
197
+
157
198
  joinGame(account: NameType, companyName: string): Action[] {
158
199
  return [this.foundCompany(account, companyName), this.join(account)]
159
200
  }
@@ -0,0 +1,261 @@
1
+ import {UInt16, UInt64} from '@wharfkit/antelope'
2
+ import type {UInt16Type, UInt64Type} from '@wharfkit/antelope'
3
+ import type {ResourceCategory, ResourceTier} from '../types'
4
+ import {getItem} from '../market/items'
5
+ import {getComponentById, getModuleRecipeByItemId, getEntityRecipeByItemId} from '../data/recipes'
6
+ import {isModuleItem, getModuleCapabilityType, MODULE_ENGINE, MODULE_GENERATOR, MODULE_EXTRACTOR, MODULE_LOADER, MODULE_CRAFTER} from '../capabilities/modules'
7
+ import {decodeCraftedItemStats} from '../derivation/crafting'
8
+ import {deriveResourceStats} from '../derivation/stratum'
9
+ import {getStatDefinitions} from '../derivation/stats'
10
+ import {computeShipHullCapabilities, computeEngineCapabilities, computeGeneratorCapabilities, computeExtractorCapabilities, computeLoaderCapabilities, computeManufacturingCapabilities} from '../entities/ship-deploy'
11
+ import {computeContainerCapabilities} from '../entities/container'
12
+ import {categoryColors, categoryIcons, componentIcon, moduleIcon, itemIcons} from '../data/colors'
13
+ import {ServerContract} from '../contracts'
14
+
15
+ export interface ResolvedItemStat {
16
+ key: string
17
+ label: string
18
+ abbreviation: string
19
+ value: number
20
+ color: string
21
+ category: ResourceCategory
22
+ inverted?: boolean
23
+ }
24
+
25
+ export interface ResolvedAttributeGroup {
26
+ capability: string
27
+ attributes: {label: string; value: number}[]
28
+ }
29
+
30
+ export type ResolvedItemType = 'resource' | 'component' | 'module' | 'entity'
31
+
32
+ export interface ResolvedModuleSlot {
33
+ name?: string
34
+ installed: boolean
35
+ attributes?: {label: string; value: number}[]
36
+ }
37
+
38
+ export interface ResolvedItem {
39
+ itemId: number
40
+ name: string
41
+ icon: string
42
+ category?: ResourceCategory
43
+ tier: ResourceTier
44
+ mass: number
45
+ itemType: ResolvedItemType
46
+ stats?: ResolvedItemStat[]
47
+ attributes?: ResolvedAttributeGroup[]
48
+ moduleSlots?: ResolvedModuleSlot[]
49
+ }
50
+
51
+ function toNum(v: UInt16Type): number {
52
+ return Number(UInt16.from(v).value.toString())
53
+ }
54
+
55
+ function toBigSeed(v: UInt64Type): bigint {
56
+ return BigInt(UInt64.from(v).toString())
57
+ }
58
+
59
+ function resolveResource(id: number, seed?: UInt64Type): ResolvedItem {
60
+ const item = getItem(id)
61
+ const cat = item.category
62
+ let stats: ResolvedItemStat[] | undefined
63
+ if (seed !== undefined) {
64
+ const derived = deriveResourceStats(toBigSeed(seed))
65
+ const defs = getStatDefinitions(cat)
66
+ const values = [derived.stat1, derived.stat2, derived.stat3]
67
+ stats = defs.map((d, i) => ({
68
+ key: d.key,
69
+ label: d.label,
70
+ abbreviation: d.abbreviation,
71
+ value: values[i] ?? 0,
72
+ color: categoryColors[cat],
73
+ category: cat,
74
+ inverted: d.inverted,
75
+ }))
76
+ }
77
+ return {
78
+ itemId: id,
79
+ name: String(item.name),
80
+ icon: categoryIcons[cat] ?? '⬡',
81
+ category: cat,
82
+ tier: item.tier,
83
+ mass: Number(item.mass.value.toString()),
84
+ itemType: 'resource',
85
+ stats,
86
+ }
87
+ }
88
+
89
+ function resolveComponent(id: number, seed?: UInt64Type): ResolvedItem {
90
+ const comp = getComponentById(id)!
91
+ let stats: ResolvedItemStat[] | undefined
92
+ if (seed !== undefined) {
93
+ const decoded = decodeCraftedItemStats(id, toBigSeed(seed))
94
+ stats = Object.entries(decoded).map(([key, value]) => {
95
+ const allDefs = getStatDefinitions('metal')
96
+ .concat(getStatDefinitions('precious'))
97
+ .concat(getStatDefinitions('gas'))
98
+ .concat(getStatDefinitions('mineral'))
99
+ .concat(getStatDefinitions('organic'))
100
+ const def = allDefs.find((d) => d.key === key)
101
+ const statDef = comp.stats.find((s) => s.key === key)
102
+ const cat = (statDef?.source ?? 'metal') as ResourceCategory
103
+ return {
104
+ key,
105
+ label: def?.label ?? key,
106
+ abbreviation: def?.abbreviation ?? key.slice(0, 3).toUpperCase(),
107
+ value,
108
+ color: categoryColors[cat],
109
+ category: cat,
110
+ inverted: def?.inverted,
111
+ }
112
+ })
113
+ }
114
+ return {
115
+ itemId: id,
116
+ name: comp.name,
117
+ icon: itemIcons[id] ?? componentIcon,
118
+ tier: 't1' as ResourceTier,
119
+ mass: comp.mass,
120
+ itemType: 'component',
121
+ stats,
122
+ }
123
+ }
124
+
125
+ function computeCapabilityGroup(moduleType: number, stats: Record<string, number>): ResolvedAttributeGroup | undefined {
126
+ switch (moduleType) {
127
+ case MODULE_ENGINE: {
128
+ const caps = computeEngineCapabilities(stats)
129
+ return {capability: 'Engine', attributes: [
130
+ {label: 'Thrust', value: caps.thrust},
131
+ {label: 'Drain', value: caps.drain},
132
+ ]}
133
+ }
134
+ case MODULE_GENERATOR: {
135
+ const caps = computeGeneratorCapabilities(stats)
136
+ return {capability: 'Generator', attributes: [
137
+ {label: 'Capacity', value: caps.capacity},
138
+ {label: 'Recharge', value: caps.recharge},
139
+ ]}
140
+ }
141
+ case MODULE_EXTRACTOR: {
142
+ const caps = computeExtractorCapabilities(stats)
143
+ return {capability: 'Extractor', attributes: [
144
+ {label: 'Rate', value: caps.rate},
145
+ {label: 'Drain', value: caps.drain},
146
+ {label: 'Depth', value: caps.depth},
147
+ {label: 'Drill', value: caps.drill},
148
+ ]}
149
+ }
150
+ case MODULE_LOADER: {
151
+ const caps = computeLoaderCapabilities(stats)
152
+ return {capability: 'Loader', attributes: [
153
+ {label: 'Mass', value: caps.mass},
154
+ {label: 'Thrust', value: caps.thrust},
155
+ {label: 'Quantity', value: caps.quantity},
156
+ ]}
157
+ }
158
+ case MODULE_CRAFTER: {
159
+ const caps = computeManufacturingCapabilities(stats)
160
+ return {capability: 'Manufacturing', attributes: [
161
+ {label: 'Speed', value: caps.speed},
162
+ {label: 'Drain', value: caps.drain},
163
+ ]}
164
+ }
165
+ default:
166
+ return undefined
167
+ }
168
+ }
169
+
170
+ function resolveModule(id: number, seed?: UInt64Type): ResolvedItem {
171
+ const recipe = getModuleRecipeByItemId(id)!
172
+ let attributes: ResolvedAttributeGroup[] | undefined
173
+ if (seed !== undefined) {
174
+ const stats = decodeCraftedItemStats(id, toBigSeed(seed))
175
+ const modType = getModuleCapabilityType(id)
176
+ const group = computeCapabilityGroup(modType, stats)
177
+ if (group) attributes = [group]
178
+ }
179
+ return {
180
+ itemId: id,
181
+ name: recipe.name,
182
+ icon: itemIcons[id] ?? moduleIcon,
183
+ tier: 't1' as ResourceTier,
184
+ mass: 0,
185
+ itemType: 'module',
186
+ attributes,
187
+ }
188
+ }
189
+
190
+ function resolveEntity(id: number, seed?: UInt64Type, modules?: ServerContract.Types.module_entry[]): ResolvedItem {
191
+ const recipe = getEntityRecipeByItemId(id)!
192
+ let attributes: ResolvedAttributeGroup[] | undefined
193
+ let moduleSlots: ResolvedModuleSlot[] | undefined
194
+
195
+ if (seed !== undefined) {
196
+ const stats = decodeCraftedItemStats(id, toBigSeed(seed))
197
+ attributes = []
198
+
199
+ const isShip = recipe.id === 'ship-t1'
200
+ if (isShip) {
201
+ const hullCaps = computeShipHullCapabilities(stats)
202
+ attributes.push({capability: 'Hull', attributes: [
203
+ {label: 'Mass', value: hullCaps.hullmass},
204
+ {label: 'Capacity', value: hullCaps.capacity},
205
+ ]})
206
+ } else {
207
+ const containerCaps = computeContainerCapabilities(stats)
208
+ attributes.push({capability: 'Hull', attributes: [
209
+ {label: 'Mass', value: containerCaps.hullmass},
210
+ {label: 'Capacity', value: containerCaps.capacity},
211
+ ]})
212
+ }
213
+ }
214
+
215
+ if (recipe.moduleSlots) {
216
+ moduleSlots = recipe.moduleSlots.map((slot, i) => {
217
+ const mod = modules?.[i]
218
+ if (mod?.installed) {
219
+ const modItemId = Number(mod.installed.item_id.value.toString())
220
+ const modSeed = BigInt(mod.installed.seed.toString())
221
+ const modStats = decodeCraftedItemStats(modItemId, modSeed)
222
+ const modType = getModuleCapabilityType(modItemId)
223
+ const group = computeCapabilityGroup(modType, modStats)
224
+ const modRecipe = getModuleRecipeByItemId(modItemId)
225
+ return {
226
+ name: modRecipe?.name ?? 'Module',
227
+ installed: true,
228
+ attributes: group?.attributes,
229
+ }
230
+ }
231
+ return {installed: false}
232
+ })
233
+ }
234
+
235
+ return {
236
+ itemId: id,
237
+ name: recipe.name,
238
+ icon: itemIcons[id] ?? componentIcon,
239
+ tier: 't1' as ResourceTier,
240
+ mass: 0,
241
+ itemType: 'entity',
242
+ attributes,
243
+ moduleSlots,
244
+ }
245
+ }
246
+
247
+ export function resolveItem(
248
+ itemId: UInt16Type,
249
+ seed?: UInt64Type,
250
+ modules?: ServerContract.Types.module_entry[]
251
+ ): ResolvedItem {
252
+ const id = toNum(itemId)
253
+
254
+ if (isModuleItem(id)) return resolveModule(id, seed)
255
+
256
+ if (getComponentById(id)) return resolveComponent(id, seed)
257
+
258
+ if (getEntityRecipeByItemId(id)) return resolveEntity(id, seed, modules)
259
+
260
+ return resolveResource(id, seed)
261
+ }
@@ -24,7 +24,7 @@ import {ServerContract} from '../contracts'
24
24
  import {
25
25
  CargoMassInfo,
26
26
  Distance,
27
- INITIAL_SHIP_MASS,
27
+ BASE_ORBITAL_MASS,
28
28
  MAX_ORBITAL_ALTITUDE,
29
29
  MIN_ORBITAL_ALTITUDE,
30
30
  PRECISION,
@@ -35,11 +35,11 @@ import {getItem} from '../market/items'
35
35
  import {hasSystem} from '../utils/system'
36
36
 
37
37
  export function calc_orbital_altitude(mass: number): number {
38
- if (mass <= INITIAL_SHIP_MASS) {
38
+ if (mass <= BASE_ORBITAL_MASS) {
39
39
  return MIN_ORBITAL_ALTITUDE
40
40
  }
41
41
 
42
- const ratio = mass / INITIAL_SHIP_MASS
42
+ const ratio = mass / BASE_ORBITAL_MASS
43
43
  const capRatio = 10.0
44
44
  let scale = Math.log(ratio) / Math.log(capRatio)
45
45
  scale = Math.min(scale, 1.0)
@@ -19,10 +19,10 @@ export interface Entity {
19
19
  }
20
20
 
21
21
  export type ShipEntity = Entity &
22
- MovementCapability &
23
- EnergyCapability &
22
+ Partial<MovementCapability> &
23
+ Partial<EnergyCapability> &
24
24
  StorageCapability &
25
- LoaderCapability &
25
+ Partial<LoaderCapability> &
26
26
  MassCapability &
27
27
  ScheduleCapability & {
28
28
  extractor?: ServerContract.Types.extractor_stats
package/src/types.ts CHANGED
@@ -12,19 +12,6 @@ import {ServerContract} from './contracts'
12
12
 
13
13
  export const PRECISION = 10000
14
14
 
15
- export const INITIAL_SHIP_GENERATOR_CAPACITY = 350
16
- export const INITIAL_SHIP_DRAIN = 25
17
- export const INITIAL_SHIP_ENERGY = 350
18
- export const INITIAL_SHIP_HULLMASS = 100000
19
- export const INITIAL_SHIP_CAPACITY = 500000
20
- export const INITIAL_SHIP_Z = 800
21
- export const INITIAL_SHIP_RECHARGE = 10
22
- export const INITIAL_SHIP_THRUST = 250
23
-
24
- export const INITIAL_LOADER_MASS = 1000
25
- export const INITIAL_LOADER_QUANTITY = 1
26
- export const INITIAL_LOADER_THRUST = 1
27
-
28
15
  export const WAREHOUSE_Z = 500
29
16
  export const INITIAL_WAREHOUSE_CAPACITY = 10000000
30
17
 
@@ -37,11 +24,7 @@ export const TRAVEL_MAX_DURATION = 86400
37
24
  export const MIN_ORBITAL_ALTITUDE = 800
38
25
  export const MAX_ORBITAL_ALTITUDE = 3000
39
26
 
40
- export const INITIAL_SHIP_MASS = 500000
41
-
42
- export const INITIAL_EXTRACTOR_RATE = 700
43
- export const INITIAL_EXTRACTOR_DRAIN = 2500
44
- export const INITIAL_EXTRACTOR_EFFICIENCY = 5000
27
+ export const BASE_ORBITAL_MASS = 100000
45
28
 
46
29
  export interface ShipLike {
47
30
  coordinates: ServerContract.Types.coordinates