@shipload/sdk 1.0.0-next.3 → 1.0.0-next.31
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 +1849 -961
- package/lib/shipload.js +9089 -4854
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +8958 -4805
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +856 -0
- package/lib/testing.js +3739 -0
- package/lib/testing.js.map +1 -0
- package/lib/testing.m.js +3733 -0
- package/lib/testing.m.js.map +1 -0
- package/package.json +15 -2
- package/src/capabilities/craftable.ts +51 -0
- package/src/capabilities/crafting.test.ts +7 -0
- package/src/capabilities/crafting.ts +3 -3
- package/src/capabilities/gathering.ts +17 -7
- package/src/capabilities/index.ts +0 -1
- package/src/capabilities/modules.ts +6 -0
- package/src/capabilities/storage.ts +16 -1
- package/src/contracts/platform.ts +231 -3
- package/src/contracts/server.ts +816 -471
- package/src/data/capabilities.ts +14 -329
- package/src/data/capability-formulas.ts +76 -0
- package/src/data/catalog.ts +0 -5
- package/src/data/colors.ts +14 -47
- package/src/data/entities.json +46 -10
- package/src/data/item-ids.ts +15 -12
- package/src/data/items.json +302 -38
- package/src/data/kind-registry.json +85 -0
- package/src/data/kind-registry.ts +150 -0
- package/src/data/metadata.ts +100 -31
- package/src/data/recipes-runtime.ts +3 -23
- package/src/data/recipes.json +250 -113
- package/src/derivation/build-methods.ts +45 -0
- package/src/derivation/capabilities.ts +415 -0
- package/src/derivation/capability-mappings.ts +117 -0
- package/src/derivation/crafting.ts +23 -24
- package/src/derivation/index.ts +17 -2
- package/src/derivation/reserve-regen.ts +34 -0
- package/src/derivation/resources.ts +125 -38
- 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 +15 -19
- package/src/derivation/tiers.ts +28 -7
- package/src/entities/entity.ts +98 -0
- package/src/entities/gamestate.ts +3 -28
- package/src/entities/makers.ts +91 -136
- package/src/entities/slot-multiplier.ts +39 -0
- package/src/errors.ts +10 -15
- package/src/format.ts +26 -4
- package/src/index-module.ts +189 -47
- package/src/managers/actions.ts +252 -83
- package/src/managers/base.ts +6 -2
- package/src/managers/construction-types.ts +79 -0
- package/src/managers/construction.ts +396 -0
- package/src/managers/context.ts +11 -1
- 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.ts +28 -0
- package/src/managers/plot.ts +127 -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 +321 -0
- package/src/nft/description.ts +37 -15
- package/src/nft/index.ts +3 -0
- package/src/resolution/describe-module.ts +5 -8
- package/src/resolution/display-name.ts +38 -10
- package/src/resolution/resolve-item.ts +22 -20
- package/src/scheduling/accessor.ts +68 -22
- package/src/scheduling/availability.ts +108 -0
- package/src/scheduling/energy.ts +48 -0
- package/src/scheduling/lane-core.ts +130 -0
- package/src/scheduling/lanes.ts +60 -0
- package/src/scheduling/projection.ts +121 -94
- package/src/scheduling/schedule.ts +237 -103
- package/src/scheduling/task-cargo.ts +46 -0
- package/src/shipload.ts +16 -1
- package/src/subscriptions/manager.ts +40 -6
- package/src/subscriptions/mappers.ts +3 -8
- package/src/subscriptions/types.ts +3 -2
- package/src/testing/catalog-hash.ts +19 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/projection-parity.ts +143 -0
- package/src/travel/travel.ts +90 -13
- package/src/types/capabilities.ts +1 -0
- package/src/types/index.ts +0 -1
- package/src/types.ts +19 -12
- package/src/utils/cargo.ts +27 -0
- package/src/utils/display-name.ts +70 -0
- package/src/utils/system.ts +25 -24
- package/src/capabilities/loading.ts +0 -8
- package/src/entities/container.ts +0 -108
- package/src/entities/ship-deploy.ts +0 -258
- 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,81 @@ 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
|
-
current_task_elapsed: UInt32.from(0),
|
|
104
|
-
current_task_remaining: UInt32.from(0),
|
|
105
|
-
pending_tasks: [],
|
|
111
|
+
lanes,
|
|
106
112
|
}
|
|
107
|
-
|
|
113
|
+
|
|
108
114
|
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')
|
|
115
|
+
|
|
116
|
+
if (kind === 'container') {
|
|
117
|
+
info.modules = []
|
|
118
|
+
if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
|
|
127
119
|
if (state.capacity !== undefined) info.capacity = UInt32.from(state.capacity)
|
|
128
|
-
}
|
|
120
|
+
} else {
|
|
121
|
+
const entityLabel = getKindMeta(template.kind)?.defaultLabel ?? kind
|
|
122
|
+
const moduleEntries = assignModulesToSlots(layout, mods, entityLabel)
|
|
123
|
+
info.modules = moduleEntries
|
|
129
124
|
|
|
130
|
-
|
|
125
|
+
const installed = packedModulesToInstalled(moduleEntries)
|
|
126
|
+
const caps = computeEntityCapabilities(ZERO_HULL_STATS, packedItemId, installed, layout)
|
|
131
127
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
128
|
+
if (state.hullmass !== undefined) {
|
|
129
|
+
info.hullmass = UInt32.from(state.hullmass)
|
|
130
|
+
} else if (installed.length > 0) {
|
|
131
|
+
info.hullmass = UInt32.from(caps.hullmass)
|
|
132
|
+
}
|
|
135
133
|
|
|
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
|
|
164
|
-
|
|
165
|
-
const totalBonus = computeStorageBonus(decoded, state.capacity)
|
|
166
|
-
info.capacity = UInt32.from(state.capacity + totalBonus)
|
|
167
|
-
} else {
|
|
168
|
-
moduleEntries = assignModulesToSlots(ITEM_WAREHOUSE_T1_PACKED, [], 'Warehouse T1')
|
|
169
|
-
}
|
|
134
|
+
if (state.capacity !== undefined) {
|
|
135
|
+
info.capacity = UInt32.from(state.capacity)
|
|
136
|
+
} else {
|
|
137
|
+
info.capacity = UInt32.from(caps.capacity)
|
|
138
|
+
}
|
|
170
139
|
|
|
171
|
-
|
|
140
|
+
if (caps.engines) info.engines = caps.engines
|
|
141
|
+
if (caps.generator) info.generator = caps.generator
|
|
142
|
+
if (caps.gatherer) info.gatherer = caps.gatherer
|
|
143
|
+
if (caps.loaders) info.loaders = caps.loaders
|
|
144
|
+
if (caps.crafter) info.crafter = caps.crafter
|
|
145
|
+
if (caps.hauler) info.hauler = caps.hauler
|
|
146
|
+
if (caps.warp) info.warp = caps.warp
|
|
147
|
+
}
|
|
172
148
|
|
|
173
149
|
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)
|
|
150
|
+
return new Entity(entityInfo)
|
|
196
151
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
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 getSlotAmp(layout: EntitySlot[], slotIndex: number): number {
|
|
38
|
+
return layout[slotIndex]?.outputPct ?? 100
|
|
39
|
+
}
|
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,16 +36,13 @@ 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
48
|
export const CANCEL_PAIRED_HAS_PENDING = 'Cannot cancel transfer, paired entity has pending tasks.'
|
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
|
+
}
|