@shipload/sdk 1.0.0-next.5 → 1.0.0-next.50
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 +2881 -1149
- package/lib/shipload.js +13031 -5511
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +12807 -5460
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +1028 -0
- package/lib/testing.js +4336 -0
- package/lib/testing.js.map +1 -0
- package/lib/testing.m.js +4330 -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 +6 -7
- package/src/capabilities/gathering.test.ts +29 -0
- package/src/capabilities/gathering.ts +37 -19
- package/src/capabilities/index.ts +0 -1
- package/src/capabilities/modules.ts +22 -0
- package/src/capabilities/storage.ts +16 -1
- package/src/contracts/platform.ts +231 -3
- package/src/contracts/server.ts +1160 -520
- 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 +31 -16
- package/src/data/capability-formulas.ts +21 -14
- package/src/data/catalog.ts +0 -5
- package/src/data/colors.ts +13 -47
- package/src/data/entities.json +154 -10
- package/src/data/item-ids.ts +31 -12
- package/src/data/items.json +192 -74
- package/src/data/kind-registry.json +131 -0
- package/src/data/kind-registry.ts +172 -0
- package/src/data/metadata.ts +166 -48
- package/src/data/recipes-runtime.ts +5 -23
- package/src/data/recipes.json +1003 -163
- package/src/derivation/build-methods.test.ts +13 -0
- package/src/derivation/build-methods.ts +48 -0
- package/src/derivation/capabilities.test.ts +151 -0
- package/src/derivation/capabilities.ts +527 -0
- package/src/derivation/capability-mappings.ts +58 -16
- package/src/derivation/crafting.ts +36 -33
- package/src/derivation/index.ts +28 -2
- package/src/derivation/recipe-usage.test.ts +81 -0
- package/src/derivation/recipe-usage.ts +141 -0
- package/src/derivation/reserve-regen.ts +34 -0
- package/src/derivation/resources.ts +98 -19
- package/src/derivation/rollups.test.ts +55 -0
- package/src/derivation/rollups.ts +56 -0
- package/src/derivation/stars.test.ts +67 -0
- package/src/derivation/stars.ts +25 -0
- package/src/derivation/stats.ts +6 -6
- 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 +141 -0
- package/src/entities/entity.ts +98 -0
- package/src/entities/gamestate.ts +3 -28
- package/src/entities/makers.ts +131 -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 +290 -34
- package/src/managers/actions.ts +602 -105
- package/src/managers/base.ts +6 -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 +412 -0
- package/src/managers/context.ts +29 -1
- package/src/managers/coordinates.ts +14 -0
- package/src/managers/entities.ts +27 -66
- package/src/managers/epochs.ts +40 -0
- package/src/managers/flatten-gather-plan.test.ts +80 -0
- package/src/managers/index.ts +20 -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/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 +336 -0
- package/src/nft/description.ts +104 -36
- package/src/nft/index.ts +3 -0
- package/src/planner/index.ts +242 -0
- package/src/planner/planner.test.ts +325 -0
- package/src/resolution/describe-module.ts +43 -25
- package/src/resolution/display-name.ts +38 -10
- package/src/resolution/resolve-item.test.ts +48 -0
- package/src/resolution/resolve-item.ts +74 -47
- 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.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 +210 -107
- package/src/scheduling/schedule.ts +240 -117
- package/src/scheduling/task-cargo.ts +46 -0
- package/src/scheduling/unwrap.test.ts +86 -0
- package/src/scheduling/unwrap.ts +190 -0
- package/src/shipload.ts +26 -1
- 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.ts +23 -0
- package/src/travel/route-planner.ts +277 -0
- package/src/travel/travel.ts +148 -117
- 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 +36 -14
- package/src/utils/cargo.test.ts +14 -0
- package/src/utils/cargo.ts +29 -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 -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
package/src/travel/travel.ts
CHANGED
|
@@ -28,12 +28,22 @@ import {
|
|
|
28
28
|
type Distance,
|
|
29
29
|
MAX_ORBITAL_ALTITUDE,
|
|
30
30
|
MIN_ORBITAL_ALTITUDE,
|
|
31
|
+
MIN_TRANSFER_DISTANCE_ORBITAL_VESSEL,
|
|
32
|
+
MIN_TRANSFER_DISTANCE_PLANETARY_STRUCTURE,
|
|
31
33
|
PRECISION,
|
|
32
34
|
type ShipLike,
|
|
33
35
|
TaskType,
|
|
34
36
|
} from '../types'
|
|
37
|
+
import {EntityClass} from '../data/kind-registry'
|
|
35
38
|
import {getItem} from '../data/catalog'
|
|
36
39
|
import {hasSystem} from '../utils/system'
|
|
40
|
+
import {WH} from '../derivation/wormhole'
|
|
41
|
+
import * as scheduleModel from '../scheduling/schedule'
|
|
42
|
+
import type {ScheduleData} from '../scheduling/schedule'
|
|
43
|
+
|
|
44
|
+
function isPositionalTask(task: ServerContract.Types.task): boolean {
|
|
45
|
+
return task.type.equals(TaskType.TRAVEL) || task.type.equals(TaskType.TRANSIT)
|
|
46
|
+
}
|
|
37
47
|
|
|
38
48
|
export function calc_orbital_altitude(mass: number): number {
|
|
39
49
|
if (mass <= BASE_ORBITAL_MASS) {
|
|
@@ -111,15 +121,16 @@ export function getInterpolatedPosition(
|
|
|
111
121
|
taskIndex: number,
|
|
112
122
|
taskProgress: number
|
|
113
123
|
): FloatPosition {
|
|
114
|
-
|
|
124
|
+
const tasks = mobilityTasks(entity)
|
|
125
|
+
if (tasks.length === 0) {
|
|
115
126
|
return {x: Number(entity.coordinates.x), y: Number(entity.coordinates.y)}
|
|
116
127
|
}
|
|
117
128
|
if (taskIndex < 0) {
|
|
118
|
-
const settled = getFlightOrigin(entity,
|
|
129
|
+
const settled = getFlightOrigin(entity, tasks.length)
|
|
119
130
|
return {x: Number(settled.x), y: Number(settled.y)}
|
|
120
131
|
}
|
|
121
|
-
const task =
|
|
122
|
-
if (!task
|
|
132
|
+
const task = tasks[taskIndex]
|
|
133
|
+
if (!isPositionalTask(task) || !task.coordinates) {
|
|
123
134
|
const origin = getFlightOrigin(entity, taskIndex)
|
|
124
135
|
return {x: Number(origin.x), y: Number(origin.y)}
|
|
125
136
|
}
|
|
@@ -192,15 +203,31 @@ export function calc_flighttime(distance: UInt64Type, acceleration: number): UIn
|
|
|
192
203
|
return UInt32.from(2 * Math.sqrt(Number(distance) / acceleration))
|
|
193
204
|
}
|
|
194
205
|
|
|
206
|
+
export function calc_transit_duration(ax: number, ay: number, bx: number, by: number): UInt32 {
|
|
207
|
+
const distance = distanceBetweenPoints(ax, ay, bx, by)
|
|
208
|
+
return UInt32.from(Math.floor(distance.toNumber() / (PRECISION * WH.TRANSIT_SPEED)))
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// The active entity's chosen loader lane (lowest slot), mirroring cargo.cpp lane selection.
|
|
212
|
+
export function shipLoaderLane(ship: ShipLike): {thrust: number; mass: number} | undefined {
|
|
213
|
+
const lanes = ship.loader_lanes ?? []
|
|
214
|
+
if (lanes.length === 0) return undefined
|
|
215
|
+
let lowest = lanes[0]
|
|
216
|
+
for (const lane of lanes) {
|
|
217
|
+
if (Number(lane.slot_index) < Number(lowest.slot_index)) lowest = lane
|
|
218
|
+
}
|
|
219
|
+
return {thrust: Number(lowest.thrust), mass: Number(lowest.mass)}
|
|
220
|
+
}
|
|
221
|
+
|
|
195
222
|
export function calc_loader_flighttime(ship: ShipLike, mass: UInt64, altitude?: number): UInt32 {
|
|
196
223
|
const z = altitude ?? ship.coordinates.z?.toNumber() ?? calc_orbital_altitude(Number(mass))
|
|
197
224
|
return calc_flighttime(z, calc_loader_acceleration(ship, mass))
|
|
198
225
|
}
|
|
199
226
|
|
|
200
227
|
export function calc_loader_acceleration(ship: ShipLike, mass: UInt64): number {
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
return calc_acceleration(thrust, Number(mass)
|
|
228
|
+
const lane = shipLoaderLane(ship)
|
|
229
|
+
const thrust = lane ? lane.thrust : 0
|
|
230
|
+
return calc_acceleration(thrust, Number(mass))
|
|
204
231
|
}
|
|
205
232
|
|
|
206
233
|
export function calc_ship_flighttime(ship: ShipLike, mass: UInt64, distance: UInt64): UInt32 {
|
|
@@ -222,8 +249,10 @@ export function calc_ship_mass(ship: ShipLike, cargos: CargoMassInfo[]): UInt64
|
|
|
222
249
|
|
|
223
250
|
mass.add(ship.hullmass)
|
|
224
251
|
|
|
225
|
-
if (ship.
|
|
226
|
-
|
|
252
|
+
if (ship.loader_lanes && ship.loader_lanes.length > 0) {
|
|
253
|
+
for (const l of ship.loader_lanes) {
|
|
254
|
+
mass.add(UInt64.from(l.mass))
|
|
255
|
+
}
|
|
227
256
|
}
|
|
228
257
|
|
|
229
258
|
for (const cargo of cargos) {
|
|
@@ -258,10 +287,10 @@ export function calculateTransferTime(
|
|
|
258
287
|
return UInt32.from(0)
|
|
259
288
|
}
|
|
260
289
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return
|
|
290
|
+
const lane = shipLoaderLane(ship)
|
|
291
|
+
if (!lane) return UInt32.from(0)
|
|
292
|
+
mass = UInt64.from(mass).adding(UInt64.from(lane.mass))
|
|
293
|
+
return calc_loader_flighttime(ship, mass)
|
|
265
294
|
}
|
|
266
295
|
|
|
267
296
|
export function calculateRefuelingTime(ship: ShipLike): UInt32 {
|
|
@@ -316,25 +345,22 @@ export function calculateLoadTimeBreakdown(
|
|
|
316
345
|
let unloadTime = 0
|
|
317
346
|
let loadTime = 0
|
|
318
347
|
|
|
319
|
-
|
|
320
|
-
|
|
348
|
+
const lane = shipLoaderLane(ship)
|
|
349
|
+
|
|
350
|
+
if (mass_unload.gt(UInt64.zero) && lane) {
|
|
351
|
+
const totalMass = UInt64.from(mass_unload).adding(UInt64.from(lane.mass))
|
|
321
352
|
unloadTime = Number(calc_loader_flighttime(ship, totalMass))
|
|
322
353
|
}
|
|
323
354
|
|
|
324
|
-
if (mass_load.gt(UInt64.zero) &&
|
|
325
|
-
const totalMass = UInt64.from(mass_load).adding(
|
|
355
|
+
if (mass_load.gt(UInt64.zero) && lane) {
|
|
356
|
+
const totalMass = UInt64.from(mass_load).adding(UInt64.from(lane.mass))
|
|
326
357
|
loadTime = Number(calc_loader_flighttime(ship, totalMass))
|
|
327
358
|
}
|
|
328
359
|
|
|
329
|
-
const numLoaders = ship.loaders ? Number(ship.loaders.quantity) : 0
|
|
330
|
-
const totalTime = numLoaders > 0 ? (unloadTime + loadTime) / numLoaders : 0
|
|
331
|
-
const unloadTimePerLoader = numLoaders > 0 ? unloadTime / numLoaders : 0
|
|
332
|
-
const loadTimePerLoader = numLoaders > 0 ? loadTime / numLoaders : 0
|
|
333
|
-
|
|
334
360
|
return {
|
|
335
|
-
unloadTime
|
|
336
|
-
loadTime
|
|
337
|
-
totalTime,
|
|
361
|
+
unloadTime,
|
|
362
|
+
loadTime,
|
|
363
|
+
totalTime: unloadTime + loadTime,
|
|
338
364
|
unloadMass: Number(mass_unload),
|
|
339
365
|
loadMass: Number(mass_load),
|
|
340
366
|
}
|
|
@@ -368,24 +394,16 @@ export function estimateTravelTime(
|
|
|
368
394
|
let loadTime = UInt32.zero
|
|
369
395
|
let unloadTime = UInt32.zero
|
|
370
396
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
ship
|
|
376
|
-
) {
|
|
377
|
-
const totalMass = UInt64.from(loadMass).adding(ship.loaders.mass)
|
|
378
|
-
loadTime = calc_loader_flighttime(ship, totalMass).dividing(ship.loaders.quantity)
|
|
397
|
+
const lane = shipLoaderLane(ship)
|
|
398
|
+
|
|
399
|
+
if (loadMass && UInt32.from(loadMass).gt(UInt32.zero) && lane) {
|
|
400
|
+
const totalMass = UInt64.from(loadMass).adding(UInt64.from(lane.mass))
|
|
401
|
+
loadTime = calc_loader_flighttime(ship, totalMass)
|
|
379
402
|
}
|
|
380
403
|
|
|
381
|
-
if (
|
|
382
|
-
unloadMass
|
|
383
|
-
|
|
384
|
-
ship.loaders &&
|
|
385
|
-
ship.loaders.quantity.gt(UInt32.zero)
|
|
386
|
-
) {
|
|
387
|
-
const totalMass = UInt64.from(unloadMass).adding(ship.loaders.mass)
|
|
388
|
-
unloadTime = calc_loader_flighttime(ship, totalMass).dividing(ship.loaders.quantity)
|
|
404
|
+
if (unloadMass && UInt32.from(unloadMass).gt(UInt32.zero) && lane) {
|
|
405
|
+
const totalMass = UInt64.from(unloadMass).adding(UInt64.from(lane.mass))
|
|
406
|
+
unloadTime = calc_loader_flighttime(ship, totalMass)
|
|
389
407
|
}
|
|
390
408
|
|
|
391
409
|
return {
|
|
@@ -417,30 +435,51 @@ export function hasEnergyForDistance(ship: ShipLike, distance: UInt64Type): bool
|
|
|
417
435
|
return UInt64.from(ship.energy ?? 0).gte(energyNeeded)
|
|
418
436
|
}
|
|
419
437
|
|
|
438
|
+
export interface TransferLoaderLane {
|
|
439
|
+
slot_index?: {toNumber(): number} | number
|
|
440
|
+
thrust: {toNumber(): number} | number
|
|
441
|
+
mass: {toNumber(): number} | number
|
|
442
|
+
}
|
|
443
|
+
|
|
420
444
|
export interface TransferEntity {
|
|
421
445
|
location: {z?: {toNumber(): number} | number}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
446
|
+
entityClass: EntityClass
|
|
447
|
+
loaderLanes?: TransferLoaderLane[]
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
function toNum(v: {toNumber(): number} | number | undefined): number {
|
|
451
|
+
if (v === undefined) return 0
|
|
452
|
+
return typeof v === 'number' ? v : v.toNumber()
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Mirrors cargo.cpp worker_lane_key_or_mobility: lowest-slot loader lane (display has no busy context).
|
|
456
|
+
function chosenLoaderLane(entity: TransferEntity): TransferLoaderLane | undefined {
|
|
457
|
+
const lanes = entity.loaderLanes ?? []
|
|
458
|
+
if (lanes.length === 0) return undefined
|
|
459
|
+
let lowest = lanes[0]
|
|
460
|
+
for (const lane of lanes) {
|
|
461
|
+
if (toNum(lane.slot_index) < toNum(lowest.slot_index)) lowest = lane
|
|
426
462
|
}
|
|
463
|
+
return lowest
|
|
427
464
|
}
|
|
428
465
|
|
|
429
|
-
export interface HasScheduleAndLocation {
|
|
466
|
+
export interface HasScheduleAndLocation extends ScheduleData {
|
|
430
467
|
coordinates: ServerContract.ActionParams.Type.coordinates
|
|
431
|
-
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function mobilityTasks(entity: HasScheduleAndLocation): ServerContract.Types.task[] {
|
|
471
|
+
return scheduleModel.mobilityLane(entity)?.schedule.tasks ?? []
|
|
432
472
|
}
|
|
433
473
|
|
|
434
474
|
export function getFlightOrigin(
|
|
435
475
|
entity: HasScheduleAndLocation,
|
|
436
476
|
flightTaskIndex: number
|
|
437
477
|
): ServerContract.ActionParams.Type.coordinates {
|
|
438
|
-
|
|
439
|
-
|
|
478
|
+
const tasks = mobilityTasks(entity)
|
|
440
479
|
let origin = entity.coordinates
|
|
441
|
-
for (let i = 0; i < flightTaskIndex && i <
|
|
442
|
-
const task =
|
|
443
|
-
if (task
|
|
480
|
+
for (let i = 0; i < flightTaskIndex && i < tasks.length; i++) {
|
|
481
|
+
const task = tasks[i]
|
|
482
|
+
if (isPositionalTask(task) && task.coordinates) {
|
|
444
483
|
origin = task.coordinates
|
|
445
484
|
}
|
|
446
485
|
}
|
|
@@ -450,11 +489,10 @@ export function getFlightOrigin(
|
|
|
450
489
|
export function getDestinationLocation(
|
|
451
490
|
entity: HasScheduleAndLocation
|
|
452
491
|
): ServerContract.ActionParams.Type.coordinates | undefined {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
if (task.type.equals(TaskType.TRAVEL) && task.coordinates) {
|
|
492
|
+
const tasks = mobilityTasks(entity)
|
|
493
|
+
for (let i = tasks.length - 1; i >= 0; i--) {
|
|
494
|
+
const task = tasks[i]
|
|
495
|
+
if (isPositionalTask(task) && task.coordinates) {
|
|
458
496
|
return task.coordinates
|
|
459
497
|
}
|
|
460
498
|
}
|
|
@@ -467,16 +505,17 @@ export function getPositionAt(
|
|
|
467
505
|
taskIndex: number,
|
|
468
506
|
taskProgress: number
|
|
469
507
|
): ServerContract.ActionParams.Type.coordinates {
|
|
470
|
-
|
|
508
|
+
const tasks = mobilityTasks(entity)
|
|
509
|
+
if (tasks.length === 0) {
|
|
471
510
|
return entity.coordinates
|
|
472
511
|
}
|
|
473
512
|
if (taskIndex < 0) {
|
|
474
|
-
return getFlightOrigin(entity,
|
|
513
|
+
return getFlightOrigin(entity, tasks.length)
|
|
475
514
|
}
|
|
476
515
|
|
|
477
|
-
const task =
|
|
516
|
+
const task = tasks[taskIndex]
|
|
478
517
|
|
|
479
|
-
if (!task
|
|
518
|
+
if (!isPositionalTask(task) || !task.coordinates) {
|
|
480
519
|
return getFlightOrigin(entity, taskIndex)
|
|
481
520
|
}
|
|
482
521
|
|
|
@@ -490,68 +529,60 @@ export function getPositionAt(
|
|
|
490
529
|
}
|
|
491
530
|
}
|
|
492
531
|
|
|
493
|
-
export function
|
|
494
|
-
|
|
495
|
-
|
|
532
|
+
export function minTransferDistance(entityClass: EntityClass): number {
|
|
533
|
+
return entityClass === EntityClass.OrbitalVessel
|
|
534
|
+
? MIN_TRANSFER_DISTANCE_ORBITAL_VESSEL
|
|
535
|
+
: MIN_TRANSFER_DISTANCE_PLANETARY_STRUCTURE
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// Mirrors cargo.cpp calc_onesided_duration: single active loader's thrust + mass, no ÷quantity.
|
|
539
|
+
export function calc_onesided_duration(
|
|
540
|
+
loaderThrust: number,
|
|
541
|
+
loaderMass: number,
|
|
542
|
+
activeZ: number,
|
|
543
|
+
counterpartZ: number,
|
|
544
|
+
activeEntityClass: EntityClass,
|
|
545
|
+
counterpartEntityClass: EntityClass,
|
|
496
546
|
cargoMass: number
|
|
497
547
|
): number {
|
|
498
|
-
if (cargoMass === 0) {
|
|
548
|
+
if (cargoMass === 0 || loaderThrust === 0) {
|
|
499
549
|
return 0
|
|
500
550
|
}
|
|
551
|
+
const rawDistance = Math.abs(activeZ - counterpartZ)
|
|
552
|
+
const minDistance = Math.max(
|
|
553
|
+
minTransferDistance(activeEntityClass),
|
|
554
|
+
minTransferDistance(counterpartEntityClass)
|
|
555
|
+
)
|
|
556
|
+
const distance = rawDistance < minDistance ? minDistance : rawDistance
|
|
557
|
+
const totalMass = cargoMass + loaderMass
|
|
558
|
+
const acceleration = calc_acceleration(loaderThrust, totalMass)
|
|
559
|
+
const flightTime = Math.floor(2 * Math.sqrt(distance / acceleration))
|
|
560
|
+
return flightTime === 0 ? 1 : flightTime
|
|
561
|
+
}
|
|
501
562
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
typeof source.loaders.mass === 'number'
|
|
513
|
-
? source.loaders.mass
|
|
514
|
-
: source.loaders.mass.toNumber()
|
|
515
|
-
const qty =
|
|
516
|
-
typeof source.loaders.quantity === 'number'
|
|
517
|
-
? source.loaders.quantity
|
|
518
|
-
: source.loaders.quantity.toNumber()
|
|
519
|
-
totalThrust += thrust * qty
|
|
520
|
-
totalLoaderMass += mass * qty
|
|
521
|
-
totalQuantity += qty
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
if (dest.loaders) {
|
|
525
|
-
const thrust =
|
|
526
|
-
typeof dest.loaders.thrust === 'number'
|
|
527
|
-
? dest.loaders.thrust
|
|
528
|
-
: dest.loaders.thrust.toNumber()
|
|
529
|
-
const mass =
|
|
530
|
-
typeof dest.loaders.mass === 'number' ? dest.loaders.mass : dest.loaders.mass.toNumber()
|
|
531
|
-
const qty =
|
|
532
|
-
typeof dest.loaders.quantity === 'number'
|
|
533
|
-
? dest.loaders.quantity
|
|
534
|
-
: dest.loaders.quantity.toNumber()
|
|
535
|
-
totalThrust += thrust * qty
|
|
536
|
-
totalLoaderMass += mass * qty
|
|
537
|
-
totalQuantity += qty
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
if (totalThrust === 0 || totalQuantity === 0) {
|
|
563
|
+
// Mirrors cargo.cpp: the active (loader-bearing) entity's chosen loader lane drives the duration.
|
|
564
|
+
export function calc_transfer_duration(
|
|
565
|
+
source: TransferEntity,
|
|
566
|
+
dest: TransferEntity,
|
|
567
|
+
cargoMass: number
|
|
568
|
+
): number {
|
|
569
|
+
const active = chosenLoaderLane(source) ? source : dest
|
|
570
|
+
const counterpart = active === source ? dest : source
|
|
571
|
+
const lane = chosenLoaderLane(active)
|
|
572
|
+
if (!lane) {
|
|
541
573
|
return 0
|
|
542
574
|
}
|
|
543
575
|
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
return Math.floor(flightTime / totalQuantity)
|
|
576
|
+
const activeZ = toNum(active.location.z)
|
|
577
|
+
const counterpartZ = toNum(counterpart.location.z)
|
|
578
|
+
|
|
579
|
+
return calc_onesided_duration(
|
|
580
|
+
toNum(lane.thrust),
|
|
581
|
+
toNum(lane.mass),
|
|
582
|
+
activeZ,
|
|
583
|
+
counterpartZ,
|
|
584
|
+
active.entityClass,
|
|
585
|
+
counterpart.entityClass,
|
|
586
|
+
cargoMass
|
|
587
|
+
)
|
|
557
588
|
}
|
|
@@ -1,6 +1,23 @@
|
|
|
1
|
-
import type {Name, UInt16, UInt32} from '@wharfkit/antelope'
|
|
1
|
+
import type {Name, UInt16, UInt32, UInt8} from '@wharfkit/antelope'
|
|
2
2
|
import type {ServerContract} from '../contracts'
|
|
3
3
|
|
|
4
|
+
export interface LoaderStats {
|
|
5
|
+
mass: {toNumber(): number; multiplying(v: unknown): {toNumber(): number}}
|
|
6
|
+
thrust: {toNumber(): number}
|
|
7
|
+
quantity: {toNumber(): number; gt(v: unknown): boolean}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface GathererStats {
|
|
11
|
+
yield: {toNumber(): number}
|
|
12
|
+
drain: {toNumber(): number}
|
|
13
|
+
depth: {toNumber(): number; toString(): string}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface CrafterStats {
|
|
17
|
+
speed: {toNumber(): number}
|
|
18
|
+
drain: {toNumber(): number}
|
|
19
|
+
}
|
|
20
|
+
|
|
4
21
|
export interface MovementCapability {
|
|
5
22
|
engines: ServerContract.Types.movement_stats
|
|
6
23
|
generator: ServerContract.Types.energy_stats
|
|
@@ -17,11 +34,11 @@ export interface StorageCapability {
|
|
|
17
34
|
}
|
|
18
35
|
|
|
19
36
|
export interface LoaderCapability {
|
|
20
|
-
loaders:
|
|
37
|
+
loaders: LoaderStats
|
|
21
38
|
}
|
|
22
39
|
|
|
23
40
|
export interface GathererCapability {
|
|
24
|
-
gatherer:
|
|
41
|
+
gatherer: GathererStats
|
|
25
42
|
}
|
|
26
43
|
|
|
27
44
|
export interface MassCapability {
|
|
@@ -29,6 +46,7 @@ export interface MassCapability {
|
|
|
29
46
|
}
|
|
30
47
|
|
|
31
48
|
export interface ScheduleCapability {
|
|
49
|
+
lanes?: ServerContract.Types.lane[]
|
|
32
50
|
schedule?: ServerContract.Types.schedule
|
|
33
51
|
}
|
|
34
52
|
|
|
@@ -37,10 +55,11 @@ export interface EntityCapabilities {
|
|
|
37
55
|
capacity?: UInt32
|
|
38
56
|
engines?: ServerContract.Types.movement_stats
|
|
39
57
|
generator?: ServerContract.Types.energy_stats
|
|
40
|
-
loaders?:
|
|
41
|
-
gatherer?:
|
|
42
|
-
crafter?:
|
|
58
|
+
loaders?: LoaderStats
|
|
59
|
+
gatherer?: GathererStats
|
|
60
|
+
crafter?: CrafterStats
|
|
43
61
|
hauler?: ServerContract.Types.hauler_stats
|
|
62
|
+
launcher?: ServerContract.Types.launcher_stats
|
|
44
63
|
}
|
|
45
64
|
|
|
46
65
|
export interface EntityState {
|
|
@@ -74,3 +93,7 @@ export function capsHasMass(caps: EntityCapabilities): boolean {
|
|
|
74
93
|
export function capsHasHauler(caps: EntityCapabilities): boolean {
|
|
75
94
|
return caps.hauler !== undefined
|
|
76
95
|
}
|
|
96
|
+
|
|
97
|
+
export function capsHasLauncher(caps: EntityCapabilities): boolean {
|
|
98
|
+
return caps.launcher !== undefined
|
|
99
|
+
}
|
package/src/types/entity.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type {ServerContract} from '../contracts'
|
|
|
3
3
|
import type {Coordinates} from '../types'
|
|
4
4
|
import type {
|
|
5
5
|
EnergyCapability,
|
|
6
|
+
GathererCapability,
|
|
6
7
|
LoaderCapability,
|
|
7
8
|
MassCapability,
|
|
8
9
|
MovementCapability,
|
|
@@ -24,9 +25,8 @@ export type ShipEntity = Entity &
|
|
|
24
25
|
StorageCapability &
|
|
25
26
|
Partial<LoaderCapability> &
|
|
26
27
|
MassCapability &
|
|
27
|
-
ScheduleCapability &
|
|
28
|
-
|
|
29
|
-
}
|
|
28
|
+
ScheduleCapability &
|
|
29
|
+
Partial<GathererCapability>
|
|
30
30
|
|
|
31
31
|
export type WarehouseEntity = Entity &
|
|
32
32
|
StorageCapability &
|
package/src/types/index.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type Int64Type,
|
|
3
|
-
Name,
|
|
4
3
|
type UInt16,
|
|
5
4
|
type UInt16Type,
|
|
6
5
|
type UInt32,
|
|
7
6
|
type UInt32Type,
|
|
8
7
|
UInt64,
|
|
8
|
+
type UInt64Type,
|
|
9
9
|
} from '@wharfkit/antelope'
|
|
10
10
|
import {ServerContract} from './contracts'
|
|
11
11
|
|
|
12
12
|
export const PRECISION = 10000
|
|
13
13
|
export const CRAFT_ENERGY_DIVISOR = 150000
|
|
14
14
|
|
|
15
|
-
export const
|
|
15
|
+
export const PLANETARY_STRUCTURE_Z = 0
|
|
16
16
|
|
|
17
17
|
export const CONTAINER_Z = 300
|
|
18
18
|
|
|
@@ -23,13 +23,22 @@ export const MAX_ORBITAL_ALTITUDE = 3000
|
|
|
23
23
|
|
|
24
24
|
export const BASE_ORBITAL_MASS = 100000
|
|
25
25
|
|
|
26
|
+
export const MIN_TRANSFER_DISTANCE_PLANETARY_STRUCTURE = 100
|
|
27
|
+
export const MIN_TRANSFER_DISTANCE_ORBITAL_VESSEL = 200
|
|
28
|
+
|
|
29
|
+
export interface ClusterSlotType {
|
|
30
|
+
hub: UInt64Type
|
|
31
|
+
gx: number
|
|
32
|
+
gy: number
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
export interface ShipLike {
|
|
27
36
|
coordinates: ServerContract.Types.coordinates
|
|
28
37
|
hullmass?: UInt32
|
|
29
38
|
energy?: UInt16
|
|
30
39
|
engines?: ServerContract.Types.movement_stats
|
|
31
40
|
generator?: ServerContract.Types.energy_stats
|
|
32
|
-
|
|
41
|
+
loader_lanes?: ServerContract.Types.loader_lane[]
|
|
33
42
|
hauler?: ServerContract.Types.hauler_stats
|
|
34
43
|
capacity?: UInt32
|
|
35
44
|
}
|
|
@@ -49,11 +58,22 @@ export enum TaskType {
|
|
|
49
58
|
WARP = 6,
|
|
50
59
|
CRAFT = 7,
|
|
51
60
|
DEPLOY = 8,
|
|
52
|
-
|
|
61
|
+
TRANSIT = 9,
|
|
53
62
|
UNWRAP = 10,
|
|
54
63
|
UNDEPLOY = 11,
|
|
55
|
-
WRAP_ENTITY = 12,
|
|
56
64
|
DEMOLISH = 13,
|
|
65
|
+
CLAIMPLOT = 14,
|
|
66
|
+
BUILDPLOT = 15,
|
|
67
|
+
CHARGE = 16,
|
|
68
|
+
UPGRADE = 17,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export enum HoldKind {
|
|
72
|
+
PULL = 1,
|
|
73
|
+
PUSH = 2,
|
|
74
|
+
GATHER = 3,
|
|
75
|
+
BUILD = 4,
|
|
76
|
+
UPGRADE = 6,
|
|
57
77
|
}
|
|
58
78
|
|
|
59
79
|
export enum LocationType {
|
|
@@ -61,6 +81,7 @@ export enum LocationType {
|
|
|
61
81
|
PLANET = 1,
|
|
62
82
|
ASTEROID = 2,
|
|
63
83
|
NEBULA = 3,
|
|
84
|
+
ICE_FIELD = 4,
|
|
64
85
|
}
|
|
65
86
|
|
|
66
87
|
export enum TaskCancelable {
|
|
@@ -69,14 +90,6 @@ export enum TaskCancelable {
|
|
|
69
90
|
ALWAYS = 2,
|
|
70
91
|
}
|
|
71
92
|
|
|
72
|
-
export const EntityType = {
|
|
73
|
-
SHIP: Name.from('ship'),
|
|
74
|
-
WAREHOUSE: Name.from('warehouse'),
|
|
75
|
-
CONTAINER: Name.from('container'),
|
|
76
|
-
} as const
|
|
77
|
-
|
|
78
|
-
export type EntityTypeName = (typeof EntityType)[keyof typeof EntityType]
|
|
79
|
-
|
|
80
93
|
export type CoordinatesType =
|
|
81
94
|
| Coordinates
|
|
82
95
|
| ServerContract.Types.coordinates
|
|
@@ -125,8 +138,10 @@ export type ModuleType =
|
|
|
125
138
|
| 'launcher'
|
|
126
139
|
| 'storage'
|
|
127
140
|
| 'hauler'
|
|
141
|
+
| 'battery'
|
|
142
|
+
| 'catcher'
|
|
128
143
|
|
|
129
|
-
export const
|
|
144
|
+
export const RESOURCE_TIER_ADJECTIVES: Record<number, string> = {
|
|
130
145
|
1: 'Crude',
|
|
131
146
|
2: 'Dense',
|
|
132
147
|
3: 'Pure',
|
|
@@ -139,6 +154,9 @@ export const TIER_ADJECTIVES: Record<number, string> = {
|
|
|
139
154
|
10: 'Ascendant',
|
|
140
155
|
}
|
|
141
156
|
|
|
157
|
+
export const COMPONENT_TIER_PREFIXES: Record<number, string> = {}
|
|
158
|
+
export const MODULE_TIER_PREFIXES: Record<number, string> = {}
|
|
159
|
+
|
|
142
160
|
export const CATEGORY_LABELS: Record<ResourceCategory, string> = {
|
|
143
161
|
ore: 'Ore',
|
|
144
162
|
crystal: 'Crystal',
|
|
@@ -162,3 +180,7 @@ export interface Item {
|
|
|
162
180
|
export function formatTier(tier: number): string {
|
|
163
181
|
return 'T' + tier
|
|
164
182
|
}
|
|
183
|
+
|
|
184
|
+
export function tierAdjective(tier: number): string {
|
|
185
|
+
return RESOURCE_TIER_ADJECTIVES[tier] ?? `T${tier}`
|
|
186
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {describe, expect, test} from 'bun:test'
|
|
2
|
+
import {cargoRef} from './cargo'
|
|
3
|
+
|
|
4
|
+
describe('cargoRef', () => {
|
|
5
|
+
test('forwards entity_id when provided', () => {
|
|
6
|
+
const ref = cargoRef({item_id: 10201, stats: 196849n, modules: [], entity_id: 42n})
|
|
7
|
+
expect(ref.entity_id).toBe(42n)
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test('omits entity_id when absent', () => {
|
|
11
|
+
const ref = cargoRef({item_id: 10201, stats: 196849n})
|
|
12
|
+
expect(ref.entity_id).toBeUndefined()
|
|
13
|
+
})
|
|
14
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type {ServerContract} from '../contracts'
|
|
2
|
+
|
|
3
|
+
export function cargoRef(src: {
|
|
4
|
+
item_id: number
|
|
5
|
+
stats: bigint | number
|
|
6
|
+
modules?: ServerContract.Types.module_entry[]
|
|
7
|
+
entity_id?: bigint | number
|
|
8
|
+
}): ServerContract.ActionParams.Type.cargo_ref {
|
|
9
|
+
return {
|
|
10
|
+
item_id: src.item_id,
|
|
11
|
+
stats: src.stats,
|
|
12
|
+
modules: src.modules ?? [],
|
|
13
|
+
entity_id: src.entity_id,
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function cargoItem(
|
|
18
|
+
src: {
|
|
19
|
+
item_id: number
|
|
20
|
+
stats: bigint | number
|
|
21
|
+
modules?: ServerContract.Types.module_entry[]
|
|
22
|
+
},
|
|
23
|
+
quantity: bigint | number
|
|
24
|
+
): ServerContract.ActionParams.Type.cargo_item {
|
|
25
|
+
return {
|
|
26
|
+
...cargoRef(src),
|
|
27
|
+
quantity,
|
|
28
|
+
}
|
|
29
|
+
}
|