@shipload/sdk 2.0.0-rc2 → 2.0.0-rc21
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/README.md +1 -349
- package/lib/shipload.d.ts +1729 -1127
- package/lib/shipload.js +7944 -3165
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +7487 -2840
- package/lib/shipload.m.js.map +1 -1
- package/package.json +6 -4
- package/src/capabilities/crafting.ts +22 -0
- package/src/capabilities/gathering.ts +36 -0
- package/src/capabilities/guards.ts +3 -8
- package/src/capabilities/hauling.ts +22 -0
- package/src/capabilities/index.ts +4 -1
- package/src/capabilities/modules.ts +86 -0
- package/src/capabilities/storage.ts +101 -9
- package/src/contracts/server.ts +785 -293
- package/src/data/capabilities.ts +408 -0
- package/src/data/categories.ts +55 -0
- package/src/data/colors.ts +71 -0
- package/src/data/entities.json +50 -0
- package/src/data/item-ids.ts +75 -0
- package/src/data/items.json +252 -0
- package/src/data/locations.ts +53 -0
- package/src/data/metadata.ts +208 -0
- package/src/data/nebula-adjectives.json +211 -0
- package/src/data/nebula-nouns.json +151 -0
- package/src/data/recipes-runtime.ts +65 -0
- package/src/data/recipes.json +878 -0
- package/src/data/syllables.json +1386 -780
- package/src/data/tiers.ts +45 -0
- package/src/derivation/crafting.ts +348 -0
- package/src/derivation/index.ts +30 -0
- package/src/derivation/location-size.ts +15 -0
- package/src/derivation/resources.ts +112 -0
- package/src/derivation/stats.ts +146 -0
- package/src/derivation/stratum.ts +134 -0
- package/src/derivation/tiers.ts +54 -0
- package/src/entities/cargo-utils.ts +10 -68
- package/src/entities/container.ts +37 -0
- package/src/entities/entity-inventory.ts +13 -13
- package/src/entities/inventory-accessor.ts +2 -6
- package/src/entities/location.ts +5 -200
- package/src/entities/makers.ts +144 -17
- package/src/entities/player.ts +1 -274
- package/src/entities/ship-deploy.ts +258 -0
- package/src/entities/ship.ts +28 -34
- package/src/entities/warehouse.ts +35 -7
- package/src/errors.ts +59 -5
- package/src/format.ts +12 -0
- package/src/index-module.ts +188 -50
- package/src/managers/actions.ts +138 -88
- package/src/managers/context.ts +19 -9
- package/src/managers/index.ts +0 -1
- package/src/managers/locations.ts +2 -85
- package/src/market/items.ts +41 -0
- package/src/nft/description.ts +176 -0
- package/src/nft/deserializers.ts +83 -0
- package/src/nft/index.ts +2 -0
- package/src/resolution/describe-module.ts +165 -0
- package/src/resolution/display-name.ts +43 -0
- package/src/resolution/resolve-item.ts +358 -0
- package/src/scheduling/projection.ts +200 -67
- package/src/scheduling/schedule.ts +2 -2
- package/src/shipload.ts +10 -5
- package/src/subscriptions/connection.ts +154 -0
- package/src/subscriptions/debug.ts +17 -0
- package/src/subscriptions/index.ts +5 -0
- package/src/subscriptions/manager.ts +240 -0
- package/src/subscriptions/mappers.ts +28 -0
- package/src/subscriptions/types.ts +143 -0
- package/src/travel/travel.ts +37 -23
- package/src/types/capabilities.ts +11 -14
- package/src/types/entity-traits.ts +3 -4
- package/src/types/entity.ts +9 -6
- package/src/types.ts +72 -72
- package/src/utils/system.ts +66 -53
- package/src/capabilities/extraction.ts +0 -37
- package/src/data/goods.json +0 -23
- package/src/managers/trades.ts +0 -119
- package/src/market/goods.ts +0 -31
- package/src/market/market.ts +0 -208
- package/src/market/rolls.ts +0 -8
- package/src/trading/collect.ts +0 -938
- package/src/trading/deal.ts +0 -207
- package/src/trading/trade.ts +0 -203
package/src/types.ts
CHANGED
|
@@ -1,68 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Int64Type,
|
|
3
|
-
Name,
|
|
4
|
-
Struct,
|
|
5
|
-
UInt16,
|
|
6
|
-
UInt16Type,
|
|
7
|
-
UInt32,
|
|
8
|
-
UInt32Type,
|
|
9
|
-
UInt64,
|
|
10
|
-
} from '@wharfkit/antelope'
|
|
1
|
+
import {Int64Type, Name, UInt16, UInt16Type, UInt32, UInt32Type, UInt64} from '@wharfkit/antelope'
|
|
11
2
|
import {ServerContract} from './contracts'
|
|
12
3
|
|
|
13
4
|
export const PRECISION = 10000
|
|
5
|
+
export const CRAFT_ENERGY_DIVISOR = 150000
|
|
14
6
|
|
|
15
|
-
// Ship constants
|
|
16
|
-
export const INITIAL_SHIP_GENERATOR_CAPACITY = 350
|
|
17
|
-
export const INITIAL_SHIP_DRAIN = 25
|
|
18
|
-
export const INITIAL_SHIP_ENERGY = 350
|
|
19
|
-
export const INITIAL_SHIP_HULLMASS = 100000
|
|
20
|
-
export const INITIAL_SHIP_CAPACITY = 500000
|
|
21
|
-
export const INITIAL_SHIP_Z = 800
|
|
22
|
-
export const INITIAL_SHIP_RECHARGE = 10
|
|
23
|
-
export const INITIAL_SHIP_THRUST = 250
|
|
24
|
-
|
|
25
|
-
// Loader constants
|
|
26
|
-
export const INITIAL_LOADER_MASS = 1000
|
|
27
|
-
export const INITIAL_LOADER_QUANTITY = 1
|
|
28
|
-
export const INITIAL_LOADER_THRUST = 1
|
|
29
|
-
|
|
30
|
-
// Warehouse constants
|
|
31
7
|
export const WAREHOUSE_Z = 500
|
|
32
|
-
export const INITIAL_WAREHOUSE_CAPACITY = 10000000
|
|
33
8
|
|
|
34
|
-
// Container constants
|
|
35
9
|
export const CONTAINER_Z = 300
|
|
36
|
-
export const INITIAL_CONTAINER_HULLMASS = 50000
|
|
37
|
-
export const INITIAL_CONTAINER_CAPACITY = 2000000
|
|
38
10
|
|
|
39
|
-
// Mechanics
|
|
40
11
|
export const TRAVEL_MAX_DURATION = 86400
|
|
41
12
|
|
|
42
|
-
// Altitude limits (for UI/calculations)
|
|
43
13
|
export const MIN_ORBITAL_ALTITUDE = 800
|
|
44
14
|
export const MAX_ORBITAL_ALTITUDE = 3000
|
|
45
15
|
|
|
46
|
-
|
|
47
|
-
export const INITIAL_SHIP_MASS = 500000
|
|
48
|
-
|
|
49
|
-
// Extractor constants
|
|
50
|
-
export const INITIAL_EXTRACTOR_RATE = 700
|
|
51
|
-
export const INITIAL_EXTRACTOR_DRAIN = 2500
|
|
52
|
-
export const INITIAL_EXTRACTOR_EFFICIENCY = 5000
|
|
16
|
+
export const BASE_ORBITAL_MASS = 100000
|
|
53
17
|
|
|
54
18
|
export interface ShipLike {
|
|
55
19
|
coordinates: ServerContract.Types.coordinates
|
|
56
|
-
hullmass
|
|
57
|
-
energy
|
|
58
|
-
engines
|
|
59
|
-
generator
|
|
60
|
-
loaders
|
|
61
|
-
|
|
20
|
+
hullmass?: UInt32
|
|
21
|
+
energy?: UInt16
|
|
22
|
+
engines?: ServerContract.Types.movement_stats
|
|
23
|
+
generator?: ServerContract.Types.energy_stats
|
|
24
|
+
loaders?: ServerContract.Types.loader_stats
|
|
25
|
+
hauler?: ServerContract.Types.hauler_stats
|
|
26
|
+
capacity?: UInt32
|
|
62
27
|
}
|
|
63
28
|
|
|
64
29
|
export interface CargoMassInfo {
|
|
65
|
-
|
|
30
|
+
item_id: UInt16Type
|
|
66
31
|
quantity: UInt32Type
|
|
67
32
|
}
|
|
68
33
|
|
|
@@ -72,7 +37,12 @@ export enum TaskType {
|
|
|
72
37
|
RECHARGE = 2,
|
|
73
38
|
LOAD = 3,
|
|
74
39
|
UNLOAD = 4,
|
|
75
|
-
|
|
40
|
+
GATHER = 5,
|
|
41
|
+
WARP = 6,
|
|
42
|
+
CRAFT = 7,
|
|
43
|
+
DEPLOY = 8,
|
|
44
|
+
WRAP = 9,
|
|
45
|
+
UNWRAP = 10,
|
|
76
46
|
}
|
|
77
47
|
|
|
78
48
|
export enum LocationType {
|
|
@@ -83,9 +53,9 @@ export enum LocationType {
|
|
|
83
53
|
}
|
|
84
54
|
|
|
85
55
|
export enum TaskCancelable {
|
|
86
|
-
NEVER = 0,
|
|
87
|
-
BEFORE_START = 1,
|
|
88
|
-
ALWAYS = 2,
|
|
56
|
+
NEVER = 0,
|
|
57
|
+
BEFORE_START = 1,
|
|
58
|
+
ALWAYS = 2,
|
|
89
59
|
}
|
|
90
60
|
|
|
91
61
|
export const EntityType = {
|
|
@@ -131,28 +101,58 @@ export interface Distance {
|
|
|
131
101
|
distance: UInt16
|
|
132
102
|
}
|
|
133
103
|
|
|
134
|
-
|
|
135
|
-
export
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
104
|
+
export type ItemType = 'resource' | 'component' | 'module' | 'entity'
|
|
105
|
+
export type ResourceCategory = 'ore' | 'crystal' | 'gas' | 'regolith' | 'biomass'
|
|
106
|
+
export type ResourceTier = 't1' | 't2' | 't3' | 't4' | 't5'
|
|
107
|
+
export type ModuleType =
|
|
108
|
+
| 'any'
|
|
109
|
+
| 'engine'
|
|
110
|
+
| 'generator'
|
|
111
|
+
| 'gatherer'
|
|
112
|
+
| 'loader'
|
|
113
|
+
| 'warp'
|
|
114
|
+
| 'crafter'
|
|
115
|
+
| 'launcher'
|
|
116
|
+
| 'storage'
|
|
117
|
+
| 'hauler'
|
|
118
|
+
|
|
119
|
+
export const TIER_ADJECTIVES: Record<number, string> = {
|
|
120
|
+
1: 'Crude',
|
|
121
|
+
2: 'Dense',
|
|
122
|
+
3: 'Pure',
|
|
123
|
+
4: 'Prime',
|
|
124
|
+
5: 'Pristine',
|
|
125
|
+
6: 'Radiant',
|
|
126
|
+
7: 'Exotic',
|
|
127
|
+
8: 'Mythic',
|
|
128
|
+
9: 'Cosmic',
|
|
129
|
+
10: 'Ascendant',
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export const CATEGORY_LABELS: Record<ResourceCategory, string> = {
|
|
133
|
+
ore: 'Ore',
|
|
134
|
+
crystal: 'Crystal',
|
|
135
|
+
gas: 'Gas',
|
|
136
|
+
regolith: 'Regolith',
|
|
137
|
+
biomass: 'Biomass',
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function tierNumber(tier: string): number {
|
|
141
|
+
return Number(String(tier).replace(/^t/i, ''))
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface Item {
|
|
145
|
+
id: number
|
|
146
|
+
name: string
|
|
147
|
+
description: string
|
|
148
|
+
color: string
|
|
149
|
+
mass: number
|
|
150
|
+
type: ItemType
|
|
151
|
+
tier: number
|
|
152
|
+
category?: ResourceCategory
|
|
153
|
+
moduleType?: ModuleType
|
|
146
154
|
}
|
|
147
155
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
@Struct.field(UInt16)
|
|
151
|
-
id!: UInt16
|
|
152
|
-
@Struct.field(Good)
|
|
153
|
-
good!: Good
|
|
154
|
-
@Struct.field(UInt32)
|
|
155
|
-
price!: UInt32
|
|
156
|
-
@Struct.field(UInt16)
|
|
157
|
-
supply!: UInt16
|
|
156
|
+
export function formatTier(tier: number): string {
|
|
157
|
+
return 'T' + tier
|
|
158
158
|
}
|
package/src/utils/system.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {Checksum256, Checksum256Type, UInt8} from '@wharfkit/antelope'
|
|
1
|
+
import {Checksum256, Checksum256Type, Checksum512, UInt8} from '@wharfkit/antelope'
|
|
2
2
|
import {hash512} from './hash'
|
|
3
|
-
import {Coordinates, CoordinatesType, LocationType
|
|
3
|
+
import {Coordinates, CoordinatesType, LocationType} from '../types'
|
|
4
4
|
import {ServerContract} from '../contracts'
|
|
5
|
+
import {deriveLocationSize} from '../derivation/location-size'
|
|
5
6
|
import syllables from '../data/syllables.json'
|
|
7
|
+
import nebulaAdjectives from '../data/nebula-adjectives.json'
|
|
8
|
+
import nebulaNouns from '../data/nebula-nouns.json'
|
|
6
9
|
|
|
7
10
|
const LOCATION_EXISTS_THRESHOLD = 0x10
|
|
8
11
|
const LOCATION_ACTIVE_THRESHOLD = 0x80
|
|
@@ -27,27 +30,72 @@ export function getLocationType(
|
|
|
27
30
|
return LocationType.NEBULA
|
|
28
31
|
}
|
|
29
32
|
|
|
30
|
-
export function
|
|
31
|
-
return locationType
|
|
33
|
+
export function isGatherableLocation(locationType: LocationType): boolean {
|
|
34
|
+
return locationType !== LocationType.EMPTY
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
export function
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
export function getLocationTypeName(type: LocationType): string {
|
|
38
|
+
switch (type) {
|
|
39
|
+
case LocationType.EMPTY:
|
|
40
|
+
return 'Empty'
|
|
41
|
+
case LocationType.PLANET:
|
|
42
|
+
return 'Planet'
|
|
43
|
+
case LocationType.ASTEROID:
|
|
44
|
+
return 'Asteroid'
|
|
45
|
+
case LocationType.NEBULA:
|
|
46
|
+
return 'Nebula'
|
|
38
47
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function uint16(hash: Checksum512, offset: number): number {
|
|
51
|
+
return (hash.array[offset] << 8) | hash.array[offset + 1]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function generatePlanetName(hashResult: Checksum512): string {
|
|
55
|
+
const syllableCount = 2 + (hashResult.array[0] % 2)
|
|
42
56
|
const name: string[] = []
|
|
43
57
|
for (let i = 0; i < syllableCount; i++) {
|
|
44
|
-
const index = hashResult
|
|
58
|
+
const index = uint16(hashResult, 1 + i * 2) % syllables.length
|
|
45
59
|
const syllable = syllables[index]
|
|
46
60
|
name.push(i > 0 ? syllable.toLowerCase() : syllable)
|
|
47
61
|
}
|
|
48
62
|
return name.join('')
|
|
49
63
|
}
|
|
50
64
|
|
|
65
|
+
function generateAsteroidName(hashResult: Checksum512): string {
|
|
66
|
+
const A = 65
|
|
67
|
+
const letter1 = String.fromCharCode(A + (hashResult.array[0] % 26))
|
|
68
|
+
const letter2 = String.fromCharCode(A + (hashResult.array[1] % 26))
|
|
69
|
+
const num = (uint16(hashResult, 2) % 9000) + 1000
|
|
70
|
+
return `${letter1}${letter2}-${num}`
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function generateNebulaName(hashResult: Checksum512): string {
|
|
74
|
+
const adjIdx = uint16(hashResult, 0) % nebulaAdjectives.length
|
|
75
|
+
const nounIdx = uint16(hashResult, 2) % nebulaNouns.length
|
|
76
|
+
return `${nebulaAdjectives[adjIdx]} ${nebulaNouns[nounIdx]}`
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function getSystemName(gameSeed: Checksum256Type, location: CoordinatesType): string {
|
|
80
|
+
const seed = Checksum256.from(gameSeed)
|
|
81
|
+
const locationType = getLocationType(seed, location)
|
|
82
|
+
if (locationType === LocationType.EMPTY) {
|
|
83
|
+
throw new Error("System doesn't exist at location")
|
|
84
|
+
}
|
|
85
|
+
const seedStr = `${location.x}-${location.y}-${locationType}-name`
|
|
86
|
+
const hashResult = hash512(seed, seedStr)
|
|
87
|
+
switch (locationType) {
|
|
88
|
+
case LocationType.PLANET:
|
|
89
|
+
return generatePlanetName(hashResult)
|
|
90
|
+
case LocationType.ASTEROID:
|
|
91
|
+
return generateAsteroidName(hashResult)
|
|
92
|
+
case LocationType.NEBULA:
|
|
93
|
+
return generateNebulaName(hashResult)
|
|
94
|
+
default:
|
|
95
|
+
return generatePlanetName(hashResult)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
51
99
|
export function hasSystem(gameSeed: Checksum256Type, coordinates: CoordinatesType): boolean {
|
|
52
100
|
return getLocationType(gameSeed, coordinates) !== LocationType.EMPTY
|
|
53
101
|
}
|
|
@@ -81,7 +129,9 @@ export function deriveLocationStatic(
|
|
|
81
129
|
loc.type = UInt8.from(LocationType.NEBULA)
|
|
82
130
|
}
|
|
83
131
|
|
|
84
|
-
loc.subtype = UInt8.from(
|
|
132
|
+
loc.subtype = UInt8.from(
|
|
133
|
+
Number(loc.type) === LocationType.PLANET ? hashResult.array[2] % 6 : hashResult.array[2]
|
|
134
|
+
)
|
|
85
135
|
loc.seed0 = UInt8.from(hashResult.array[3])
|
|
86
136
|
loc.seed1 = UInt8.from(hashResult.array[4])
|
|
87
137
|
|
|
@@ -109,47 +159,10 @@ export function deriveLocation(
|
|
|
109
159
|
epochSeed: Checksum256Type,
|
|
110
160
|
coordinates: CoordinatesType
|
|
111
161
|
): ServerContract.Types.location_derived {
|
|
162
|
+
const staticProps = deriveLocationStatic(gameSeed, coordinates)
|
|
112
163
|
return ServerContract.Types.location_derived.from({
|
|
113
|
-
static_props:
|
|
164
|
+
static_props: staticProps,
|
|
114
165
|
epoch_props: deriveLocationEpoch(epochSeed, coordinates),
|
|
166
|
+
size: deriveLocationSize(staticProps),
|
|
115
167
|
})
|
|
116
168
|
}
|
|
117
|
-
|
|
118
|
-
export function deriveLocationMixture(
|
|
119
|
-
location: ServerContract.Types.location_derived,
|
|
120
|
-
epochSeed: Checksum256Type
|
|
121
|
-
): ServerContract.Types.mixture_info {
|
|
122
|
-
const locationType = location.static_props.type.toNumber()
|
|
123
|
-
|
|
124
|
-
if (locationType === LocationType.NEBULA) {
|
|
125
|
-
return ServerContract.Types.mixture_info.from({
|
|
126
|
-
components: [{good_id: 1, purity: PRECISION}],
|
|
127
|
-
})
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (locationType === LocationType.ASTEROID) {
|
|
131
|
-
const seed = Checksum256.from(epochSeed)
|
|
132
|
-
const coords = location.static_props.coords
|
|
133
|
-
const str = `mixture-${coords.x}-${coords.y}`
|
|
134
|
-
const hashResult = hash512(seed, str)
|
|
135
|
-
|
|
136
|
-
const ironPrimary = location.static_props.subtype.toNumber() % 2 === 0
|
|
137
|
-
const purityRange = 0.3
|
|
138
|
-
const purityRoll = hashResult.array[0] / 255
|
|
139
|
-
const primaryPurity = 0.5 + purityRoll * purityRange
|
|
140
|
-
|
|
141
|
-
const primaryId = ironPrimary ? 26 : 29
|
|
142
|
-
const secondaryId = ironPrimary ? 29 : 26
|
|
143
|
-
const primaryAmt = Math.floor(primaryPurity * PRECISION)
|
|
144
|
-
const secondaryAmt = PRECISION - primaryAmt
|
|
145
|
-
|
|
146
|
-
return ServerContract.Types.mixture_info.from({
|
|
147
|
-
components: [
|
|
148
|
-
{good_id: primaryId, purity: primaryAmt},
|
|
149
|
-
{good_id: secondaryId, purity: secondaryAmt},
|
|
150
|
-
],
|
|
151
|
-
})
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return ServerContract.Types.mixture_info.from({components: []})
|
|
155
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import {UInt16, UInt32} from '@wharfkit/antelope'
|
|
2
|
-
import {ServerContract} from '../contracts'
|
|
3
|
-
import {PRECISION} from '../types'
|
|
4
|
-
|
|
5
|
-
function calc_load_time_internal(
|
|
6
|
-
loaders: ServerContract.Types.loader_stats,
|
|
7
|
-
shipZ: number,
|
|
8
|
-
cargoMass: number
|
|
9
|
-
): number {
|
|
10
|
-
if (cargoMass === 0 || loaders.quantity.toNumber() === 0 || loaders.thrust.toNumber() === 0) {
|
|
11
|
-
return 0
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const totalMass = cargoMass + loaders.mass.toNumber()
|
|
15
|
-
const acceleration = (loaders.thrust.toNumber() / totalMass) * PRECISION
|
|
16
|
-
const flightTime = Math.floor(2 * Math.sqrt(shipZ / acceleration))
|
|
17
|
-
return Math.floor(flightTime / loaders.quantity.toNumber())
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function calc_extraction_duration(
|
|
21
|
-
extractor: ServerContract.Types.extractor_stats,
|
|
22
|
-
loaders: ServerContract.Types.loader_stats,
|
|
23
|
-
shipZ: number,
|
|
24
|
-
batchMass: number
|
|
25
|
-
): UInt32 {
|
|
26
|
-
const extractionTime = Math.floor(batchMass / extractor.rate.toNumber())
|
|
27
|
-
const loadingTime = calc_load_time_internal(loaders, shipZ, batchMass)
|
|
28
|
-
return UInt32.from(Math.max(extractionTime, loadingTime))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function calc_extraction_energy(
|
|
32
|
-
extractor: ServerContract.Types.extractor_stats,
|
|
33
|
-
duration: number
|
|
34
|
-
): UInt16 {
|
|
35
|
-
const energy = Math.floor((duration * extractor.drain.toNumber()) / PRECISION)
|
|
36
|
-
return UInt16.from(energy)
|
|
37
|
-
}
|
package/src/data/goods.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": 1,
|
|
4
|
-
"name": "Hydrogen",
|
|
5
|
-
"description": "A lightweight fuel source essential for interstellar travel.",
|
|
6
|
-
"base_price": 50,
|
|
7
|
-
"mass": 15000
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
"id": 26,
|
|
11
|
-
"name": "Iron",
|
|
12
|
-
"description": "A versatile metal used in construction and manufacturing.",
|
|
13
|
-
"base_price": 125,
|
|
14
|
-
"mass": 40000
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"id": 29,
|
|
18
|
-
"name": "Copper",
|
|
19
|
-
"description": "A conductive metal vital for electronics and wiring.",
|
|
20
|
-
"base_price": 200,
|
|
21
|
-
"mass": 60000
|
|
22
|
-
}
|
|
23
|
-
]
|
package/src/managers/trades.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import {UInt64} from '@wharfkit/antelope'
|
|
2
|
-
import {BaseManager} from './base'
|
|
3
|
-
import {Ship} from '../entities/ship'
|
|
4
|
-
import {Deal, findDealsForShip, FindDealsOptions} from '../trading/deal'
|
|
5
|
-
import {
|
|
6
|
-
analyzeCollectOptions,
|
|
7
|
-
CollectAnalysis,
|
|
8
|
-
CollectAnalysisCallbacks,
|
|
9
|
-
CollectAnalysisOptions,
|
|
10
|
-
} from '../trading/collect'
|
|
11
|
-
import {Coordinates, GoodPrice} from '../types'
|
|
12
|
-
import {Location, toLocation} from '../entities/location'
|
|
13
|
-
import {findNearbyPlanets} from '../travel/travel'
|
|
14
|
-
import {getCurrentEpoch} from '../scheduling/epoch'
|
|
15
|
-
|
|
16
|
-
export class TradesManager extends BaseManager {
|
|
17
|
-
private priceCache = new Map<string, GoodPrice[]>()
|
|
18
|
-
private priceCacheEpoch: UInt64 | undefined
|
|
19
|
-
|
|
20
|
-
private makePriceCacheKey(location: Coordinates): string {
|
|
21
|
-
return `${location.x},${location.y}`
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
private async createCallbacks(): Promise<CollectAnalysisCallbacks> {
|
|
25
|
-
const game = await this.getGame()
|
|
26
|
-
const serverState = await this.getState()
|
|
27
|
-
const currentEpoch = getCurrentEpoch(game)
|
|
28
|
-
|
|
29
|
-
if (!this.priceCacheEpoch || !this.priceCacheEpoch.equals(currentEpoch)) {
|
|
30
|
-
this.priceCache.clear()
|
|
31
|
-
this.priceCacheEpoch = currentEpoch
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const getNearbyLocations = async (
|
|
35
|
-
origin: Coordinates,
|
|
36
|
-
maxDistance: number
|
|
37
|
-
): Promise<Location[]> => {
|
|
38
|
-
const nearby = findNearbyPlanets(game.config.seed, origin, maxDistance)
|
|
39
|
-
return nearby.map((d) => toLocation(d.destination))
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const getMarketPrices = async (location: Coordinates): Promise<GoodPrice[]> => {
|
|
43
|
-
const cacheKey = this.makePriceCacheKey(location)
|
|
44
|
-
const cached = this.priceCache.get(cacheKey)
|
|
45
|
-
if (cached) {
|
|
46
|
-
return cached
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const locationWithSupply = await this.context.locations.getLocationComplete(location)
|
|
50
|
-
const prices = locationWithSupply.marketPrices || []
|
|
51
|
-
|
|
52
|
-
const result = prices.map((price) => {
|
|
53
|
-
const actualSupply = locationWithSupply.getSupply(price.id)
|
|
54
|
-
|
|
55
|
-
if (actualSupply !== undefined) {
|
|
56
|
-
return GoodPrice.from({
|
|
57
|
-
id: price.id,
|
|
58
|
-
good: price.good,
|
|
59
|
-
price: price.price,
|
|
60
|
-
supply: actualSupply,
|
|
61
|
-
})
|
|
62
|
-
}
|
|
63
|
-
return price
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
this.priceCache.set(cacheKey, result)
|
|
67
|
-
return result
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const getGameSeed = () => game.config.seed
|
|
71
|
-
const getState = () => serverState
|
|
72
|
-
|
|
73
|
-
return {getNearbyLocations, getMarketPrices, getGameSeed, getState}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
clearPriceCache(): void {
|
|
77
|
-
this.priceCache.clear()
|
|
78
|
-
this.priceCacheEpoch = undefined
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
async findDeals(
|
|
82
|
-
ship: Ship,
|
|
83
|
-
originLocation?: Coordinates,
|
|
84
|
-
options: FindDealsOptions = {}
|
|
85
|
-
): Promise<Deal[]> {
|
|
86
|
-
const origin = originLocation || Coordinates.from(ship.coordinates)
|
|
87
|
-
const callbacks = await this.createCallbacks()
|
|
88
|
-
|
|
89
|
-
const deals = await findDealsForShip(
|
|
90
|
-
ship,
|
|
91
|
-
origin,
|
|
92
|
-
callbacks.getNearbyLocations,
|
|
93
|
-
callbacks.getMarketPrices,
|
|
94
|
-
options
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
return deals
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async findBestDeal(
|
|
101
|
-
ship: Ship,
|
|
102
|
-
originLocation?: Coordinates,
|
|
103
|
-
options: FindDealsOptions = {}
|
|
104
|
-
): Promise<Deal | undefined> {
|
|
105
|
-
const deals = await this.findDeals(ship, originLocation, {...options, maxDeals: 1})
|
|
106
|
-
return deals[0]
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async getCollectOptions(
|
|
110
|
-
ship: Ship,
|
|
111
|
-
arrivedAt?: Coordinates,
|
|
112
|
-
options: CollectAnalysisOptions = {}
|
|
113
|
-
): Promise<CollectAnalysis> {
|
|
114
|
-
const location = arrivedAt || Coordinates.from(ship.coordinates)
|
|
115
|
-
const callbacks = await this.createCallbacks()
|
|
116
|
-
|
|
117
|
-
return analyzeCollectOptions(ship, location, callbacks, options)
|
|
118
|
-
}
|
|
119
|
-
}
|
package/src/market/goods.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import {UInt16, UInt16Type, UInt32} from '@wharfkit/antelope'
|
|
2
|
-
import {Good} from '../types'
|
|
3
|
-
import goodsData from '../data/goods.json'
|
|
4
|
-
|
|
5
|
-
const goods = goodsData as Array<{
|
|
6
|
-
id: number
|
|
7
|
-
name: string
|
|
8
|
-
description: string
|
|
9
|
-
base_price: number
|
|
10
|
-
mass: number
|
|
11
|
-
}>
|
|
12
|
-
|
|
13
|
-
export const goodIds = goods.map((g) => g.id)
|
|
14
|
-
|
|
15
|
-
export function getGood(goodId: UInt16Type): Good {
|
|
16
|
-
const good = goods.find((g) => UInt16.from(goodId).equals(g.id))
|
|
17
|
-
if (!good) {
|
|
18
|
-
throw new Error('Good does not exist')
|
|
19
|
-
}
|
|
20
|
-
return Good.from({
|
|
21
|
-
id: UInt16.from(good.id),
|
|
22
|
-
name: good.name,
|
|
23
|
-
description: good.description,
|
|
24
|
-
base_price: UInt32.from(good.base_price),
|
|
25
|
-
mass: UInt32.from(good.mass),
|
|
26
|
-
})
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function getGoods(): Good[] {
|
|
30
|
-
return goods.map((g) => getGood(g.id))
|
|
31
|
-
}
|