@shipload/sdk 1.0.0-next.7 → 1.0.0-next.70
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 +52 -0
- package/lib/scan.js +162 -0
- package/lib/scan.js.map +1 -0
- package/lib/scan.m.js +152 -0
- package/lib/scan.m.js.map +1 -0
- package/lib/shipload.d.ts +5696 -1503
- package/lib/shipload.js +20294 -5200
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +20371 -5683
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +1648 -0
- package/lib/testing.js +6980 -0
- package/lib/testing.js.map +1 -0
- package/lib/testing.m.js +6974 -0
- package/lib/testing.m.js.map +1 -0
- package/package.json +20 -2
- package/src/capabilities/craftable.test.ts +82 -0
- package/src/capabilities/craftable.ts +82 -0
- package/src/capabilities/crafting.test.ts +80 -0
- package/src/capabilities/crafting.ts +50 -8
- package/src/capabilities/gathering.test.ts +29 -0
- package/src/capabilities/gathering.ts +38 -20
- package/src/capabilities/hauling.ts +0 -5
- package/src/capabilities/index.ts +0 -1
- package/src/capabilities/modules.ts +27 -30
- package/src/capabilities/movement.ts +1 -1
- package/src/capabilities/storage.test.ts +26 -0
- package/src/capabilities/storage.ts +22 -7
- package/src/contracts/fund.ts +306 -0
- package/src/contracts/platform.ts +312 -3
- package/src/contracts/server.ts +2661 -466
- package/src/contracts/token.ts +170 -0
- package/src/contracts.ts +2 -0
- 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 +49 -18
- package/src/data/capability-formulas.ts +26 -14
- package/src/data/catalog.test.ts +19 -0
- package/src/data/catalog.ts +13 -3
- package/src/data/charters.json +396 -0
- package/src/data/citizenry-adjectives.json +42 -0
- package/src/data/citizenry-nouns.json +50 -0
- package/src/data/colors.ts +14 -32
- package/src/data/entities.json +421 -15
- package/src/data/item-ids.ts +53 -13
- package/src/data/items.json +330 -77
- package/src/data/kind-registry.json +212 -0
- package/src/data/kind-registry.ts +192 -0
- package/src/data/metadata.ts +312 -51
- package/src/data/recipes-runtime.ts +6 -23
- package/src/data/recipes.json +2173 -173
- package/src/data/tiers.ts +9 -6
- package/src/derivation/build-methods.test.ts +71 -0
- package/src/derivation/build-methods.ts +50 -0
- package/src/derivation/capabilities.test.ts +348 -0
- package/src/derivation/capabilities.ts +707 -0
- package/src/derivation/capability-mappings.ts +60 -16
- package/src/derivation/crafting.test.ts +17 -0
- package/src/derivation/crafting.ts +57 -34
- package/src/derivation/index.ts +27 -2
- package/src/derivation/recipe-usage.test.ts +88 -0
- package/src/derivation/recipe-usage.ts +141 -0
- package/src/derivation/reserve-regen.ts +34 -0
- package/src/derivation/resources.ts +9 -1
- package/src/derivation/rollups.test.ts +55 -0
- package/src/derivation/rollups.ts +72 -0
- package/src/derivation/stars.test.ts +67 -0
- package/src/derivation/stars.ts +25 -0
- package/src/derivation/stat-scaling.ts +12 -0
- package/src/derivation/stats.ts +6 -6
- package/src/derivation/strata.ts +5 -3
- package/src/derivation/stratum.ts +26 -22
- package/src/derivation/tiers.ts +40 -7
- package/src/derivation/upgrades.ts +14 -0
- package/src/derivation/wormhole.ts +154 -0
- package/src/entities/entity.ts +102 -0
- package/src/entities/gamestate.ts +3 -28
- package/src/entities/makers.ts +144 -136
- package/src/entities/slot-multiplier.ts +43 -0
- package/src/entity/hydrate.test.ts +156 -0
- package/src/entity/hydrate.ts +86 -0
- package/src/errors.ts +21 -16
- package/src/format.ts +42 -9
- package/src/index-module.ts +411 -32
- package/src/influence/ballot.test.ts +103 -0
- package/src/influence/ballot.ts +98 -0
- package/src/influence/categories.ts +32 -0
- package/src/influence/charter-metadata.test.ts +136 -0
- package/src/influence/charter-metadata.ts +236 -0
- package/src/influence/charters.test.ts +112 -0
- package/src/influence/charters.ts +150 -0
- package/src/influence/citizenry.ts +38 -0
- package/src/influence/civic-shuttle.test.ts +202 -0
- package/src/influence/civic-shuttle.ts +142 -0
- package/src/influence/civic.test.ts +287 -0
- package/src/influence/civic.ts +269 -0
- package/src/influence/constants.ts +84 -0
- package/src/influence/decay.ts +20 -0
- package/src/influence/decomp.ts +95 -0
- package/src/influence/demand.ts +106 -0
- package/src/influence/duration.ts +101 -0
- package/src/influence/index.ts +118 -0
- package/src/influence/influence.test.ts +450 -0
- package/src/influence/quality.ts +25 -0
- package/src/influence/valuation.ts +154 -0
- package/src/managers/actions.ts +940 -93
- package/src/managers/balances.test.ts +161 -0
- package/src/managers/balances.ts +93 -0
- package/src/managers/base.ts +10 -2
- package/src/managers/cluster.test.ts +39 -0
- package/src/managers/cluster.ts +53 -0
- package/src/managers/construction-types.ts +80 -0
- package/src/managers/construction.ts +453 -0
- package/src/managers/context.ts +58 -1
- package/src/managers/coordinates.ts +14 -0
- package/src/managers/entities.ts +35 -63
- package/src/managers/epochs.ts +72 -1
- package/src/managers/index.ts +38 -1
- package/src/managers/influence.test.ts +56 -0
- package/src/managers/influence.ts +425 -0
- package/src/managers/jobs.test.ts +80 -0
- package/src/managers/jobs.ts +54 -0
- package/src/managers/locations.ts +25 -29
- package/src/managers/nft.test.ts +21 -0
- package/src/managers/nft.ts +110 -0
- package/src/managers/players.ts +25 -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 +388 -0
- package/src/nft/description.ts +222 -100
- package/src/nft/index.ts +3 -0
- package/src/planner/index.ts +296 -0
- package/src/planner/planner.test.ts +459 -0
- package/src/receipts.ts +22 -0
- package/src/resolution/describe-module.ts +43 -25
- package/src/resolution/display-name.ts +39 -11
- package/src/resolution/resolve-item.test.ts +48 -0
- package/src/resolution/resolve-item.ts +112 -58
- package/src/scan/index.ts +244 -0
- package/src/scan/scan-wasm.base64.ts +2 -0
- package/src/scheduling/accessor.ts +65 -23
- package/src/scheduling/availability.test.ts +320 -0
- package/src/scheduling/availability.ts +251 -0
- package/src/scheduling/cancel.test.ts +550 -0
- package/src/scheduling/cancel.ts +254 -0
- package/src/scheduling/cluster-stock.test.ts +31 -0
- package/src/scheduling/cluster-stock.ts +15 -0
- package/src/scheduling/energy.ts +47 -0
- package/src/scheduling/epoch.ts +1 -0
- package/src/scheduling/idle-resolve.ts +45 -0
- package/src/scheduling/jobs.test.ts +49 -0
- package/src/scheduling/jobs.ts +137 -0
- package/src/scheduling/lane-core.ts +128 -0
- package/src/scheduling/lanes.test.ts +250 -0
- package/src/scheduling/lanes.ts +227 -0
- package/src/scheduling/projection.ts +265 -149
- package/src/scheduling/schedule.test.ts +163 -0
- package/src/scheduling/schedule.ts +282 -116
- package/src/scheduling/task-cargo.test.ts +110 -0
- package/src/scheduling/task-cargo.ts +62 -0
- package/src/scheduling/task-effects.test.ts +35 -0
- package/src/scheduling/task-effects.ts +34 -0
- package/src/scheduling/unwrap.test.ts +86 -0
- package/src/scheduling/unwrap.ts +190 -0
- package/src/shipload.ts +63 -4
- package/src/subscriptions/manager.cluster.test.ts +51 -0
- package/src/subscriptions/manager.ts +245 -172
- package/src/subscriptions/mappers.ts +5 -8
- package/src/subscriptions/types.ts +28 -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.test.ts +86 -0
- package/src/travel/reach.ts +34 -0
- package/src/travel/route-build.test.ts +63 -0
- package/src/travel/route-build.ts +60 -0
- package/src/travel/route-planner.ts +288 -0
- package/src/travel/route-simulator.ts +170 -0
- package/src/travel/travel.ts +190 -123
- package/src/types/capabilities.ts +37 -8
- package/src/types/entity.ts +3 -3
- package/src/types/index.ts +0 -1
- package/src/types.ts +81 -23
- package/src/utils/cargo.test.ts +14 -0
- package/src/utils/cargo.ts +2 -0
- package/src/utils/display-name.ts +70 -0
- package/src/utils/hash.ts +22 -2
- package/src/utils/system.ts +24 -5
- package/src/capabilities/loading.ts +0 -8
- package/src/entities/container.ts +0 -123
- package/src/entities/ship-deploy.ts +0 -295
- package/src/entities/ship.ts +0 -221
- package/src/entities/warehouse.ts +0 -127
- package/src/types/entity-traits.ts +0 -69
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {Name, TimePoint, UInt16, UInt32, UInt64} from '@wharfkit/antelope'
|
|
1
|
+
import {Name, type TimePoint, type UInt16, UInt32, UInt64} from '@wharfkit/antelope'
|
|
2
2
|
import {ServerContract} from '../contracts'
|
|
3
|
-
import {Coordinates,
|
|
3
|
+
import {Coordinates, TaskType} from '../types'
|
|
4
4
|
import {
|
|
5
|
-
capsHasLoaders,
|
|
6
5
|
capsHasMovement,
|
|
7
6
|
capsHasStorage,
|
|
8
7
|
type EntityCapabilities,
|
|
@@ -14,38 +13,48 @@ import {
|
|
|
14
13
|
RECIPE_INPUTS_INSUFFICIENT,
|
|
15
14
|
RECIPE_INPUTS_INVALID,
|
|
16
15
|
RECIPE_NOT_FOUND,
|
|
17
|
-
|
|
16
|
+
ENTITY_CARGO_NOT_LOADED,
|
|
18
17
|
} from '../errors'
|
|
19
|
-
import {getRecipe, type RecipeInput} from '../data/recipes-runtime'
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
18
|
+
import {getEntityLayout, getRecipe, type RecipeInput} from '../data/recipes-runtime'
|
|
19
|
+
import {ITEM_SHIP_T1_PACKED} from '../data/item-ids'
|
|
20
|
+
import {computeEntityCapabilities} from '../derivation/capabilities'
|
|
21
|
+
import {decodeCraftedItemStats, decodeStat} from '../derivation/crafting'
|
|
22
|
+
import {packedModulesToInstalled, type InstalledModule} from '../entities/slot-multiplier'
|
|
23
|
+
import {lerp} from '../travel/travel'
|
|
22
24
|
import {
|
|
23
25
|
calcStacksMass,
|
|
24
26
|
cargoItemToStack,
|
|
25
27
|
type CargoStack,
|
|
26
28
|
mergeStacks,
|
|
27
|
-
|
|
29
|
+
subtractFromStacks,
|
|
28
30
|
stackToCargoItem,
|
|
29
31
|
} from '../capabilities/storage'
|
|
32
|
+
import {hydrateEntityLanes} from '../entity/hydrate'
|
|
33
|
+
import {craftCargoOwnership} from './availability'
|
|
30
34
|
import * as schedule from './schedule'
|
|
31
35
|
import type {ScheduleData} from './schedule'
|
|
32
36
|
|
|
33
37
|
export interface ProjectedEntity {
|
|
34
38
|
location: Coordinates
|
|
35
|
-
energy:
|
|
39
|
+
energy: UInt32
|
|
36
40
|
cargo: CargoStack[]
|
|
37
41
|
shipMass: UInt32
|
|
38
42
|
capacity?: UInt64
|
|
39
43
|
engines?: ServerContract.Types.movement_stats
|
|
40
|
-
|
|
44
|
+
loaderLanes: ServerContract.Types.loader_lane[]
|
|
41
45
|
generator?: ServerContract.Types.energy_stats
|
|
42
46
|
hauler?: ServerContract.Types.hauler_stats
|
|
47
|
+
launcher?: ServerContract.Types.launcher_stats
|
|
43
48
|
readonly cargoMass: UInt64
|
|
44
49
|
readonly totalMass: UInt64
|
|
50
|
+
readonly gathererLanes: ServerContract.Types.gatherer_lane[]
|
|
51
|
+
readonly crafterLanes: ServerContract.Types.crafter_lane[]
|
|
52
|
+
readonly builderLanes: ServerContract.Types.builder_lane[]
|
|
45
53
|
|
|
46
54
|
hasMovement(): boolean
|
|
47
55
|
hasStorage(): boolean
|
|
48
56
|
hasLoaders(): boolean
|
|
57
|
+
hasLauncher(): boolean
|
|
49
58
|
|
|
50
59
|
capabilities(): EntityCapabilities
|
|
51
60
|
state(): EntityState
|
|
@@ -53,53 +62,196 @@ export interface ProjectedEntity {
|
|
|
53
62
|
|
|
54
63
|
export interface Projectable extends ScheduleData {
|
|
55
64
|
coordinates: Coordinates | ServerContract.Types.coordinates
|
|
56
|
-
energy?:
|
|
65
|
+
energy?: UInt32
|
|
57
66
|
hullmass?: UInt32
|
|
58
67
|
generator?: ServerContract.Types.energy_stats
|
|
59
68
|
engines?: ServerContract.Types.movement_stats
|
|
60
|
-
|
|
69
|
+
loader_lanes?: ServerContract.Types.loader_lane[]
|
|
70
|
+
gatherer_lanes?: ServerContract.Types.gatherer_lane[]
|
|
71
|
+
crafter_lanes?: ServerContract.Types.crafter_lane[]
|
|
72
|
+
builder_lanes?: ServerContract.Types.builder_lane[]
|
|
61
73
|
hauler?: ServerContract.Types.hauler_stats
|
|
74
|
+
launcher?: ServerContract.Types.launcher_stats
|
|
62
75
|
capacity?: UInt32
|
|
63
76
|
cargo: ServerContract.Types.cargo_item[]
|
|
64
77
|
cargomass: UInt32
|
|
78
|
+
projected_at?: TimePoint
|
|
65
79
|
owner?: Name
|
|
80
|
+
stats?: bigint
|
|
81
|
+
item_id?: number | UInt16
|
|
82
|
+
modules?: ServerContract.Types.module_entry[] | InstalledModule[]
|
|
66
83
|
}
|
|
67
84
|
|
|
68
|
-
function
|
|
69
|
-
|
|
85
|
+
function toInstalledModules(
|
|
86
|
+
modules: ServerContract.Types.module_entry[] | InstalledModule[]
|
|
87
|
+
): InstalledModule[] {
|
|
88
|
+
if (modules.length > 0 && 'itemId' in modules[0]) {
|
|
89
|
+
return modules as InstalledModule[]
|
|
90
|
+
}
|
|
91
|
+
return packedModulesToInstalled(modules as ServerContract.Types.module_entry[])
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
interface ProjectedCaps {
|
|
95
|
+
hullmass?: UInt32
|
|
96
|
+
capacity?: UInt32
|
|
97
|
+
engines?: ServerContract.Types.movement_stats
|
|
98
|
+
generator?: ServerContract.Types.energy_stats
|
|
99
|
+
loaderLanes: ServerContract.Types.loader_lane[]
|
|
100
|
+
gathererLanes: ServerContract.Types.gatherer_lane[]
|
|
101
|
+
crafterLanes: ServerContract.Types.crafter_lane[]
|
|
102
|
+
builderLanes: ServerContract.Types.builder_lane[]
|
|
103
|
+
hauler?: ServerContract.Types.hauler_stats
|
|
104
|
+
launcher?: ServerContract.Types.launcher_stats
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function recomputeCaps(entity: Projectable): ProjectedCaps | undefined {
|
|
108
|
+
if (
|
|
109
|
+
entity.item_id === undefined ||
|
|
110
|
+
entity.modules === undefined ||
|
|
111
|
+
entity.stats === undefined
|
|
112
|
+
) {
|
|
113
|
+
return undefined
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const itemId = Number(
|
|
117
|
+
typeof entity.item_id === 'number' ? entity.item_id : entity.item_id.value
|
|
118
|
+
)
|
|
119
|
+
const hullStats = decodeCraftedItemStats(itemId, entity.stats)
|
|
120
|
+
if (hullStats.strength === undefined) hullStats.strength = decodeStat(entity.stats, 0)
|
|
121
|
+
if (hullStats.hardness === undefined) hullStats.hardness = decodeStat(entity.stats, 2)
|
|
122
|
+
// The retired Ship T1 recipe only assigned names to its first two stat slots.
|
|
123
|
+
// Its on-chain entity row still carries five packed channels, and the ship hull
|
|
124
|
+
// formula deliberately consumes all five. Keep the unlabelled channels internal
|
|
125
|
+
// to projection so replay remains contract-parity until deployment replaces it.
|
|
126
|
+
if (itemId === ITEM_SHIP_T1_PACKED) {
|
|
127
|
+
hullStats.__legacyShipChannel3 = decodeStat(entity.stats, 3)
|
|
128
|
+
hullStats.__legacyShipChannel4 = decodeStat(entity.stats, 4)
|
|
129
|
+
}
|
|
130
|
+
const layout = getEntityLayout(itemId)?.slots ?? []
|
|
131
|
+
const installed = toInstalledModules(entity.modules)
|
|
132
|
+
const caps = computeEntityCapabilities(hullStats, itemId, installed, layout)
|
|
133
|
+
|
|
134
|
+
const toLoaderLane = (l: {
|
|
135
|
+
slotIndex: number
|
|
136
|
+
mass: number
|
|
137
|
+
thrust: number
|
|
138
|
+
outputPct: number
|
|
139
|
+
}): ServerContract.Types.loader_lane =>
|
|
140
|
+
ServerContract.Types.loader_lane.from({
|
|
141
|
+
slot_index: l.slotIndex,
|
|
142
|
+
mass: l.mass,
|
|
143
|
+
thrust: l.thrust,
|
|
144
|
+
output_pct: l.outputPct,
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
const toCrafterLane = (l: {
|
|
148
|
+
slotIndex: number
|
|
149
|
+
speed: number
|
|
150
|
+
drain: number
|
|
151
|
+
outputPct: number
|
|
152
|
+
}): ServerContract.Types.crafter_lane =>
|
|
153
|
+
ServerContract.Types.crafter_lane.from({
|
|
154
|
+
slot_index: l.slotIndex,
|
|
155
|
+
speed: l.speed,
|
|
156
|
+
drain: l.drain,
|
|
157
|
+
output_pct: l.outputPct,
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
const toBuilderLane = (l: {
|
|
161
|
+
slotIndex: number
|
|
162
|
+
speed: number
|
|
163
|
+
drain: number
|
|
164
|
+
outputPct: number
|
|
165
|
+
}): ServerContract.Types.builder_lane =>
|
|
166
|
+
ServerContract.Types.builder_lane.from({
|
|
167
|
+
slot_index: l.slotIndex,
|
|
168
|
+
speed: l.speed,
|
|
169
|
+
drain: l.drain,
|
|
170
|
+
output_pct: l.outputPct,
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
hullmass: UInt32.from(caps.hullmass),
|
|
175
|
+
capacity: UInt32.from(caps.capacity),
|
|
176
|
+
engines: caps.engines ? ServerContract.Types.movement_stats.from(caps.engines) : undefined,
|
|
177
|
+
generator: caps.generator
|
|
178
|
+
? ServerContract.Types.energy_stats.from(caps.generator)
|
|
179
|
+
: undefined,
|
|
180
|
+
loaderLanes: (caps.loaderLanes ?? []).map(toLoaderLane),
|
|
181
|
+
gathererLanes: hydrateEntityLanes(caps),
|
|
182
|
+
crafterLanes: (caps.crafterLanes ?? []).map(toCrafterLane),
|
|
183
|
+
builderLanes: (caps.builderLanes ?? []).map(toBuilderLane),
|
|
184
|
+
hauler: caps.hauler
|
|
185
|
+
? ServerContract.Types.hauler_stats.from({
|
|
186
|
+
capacity: caps.hauler.capacity,
|
|
187
|
+
efficiency: caps.hauler.efficiency,
|
|
188
|
+
drain: caps.hauler.drain,
|
|
189
|
+
capacity_by_tier: caps.hauler.capacityByTier,
|
|
190
|
+
})
|
|
191
|
+
: undefined,
|
|
192
|
+
launcher: caps.launcher
|
|
193
|
+
? ServerContract.Types.launcher_stats.from({
|
|
194
|
+
charge_rate: caps.launcher.chargeRate,
|
|
195
|
+
velocity: caps.launcher.velocity,
|
|
196
|
+
drain: caps.launcher.drain,
|
|
197
|
+
})
|
|
198
|
+
: undefined,
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function loaderLanesTotalMass(lanes: ServerContract.Types.loader_lane[]): UInt64 {
|
|
203
|
+
let total = 0
|
|
204
|
+
for (const l of lanes) total += Number(l.mass)
|
|
205
|
+
return UInt64.from(total)
|
|
70
206
|
}
|
|
71
207
|
|
|
72
208
|
export function createProjectedEntity(entity: Projectable): ProjectedEntity {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
209
|
+
const needsRecompute =
|
|
210
|
+
entity.hullmass === undefined ||
|
|
211
|
+
entity.loader_lanes === undefined ||
|
|
212
|
+
entity.engines === undefined ||
|
|
213
|
+
entity.generator === undefined ||
|
|
214
|
+
entity.hauler === undefined ||
|
|
215
|
+
entity.launcher === undefined ||
|
|
216
|
+
entity.capacity === undefined
|
|
217
|
+
const caps = needsRecompute ? recomputeCaps(entity) : undefined
|
|
218
|
+
|
|
219
|
+
const shipMass = UInt32.from(entity.hullmass ?? caps?.hullmass ?? 0)
|
|
220
|
+
const loaderLanes = entity.loader_lanes ?? caps?.loaderLanes ?? []
|
|
221
|
+
const gathererLanes = entity.gatherer_lanes ?? caps?.gathererLanes ?? []
|
|
222
|
+
const crafterLanes = entity.crafter_lanes ?? caps?.crafterLanes ?? []
|
|
223
|
+
const builderLanes = entity.builder_lanes ?? caps?.builderLanes ?? []
|
|
224
|
+
const engines = entity.engines ?? caps?.engines
|
|
225
|
+
const generator = entity.generator ?? caps?.generator
|
|
226
|
+
const hauler = entity.hauler ?? caps?.hauler
|
|
227
|
+
const launcher = entity.launcher ?? caps?.launcher
|
|
228
|
+
const capacity = entity.capacity ?? caps?.capacity
|
|
79
229
|
|
|
80
230
|
const cargo: CargoStack[] = entity.cargo.map(cargoItemToStack)
|
|
81
231
|
|
|
82
232
|
const projected: ProjectedEntity = {
|
|
83
233
|
location: Coordinates.from(entity.coordinates),
|
|
84
|
-
energy:
|
|
234
|
+
energy: UInt32.from(entity.energy ?? 0),
|
|
85
235
|
cargo,
|
|
86
236
|
shipMass,
|
|
87
237
|
capacity: capacity ? UInt64.from(capacity) : undefined,
|
|
88
238
|
engines,
|
|
89
239
|
generator,
|
|
90
240
|
hauler,
|
|
91
|
-
|
|
241
|
+
launcher,
|
|
242
|
+
loaderLanes,
|
|
243
|
+
gathererLanes,
|
|
244
|
+
crafterLanes,
|
|
245
|
+
builderLanes,
|
|
92
246
|
|
|
93
247
|
get cargoMass() {
|
|
94
248
|
return calcStacksMass(this.cargo)
|
|
95
249
|
},
|
|
96
250
|
|
|
97
251
|
get totalMass() {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
return mass
|
|
252
|
+
return UInt64.from(this.shipMass)
|
|
253
|
+
.adding(this.cargoMass)
|
|
254
|
+
.adding(loaderLanesTotalMass(this.loaderLanes))
|
|
103
255
|
},
|
|
104
256
|
|
|
105
257
|
hasMovement() {
|
|
@@ -111,7 +263,11 @@ export function createProjectedEntity(entity: Projectable): ProjectedEntity {
|
|
|
111
263
|
},
|
|
112
264
|
|
|
113
265
|
hasLoaders() {
|
|
114
|
-
return
|
|
266
|
+
return this.loaderLanes.length > 0
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
hasLauncher() {
|
|
270
|
+
return this.launcher !== undefined
|
|
115
271
|
},
|
|
116
272
|
|
|
117
273
|
capabilities(): EntityCapabilities {
|
|
@@ -120,7 +276,7 @@ export function createProjectedEntity(entity: Projectable): ProjectedEntity {
|
|
|
120
276
|
capacity: this.capacity ? UInt32.from(this.capacity) : undefined,
|
|
121
277
|
engines: this.engines,
|
|
122
278
|
generator: this.generator,
|
|
123
|
-
|
|
279
|
+
launcher: this.launcher,
|
|
124
280
|
}
|
|
125
281
|
},
|
|
126
282
|
|
|
@@ -146,12 +302,12 @@ function applyRechargeTask(
|
|
|
146
302
|
if (!projected.generator) return
|
|
147
303
|
|
|
148
304
|
if (options.complete) {
|
|
149
|
-
projected.energy =
|
|
305
|
+
projected.energy = UInt32.from(projected.generator.capacity)
|
|
150
306
|
} else if (options.progress !== undefined) {
|
|
151
307
|
const capacity = Number(projected.generator.capacity)
|
|
152
308
|
const currentEnergy = Number(projected.energy)
|
|
153
309
|
const rechargeAmount = (capacity - currentEnergy) * options.progress
|
|
154
|
-
projected.energy =
|
|
310
|
+
projected.energy = UInt32.from(Math.min(capacity, currentEnergy + rechargeAmount))
|
|
155
311
|
}
|
|
156
312
|
}
|
|
157
313
|
|
|
@@ -160,28 +316,25 @@ function applyFlightTask(
|
|
|
160
316
|
task: ServerContract.Types.task,
|
|
161
317
|
options: {complete: boolean; progress?: number}
|
|
162
318
|
): void {
|
|
163
|
-
if (!task.coordinates
|
|
319
|
+
if (!task.coordinates) return
|
|
164
320
|
|
|
165
|
-
const origin = projected.location
|
|
166
321
|
const destination = Coordinates.from(task.coordinates)
|
|
167
|
-
const distance = distanceBetweenCoordinates(origin, task.coordinates)
|
|
168
|
-
const energyUsage = distance.dividing(PRECISION).multiplying(projected.engines.drain)
|
|
169
322
|
|
|
170
323
|
if (options.complete) {
|
|
171
|
-
projected
|
|
172
|
-
? UInt16.from(projected.energy.subtracting(energyUsage))
|
|
173
|
-
: UInt16.from(0)
|
|
324
|
+
applyEnergyCost(projected, task)
|
|
174
325
|
projected.location = destination
|
|
175
326
|
} else if (options.progress !== undefined) {
|
|
176
|
-
const interpolated = lerp(
|
|
327
|
+
const interpolated = lerp(projected.location, destination, options.progress)
|
|
177
328
|
projected.location = Coordinates.from({
|
|
178
329
|
x: Math.round(interpolated.x),
|
|
179
330
|
y: Math.round(interpolated.y),
|
|
180
331
|
})
|
|
181
|
-
const partialEnergy = UInt64.from(
|
|
332
|
+
const partialEnergy = UInt64.from(
|
|
333
|
+
Math.floor(Number(task.energy_cost ?? 0) * options.progress)
|
|
334
|
+
)
|
|
182
335
|
projected.energy = projected.energy.gt(partialEnergy)
|
|
183
|
-
?
|
|
184
|
-
:
|
|
336
|
+
? UInt32.from(projected.energy.subtracting(partialEnergy))
|
|
337
|
+
: UInt32.from(0)
|
|
185
338
|
}
|
|
186
339
|
}
|
|
187
340
|
|
|
@@ -190,7 +343,7 @@ function addCargoItem(projected: ProjectedEntity, item: ServerContract.Types.car
|
|
|
190
343
|
}
|
|
191
344
|
|
|
192
345
|
function removeCargoItem(projected: ProjectedEntity, item: ServerContract.Types.cargo_item): void {
|
|
193
|
-
projected.cargo =
|
|
346
|
+
projected.cargo = subtractFromStacks(projected.cargo, cargoItemToStack(item))
|
|
194
347
|
}
|
|
195
348
|
|
|
196
349
|
function applyAddCargoTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
|
|
@@ -207,10 +360,10 @@ function applyRemoveCargoTask(projected: ProjectedEntity, task: ServerContract.T
|
|
|
207
360
|
|
|
208
361
|
function applyEnergyCost(projected: ProjectedEntity, task: ServerContract.Types.task): void {
|
|
209
362
|
if (!task.energy_cost) return
|
|
210
|
-
const energyCost =
|
|
363
|
+
const energyCost = UInt32.from(task.energy_cost)
|
|
211
364
|
projected.energy = projected.energy.gt(energyCost)
|
|
212
|
-
?
|
|
213
|
-
:
|
|
365
|
+
? UInt32.from(projected.energy.subtracting(energyCost))
|
|
366
|
+
: UInt32.from(0)
|
|
214
367
|
}
|
|
215
368
|
|
|
216
369
|
function applyGatherTask(
|
|
@@ -220,7 +373,7 @@ function applyGatherTask(
|
|
|
220
373
|
): void {
|
|
221
374
|
if (!options.complete) return
|
|
222
375
|
applyEnergyCost(projected, task)
|
|
223
|
-
if (
|
|
376
|
+
if (task.couplings.length === 0) {
|
|
224
377
|
applyAddCargoTask(projected, task)
|
|
225
378
|
}
|
|
226
379
|
}
|
|
@@ -229,16 +382,14 @@ function applyCraftTask(projected: ProjectedEntity, task: ServerContract.Types.t
|
|
|
229
382
|
applyEnergyCost(projected, task)
|
|
230
383
|
if (task.cargo.length === 0) return
|
|
231
384
|
|
|
232
|
-
|
|
233
|
-
|
|
385
|
+
const {clustered, ownOutput} = craftCargoOwnership(task)
|
|
386
|
+
if (!clustered) {
|
|
387
|
+
for (let i = 0; i < task.cargo.length - 1; i++) {
|
|
388
|
+
removeCargoItem(projected, task.cargo[i])
|
|
389
|
+
}
|
|
234
390
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
function applyDeployTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
|
|
239
|
-
applyEnergyCost(projected, task)
|
|
240
|
-
if (task.cargo.length > 0) {
|
|
241
|
-
removeCargoItem(projected, task.cargo[0])
|
|
391
|
+
if (ownOutput) {
|
|
392
|
+
addCargoItem(projected, task.cargo[task.cargo.length - 1])
|
|
242
393
|
}
|
|
243
394
|
}
|
|
244
395
|
|
|
@@ -248,14 +399,25 @@ function applyTask(projected: ProjectedEntity, task: ServerContract.Types.task):
|
|
|
248
399
|
applyRechargeTask(projected, task, {complete: true})
|
|
249
400
|
break
|
|
250
401
|
case TaskType.TRAVEL:
|
|
402
|
+
case TaskType.WARP:
|
|
403
|
+
case TaskType.TRANSIT:
|
|
251
404
|
applyFlightTask(projected, task, {complete: true})
|
|
252
405
|
break
|
|
253
406
|
case TaskType.LOAD:
|
|
254
407
|
case TaskType.UNWRAP:
|
|
408
|
+
case TaskType.CIVIC_WITHDRAW:
|
|
255
409
|
applyAddCargoTask(projected, task)
|
|
256
410
|
break
|
|
257
411
|
case TaskType.UNLOAD:
|
|
258
|
-
case TaskType.
|
|
412
|
+
case TaskType.CONTRIBUTE:
|
|
413
|
+
applyRemoveCargoTask(projected, task)
|
|
414
|
+
break
|
|
415
|
+
case TaskType.CIVIC_DEPOSIT:
|
|
416
|
+
applyEnergyCost(projected, task)
|
|
417
|
+
applyRemoveCargoTask(projected, task)
|
|
418
|
+
break
|
|
419
|
+
case TaskType.UPGRADE:
|
|
420
|
+
applyEnergyCost(projected, task)
|
|
259
421
|
applyRemoveCargoTask(projected, task)
|
|
260
422
|
break
|
|
261
423
|
case TaskType.GATHER:
|
|
@@ -264,11 +426,9 @@ function applyTask(projected: ProjectedEntity, task: ServerContract.Types.task):
|
|
|
264
426
|
case TaskType.CRAFT:
|
|
265
427
|
applyCraftTask(projected, task)
|
|
266
428
|
break
|
|
267
|
-
case TaskType.DEPLOY:
|
|
268
|
-
applyDeployTask(projected, task)
|
|
269
|
-
break
|
|
270
429
|
case TaskType.UNDEPLOY:
|
|
271
|
-
|
|
430
|
+
applyAddCargoTask(projected, task)
|
|
431
|
+
break
|
|
272
432
|
case TaskType.DEMOLISH:
|
|
273
433
|
break
|
|
274
434
|
}
|
|
@@ -278,52 +438,33 @@ export interface ProjectionOptions {
|
|
|
278
438
|
upToTaskIndex?: number
|
|
279
439
|
}
|
|
280
440
|
|
|
441
|
+
function anchoredSkipCount(entity: Projectable, ordered: readonly schedule.OrderedTask[]): number {
|
|
442
|
+
return schedule.appliedTaskCount(entity, ordered)
|
|
443
|
+
}
|
|
444
|
+
|
|
281
445
|
export function projectEntity(entity: Projectable, options?: ProjectionOptions): ProjectedEntity {
|
|
282
446
|
const projected = createProjectedEntity(entity)
|
|
283
|
-
|
|
447
|
+
const ordered = schedule.orderedTasks(entity)
|
|
448
|
+
if (ordered.length === 0) return projected
|
|
284
449
|
|
|
285
|
-
const tasks = entity.schedule.tasks
|
|
286
450
|
const taskCount =
|
|
287
451
|
options?.upToTaskIndex !== undefined
|
|
288
|
-
? Math.max(0, Math.min(options.upToTaskIndex,
|
|
289
|
-
:
|
|
452
|
+
? Math.max(0, Math.min(options.upToTaskIndex, ordered.length))
|
|
453
|
+
: ordered.length
|
|
290
454
|
|
|
291
|
-
for (let i =
|
|
292
|
-
applyTask(projected,
|
|
455
|
+
for (let i = anchoredSkipCount(entity, ordered); i < taskCount; i++) {
|
|
456
|
+
applyTask(projected, ordered[i].task)
|
|
293
457
|
}
|
|
294
458
|
return projected
|
|
295
459
|
}
|
|
296
460
|
|
|
297
|
-
export
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
function buildRemainingProjectable(snapshot: ProjectableSnapshot): Projectable | null {
|
|
303
|
-
if (!snapshot.schedule) return null
|
|
304
|
-
const remainingTasks: ServerContract.Types.task[] = []
|
|
305
|
-
if (snapshot.current_task) remainingTasks.push(snapshot.current_task)
|
|
306
|
-
if (snapshot.pending_tasks?.length) remainingTasks.push(...snapshot.pending_tasks)
|
|
307
|
-
if (remainingTasks.length === 0) return null
|
|
308
|
-
|
|
309
|
-
const completedCount = snapshot.schedule.tasks.length - remainingTasks.length
|
|
310
|
-
let startedMs = snapshot.schedule.started.toMilliseconds()
|
|
311
|
-
for (let i = 0; i < completedCount; i++) {
|
|
312
|
-
startedMs += snapshot.schedule.tasks[i].duration.toNumber() * 1000
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return {
|
|
316
|
-
...snapshot,
|
|
317
|
-
schedule: ServerContract.Types.schedule.from({
|
|
318
|
-
started: TimePoint.fromMilliseconds(startedMs),
|
|
319
|
-
tasks: remainingTasks,
|
|
320
|
-
}),
|
|
461
|
+
export function projectRemainingAt(entity: Projectable, _now: Date): ProjectedEntity {
|
|
462
|
+
const projected = createProjectedEntity(entity)
|
|
463
|
+
const ordered = schedule.orderedTasks(entity)
|
|
464
|
+
for (let i = anchoredSkipCount(entity, ordered); i < ordered.length; i++) {
|
|
465
|
+
applyTask(projected, ordered[i].task)
|
|
321
466
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
export function projectFromCurrentState(snapshot: ProjectableSnapshot): ProjectedEntity {
|
|
325
|
-
const projectable = buildRemainingProjectable(snapshot)
|
|
326
|
-
return projectable ? projectEntity(projectable) : createProjectedEntity(snapshot)
|
|
467
|
+
return projected
|
|
327
468
|
}
|
|
328
469
|
|
|
329
470
|
function getRecipeInputsForOutput(outputItemId: number): RecipeInput[] | undefined {
|
|
@@ -346,19 +487,10 @@ function validateCraftTask(task: ServerContract.Types.task, projected: Projected
|
|
|
346
487
|
let matched = false
|
|
347
488
|
for (let ri = 0; ri < recipe.length; ri++) {
|
|
348
489
|
const req = recipe[ri]
|
|
349
|
-
if (
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
break
|
|
354
|
-
}
|
|
355
|
-
} else {
|
|
356
|
-
const item = getItem(input.item_id)
|
|
357
|
-
if (item.category === req.category && item.tier === req.tier) {
|
|
358
|
-
groupedInputs[ri].push(input)
|
|
359
|
-
matched = true
|
|
360
|
-
break
|
|
361
|
-
}
|
|
490
|
+
if (input.item_id.toNumber() === req.itemId) {
|
|
491
|
+
groupedInputs[ri].push(input)
|
|
492
|
+
matched = true
|
|
493
|
+
break
|
|
362
494
|
}
|
|
363
495
|
}
|
|
364
496
|
if (!matched) throw new Error(RECIPE_INPUTS_INVALID)
|
|
@@ -389,15 +521,16 @@ function validateCraftTask(task: ServerContract.Types.task, projected: Projected
|
|
|
389
521
|
break
|
|
390
522
|
}
|
|
391
523
|
}
|
|
392
|
-
if (!found) throw new Error(
|
|
524
|
+
if (!found) throw new Error(ENTITY_CARGO_NOT_LOADED)
|
|
393
525
|
}
|
|
394
526
|
}
|
|
395
527
|
|
|
396
528
|
export function validateSchedule(entity: Projectable): void {
|
|
397
|
-
|
|
529
|
+
const ordered = schedule.orderedTasks(entity)
|
|
530
|
+
if (ordered.length === 0) return
|
|
398
531
|
|
|
399
532
|
const projected = createProjectedEntity(entity)
|
|
400
|
-
for (const task of
|
|
533
|
+
for (const {task} of ordered) {
|
|
401
534
|
if (task.type.toNumber() === TaskType.CRAFT) {
|
|
402
535
|
validateCraftTask(task, projected)
|
|
403
536
|
}
|
|
@@ -411,61 +544,44 @@ export function validateSchedule(entity: Projectable): void {
|
|
|
411
544
|
export function projectEntityAt(entity: Projectable, now: Date): ProjectedEntity {
|
|
412
545
|
const projected = createProjectedEntity(entity)
|
|
413
546
|
|
|
414
|
-
|
|
547
|
+
const ordered = schedule.orderedTasks(entity)
|
|
548
|
+
if (ordered.length === 0) {
|
|
415
549
|
return projected
|
|
416
550
|
}
|
|
417
551
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
552
|
+
const nowMs = now.getTime()
|
|
553
|
+
const skip = anchoredSkipCount(entity, ordered)
|
|
554
|
+
|
|
555
|
+
for (let i = skip; i < ordered.length; i++) {
|
|
556
|
+
const {task, startsAt} = ordered[i]
|
|
557
|
+
const duration = task.duration.toNumber()
|
|
558
|
+
const elapsed = Math.min(
|
|
559
|
+
Math.max(0, Math.floor((nowMs - startsAt.getTime()) / 1000)),
|
|
560
|
+
duration
|
|
561
|
+
)
|
|
562
|
+
const taskComplete = elapsed >= duration
|
|
563
|
+
const taskInProgress = elapsed > 0 && elapsed < duration
|
|
422
564
|
|
|
423
565
|
if (!taskComplete && !taskInProgress) {
|
|
424
|
-
|
|
566
|
+
continue
|
|
425
567
|
}
|
|
426
568
|
|
|
427
|
-
const progress = taskInProgress
|
|
428
|
-
? schedule.getTaskElapsed(entity, i, now) / task.duration.toNumber()
|
|
429
|
-
: undefined
|
|
569
|
+
const progress = taskInProgress ? elapsed / duration : undefined
|
|
430
570
|
|
|
431
571
|
switch (task.type.toNumber()) {
|
|
432
572
|
case TaskType.RECHARGE:
|
|
433
573
|
applyRechargeTask(projected, task, {complete: taskComplete, progress})
|
|
434
574
|
break
|
|
435
575
|
case TaskType.TRAVEL:
|
|
576
|
+
case TaskType.WARP:
|
|
577
|
+
case TaskType.TRANSIT:
|
|
436
578
|
applyFlightTask(projected, task, {complete: taskComplete, progress})
|
|
437
579
|
break
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
if (taskComplete) applyAddCargoTask(projected, task)
|
|
441
|
-
break
|
|
442
|
-
case TaskType.UNLOAD:
|
|
443
|
-
case TaskType.WRAP:
|
|
444
|
-
if (taskComplete) applyRemoveCargoTask(projected, task)
|
|
445
|
-
break
|
|
446
|
-
case TaskType.GATHER:
|
|
447
|
-
if (taskComplete) applyGatherTask(projected, task, {complete: true})
|
|
448
|
-
break
|
|
449
|
-
case TaskType.CRAFT:
|
|
450
|
-
if (taskComplete) applyCraftTask(projected, task)
|
|
451
|
-
break
|
|
452
|
-
case TaskType.DEPLOY:
|
|
453
|
-
if (taskComplete) applyDeployTask(projected, task)
|
|
454
|
-
break
|
|
455
|
-
case TaskType.UNDEPLOY:
|
|
456
|
-
case TaskType.WRAP_ENTITY:
|
|
457
|
-
case TaskType.DEMOLISH:
|
|
580
|
+
default:
|
|
581
|
+
if (taskComplete) applyTask(projected, task)
|
|
458
582
|
break
|
|
459
583
|
}
|
|
460
584
|
}
|
|
461
585
|
|
|
462
586
|
return projected
|
|
463
587
|
}
|
|
464
|
-
|
|
465
|
-
export function projectFromCurrentStateAt(
|
|
466
|
-
snapshot: ProjectableSnapshot,
|
|
467
|
-
now: Date
|
|
468
|
-
): ProjectedEntity {
|
|
469
|
-
const projectable = buildRemainingProjectable(snapshot)
|
|
470
|
-
return projectable ? projectEntityAt(projectable, now) : createProjectedEntity(snapshot)
|
|
471
|
-
}
|