@shipload/sdk 1.0.0-next.7 → 1.0.0-next.8
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 +42 -13
- package/lib/shipload.js +157 -1
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +153 -2
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -1
- package/src/index-module.ts +9 -0
- package/src/scheduling/predict-cargo.ts +151 -0
- package/src/travel/travel.ts +3 -1
- package/src/types/entity-traits.ts +38 -0
- package/src/types.ts +2 -0
- package/src/utils/system.ts +7 -0
package/package.json
CHANGED
package/src/index-module.ts
CHANGED
|
@@ -71,6 +71,7 @@ export {
|
|
|
71
71
|
getLocationType,
|
|
72
72
|
getLocationTypeName,
|
|
73
73
|
isGatherableLocation,
|
|
74
|
+
isLocationBuildable,
|
|
74
75
|
deriveLocationStatic,
|
|
75
76
|
deriveLocation,
|
|
76
77
|
} from './utils/system'
|
|
@@ -179,8 +180,16 @@ export type {
|
|
|
179
180
|
ProjectionOptions,
|
|
180
181
|
} from './scheduling/projection'
|
|
181
182
|
|
|
183
|
+
export {predictTaskCargoEffects} from './scheduling/predict-cargo'
|
|
184
|
+
export type {
|
|
185
|
+
PredictedCargoAddition,
|
|
186
|
+
PredictedCargoTarget,
|
|
187
|
+
TaskCargoEffect,
|
|
188
|
+
} from './scheduling/predict-cargo'
|
|
189
|
+
|
|
182
190
|
export * from './types/capabilities'
|
|
183
191
|
export * from './types/entity'
|
|
192
|
+
export {EntityClass, getEntityClass, getPackedEntityType} from './types/entity-traits'
|
|
184
193
|
export * from './capabilities'
|
|
185
194
|
|
|
186
195
|
export {
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type {ServerContract} from '../contracts'
|
|
2
|
+
import {TaskType} from '../types'
|
|
3
|
+
|
|
4
|
+
export type PredictedCargoTarget = {kind: 'existing'; rowId: bigint} | {kind: 'new'; label: string}
|
|
5
|
+
|
|
6
|
+
export interface PredictedCargoAddition {
|
|
7
|
+
item_id: number
|
|
8
|
+
stats: bigint
|
|
9
|
+
modules: ServerContract.Types.module_entry[]
|
|
10
|
+
quantity: number
|
|
11
|
+
target: PredictedCargoTarget
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface TaskCargoEffect {
|
|
15
|
+
additions: PredictedCargoAddition[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface StackState {
|
|
19
|
+
item_id: number
|
|
20
|
+
stats: bigint
|
|
21
|
+
modules: ServerContract.Types.module_entry[]
|
|
22
|
+
quantity: number
|
|
23
|
+
target: PredictedCargoTarget
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function modulesEqual(
|
|
27
|
+
a: ServerContract.Types.module_entry[],
|
|
28
|
+
b: ServerContract.Types.module_entry[]
|
|
29
|
+
): boolean {
|
|
30
|
+
if (a.length !== b.length) return false
|
|
31
|
+
for (let i = 0; i < a.length; i++) {
|
|
32
|
+
const ai = a[i]
|
|
33
|
+
const bi = b[i]
|
|
34
|
+
if (Number(ai.type) !== Number(bi.type)) return false
|
|
35
|
+
const aInst = ai.installed
|
|
36
|
+
const bInst = bi.installed
|
|
37
|
+
if (!aInst && !bInst) continue
|
|
38
|
+
if (!aInst || !bInst) return false
|
|
39
|
+
if (Number(aInst.item_id) !== Number(bInst.item_id)) return false
|
|
40
|
+
if (BigInt(aInst.stats.toString()) !== BigInt(bInst.stats.toString())) return false
|
|
41
|
+
}
|
|
42
|
+
return true
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function findStack(
|
|
46
|
+
state: StackState[],
|
|
47
|
+
item_id: number,
|
|
48
|
+
stats: bigint,
|
|
49
|
+
modules: ServerContract.Types.module_entry[]
|
|
50
|
+
): number {
|
|
51
|
+
for (let i = 0; i < state.length; i++) {
|
|
52
|
+
const s = state[i]
|
|
53
|
+
if (s.item_id !== item_id) continue
|
|
54
|
+
if (s.stats !== stats) continue
|
|
55
|
+
if (!modulesEqual(s.modules, modules)) continue
|
|
56
|
+
return i
|
|
57
|
+
}
|
|
58
|
+
return -1
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function applyAddition(
|
|
62
|
+
state: StackState[],
|
|
63
|
+
item: ServerContract.Types.cargo_item,
|
|
64
|
+
nextNewLabel: () => string
|
|
65
|
+
): PredictedCargoAddition {
|
|
66
|
+
const item_id = Number(item.item_id)
|
|
67
|
+
const stats = BigInt(item.stats.toString())
|
|
68
|
+
const modules = item.modules ?? []
|
|
69
|
+
const quantity = Number(item.quantity)
|
|
70
|
+
|
|
71
|
+
const idx = findStack(state, item_id, stats, modules)
|
|
72
|
+
if (idx === -1) {
|
|
73
|
+
const target: PredictedCargoTarget = {kind: 'new', label: nextNewLabel()}
|
|
74
|
+
state.push({item_id, stats, modules, quantity, target})
|
|
75
|
+
return {item_id, stats, modules, quantity, target}
|
|
76
|
+
}
|
|
77
|
+
state[idx].quantity += quantity
|
|
78
|
+
return {item_id, stats, modules, quantity, target: state[idx].target}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function applyRemoval(state: StackState[], item: ServerContract.Types.cargo_item): void {
|
|
82
|
+
const item_id = Number(item.item_id)
|
|
83
|
+
const stats = BigInt(item.stats.toString())
|
|
84
|
+
const modules = item.modules ?? []
|
|
85
|
+
const quantity = Number(item.quantity)
|
|
86
|
+
|
|
87
|
+
const idx = findStack(state, item_id, stats, modules)
|
|
88
|
+
if (idx === -1) return
|
|
89
|
+
state[idx].quantity -= quantity
|
|
90
|
+
if (state[idx].quantity <= 0) state.splice(idx, 1)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function predictTaskCargoEffects(
|
|
94
|
+
cargo: readonly ServerContract.Types.cargo_view[],
|
|
95
|
+
tasks: readonly ServerContract.Types.task[]
|
|
96
|
+
): TaskCargoEffect[] {
|
|
97
|
+
const state: StackState[] = cargo.map((c) => ({
|
|
98
|
+
item_id: Number(c.item_id),
|
|
99
|
+
stats: BigInt(c.stats.toString()),
|
|
100
|
+
modules: c.modules ?? [],
|
|
101
|
+
quantity: Number(c.quantity),
|
|
102
|
+
target: {kind: 'existing', rowId: BigInt(c.id.toString())},
|
|
103
|
+
}))
|
|
104
|
+
|
|
105
|
+
let newCounter = 0
|
|
106
|
+
const nextNewLabel = () => {
|
|
107
|
+
newCounter += 1
|
|
108
|
+
return `new#${newCounter}`
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const effects: TaskCargoEffect[] = []
|
|
112
|
+
|
|
113
|
+
for (const task of tasks) {
|
|
114
|
+
const type = Number(task.type)
|
|
115
|
+
const items = task.cargo ?? []
|
|
116
|
+
const additions: PredictedCargoAddition[] = []
|
|
117
|
+
|
|
118
|
+
switch (type) {
|
|
119
|
+
case TaskType.LOAD:
|
|
120
|
+
case TaskType.UNWRAP: {
|
|
121
|
+
for (const item of items) additions.push(applyAddition(state, item, nextNewLabel))
|
|
122
|
+
break
|
|
123
|
+
}
|
|
124
|
+
case TaskType.GATHER: {
|
|
125
|
+
if (!task.entitytarget) {
|
|
126
|
+
for (const item of items)
|
|
127
|
+
additions.push(applyAddition(state, item, nextNewLabel))
|
|
128
|
+
}
|
|
129
|
+
break
|
|
130
|
+
}
|
|
131
|
+
case TaskType.UNLOAD:
|
|
132
|
+
case TaskType.WRAP: {
|
|
133
|
+
for (const item of items) applyRemoval(state, item)
|
|
134
|
+
break
|
|
135
|
+
}
|
|
136
|
+
case TaskType.CRAFT: {
|
|
137
|
+
if (items.length > 0) {
|
|
138
|
+
for (let i = 0; i < items.length - 1; i++) applyRemoval(state, items[i])
|
|
139
|
+
additions.push(applyAddition(state, items[items.length - 1], nextNewLabel))
|
|
140
|
+
}
|
|
141
|
+
break
|
|
142
|
+
}
|
|
143
|
+
default:
|
|
144
|
+
break
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
effects.push({additions})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return effects
|
|
151
|
+
}
|
package/src/travel/travel.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
type Distance,
|
|
29
29
|
MAX_ORBITAL_ALTITUDE,
|
|
30
30
|
MIN_ORBITAL_ALTITUDE,
|
|
31
|
+
MIN_TRANSFER_DISTANCE,
|
|
31
32
|
PRECISION,
|
|
32
33
|
type ShipLike,
|
|
33
34
|
TaskType,
|
|
@@ -547,7 +548,8 @@ export function calc_transfer_duration(
|
|
|
547
548
|
: (source.location.z?.toNumber() ?? 0)
|
|
548
549
|
const destZ =
|
|
549
550
|
typeof dest.location.z === 'number' ? dest.location.z : (dest.location.z?.toNumber() ?? 0)
|
|
550
|
-
const
|
|
551
|
+
const rawDistance = Math.abs(sourceZ - destZ)
|
|
552
|
+
const distance = rawDistance < MIN_TRANSFER_DISTANCE ? MIN_TRANSFER_DISTANCE : rawDistance
|
|
551
553
|
|
|
552
554
|
const totalMass = cargoMass + totalLoaderMass
|
|
553
555
|
const acceleration = calc_acceleration(totalThrust, totalMass)
|
|
@@ -1,9 +1,47 @@
|
|
|
1
1
|
import {Name} from '@wharfkit/antelope'
|
|
2
|
+
import {
|
|
3
|
+
ITEM_CONTAINER_T1_PACKED,
|
|
4
|
+
ITEM_CONTAINER_T2_PACKED,
|
|
5
|
+
ITEM_SHIP_T1_PACKED,
|
|
6
|
+
ITEM_WAREHOUSE_T1_PACKED,
|
|
7
|
+
} from '../data/item-ids'
|
|
2
8
|
|
|
3
9
|
export const ENTITY_SHIP = Name.from('ship')
|
|
4
10
|
export const ENTITY_WAREHOUSE = Name.from('warehouse')
|
|
5
11
|
export const ENTITY_CONTAINER = Name.from('container')
|
|
6
12
|
|
|
13
|
+
export enum EntityClass {
|
|
14
|
+
OrbitalVessel = 0,
|
|
15
|
+
PlanetaryStructure = 1,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getEntityClass(entityType: Name | EntityTypeName): EntityClass {
|
|
19
|
+
const typeName = typeof entityType === 'string' ? entityType : entityType.toString()
|
|
20
|
+
switch (typeName) {
|
|
21
|
+
case 'ship':
|
|
22
|
+
case 'container':
|
|
23
|
+
return EntityClass.OrbitalVessel
|
|
24
|
+
case 'warehouse':
|
|
25
|
+
return EntityClass.PlanetaryStructure
|
|
26
|
+
default:
|
|
27
|
+
throw new Error(`Entity type has no class: ${typeName}`)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function getPackedEntityType(itemId: number): Name | null {
|
|
32
|
+
switch (itemId) {
|
|
33
|
+
case ITEM_SHIP_T1_PACKED:
|
|
34
|
+
return ENTITY_SHIP
|
|
35
|
+
case ITEM_CONTAINER_T1_PACKED:
|
|
36
|
+
case ITEM_CONTAINER_T2_PACKED:
|
|
37
|
+
return ENTITY_CONTAINER
|
|
38
|
+
case ITEM_WAREHOUSE_T1_PACKED:
|
|
39
|
+
return ENTITY_WAREHOUSE
|
|
40
|
+
default:
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
7
45
|
export type EntityTypeName = 'ship' | 'warehouse' | 'container'
|
|
8
46
|
|
|
9
47
|
export interface EntityTraits {
|
package/src/types.ts
CHANGED
package/src/utils/system.ts
CHANGED
|
@@ -150,6 +150,13 @@ export function deriveLocationStatic(
|
|
|
150
150
|
return loc
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
export function isLocationBuildable(
|
|
154
|
+
gameSeed: Checksum256Type,
|
|
155
|
+
coordinates: CoordinatesType
|
|
156
|
+
): boolean {
|
|
157
|
+
return getLocationType(gameSeed, coordinates) === LocationType.PLANET
|
|
158
|
+
}
|
|
159
|
+
|
|
153
160
|
export function deriveLocation(
|
|
154
161
|
gameSeed: Checksum256Type,
|
|
155
162
|
coordinates: CoordinatesType
|