@shipload/sdk 1.0.0-next.4 → 1.0.0-next.6
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 +197 -92
- package/lib/shipload.js +672 -64
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +664 -64
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -1
- package/src/contracts/server.ts +54 -1
- package/src/data/colors.ts +1 -0
- package/src/data/items.json +245 -0
- package/src/data/metadata.ts +44 -1
- package/src/derivation/index.ts +1 -0
- package/src/derivation/resources.ts +116 -37
- package/src/entities/container.ts +15 -0
- package/src/entities/ship-deploy.ts +42 -6
- package/src/entities/ship.ts +17 -0
- package/src/entities/warehouse.ts +8 -0
- package/src/index-module.ts +24 -15
- package/src/managers/actions.ts +24 -1
- package/src/nft/description.ts +21 -2
- package/src/resolution/resolve-item.ts +9 -5
- package/src/scheduling/accessor.ts +4 -0
- package/src/scheduling/projection.ts +8 -0
- package/src/scheduling/schedule.ts +15 -1
- package/src/subscriptions/manager.ts +37 -1
- package/src/travel/travel.ts +58 -1
- package/src/types.ts +4 -0
- package/src/utils/system.ts +21 -8
package/src/data/metadata.ts
CHANGED
|
@@ -11,7 +11,7 @@ export interface EntityMetadata {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export const itemMetadata: Record<number, ItemMetadata> = {
|
|
14
|
-
// === Resources
|
|
14
|
+
// === Resources / Ore ===
|
|
15
15
|
101: {name: 'Ore', description: 'Crude metallic ore.', color: '#C26D3F'},
|
|
16
16
|
102: {name: 'Ore', description: 'Refined metallic ore with improved purity.', color: '#C26D3F'},
|
|
17
17
|
103: {
|
|
@@ -19,6 +19,15 @@ export const itemMetadata: Record<number, ItemMetadata> = {
|
|
|
19
19
|
description: 'High-grade metallic ore with exceptional density.',
|
|
20
20
|
color: '#C26D3F',
|
|
21
21
|
},
|
|
22
|
+
104: {name: 'Ore', description: '', color: '#C26D3F'},
|
|
23
|
+
105: {name: 'Ore', description: '', color: '#C26D3F'},
|
|
24
|
+
106: {name: 'Ore', description: '', color: '#C26D3F'},
|
|
25
|
+
107: {name: 'Ore', description: '', color: '#C26D3F'},
|
|
26
|
+
108: {name: 'Ore', description: '', color: '#C26D3F'},
|
|
27
|
+
109: {name: 'Ore', description: '', color: '#C26D3F'},
|
|
28
|
+
110: {name: 'Ore', description: '', color: '#C26D3F'},
|
|
29
|
+
|
|
30
|
+
// === Resources / Crystal ===
|
|
22
31
|
201: {name: 'Crystal', description: 'Raw resonant crystal.', color: '#4ADBFF'},
|
|
23
32
|
202: {
|
|
24
33
|
name: 'Crystal',
|
|
@@ -30,6 +39,15 @@ export const itemMetadata: Record<number, ItemMetadata> = {
|
|
|
30
39
|
description: 'High-grade resonant crystal with exceptional purity.',
|
|
31
40
|
color: '#4ADBFF',
|
|
32
41
|
},
|
|
42
|
+
204: {name: 'Crystal', description: '', color: '#4ADBFF'},
|
|
43
|
+
205: {name: 'Crystal', description: '', color: '#4ADBFF'},
|
|
44
|
+
206: {name: 'Crystal', description: '', color: '#4ADBFF'},
|
|
45
|
+
207: {name: 'Crystal', description: '', color: '#4ADBFF'},
|
|
46
|
+
208: {name: 'Crystal', description: '', color: '#4ADBFF'},
|
|
47
|
+
209: {name: 'Crystal', description: '', color: '#4ADBFF'},
|
|
48
|
+
210: {name: 'Crystal', description: '', color: '#4ADBFF'},
|
|
49
|
+
|
|
50
|
+
// === Resources / Gas ===
|
|
33
51
|
301: {name: 'Gas', description: 'Raw volatile gas.', color: '#B8E4A0'},
|
|
34
52
|
302: {
|
|
35
53
|
name: 'Gas',
|
|
@@ -41,6 +59,15 @@ export const itemMetadata: Record<number, ItemMetadata> = {
|
|
|
41
59
|
description: 'High-grade volatile gas with exceptional energy density.',
|
|
42
60
|
color: '#B8E4A0',
|
|
43
61
|
},
|
|
62
|
+
304: {name: 'Gas', description: '', color: '#B8E4A0'},
|
|
63
|
+
305: {name: 'Gas', description: '', color: '#B8E4A0'},
|
|
64
|
+
306: {name: 'Gas', description: '', color: '#B8E4A0'},
|
|
65
|
+
307: {name: 'Gas', description: '', color: '#B8E4A0'},
|
|
66
|
+
308: {name: 'Gas', description: '', color: '#B8E4A0'},
|
|
67
|
+
309: {name: 'Gas', description: '', color: '#B8E4A0'},
|
|
68
|
+
310: {name: 'Gas', description: '', color: '#B8E4A0'},
|
|
69
|
+
|
|
70
|
+
// === Resources / Regolith ===
|
|
44
71
|
401: {name: 'Regolith', description: 'Crude regolith dust.', color: '#C4A57B'},
|
|
45
72
|
402: {
|
|
46
73
|
name: 'Regolith',
|
|
@@ -52,6 +79,15 @@ export const itemMetadata: Record<number, ItemMetadata> = {
|
|
|
52
79
|
description: 'High-grade regolith with exceptional uniformity.',
|
|
53
80
|
color: '#C4A57B',
|
|
54
81
|
},
|
|
82
|
+
404: {name: 'Regolith', description: '', color: '#C4A57B'},
|
|
83
|
+
405: {name: 'Regolith', description: '', color: '#C4A57B'},
|
|
84
|
+
406: {name: 'Regolith', description: '', color: '#C4A57B'},
|
|
85
|
+
407: {name: 'Regolith', description: '', color: '#C4A57B'},
|
|
86
|
+
408: {name: 'Regolith', description: '', color: '#C4A57B'},
|
|
87
|
+
409: {name: 'Regolith', description: '', color: '#C4A57B'},
|
|
88
|
+
410: {name: 'Regolith', description: '', color: '#C4A57B'},
|
|
89
|
+
|
|
90
|
+
// === Resources / Biomass ===
|
|
55
91
|
501: {name: 'Biomass', description: 'Crude organic biomass.', color: '#5A8B3E'},
|
|
56
92
|
502: {
|
|
57
93
|
name: 'Biomass',
|
|
@@ -63,6 +99,13 @@ export const itemMetadata: Record<number, ItemMetadata> = {
|
|
|
63
99
|
description: 'High-grade biomass with exceptional saturation.',
|
|
64
100
|
color: '#5A8B3E',
|
|
65
101
|
},
|
|
102
|
+
504: {name: 'Biomass', description: '', color: '#5A8B3E'},
|
|
103
|
+
505: {name: 'Biomass', description: '', color: '#5A8B3E'},
|
|
104
|
+
506: {name: 'Biomass', description: '', color: '#5A8B3E'},
|
|
105
|
+
507: {name: 'Biomass', description: '', color: '#5A8B3E'},
|
|
106
|
+
508: {name: 'Biomass', description: '', color: '#5A8B3E'},
|
|
107
|
+
509: {name: 'Biomass', description: '', color: '#5A8B3E'},
|
|
108
|
+
510: {name: 'Biomass', description: '', color: '#5A8B3E'},
|
|
66
109
|
|
|
67
110
|
// === Components (T1) ===
|
|
68
111
|
10001: {
|
package/src/derivation/index.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import {getItem} from '../data/catalog'
|
|
2
|
+
import {LocationType} from '../types'
|
|
2
3
|
|
|
3
4
|
export const DEPTH_THRESHOLD_T1 = 0
|
|
4
|
-
export const DEPTH_THRESHOLD_T2 =
|
|
5
|
-
export const DEPTH_THRESHOLD_T3 =
|
|
6
|
-
export const DEPTH_THRESHOLD_T4 =
|
|
7
|
-
export const DEPTH_THRESHOLD_T5 =
|
|
5
|
+
export const DEPTH_THRESHOLD_T2 = 1500
|
|
6
|
+
export const DEPTH_THRESHOLD_T3 = 5000
|
|
7
|
+
export const DEPTH_THRESHOLD_T4 = 12000
|
|
8
|
+
export const DEPTH_THRESHOLD_T5 = 22000
|
|
9
|
+
export const DEPTH_THRESHOLD_T6 = 32000
|
|
10
|
+
export const DEPTH_THRESHOLD_T7 = 42000
|
|
11
|
+
export const DEPTH_THRESHOLD_T8 = 50000
|
|
12
|
+
export const DEPTH_THRESHOLD_T9 = 57000
|
|
13
|
+
export const DEPTH_THRESHOLD_T10 = 63000
|
|
8
14
|
|
|
9
15
|
export const LOCATION_MIN_DEPTH = 500
|
|
10
16
|
export const LOCATION_MAX_DEPTH = 65535
|
|
@@ -18,19 +24,22 @@ export const PLANET_SUBTYPE_ICY = 3
|
|
|
18
24
|
export const PLANET_SUBTYPE_OCEAN = 4
|
|
19
25
|
export const PLANET_SUBTYPE_INDUSTRIAL = 5
|
|
20
26
|
|
|
27
|
+
const DEPTH_THRESHOLD_TABLE = [
|
|
28
|
+
DEPTH_THRESHOLD_T1,
|
|
29
|
+
DEPTH_THRESHOLD_T2,
|
|
30
|
+
DEPTH_THRESHOLD_T3,
|
|
31
|
+
DEPTH_THRESHOLD_T4,
|
|
32
|
+
DEPTH_THRESHOLD_T5,
|
|
33
|
+
DEPTH_THRESHOLD_T6,
|
|
34
|
+
DEPTH_THRESHOLD_T7,
|
|
35
|
+
DEPTH_THRESHOLD_T8,
|
|
36
|
+
DEPTH_THRESHOLD_T9,
|
|
37
|
+
DEPTH_THRESHOLD_T10,
|
|
38
|
+
]
|
|
39
|
+
|
|
21
40
|
export function getDepthThreshold(tier: number): number {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return DEPTH_THRESHOLD_T1
|
|
25
|
-
case 2:
|
|
26
|
-
return DEPTH_THRESHOLD_T2
|
|
27
|
-
case 3:
|
|
28
|
-
return DEPTH_THRESHOLD_T3
|
|
29
|
-
case 4:
|
|
30
|
-
return DEPTH_THRESHOLD_T4
|
|
31
|
-
default:
|
|
32
|
-
return DEPTH_THRESHOLD_T5
|
|
33
|
-
}
|
|
41
|
+
if (tier < 1 || tier > 10) return 65535
|
|
42
|
+
return DEPTH_THRESHOLD_TABLE[tier - 1]
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
export function getResourceTier(itemId: number): number {
|
|
@@ -46,9 +55,9 @@ export function getResourceWeight(itemId: number, stratum: number): number {
|
|
|
46
55
|
|
|
47
56
|
switch (tier) {
|
|
48
57
|
case 1:
|
|
49
|
-
if (stratum <
|
|
50
|
-
if (stratum <
|
|
51
|
-
if (stratum <
|
|
58
|
+
if (stratum < DEPTH_THRESHOLD_T2) return 100
|
|
59
|
+
if (stratum < DEPTH_THRESHOLD_T3) return 80
|
|
60
|
+
if (stratum < DEPTH_THRESHOLD_T4) return 50
|
|
52
61
|
return 30
|
|
53
62
|
case 2:
|
|
54
63
|
if (depthAbove < 3000) return 40
|
|
@@ -67,37 +76,107 @@ export function getResourceWeight(itemId: number, stratum: number): number {
|
|
|
67
76
|
}
|
|
68
77
|
}
|
|
69
78
|
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const ICY_RESOURCES = [101, 301, 302, 401, 403, 501, 502]
|
|
76
|
-
const OCEAN_RESOURCES = [201, 203, 301, 303, 501, 502, 503]
|
|
77
|
-
const INDUSTRIAL_RESOURCES = [101, 102, 103, 201, 203, 402, 403]
|
|
79
|
+
const RESOURCE_ORE = 0
|
|
80
|
+
const RESOURCE_GAS = 1
|
|
81
|
+
const RESOURCE_REGOLITH = 2
|
|
82
|
+
const RESOURCE_BIOMASS = 3
|
|
83
|
+
const RESOURCE_CRYSTAL = 4
|
|
78
84
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
interface LocationProfileEntry {
|
|
86
|
+
category: number
|
|
87
|
+
maxTier: number
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function categoryBaseId(category: number): number {
|
|
91
|
+
switch (category) {
|
|
92
|
+
case RESOURCE_ORE:
|
|
93
|
+
return 100
|
|
94
|
+
case RESOURCE_CRYSTAL:
|
|
95
|
+
return 200
|
|
96
|
+
case RESOURCE_GAS:
|
|
97
|
+
return 300
|
|
98
|
+
case RESOURCE_REGOLITH:
|
|
99
|
+
return 400
|
|
100
|
+
case RESOURCE_BIOMASS:
|
|
101
|
+
return 500
|
|
102
|
+
default:
|
|
103
|
+
return 0
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function resourceId(category: number, tier: number): number {
|
|
108
|
+
return categoryBaseId(category) + tier
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function getLocationProfile(locationType: number, subtype: number): LocationProfileEntry[] {
|
|
112
|
+
if (locationType === LocationType.ASTEROID) {
|
|
113
|
+
return [
|
|
114
|
+
{category: RESOURCE_ORE, maxTier: 5},
|
|
115
|
+
{category: RESOURCE_CRYSTAL, maxTier: 5},
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
if (locationType === LocationType.NEBULA) {
|
|
119
|
+
return [
|
|
120
|
+
{category: RESOURCE_GAS, maxTier: 5},
|
|
121
|
+
{category: RESOURCE_REGOLITH, maxTier: 5},
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
if (locationType === LocationType.ICE_FIELD) {
|
|
125
|
+
return [
|
|
126
|
+
{category: RESOURCE_GAS, maxTier: 5},
|
|
127
|
+
{category: RESOURCE_BIOMASS, maxTier: 5},
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
if (locationType === LocationType.PLANET) {
|
|
83
131
|
switch (subtype) {
|
|
84
132
|
case PLANET_SUBTYPE_GAS_GIANT:
|
|
85
|
-
return
|
|
133
|
+
return [
|
|
134
|
+
{category: RESOURCE_GAS, maxTier: 10},
|
|
135
|
+
{category: RESOURCE_CRYSTAL, maxTier: 3},
|
|
136
|
+
]
|
|
86
137
|
case PLANET_SUBTYPE_ROCKY:
|
|
87
|
-
return
|
|
138
|
+
return [
|
|
139
|
+
{category: RESOURCE_REGOLITH, maxTier: 10},
|
|
140
|
+
{category: RESOURCE_ORE, maxTier: 3},
|
|
141
|
+
]
|
|
88
142
|
case PLANET_SUBTYPE_TERRESTRIAL:
|
|
89
|
-
return
|
|
143
|
+
return [
|
|
144
|
+
{category: RESOURCE_ORE, maxTier: 10},
|
|
145
|
+
{category: RESOURCE_BIOMASS, maxTier: 3},
|
|
146
|
+
]
|
|
90
147
|
case PLANET_SUBTYPE_ICY:
|
|
91
|
-
return
|
|
148
|
+
return [
|
|
149
|
+
{category: RESOURCE_CRYSTAL, maxTier: 10},
|
|
150
|
+
{category: RESOURCE_REGOLITH, maxTier: 3},
|
|
151
|
+
]
|
|
92
152
|
case PLANET_SUBTYPE_OCEAN:
|
|
93
|
-
return
|
|
153
|
+
return [
|
|
154
|
+
{category: RESOURCE_BIOMASS, maxTier: 10},
|
|
155
|
+
{category: RESOURCE_GAS, maxTier: 3},
|
|
156
|
+
]
|
|
94
157
|
case PLANET_SUBTYPE_INDUSTRIAL:
|
|
95
|
-
return
|
|
158
|
+
return [
|
|
159
|
+
{category: RESOURCE_ORE, maxTier: 3},
|
|
160
|
+
{category: RESOURCE_CRYSTAL, maxTier: 3},
|
|
161
|
+
{category: RESOURCE_REGOLITH, maxTier: 3},
|
|
162
|
+
{category: RESOURCE_BIOMASS, maxTier: 3},
|
|
163
|
+
]
|
|
96
164
|
}
|
|
97
165
|
}
|
|
98
166
|
return []
|
|
99
167
|
}
|
|
100
168
|
|
|
169
|
+
export function getLocationCandidates(locationType: number, subtype: number): number[] {
|
|
170
|
+
const profile = getLocationProfile(locationType, subtype)
|
|
171
|
+
const ids: number[] = []
|
|
172
|
+
for (const {category, maxTier} of profile) {
|
|
173
|
+
for (let tier = 1; tier <= maxTier; tier++) {
|
|
174
|
+
ids.push(resourceId(category, tier))
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return ids
|
|
178
|
+
}
|
|
179
|
+
|
|
101
180
|
export function getEligibleResources(
|
|
102
181
|
locationType: number,
|
|
103
182
|
subtype: number,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {UInt64, type UInt64Type} from '@wharfkit/antelope'
|
|
2
2
|
import {ServerContract} from '../contracts'
|
|
3
3
|
import type {CoordinatesType} from '../types'
|
|
4
|
+
import {type FloatPosition, getInterpolatedPosition} from '../travel/travel'
|
|
4
5
|
import {Location} from './location'
|
|
5
6
|
import {ScheduleAccessor} from '../scheduling/accessor'
|
|
6
7
|
import * as schedule from '../scheduling/schedule'
|
|
@@ -24,6 +25,14 @@ export class Container extends ServerContract.Types.entity_info {
|
|
|
24
25
|
return this.entity_name
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
get entityClass(): 'mobile' {
|
|
29
|
+
return 'mobile'
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get canUndeploy(): boolean {
|
|
33
|
+
return true
|
|
34
|
+
}
|
|
35
|
+
|
|
27
36
|
get sched(): ScheduleAccessor {
|
|
28
37
|
this._sched ??= new ScheduleAccessor(this)
|
|
29
38
|
return this._sched
|
|
@@ -33,6 +42,12 @@ export class Container extends ServerContract.Types.entity_info {
|
|
|
33
42
|
return this.is_idle
|
|
34
43
|
}
|
|
35
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
|
+
|
|
36
51
|
isLoading(now: Date): boolean {
|
|
37
52
|
return schedule.isLoading(this, now)
|
|
38
53
|
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
MODULE_HAULER,
|
|
9
9
|
MODULE_LOADER,
|
|
10
10
|
} from '../capabilities/modules'
|
|
11
|
+
import {getItem} from '../data/catalog'
|
|
11
12
|
|
|
12
13
|
export function computeShipHullCapabilities(stats: Record<string, number>): {
|
|
13
14
|
hullmass: number
|
|
@@ -52,7 +53,38 @@ export function computeGeneratorCapabilities(stats: Record<string, number>): {
|
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
export
|
|
56
|
+
export interface GathererDepthParams {
|
|
57
|
+
readonly floor: number
|
|
58
|
+
readonly slope: number
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const GATHERER_DEPTH_TABLE: readonly GathererDepthParams[] = [
|
|
62
|
+
{floor: 500, slope: 5},
|
|
63
|
+
{floor: 2000, slope: 11},
|
|
64
|
+
{floor: 7000, slope: 16},
|
|
65
|
+
{floor: 15000, slope: 18},
|
|
66
|
+
{floor: 25000, slope: 19},
|
|
67
|
+
{floor: 35000, slope: 16},
|
|
68
|
+
{floor: 46000, slope: 12},
|
|
69
|
+
{floor: 53500, slope: 10},
|
|
70
|
+
{floor: 60000, slope: 5},
|
|
71
|
+
{floor: 63500, slope: 2},
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
export const GATHERER_DEPTH_MAX_TIER = 10
|
|
75
|
+
|
|
76
|
+
export function gathererDepthForTier(tol: number, tier: number): number {
|
|
77
|
+
if (tier < 1 || tier > GATHERER_DEPTH_MAX_TIER) {
|
|
78
|
+
throw new Error(`gatherer tier out of range: ${tier}`)
|
|
79
|
+
}
|
|
80
|
+
const p = GATHERER_DEPTH_TABLE[tier - 1]
|
|
81
|
+
return p.floor + tol * p.slope
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function computeGathererCapabilities(
|
|
85
|
+
stats: Record<string, number>,
|
|
86
|
+
tier: number
|
|
87
|
+
): {
|
|
56
88
|
yield: number
|
|
57
89
|
drain: number
|
|
58
90
|
depth: number
|
|
@@ -66,7 +98,7 @@ export function computeGathererCapabilities(stats: Record<string, number>): {
|
|
|
66
98
|
return {
|
|
67
99
|
yield: 200 + str,
|
|
68
100
|
drain: Math.max(250, 1250 - Math.floor((con * 25) / 20)),
|
|
69
|
-
depth:
|
|
101
|
+
depth: gathererDepthForTier(tol, tier),
|
|
70
102
|
speed: 100 + Math.floor((ref * 4) / 5),
|
|
71
103
|
}
|
|
72
104
|
}
|
|
@@ -197,16 +229,20 @@ export function computeShipCapabilities(
|
|
|
197
229
|
if (gathererModules.length > 0) {
|
|
198
230
|
let totalYield = 0
|
|
199
231
|
let totalDrain = 0
|
|
200
|
-
let
|
|
232
|
+
let maxDepth = 0
|
|
201
233
|
let totalSpeed = 0
|
|
202
234
|
for (const m of gathererModules) {
|
|
203
|
-
const
|
|
235
|
+
const tier = getItem(m.itemId).tier
|
|
236
|
+
const caps = computeGathererCapabilities(
|
|
237
|
+
decodeCraftedItemStats(m.itemId, m.stats),
|
|
238
|
+
tier
|
|
239
|
+
)
|
|
204
240
|
totalYield += caps.yield
|
|
205
241
|
totalDrain += caps.drain
|
|
206
|
-
|
|
242
|
+
if (caps.depth > maxDepth) maxDepth = caps.depth
|
|
207
243
|
totalSpeed += caps.speed
|
|
208
244
|
}
|
|
209
|
-
ship.gatherer = {yield: totalYield, drain: totalDrain, depth:
|
|
245
|
+
ship.gatherer = {yield: totalYield, drain: totalDrain, depth: maxDepth, speed: totalSpeed}
|
|
210
246
|
}
|
|
211
247
|
|
|
212
248
|
const haulerModules = modules.filter((m) => getModuleCapabilityType(m.itemId) === MODULE_HAULER)
|
package/src/entities/ship.ts
CHANGED
|
@@ -2,7 +2,9 @@ import {type UInt16, type UInt16Type, UInt32, UInt64, type UInt64Type} from '@wh
|
|
|
2
2
|
import {ServerContract} from '../contracts'
|
|
3
3
|
import {Coordinates, type CoordinatesType} from '../types'
|
|
4
4
|
import {
|
|
5
|
+
type FloatPosition,
|
|
5
6
|
getDestinationLocation,
|
|
7
|
+
getInterpolatedPosition,
|
|
6
8
|
getPositionAt,
|
|
7
9
|
getFlightOrigin as travelGetFlightOrigin,
|
|
8
10
|
} from '../travel/travel'
|
|
@@ -55,6 +57,14 @@ export class Ship extends ServerContract.Types.entity_info {
|
|
|
55
57
|
return this.entity_name
|
|
56
58
|
}
|
|
57
59
|
|
|
60
|
+
get entityClass(): 'mobile' {
|
|
61
|
+
return 'mobile'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get canUndeploy(): boolean {
|
|
65
|
+
return true
|
|
66
|
+
}
|
|
67
|
+
|
|
58
68
|
get inv(): InventoryAccessor {
|
|
59
69
|
this._inv ??= new InventoryAccessor(this)
|
|
60
70
|
return this._inv
|
|
@@ -87,12 +97,19 @@ export class Ship extends ServerContract.Types.entity_info {
|
|
|
87
97
|
return dest ? Coordinates.from(dest) : undefined
|
|
88
98
|
}
|
|
89
99
|
|
|
100
|
+
/** Chain-tile coordinates at `now`. For smooth visual position use interpolatedPositionAt. */
|
|
90
101
|
positionAt(now: Date): Coordinates {
|
|
91
102
|
const taskIndex = this.sched.currentTaskIndex(now)
|
|
92
103
|
const progress = this.sched.currentTaskProgress(now)
|
|
93
104
|
return Coordinates.from(getPositionAt(this, taskIndex, progress))
|
|
94
105
|
}
|
|
95
106
|
|
|
107
|
+
interpolatedPositionAt(now: Date): FloatPosition {
|
|
108
|
+
const taskIndex = this.sched.currentTaskIndex(now)
|
|
109
|
+
const progress = this.sched.currentTaskProgressFloat(now)
|
|
110
|
+
return getInterpolatedPosition(this, taskIndex, progress)
|
|
111
|
+
}
|
|
112
|
+
|
|
96
113
|
isInFlight(now: Date): boolean {
|
|
97
114
|
return schedule.isInFlight(this, now)
|
|
98
115
|
}
|
|
@@ -31,6 +31,14 @@ export class Warehouse extends ServerContract.Types.entity_info {
|
|
|
31
31
|
return this.entity_name
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
get entityClass(): 'building' {
|
|
35
|
+
return 'building'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get canDemolish(): boolean {
|
|
39
|
+
return true
|
|
40
|
+
}
|
|
41
|
+
|
|
34
42
|
get inv(): InventoryAccessor {
|
|
35
43
|
this._inv ??= new InventoryAccessor(this)
|
|
36
44
|
return this._inv
|
package/src/index-module.ts
CHANGED
|
@@ -86,6 +86,7 @@ export {
|
|
|
86
86
|
getEligibleResources,
|
|
87
87
|
getResourceWeight,
|
|
88
88
|
getLocationCandidates,
|
|
89
|
+
getLocationProfile,
|
|
89
90
|
getDepthThreshold,
|
|
90
91
|
getResourceTier,
|
|
91
92
|
DEPTH_THRESHOLD_T1,
|
|
@@ -117,30 +118,35 @@ export {
|
|
|
117
118
|
distanceBetweenCoordinates,
|
|
118
119
|
distanceBetweenPoints,
|
|
119
120
|
findNearbyPlanets,
|
|
120
|
-
lerp,
|
|
121
|
-
rotation,
|
|
122
|
-
calc_ship_mass,
|
|
123
121
|
calc_acceleration,
|
|
122
|
+
calc_energyusage,
|
|
124
123
|
calc_flighttime,
|
|
125
|
-
calc_ship_flighttime,
|
|
126
|
-
calc_ship_acceleration,
|
|
127
|
-
calc_rechargetime,
|
|
128
|
-
calc_ship_rechargetime,
|
|
129
|
-
calc_loader_flighttime,
|
|
130
124
|
calc_loader_acceleration,
|
|
131
|
-
|
|
125
|
+
calc_loader_flighttime,
|
|
132
126
|
calc_orbital_altitude,
|
|
127
|
+
calc_rechargetime,
|
|
128
|
+
calc_ship_acceleration,
|
|
129
|
+
calc_ship_flighttime,
|
|
130
|
+
calc_ship_mass,
|
|
131
|
+
calc_ship_rechargetime,
|
|
133
132
|
calc_transfer_duration,
|
|
134
|
-
|
|
133
|
+
calculateFlightTime,
|
|
135
134
|
calculateLoadTimeBreakdown,
|
|
136
135
|
calculateRefuelingTime,
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
calculateTransferTime,
|
|
137
|
+
easeFlightProgress,
|
|
139
138
|
estimateDealTravelTime,
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
estimateTravelTime,
|
|
140
|
+
flightSpeedFactor,
|
|
141
|
+
type FloatPosition,
|
|
142
142
|
getDestinationLocation,
|
|
143
|
+
getFlightOrigin,
|
|
144
|
+
getInterpolatedPosition,
|
|
143
145
|
getPositionAt,
|
|
146
|
+
hasEnergyForDistance,
|
|
147
|
+
interpolateFlightPosition,
|
|
148
|
+
lerp,
|
|
149
|
+
rotation,
|
|
144
150
|
} from './travel/travel'
|
|
145
151
|
export type {
|
|
146
152
|
LoadTimeBreakdown,
|
|
@@ -246,8 +252,11 @@ export {
|
|
|
246
252
|
computeWarehouseHullCapabilities,
|
|
247
253
|
computeStorageCapabilities,
|
|
248
254
|
computeShipCapabilities,
|
|
255
|
+
GATHERER_DEPTH_TABLE,
|
|
256
|
+
GATHERER_DEPTH_MAX_TIER,
|
|
257
|
+
gathererDepthForTier,
|
|
249
258
|
} from './entities/ship-deploy'
|
|
250
|
-
export type {ShipCapabilities} from './entities/ship-deploy'
|
|
259
|
+
export type {ShipCapabilities, GathererDepthParams} from './entities/ship-deploy'
|
|
251
260
|
|
|
252
261
|
export {resolveItem} from './resolution/resolve-item'
|
|
253
262
|
export type {
|
package/src/managers/actions.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {type CoordinatesType, EntityType, type EntityTypeName} from '../types'
|
|
|
15
15
|
import {ServerContract} from '../contracts'
|
|
16
16
|
|
|
17
17
|
export type EntityRefInput = {
|
|
18
|
-
entityType:
|
|
18
|
+
entityType: NameType
|
|
19
19
|
entityId: UInt64Type
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -244,6 +244,29 @@ export class ActionsManager extends BaseManager {
|
|
|
244
244
|
})
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
+
undeploy(host: EntityRefInput, target: EntityRefInput): Action {
|
|
248
|
+
return this.server.action('undeploy', {
|
|
249
|
+
host_type: Name.from(host.entityType),
|
|
250
|
+
host_id: UInt64.from(host.entityId),
|
|
251
|
+
target_type: Name.from(target.entityType),
|
|
252
|
+
target_id: UInt64.from(target.entityId),
|
|
253
|
+
})
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
wrapEntity(entity: EntityRefInput): Action {
|
|
257
|
+
return this.server.action('wrapentity', {
|
|
258
|
+
entity_type: Name.from(entity.entityType),
|
|
259
|
+
entity_id: UInt64.from(entity.entityId),
|
|
260
|
+
})
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
demolish(entity: EntityRefInput): Action {
|
|
264
|
+
return this.server.action('demolish', {
|
|
265
|
+
entity_type: Name.from(entity.entityType),
|
|
266
|
+
entity_id: UInt64.from(entity.entityId),
|
|
267
|
+
})
|
|
268
|
+
}
|
|
269
|
+
|
|
247
270
|
joinGame(account: NameType, companyName: string): Action[] {
|
|
248
271
|
return [this.foundCompany(account, companyName), this.join(account)]
|
|
249
272
|
}
|
package/src/nft/description.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
MODULE_ENGINE,
|
|
5
5
|
MODULE_GATHERER,
|
|
6
6
|
MODULE_GENERATOR,
|
|
7
|
+
MODULE_HAULER,
|
|
7
8
|
MODULE_LOADER,
|
|
8
9
|
MODULE_STORAGE,
|
|
9
10
|
MODULE_WARP,
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
ITEM_ENGINE_T1,
|
|
16
17
|
ITEM_GATHERER_T1,
|
|
17
18
|
ITEM_GENERATOR_T1,
|
|
19
|
+
ITEM_HAULER_T1,
|
|
18
20
|
ITEM_LOADER_T1,
|
|
19
21
|
ITEM_SHIP_T1_PACKED,
|
|
20
22
|
ITEM_STORAGE_T1,
|
|
@@ -22,6 +24,8 @@ import {
|
|
|
22
24
|
ITEM_WARP_T1,
|
|
23
25
|
} from '../data/item-ids'
|
|
24
26
|
import {decodeStat} from '../derivation/crafting'
|
|
27
|
+
import {gathererDepthForTier} from '../entities/ship-deploy'
|
|
28
|
+
import {getItem} from '../data/catalog'
|
|
25
29
|
|
|
26
30
|
function idiv(a: number, b: number): number {
|
|
27
31
|
return Math.floor(a / b)
|
|
@@ -49,12 +53,16 @@ export const computeGeneratorRech = (fin: number): number => 1 + idiv(fin * 3, 1
|
|
|
49
53
|
export const computeGathererYield = (str: number): number => 200 + str
|
|
50
54
|
export const computeGathererDrain = (con: number): number =>
|
|
51
55
|
Math.max(250, 1250 - idiv(con * 25, 20))
|
|
52
|
-
export const computeGathererDepth = (tol: number): number =>
|
|
56
|
+
export const computeGathererDepth = (tol: number, tier: number): number =>
|
|
57
|
+
gathererDepthForTier(tol, tier)
|
|
53
58
|
export const computeGathererSpeed = (ref: number): number => 100 + idiv(ref * 4, 5)
|
|
54
59
|
export const computeLoaderMass = (ins: number): number => Math.max(200, 2000 - ins * 2)
|
|
55
60
|
export const computeLoaderThrust = (pla: number): number => 1 + idiv(pla, 500)
|
|
56
61
|
export const computeCrafterSpeed = (rea: number): number => 100 + idiv(rea * 4, 5)
|
|
57
62
|
export const computeCrafterDrain = (fin: number): number => Math.max(5, 30 - idiv(fin, 33))
|
|
63
|
+
export const computeHaulerCapacity = (fin: number): number => Math.max(1, 1 + idiv(fin, 400))
|
|
64
|
+
export const computeHaulerEfficiency = (con: number): number => 2000 + con * 6
|
|
65
|
+
export const computeHaulerDrain = (com: number): number => Math.max(3, 15 - idiv(com, 80))
|
|
58
66
|
export const computeWarpRange = (stat: number): number => 100 + stat * 3
|
|
59
67
|
|
|
60
68
|
export function entityDisplayName(itemId: number): string {
|
|
@@ -86,6 +94,8 @@ export function moduleDisplayName(itemId: number): string {
|
|
|
86
94
|
return 'Crafter'
|
|
87
95
|
case ITEM_STORAGE_T1:
|
|
88
96
|
return 'Storage'
|
|
97
|
+
case ITEM_HAULER_T1:
|
|
98
|
+
return 'Hauler'
|
|
89
99
|
case ITEM_WARP_T1:
|
|
90
100
|
return 'Warp'
|
|
91
101
|
default:
|
|
@@ -121,8 +131,10 @@ export function formatModuleLine(slot: number, itemId: number, stats: bigint): s
|
|
|
121
131
|
const tol = decodeStat(stats, 1)
|
|
122
132
|
const con = decodeStat(stats, 3)
|
|
123
133
|
const ref = decodeStat(stats, 4)
|
|
134
|
+
const tier = getItem(itemId).tier
|
|
124
135
|
out += ` Yield ${computeGathererYield(str)} Depth ${computeGathererDepth(
|
|
125
|
-
tol
|
|
136
|
+
tol,
|
|
137
|
+
tier
|
|
126
138
|
)} Speed ${computeGathererSpeed(ref)} Drain ${computeGathererDrain(con)}`
|
|
127
139
|
break
|
|
128
140
|
}
|
|
@@ -147,6 +159,13 @@ export function formatModuleLine(slot: number, itemId: number, stats: bigint): s
|
|
|
147
159
|
out += ` +${pct}% capacity`
|
|
148
160
|
break
|
|
149
161
|
}
|
|
162
|
+
case MODULE_HAULER: {
|
|
163
|
+
const fin = decodeStat(stats, 0)
|
|
164
|
+
const con = decodeStat(stats, 1)
|
|
165
|
+
const com = decodeStat(stats, 2)
|
|
166
|
+
out += ` Capacity ${computeHaulerCapacity(fin)} Efficiency ${computeHaulerEfficiency(con)} Drain ${computeHaulerDrain(com)}`
|
|
167
|
+
break
|
|
168
|
+
}
|
|
150
169
|
case MODULE_WARP: {
|
|
151
170
|
const stat = decodeStat(stats, 0)
|
|
152
171
|
out += ` Range ${computeWarpRange(stat)}`
|