@shipload/sdk 1.0.0-next.4 → 1.0.0-next.41
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/scan.d.ts +34 -0
- package/lib/scan.js +136 -0
- package/lib/scan.js.map +1 -0
- package/lib/scan.m.js +129 -0
- package/lib/scan.m.js.map +1 -0
- package/lib/shipload.d.ts +2473 -973
- package/lib/shipload.js +11529 -5211
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +11338 -5162
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +970 -0
- package/lib/testing.js +4013 -0
- package/lib/testing.js.map +1 -0
- package/lib/testing.m.js +4007 -0
- package/lib/testing.m.js.map +1 -0
- package/package.json +20 -2
- package/src/capabilities/craftable.ts +51 -0
- package/src/capabilities/crafting.test.ts +7 -0
- package/src/capabilities/crafting.ts +5 -6
- package/src/capabilities/gathering.test.ts +16 -0
- package/src/capabilities/gathering.ts +35 -18
- package/src/capabilities/index.ts +0 -1
- package/src/capabilities/modules.ts +9 -0
- package/src/capabilities/storage.ts +16 -1
- package/src/contracts/platform.ts +231 -3
- package/src/contracts/server.ts +1021 -481
- package/src/coordinates/address.ts +88 -0
- package/src/coordinates/constants.test.ts +15 -0
- package/src/coordinates/constants.ts +23 -0
- package/src/coordinates/index.ts +15 -0
- package/src/coordinates/memo.test.ts +47 -0
- package/src/coordinates/memo.ts +20 -0
- package/src/coordinates/permutation.ts +77 -0
- package/src/coordinates/regions.ts +48 -0
- package/src/coordinates/sectors.ts +115 -0
- package/src/data/capabilities.ts +12 -5
- package/src/data/capability-formulas.ts +14 -7
- package/src/data/catalog.ts +0 -5
- package/src/data/colors.ts +14 -47
- package/src/data/entities.json +76 -10
- package/src/data/item-ids.ts +18 -12
- package/src/data/items.json +321 -38
- package/src/data/kind-registry.json +109 -0
- package/src/data/kind-registry.ts +165 -0
- package/src/data/metadata.ts +119 -33
- package/src/data/recipes-runtime.ts +3 -23
- package/src/data/recipes.json +238 -117
- package/src/derivation/build-methods.ts +45 -0
- package/src/derivation/capabilities.test.ts +151 -0
- package/src/derivation/capabilities.ts +512 -0
- package/src/derivation/capability-mappings.ts +9 -12
- package/src/derivation/crafting.ts +23 -24
- package/src/derivation/index.ts +25 -2
- package/src/derivation/recipe-usage.test.ts +78 -0
- package/src/derivation/recipe-usage.ts +141 -0
- package/src/derivation/reserve-regen.ts +34 -0
- package/src/derivation/resources.ts +125 -38
- package/src/derivation/rollups.test.ts +55 -0
- package/src/derivation/rollups.ts +56 -0
- package/src/derivation/stars.test.ts +51 -0
- package/src/derivation/stars.ts +15 -0
- package/src/derivation/stats.ts +6 -6
- package/src/derivation/stratum.ts +17 -20
- package/src/derivation/tiers.ts +40 -7
- package/src/derivation/wormhole.ts +136 -0
- package/src/entities/entity.ts +98 -0
- package/src/entities/gamestate.ts +3 -28
- package/src/entities/makers.ts +124 -134
- package/src/entities/slot-multiplier.ts +43 -0
- package/src/errors.ts +12 -16
- package/src/format.ts +26 -4
- package/src/index-module.ts +267 -47
- package/src/managers/actions.ts +528 -95
- package/src/managers/base.ts +6 -2
- package/src/managers/construction-types.ts +80 -0
- package/src/managers/construction.ts +412 -0
- package/src/managers/context.ts +20 -1
- package/src/managers/coordinates.ts +14 -0
- package/src/managers/entities.ts +18 -66
- package/src/managers/epochs.ts +40 -0
- package/src/managers/index.ts +17 -1
- package/src/managers/locations.ts +25 -29
- package/src/managers/nft.test.ts +14 -0
- package/src/managers/nft.ts +70 -0
- package/src/managers/plot.ts +122 -0
- package/src/nft/atomicassets.abi.json +1342 -0
- package/src/nft/atomicassets.ts +237 -0
- package/src/nft/atomicdata.ts +130 -0
- package/src/nft/buildImmutableData.ts +338 -0
- package/src/nft/description.ts +98 -24
- package/src/nft/index.ts +3 -0
- package/src/planner/index.ts +127 -0
- package/src/planner/planner.test.ts +319 -0
- package/src/resolution/describe-module.ts +18 -13
- package/src/resolution/display-name.ts +38 -10
- package/src/resolution/resolve-item.test.ts +37 -0
- package/src/resolution/resolve-item.ts +55 -24
- package/src/scan/index.ts +180 -0
- package/src/scan/scan-wasm.base64.ts +2 -0
- package/src/scheduling/accessor.ts +68 -22
- package/src/scheduling/availability.ts +108 -0
- package/src/scheduling/cancel.test.ts +348 -0
- package/src/scheduling/cancel.ts +209 -0
- package/src/scheduling/energy.ts +47 -0
- package/src/scheduling/idle-resolve.ts +45 -0
- package/src/scheduling/lane-core.ts +128 -0
- package/src/scheduling/lanes.test.ts +249 -0
- package/src/scheduling/lanes.ts +198 -0
- package/src/scheduling/projection.ts +209 -105
- package/src/scheduling/schedule.ts +241 -104
- package/src/scheduling/task-cargo.ts +46 -0
- package/src/shipload.ts +21 -1
- package/src/subscriptions/manager.ts +229 -142
- package/src/subscriptions/mappers.ts +5 -8
- package/src/subscriptions/types.ts +11 -3
- package/src/testing/catalog-hash.ts +19 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/projection-parity.ts +167 -0
- package/src/travel/reach.ts +23 -0
- package/src/travel/route-planner.ts +196 -0
- package/src/travel/travel.ts +200 -112
- package/src/types/capabilities.ts +29 -6
- package/src/types/entity.ts +3 -3
- package/src/types/index.ts +0 -1
- package/src/types.ts +28 -13
- package/src/utils/cargo.ts +27 -0
- package/src/utils/display-name.ts +70 -0
- package/src/utils/system.ts +36 -24
- package/src/capabilities/loading.ts +0 -8
- package/src/entities/container.ts +0 -108
- package/src/entities/ship-deploy.ts +0 -259
- package/src/entities/ship.ts +0 -204
- package/src/entities/warehouse.ts +0 -119
- package/src/types/entity-traits.ts +0 -69
package/src/entities/makers.ts
CHANGED
|
@@ -1,42 +1,57 @@
|
|
|
1
1
|
import {Name, UInt16, UInt32, UInt64, UInt8} from '@wharfkit/antelope'
|
|
2
|
+
import type {NameType, UInt64Type} from '@wharfkit/antelope'
|
|
2
3
|
import {ServerContract} from '../contracts'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import {ITEM_SHIP_T1_PACKED, ITEM_WAREHOUSE_T1_PACKED} from '../data/item-ids'
|
|
4
|
+
import {Entity} from './entity'
|
|
5
|
+
import {getKindMeta, getTemplateMeta} from '../data/kind-registry'
|
|
6
|
+
import type {EntityTypeName} from '../data/kind-registry'
|
|
7
7
|
import {getEntityLayout} from '../data/recipes-runtime'
|
|
8
|
+
import type {EntitySlot} from '../data/recipes-runtime'
|
|
8
9
|
import {itemMetadata} from '../data/metadata'
|
|
9
10
|
import {getItem} from '../data/catalog'
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
import {getModuleCapabilityType, moduleAccepts, moduleSlotTypeToCode} from '../capabilities/modules'
|
|
12
|
+
import {computeEntityCapabilities} from '../derivation/capabilities'
|
|
13
|
+
import {packedModulesToInstalled} from './slot-multiplier'
|
|
14
|
+
import {LANE_MOBILITY} from '../scheduling/schedule'
|
|
15
|
+
|
|
16
|
+
export interface PackedModuleInput {
|
|
17
|
+
itemId: number
|
|
18
|
+
stats: bigint
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface EntityStateInput {
|
|
22
|
+
id: UInt64Type
|
|
23
|
+
owner: NameType
|
|
24
|
+
name: string
|
|
25
|
+
coordinates: {x: number; y: number; z?: number}
|
|
26
|
+
itemId?: number
|
|
27
|
+
hullmass?: number
|
|
28
|
+
capacity?: number
|
|
29
|
+
cargomass?: number
|
|
30
|
+
energy?: number
|
|
31
|
+
modules?: PackedModuleInput[]
|
|
32
|
+
schedule?: ServerContract.Types.schedule
|
|
33
|
+
lanes?: ServerContract.Types.lane[]
|
|
34
|
+
cargo?: ServerContract.Types.cargo_item[]
|
|
35
|
+
}
|
|
18
36
|
|
|
19
37
|
function assignModulesToSlots(
|
|
20
|
-
|
|
38
|
+
slots: EntitySlot[],
|
|
21
39
|
modules: PackedModuleInput[],
|
|
22
40
|
entityLabel: string
|
|
23
41
|
): ServerContract.Types.module_entry[] {
|
|
24
|
-
const layout = getEntityLayout(packedEntityItemId)
|
|
25
|
-
const slots = layout?.slots ?? []
|
|
26
42
|
const result: Array<{type: number; installed?: ServerContract.Types.packed_module}> = slots.map(
|
|
27
43
|
(s) => ({type: moduleSlotTypeToCode(s.type), installed: undefined})
|
|
28
44
|
)
|
|
29
45
|
|
|
30
46
|
for (const mod of modules) {
|
|
31
|
-
const
|
|
32
|
-
const modType = getModuleCapabilityType(itemId)
|
|
47
|
+
const modType = getModuleCapabilityType(mod.itemId)
|
|
33
48
|
const slotIdx = result.findIndex((r) => !r.installed && moduleAccepts(r.type, modType))
|
|
34
49
|
if (slotIdx === -1) {
|
|
35
50
|
let modName: string
|
|
36
51
|
try {
|
|
37
|
-
modName = getItem(itemId).name
|
|
52
|
+
modName = getItem(mod.itemId).name
|
|
38
53
|
} catch {
|
|
39
|
-
modName = itemMetadata[itemId]?.name ?? `item ${itemId}`
|
|
54
|
+
modName = itemMetadata[mod.itemId]?.name ?? `item ${mod.itemId}`
|
|
40
55
|
}
|
|
41
56
|
throw new Error(
|
|
42
57
|
`No compatible slot for module ${modName} (type ${modType}) on ${entityLabel}`
|
|
@@ -56,141 +71,116 @@ function assignModulesToSlots(
|
|
|
56
71
|
)
|
|
57
72
|
}
|
|
58
73
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
74
|
+
const ZERO_HULL_STATS: Record<string, number> = {
|
|
75
|
+
density: 0,
|
|
76
|
+
strength: 0,
|
|
77
|
+
hardness: 0,
|
|
78
|
+
cohesion: 0,
|
|
64
79
|
}
|
|
65
80
|
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
let totalBonus = 0
|
|
71
|
-
for (const m of decoded) {
|
|
72
|
-
if (getModuleCapabilityType(m.itemId) !== MODULE_STORAGE) continue
|
|
73
|
-
const stats = decodeCraftedItemStats(m.itemId, m.stats)
|
|
74
|
-
const {capacityBonus} = computeStorageCapabilities(stats, baseCapacity)
|
|
75
|
-
totalBonus += capacityBonus
|
|
81
|
+
export function makeEntity(packedItemId: number, state: EntityStateInput): Entity {
|
|
82
|
+
const template = getTemplateMeta(packedItemId)
|
|
83
|
+
if (!template) {
|
|
84
|
+
throw new Error(`Unknown packed entity item ID: ${packedItemId}`)
|
|
76
85
|
}
|
|
77
|
-
return totalBonus
|
|
78
|
-
}
|
|
79
86
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
87
|
+
const kind = template.kind.toString() as EntityTypeName
|
|
88
|
+
const layout = getEntityLayout(packedItemId)?.slots ?? []
|
|
89
|
+
const mods = state.modules ?? []
|
|
90
|
+
|
|
91
|
+
const lanes =
|
|
92
|
+
state.lanes ??
|
|
93
|
+
(state.schedule
|
|
94
|
+
? [
|
|
95
|
+
ServerContract.Types.lane.from({
|
|
96
|
+
lane_key: UInt8.from(LANE_MOBILITY),
|
|
97
|
+
schedule: state.schedule,
|
|
98
|
+
}),
|
|
99
|
+
]
|
|
100
|
+
: [])
|
|
92
101
|
|
|
93
|
-
export function makeShip(state: ShipStateInput): Ship {
|
|
94
102
|
const info: Record<string, unknown> = {
|
|
95
|
-
type:
|
|
103
|
+
type: template.kind,
|
|
96
104
|
id: UInt64.from(state.id),
|
|
97
105
|
owner: Name.from(state.owner),
|
|
98
106
|
entity_name: state.name,
|
|
99
107
|
coordinates: ServerContract.Types.coordinates.from(state.coordinates),
|
|
100
|
-
|
|
108
|
+
item_id: UInt16.from(state.itemId ?? template.itemId),
|
|
109
|
+
cargomass: UInt32.from(state.cargomass ?? 0),
|
|
101
110
|
cargo: state.cargo || [],
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
current_task_remaining: UInt32.from(0),
|
|
105
|
-
pending_tasks: [],
|
|
111
|
+
lanes,
|
|
112
|
+
holds: [],
|
|
106
113
|
}
|
|
107
|
-
|
|
114
|
+
|
|
108
115
|
if (state.energy !== undefined) info.energy = UInt16.from(state.energy)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
moduleEntries = assignModulesToSlots(ITEM_SHIP_T1_PACKED, state.modules, 'Ship T1')
|
|
114
|
-
const {capabilities, finalCapacity} = deriveShipFromModules(
|
|
115
|
-
state.modules,
|
|
116
|
-
state.capacity ?? 0
|
|
117
|
-
)
|
|
118
|
-
if (capabilities.engines) info.engines = capabilities.engines
|
|
119
|
-
if (capabilities.generator) info.generator = capabilities.generator
|
|
120
|
-
if (capabilities.gatherer) info.gatherer = capabilities.gatherer
|
|
121
|
-
if (capabilities.hauler) info.hauler = capabilities.hauler
|
|
122
|
-
if (capabilities.loaders) info.loaders = capabilities.loaders
|
|
123
|
-
if (capabilities.crafter) info.crafter = capabilities.crafter
|
|
124
|
-
if (state.capacity !== undefined) info.capacity = UInt32.from(finalCapacity)
|
|
125
|
-
} else {
|
|
126
|
-
moduleEntries = assignModulesToSlots(ITEM_SHIP_T1_PACKED, [], 'Ship T1')
|
|
116
|
+
|
|
117
|
+
if (kind === 'container') {
|
|
118
|
+
info.modules = []
|
|
119
|
+
if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
|
|
127
120
|
if (state.capacity !== undefined) info.capacity = UInt32.from(state.capacity)
|
|
128
|
-
}
|
|
121
|
+
} else {
|
|
122
|
+
const entityLabel = getKindMeta(template.kind)?.defaultLabel ?? kind
|
|
123
|
+
const moduleEntries = assignModulesToSlots(layout, mods, entityLabel)
|
|
124
|
+
info.modules = moduleEntries
|
|
129
125
|
|
|
130
|
-
|
|
126
|
+
const installed = packedModulesToInstalled(moduleEntries)
|
|
127
|
+
const caps = computeEntityCapabilities(ZERO_HULL_STATS, packedItemId, installed, layout)
|
|
131
128
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
129
|
+
if (state.hullmass !== undefined) {
|
|
130
|
+
info.hullmass = UInt32.from(state.hullmass)
|
|
131
|
+
} else if (installed.length > 0) {
|
|
132
|
+
info.hullmass = UInt32.from(caps.hullmass)
|
|
133
|
+
}
|
|
135
134
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
entity_name: state.name,
|
|
142
|
-
coordinates: ServerContract.Types.coordinates.from(state.coordinates),
|
|
143
|
-
capacity: UInt32.from(state.capacity),
|
|
144
|
-
cargomass: UInt32.from(0),
|
|
145
|
-
cargo: state.cargo || [],
|
|
146
|
-
is_idle: !state.schedule,
|
|
147
|
-
current_task_elapsed: UInt32.from(0),
|
|
148
|
-
current_task_remaining: UInt32.from(0),
|
|
149
|
-
pending_tasks: [],
|
|
150
|
-
}
|
|
151
|
-
if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
|
|
152
|
-
if (state.schedule) info.schedule = state.schedule
|
|
153
|
-
|
|
154
|
-
let moduleEntries: ServerContract.Types.module_entry[] = []
|
|
155
|
-
if (state.modules && state.modules.length > 0) {
|
|
156
|
-
moduleEntries = assignModulesToSlots(
|
|
157
|
-
ITEM_WAREHOUSE_T1_PACKED,
|
|
158
|
-
state.modules,
|
|
159
|
-
'Warehouse T1'
|
|
160
|
-
)
|
|
161
|
-
const decoded = state.modules.map(decodePackedInput)
|
|
162
|
-
const capabilities = computeWarehouseCapabilities(decoded)
|
|
163
|
-
if (capabilities.loaders) info.loaders = capabilities.loaders
|
|
135
|
+
if (state.capacity !== undefined) {
|
|
136
|
+
info.capacity = UInt32.from(state.capacity)
|
|
137
|
+
} else {
|
|
138
|
+
info.capacity = UInt32.from(caps.capacity)
|
|
139
|
+
}
|
|
164
140
|
|
|
165
|
-
|
|
166
|
-
info.
|
|
167
|
-
|
|
168
|
-
|
|
141
|
+
if (caps.engines) info.engines = caps.engines
|
|
142
|
+
if (caps.generator) info.generator = caps.generator
|
|
143
|
+
if (caps.hauler) info.hauler = caps.hauler
|
|
144
|
+
if (caps.warp) info.warp = caps.warp
|
|
145
|
+
if (caps.launcher) {
|
|
146
|
+
info.launcher = ServerContract.Types.launcher_stats.from({
|
|
147
|
+
charge_rate: caps.launcher.chargeRate,
|
|
148
|
+
velocity: caps.launcher.velocity,
|
|
149
|
+
drain: caps.launcher.drain,
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
info.gatherer_lanes = (caps.gathererLanes ?? []).map((l) =>
|
|
154
|
+
ServerContract.Types.gatherer_lane.from({
|
|
155
|
+
slot_index: l.slotIndex,
|
|
156
|
+
yield: l.yield,
|
|
157
|
+
drain: l.drain,
|
|
158
|
+
depth: l.depth,
|
|
159
|
+
output_pct: l.outputPct,
|
|
160
|
+
})
|
|
161
|
+
)
|
|
162
|
+
info.crafter_lanes = (caps.crafterLanes ?? []).map((l) =>
|
|
163
|
+
ServerContract.Types.crafter_lane.from({
|
|
164
|
+
slot_index: l.slotIndex,
|
|
165
|
+
speed: l.speed,
|
|
166
|
+
drain: l.drain,
|
|
167
|
+
output_pct: l.outputPct,
|
|
168
|
+
})
|
|
169
|
+
)
|
|
170
|
+
info.loader_lanes = (caps.loaderLanes ?? []).map((l) =>
|
|
171
|
+
ServerContract.Types.loader_lane.from({
|
|
172
|
+
slot_index: l.slotIndex,
|
|
173
|
+
mass: l.mass,
|
|
174
|
+
thrust: l.thrust,
|
|
175
|
+
output_pct: l.outputPct,
|
|
176
|
+
})
|
|
177
|
+
)
|
|
169
178
|
}
|
|
170
179
|
|
|
171
|
-
info.
|
|
180
|
+
if (!info.gatherer_lanes) info.gatherer_lanes = []
|
|
181
|
+
if (!info.crafter_lanes) info.crafter_lanes = []
|
|
182
|
+
if (!info.loader_lanes) info.loader_lanes = []
|
|
172
183
|
|
|
173
184
|
const entityInfo = ServerContract.Types.entity_info.from(info)
|
|
174
|
-
return new
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export function makeContainer(state: ContainerStateInput): Container {
|
|
178
|
-
const entityInfo = ServerContract.Types.entity_info.from({
|
|
179
|
-
type: Name.from('container'),
|
|
180
|
-
id: UInt64.from(state.id),
|
|
181
|
-
owner: Name.from(state.owner),
|
|
182
|
-
entity_name: state.name,
|
|
183
|
-
coordinates: ServerContract.Types.coordinates.from(state.coordinates),
|
|
184
|
-
hullmass: UInt32.from(state.hullmass),
|
|
185
|
-
capacity: UInt32.from(state.capacity),
|
|
186
|
-
cargomass: UInt32.from(state.cargomass || 0),
|
|
187
|
-
cargo: state.cargo || [],
|
|
188
|
-
modules: [],
|
|
189
|
-
is_idle: !state.schedule,
|
|
190
|
-
current_task_elapsed: UInt32.from(0),
|
|
191
|
-
current_task_remaining: UInt32.from(0),
|
|
192
|
-
pending_tasks: [],
|
|
193
|
-
schedule: state.schedule,
|
|
194
|
-
})
|
|
195
|
-
return new Container(entityInfo)
|
|
185
|
+
return new Entity(entityInfo)
|
|
196
186
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type {EntitySlot} from '../data/recipes-runtime'
|
|
2
|
+
import type {ServerContract} from '../contracts'
|
|
3
|
+
|
|
4
|
+
export const U16_MAX = 65535
|
|
5
|
+
|
|
6
|
+
export interface InstalledModule {
|
|
7
|
+
slotIndex: number
|
|
8
|
+
itemId: number
|
|
9
|
+
stats: bigint
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function packedModulesToInstalled(
|
|
13
|
+
entries: ServerContract.Types.module_entry[]
|
|
14
|
+
): InstalledModule[] {
|
|
15
|
+
const installed: InstalledModule[] = []
|
|
16
|
+
entries.forEach((entry, slotIndex) => {
|
|
17
|
+
if (!entry.installed) return
|
|
18
|
+
installed.push({
|
|
19
|
+
slotIndex,
|
|
20
|
+
itemId: Number(entry.installed.item_id.value),
|
|
21
|
+
stats: BigInt(entry.installed.stats.toString()),
|
|
22
|
+
})
|
|
23
|
+
})
|
|
24
|
+
return installed
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function clampUint16(value: number): number {
|
|
28
|
+
return Math.min(value, U16_MAX)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const clampUint32 = (v: number): number => Math.min(Math.max(Math.floor(v), 0), 4294967295)
|
|
32
|
+
|
|
33
|
+
export function applySlotMultiplier(value: number, outputPct: number): number {
|
|
34
|
+
return clampUint16(Math.floor((value * outputPct) / 100))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function applySlotMultiplierUint32(value: number, outputPct: number): number {
|
|
38
|
+
return clampUint32(Math.floor((value * outputPct) / 100))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function getSlotAmp(layout: EntitySlot[], slotIndex: number): number {
|
|
42
|
+
return layout[slotIndex]?.outputPct ?? 100
|
|
43
|
+
}
|
package/src/errors.ts
CHANGED
|
@@ -16,20 +16,18 @@ export const REQUIRES_POSITIVE_VALUE = 'Value must be greater than zero.'
|
|
|
16
16
|
export const PLAYER_ALREADY_JOINED = 'Player has already joined the game.'
|
|
17
17
|
export const PLAYER_NOT_JOINED = 'Player has not joined the game.'
|
|
18
18
|
export const PLAYER_NOT_FOUND = 'Cannot find player for given account name.'
|
|
19
|
-
export const
|
|
20
|
-
'Starter ship already claimed; destroy existing ships to re-claim.'
|
|
21
|
-
export const SHIP_ALREADY_THERE = 'Ship cannot travel to the location its already at.'
|
|
19
|
+
export const ENTITY_ALREADY_THERE = 'Entity cannot travel to the location it is already at.'
|
|
22
20
|
export const SHIP_ALREADY_TRAVELING = 'Ship is already traveling.'
|
|
23
21
|
export const SHIP_CANNOT_BUY_TRAVELING = 'Ship cannot buy goods while traveling.'
|
|
24
22
|
export const SHIP_CANNOT_UPDATE_TRAVELING = 'Ship cannot be updated while traveling.'
|
|
25
|
-
export const
|
|
26
|
-
export const
|
|
23
|
+
export const ENTITY_INVALID_DESTINATION = 'Cannot travel: no system at specified destination.'
|
|
24
|
+
export const ENTITY_INVALID_TRAVEL_DURATION =
|
|
27
25
|
'This trip cannot be made as it would exceed the maximum travel duration.'
|
|
28
26
|
export const SHIP_NOT_ARRIVED = 'Ship has not yet arrived at its destination.'
|
|
29
|
-
export const
|
|
30
|
-
'
|
|
31
|
-
export const
|
|
32
|
-
'
|
|
27
|
+
export const ENTITY_NOT_ENOUGH_ENERGY =
|
|
28
|
+
'Entity does not have enough energy to travel to the destination.'
|
|
29
|
+
export const ENTITY_NOT_ENOUGH_ENERGY_CAPACITY =
|
|
30
|
+
'Entity does not have enough energy capacity to travel.'
|
|
33
31
|
export const SHIP_NOT_FOUND = 'Cannot find ship for given account.'
|
|
34
32
|
export const SHIP_NOT_OWNED = 'Ship is not owned by this account.'
|
|
35
33
|
export const NO_SCHEDULE = 'No scheduled tasks.'
|
|
@@ -38,19 +36,15 @@ export const SHIP_NO_COMPLETED_TASKS = 'No completed tasks to resolve.'
|
|
|
38
36
|
export const RESOLVE_COUNT_EXCEEDS_COMPLETED = 'Requested resolve count exceeds completed tasks.'
|
|
39
37
|
export const SHIP_CANNOT_CANCEL_TASK = 'Cannot cancel task that is immutable or in progress.'
|
|
40
38
|
export const SHIP_NO_TASKS_TO_CANCEL = 'No tasks to cancel.'
|
|
41
|
-
export const
|
|
42
|
-
export const
|
|
43
|
-
export const
|
|
44
|
-
export const SHIP_CAPACITY_EXCEEDED = 'Ship cargo capacity would be exceeded.'
|
|
39
|
+
export const ENTITY_INVALID_CARGO = 'Invalid cargo specified for load/unload.'
|
|
40
|
+
export const ENTITY_CARGO_NOT_OWNED = 'Cannot load cargo that is not owned.'
|
|
41
|
+
export const ENTITY_CARGO_NOT_LOADED = 'Cannot unload cargo that is not loaded.'
|
|
45
42
|
export const ENTITY_CAPACITY_EXCEEDED = 'Entity cargo capacity would be exceeded.'
|
|
46
43
|
export const WAREHOUSE_NOT_FOUND = 'Cannot find warehouse for given id.'
|
|
47
44
|
export const WAREHOUSE_ALREADY_AT_LOCATION = 'Warehouse already exists at this location.'
|
|
48
|
-
export const WAREHOUSE_CAPACITY_EXCEEDED = 'Warehouse capacity would be exceeded.'
|
|
49
45
|
export const CONTAINER_NOT_FOUND = 'Cannot find container for given id.'
|
|
50
|
-
export const CONTAINER_CAPACITY_EXCEEDED = 'Container capacity would be exceeded.'
|
|
51
46
|
export const DESTINATION_CAPACITY_EXCEEDED =
|
|
52
47
|
'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
48
|
export const GROUP_EMPTY = 'Group travel requires at least one entity.'
|
|
55
49
|
export const GROUP_NO_THRUST = 'Group travel requires at least one entity with engines.'
|
|
56
50
|
export const GROUP_NOT_SAME_LOCATION = 'All entities must be at the same location for group travel.'
|
|
@@ -62,6 +56,8 @@ export const GROUP_HAUL_CAPACITY_EXCEEDED =
|
|
|
62
56
|
'Group travel requires sufficient hauler capacity for all non-self-propelled entities.'
|
|
63
57
|
export const CANCEL_CONTAINS_GROUPED_TASK =
|
|
64
58
|
'Cannot cancel range containing grouped task - cancel non-grouped tasks first.'
|
|
59
|
+
export const WOULD_STRAND = 'Cancelling this would leave a later task without the cargo it needs.'
|
|
60
|
+
export const WOULD_OVERFILL = 'Cancelling this would overfill the other entity with returned cargo.'
|
|
65
61
|
export const WARP_NO_CAPABILITY = 'Entity does not have warp capability.'
|
|
66
62
|
export const WARP_HAS_SCHEDULE = 'Entity must be idle to warp.'
|
|
67
63
|
export const WARP_HAS_CARGO = 'Entity must have no cargo to warp.'
|
package/src/format.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
export function formatMass(kg: number): string {
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
2
|
+
if (kg === 0) return '0 t'
|
|
3
|
+
const sign = kg < 0 ? '-' : ''
|
|
4
|
+
const centitonnes = Math.round(Math.abs(kg) / 10)
|
|
5
|
+
const t = Math.floor(centitonnes / 100)
|
|
6
|
+
const frac = centitonnes % 100
|
|
7
|
+
if (frac === 0) return `${sign}${t} t`
|
|
8
|
+
const fracStr = String(frac).padStart(2, '0').replace(/0$/, '')
|
|
9
|
+
return `${sign}${t}.${fracStr} t`
|
|
6
10
|
}
|
|
7
11
|
|
|
8
12
|
export function formatMassDelta(kg: number): string {
|
|
@@ -10,3 +14,21 @@ export function formatMassDelta(kg: number): string {
|
|
|
10
14
|
const sign = kg > 0 ? '+' : '-'
|
|
11
15
|
return `${sign}${formatMass(Math.abs(kg))}`
|
|
12
16
|
}
|
|
17
|
+
|
|
18
|
+
export function formatLocation(loc: {x: number; y: number}): string {
|
|
19
|
+
return `${loc.x}, ${loc.y}`
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function trim(n: number, digits = 1): string {
|
|
23
|
+
return n.toFixed(digits).replace(/\.?0+$/, '')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function formatMassScaled(kg: number): string {
|
|
27
|
+
if (kg === 0) return '0 t'
|
|
28
|
+
const sign = kg < 0 ? '-' : ''
|
|
29
|
+
const tonnes = Math.abs(kg) / 1000
|
|
30
|
+
if (tonnes >= 1_000_000_000) return `${sign}${trim(tonnes / 1_000_000_000)}b t`
|
|
31
|
+
if (tonnes >= 1_000_000) return `${sign}${trim(tonnes / 1_000_000)}m t`
|
|
32
|
+
if (tonnes >= 1_000) return `${sign}${trim(tonnes / 1_000)}k t`
|
|
33
|
+
return formatMass(kg)
|
|
34
|
+
}
|