@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
package/src/managers/actions.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {CoordinatesType, EntityType, EntityTypeName} from '../types'
|
|
|
5
5
|
import {ServerContract} from '../contracts'
|
|
6
6
|
|
|
7
7
|
interface SellableCargo {
|
|
8
|
-
|
|
8
|
+
item_id: {toNumber(): number} | number
|
|
9
9
|
quantity: {toNumber(): number} | number
|
|
10
10
|
hasCargo: boolean
|
|
11
11
|
}
|
|
@@ -86,35 +86,35 @@ export class ActionsManager extends BaseManager {
|
|
|
86
86
|
source_id: UInt64.from(sourceId),
|
|
87
87
|
dest_type: destType,
|
|
88
88
|
dest_id: UInt64.from(destId),
|
|
89
|
-
|
|
89
|
+
item_id: UInt16.from(goodId),
|
|
90
90
|
quantity: UInt32.from(quantity),
|
|
91
91
|
})
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
buyItems(
|
|
95
95
|
entityId: UInt64Type,
|
|
96
96
|
goodId: UInt64Type,
|
|
97
97
|
quantity: UInt64Type,
|
|
98
98
|
entityType: EntityTypeName = EntityType.SHIP
|
|
99
99
|
): Action {
|
|
100
|
-
return this.server.action('
|
|
100
|
+
return this.server.action('buyitems', {
|
|
101
101
|
entity_type: entityType,
|
|
102
102
|
id: UInt64.from(entityId),
|
|
103
|
-
|
|
103
|
+
item_id: UInt16.from(goodId),
|
|
104
104
|
quantity: UInt32.from(quantity),
|
|
105
105
|
})
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
sellItems(
|
|
109
109
|
entityId: UInt64Type,
|
|
110
110
|
goodId: UInt64Type,
|
|
111
111
|
quantity: UInt64Type,
|
|
112
112
|
entityType: EntityTypeName = EntityType.SHIP
|
|
113
113
|
): Action {
|
|
114
|
-
return this.server.action('
|
|
114
|
+
return this.server.action('sellitems', {
|
|
115
115
|
entity_type: entityType,
|
|
116
116
|
id: UInt64.from(entityId),
|
|
117
|
-
|
|
117
|
+
item_id: UInt16.from(goodId),
|
|
118
118
|
quantity: UInt32.from(quantity),
|
|
119
119
|
})
|
|
120
120
|
}
|
|
@@ -175,6 +175,18 @@ export class ActionsManager extends BaseManager {
|
|
|
175
175
|
})
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
warp(shipId: UInt64Type, destination: CoordinatesType): Action {
|
|
179
|
+
const x = Int64.from(destination.x)
|
|
180
|
+
const y = Int64.from(destination.y)
|
|
181
|
+
|
|
182
|
+
return this.server.action('warp', {
|
|
183
|
+
entity_type: EntityType.SHIP,
|
|
184
|
+
id: UInt64.from(shipId),
|
|
185
|
+
x,
|
|
186
|
+
y,
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
|
|
178
190
|
joinGame(account: NameType, companyName: string): Action[] {
|
|
179
191
|
return [this.foundCompany(account, companyName), this.join(account)]
|
|
180
192
|
}
|
|
@@ -195,6 +207,6 @@ export class ActionsManager extends BaseManager {
|
|
|
195
207
|
|
|
196
208
|
return shipCargo
|
|
197
209
|
.filter((c) => c.hasCargo)
|
|
198
|
-
.map((c) => this.
|
|
210
|
+
.map((c) => this.sellItems(shipId, c.item_id, c.quantity, EntityType.SHIP))
|
|
199
211
|
}
|
|
200
212
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {Bytes, Checksum256, UInt16Type, UInt64, UInt64Type} from '@wharfkit/antelope'
|
|
2
2
|
import {BaseManager} from './base'
|
|
3
|
-
import {CoordinatesType, coordsToLocationId, Distance,
|
|
3
|
+
import {CoordinatesType, coordsToLocationId, Distance, ItemPrice} from '../types'
|
|
4
4
|
import {marketPrice, marketPrices} from '../market/market'
|
|
5
5
|
import {hasSystem} from '../utils/system'
|
|
6
6
|
import {findNearbyPlanets} from '../travel/travel'
|
|
@@ -8,19 +8,19 @@ import {Location, toLocation} from '../entities/location'
|
|
|
8
8
|
import {ServerContract} from '../contracts'
|
|
9
9
|
|
|
10
10
|
export class LocationsManager extends BaseManager {
|
|
11
|
-
async getMarketPrice(location: CoordinatesType, goodId: number): Promise<
|
|
11
|
+
async getMarketPrice(location: CoordinatesType, goodId: number): Promise<ItemPrice> {
|
|
12
12
|
const game = await this.getGame()
|
|
13
13
|
const state = await this.getState()
|
|
14
14
|
return marketPrice(location, goodId, game.config.seed, state)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
async getMarketPrices(location: CoordinatesType): Promise<
|
|
17
|
+
async getMarketPrices(location: CoordinatesType): Promise<ItemPrice[]> {
|
|
18
18
|
const game = await this.getGame()
|
|
19
19
|
const state = await this.getState()
|
|
20
20
|
return marketPrices(location, game.config.seed, state)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
async getMarketPricesWithSupply(location: CoordinatesType): Promise<
|
|
23
|
+
async getMarketPricesWithSupply(location: CoordinatesType): Promise<ItemPrice[]> {
|
|
24
24
|
const [game, state, supplyRows] = await Promise.all([
|
|
25
25
|
this.getGame(),
|
|
26
26
|
this.getState(),
|
|
@@ -32,16 +32,16 @@ export class LocationsManager extends BaseManager {
|
|
|
32
32
|
const supplyMap = new Map<number, number>()
|
|
33
33
|
for (const row of supplyRows) {
|
|
34
34
|
if (UInt64.from(row.epoch).equals(state.epoch)) {
|
|
35
|
-
supplyMap.set(Number(row.
|
|
35
|
+
supplyMap.set(Number(row.item_id), Number(row.supply))
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
return prices.map((price) => {
|
|
40
40
|
const actualSupply = supplyMap.get(Number(price.id))
|
|
41
41
|
if (actualSupply !== undefined) {
|
|
42
|
-
return
|
|
42
|
+
return ItemPrice.from({
|
|
43
43
|
id: price.id,
|
|
44
|
-
|
|
44
|
+
item: price.item,
|
|
45
45
|
price: price.price,
|
|
46
46
|
supply: UInt64.from(actualSupply),
|
|
47
47
|
})
|
package/src/managers/trades.ts
CHANGED
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
CollectAnalysisCallbacks,
|
|
9
9
|
CollectAnalysisOptions,
|
|
10
10
|
} from '../trading/collect'
|
|
11
|
-
import {Coordinates,
|
|
11
|
+
import {Coordinates, ItemPrice} from '../types'
|
|
12
12
|
import {Location, toLocation} from '../entities/location'
|
|
13
13
|
import {findNearbyPlanets} from '../travel/travel'
|
|
14
14
|
import {getCurrentEpoch} from '../scheduling/epoch'
|
|
15
15
|
|
|
16
16
|
export class TradesManager extends BaseManager {
|
|
17
|
-
private priceCache = new Map<string,
|
|
17
|
+
private priceCache = new Map<string, ItemPrice[]>()
|
|
18
18
|
private priceCacheEpoch: UInt64 | undefined
|
|
19
19
|
|
|
20
20
|
private makePriceCacheKey(location: Coordinates): string {
|
|
@@ -39,7 +39,7 @@ export class TradesManager extends BaseManager {
|
|
|
39
39
|
return nearby.map((d) => toLocation(d.destination))
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
const getMarketPrices = async (location: Coordinates): Promise<
|
|
42
|
+
const getMarketPrices = async (location: Coordinates): Promise<ItemPrice[]> => {
|
|
43
43
|
const cacheKey = this.makePriceCacheKey(location)
|
|
44
44
|
const cached = this.priceCache.get(cacheKey)
|
|
45
45
|
if (cached) {
|
|
@@ -53,9 +53,9 @@ export class TradesManager extends BaseManager {
|
|
|
53
53
|
const actualSupply = locationWithSupply.getSupply(price.id)
|
|
54
54
|
|
|
55
55
|
if (actualSupply !== undefined) {
|
|
56
|
-
return
|
|
56
|
+
return ItemPrice.from({
|
|
57
57
|
id: price.id,
|
|
58
|
-
|
|
58
|
+
item: price.item,
|
|
59
59
|
price: price.price,
|
|
60
60
|
supply: actualSupply,
|
|
61
61
|
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {UInt16, UInt16Type} from '@wharfkit/antelope'
|
|
2
|
+
import {Item} from '../types'
|
|
3
|
+
import itemsData from '../data/items.json'
|
|
4
|
+
|
|
5
|
+
const items: Item[] = itemsData.map((g) =>
|
|
6
|
+
Item.from({
|
|
7
|
+
id: g.id,
|
|
8
|
+
name: g.name,
|
|
9
|
+
description: g.description,
|
|
10
|
+
base_price: g.base_price,
|
|
11
|
+
mass: g.mass,
|
|
12
|
+
category: g.category,
|
|
13
|
+
rarity: g.rarity,
|
|
14
|
+
color: g.color,
|
|
15
|
+
})
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
export const itemIds = items.map((i) => i.id)
|
|
19
|
+
|
|
20
|
+
export function getItem(itemId: UInt16Type): Item {
|
|
21
|
+
const id = UInt16.from(itemId)
|
|
22
|
+
const item = items.find((i) => i.id.equals(id))
|
|
23
|
+
if (!item) {
|
|
24
|
+
throw new Error(`Item with id ${id} not found`)
|
|
25
|
+
}
|
|
26
|
+
return item
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getItems(): Item[] {
|
|
30
|
+
return items
|
|
31
|
+
}
|
package/src/market/market.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {CoordinatesType,
|
|
2
|
-
import {
|
|
1
|
+
import {CoordinatesType, ItemPrice} from '../types'
|
|
2
|
+
import {getItem, getItems} from './items'
|
|
3
3
|
import {Checksum256Type, UInt16, UInt16Type, UInt32} from '@wharfkit/antelope'
|
|
4
4
|
import {roll} from './rolls'
|
|
5
5
|
import {ServerContract} from '../contracts'
|
|
@@ -174,9 +174,9 @@ export function marketPrice(
|
|
|
174
174
|
goodId: UInt16Type,
|
|
175
175
|
gameSeed: Checksum256Type,
|
|
176
176
|
state: ServerContract.Types.state_row
|
|
177
|
-
):
|
|
178
|
-
const
|
|
179
|
-
let price = Number(
|
|
177
|
+
): ItemPrice {
|
|
178
|
+
const item = getItem(goodId)
|
|
179
|
+
let price = Number(item.base_price)
|
|
180
180
|
|
|
181
181
|
// Rarity multiplier of the deal (changes with epoch)
|
|
182
182
|
// Large impact range on price, from 0.285x to 3.0x
|
|
@@ -191,9 +191,9 @@ export function marketPrice(
|
|
|
191
191
|
// Determine the current supply of the good at the location
|
|
192
192
|
const supply = getSupply(gameSeed, state, location, goodId)
|
|
193
193
|
|
|
194
|
-
return
|
|
194
|
+
return ItemPrice.from({
|
|
195
195
|
id: goodId,
|
|
196
|
-
|
|
196
|
+
item,
|
|
197
197
|
price: UInt32.from(price),
|
|
198
198
|
supply: UInt16.from(supply),
|
|
199
199
|
})
|
|
@@ -203,6 +203,6 @@ export function marketPrices(
|
|
|
203
203
|
location: ServerContract.ActionParams.Type.coordinates,
|
|
204
204
|
gameSeed: Checksum256Type,
|
|
205
205
|
state: ServerContract.Types.state_row
|
|
206
|
-
):
|
|
207
|
-
return
|
|
206
|
+
): ItemPrice[] {
|
|
207
|
+
return getItems().map((item) => marketPrice(location, item.id, gameSeed, state))
|
|
208
208
|
}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from '../types/capabilities'
|
|
11
11
|
import {distanceBetweenCoordinates, lerp} from '../travel/travel'
|
|
12
12
|
import {calcCargoMass} from '../capabilities/storage'
|
|
13
|
-
import {
|
|
13
|
+
import {getItem} from '../market/items'
|
|
14
14
|
import * as schedule from './schedule'
|
|
15
15
|
import {ScheduleData} from './schedule'
|
|
16
16
|
|
|
@@ -169,21 +169,21 @@ function applyFlightTask(
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
function
|
|
173
|
-
const
|
|
174
|
-
return
|
|
172
|
+
function getItemMass(item_id: UInt16 | number): UInt32 {
|
|
173
|
+
const item = getItem(item_id)
|
|
174
|
+
return item.mass
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
function applyLoadTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
|
|
178
178
|
for (const item of task.cargo) {
|
|
179
|
-
const good_mass =
|
|
179
|
+
const good_mass = getItemMass(item.item_id)
|
|
180
180
|
projected.cargoMass = projected.cargoMass.adding(good_mass.multiplying(item.quantity))
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
function applyUnloadTask(projected: ProjectedEntity, task: ServerContract.Types.task): void {
|
|
185
185
|
for (const item of task.cargo) {
|
|
186
|
-
const good_mass =
|
|
186
|
+
const good_mass = getItemMass(item.item_id)
|
|
187
187
|
const cargoMass = good_mass.multiplying(item.quantity)
|
|
188
188
|
projected.cargoMass = projected.cargoMass.gt(cargoMass)
|
|
189
189
|
? projected.cargoMass.subtracting(cargoMass)
|
|
@@ -206,7 +206,7 @@ function applyExtractTask(
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
for (const item of task.cargo) {
|
|
209
|
-
const good_mass =
|
|
209
|
+
const good_mass = getItemMass(item.item_id)
|
|
210
210
|
projected.cargoMass = projected.cargoMass.adding(good_mass.multiplying(item.quantity))
|
|
211
211
|
}
|
|
212
212
|
}
|
package/src/trading/collect.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {Checksum256Type, Int64, UInt16, UInt32, UInt64} from '@wharfkit/antelope'
|
|
2
2
|
import {Ship} from '../entities/ship'
|
|
3
3
|
import {Location} from '../entities/location'
|
|
4
|
-
import {Coordinates,
|
|
4
|
+
import {Coordinates, ItemPrice, ShipLike} from '../types'
|
|
5
5
|
import {Deal, findDealsForShip} from './deal'
|
|
6
6
|
|
|
7
7
|
import {EntityInventory} from '../entities/entity-inventory'
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
EstimatedTravelTime,
|
|
12
12
|
estimateTravelTime,
|
|
13
13
|
} from '../travel/travel'
|
|
14
|
-
import {
|
|
14
|
+
import {getItem, getItems} from '../market/items'
|
|
15
15
|
import {getRarity, Rarities} from '../market/market'
|
|
16
16
|
import {ServerContract} from '../contracts'
|
|
17
17
|
|
|
@@ -23,7 +23,7 @@ function calculateCargoMass(cargo: EntityInventory[]): UInt32 {
|
|
|
23
23
|
let mass = UInt32.from(0)
|
|
24
24
|
for (const c of cargo) {
|
|
25
25
|
if (UInt64.from(c.quantity).gt(UInt64.zero)) {
|
|
26
|
-
const goodMass =
|
|
26
|
+
const goodMass = getItem(c.item_id).mass
|
|
27
27
|
mass = mass.adding(goodMass.multiplying(c.quantity))
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -102,7 +102,7 @@ export interface CollectOption {
|
|
|
102
102
|
/** Detailed breakdown of travel time components */
|
|
103
103
|
travelTimeBreakdown?: EstimatedTravelTime
|
|
104
104
|
/** Info about a discounted good at the destination (for explore options) */
|
|
105
|
-
discountedGood?:
|
|
105
|
+
discountedGood?: DiscountedItemInfo
|
|
106
106
|
/** Top potential deals available at destination (for explore options) */
|
|
107
107
|
potentialDeals?: PotentialDeal[]
|
|
108
108
|
/** Details of cargo being sold (if selling cargo) */
|
|
@@ -190,7 +190,7 @@ export function analyzeCargoSale(
|
|
|
190
190
|
for (const c of cargo) {
|
|
191
191
|
if (UInt64.from(c.quantity).equals(UInt64.zero)) continue
|
|
192
192
|
|
|
193
|
-
const goodId = Number(c.
|
|
193
|
+
const goodId = Number(c.item_id)
|
|
194
194
|
const salePrice = prices.get(goodId)
|
|
195
195
|
|
|
196
196
|
if (salePrice) {
|
|
@@ -219,7 +219,7 @@ export function buildCargoSaleItems(
|
|
|
219
219
|
for (const c of cargo) {
|
|
220
220
|
if (UInt64.from(c.quantity).equals(UInt64.zero)) continue
|
|
221
221
|
|
|
222
|
-
const goodId = Number(c.
|
|
222
|
+
const goodId = Number(c.item_id)
|
|
223
223
|
const salePrice = prices.get(goodId)
|
|
224
224
|
const pricePerUnit = salePrice ? UInt32.from(salePrice) : UInt32.zero
|
|
225
225
|
const revenue = UInt64.from(pricePerUnit).multiplying(c.quantity)
|
|
@@ -227,8 +227,8 @@ export function buildCargoSaleItems(
|
|
|
227
227
|
const profit = Int64.from(revenue).subtracting(cost)
|
|
228
228
|
|
|
229
229
|
items.push({
|
|
230
|
-
goodId: c.
|
|
231
|
-
goodName: c.
|
|
230
|
+
goodId: c.item_id,
|
|
231
|
+
goodName: c.item?.name ?? `Item #${goodId}`,
|
|
232
232
|
quantity: UInt32.from(c.quantity),
|
|
233
233
|
pricePerUnit,
|
|
234
234
|
revenue,
|
|
@@ -271,10 +271,10 @@ export function createSellAndTradeOption(
|
|
|
271
271
|
: undefined
|
|
272
272
|
|
|
273
273
|
return {
|
|
274
|
-
id: `sell-trade-${deal.destination.coordinates.x}-${deal.destination.coordinates.y}-${deal.
|
|
274
|
+
id: `sell-trade-${deal.destination.coordinates.x}-${deal.destination.coordinates.y}-${deal.item.id}`,
|
|
275
275
|
type: 'sell-and-trade',
|
|
276
|
-
title: `Trade ${deal.
|
|
277
|
-
description: `Sell cargo, buy ${deal.maxQuantity} ${deal.
|
|
276
|
+
title: `Trade ${deal.item.item.name}`,
|
|
277
|
+
description: `Sell cargo, buy ${deal.maxQuantity} ${deal.item.item.name}, deliver to (${deal.destination.coordinates.x}, ${deal.destination.coordinates.y})`,
|
|
278
278
|
reason: `${deal.marginPercent.toFixed(0)}% margin, ${deal.profitPerSecond.toFixed(
|
|
279
279
|
1
|
|
280
280
|
)}/s profit rate`,
|
|
@@ -363,7 +363,7 @@ export function createSellAndRepositionOption(
|
|
|
363
363
|
id: `sell-reposition-${reposition.location.coordinates.x}-${reposition.location.coordinates.y}`,
|
|
364
364
|
type: 'sell-and-reposition',
|
|
365
365
|
title: 'Sell & Move',
|
|
366
|
-
description: `Sell cargo here, travel empty to buy ${deal.
|
|
366
|
+
description: `Sell cargo here, travel empty to buy ${deal.item.item.name}`,
|
|
367
367
|
reason: `No good trades here — ${deal.marginPercent.toFixed(
|
|
368
368
|
0
|
|
369
369
|
)}% margin trade available at destination`,
|
|
@@ -455,7 +455,7 @@ export interface CargoSaleItem {
|
|
|
455
455
|
/**
|
|
456
456
|
* Info about a discounted good for explore options
|
|
457
457
|
*/
|
|
458
|
-
export interface
|
|
458
|
+
export interface DiscountedItemInfo {
|
|
459
459
|
goodId: number
|
|
460
460
|
name: string
|
|
461
461
|
rarity: string
|
|
@@ -479,7 +479,7 @@ export interface PotentialDeal {
|
|
|
479
479
|
export function createExploreOption(
|
|
480
480
|
destination: Location,
|
|
481
481
|
travelTime?: UInt32,
|
|
482
|
-
discountedGood?:
|
|
482
|
+
discountedGood?: DiscountedItemInfo,
|
|
483
483
|
travelTimeBreakdown?: EstimatedTravelTime,
|
|
484
484
|
potentialDeals?: PotentialDeal[]
|
|
485
485
|
): CollectOption {
|
|
@@ -536,7 +536,7 @@ export function createExploreOption(
|
|
|
536
536
|
*/
|
|
537
537
|
export interface CollectAnalysisCallbacks {
|
|
538
538
|
getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>
|
|
539
|
-
getMarketPrices: (location: Coordinates) => Promise<
|
|
539
|
+
getMarketPrices: (location: Coordinates) => Promise<ItemPrice[]>
|
|
540
540
|
getGameSeed?: () => Checksum256Type
|
|
541
541
|
getState?: () => ServerContract.Types.state_row
|
|
542
542
|
}
|
|
@@ -582,10 +582,10 @@ export async function analyzeCollectOptions(
|
|
|
582
582
|
)
|
|
583
583
|
|
|
584
584
|
if (hasCargo && dealsAtOrigin.length > 0) {
|
|
585
|
-
const cargoGoodIds = new Set(cargo.map((c) => Number(c.
|
|
585
|
+
const cargoGoodIds = new Set(cargo.map((c) => Number(c.item_id)))
|
|
586
586
|
|
|
587
587
|
for (const deal of dealsAtOrigin.slice(0, 3)) {
|
|
588
|
-
const dealGoodId = Number(deal.
|
|
588
|
+
const dealGoodId = Number(deal.item.id)
|
|
589
589
|
if (cargoGoodIds.has(dealGoodId)) {
|
|
590
590
|
continue
|
|
591
591
|
}
|
|
@@ -767,10 +767,10 @@ export async function analyzeCollectOptions(
|
|
|
767
767
|
if (!hasCargo && dealsAtOrigin.length > 0) {
|
|
768
768
|
for (const deal of dealsAtOrigin.slice(0, 3)) {
|
|
769
769
|
const option: CollectOption = {
|
|
770
|
-
id: `trade-${deal.destination.coordinates.x}-${deal.destination.coordinates.y}-${deal.
|
|
770
|
+
id: `trade-${deal.destination.coordinates.x}-${deal.destination.coordinates.y}-${deal.item.id}`,
|
|
771
771
|
type: 'sell-and-trade',
|
|
772
|
-
title: `Trade ${deal.
|
|
773
|
-
description: `Buy ${deal.maxQuantity} ${deal.
|
|
772
|
+
title: `Trade ${deal.item.item.name}`,
|
|
773
|
+
description: `Buy ${deal.maxQuantity} ${deal.item.item.name}, deliver to (${deal.destination.coordinates.x}, ${deal.destination.coordinates.y})`,
|
|
774
774
|
reason: `${deal.marginPercent.toFixed(0)}% margin, ${deal.profitPerSecond.toFixed(
|
|
775
775
|
1
|
|
776
776
|
)}/s profit rate`,
|
|
@@ -804,7 +804,7 @@ export async function analyzeCollectOptions(
|
|
|
804
804
|
dest: Location
|
|
805
805
|
travelTime: UInt32
|
|
806
806
|
travelTimeBreakdown: EstimatedTravelTime
|
|
807
|
-
discountedGood?:
|
|
807
|
+
discountedGood?: DiscountedItemInfo
|
|
808
808
|
bestDiscount: number
|
|
809
809
|
potentialDeals?: PotentialDeal[]
|
|
810
810
|
score: number
|
|
@@ -821,11 +821,11 @@ export async function analyzeCollectOptions(
|
|
|
821
821
|
unloadMass,
|
|
822
822
|
})
|
|
823
823
|
|
|
824
|
-
let discountedGood:
|
|
824
|
+
let discountedGood: DiscountedItemInfo | undefined
|
|
825
825
|
let bestDiscount = 0
|
|
826
826
|
|
|
827
827
|
if (gameSeed && state) {
|
|
828
|
-
const allGoods =
|
|
828
|
+
const allGoods = getItems()
|
|
829
829
|
for (const good of allGoods) {
|
|
830
830
|
const rarity = getRarity(gameSeed, state.seed, dest.coordinates, good.id)
|
|
831
831
|
if (rarity.minMultiplier < 1.0) {
|
|
@@ -862,8 +862,8 @@ export async function analyzeCollectOptions(
|
|
|
862
862
|
)
|
|
863
863
|
|
|
864
864
|
const potentialDeals: PotentialDeal[] = destDeals.map((d) => ({
|
|
865
|
-
goodId: Number(d.
|
|
866
|
-
goodName: d.
|
|
865
|
+
goodId: Number(d.item.id),
|
|
866
|
+
goodName: d.item.item.name,
|
|
867
867
|
destinationCoords: d.destination.coordinates,
|
|
868
868
|
marginPercent: d.marginPercent,
|
|
869
869
|
profitPerSecond: d.profitPerSecond,
|
package/src/trading/deal.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {Int64, UInt16, UInt32, UInt64, UInt64Type} from '@wharfkit/antelope'
|
|
2
|
-
import {Coordinates,
|
|
2
|
+
import {Coordinates, ItemPrice, PRECISION, ShipLike} from '../types'
|
|
3
3
|
import {Location} from '../entities/location'
|
|
4
4
|
import {Ship} from '../entities/ship'
|
|
5
5
|
import {
|
|
@@ -17,8 +17,8 @@ export interface Deal {
|
|
|
17
17
|
origin: Location
|
|
18
18
|
/** Destination location */
|
|
19
19
|
destination: Location
|
|
20
|
-
/**
|
|
21
|
-
|
|
20
|
+
/** Item to trade */
|
|
21
|
+
item: ItemPrice
|
|
22
22
|
/** Distance between origin and destination */
|
|
23
23
|
distance: UInt64
|
|
24
24
|
/** Available supply at origin */
|
|
@@ -68,7 +68,7 @@ export async function findDealsForShip(
|
|
|
68
68
|
ship: Ship,
|
|
69
69
|
originLocation: Coordinates,
|
|
70
70
|
getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>,
|
|
71
|
-
getMarketPrices: (location: Coordinates) => Promise<
|
|
71
|
+
getMarketPrices: (location: Coordinates) => Promise<ItemPrice[]>,
|
|
72
72
|
options: FindDealsOptions = {}
|
|
73
73
|
): Promise<Deal[]> {
|
|
74
74
|
const {
|
|
@@ -123,7 +123,7 @@ export async function findDealsForShip(
|
|
|
123
123
|
balance !== undefined
|
|
124
124
|
? balance.dividing(originGood.price)
|
|
125
125
|
: UInt64.from(Number.MAX_SAFE_INTEGER)
|
|
126
|
-
const canHaul = effectiveAvailableMass.dividing(originGood.
|
|
126
|
+
const canHaul = effectiveAvailableMass.dividing(originGood.item.mass)
|
|
127
127
|
const supplyLimit = UInt64.from(originGood.supply)
|
|
128
128
|
|
|
129
129
|
// Find minimum of canAfford, canHaul, supplyLimit
|
|
@@ -134,7 +134,7 @@ export async function findDealsForShip(
|
|
|
134
134
|
if (maxQuantity.equals(UInt64.zero)) continue
|
|
135
135
|
|
|
136
136
|
// Calculate travel time with cargo (includes recharge + load time)
|
|
137
|
-
const cargoMass = originGood.
|
|
137
|
+
const cargoMass = originGood.item.mass.multiplying(maxQuantity)
|
|
138
138
|
const availableSpaceUInt = UInt64.from(availableSpace)
|
|
139
139
|
const baseMass =
|
|
140
140
|
availableSpace !== undefined
|
|
@@ -161,7 +161,7 @@ export async function findDealsForShip(
|
|
|
161
161
|
deals.push({
|
|
162
162
|
origin,
|
|
163
163
|
destination: destLocation,
|
|
164
|
-
|
|
164
|
+
item: originGood,
|
|
165
165
|
distance,
|
|
166
166
|
supply: originGood.supply,
|
|
167
167
|
buyPrice: originGood.price,
|
|
@@ -190,7 +190,7 @@ export async function findBestDeal(
|
|
|
190
190
|
ship: Ship,
|
|
191
191
|
originLocation: Coordinates,
|
|
192
192
|
getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>,
|
|
193
|
-
getMarketPrices: (location: Coordinates) => Promise<
|
|
193
|
+
getMarketPrices: (location: Coordinates) => Promise<ItemPrice[]>,
|
|
194
194
|
options: FindDealsOptions = {}
|
|
195
195
|
): Promise<Deal | undefined> {
|
|
196
196
|
const deals = await findDealsForShip(
|
package/src/trading/trade.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {Int64, Int64Type, UInt32, UInt32Type, UInt64} from '@wharfkit/antelope'
|
|
2
2
|
import {Ship} from '../entities/ship'
|
|
3
3
|
import {Player} from '../entities/player'
|
|
4
|
-
import {
|
|
4
|
+
import {ItemPrice} from '../types'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Trade calculation result
|
|
@@ -53,10 +53,10 @@ export function calculateUpdatedCargoCost(
|
|
|
53
53
|
export function calculateMaxTradeQuantity(
|
|
54
54
|
ship: Ship,
|
|
55
55
|
player: Player,
|
|
56
|
-
goodPrice:
|
|
56
|
+
goodPrice: ItemPrice
|
|
57
57
|
): TradeCalculation {
|
|
58
58
|
const pricePerUnit = UInt32.from(goodPrice.price)
|
|
59
|
-
const massPerUnit = UInt32.from(goodPrice.
|
|
59
|
+
const massPerUnit = UInt32.from(goodPrice.item.mass)
|
|
60
60
|
|
|
61
61
|
const spaceForQuantity = ship.availableCapacity.dividing(massPerUnit)
|
|
62
62
|
const affordableQuantity = player.balance.dividing(pricePerUnit)
|
|
@@ -128,21 +128,21 @@ export function calculateProfitPerSecond(profit: Int64Type, travelTimeSeconds: U
|
|
|
128
128
|
/**
|
|
129
129
|
* Find the best good to trade between two locations
|
|
130
130
|
*/
|
|
131
|
-
export function
|
|
131
|
+
export function findBestItemToTrade(
|
|
132
132
|
ship: Ship,
|
|
133
133
|
player: Player,
|
|
134
|
-
originPrices:
|
|
135
|
-
destPrices:
|
|
134
|
+
originPrices: ItemPrice[],
|
|
135
|
+
destPrices: ItemPrice[],
|
|
136
136
|
travelTimeSeconds: UInt32Type
|
|
137
137
|
): {
|
|
138
|
-
|
|
138
|
+
item: ItemPrice
|
|
139
139
|
quantity: number
|
|
140
140
|
profit: number
|
|
141
141
|
profitPerSecond: number
|
|
142
142
|
margin: number
|
|
143
143
|
} | null {
|
|
144
144
|
let bestTrade: {
|
|
145
|
-
|
|
145
|
+
item: ItemPrice
|
|
146
146
|
quantity: number
|
|
147
147
|
profit: number
|
|
148
148
|
profitPerSecond: number
|
|
@@ -169,7 +169,7 @@ export function findBestGoodToTrade(
|
|
|
169
169
|
if (profitPerSecond > bestProfitPerSecond) {
|
|
170
170
|
bestProfitPerSecond = profitPerSecond
|
|
171
171
|
bestTrade = {
|
|
172
|
-
|
|
172
|
+
item: originPrice,
|
|
173
173
|
quantity: calc.maxQuantity,
|
|
174
174
|
profit: Number(tradeResult.profit),
|
|
175
175
|
profitPerSecond,
|
package/src/travel/travel.ts
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
ShipLike,
|
|
32
32
|
TaskType,
|
|
33
33
|
} from '../types'
|
|
34
|
-
import {
|
|
34
|
+
import {getItem} from '../market/items'
|
|
35
35
|
import {hasSystem} from '../utils/system'
|
|
36
36
|
|
|
37
37
|
export function calc_orbital_altitude(mass: number): number {
|
|
@@ -165,7 +165,7 @@ export function calc_ship_mass(ship: ShipLike, cargos: CargoMassInfo[]): UInt64
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
for (const cargo of cargos) {
|
|
168
|
-
mass.add(
|
|
168
|
+
mass.add(getItem(cargo.item_id).mass.multiplying(cargo.quantity))
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
return mass
|
|
@@ -183,9 +183,9 @@ export function calculateTransferTime(
|
|
|
183
183
|
let mass = UInt64.from(0)
|
|
184
184
|
|
|
185
185
|
for (const cargo of cargos) {
|
|
186
|
-
const qty = quantities?.get(Number(cargo.
|
|
186
|
+
const qty = quantities?.get(Number(cargo.item_id)) ?? 0
|
|
187
187
|
if (qty > 0) {
|
|
188
|
-
const good_mass =
|
|
188
|
+
const good_mass = getItem(cargo.item_id).mass
|
|
189
189
|
const cargo_mass = good_mass.multiplying(qty)
|
|
190
190
|
mass = UInt64.from(mass).adding(cargo_mass)
|
|
191
191
|
}
|
|
@@ -231,12 +231,12 @@ export function calculateLoadTimeBreakdown(
|
|
|
231
231
|
let mass_load = UInt64.from(0)
|
|
232
232
|
|
|
233
233
|
for (const cargo of cargos) {
|
|
234
|
-
const goodId = Number(cargo.
|
|
234
|
+
const goodId = Number(cargo.item_id)
|
|
235
235
|
const loadQty = loadQuantities?.get(goodId) ?? 0
|
|
236
236
|
const unloadQty = unloadQuantities?.get(goodId) ?? 0
|
|
237
237
|
|
|
238
238
|
if (loadQty > 0 || unloadQty > 0) {
|
|
239
|
-
const good =
|
|
239
|
+
const good = getItem(cargo.item_id)
|
|
240
240
|
|
|
241
241
|
if (loadQty > 0) {
|
|
242
242
|
const cargo_mass = good.mass.multiplying(loadQty)
|