@shipload/sdk 2.0.0-rc2 → 2.0.0-rc20
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/README.md +1 -349
- package/lib/shipload.d.ts +1658 -1126
- package/lib/shipload.js +6847 -3082
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +6468 -2793
- package/lib/shipload.m.js.map +1 -1
- package/package.json +6 -4
- package/src/capabilities/crafting.ts +22 -0
- package/src/capabilities/gathering.ts +36 -0
- package/src/capabilities/guards.ts +3 -8
- package/src/capabilities/hauling.ts +22 -0
- package/src/capabilities/index.ts +4 -1
- package/src/capabilities/modules.ts +57 -0
- package/src/capabilities/storage.ts +101 -9
- package/src/contracts/server.ts +717 -293
- package/src/data/capabilities.ts +408 -0
- package/src/data/categories.ts +55 -0
- package/src/data/colors.ts +71 -0
- package/src/data/items.json +17 -0
- package/src/data/locations.ts +53 -0
- package/src/data/nebula-adjectives.json +211 -0
- package/src/data/nebula-nouns.json +151 -0
- package/src/data/recipes.ts +587 -0
- package/src/data/syllables.json +1386 -780
- package/src/data/tiers.ts +45 -0
- package/src/derivation/crafting.ts +287 -0
- package/src/derivation/index.ts +30 -0
- package/src/derivation/location-size.ts +15 -0
- package/src/derivation/resources.ts +136 -0
- package/src/derivation/stats.ts +146 -0
- package/src/derivation/stratum.ts +134 -0
- package/src/derivation/tiers.ts +54 -0
- package/src/entities/cargo-utils.ts +10 -68
- package/src/entities/container.ts +37 -0
- package/src/entities/entity-inventory.ts +13 -13
- package/src/entities/inventory-accessor.ts +2 -6
- package/src/entities/location.ts +5 -200
- package/src/entities/makers.ts +136 -17
- package/src/entities/player.ts +1 -274
- package/src/entities/ship-deploy.ts +258 -0
- package/src/entities/ship.ts +28 -34
- package/src/entities/warehouse.ts +35 -7
- package/src/errors.ts +59 -5
- package/src/format.ts +12 -0
- package/src/index-module.ts +233 -50
- package/src/managers/actions.ts +138 -88
- package/src/managers/context.ts +19 -9
- package/src/managers/index.ts +0 -1
- package/src/managers/locations.ts +2 -85
- package/src/market/items.ts +93 -0
- package/src/nft/description.ts +176 -0
- package/src/nft/deserializers.ts +81 -0
- package/src/nft/index.ts +2 -0
- package/src/resolution/describe-module.ts +165 -0
- package/src/resolution/display-name.ts +39 -0
- package/src/resolution/resolve-item.ts +343 -0
- package/src/scheduling/projection.ts +220 -67
- package/src/scheduling/schedule.ts +2 -2
- package/src/shipload.ts +10 -5
- package/src/subscriptions/connection.ts +154 -0
- package/src/subscriptions/debug.ts +17 -0
- package/src/subscriptions/index.ts +5 -0
- package/src/subscriptions/manager.ts +240 -0
- package/src/subscriptions/mappers.ts +28 -0
- package/src/subscriptions/types.ts +143 -0
- package/src/travel/travel.ts +30 -17
- package/src/types/capabilities.ts +11 -14
- package/src/types/entity-traits.ts +3 -4
- package/src/types/entity.ts +9 -6
- package/src/types.ts +61 -55
- package/src/utils/system.ts +66 -53
- package/src/capabilities/extraction.ts +0 -37
- package/src/data/goods.json +0 -23
- package/src/managers/trades.ts +0 -119
- package/src/market/goods.ts +0 -31
- package/src/market/market.ts +0 -208
- package/src/market/rolls.ts +0 -8
- package/src/trading/collect.ts +0 -938
- package/src/trading/deal.ts +0 -207
- package/src/trading/trade.ts +0 -203
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import {decodeCraftedItemStats} from '../derivation/crafting'
|
|
2
|
+
import {
|
|
3
|
+
getModuleCapabilityType,
|
|
4
|
+
MODULE_CRAFTER,
|
|
5
|
+
MODULE_ENGINE,
|
|
6
|
+
MODULE_GATHERER,
|
|
7
|
+
MODULE_GENERATOR,
|
|
8
|
+
MODULE_HAULER,
|
|
9
|
+
MODULE_LOADER,
|
|
10
|
+
} from '../capabilities/modules'
|
|
11
|
+
|
|
12
|
+
export function computeShipHullCapabilities(stats: Record<string, number>): {
|
|
13
|
+
hullmass: number
|
|
14
|
+
capacity: number
|
|
15
|
+
} {
|
|
16
|
+
const density = stats.density ?? 500
|
|
17
|
+
const strength = stats.strength ?? 500
|
|
18
|
+
const fineness = stats.fineness ?? 500
|
|
19
|
+
const saturation = stats.saturation ?? 500
|
|
20
|
+
|
|
21
|
+
const hullmass = 25000 + 75 * density
|
|
22
|
+
const statSum = strength + fineness + saturation
|
|
23
|
+
const exponent = statSum / 2997.0
|
|
24
|
+
const capacity = Math.floor(1000000 * Math.pow(10, exponent))
|
|
25
|
+
|
|
26
|
+
return {hullmass, capacity}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function computeEngineCapabilities(stats: Record<string, number>): {
|
|
30
|
+
thrust: number
|
|
31
|
+
drain: number
|
|
32
|
+
} {
|
|
33
|
+
const vol = stats.volatility ?? 500
|
|
34
|
+
const thm = stats.thermal ?? 500
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
thrust: 400 + Math.floor((vol * 3) / 4),
|
|
38
|
+
drain: Math.max(30, 50 - Math.floor(thm / 70)),
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function computeGeneratorCapabilities(stats: Record<string, number>): {
|
|
43
|
+
capacity: number
|
|
44
|
+
recharge: number
|
|
45
|
+
} {
|
|
46
|
+
const res = stats.resonance ?? 500
|
|
47
|
+
const ref = stats.reflectivity ?? 500
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
capacity: 300 + Math.floor(res / 6),
|
|
51
|
+
recharge: 1 + Math.floor((ref * 3) / 1000),
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function computeGathererCapabilities(stats: Record<string, number>): {
|
|
56
|
+
yield: number
|
|
57
|
+
drain: number
|
|
58
|
+
depth: number
|
|
59
|
+
speed: number
|
|
60
|
+
} {
|
|
61
|
+
const str = stats.strength ?? 500
|
|
62
|
+
const con = stats.conductivity ?? 500
|
|
63
|
+
const ref = stats.reflectivity ?? 500
|
|
64
|
+
const tol = stats.tolerance ?? 500
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
yield: 200 + str,
|
|
68
|
+
drain: Math.max(250, 1250 - Math.floor((con * 25) / 20)),
|
|
69
|
+
depth: 200 + Math.floor((tol * 3) / 2),
|
|
70
|
+
speed: 100 + Math.floor((ref * 4) / 5),
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function computeLoaderCapabilities(stats: Record<string, number>): {
|
|
75
|
+
mass: number
|
|
76
|
+
thrust: number
|
|
77
|
+
quantity: number
|
|
78
|
+
} {
|
|
79
|
+
const fin = stats.fineness ?? 500
|
|
80
|
+
const pla = stats.plasticity ?? 500
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
mass: Math.max(200, 2000 - Math.floor(fin * 2)),
|
|
84
|
+
thrust: 1 + Math.floor(pla / 500),
|
|
85
|
+
quantity: 1,
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function computeCrafterCapabilities(stats: Record<string, number>): {
|
|
90
|
+
speed: number
|
|
91
|
+
drain: number
|
|
92
|
+
} {
|
|
93
|
+
const rea = stats.reactivity ?? 500
|
|
94
|
+
const com = stats.composition ?? 500
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
speed: 100 + Math.floor((rea * 4) / 5),
|
|
98
|
+
drain: Math.max(5, 30 - Math.floor(com / 33)),
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function computeHaulerCapabilities(stats: Record<string, number>): {
|
|
103
|
+
capacity: number
|
|
104
|
+
efficiency: number
|
|
105
|
+
drain: number
|
|
106
|
+
} {
|
|
107
|
+
const res = stats.resonance ?? 500
|
|
108
|
+
const con = stats.conductivity ?? 500
|
|
109
|
+
const ref = stats.reflectivity ?? 500
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
capacity: Math.max(1, 1 + Math.floor(res / 400)),
|
|
113
|
+
efficiency: 2000 + con * 6,
|
|
114
|
+
drain: Math.max(3, 15 - Math.floor(ref / 80)),
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function computeStorageCapabilities(
|
|
119
|
+
stats: Record<string, number>,
|
|
120
|
+
baseCapacity: number
|
|
121
|
+
): {
|
|
122
|
+
capacityBonus: number
|
|
123
|
+
} {
|
|
124
|
+
const strength = stats.strength ?? 500
|
|
125
|
+
const fineness = stats.fineness ?? 500
|
|
126
|
+
const saturation = stats.saturation ?? 500
|
|
127
|
+
|
|
128
|
+
const statSum = strength + fineness + saturation
|
|
129
|
+
const capacityBonus = Math.floor(
|
|
130
|
+
(baseCapacity * (10 + Math.floor((statSum * 10) / 2997))) / 100
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
return {capacityBonus}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function computeWarehouseHullCapabilities(stats: Record<string, number>): {
|
|
137
|
+
hullmass: number
|
|
138
|
+
capacity: number
|
|
139
|
+
} {
|
|
140
|
+
const density = stats.density ?? 500
|
|
141
|
+
const strength = stats.strength ?? 500
|
|
142
|
+
const fineness = stats.fineness ?? 500
|
|
143
|
+
const saturation = stats.saturation ?? 500
|
|
144
|
+
|
|
145
|
+
const hullmass = 25000 + 75 * density
|
|
146
|
+
const statSum = strength + fineness + saturation
|
|
147
|
+
const exponent = statSum / 2997.0
|
|
148
|
+
const capacity = Math.floor(20000000 * Math.pow(10, exponent))
|
|
149
|
+
|
|
150
|
+
return {hullmass, capacity}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface ShipCapabilities {
|
|
154
|
+
engines?: {thrust: number; drain: number}
|
|
155
|
+
generator?: {capacity: number; recharge: number}
|
|
156
|
+
gatherer?: {yield: number; drain: number; depth: number; speed: number}
|
|
157
|
+
hauler?: {capacity: number; efficiency: number; drain: number}
|
|
158
|
+
loaders?: {mass: number; thrust: number; quantity: number}
|
|
159
|
+
crafter?: {speed: number; drain: number}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function computeShipCapabilities(
|
|
163
|
+
modules: {itemId: number; stats: bigint}[]
|
|
164
|
+
): ShipCapabilities {
|
|
165
|
+
const ship: ShipCapabilities = {}
|
|
166
|
+
|
|
167
|
+
const engineModules = modules.filter((m) => getModuleCapabilityType(m.itemId) === MODULE_ENGINE)
|
|
168
|
+
if (engineModules.length > 0) {
|
|
169
|
+
let totalThrust = 0
|
|
170
|
+
let totalDrain = 0
|
|
171
|
+
for (const m of engineModules) {
|
|
172
|
+
const caps = computeEngineCapabilities(decodeCraftedItemStats(m.itemId, m.stats))
|
|
173
|
+
totalThrust += caps.thrust
|
|
174
|
+
totalDrain += caps.drain
|
|
175
|
+
}
|
|
176
|
+
ship.engines = {thrust: totalThrust, drain: totalDrain}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const generatorModules = modules.filter(
|
|
180
|
+
(m) => getModuleCapabilityType(m.itemId) === MODULE_GENERATOR
|
|
181
|
+
)
|
|
182
|
+
if (generatorModules.length > 0) {
|
|
183
|
+
let totalCapacity = 0
|
|
184
|
+
let totalRecharge = 0
|
|
185
|
+
for (const m of generatorModules) {
|
|
186
|
+
const caps = computeGeneratorCapabilities(decodeCraftedItemStats(m.itemId, m.stats))
|
|
187
|
+
totalCapacity += caps.capacity
|
|
188
|
+
totalRecharge += caps.recharge
|
|
189
|
+
}
|
|
190
|
+
ship.generator = {capacity: totalCapacity, recharge: totalRecharge}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const gathererModules = modules.filter(
|
|
194
|
+
(m) => getModuleCapabilityType(m.itemId) === MODULE_GATHERER
|
|
195
|
+
)
|
|
196
|
+
if (gathererModules.length > 0) {
|
|
197
|
+
let totalYield = 0
|
|
198
|
+
let totalDrain = 0
|
|
199
|
+
let totalDepth = 0
|
|
200
|
+
let totalSpeed = 0
|
|
201
|
+
for (const m of gathererModules) {
|
|
202
|
+
const caps = computeGathererCapabilities(decodeCraftedItemStats(m.itemId, m.stats))
|
|
203
|
+
totalYield += caps.yield
|
|
204
|
+
totalDrain += caps.drain
|
|
205
|
+
totalDepth += caps.depth
|
|
206
|
+
totalSpeed += caps.speed
|
|
207
|
+
}
|
|
208
|
+
ship.gatherer = {yield: totalYield, drain: totalDrain, depth: totalDepth, speed: totalSpeed}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const haulerModules = modules.filter((m) => getModuleCapabilityType(m.itemId) === MODULE_HAULER)
|
|
212
|
+
if (haulerModules.length > 0) {
|
|
213
|
+
let totalCapacity = 0
|
|
214
|
+
let weightedEffNum = 0
|
|
215
|
+
let totalDrain = 0
|
|
216
|
+
for (const m of haulerModules) {
|
|
217
|
+
const caps = computeHaulerCapabilities(decodeCraftedItemStats(m.itemId, m.stats))
|
|
218
|
+
totalCapacity += caps.capacity
|
|
219
|
+
weightedEffNum += caps.efficiency * caps.capacity
|
|
220
|
+
totalDrain += caps.drain
|
|
221
|
+
}
|
|
222
|
+
ship.hauler = {
|
|
223
|
+
capacity: totalCapacity,
|
|
224
|
+
efficiency: totalCapacity > 0 ? Math.floor(weightedEffNum / totalCapacity) : 0,
|
|
225
|
+
drain: totalDrain,
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const loaderModules = modules.filter((m) => getModuleCapabilityType(m.itemId) === MODULE_LOADER)
|
|
230
|
+
if (loaderModules.length > 0) {
|
|
231
|
+
let totalMass = 0
|
|
232
|
+
let totalThrust = 0
|
|
233
|
+
let totalQuantity = 0
|
|
234
|
+
for (const m of loaderModules) {
|
|
235
|
+
const caps = computeLoaderCapabilities(decodeCraftedItemStats(m.itemId, m.stats))
|
|
236
|
+
totalMass += caps.mass
|
|
237
|
+
totalThrust += caps.thrust
|
|
238
|
+
totalQuantity += caps.quantity
|
|
239
|
+
}
|
|
240
|
+
ship.loaders = {mass: totalMass, thrust: totalThrust, quantity: totalQuantity}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const crafterModules = modules.filter(
|
|
244
|
+
(m) => getModuleCapabilityType(m.itemId) === MODULE_CRAFTER
|
|
245
|
+
)
|
|
246
|
+
if (crafterModules.length > 0) {
|
|
247
|
+
let totalSpeed = 0
|
|
248
|
+
let totalDrain = 0
|
|
249
|
+
for (const m of crafterModules) {
|
|
250
|
+
const caps = computeCrafterCapabilities(decodeCraftedItemStats(m.itemId, m.stats))
|
|
251
|
+
totalSpeed += caps.speed
|
|
252
|
+
totalDrain += caps.drain
|
|
253
|
+
}
|
|
254
|
+
ship.crafter = {speed: totalSpeed, drain: totalDrain}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return ship
|
|
258
|
+
}
|
package/src/entities/ship.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {UInt16, UInt32, UInt64, UInt64Type} from '@wharfkit/antelope'
|
|
1
|
+
import {UInt16, UInt16Type, UInt32, UInt64, UInt64Type} from '@wharfkit/antelope'
|
|
2
2
|
import {ServerContract} from '../contracts'
|
|
3
3
|
import {Coordinates, CoordinatesType} from '../types'
|
|
4
4
|
import {
|
|
@@ -21,20 +21,22 @@ import {
|
|
|
21
21
|
hasEnergyForDistance,
|
|
22
22
|
maxTravelDistance,
|
|
23
23
|
} from '../capabilities/movement'
|
|
24
|
-
import * as cargoUtils from './cargo-utils'
|
|
25
24
|
import * as schedule from '../scheduling/schedule'
|
|
26
25
|
|
|
26
|
+
export interface PackedModuleInput {
|
|
27
|
+
itemId: UInt16Type
|
|
28
|
+
stats: UInt64Type
|
|
29
|
+
}
|
|
30
|
+
|
|
27
31
|
export interface ShipStateInput {
|
|
28
32
|
id: UInt64Type
|
|
29
33
|
owner: string
|
|
30
34
|
name: string
|
|
31
35
|
coordinates: CoordinatesType | {x: number; y: number; z?: number}
|
|
32
|
-
hullmass
|
|
33
|
-
capacity
|
|
34
|
-
energy
|
|
35
|
-
|
|
36
|
-
generator: ServerContract.Types.energy_stats
|
|
37
|
-
loaders: ServerContract.Types.loader_stats
|
|
36
|
+
hullmass?: number
|
|
37
|
+
capacity?: number
|
|
38
|
+
energy?: number
|
|
39
|
+
modules?: PackedModuleInput[]
|
|
38
40
|
schedule?: ServerContract.Types.schedule
|
|
39
41
|
cargo?: ServerContract.Types.cargo_item[]
|
|
40
42
|
}
|
|
@@ -105,12 +107,24 @@ export class Ship extends ServerContract.Types.entity_info {
|
|
|
105
107
|
return schedule.isUnloading(this, now)
|
|
106
108
|
}
|
|
107
109
|
|
|
108
|
-
|
|
109
|
-
return schedule.
|
|
110
|
+
isGathering(now: Date): boolean {
|
|
111
|
+
return schedule.isGathering(this, now)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get hasEngines(): boolean {
|
|
115
|
+
return this.engines !== undefined
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get hasGenerator(): boolean {
|
|
119
|
+
return this.generator !== undefined
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
get hasGatherer(): boolean {
|
|
123
|
+
return this.gatherer !== undefined
|
|
110
124
|
}
|
|
111
125
|
|
|
112
|
-
get
|
|
113
|
-
return this.
|
|
126
|
+
get hasWarp(): boolean {
|
|
127
|
+
return this.warp !== undefined
|
|
114
128
|
}
|
|
115
129
|
|
|
116
130
|
project(): ProjectedEntity {
|
|
@@ -129,10 +143,6 @@ export class Ship extends ServerContract.Types.entity_info {
|
|
|
129
143
|
return this.inv.totalMass
|
|
130
144
|
}
|
|
131
145
|
|
|
132
|
-
get cargoValue(): UInt64 {
|
|
133
|
-
return this.inv.totalValue
|
|
134
|
-
}
|
|
135
|
-
|
|
136
146
|
get totalMass(): UInt64 {
|
|
137
147
|
let mass = UInt64.from(this.hullmass ?? 0).adding(this.totalCargoMass)
|
|
138
148
|
if (this.loaders) {
|
|
@@ -155,8 +165,8 @@ export class Ship extends ServerContract.Types.entity_info {
|
|
|
155
165
|
: this.maxCapacity.subtracting(this.totalMass)
|
|
156
166
|
}
|
|
157
167
|
|
|
158
|
-
|
|
159
|
-
return this.inv.
|
|
168
|
+
getCargoForItem(goodId: UInt64Type): EntityInventory | undefined {
|
|
169
|
+
return this.inv.forItem(goodId)
|
|
160
170
|
}
|
|
161
171
|
|
|
162
172
|
get sellableCargo(): EntityInventory[] {
|
|
@@ -189,20 +199,4 @@ export class Ship extends ServerContract.Types.entity_info {
|
|
|
189
199
|
if (!this.engines || !this.generator || this.energy === undefined) return false
|
|
190
200
|
return hasEnergyForDistance(this as MovementEntity, distance)
|
|
191
201
|
}
|
|
192
|
-
|
|
193
|
-
calculateSaleValue(prices: Map<number, UInt64>): cargoUtils.SaleValue {
|
|
194
|
-
return cargoUtils.calculateSaleValue(this.cargo, prices)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
calculateSaleValueFromArray(prices: UInt64[]): cargoUtils.SaleValue {
|
|
198
|
-
return cargoUtils.calculateSaleValueFromArray(this.cargo, prices)
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
afterSellGoods(goodsToSell: Array<{goodId: number; quantity: number}>): EntityInventory[] {
|
|
202
|
-
return cargoUtils.afterSellGoods(this.cargo, goodsToSell)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
afterSellAllGoods(): EntityInventory[] {
|
|
206
|
-
return cargoUtils.afterSellAllGoods(this.cargo)
|
|
207
|
-
}
|
|
208
202
|
}
|
|
@@ -6,14 +6,19 @@ import {ScheduleAccessor} from '../scheduling/accessor'
|
|
|
6
6
|
import {InventoryAccessor} from './inventory-accessor'
|
|
7
7
|
import {EntityInventory} from './entity-inventory'
|
|
8
8
|
import * as schedule from '../scheduling/schedule'
|
|
9
|
+
import type {PackedModuleInput} from './ship'
|
|
10
|
+
import {decodeCraftedItemStats} from '../derivation/crafting'
|
|
11
|
+
import {getModuleCapabilityType, MODULE_LOADER} from '../capabilities/modules'
|
|
12
|
+
import {computeLoaderCapabilities} from './ship-deploy'
|
|
9
13
|
|
|
10
14
|
export interface WarehouseStateInput {
|
|
11
15
|
id: UInt64Type
|
|
12
16
|
owner: string
|
|
13
17
|
name: string
|
|
14
18
|
coordinates: CoordinatesType | {x: number; y: number; z?: number}
|
|
19
|
+
hullmass?: number
|
|
15
20
|
capacity: number
|
|
16
|
-
|
|
21
|
+
modules?: PackedModuleInput[]
|
|
17
22
|
schedule?: ServerContract.Types.schedule
|
|
18
23
|
cargo?: ServerContract.Types.cargo_item[]
|
|
19
24
|
}
|
|
@@ -58,10 +63,6 @@ export class Warehouse extends ServerContract.Types.entity_info {
|
|
|
58
63
|
return this.inv.totalMass
|
|
59
64
|
}
|
|
60
65
|
|
|
61
|
-
get cargoValue(): UInt64 {
|
|
62
|
-
return this.inv.totalValue
|
|
63
|
-
}
|
|
64
|
-
|
|
65
66
|
get maxCapacity(): UInt64 {
|
|
66
67
|
return UInt64.from(this.capacity)
|
|
67
68
|
}
|
|
@@ -79,11 +80,38 @@ export class Warehouse extends ServerContract.Types.entity_info {
|
|
|
79
80
|
return this.totalCargoMass.gte(this.maxCapacity)
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
return this.inv.
|
|
83
|
+
getCargoForItem(goodId: UInt64Type): EntityInventory | undefined {
|
|
84
|
+
return this.inv.forItem(goodId)
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
get orbitalAltitude(): number {
|
|
87
88
|
return this.coordinates.z?.toNumber() || 0
|
|
88
89
|
}
|
|
90
|
+
|
|
91
|
+
get totalMass(): UInt64 {
|
|
92
|
+
const hull = this.hullmass ? UInt64.from(this.hullmass) : UInt64.from(0)
|
|
93
|
+
return hull.adding(this.totalCargoMass)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function computeWarehouseCapabilities(modules: {itemId: number; stats: bigint}[]): {
|
|
98
|
+
loaders?: {mass: number; thrust: number; quantity: number}
|
|
99
|
+
} {
|
|
100
|
+
const warehouse: {loaders?: {mass: number; thrust: number; quantity: number}} = {}
|
|
101
|
+
|
|
102
|
+
const loaderModules = modules.filter((m) => getModuleCapabilityType(m.itemId) === MODULE_LOADER)
|
|
103
|
+
if (loaderModules.length > 0) {
|
|
104
|
+
let totalMass = 0
|
|
105
|
+
let totalThrust = 0
|
|
106
|
+
let totalQuantity = 0
|
|
107
|
+
for (const m of loaderModules) {
|
|
108
|
+
const caps = computeLoaderCapabilities(decodeCraftedItemStats(m.itemId, m.stats))
|
|
109
|
+
totalMass += caps.mass
|
|
110
|
+
totalThrust += caps.thrust
|
|
111
|
+
totalQuantity += caps.quantity
|
|
112
|
+
}
|
|
113
|
+
warehouse.loaders = {mass: totalMass, thrust: totalThrust, quantity: totalQuantity}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return warehouse
|
|
89
117
|
}
|
package/src/errors.ts
CHANGED
|
@@ -9,16 +9,15 @@ export const ERROR_SYSTEM_DISABLED = 'This game is currently disabled.'
|
|
|
9
9
|
export const ERROR_SYSTEM_NOT_INITIALIZED = 'This game has not been initialized.'
|
|
10
10
|
export const GAME_NOT_FOUND = 'Cannot find game for given account name.'
|
|
11
11
|
export const GAME_SEED_NOT_SET = 'This game has not initialized an epoch seed value.'
|
|
12
|
-
export const
|
|
13
|
-
export const GOOD_NOT_AVAILABLE_AT_LOCATION = 'Good is not tradeable at ship location.'
|
|
14
|
-
export const INSUFFICIENT_BALANCE = 'Insufficient balance.'
|
|
15
|
-
export const INSUFFICIENT_GOOD_QUANTITY = 'Insufficient quantity in cargo.'
|
|
16
|
-
export const INSUFFICIENT_GOOD_SUPPLY = 'Insufficient supply of good at location.'
|
|
12
|
+
export const ITEM_DOES_NOT_EXIST = 'Item does not exist.'
|
|
17
13
|
export const INVALID_AMOUNT = 'Invalid amount.'
|
|
18
14
|
export const REQUIRES_MORE_THAN_ONE = 'A value greater than one is required.'
|
|
19
15
|
export const REQUIRES_POSITIVE_VALUE = 'Value must be greater than zero.'
|
|
20
16
|
export const PLAYER_ALREADY_JOINED = 'Player has already joined the game.'
|
|
17
|
+
export const PLAYER_NOT_JOINED = 'Player has not joined the game.'
|
|
21
18
|
export const PLAYER_NOT_FOUND = 'Cannot find player for given account name.'
|
|
19
|
+
export const STARTER_ALREADY_CLAIMED =
|
|
20
|
+
'Starter ship already claimed; destroy existing ships to re-claim.'
|
|
22
21
|
export const SHIP_ALREADY_THERE = 'Ship cannot travel to the location its already at.'
|
|
23
22
|
export const SHIP_ALREADY_TRAVELING = 'Ship is already traveling.'
|
|
24
23
|
export const SHIP_CANNOT_BUY_TRAVELING = 'Ship cannot buy goods while traveling.'
|
|
@@ -36,11 +35,66 @@ export const SHIP_NOT_OWNED = 'Ship is not owned by this account.'
|
|
|
36
35
|
export const NO_SCHEDULE = 'No scheduled tasks.'
|
|
37
36
|
export const SHIP_NOT_IDLE = 'Ship must be idle (no active schedule) for this action.'
|
|
38
37
|
export const SHIP_NO_COMPLETED_TASKS = 'No completed tasks to resolve.'
|
|
38
|
+
export const RESOLVE_COUNT_EXCEEDS_COMPLETED = 'Requested resolve count exceeds completed tasks.'
|
|
39
39
|
export const SHIP_CANNOT_CANCEL_TASK = 'Cannot cancel task that is immutable or in progress.'
|
|
40
40
|
export const SHIP_NO_TASKS_TO_CANCEL = 'No tasks to cancel.'
|
|
41
41
|
export const SHIP_INVALID_CARGO = 'Invalid cargo specified for load/unload.'
|
|
42
42
|
export const SHIP_CARGO_NOT_OWNED = 'Cannot load cargo that is not owned.'
|
|
43
43
|
export const SHIP_CARGO_NOT_LOADED = 'Cannot unload cargo that is not loaded.'
|
|
44
|
+
export const SHIP_CAPACITY_EXCEEDED = 'Ship cargo capacity would be exceeded.'
|
|
45
|
+
export const ENTITY_CAPACITY_EXCEEDED = 'Entity cargo capacity would be exceeded.'
|
|
44
46
|
export const WAREHOUSE_NOT_FOUND = 'Cannot find warehouse for given id.'
|
|
45
47
|
export const WAREHOUSE_ALREADY_AT_LOCATION = 'Warehouse already exists at this location.'
|
|
46
48
|
export const WAREHOUSE_CAPACITY_EXCEEDED = 'Warehouse capacity would be exceeded.'
|
|
49
|
+
export const CONTAINER_NOT_FOUND = 'Cannot find container for given id.'
|
|
50
|
+
export const CONTAINER_CAPACITY_EXCEEDED = 'Container capacity would be exceeded.'
|
|
51
|
+
export const DESTINATION_CAPACITY_EXCEEDED =
|
|
52
|
+
'Destination entity does not have enough capacity for the gather.'
|
|
53
|
+
export const CANCEL_PAIRED_HAS_PENDING = 'Cannot cancel transfer, paired entity has pending tasks.'
|
|
54
|
+
export const GROUP_EMPTY = 'Group travel requires at least one entity.'
|
|
55
|
+
export const GROUP_NO_THRUST = 'Group travel requires at least one entity with engines.'
|
|
56
|
+
export const GROUP_NOT_SAME_LOCATION = 'All entities must be at the same location for group travel.'
|
|
57
|
+
export const GROUP_NOT_SAME_OWNER = 'All entities must have the same owner for group travel.'
|
|
58
|
+
export const GROUP_ENTITY_NOT_MOVABLE = 'Entity cannot participate in group travel.'
|
|
59
|
+
export const GROUP_NOT_FOUND = 'Entity group not found.'
|
|
60
|
+
export const GROUP_DUPLICATE_ENTITY = 'Duplicate entity in group.'
|
|
61
|
+
export const GROUP_HAUL_CAPACITY_EXCEEDED =
|
|
62
|
+
'Group travel requires sufficient hauler capacity for all non-self-propelled entities.'
|
|
63
|
+
export const CANCEL_CONTAINS_GROUPED_TASK =
|
|
64
|
+
'Cannot cancel range containing grouped task - cancel non-grouped tasks first.'
|
|
65
|
+
export const WARP_NO_CAPABILITY = 'Entity does not have warp capability.'
|
|
66
|
+
export const WARP_HAS_SCHEDULE = 'Entity must be idle to warp.'
|
|
67
|
+
export const WARP_HAS_CARGO = 'Entity must have no cargo to warp.'
|
|
68
|
+
export const WARP_NOT_FULL_ENERGY = 'Entity must have full energy to warp.'
|
|
69
|
+
export const WARP_OUT_OF_RANGE = 'Destination exceeds warp range.'
|
|
70
|
+
|
|
71
|
+
export const ENTITY_NO_CRAFTER = 'Entity does not have crafting capability.'
|
|
72
|
+
export const RECIPE_NOT_FOUND = 'Recipe does not exist.'
|
|
73
|
+
export const RECIPE_INPUTS_INSUFFICIENT = 'Insufficient inputs for recipe.'
|
|
74
|
+
export const RECIPE_INPUTS_INVALID = 'Input cargo does not match recipe requirements.'
|
|
75
|
+
export const RECIPE_INPUTS_EXCESS = 'Provided inputs exceed recipe requirements.'
|
|
76
|
+
export const RECIPE_INPUTS_MIXED = 'All stacks for a recipe input must be the same resource.'
|
|
77
|
+
export const ITEM_NOT_DEPLOYABLE = 'Item cannot be deployed as an entity.'
|
|
78
|
+
export const DEPLOY_ENTITY_HAS_SCHEDULE = 'Entity must be idle to deploy.'
|
|
79
|
+
export const BLEND_INPUTS_MUST_MATCH = 'All blend inputs must be the same item.'
|
|
80
|
+
export const GATHER_NOT_ENOUGH_ENERGY = 'Gather requires more energy than entity has.'
|
|
81
|
+
export const GATHER_EXCEEDS_ENERGY_CAPACITY = "Gather drain exceeds entity's energy capacity."
|
|
82
|
+
export const CRAFT_NOT_ENOUGH_ENERGY = 'Craft requires more energy than entity has.'
|
|
83
|
+
export const CRAFT_EXCEEDS_ENERGY_CAPACITY = "Craft drain exceeds entity's energy capacity."
|
|
84
|
+
export const BLEND_REQUIRES_MULTIPLE = 'Blend requires at least two input stacks.'
|
|
85
|
+
export const BLEND_STAT_LESS_NOT_SUPPORTED = 'Stat-less items cannot be blended.'
|
|
86
|
+
|
|
87
|
+
export const MODULE_SLOT_INVALID = 'Module slot index is invalid.'
|
|
88
|
+
export const MODULE_SLOT_OCCUPIED = 'Module slot is already occupied.'
|
|
89
|
+
export const MODULE_SLOT_EMPTY = 'Module slot is empty.'
|
|
90
|
+
export const MODULE_TYPE_MISMATCH = 'Module type not allowed in this slot.'
|
|
91
|
+
export const MODULE_CARGO_NOT_FOUND = 'Module cargo not found.'
|
|
92
|
+
export const MODULE_NOT_MODULE = 'Item is not a module.'
|
|
93
|
+
export const MODULE_ENTITY_BUSY = 'Entity must be idle to modify modules.'
|
|
94
|
+
export const ITEM_NOT_PACKED_ENTITY = 'Item is not a packed entity.'
|
|
95
|
+
|
|
96
|
+
// SDK-only market errors (no contract counterpart yet)
|
|
97
|
+
export const ITEM_NOT_AVAILABLE_AT_LOCATION = 'Item is not tradeable at ship location.'
|
|
98
|
+
export const INSUFFICIENT_BALANCE = 'Insufficient balance.'
|
|
99
|
+
export const INSUFFICIENT_ITEM_QUANTITY = 'Insufficient quantity in cargo.'
|
|
100
|
+
export const INSUFFICIENT_ITEM_SUPPLY = 'Insufficient supply of item at location.'
|
package/src/format.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function formatMass(kg: number): string {
|
|
2
|
+
const t = kg / 1000
|
|
3
|
+
const fixed = t.toFixed(2)
|
|
4
|
+
const trimmed = fixed.replace(/\.?0+$/, '')
|
|
5
|
+
return `${trimmed} t`
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function formatMassDelta(kg: number): string {
|
|
9
|
+
if (kg === 0) return '0 t'
|
|
10
|
+
const sign = kg > 0 ? '+' : '-'
|
|
11
|
+
return `${sign}${formatMass(Math.abs(kg))}`
|
|
12
|
+
}
|