@shipload/sdk 2.0.0-rc7 → 2.0.0-rc9
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 +415 -38
- package/lib/shipload.js +1433 -76
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +1372 -77
- package/lib/shipload.m.js.map +1 -1
- package/package.json +6 -5
- package/src/capabilities/modules.ts +9 -5
- package/src/contracts/server.ts +279 -22
- package/src/data/capabilities.ts +372 -0
- package/src/data/categories.ts +57 -0
- package/src/data/colors.ts +25 -1
- package/src/data/locations.ts +53 -0
- package/src/data/recipes.ts +141 -26
- package/src/data/tiers.ts +41 -0
- package/src/derivation/crafting.ts +58 -1
- package/src/entities/container.ts +18 -0
- package/src/entities/makers.ts +6 -4
- package/src/entities/ship-deploy.ts +34 -1
- package/src/entities/warehouse.ts +7 -1
- package/src/index-module.ts +73 -4
- package/src/nft/description.ts +173 -0
- package/src/nft/deserializers.ts +81 -0
- package/src/nft/index.ts +2 -0
- package/src/resolution/resolve-item.ts +39 -10
- package/src/travel/travel.ts +17 -8
- package/src/types/entity.ts +1 -1
- package/src/types.ts +6 -6
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ITEM_ENGINE_T1,
|
|
3
|
+
ITEM_EXTRACTOR_T1,
|
|
4
|
+
ITEM_GENERATOR_T1,
|
|
5
|
+
ITEM_LOADER_T1,
|
|
6
|
+
ITEM_MANUFACTURING_T1,
|
|
7
|
+
ITEM_STORAGE_T1,
|
|
8
|
+
MODULE_CRAFTER,
|
|
9
|
+
MODULE_ENGINE,
|
|
10
|
+
MODULE_EXTRACTOR,
|
|
11
|
+
MODULE_GENERATOR,
|
|
12
|
+
MODULE_LOADER,
|
|
13
|
+
MODULE_STORAGE,
|
|
14
|
+
getModuleCapabilityType,
|
|
15
|
+
} from '../capabilities/modules'
|
|
16
|
+
import {
|
|
17
|
+
ITEM_CONTAINER_T1_PACKED,
|
|
18
|
+
ITEM_CONTAINER_T2_PACKED,
|
|
19
|
+
ITEM_SHIP_T1_PACKED,
|
|
20
|
+
ITEM_WAREHOUSE_T1_PACKED,
|
|
21
|
+
} from '../data/recipes'
|
|
22
|
+
import {decodeStat} from '../derivation/crafting'
|
|
23
|
+
|
|
24
|
+
function idiv(a: number, b: number): number {
|
|
25
|
+
return Math.floor(a / b)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function computeBaseHullmass(seed: bigint): number {
|
|
29
|
+
const density = decodeStat(seed, 1)
|
|
30
|
+
return 25000 + 75 * density
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function computeBaseCapacityShip(seed: bigint): number {
|
|
34
|
+
const s = decodeStat(seed, 0) + decodeStat(seed, 2) + decodeStat(seed, 3)
|
|
35
|
+
return Math.floor(1_000_000 * Math.pow(10, s / 2997))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function computeBaseCapacityWarehouse(seed: bigint): number {
|
|
39
|
+
const s = decodeStat(seed, 0) + decodeStat(seed, 2) + decodeStat(seed, 3)
|
|
40
|
+
return Math.floor(20_000_000 * Math.pow(10, s / 2997))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const computeEngineThrust = (vol: number): number => 400 + idiv(vol * 3, 4)
|
|
44
|
+
export const computeEngineDrain = (thm: number): number => Math.max(30, 50 - idiv(thm, 70))
|
|
45
|
+
export const computeGeneratorCap = (res: number): number => 300 + idiv(res, 6)
|
|
46
|
+
export const computeGeneratorRech = (clr: number): number => 5 + idiv(clr * 15, 1000)
|
|
47
|
+
export const computeExtractorRate = (str: number): number => 200 + str
|
|
48
|
+
export const computeExtractorDrain = (con: number): number => Math.max(10, 50 - idiv(con, 20))
|
|
49
|
+
export const computeExtractorDepth = (tol: number): number => 200 + idiv(tol * 3, 2)
|
|
50
|
+
export const computeExtractorDrill = (ref: number): number => 100 + idiv(ref * 4, 5)
|
|
51
|
+
export const computeLoaderMass = (duc: number): number => Math.max(200, 2000 - duc * 2)
|
|
52
|
+
export const computeLoaderThrust = (pla: number): number => 1 + idiv(pla, 500)
|
|
53
|
+
export const computeCrafterSpeed = (rea: number): number => 100 + idiv(rea * 4, 5)
|
|
54
|
+
export const computeCrafterDrain = (clr: number): number => Math.max(5, 30 - idiv(clr, 33))
|
|
55
|
+
|
|
56
|
+
export function entityDisplayName(itemId: number): string {
|
|
57
|
+
switch (itemId) {
|
|
58
|
+
case ITEM_SHIP_T1_PACKED:
|
|
59
|
+
return 'Ship T1'
|
|
60
|
+
case ITEM_WAREHOUSE_T1_PACKED:
|
|
61
|
+
return 'Warehouse T1'
|
|
62
|
+
case ITEM_CONTAINER_T1_PACKED:
|
|
63
|
+
return 'Container T1'
|
|
64
|
+
case ITEM_CONTAINER_T2_PACKED:
|
|
65
|
+
return 'Container T2'
|
|
66
|
+
default:
|
|
67
|
+
return 'Entity'
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function moduleDisplayName(itemId: number): string {
|
|
72
|
+
switch (itemId) {
|
|
73
|
+
case ITEM_ENGINE_T1:
|
|
74
|
+
return 'Engine T1'
|
|
75
|
+
case ITEM_GENERATOR_T1:
|
|
76
|
+
return 'Generator T1'
|
|
77
|
+
case ITEM_EXTRACTOR_T1:
|
|
78
|
+
return 'Extractor T1'
|
|
79
|
+
case ITEM_LOADER_T1:
|
|
80
|
+
return 'Loader T1'
|
|
81
|
+
case ITEM_MANUFACTURING_T1:
|
|
82
|
+
return 'Manufacturing T1'
|
|
83
|
+
case ITEM_STORAGE_T1:
|
|
84
|
+
return 'Storage T1'
|
|
85
|
+
default:
|
|
86
|
+
return 'Module'
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function formatModuleLine(slot: number, itemId: number, seed: bigint): string {
|
|
91
|
+
let out = `Slot ${slot} - `
|
|
92
|
+
if (itemId === 0) {
|
|
93
|
+
out += '(empty)'
|
|
94
|
+
return out
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
out += moduleDisplayName(itemId)
|
|
98
|
+
const subtype = getModuleCapabilityType(itemId)
|
|
99
|
+
|
|
100
|
+
switch (subtype) {
|
|
101
|
+
case MODULE_ENGINE: {
|
|
102
|
+
const vol = decodeStat(seed, 0)
|
|
103
|
+
const thm = decodeStat(seed, 1)
|
|
104
|
+
out += ` Thrust ${computeEngineThrust(vol)} Drain ${computeEngineDrain(thm)}`
|
|
105
|
+
break
|
|
106
|
+
}
|
|
107
|
+
case MODULE_GENERATOR: {
|
|
108
|
+
const res = decodeStat(seed, 0)
|
|
109
|
+
const clr = decodeStat(seed, 1)
|
|
110
|
+
out += ` Capacity ${computeGeneratorCap(res)} Recharge ${computeGeneratorRech(clr)}`
|
|
111
|
+
break
|
|
112
|
+
}
|
|
113
|
+
case MODULE_EXTRACTOR: {
|
|
114
|
+
const str = decodeStat(seed, 0)
|
|
115
|
+
const tol = decodeStat(seed, 1)
|
|
116
|
+
const con = decodeStat(seed, 3)
|
|
117
|
+
const ref = decodeStat(seed, 4)
|
|
118
|
+
out += ` Rate ${computeExtractorRate(str)} Depth ${computeExtractorDepth(tol)} Drill ${computeExtractorDrill(ref)} Drain ${computeExtractorDrain(con)}`
|
|
119
|
+
break
|
|
120
|
+
}
|
|
121
|
+
case MODULE_LOADER: {
|
|
122
|
+
const duc = decodeStat(seed, 0)
|
|
123
|
+
const pla = decodeStat(seed, 1)
|
|
124
|
+
out += ` Mass ${computeLoaderMass(duc)} Thrust ${computeLoaderThrust(pla)}`
|
|
125
|
+
break
|
|
126
|
+
}
|
|
127
|
+
case MODULE_CRAFTER: {
|
|
128
|
+
const rea = decodeStat(seed, 0)
|
|
129
|
+
const clr = decodeStat(seed, 1)
|
|
130
|
+
out += ` Speed ${computeCrafterSpeed(rea)} Drain ${computeCrafterDrain(clr)}`
|
|
131
|
+
break
|
|
132
|
+
}
|
|
133
|
+
case MODULE_STORAGE: {
|
|
134
|
+
const str = decodeStat(seed, 0)
|
|
135
|
+
const duc = decodeStat(seed, 1)
|
|
136
|
+
const pur = decodeStat(seed, 2)
|
|
137
|
+
const sum = str + duc + pur
|
|
138
|
+
const pct = 10 + idiv(sum * 10, 2997)
|
|
139
|
+
out += ` +${pct}% capacity`
|
|
140
|
+
break
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return out
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function buildEntityDescription(
|
|
147
|
+
itemId: number,
|
|
148
|
+
hullSeed: bigint,
|
|
149
|
+
moduleItems: number[],
|
|
150
|
+
moduleSeeds: bigint[]
|
|
151
|
+
): string {
|
|
152
|
+
const hullMass = computeBaseHullmass(hullSeed)
|
|
153
|
+
let baseCapacity = 0
|
|
154
|
+
if (itemId === ITEM_SHIP_T1_PACKED) {
|
|
155
|
+
baseCapacity = computeBaseCapacityShip(hullSeed)
|
|
156
|
+
} else if (itemId === ITEM_WAREHOUSE_T1_PACKED) {
|
|
157
|
+
baseCapacity = computeBaseCapacityWarehouse(hullSeed)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
let out = entityDisplayName(itemId)
|
|
161
|
+
out += ` - Hull ${hullMass} mass`
|
|
162
|
+
if (baseCapacity > 0) {
|
|
163
|
+
out += ` * ${baseCapacity} capacity`
|
|
164
|
+
}
|
|
165
|
+
out += '\n\n'
|
|
166
|
+
|
|
167
|
+
for (let i = 0; i < moduleItems.length; i++) {
|
|
168
|
+
out += formatModuleLine(i, moduleItems[i], moduleSeeds[i] ?? 0n)
|
|
169
|
+
out += '\n'
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return out
|
|
173
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {getEntitySlotLayout} from '../data/recipes'
|
|
2
|
+
import {
|
|
3
|
+
ITEM_TYPE_COMPONENT,
|
|
4
|
+
ITEM_TYPE_ENTITY,
|
|
5
|
+
ITEM_TYPE_MODULE,
|
|
6
|
+
ITEM_TYPE_RESOURCE,
|
|
7
|
+
itemTypeCode,
|
|
8
|
+
} from '../data/tiers'
|
|
9
|
+
|
|
10
|
+
export interface NFTInstalledModule {
|
|
11
|
+
item_id: number
|
|
12
|
+
seed: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface NFTModuleSlot {
|
|
16
|
+
type: number
|
|
17
|
+
installed?: NFTInstalledModule
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface NFTCargoItem {
|
|
21
|
+
item_id: number
|
|
22
|
+
quantity: number
|
|
23
|
+
seed: string
|
|
24
|
+
modules?: NFTModuleSlot[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface NFTCommonBase {
|
|
28
|
+
quantity: number
|
|
29
|
+
seed: string
|
|
30
|
+
origin_x: string
|
|
31
|
+
origin_y: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function readCommonBase(data: Record<string, any>): NFTCommonBase {
|
|
35
|
+
return {
|
|
36
|
+
quantity: Number(data.quantity),
|
|
37
|
+
seed: String(data.seed),
|
|
38
|
+
origin_x: String(data.origin_x),
|
|
39
|
+
origin_y: String(data.origin_y),
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function deserializeScalar(data: Record<string, any>, itemId: number): NFTCargoItem {
|
|
44
|
+
const base = readCommonBase(data)
|
|
45
|
+
return {item_id: itemId, quantity: base.quantity, seed: base.seed}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const deserializeResource = deserializeScalar
|
|
49
|
+
export const deserializeComponent = deserializeScalar
|
|
50
|
+
export const deserializeModule = deserializeScalar
|
|
51
|
+
|
|
52
|
+
export function deserializeEntity(data: Record<string, any>, itemId: number): NFTCargoItem {
|
|
53
|
+
const base = readCommonBase(data)
|
|
54
|
+
const moduleItems: number[] = (data.module_items ?? []).map((v: any) => Number(v))
|
|
55
|
+
const moduleSeeds: string[] = (data.module_seeds ?? []).map((v: any) => String(v))
|
|
56
|
+
const layout = getEntitySlotLayout(itemId)
|
|
57
|
+
|
|
58
|
+
const modules: NFTModuleSlot[] = layout.map((slot, i) => ({
|
|
59
|
+
type: slot.type,
|
|
60
|
+
installed:
|
|
61
|
+
moduleItems[i] && moduleItems[i] !== 0
|
|
62
|
+
? {item_id: moduleItems[i], seed: moduleSeeds[i]}
|
|
63
|
+
: undefined,
|
|
64
|
+
}))
|
|
65
|
+
|
|
66
|
+
return {item_id: itemId, quantity: base.quantity, seed: base.seed, modules}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function deserializeAsset(data: Record<string, any>, itemId: number): NFTCargoItem {
|
|
70
|
+
const type = itemTypeCode(itemId)
|
|
71
|
+
switch (type) {
|
|
72
|
+
case ITEM_TYPE_RESOURCE:
|
|
73
|
+
case ITEM_TYPE_COMPONENT:
|
|
74
|
+
case ITEM_TYPE_MODULE:
|
|
75
|
+
return deserializeScalar(data, itemId)
|
|
76
|
+
case ITEM_TYPE_ENTITY:
|
|
77
|
+
return deserializeEntity(data, itemId)
|
|
78
|
+
default:
|
|
79
|
+
throw new Error(`unknown item type ${type} for item ${itemId}`)
|
|
80
|
+
}
|
|
81
|
+
}
|
package/src/nft/index.ts
ADDED
|
@@ -3,13 +3,13 @@ import type {UInt16Type, UInt64Type} from '@wharfkit/antelope'
|
|
|
3
3
|
import type {ResourceCategory, ResourceTier} from '../types'
|
|
4
4
|
import {getItem} from '../market/items'
|
|
5
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'
|
|
6
|
+
import {isModuleItem, getModuleCapabilityType, MODULE_ENGINE, MODULE_GENERATOR, MODULE_EXTRACTOR, MODULE_LOADER, MODULE_CRAFTER, MODULE_STORAGE} from '../capabilities/modules'
|
|
7
7
|
import {decodeCraftedItemStats} from '../derivation/crafting'
|
|
8
8
|
import {deriveResourceStats} from '../derivation/stratum'
|
|
9
9
|
import {getStatDefinitions} from '../derivation/stats'
|
|
10
10
|
import {computeShipHullCapabilities, computeEngineCapabilities, computeGeneratorCapabilities, computeExtractorCapabilities, computeLoaderCapabilities, computeManufacturingCapabilities} from '../entities/ship-deploy'
|
|
11
11
|
import {computeContainerCapabilities} from '../entities/container'
|
|
12
|
-
import {categoryColors, categoryIcons, componentIcon, moduleIcon} from '../data/colors'
|
|
12
|
+
import {categoryColors, categoryIcons, componentIcon, moduleIcon, itemIcons} from '../data/colors'
|
|
13
13
|
import {ServerContract} from '../contracts'
|
|
14
14
|
|
|
15
15
|
export interface ResolvedItemStat {
|
|
@@ -29,6 +29,12 @@ export interface ResolvedAttributeGroup {
|
|
|
29
29
|
|
|
30
30
|
export type ResolvedItemType = 'resource' | 'component' | 'module' | 'entity'
|
|
31
31
|
|
|
32
|
+
export interface ResolvedModuleSlot {
|
|
33
|
+
name?: string
|
|
34
|
+
installed: boolean
|
|
35
|
+
attributes?: {label: string; value: number}[]
|
|
36
|
+
}
|
|
37
|
+
|
|
32
38
|
export interface ResolvedItem {
|
|
33
39
|
itemId: number
|
|
34
40
|
name: string
|
|
@@ -39,6 +45,7 @@ export interface ResolvedItem {
|
|
|
39
45
|
itemType: ResolvedItemType
|
|
40
46
|
stats?: ResolvedItemStat[]
|
|
41
47
|
attributes?: ResolvedAttributeGroup[]
|
|
48
|
+
moduleSlots?: ResolvedModuleSlot[]
|
|
42
49
|
}
|
|
43
50
|
|
|
44
51
|
function toNum(v: UInt16Type): number {
|
|
@@ -107,7 +114,7 @@ function resolveComponent(id: number, seed?: UInt64Type): ResolvedItem {
|
|
|
107
114
|
return {
|
|
108
115
|
itemId: id,
|
|
109
116
|
name: comp.name,
|
|
110
|
-
icon: componentIcon,
|
|
117
|
+
icon: itemIcons[id] ?? componentIcon,
|
|
111
118
|
tier: 't1' as ResourceTier,
|
|
112
119
|
mass: comp.mass,
|
|
113
120
|
itemType: 'component',
|
|
@@ -155,6 +162,16 @@ function computeCapabilityGroup(moduleType: number, stats: Record<string, number
|
|
|
155
162
|
{label: 'Drain', value: caps.drain},
|
|
156
163
|
]}
|
|
157
164
|
}
|
|
165
|
+
case MODULE_STORAGE: {
|
|
166
|
+
const str = stats.strength ?? 500
|
|
167
|
+
const duc = stats.ductility ?? 500
|
|
168
|
+
const pur = stats.purity ?? 500
|
|
169
|
+
const statSum = str + duc + pur
|
|
170
|
+
const pct = 10 + Math.floor(statSum * 10 / 2997)
|
|
171
|
+
return {capability: 'Storage', attributes: [
|
|
172
|
+
{label: 'Capacity Bonus', value: pct},
|
|
173
|
+
]}
|
|
174
|
+
}
|
|
158
175
|
default:
|
|
159
176
|
return undefined
|
|
160
177
|
}
|
|
@@ -172,7 +189,7 @@ function resolveModule(id: number, seed?: UInt64Type): ResolvedItem {
|
|
|
172
189
|
return {
|
|
173
190
|
itemId: id,
|
|
174
191
|
name: recipe.name,
|
|
175
|
-
icon: moduleIcon,
|
|
192
|
+
icon: itemIcons[id] ?? moduleIcon,
|
|
176
193
|
tier: 't1' as ResourceTier,
|
|
177
194
|
mass: 0,
|
|
178
195
|
itemType: 'module',
|
|
@@ -183,6 +200,8 @@ function resolveModule(id: number, seed?: UInt64Type): ResolvedItem {
|
|
|
183
200
|
function resolveEntity(id: number, seed?: UInt64Type, modules?: ServerContract.Types.module_entry[]): ResolvedItem {
|
|
184
201
|
const recipe = getEntityRecipeByItemId(id)!
|
|
185
202
|
let attributes: ResolvedAttributeGroup[] | undefined
|
|
203
|
+
let moduleSlots: ResolvedModuleSlot[] | undefined
|
|
204
|
+
|
|
186
205
|
if (seed !== undefined) {
|
|
187
206
|
const stats = decodeCraftedItemStats(id, toBigSeed(seed))
|
|
188
207
|
attributes = []
|
|
@@ -201,27 +220,37 @@ function resolveEntity(id: number, seed?: UInt64Type, modules?: ServerContract.T
|
|
|
201
220
|
{label: 'Capacity', value: containerCaps.capacity},
|
|
202
221
|
]})
|
|
203
222
|
}
|
|
223
|
+
}
|
|
204
224
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
225
|
+
if (recipe.moduleSlots) {
|
|
226
|
+
moduleSlots = recipe.moduleSlots.map((slot, i) => {
|
|
227
|
+
const mod = modules?.[i]
|
|
228
|
+
if (mod?.installed) {
|
|
208
229
|
const modItemId = Number(mod.installed.item_id.value.toString())
|
|
209
230
|
const modSeed = BigInt(mod.installed.seed.toString())
|
|
210
231
|
const modStats = decodeCraftedItemStats(modItemId, modSeed)
|
|
211
232
|
const modType = getModuleCapabilityType(modItemId)
|
|
212
233
|
const group = computeCapabilityGroup(modType, modStats)
|
|
213
|
-
|
|
234
|
+
const modRecipe = getModuleRecipeByItemId(modItemId)
|
|
235
|
+
return {
|
|
236
|
+
name: modRecipe?.name ?? 'Module',
|
|
237
|
+
installed: true,
|
|
238
|
+
attributes: group?.attributes,
|
|
239
|
+
}
|
|
214
240
|
}
|
|
215
|
-
|
|
241
|
+
return {installed: false}
|
|
242
|
+
})
|
|
216
243
|
}
|
|
244
|
+
|
|
217
245
|
return {
|
|
218
246
|
itemId: id,
|
|
219
247
|
name: recipe.name,
|
|
220
|
-
icon: componentIcon,
|
|
248
|
+
icon: itemIcons[id] ?? componentIcon,
|
|
221
249
|
tier: 't1' as ResourceTier,
|
|
222
250
|
mass: 0,
|
|
223
251
|
itemType: 'entity',
|
|
224
252
|
attributes,
|
|
253
|
+
moduleSlots,
|
|
225
254
|
}
|
|
226
255
|
}
|
|
227
256
|
|
package/src/travel/travel.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
Checksum256,
|
|
15
15
|
Int64,
|
|
16
16
|
Int64Type,
|
|
17
|
+
UInt16,
|
|
17
18
|
UInt32,
|
|
18
19
|
UInt32Type,
|
|
19
20
|
UInt64,
|
|
@@ -126,7 +127,8 @@ export function calc_rechargetime(
|
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
export function calc_ship_rechargetime(ship: ShipLike): UInt32 {
|
|
129
|
-
|
|
130
|
+
if (!ship.generator) return UInt32.from(0)
|
|
131
|
+
return calc_rechargetime(ship.generator.capacity, ship.energy ?? UInt16.from(0), ship.generator.recharge)
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
export function calc_flighttime(distance: UInt64Type, acceleration: number): UInt32 {
|
|
@@ -139,7 +141,9 @@ export function calc_loader_flighttime(ship: ShipLike, mass: UInt64, altitude?:
|
|
|
139
141
|
}
|
|
140
142
|
|
|
141
143
|
export function calc_loader_acceleration(ship: ShipLike, mass: UInt64): number {
|
|
142
|
-
|
|
144
|
+
const thrust = ship.loaders ? Number(ship.loaders.thrust) : 0
|
|
145
|
+
const loaderMass = ship.loaders ? Number(ship.loaders.mass) : 0
|
|
146
|
+
return calc_acceleration(thrust, Number(mass) + loaderMass)
|
|
143
147
|
}
|
|
144
148
|
|
|
145
149
|
export function calc_ship_flighttime(ship: ShipLike, mass: UInt64, distance: UInt64): UInt32 {
|
|
@@ -148,7 +152,8 @@ export function calc_ship_flighttime(ship: ShipLike, mass: UInt64, distance: UIn
|
|
|
148
152
|
}
|
|
149
153
|
|
|
150
154
|
export function calc_ship_acceleration(ship: ShipLike, mass: UInt64): number {
|
|
151
|
-
|
|
155
|
+
const thrust = ship.engines ? Number(ship.engines.thrust) : 0
|
|
156
|
+
return calc_acceleration(thrust, Number(mass))
|
|
152
157
|
}
|
|
153
158
|
|
|
154
159
|
export function calc_acceleration(thrust: number, mass: number): number {
|
|
@@ -160,7 +165,7 @@ export function calc_ship_mass(ship: ShipLike, cargos: CargoMassInfo[]): UInt64
|
|
|
160
165
|
|
|
161
166
|
mass.add(ship.hullmass)
|
|
162
167
|
|
|
163
|
-
if (ship.loaders.quantity.gt(UInt32.zero)) {
|
|
168
|
+
if (ship.loaders && ship.loaders.quantity.gt(UInt32.zero)) {
|
|
164
169
|
mass.add(ship.loaders.mass.multiplying(ship.loaders.quantity))
|
|
165
170
|
}
|
|
166
171
|
|
|
@@ -195,6 +200,7 @@ export function calculateTransferTime(
|
|
|
195
200
|
return UInt32.from(0)
|
|
196
201
|
}
|
|
197
202
|
|
|
203
|
+
if (!ship.loaders) return UInt32.from(0)
|
|
198
204
|
mass = UInt64.from(mass).adding(ship.loaders.mass)
|
|
199
205
|
const transfer_time = calc_loader_flighttime(ship, mass)
|
|
200
206
|
return transfer_time.dividing(ship.loaders.quantity)
|
|
@@ -252,17 +258,17 @@ export function calculateLoadTimeBreakdown(
|
|
|
252
258
|
let unloadTime = 0
|
|
253
259
|
let loadTime = 0
|
|
254
260
|
|
|
255
|
-
if (mass_unload.gt(UInt64.zero)) {
|
|
261
|
+
if (mass_unload.gt(UInt64.zero) && ship.loaders) {
|
|
256
262
|
const totalMass = UInt64.from(mass_unload).adding(ship.loaders.mass)
|
|
257
263
|
unloadTime = Number(calc_loader_flighttime(ship, totalMass))
|
|
258
264
|
}
|
|
259
265
|
|
|
260
|
-
if (mass_load.gt(UInt64.zero)) {
|
|
266
|
+
if (mass_load.gt(UInt64.zero) && ship.loaders) {
|
|
261
267
|
const totalMass = UInt64.from(mass_load).adding(ship.loaders.mass)
|
|
262
268
|
loadTime = Number(calc_loader_flighttime(ship, totalMass))
|
|
263
269
|
}
|
|
264
270
|
|
|
265
|
-
const numLoaders = Number(ship.loaders.quantity)
|
|
271
|
+
const numLoaders = ship.loaders ? Number(ship.loaders.quantity) : 0
|
|
266
272
|
const totalTime = numLoaders > 0 ? (unloadTime + loadTime) / numLoaders : 0
|
|
267
273
|
const unloadTimePerLoader = numLoaders > 0 ? unloadTime / numLoaders : 0
|
|
268
274
|
const loadTimePerLoader = numLoaders > 0 ? loadTime / numLoaders : 0
|
|
@@ -307,6 +313,7 @@ export function estimateTravelTime(
|
|
|
307
313
|
if (
|
|
308
314
|
loadMass &&
|
|
309
315
|
UInt32.from(loadMass).gt(UInt32.zero) &&
|
|
316
|
+
ship.loaders &&
|
|
310
317
|
ship.loaders.quantity.gt(UInt32.zero)
|
|
311
318
|
) {
|
|
312
319
|
const totalMass = UInt64.from(loadMass).adding(ship.loaders.mass)
|
|
@@ -316,6 +323,7 @@ export function estimateTravelTime(
|
|
|
316
323
|
if (
|
|
317
324
|
unloadMass &&
|
|
318
325
|
UInt32.from(unloadMass).gt(UInt32.zero) &&
|
|
326
|
+
ship.loaders &&
|
|
319
327
|
ship.loaders.quantity.gt(UInt32.zero)
|
|
320
328
|
) {
|
|
321
329
|
const totalMass = UInt64.from(unloadMass).adding(ship.loaders.mass)
|
|
@@ -346,8 +354,9 @@ export function estimateDealTravelTime(
|
|
|
346
354
|
}
|
|
347
355
|
|
|
348
356
|
export function hasEnergyForDistance(ship: ShipLike, distance: UInt64Type): boolean {
|
|
357
|
+
if (!ship.engines) return false
|
|
349
358
|
const energyNeeded = UInt64.from(distance).dividing(PRECISION).multiplying(ship.engines.drain)
|
|
350
|
-
return UInt64.from(ship.energy).gte(energyNeeded)
|
|
359
|
+
return UInt64.from(ship.energy ?? 0).gte(energyNeeded)
|
|
351
360
|
}
|
|
352
361
|
|
|
353
362
|
export interface TransferEntity {
|
package/src/types/entity.ts
CHANGED
|
@@ -28,7 +28,7 @@ export type ShipEntity = Entity &
|
|
|
28
28
|
extractor?: ServerContract.Types.extractor_stats
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export type WarehouseEntity = Entity & StorageCapability & LoaderCapability & ScheduleCapability
|
|
31
|
+
export type WarehouseEntity = Entity & StorageCapability & Partial<LoaderCapability> & MassCapability & ScheduleCapability
|
|
32
32
|
|
|
33
33
|
export type ContainerEntity = Entity & StorageCapability & MassCapability & ScheduleCapability
|
|
34
34
|
|
package/src/types.ts
CHANGED
|
@@ -28,12 +28,12 @@ export const BASE_ORBITAL_MASS = 100000
|
|
|
28
28
|
|
|
29
29
|
export interface ShipLike {
|
|
30
30
|
coordinates: ServerContract.Types.coordinates
|
|
31
|
-
hullmass
|
|
32
|
-
energy
|
|
33
|
-
engines
|
|
34
|
-
generator
|
|
35
|
-
loaders
|
|
36
|
-
capacity
|
|
31
|
+
hullmass?: UInt32
|
|
32
|
+
energy?: UInt16
|
|
33
|
+
engines?: ServerContract.Types.movement_stats
|
|
34
|
+
generator?: ServerContract.Types.energy_stats
|
|
35
|
+
loaders?: ServerContract.Types.loader_stats
|
|
36
|
+
capacity?: UInt32
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export interface CargoMassInfo {
|