@shipload/sdk 1.0.0-next.11 → 1.0.0-next.13
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 +779 -984
- package/lib/shipload.js +2203 -2738
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +2186 -2712
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +713 -0
- package/lib/testing.js +3065 -0
- package/lib/testing.js.map +1 -0
- package/lib/testing.m.js +3059 -0
- package/lib/testing.m.js.map +1 -0
- package/package.json +14 -1
- package/src/data/kind-registry.json +78 -0
- package/src/data/kind-registry.ts +133 -0
- package/src/derivation/capabilities.ts +397 -0
- package/src/derivation/crafting.ts +1 -1
- package/src/entities/entity.ts +98 -0
- package/src/entities/makers.ts +75 -228
- package/src/index-module.ts +30 -34
- package/src/managers/entities.ts +18 -114
- package/src/managers/index.ts +1 -1
- package/src/nft/atomicdata.ts +2 -0
- package/src/nft/description.ts +1 -1
- package/src/resolution/resolve-item.ts +3 -2
- package/src/subscriptions/manager.ts +2 -5
- package/src/subscriptions/mappers.ts +3 -12
- 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/types/index.ts +0 -1
- package/src/types.ts +0 -9
- package/src/entities/container.ts +0 -123
- package/src/entities/extractor.ts +0 -144
- package/src/entities/factory.ts +0 -135
- package/src/entities/nexus.ts +0 -29
- package/src/entities/ship-deploy.ts +0 -316
- package/src/entities/ship.ts +0 -221
- package/src/entities/warehouse.ts +0 -136
- package/src/types/entity-traits.ts +0 -171
|
@@ -26,8 +26,9 @@ import {
|
|
|
26
26
|
computeLoaderCapabilities,
|
|
27
27
|
computeShipHullCapabilities,
|
|
28
28
|
computeWarehouseHullCapabilities,
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
computeContainerCapabilities,
|
|
30
|
+
computeContainerT2Capabilities,
|
|
31
|
+
} from '../derivation/capabilities'
|
|
31
32
|
import {
|
|
32
33
|
categoryColors,
|
|
33
34
|
categoryIcons,
|
|
@@ -13,13 +13,10 @@ import type {
|
|
|
13
13
|
WireEntity,
|
|
14
14
|
} from './types'
|
|
15
15
|
import {mapEntity, parseWireEntity} from './mappers'
|
|
16
|
-
import type {
|
|
17
|
-
import type {Warehouse} from '../entities/warehouse'
|
|
18
|
-
import type {Container} from '../entities/container'
|
|
19
|
-
import type {Nexus} from '../entities/nexus'
|
|
16
|
+
import type {Entity} from '../entities/entity'
|
|
20
17
|
|
|
21
18
|
export type SubscriptionEntityType = 'ship' | 'warehouse' | 'container' | 'nexus'
|
|
22
|
-
export type EntityInstance =
|
|
19
|
+
export type EntityInstance = Entity
|
|
23
20
|
|
|
24
21
|
export interface SubscriptionsOptions {
|
|
25
22
|
url: string
|
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import {ServerContract} from '../contracts'
|
|
2
|
-
import {
|
|
3
|
-
import {Warehouse} from '../entities/warehouse'
|
|
4
|
-
import {Container} from '../entities/container'
|
|
5
|
-
import {Nexus} from '../entities/nexus'
|
|
2
|
+
import {Entity} from '../entities/entity'
|
|
6
3
|
import type {WireEntity} from './types'
|
|
7
4
|
|
|
8
|
-
export function mapEntity(
|
|
9
|
-
ei
|
|
10
|
-
): Ship | Warehouse | Container | Nexus {
|
|
11
|
-
if (ei.type.equals('ship')) return new Ship(ei)
|
|
12
|
-
if (ei.type.equals('warehouse')) return new Warehouse(ei)
|
|
13
|
-
if (ei.type.equals('container')) return new Container(ei)
|
|
14
|
-
if (ei.type.equals('nexus')) return new Nexus(ei)
|
|
15
|
-
throw new Error(`mapEntity: unknown entity type ${ei.type.toString()}`)
|
|
5
|
+
export function mapEntity(ei: ServerContract.Types.entity_info): Entity {
|
|
6
|
+
return new Entity(ei)
|
|
16
7
|
}
|
|
17
8
|
|
|
18
9
|
export function parseWireEntity(raw: WireEntity): ServerContract.Types.entity_info {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {createHash} from 'node:crypto'
|
|
2
|
+
import {readFileSync} from 'node:fs'
|
|
3
|
+
|
|
4
|
+
export const CATALOG_FILES_REL = [
|
|
5
|
+
'items.json',
|
|
6
|
+
'recipes.json',
|
|
7
|
+
'entities.json',
|
|
8
|
+
'kind-registry.json',
|
|
9
|
+
'item-ids.ts',
|
|
10
|
+
] as const
|
|
11
|
+
|
|
12
|
+
export function computeCatalogHash(filePaths: ReadonlyArray<string>): string {
|
|
13
|
+
const hash = createHash('sha256')
|
|
14
|
+
for (const p of filePaths) {
|
|
15
|
+
hash.update(readFileSync(p))
|
|
16
|
+
hash.update('\0')
|
|
17
|
+
}
|
|
18
|
+
return hash.digest('hex')
|
|
19
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type {UInt16, UInt32} from '@wharfkit/antelope'
|
|
2
|
+
import type {ServerContract} from '../contracts'
|
|
3
|
+
import type {ProjectedEntity} from '../scheduling/projection'
|
|
4
|
+
import {type CargoStack, cargoItemToStack, mergeStacks} from '../capabilities/storage'
|
|
5
|
+
|
|
6
|
+
export interface ContractProjectedState {
|
|
7
|
+
owner: {toString(): string}
|
|
8
|
+
coordinates: ServerContract.Types.coordinates
|
|
9
|
+
energy?: UInt16
|
|
10
|
+
cargomass: UInt32
|
|
11
|
+
cargo: ServerContract.Types.cargo_view[]
|
|
12
|
+
hullmass?: UInt32
|
|
13
|
+
capacity?: UInt32
|
|
14
|
+
engines?: ServerContract.Types.movement_stats
|
|
15
|
+
loaders?: ServerContract.Types.loader_stats
|
|
16
|
+
generator?: ServerContract.Types.energy_stats
|
|
17
|
+
hauler?: ServerContract.Types.hauler_stats
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ProjectionComparisonOptions {
|
|
21
|
+
step?: number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function assertProjectionEquals(
|
|
25
|
+
contract: ContractProjectedState,
|
|
26
|
+
sdk: ProjectedEntity,
|
|
27
|
+
options: ProjectionComparisonOptions = {}
|
|
28
|
+
): void {
|
|
29
|
+
const mismatches: string[] = []
|
|
30
|
+
|
|
31
|
+
const record = (name: string, c: unknown, s: unknown) => {
|
|
32
|
+
if (c !== s) mismatches.push(` ${name}: contract=${fmt(c)} sdk=${fmt(s)}`)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const recordStatBlock = (name: string, c: unknown, s: unknown) => {
|
|
36
|
+
const cPresent = c !== undefined && c !== null
|
|
37
|
+
const sPresent = s !== undefined && s !== null
|
|
38
|
+
if (cPresent !== sPresent) {
|
|
39
|
+
mismatches.push(
|
|
40
|
+
` ${name}: contract=${cPresent ? 'present' : 'absent'} sdk=${sPresent ? 'present' : 'absent'}`
|
|
41
|
+
)
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
if (!cPresent) return
|
|
45
|
+
const cn = JSON.stringify(normaliseStatBlock(c))
|
|
46
|
+
const sn = JSON.stringify(normaliseStatBlock(s))
|
|
47
|
+
if (cn !== sn) mismatches.push(` ${name}: contract=${cn} sdk=${sn}`)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
record('coordinates.x', toNum(contract.coordinates.x), Number(sdk.location.x))
|
|
51
|
+
record('coordinates.y', toNum(contract.coordinates.y), Number(sdk.location.y))
|
|
52
|
+
record('energy', toNum(contract.energy), Number(sdk.energy))
|
|
53
|
+
record('cargomass', toNum(contract.cargomass), Number(sdk.cargoMass))
|
|
54
|
+
record('hullmass', toNum(contract.hullmass), Number(sdk.shipMass))
|
|
55
|
+
record('capacity', toNum(contract.capacity), sdk.capacity ? Number(sdk.capacity) : undefined)
|
|
56
|
+
|
|
57
|
+
recordStatBlock('engines', contract.engines, sdk.engines)
|
|
58
|
+
recordStatBlock('loaders', contract.loaders, sdk.loaders)
|
|
59
|
+
recordStatBlock('generator', contract.generator, sdk.generator)
|
|
60
|
+
recordStatBlock('hauler', contract.hauler, sdk.hauler)
|
|
61
|
+
|
|
62
|
+
if (contract.cargo.length > 0 || sdk.cargo.length > 0) {
|
|
63
|
+
const contractCargo = normaliseCargo(mergeContractCargo(contract.cargo))
|
|
64
|
+
const sdkCargo = normaliseCargo(sdk.cargo)
|
|
65
|
+
if (contractCargo.length !== sdkCargo.length) {
|
|
66
|
+
mismatches.push(
|
|
67
|
+
` cargo.length: contract=${contractCargo.length} sdk=${sdkCargo.length}`
|
|
68
|
+
)
|
|
69
|
+
} else {
|
|
70
|
+
for (let i = 0; i < contractCargo.length; i++) {
|
|
71
|
+
const c = contractCargo[i]
|
|
72
|
+
const s = sdkCargo[i]
|
|
73
|
+
if (c.itemId !== s.itemId || c.stats !== s.stats || c.quantity !== s.quantity) {
|
|
74
|
+
mismatches.push(
|
|
75
|
+
` cargo[${i}]: contract={item:${c.itemId},stats:${c.stats},qty:${c.quantity}} sdk={item:${s.itemId},stats:${s.stats},qty:${s.quantity}}`
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (mismatches.length > 0) {
|
|
83
|
+
const header =
|
|
84
|
+
options.step !== undefined
|
|
85
|
+
? `projection divergence at step ${options.step}:`
|
|
86
|
+
: 'projection divergence:'
|
|
87
|
+
throw new Error([header, ...mismatches].join('\n'))
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface NormalisedStack {
|
|
92
|
+
itemId: number
|
|
93
|
+
stats: string
|
|
94
|
+
quantity: string
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function mergeContractCargo(cargo: ServerContract.Types.cargo_view[]): CargoStack[] {
|
|
98
|
+
return cargo.reduce<CargoStack[]>(
|
|
99
|
+
(acc, row) =>
|
|
100
|
+
mergeStacks(acc, cargoItemToStack(row as unknown as ServerContract.Types.cargo_item)),
|
|
101
|
+
[]
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function normaliseCargo(cargo: CargoStack[]): NormalisedStack[] {
|
|
106
|
+
return cargo
|
|
107
|
+
.map((s) => ({
|
|
108
|
+
itemId: Number(s.item_id),
|
|
109
|
+
stats: BigInt(s.stats.toString()).toString(),
|
|
110
|
+
quantity: BigInt(s.quantity.toString()).toString(),
|
|
111
|
+
}))
|
|
112
|
+
.sort(stackSort)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function stackSort(a: NormalisedStack, b: NormalisedStack): number {
|
|
116
|
+
if (a.itemId !== b.itemId) return a.itemId - b.itemId
|
|
117
|
+
return a.stats < b.stats ? -1 : a.stats > b.stats ? 1 : 0
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function toNum(v: unknown): number | undefined {
|
|
121
|
+
if (v === undefined || v === null) return undefined
|
|
122
|
+
if (typeof v === 'number') return v
|
|
123
|
+
if (typeof v === 'bigint') return Number(v)
|
|
124
|
+
if (typeof (v as {toNumber?: unknown}).toNumber === 'function') {
|
|
125
|
+
return (v as {toNumber(): number}).toNumber()
|
|
126
|
+
}
|
|
127
|
+
return Number(v as number)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function fmt(v: unknown): string {
|
|
131
|
+
if (v === undefined) return 'undefined'
|
|
132
|
+
if (v === null) return 'null'
|
|
133
|
+
return String(v)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function normaliseStatBlock(block: unknown): Record<string, number> {
|
|
137
|
+
const out: Record<string, number> = {}
|
|
138
|
+
const obj = block as Record<string, unknown>
|
|
139
|
+
for (const k of Object.keys(obj).sort()) {
|
|
140
|
+
out[k] = toNum(obj[k]) ?? 0
|
|
141
|
+
}
|
|
142
|
+
return out
|
|
143
|
+
}
|
package/src/types/index.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type Int64Type,
|
|
3
|
-
Name,
|
|
4
3
|
type UInt16,
|
|
5
4
|
type UInt16Type,
|
|
6
5
|
type UInt32,
|
|
@@ -72,14 +71,6 @@ export enum TaskCancelable {
|
|
|
72
71
|
ALWAYS = 2,
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
export const EntityType = {
|
|
76
|
-
SHIP: Name.from('ship'),
|
|
77
|
-
WAREHOUSE: Name.from('warehouse'),
|
|
78
|
-
CONTAINER: Name.from('container'),
|
|
79
|
-
} as const
|
|
80
|
-
|
|
81
|
-
export type EntityTypeName = (typeof EntityType)[keyof typeof EntityType]
|
|
82
|
-
|
|
83
74
|
export type CoordinatesType =
|
|
84
75
|
| Coordinates
|
|
85
76
|
| ServerContract.Types.coordinates
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import {UInt64, type UInt64Type} from '@wharfkit/antelope'
|
|
2
|
-
import {ServerContract} from '../contracts'
|
|
3
|
-
import type {CoordinatesType} from '../types'
|
|
4
|
-
import {type FloatPosition, getInterpolatedPosition} from '../travel/travel'
|
|
5
|
-
import {Location} from './location'
|
|
6
|
-
import {ScheduleAccessor} from '../scheduling/accessor'
|
|
7
|
-
import * as schedule from '../scheduling/schedule'
|
|
8
|
-
|
|
9
|
-
export interface ContainerStateInput {
|
|
10
|
-
id: UInt64Type
|
|
11
|
-
owner: string
|
|
12
|
-
name: string
|
|
13
|
-
coordinates: CoordinatesType | {x: number; y: number; z?: number}
|
|
14
|
-
hullmass: number
|
|
15
|
-
capacity: number
|
|
16
|
-
cargomass?: number
|
|
17
|
-
cargo?: ServerContract.Types.cargo_item[]
|
|
18
|
-
schedule?: ServerContract.Types.schedule
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export class Container extends ServerContract.Types.entity_info {
|
|
22
|
-
private _sched?: ScheduleAccessor
|
|
23
|
-
|
|
24
|
-
get name(): string {
|
|
25
|
-
return this.entity_name
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get entityClass(): 'orbital' {
|
|
29
|
-
return 'orbital'
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
get canUndeploy(): boolean {
|
|
33
|
-
return true
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
get sched(): ScheduleAccessor {
|
|
37
|
-
this._sched ??= new ScheduleAccessor(this)
|
|
38
|
-
return this._sched
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
get isIdle(): boolean {
|
|
42
|
-
return this.is_idle
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
interpolatedPositionAt(now: Date): FloatPosition {
|
|
46
|
-
const taskIndex = this.sched.currentTaskIndex(now)
|
|
47
|
-
const progress = this.sched.currentTaskProgressFloat(now)
|
|
48
|
-
return getInterpolatedPosition(this, taskIndex, progress)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
isLoading(now: Date): boolean {
|
|
52
|
-
return schedule.isLoading(this, now)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
isUnloading(now: Date): boolean {
|
|
56
|
-
return schedule.isUnloading(this, now)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
get location(): Location {
|
|
60
|
-
return Location.from(this.coordinates)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
get totalMass(): UInt64 {
|
|
64
|
-
return UInt64.from(this.hullmass ?? 0).adding(this.cargomass)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
get maxCapacity(): UInt64 {
|
|
68
|
-
return UInt64.from(this.capacity)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
get availableCapacity(): UInt64 {
|
|
72
|
-
const cargo = UInt64.from(this.cargomass)
|
|
73
|
-
return cargo.gte(this.maxCapacity) ? UInt64.from(0) : this.maxCapacity.subtracting(cargo)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
hasSpace(additionalMass: UInt64): boolean {
|
|
77
|
-
return UInt64.from(this.cargomass).adding(additionalMass).lte(this.maxCapacity)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
get isFull(): boolean {
|
|
81
|
-
return UInt64.from(this.cargomass).gte(this.maxCapacity)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
get orbitalAltitude(): number {
|
|
85
|
-
return this.coordinates.z?.toNumber() || 0
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function computeContainerCapabilities(stats: Record<string, number>): {
|
|
90
|
-
hullmass: number
|
|
91
|
-
capacity: number
|
|
92
|
-
} {
|
|
93
|
-
const density = stats.density
|
|
94
|
-
const strength = stats.strength
|
|
95
|
-
const hardness = stats.hardness
|
|
96
|
-
const saturation = stats.saturation
|
|
97
|
-
|
|
98
|
-
const hullmass = 100000 - 75 * density
|
|
99
|
-
|
|
100
|
-
const statSum = strength + hardness + saturation
|
|
101
|
-
const exponent = statSum / 2997
|
|
102
|
-
const capacity = Math.floor(1000000 * 10 ** exponent)
|
|
103
|
-
|
|
104
|
-
return {hullmass, capacity}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function computeContainerT2Capabilities(stats: Record<string, number>): {
|
|
108
|
-
hullmass: number
|
|
109
|
-
capacity: number
|
|
110
|
-
} {
|
|
111
|
-
const strength = stats.strength
|
|
112
|
-
const density = stats.density
|
|
113
|
-
const hardness = stats.hardness
|
|
114
|
-
const saturation = stats.saturation
|
|
115
|
-
|
|
116
|
-
const hullmass = 70000 - 50 * density
|
|
117
|
-
|
|
118
|
-
const statSum = strength + hardness + saturation
|
|
119
|
-
const exponent = statSum / 2500
|
|
120
|
-
const capacity = Math.floor(1500000 * 10 ** exponent)
|
|
121
|
-
|
|
122
|
-
return {hullmass, capacity}
|
|
123
|
-
}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import {UInt64, type UInt64Type} from '@wharfkit/antelope'
|
|
2
|
-
import {ServerContract} from '../contracts'
|
|
3
|
-
import type {CoordinatesType} from '../types'
|
|
4
|
-
import {Location} from './location'
|
|
5
|
-
import {ScheduleAccessor} from '../scheduling/accessor'
|
|
6
|
-
import {InventoryAccessor} from './inventory-accessor'
|
|
7
|
-
import type {EntityInventory} from './entity-inventory'
|
|
8
|
-
import type {PackedModuleInput} from './ship'
|
|
9
|
-
import {decodeCraftedItemStats} from '../derivation/crafting'
|
|
10
|
-
import {getModuleCapabilityType, MODULE_GATHERER, MODULE_GENERATOR} from '../capabilities/modules'
|
|
11
|
-
import {computeGathererCapabilities, computeGeneratorCapabilities} from './ship-deploy'
|
|
12
|
-
import {applySlotMultiplier, clampUint16, getSlotAmp, type InstalledModule} from './slot-multiplier'
|
|
13
|
-
import type {EntitySlot} from '../data/recipes-runtime'
|
|
14
|
-
import {getItem} from '../data/catalog'
|
|
15
|
-
|
|
16
|
-
export interface ExtractorStateInput {
|
|
17
|
-
id: UInt64Type
|
|
18
|
-
owner: string
|
|
19
|
-
name: string
|
|
20
|
-
coordinates: CoordinatesType | {x: number; y: number; z?: number}
|
|
21
|
-
hullmass?: number
|
|
22
|
-
capacity?: number
|
|
23
|
-
energy?: number
|
|
24
|
-
modules?: PackedModuleInput[]
|
|
25
|
-
schedule?: ServerContract.Types.schedule
|
|
26
|
-
cargo?: ServerContract.Types.cargo_item[]
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export class Extractor extends ServerContract.Types.entity_info {
|
|
30
|
-
private _sched?: ScheduleAccessor
|
|
31
|
-
private _inv?: InventoryAccessor
|
|
32
|
-
|
|
33
|
-
get name(): string {
|
|
34
|
-
return this.entity_name
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
get entityClass(): 'planetary' {
|
|
38
|
-
return 'planetary'
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
get canDemolish(): boolean {
|
|
42
|
-
return true
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
get inv(): InventoryAccessor {
|
|
46
|
-
this._inv ??= new InventoryAccessor(this)
|
|
47
|
-
return this._inv
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get inventory(): EntityInventory[] {
|
|
51
|
-
return this.inv.items
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
get sched(): ScheduleAccessor {
|
|
55
|
-
this._sched ??= new ScheduleAccessor(this)
|
|
56
|
-
return this._sched
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
get isIdle(): boolean {
|
|
60
|
-
return this.is_idle
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
get location(): Location {
|
|
64
|
-
return Location.from(this.coordinates)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
get totalCargoMass(): UInt64 {
|
|
68
|
-
return this.inv.totalMass
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
get maxCapacity(): UInt64 {
|
|
72
|
-
return UInt64.from(this.capacity)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
get availableCapacity(): UInt64 {
|
|
76
|
-
const cargo = this.totalCargoMass
|
|
77
|
-
return cargo.gte(this.maxCapacity) ? UInt64.from(0) : this.maxCapacity.subtracting(cargo)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
get isFull(): boolean {
|
|
81
|
-
return this.totalCargoMass.gte(this.maxCapacity)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
get totalMass(): UInt64 {
|
|
85
|
-
const hull = this.hullmass ? UInt64.from(this.hullmass) : UInt64.from(0)
|
|
86
|
-
return hull.adding(this.totalCargoMass)
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export interface ExtractorCapabilities {
|
|
91
|
-
generator?: {capacity: number; recharge: number}
|
|
92
|
-
gatherer?: {yield: number; drain: number; depth: number; speed: number}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export function computeExtractorCapabilities(
|
|
96
|
-
modules: InstalledModule[],
|
|
97
|
-
layout: EntitySlot[]
|
|
98
|
-
): ExtractorCapabilities {
|
|
99
|
-
const out: ExtractorCapabilities = {}
|
|
100
|
-
|
|
101
|
-
const genModules = modules.filter((m) => getModuleCapabilityType(m.itemId) === MODULE_GENERATOR)
|
|
102
|
-
if (genModules.length > 0) {
|
|
103
|
-
let totalCapacity = 0
|
|
104
|
-
let totalRecharge = 0
|
|
105
|
-
for (const m of genModules) {
|
|
106
|
-
const caps = computeGeneratorCapabilities(decodeCraftedItemStats(m.itemId, m.stats))
|
|
107
|
-
const amp = getSlotAmp(layout, m.slotIndex)
|
|
108
|
-
totalCapacity += applySlotMultiplier(caps.capacity, amp)
|
|
109
|
-
totalRecharge += applySlotMultiplier(caps.recharge, amp)
|
|
110
|
-
}
|
|
111
|
-
out.generator = {
|
|
112
|
-
capacity: clampUint16(totalCapacity),
|
|
113
|
-
recharge: clampUint16(totalRecharge),
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const gathModules = modules.filter((m) => getModuleCapabilityType(m.itemId) === MODULE_GATHERER)
|
|
118
|
-
if (gathModules.length > 0) {
|
|
119
|
-
let totalYield = 0
|
|
120
|
-
let totalDrain = 0
|
|
121
|
-
let maxDepth = 0
|
|
122
|
-
let totalSpeed = 0
|
|
123
|
-
for (const m of gathModules) {
|
|
124
|
-
const tier = getItem(m.itemId).tier
|
|
125
|
-
const caps = computeGathererCapabilities(
|
|
126
|
-
decodeCraftedItemStats(m.itemId, m.stats),
|
|
127
|
-
tier
|
|
128
|
-
)
|
|
129
|
-
const amp = getSlotAmp(layout, m.slotIndex)
|
|
130
|
-
totalYield += applySlotMultiplier(caps.yield, amp)
|
|
131
|
-
totalDrain += caps.drain
|
|
132
|
-
if (caps.depth > maxDepth) maxDepth = caps.depth
|
|
133
|
-
totalSpeed += applySlotMultiplier(caps.speed, amp)
|
|
134
|
-
}
|
|
135
|
-
out.gatherer = {
|
|
136
|
-
yield: clampUint16(totalYield),
|
|
137
|
-
drain: totalDrain,
|
|
138
|
-
depth: maxDepth,
|
|
139
|
-
speed: clampUint16(totalSpeed),
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return out
|
|
144
|
-
}
|
package/src/entities/factory.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import {UInt64, type UInt64Type} from '@wharfkit/antelope'
|
|
2
|
-
import {ServerContract} from '../contracts'
|
|
3
|
-
import type {CoordinatesType} from '../types'
|
|
4
|
-
import {Location} from './location'
|
|
5
|
-
import {ScheduleAccessor} from '../scheduling/accessor'
|
|
6
|
-
import {InventoryAccessor} from './inventory-accessor'
|
|
7
|
-
import type {EntityInventory} from './entity-inventory'
|
|
8
|
-
import type {PackedModuleInput} from './ship'
|
|
9
|
-
import {decodeCraftedItemStats} from '../derivation/crafting'
|
|
10
|
-
import {getModuleCapabilityType, MODULE_CRAFTER, MODULE_GENERATOR} from '../capabilities/modules'
|
|
11
|
-
import {computeCrafterCapabilities, computeGeneratorCapabilities} from './ship-deploy'
|
|
12
|
-
import {applySlotMultiplier, clampUint16, getSlotAmp, type InstalledModule} from './slot-multiplier'
|
|
13
|
-
import type {EntitySlot} from '../data/recipes-runtime'
|
|
14
|
-
|
|
15
|
-
export interface FactoryStateInput {
|
|
16
|
-
id: UInt64Type
|
|
17
|
-
owner: string
|
|
18
|
-
name: string
|
|
19
|
-
coordinates: CoordinatesType | {x: number; y: number; z?: number}
|
|
20
|
-
hullmass?: number
|
|
21
|
-
capacity?: number
|
|
22
|
-
energy?: number
|
|
23
|
-
modules?: PackedModuleInput[]
|
|
24
|
-
schedule?: ServerContract.Types.schedule
|
|
25
|
-
cargo?: ServerContract.Types.cargo_item[]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export class Factory extends ServerContract.Types.entity_info {
|
|
29
|
-
private _sched?: ScheduleAccessor
|
|
30
|
-
private _inv?: InventoryAccessor
|
|
31
|
-
|
|
32
|
-
get name(): string {
|
|
33
|
-
return this.entity_name
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
get entityClass(): 'planetary' {
|
|
37
|
-
return 'planetary'
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
get canDemolish(): boolean {
|
|
41
|
-
return true
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
get inv(): InventoryAccessor {
|
|
45
|
-
this._inv ??= new InventoryAccessor(this)
|
|
46
|
-
return this._inv
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
get inventory(): EntityInventory[] {
|
|
50
|
-
return this.inv.items
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
get sched(): ScheduleAccessor {
|
|
54
|
-
this._sched ??= new ScheduleAccessor(this)
|
|
55
|
-
return this._sched
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
get isIdle(): boolean {
|
|
59
|
-
return this.is_idle
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
get location(): Location {
|
|
63
|
-
return Location.from(this.coordinates)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
get totalCargoMass(): UInt64 {
|
|
67
|
-
return this.inv.totalMass
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
get maxCapacity(): UInt64 {
|
|
71
|
-
return UInt64.from(this.capacity)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
get availableCapacity(): UInt64 {
|
|
75
|
-
const cargo = this.totalCargoMass
|
|
76
|
-
return cargo.gte(this.maxCapacity) ? UInt64.from(0) : this.maxCapacity.subtracting(cargo)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
get isFull(): boolean {
|
|
80
|
-
return this.totalCargoMass.gte(this.maxCapacity)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
get totalMass(): UInt64 {
|
|
84
|
-
const hull = this.hullmass ? UInt64.from(this.hullmass) : UInt64.from(0)
|
|
85
|
-
return hull.adding(this.totalCargoMass)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export interface FactoryCapabilities {
|
|
90
|
-
generator?: {capacity: number; recharge: number}
|
|
91
|
-
crafter?: {speed: number; drain: number}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function computeFactoryCapabilities(
|
|
95
|
-
modules: InstalledModule[],
|
|
96
|
-
layout: EntitySlot[]
|
|
97
|
-
): FactoryCapabilities {
|
|
98
|
-
const out: FactoryCapabilities = {}
|
|
99
|
-
|
|
100
|
-
const genModules = modules.filter((m) => getModuleCapabilityType(m.itemId) === MODULE_GENERATOR)
|
|
101
|
-
if (genModules.length > 0) {
|
|
102
|
-
let totalCapacity = 0
|
|
103
|
-
let totalRecharge = 0
|
|
104
|
-
for (const m of genModules) {
|
|
105
|
-
const caps = computeGeneratorCapabilities(decodeCraftedItemStats(m.itemId, m.stats))
|
|
106
|
-
const amp = getSlotAmp(layout, m.slotIndex)
|
|
107
|
-
totalCapacity += applySlotMultiplier(caps.capacity, amp)
|
|
108
|
-
totalRecharge += applySlotMultiplier(caps.recharge, amp)
|
|
109
|
-
}
|
|
110
|
-
out.generator = {
|
|
111
|
-
capacity: clampUint16(totalCapacity),
|
|
112
|
-
recharge: clampUint16(totalRecharge),
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const crafterModules = modules.filter(
|
|
117
|
-
(m) => getModuleCapabilityType(m.itemId) === MODULE_CRAFTER
|
|
118
|
-
)
|
|
119
|
-
if (crafterModules.length > 0) {
|
|
120
|
-
let totalSpeed = 0
|
|
121
|
-
let totalDrain = 0
|
|
122
|
-
for (const m of crafterModules) {
|
|
123
|
-
const caps = computeCrafterCapabilities(decodeCraftedItemStats(m.itemId, m.stats))
|
|
124
|
-
const amp = getSlotAmp(layout, m.slotIndex)
|
|
125
|
-
totalSpeed += applySlotMultiplier(caps.speed, amp)
|
|
126
|
-
totalDrain += caps.drain
|
|
127
|
-
}
|
|
128
|
-
out.crafter = {
|
|
129
|
-
speed: clampUint16(totalSpeed),
|
|
130
|
-
drain: totalDrain,
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return out
|
|
135
|
-
}
|
package/src/entities/nexus.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type {UInt64Type} from '@wharfkit/antelope'
|
|
2
|
-
import {ServerContract} from '../contracts'
|
|
3
|
-
import type {CoordinatesType} from '../types'
|
|
4
|
-
import {Location} from './location'
|
|
5
|
-
|
|
6
|
-
export interface NexusStateInput {
|
|
7
|
-
id: UInt64Type
|
|
8
|
-
owner: string
|
|
9
|
-
name: string
|
|
10
|
-
coordinates: CoordinatesType | {x: number; y: number; z?: number}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class Nexus extends ServerContract.Types.entity_info {
|
|
14
|
-
get name(): string {
|
|
15
|
-
return this.entity_name
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
get entityClass(): 'orbital' {
|
|
19
|
-
return 'orbital'
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
get location(): Location {
|
|
23
|
-
return Location.from(this.coordinates)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
get orbitalAltitude(): number {
|
|
27
|
-
return this.coordinates.z?.toNumber() || 0
|
|
28
|
-
}
|
|
29
|
-
}
|