@shipload/sdk 2.0.0-rc2 → 2.0.0-rc4
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 +319 -137
- package/lib/shipload.js +3253 -1812
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +2657 -1131
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/extraction.ts +14 -21
- package/src/capabilities/storage.ts +2 -2
- package/src/contracts/server.ts +311 -120
- package/src/data/items.json +16 -0
- package/src/data/nebula-adjectives.json +211 -0
- package/src/data/nebula-nouns.json +151 -0
- package/src/data/syllables.json +1386 -780
- package/src/derivation/index.ts +25 -0
- package/src/derivation/location-size.ts +15 -0
- package/src/derivation/resources.ts +141 -0
- package/src/derivation/stratum.ts +118 -0
- package/src/entities/cargo-utils.ts +8 -8
- package/src/entities/entity-inventory.ts +13 -9
- package/src/entities/inventory-accessor.ts +2 -2
- package/src/entities/location.ts +10 -10
- package/src/entities/ship.ts +10 -6
- package/src/entities/warehouse.ts +2 -2
- package/src/errors.ts +4 -4
- package/src/index-module.ts +31 -6
- package/src/managers/actions.ts +21 -9
- package/src/managers/locations.ts +7 -7
- package/src/managers/trades.ts +5 -5
- package/src/market/items.ts +31 -0
- package/src/market/market.ts +9 -9
- package/src/scheduling/projection.ts +7 -7
- package/src/trading/collect.ts +25 -25
- package/src/trading/deal.ts +8 -8
- package/src/trading/trade.ts +9 -9
- package/src/travel/travel.ts +6 -6
- package/src/types.ts +17 -7
- package/src/utils/system.ts +51 -52
- package/src/data/goods.json +0 -23
- package/src/market/goods.ts +0 -31
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export {deriveStratum, deriveResourceStats} from './stratum'
|
|
2
|
+
export type {StratumInfo, ResourceStats} from './stratum'
|
|
3
|
+
export {deriveLocationSize} from './location-size'
|
|
4
|
+
export {
|
|
5
|
+
getEligibleResources,
|
|
6
|
+
getResourceWeight,
|
|
7
|
+
getLocationCandidates,
|
|
8
|
+
getDepthThreshold,
|
|
9
|
+
getResourceRarity,
|
|
10
|
+
depthScaleFactor,
|
|
11
|
+
DEPTH_THRESHOLD_COMMON,
|
|
12
|
+
DEPTH_THRESHOLD_UNCOMMON,
|
|
13
|
+
DEPTH_THRESHOLD_RARE,
|
|
14
|
+
DEPTH_THRESHOLD_EPIC,
|
|
15
|
+
DEPTH_THRESHOLD_LEGENDARY,
|
|
16
|
+
LOCATION_MIN_DEPTH,
|
|
17
|
+
LOCATION_MAX_DEPTH,
|
|
18
|
+
YIELD_THRESHOLD,
|
|
19
|
+
PLANET_SUBTYPE_GAS_GIANT,
|
|
20
|
+
PLANET_SUBTYPE_ROCKY,
|
|
21
|
+
PLANET_SUBTYPE_TERRESTRIAL,
|
|
22
|
+
PLANET_SUBTYPE_ICY,
|
|
23
|
+
PLANET_SUBTYPE_OCEAN,
|
|
24
|
+
PLANET_SUBTYPE_INDUSTRIAL,
|
|
25
|
+
} from './resources'
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {ServerContract} from '../contracts'
|
|
2
|
+
import {LocationType} from '../types'
|
|
3
|
+
import {LOCATION_MAX_DEPTH, LOCATION_MIN_DEPTH} from './resources'
|
|
4
|
+
|
|
5
|
+
export function deriveLocationSize(loc: ServerContract.Types.location_static): number {
|
|
6
|
+
if (loc.type.toNumber() === LocationType.EMPTY) return 0
|
|
7
|
+
|
|
8
|
+
const raw = (loc.seed0.toNumber() << 8) | loc.seed1.toNumber()
|
|
9
|
+
const normalized = raw / 65535
|
|
10
|
+
|
|
11
|
+
const curved = Math.pow(normalized, 3.0)
|
|
12
|
+
|
|
13
|
+
const range = LOCATION_MAX_DEPTH - LOCATION_MIN_DEPTH
|
|
14
|
+
return Math.floor(LOCATION_MIN_DEPTH + curved * range)
|
|
15
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import {ResourceRarity} from '../types'
|
|
2
|
+
|
|
3
|
+
export const DEPTH_THRESHOLD_COMMON = 0
|
|
4
|
+
export const DEPTH_THRESHOLD_UNCOMMON = 2000
|
|
5
|
+
export const DEPTH_THRESHOLD_RARE = 10000
|
|
6
|
+
export const DEPTH_THRESHOLD_EPIC = 30000
|
|
7
|
+
export const DEPTH_THRESHOLD_LEGENDARY = 55000
|
|
8
|
+
|
|
9
|
+
export const LOCATION_MIN_DEPTH = 500
|
|
10
|
+
export const LOCATION_MAX_DEPTH = 65535
|
|
11
|
+
|
|
12
|
+
export const YIELD_THRESHOLD = Math.floor(0.003 * 0xffffffff)
|
|
13
|
+
|
|
14
|
+
export const PLANET_SUBTYPE_GAS_GIANT = 0
|
|
15
|
+
export const PLANET_SUBTYPE_ROCKY = 1
|
|
16
|
+
export const PLANET_SUBTYPE_TERRESTRIAL = 2
|
|
17
|
+
export const PLANET_SUBTYPE_ICY = 3
|
|
18
|
+
export const PLANET_SUBTYPE_OCEAN = 4
|
|
19
|
+
export const PLANET_SUBTYPE_INDUSTRIAL = 5
|
|
20
|
+
|
|
21
|
+
interface ResourceEntry {
|
|
22
|
+
id: number
|
|
23
|
+
rarity: ResourceRarity
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const RESOURCE_CATALOG: ResourceEntry[] = [
|
|
27
|
+
{id: 26, rarity: 'common'},
|
|
28
|
+
{id: 1, rarity: 'common'},
|
|
29
|
+
{id: 14, rarity: 'common'},
|
|
30
|
+
{id: 6, rarity: 'common'},
|
|
31
|
+
{id: 29, rarity: 'uncommon'},
|
|
32
|
+
{id: 2, rarity: 'uncommon'},
|
|
33
|
+
{id: 1000, rarity: 'uncommon'},
|
|
34
|
+
{id: 1003, rarity: 'uncommon'},
|
|
35
|
+
{id: 22, rarity: 'rare'},
|
|
36
|
+
{id: 18, rarity: 'rare'},
|
|
37
|
+
{id: 1001, rarity: 'rare'},
|
|
38
|
+
{id: 1002, rarity: 'rare'},
|
|
39
|
+
{id: 74, rarity: 'epic'},
|
|
40
|
+
{id: 54, rarity: 'epic'},
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
export function getDepthThreshold(rarity: ResourceRarity): number {
|
|
44
|
+
switch (rarity) {
|
|
45
|
+
case 'common':
|
|
46
|
+
return DEPTH_THRESHOLD_COMMON
|
|
47
|
+
case 'uncommon':
|
|
48
|
+
return DEPTH_THRESHOLD_UNCOMMON
|
|
49
|
+
case 'rare':
|
|
50
|
+
return DEPTH_THRESHOLD_RARE
|
|
51
|
+
case 'epic':
|
|
52
|
+
return DEPTH_THRESHOLD_EPIC
|
|
53
|
+
case 'legendary':
|
|
54
|
+
return DEPTH_THRESHOLD_LEGENDARY
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function getResourceRarity(itemId: number): ResourceRarity {
|
|
59
|
+
const entry = RESOURCE_CATALOG.find((r) => r.id === itemId)
|
|
60
|
+
return entry ? entry.rarity : 'legendary'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function getResourceWeight(itemId: number, stratum: number): number {
|
|
64
|
+
const rarity = getResourceRarity(itemId)
|
|
65
|
+
const threshold = getDepthThreshold(rarity)
|
|
66
|
+
if (stratum < threshold) return 0
|
|
67
|
+
|
|
68
|
+
const depthAbove = stratum - threshold
|
|
69
|
+
|
|
70
|
+
switch (rarity) {
|
|
71
|
+
case 'common':
|
|
72
|
+
if (stratum < 2000) return 100
|
|
73
|
+
if (stratum < 10000) return 80
|
|
74
|
+
if (stratum < 30000) return 50
|
|
75
|
+
return 30
|
|
76
|
+
case 'uncommon':
|
|
77
|
+
if (depthAbove < 3000) return 40
|
|
78
|
+
if (depthAbove < 8000) return 60
|
|
79
|
+
return 50
|
|
80
|
+
case 'rare':
|
|
81
|
+
if (depthAbove < 5000) return 20
|
|
82
|
+
if (depthAbove < 15000) return 35
|
|
83
|
+
return 40
|
|
84
|
+
case 'epic':
|
|
85
|
+
if (depthAbove < 10000) return 10
|
|
86
|
+
if (depthAbove < 25000) return 20
|
|
87
|
+
return 30
|
|
88
|
+
case 'legendary':
|
|
89
|
+
return 10
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const ASTEROID_RESOURCES = [26, 29, 22, 74, 14, 1000, 1001]
|
|
94
|
+
const NEBULA_RESOURCES = [1, 2, 18, 54]
|
|
95
|
+
const GAS_GIANT_RESOURCES = [1, 2, 18, 54]
|
|
96
|
+
const ROCKY_RESOURCES = [26, 29, 22, 74, 6, 1003, 1002]
|
|
97
|
+
const TERRESTRIAL_RESOURCES = [6, 1003, 1002, 1001]
|
|
98
|
+
const ICY_RESOURCES = [6, 14, 1000, 1001, 18]
|
|
99
|
+
const OCEAN_RESOURCES = [1, 2, 1003, 1002]
|
|
100
|
+
const INDUSTRIAL_RESOURCES = [26, 29, 22, 74, 14, 1000, 54]
|
|
101
|
+
|
|
102
|
+
export function getLocationCandidates(locationType: number, subtype: number): number[] {
|
|
103
|
+
if (locationType === 2) return ASTEROID_RESOURCES
|
|
104
|
+
if (locationType === 3) return NEBULA_RESOURCES
|
|
105
|
+
if (locationType === 1) {
|
|
106
|
+
switch (subtype) {
|
|
107
|
+
case PLANET_SUBTYPE_GAS_GIANT:
|
|
108
|
+
return GAS_GIANT_RESOURCES
|
|
109
|
+
case PLANET_SUBTYPE_ROCKY:
|
|
110
|
+
return ROCKY_RESOURCES
|
|
111
|
+
case PLANET_SUBTYPE_TERRESTRIAL:
|
|
112
|
+
return TERRESTRIAL_RESOURCES
|
|
113
|
+
case PLANET_SUBTYPE_ICY:
|
|
114
|
+
return ICY_RESOURCES
|
|
115
|
+
case PLANET_SUBTYPE_OCEAN:
|
|
116
|
+
return OCEAN_RESOURCES
|
|
117
|
+
case PLANET_SUBTYPE_INDUSTRIAL:
|
|
118
|
+
return INDUSTRIAL_RESOURCES
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return []
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function getEligibleResources(
|
|
125
|
+
locationType: number,
|
|
126
|
+
subtype: number,
|
|
127
|
+
stratum: number
|
|
128
|
+
): number[] {
|
|
129
|
+
const candidates = getLocationCandidates(locationType, subtype)
|
|
130
|
+
return candidates.filter((itemId) => {
|
|
131
|
+
const rarity = getResourceRarity(itemId)
|
|
132
|
+
const threshold = getDepthThreshold(rarity)
|
|
133
|
+
return stratum >= threshold
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function depthScaleFactor(stratum: number): number {
|
|
138
|
+
if (stratum <= 1) return 1.0
|
|
139
|
+
const logScale = Math.log(stratum) / Math.log(65535)
|
|
140
|
+
return 1.0 + logScale * 2.0
|
|
141
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import {Bytes, Checksum256, Checksum256Type} from '@wharfkit/antelope'
|
|
2
|
+
import {hash512} from '../utils/hash'
|
|
3
|
+
import {Coordinates, CoordinatesType} from '../types'
|
|
4
|
+
import {
|
|
5
|
+
depthScaleFactor,
|
|
6
|
+
getEligibleResources,
|
|
7
|
+
getResourceWeight,
|
|
8
|
+
YIELD_THRESHOLD,
|
|
9
|
+
} from './resources'
|
|
10
|
+
|
|
11
|
+
export interface StratumInfo {
|
|
12
|
+
itemId: number
|
|
13
|
+
seed: bigint
|
|
14
|
+
richness: number
|
|
15
|
+
reserve: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ResourceStats {
|
|
19
|
+
purity: number
|
|
20
|
+
density: number
|
|
21
|
+
reactivity: number
|
|
22
|
+
resonance: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function deriveStratum(
|
|
26
|
+
epochSeed: Checksum256Type,
|
|
27
|
+
coords: CoordinatesType,
|
|
28
|
+
stratum: number,
|
|
29
|
+
locationType: number,
|
|
30
|
+
subtype: number,
|
|
31
|
+
_maxDepth: number
|
|
32
|
+
): StratumInfo {
|
|
33
|
+
const seed = Checksum256.from(epochSeed)
|
|
34
|
+
const c = Coordinates.from(coords)
|
|
35
|
+
const input = `stratum-${c.x}-${c.y}-${stratum}`
|
|
36
|
+
const hashResult = hash512(seed, input)
|
|
37
|
+
const bytes = hashResult.array
|
|
38
|
+
|
|
39
|
+
const rawReserve = ((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]) >>> 0
|
|
40
|
+
|
|
41
|
+
let reserve = 0
|
|
42
|
+
if (rawReserve <= YIELD_THRESHOLD) {
|
|
43
|
+
const baseReserve = (rawReserve % 333) + 1
|
|
44
|
+
const scale = depthScaleFactor(stratum)
|
|
45
|
+
reserve = Math.floor(baseReserve * scale)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (reserve === 0) return {itemId: 0, seed: 0n, richness: 0, reserve: 0}
|
|
49
|
+
|
|
50
|
+
const eligible = getEligibleResources(locationType, subtype, stratum)
|
|
51
|
+
if (eligible.length === 0) return {itemId: 0, seed: 0n, richness: 0, reserve: 0}
|
|
52
|
+
|
|
53
|
+
const resourceRoll = ((bytes[4] << 24) | (bytes[5] << 16) | (bytes[6] << 8) | bytes[7]) >>> 0
|
|
54
|
+
|
|
55
|
+
let totalWeight = 0
|
|
56
|
+
for (const id of eligible) {
|
|
57
|
+
totalWeight += getResourceWeight(id, stratum)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let selectedItemId = eligible[0]
|
|
61
|
+
if (totalWeight > 0) {
|
|
62
|
+
const roll = resourceRoll % totalWeight
|
|
63
|
+
let cumulative = 0
|
|
64
|
+
for (const id of eligible) {
|
|
65
|
+
cumulative += getResourceWeight(id, stratum)
|
|
66
|
+
if (roll < cumulative) {
|
|
67
|
+
selectedItemId = id
|
|
68
|
+
break
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const seedBigInt =
|
|
74
|
+
(BigInt(bytes[8]) << 56n) |
|
|
75
|
+
(BigInt(bytes[9]) << 48n) |
|
|
76
|
+
(BigInt(bytes[10]) << 40n) |
|
|
77
|
+
(BigInt(bytes[11]) << 32n) |
|
|
78
|
+
(BigInt(bytes[12]) << 24n) |
|
|
79
|
+
(BigInt(bytes[13]) << 16n) |
|
|
80
|
+
(BigInt(bytes[14]) << 8n) |
|
|
81
|
+
BigInt(bytes[15])
|
|
82
|
+
|
|
83
|
+
const rawRichness = (bytes[16] << 8) | bytes[17]
|
|
84
|
+
const normalized = rawRichness / 65535
|
|
85
|
+
const baseRichness = Math.floor(normalized * normalized * 999) + 1
|
|
86
|
+
|
|
87
|
+
let depthBonus = 0
|
|
88
|
+
if (stratum > 1) {
|
|
89
|
+
depthBonus = 50 * Math.log(stratum) / Math.log(65535)
|
|
90
|
+
}
|
|
91
|
+
const richness = Math.min(Math.floor(baseRichness + depthBonus), 1000)
|
|
92
|
+
|
|
93
|
+
return {itemId: selectedItemId, seed: seedBigInt, richness, reserve}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function deriveResourceStats(seed: bigint): ResourceStats {
|
|
97
|
+
const seedStr = seed.toString()
|
|
98
|
+
const encoder = new TextEncoder()
|
|
99
|
+
const data = encoder.encode(seedStr)
|
|
100
|
+
const hashResult = Checksum256.hash(Bytes.from(data))
|
|
101
|
+
const hashBytes = hashResult.array
|
|
102
|
+
|
|
103
|
+
const extractU16 = (offset: number): number => (hashBytes[offset] << 8) | hashBytes[offset + 1]
|
|
104
|
+
|
|
105
|
+
const weibullStat = (raw: number): number => {
|
|
106
|
+
const u = raw / 65536
|
|
107
|
+
let x = 0.27 * Math.sqrt(-Math.log(1 - u))
|
|
108
|
+
if (x > 1) x = 1
|
|
109
|
+
return Math.floor(x * 999) + 1
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
purity: weibullStat(extractU16(0)),
|
|
114
|
+
density: weibullStat(extractU16(2)),
|
|
115
|
+
reactivity: weibullStat(extractU16(4)),
|
|
116
|
+
resonance: weibullStat(extractU16(6)),
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -18,11 +18,11 @@ export function cargoValue(cargo: EntityInventory[]): UInt64 {
|
|
|
18
18
|
}, UInt64.from(0))
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export function
|
|
21
|
+
export function getCargoForItem(
|
|
22
22
|
cargo: EntityInventory[],
|
|
23
23
|
goodId: UInt64Type
|
|
24
24
|
): EntityInventory | undefined {
|
|
25
|
-
return cargo.find((c) => c.
|
|
25
|
+
return cargo.find((c) => c.item_id.equals(goodId))
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export function hasSpace(
|
|
@@ -67,7 +67,7 @@ export function calculateSaleValue(
|
|
|
67
67
|
for (const item of cargo) {
|
|
68
68
|
if (UInt32.from(item.quantity).equals(UInt32.from(0))) continue
|
|
69
69
|
|
|
70
|
-
const goodId = Number(item.
|
|
70
|
+
const goodId = Number(item.item_id)
|
|
71
71
|
const salePrice = prices.get(goodId)
|
|
72
72
|
|
|
73
73
|
if (salePrice) {
|
|
@@ -97,7 +97,7 @@ export function calculateSaleValueFromArray(
|
|
|
97
97
|
return calculateSaleValue(cargo, priceMap)
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
export function
|
|
100
|
+
export function afterSellItems(
|
|
101
101
|
cargo: ServerContract.Types.cargo_item[],
|
|
102
102
|
goodsToSell: Array<{goodId: number; quantity: number}>
|
|
103
103
|
): EntityInventory[] {
|
|
@@ -106,7 +106,7 @@ export function afterSellGoods(
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
return cargo.map((item) => {
|
|
109
|
-
const saleItem = goodsToSell.find((s) => Number(item.
|
|
109
|
+
const saleItem = goodsToSell.find((s) => Number(item.item_id) === s.goodId)
|
|
110
110
|
if (!saleItem) {
|
|
111
111
|
return new EntityInventory(item)
|
|
112
112
|
}
|
|
@@ -116,7 +116,7 @@ export function afterSellGoods(
|
|
|
116
116
|
|
|
117
117
|
return new EntityInventory(
|
|
118
118
|
ServerContract.Types.cargo_item.from({
|
|
119
|
-
|
|
119
|
+
item_id: item.item_id,
|
|
120
120
|
quantity: UInt32.from(newQty),
|
|
121
121
|
unit_cost: item.unit_cost,
|
|
122
122
|
})
|
|
@@ -124,7 +124,7 @@ export function afterSellGoods(
|
|
|
124
124
|
})
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
export function
|
|
127
|
+
export function afterSellAllItems(cargo: ServerContract.Types.cargo_item[]): EntityInventory[] {
|
|
128
128
|
if (cargo.length === 0) {
|
|
129
129
|
return []
|
|
130
130
|
}
|
|
@@ -133,7 +133,7 @@ export function afterSellAllGoods(cargo: ServerContract.Types.cargo_item[]): Ent
|
|
|
133
133
|
(item) =>
|
|
134
134
|
new EntityInventory(
|
|
135
135
|
ServerContract.Types.cargo_item.from({
|
|
136
|
-
|
|
136
|
+
item_id: item.item_id,
|
|
137
137
|
quantity: UInt32.from(0),
|
|
138
138
|
unit_cost: item.unit_cost,
|
|
139
139
|
})
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
import {UInt32, UInt64} from '@wharfkit/antelope'
|
|
2
2
|
import {ServerContract} from '../contracts'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import {getItem} from '../market/items'
|
|
4
|
+
import {Item} from '../types'
|
|
5
5
|
|
|
6
6
|
export class EntityInventory extends ServerContract.Types.cargo_item {
|
|
7
|
-
private
|
|
7
|
+
private _item?: Item
|
|
8
8
|
|
|
9
|
-
get
|
|
10
|
-
if (!this.
|
|
11
|
-
this.
|
|
9
|
+
get item(): Item {
|
|
10
|
+
if (!this._item) {
|
|
11
|
+
this._item = getItem(this.item_id)
|
|
12
12
|
}
|
|
13
|
-
return this.
|
|
13
|
+
return this._item
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get good(): Item {
|
|
17
|
+
return this.item
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
get name(): string {
|
|
17
|
-
return this.
|
|
21
|
+
return this.item.name
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
get unitMass(): UInt32 {
|
|
21
|
-
return this.
|
|
25
|
+
return this.item.mass
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
get totalMass(): UInt64 {
|
|
@@ -24,8 +24,8 @@ export class InventoryAccessor {
|
|
|
24
24
|
return this.items.reduce((sum, c) => sum.adding(c.totalCost), UInt64.from(0))
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
return this.items.find((c) => c.
|
|
27
|
+
forItem(goodId: UInt64Type): EntityInventory | undefined {
|
|
28
|
+
return this.items.find((c) => c.item_id.equals(goodId))
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
get sellable(): EntityInventory[] {
|
package/src/entities/location.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {Checksum256, Checksum256Type, UInt16, UInt16Type, UInt64} from '@wharfkit/antelope'
|
|
2
2
|
import {ServerContract} from '../contracts'
|
|
3
|
-
import {Coordinates, CoordinatesType, Distance,
|
|
3
|
+
import {Coordinates, CoordinatesType, Distance, ItemPrice, LocationType} from '../types'
|
|
4
4
|
import {getLocationType, hasSystem, isExtractableLocation} from '../utils/system'
|
|
5
5
|
import {findNearbyPlanets} from '../travel/travel'
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ import {findNearbyPlanets} from '../travel/travel'
|
|
|
10
10
|
*/
|
|
11
11
|
export class Location {
|
|
12
12
|
readonly coordinates: Coordinates
|
|
13
|
-
private _marketPrices?:
|
|
13
|
+
private _marketPrices?: ItemPrice[]
|
|
14
14
|
private _gameSeed?: Checksum256
|
|
15
15
|
private _hasSystem?: boolean
|
|
16
16
|
private _locationRows?: ServerContract.Types.supply_row[]
|
|
@@ -56,21 +56,21 @@ export class Location {
|
|
|
56
56
|
/**
|
|
57
57
|
* Set cached market prices for this location
|
|
58
58
|
*/
|
|
59
|
-
setMarketPrices(prices:
|
|
59
|
+
setMarketPrices(prices: ItemPrice[]): void {
|
|
60
60
|
this._marketPrices = prices
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* Get cached market prices (returns undefined if not cached)
|
|
65
65
|
*/
|
|
66
|
-
get marketPrices():
|
|
66
|
+
get marketPrices(): ItemPrice[] | undefined {
|
|
67
67
|
return this._marketPrices
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* Get price for a specific good (from cache)
|
|
72
72
|
*/
|
|
73
|
-
getPrice(goodId: UInt16Type):
|
|
73
|
+
getPrice(goodId: UInt16Type): ItemPrice | undefined {
|
|
74
74
|
if (!this._marketPrices) return undefined
|
|
75
75
|
return this._marketPrices.find((p) => p.id.equals(goodId))
|
|
76
76
|
}
|
|
@@ -112,7 +112,7 @@ export class Location {
|
|
|
112
112
|
getSupply(goodId: UInt16Type): UInt16 | undefined {
|
|
113
113
|
if (!this._locationRows) return undefined
|
|
114
114
|
const row = this._locationRows.find(
|
|
115
|
-
(r) => r.
|
|
115
|
+
(r) => r.item_id.equals(goodId) && this._epoch && r.epoch.equals(this._epoch)
|
|
116
116
|
)
|
|
117
117
|
return row ? row.supply : undefined
|
|
118
118
|
}
|
|
@@ -199,9 +199,9 @@ export class Location {
|
|
|
199
199
|
: UInt16.from(0)
|
|
200
200
|
: currentSupply.adding(quantityDelta)
|
|
201
201
|
|
|
202
|
-
return
|
|
202
|
+
return ItemPrice.from({
|
|
203
203
|
id: price.id,
|
|
204
|
-
|
|
204
|
+
item: price.item,
|
|
205
205
|
price: price.price,
|
|
206
206
|
supply: newSupply,
|
|
207
207
|
})
|
|
@@ -213,7 +213,7 @@ export class Location {
|
|
|
213
213
|
// Copy location rows if cached
|
|
214
214
|
if (this._locationRows && this._epoch) {
|
|
215
215
|
newLocation._locationRows = this._locationRows.map((row) => {
|
|
216
|
-
if (row.
|
|
216
|
+
if (row.item_id.equals(goodId) && row.epoch.equals(this._epoch!)) {
|
|
217
217
|
const currentSupply = UInt16.from(row.supply)
|
|
218
218
|
const delta = UInt16.from(Math.abs(quantityDelta))
|
|
219
219
|
const newSupply =
|
|
@@ -227,7 +227,7 @@ export class Location {
|
|
|
227
227
|
id: row.id,
|
|
228
228
|
coordinates: row.coordinates,
|
|
229
229
|
epoch: row.epoch,
|
|
230
|
-
|
|
230
|
+
item_id: row.item_id,
|
|
231
231
|
supply: newSupply,
|
|
232
232
|
})
|
|
233
233
|
}
|
package/src/entities/ship.ts
CHANGED
|
@@ -113,6 +113,10 @@ export class Ship extends ServerContract.Types.entity_info {
|
|
|
113
113
|
return this.extractor !== undefined
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
get hasWarp(): boolean {
|
|
117
|
+
return this.warp !== undefined
|
|
118
|
+
}
|
|
119
|
+
|
|
116
120
|
project(): ProjectedEntity {
|
|
117
121
|
return sharedProjectEntity(this)
|
|
118
122
|
}
|
|
@@ -155,8 +159,8 @@ export class Ship extends ServerContract.Types.entity_info {
|
|
|
155
159
|
: this.maxCapacity.subtracting(this.totalMass)
|
|
156
160
|
}
|
|
157
161
|
|
|
158
|
-
|
|
159
|
-
return this.inv.
|
|
162
|
+
getCargoForItem(goodId: UInt64Type): EntityInventory | undefined {
|
|
163
|
+
return this.inv.forItem(goodId)
|
|
160
164
|
}
|
|
161
165
|
|
|
162
166
|
get sellableCargo(): EntityInventory[] {
|
|
@@ -198,11 +202,11 @@ export class Ship extends ServerContract.Types.entity_info {
|
|
|
198
202
|
return cargoUtils.calculateSaleValueFromArray(this.cargo, prices)
|
|
199
203
|
}
|
|
200
204
|
|
|
201
|
-
|
|
202
|
-
return cargoUtils.
|
|
205
|
+
afterSellItems(goodsToSell: Array<{goodId: number; quantity: number}>): EntityInventory[] {
|
|
206
|
+
return cargoUtils.afterSellItems(this.cargo, goodsToSell)
|
|
203
207
|
}
|
|
204
208
|
|
|
205
|
-
|
|
206
|
-
return cargoUtils.
|
|
209
|
+
afterSellAllItems(): EntityInventory[] {
|
|
210
|
+
return cargoUtils.afterSellAllItems(this.cargo)
|
|
207
211
|
}
|
|
208
212
|
}
|
|
@@ -79,8 +79,8 @@ export class Warehouse extends ServerContract.Types.entity_info {
|
|
|
79
79
|
return this.totalCargoMass.gte(this.maxCapacity)
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
return this.inv.
|
|
82
|
+
getCargoForItem(goodId: UInt64Type): EntityInventory | undefined {
|
|
83
|
+
return this.inv.forItem(goodId)
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
get orbitalAltitude(): number {
|
package/src/errors.ts
CHANGED
|
@@ -9,11 +9,11 @@ export const ERROR_SYSTEM_DISABLED = 'This game is currently disabled.'
|
|
|
9
9
|
export const ERROR_SYSTEM_NOT_INITIALIZED = 'This game has not been initialized.'
|
|
10
10
|
export const GAME_NOT_FOUND = 'Cannot find game for given account name.'
|
|
11
11
|
export const GAME_SEED_NOT_SET = 'This game has not initialized an epoch seed value.'
|
|
12
|
-
export const
|
|
13
|
-
export const
|
|
12
|
+
export const ITEM_DOES_NOT_EXIST = 'Item does not exist.'
|
|
13
|
+
export const ITEM_NOT_AVAILABLE_AT_LOCATION = 'Item is not tradeable at ship location.'
|
|
14
14
|
export const INSUFFICIENT_BALANCE = 'Insufficient balance.'
|
|
15
|
-
export const
|
|
16
|
-
export const
|
|
15
|
+
export const INSUFFICIENT_ITEM_QUANTITY = 'Insufficient quantity in cargo.'
|
|
16
|
+
export const INSUFFICIENT_ITEM_SUPPLY = 'Insufficient supply of item at location.'
|
|
17
17
|
export const INVALID_AMOUNT = 'Invalid amount.'
|
|
18
18
|
export const REQUIRES_MORE_THAN_ONE = 'A value greater than one is required.'
|
|
19
19
|
export const REQUIRES_POSITIVE_VALUE = 'Value must be greater than zero.'
|
package/src/index-module.ts
CHANGED
|
@@ -22,8 +22,7 @@ export type cargo_item = ServerContract.Types.cargo_item
|
|
|
22
22
|
export type warehouse_row = ServerContract.Types.warehouse_row
|
|
23
23
|
export type container_row = ServerContract.Types.container_row
|
|
24
24
|
export type extractor_stats = ServerContract.Types.extractor_stats
|
|
25
|
-
|
|
26
|
-
export type mixture_component = ServerContract.Types.mixture_component
|
|
25
|
+
|
|
27
26
|
export type location_static = ServerContract.Types.location_static
|
|
28
27
|
export type location_epoch = ServerContract.Types.location_epoch
|
|
29
28
|
export type location_derived = ServerContract.Types.location_derived
|
|
@@ -45,7 +44,7 @@ export {
|
|
|
45
44
|
export type {EntityType} from './managers'
|
|
46
45
|
export type {EntityRefInput} from './managers/actions'
|
|
47
46
|
|
|
48
|
-
export {
|
|
47
|
+
export {getItem, getItems, itemIds} from './market/items'
|
|
49
48
|
export {getCurrentEpoch, getEpochInfo} from './scheduling/epoch'
|
|
50
49
|
export type {EpochInfo} from './scheduling/epoch'
|
|
51
50
|
export {marketPrice, marketPrices, getRarity, Rarities} from './market/market'
|
|
@@ -58,9 +57,35 @@ export {
|
|
|
58
57
|
deriveLocationStatic,
|
|
59
58
|
deriveLocationEpoch,
|
|
60
59
|
deriveLocation,
|
|
61
|
-
deriveLocationMixture,
|
|
62
60
|
} from './utils/system'
|
|
63
61
|
|
|
62
|
+
export {
|
|
63
|
+
deriveStratum,
|
|
64
|
+
deriveResourceStats,
|
|
65
|
+
deriveLocationSize,
|
|
66
|
+
getEligibleResources,
|
|
67
|
+
getResourceWeight,
|
|
68
|
+
getLocationCandidates,
|
|
69
|
+
getDepthThreshold,
|
|
70
|
+
getResourceRarity,
|
|
71
|
+
depthScaleFactor,
|
|
72
|
+
DEPTH_THRESHOLD_COMMON,
|
|
73
|
+
DEPTH_THRESHOLD_UNCOMMON,
|
|
74
|
+
DEPTH_THRESHOLD_RARE,
|
|
75
|
+
DEPTH_THRESHOLD_EPIC,
|
|
76
|
+
DEPTH_THRESHOLD_LEGENDARY,
|
|
77
|
+
LOCATION_MIN_DEPTH,
|
|
78
|
+
LOCATION_MAX_DEPTH,
|
|
79
|
+
PLANET_SUBTYPE_GAS_GIANT,
|
|
80
|
+
PLANET_SUBTYPE_ROCKY,
|
|
81
|
+
PLANET_SUBTYPE_TERRESTRIAL,
|
|
82
|
+
PLANET_SUBTYPE_ICY,
|
|
83
|
+
PLANET_SUBTYPE_OCEAN,
|
|
84
|
+
PLANET_SUBTYPE_INDUSTRIAL,
|
|
85
|
+
} from './derivation'
|
|
86
|
+
|
|
87
|
+
export type {StratumInfo, ResourceStats} from './derivation'
|
|
88
|
+
|
|
64
89
|
export {hash, hash512} from './utils/hash'
|
|
65
90
|
|
|
66
91
|
export type {Deal, FindDealsOptions} from './trading/deal'
|
|
@@ -74,7 +99,7 @@ export type {
|
|
|
74
99
|
CollectAnalysisCallbacks,
|
|
75
100
|
BetterSaleLocation,
|
|
76
101
|
RepositionLocation,
|
|
77
|
-
|
|
102
|
+
DiscountedItemInfo,
|
|
78
103
|
PotentialDeal,
|
|
79
104
|
CargoSaleItem,
|
|
80
105
|
} from './trading/collect'
|
|
@@ -131,7 +156,7 @@ export {
|
|
|
131
156
|
calculateTradeProfit,
|
|
132
157
|
calculateProfitPerMass,
|
|
133
158
|
calculateProfitPerSecond,
|
|
134
|
-
|
|
159
|
+
findBestItemToTrade,
|
|
135
160
|
calculateBreakEvenPrice,
|
|
136
161
|
isProfitable,
|
|
137
162
|
calculateROI,
|