@shipload/sdk 2.0.0-rc1 → 2.0.0-rc3
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 +349 -1
- package/lib/shipload.d.ts +809 -314
- package/lib/shipload.js +2745 -1740
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +2158 -1154
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -2
- package/src/capabilities/extraction.ts +30 -0
- package/src/capabilities/guards.ts +43 -0
- package/src/capabilities/index.ts +5 -0
- package/src/capabilities/loading.ts +8 -0
- package/src/capabilities/movement.ts +29 -0
- package/src/capabilities/storage.ts +67 -0
- package/src/contracts/server.ts +506 -183
- package/src/data/items.json +16 -0
- 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 +116 -0
- package/src/entities/cargo-utils.ts +98 -3
- package/src/entities/container.ts +70 -0
- package/src/entities/entity-inventory.ts +13 -9
- package/src/entities/inventory-accessor.ts +46 -0
- package/src/entities/location.ts +31 -17
- package/src/entities/makers.ts +69 -0
- package/src/entities/player.ts +2 -1
- package/src/entities/ship.ts +93 -440
- package/src/entities/warehouse.ts +29 -145
- package/src/errors.ts +4 -4
- package/src/index-module.ts +62 -4
- package/src/managers/actions.ts +75 -31
- package/src/managers/entities.ts +22 -5
- package/src/managers/locations.ts +34 -15
- package/src/managers/trades.ts +7 -7
- package/src/market/items.ts +31 -0
- package/src/market/market.ts +12 -13
- package/src/scheduling/accessor.ts +82 -0
- package/src/scheduling/projection.ts +126 -54
- package/src/scheduling/schedule.ts +24 -0
- package/src/trading/collect.ts +25 -26
- package/src/trading/deal.ts +8 -9
- package/src/trading/trade.ts +9 -9
- package/src/travel/travel.ts +69 -8
- package/src/types/capabilities.ts +79 -0
- package/src/types/entity-traits.ts +70 -0
- package/src/types/entity.ts +36 -0
- package/src/types/index.ts +3 -0
- package/src/types.ts +92 -15
- package/src/utils/hash.ts +1 -1
- package/src/utils/system.ts +97 -4
- package/src/data/goods.json +0 -23
- package/src/market/goods.ts +0 -31
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'
|
|
@@ -10,9 +10,8 @@ import {
|
|
|
10
10
|
distanceBetweenCoordinates,
|
|
11
11
|
EstimatedTravelTime,
|
|
12
12
|
estimateTravelTime,
|
|
13
|
-
hasEnergyForDistance,
|
|
14
13
|
} from '../travel/travel'
|
|
15
|
-
import {
|
|
14
|
+
import {getItem, getItems} from '../market/items'
|
|
16
15
|
import {getRarity, Rarities} from '../market/market'
|
|
17
16
|
import {ServerContract} from '../contracts'
|
|
18
17
|
|
|
@@ -24,7 +23,7 @@ function calculateCargoMass(cargo: EntityInventory[]): UInt32 {
|
|
|
24
23
|
let mass = UInt32.from(0)
|
|
25
24
|
for (const c of cargo) {
|
|
26
25
|
if (UInt64.from(c.quantity).gt(UInt64.zero)) {
|
|
27
|
-
const goodMass =
|
|
26
|
+
const goodMass = getItem(c.item_id).mass
|
|
28
27
|
mass = mass.adding(goodMass.multiplying(c.quantity))
|
|
29
28
|
}
|
|
30
29
|
}
|
|
@@ -103,7 +102,7 @@ export interface CollectOption {
|
|
|
103
102
|
/** Detailed breakdown of travel time components */
|
|
104
103
|
travelTimeBreakdown?: EstimatedTravelTime
|
|
105
104
|
/** Info about a discounted good at the destination (for explore options) */
|
|
106
|
-
discountedGood?:
|
|
105
|
+
discountedGood?: DiscountedItemInfo
|
|
107
106
|
/** Top potential deals available at destination (for explore options) */
|
|
108
107
|
potentialDeals?: PotentialDeal[]
|
|
109
108
|
/** Details of cargo being sold (if selling cargo) */
|
|
@@ -191,7 +190,7 @@ export function analyzeCargoSale(
|
|
|
191
190
|
for (const c of cargo) {
|
|
192
191
|
if (UInt64.from(c.quantity).equals(UInt64.zero)) continue
|
|
193
192
|
|
|
194
|
-
const goodId = Number(c.
|
|
193
|
+
const goodId = Number(c.item_id)
|
|
195
194
|
const salePrice = prices.get(goodId)
|
|
196
195
|
|
|
197
196
|
if (salePrice) {
|
|
@@ -220,7 +219,7 @@ export function buildCargoSaleItems(
|
|
|
220
219
|
for (const c of cargo) {
|
|
221
220
|
if (UInt64.from(c.quantity).equals(UInt64.zero)) continue
|
|
222
221
|
|
|
223
|
-
const goodId = Number(c.
|
|
222
|
+
const goodId = Number(c.item_id)
|
|
224
223
|
const salePrice = prices.get(goodId)
|
|
225
224
|
const pricePerUnit = salePrice ? UInt32.from(salePrice) : UInt32.zero
|
|
226
225
|
const revenue = UInt64.from(pricePerUnit).multiplying(c.quantity)
|
|
@@ -228,8 +227,8 @@ export function buildCargoSaleItems(
|
|
|
228
227
|
const profit = Int64.from(revenue).subtracting(cost)
|
|
229
228
|
|
|
230
229
|
items.push({
|
|
231
|
-
goodId: c.
|
|
232
|
-
goodName: c.
|
|
230
|
+
goodId: c.item_id,
|
|
231
|
+
goodName: c.item?.name ?? `Item #${goodId}`,
|
|
233
232
|
quantity: UInt32.from(c.quantity),
|
|
234
233
|
pricePerUnit,
|
|
235
234
|
revenue,
|
|
@@ -272,10 +271,10 @@ export function createSellAndTradeOption(
|
|
|
272
271
|
: undefined
|
|
273
272
|
|
|
274
273
|
return {
|
|
275
|
-
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}`,
|
|
276
275
|
type: 'sell-and-trade',
|
|
277
|
-
title: `Trade ${deal.
|
|
278
|
-
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})`,
|
|
279
278
|
reason: `${deal.marginPercent.toFixed(0)}% margin, ${deal.profitPerSecond.toFixed(
|
|
280
279
|
1
|
|
281
280
|
)}/s profit rate`,
|
|
@@ -364,7 +363,7 @@ export function createSellAndRepositionOption(
|
|
|
364
363
|
id: `sell-reposition-${reposition.location.coordinates.x}-${reposition.location.coordinates.y}`,
|
|
365
364
|
type: 'sell-and-reposition',
|
|
366
365
|
title: 'Sell & Move',
|
|
367
|
-
description: `Sell cargo here, travel empty to buy ${deal.
|
|
366
|
+
description: `Sell cargo here, travel empty to buy ${deal.item.item.name}`,
|
|
368
367
|
reason: `No good trades here — ${deal.marginPercent.toFixed(
|
|
369
368
|
0
|
|
370
369
|
)}% margin trade available at destination`,
|
|
@@ -456,7 +455,7 @@ export interface CargoSaleItem {
|
|
|
456
455
|
/**
|
|
457
456
|
* Info about a discounted good for explore options
|
|
458
457
|
*/
|
|
459
|
-
export interface
|
|
458
|
+
export interface DiscountedItemInfo {
|
|
460
459
|
goodId: number
|
|
461
460
|
name: string
|
|
462
461
|
rarity: string
|
|
@@ -480,7 +479,7 @@ export interface PotentialDeal {
|
|
|
480
479
|
export function createExploreOption(
|
|
481
480
|
destination: Location,
|
|
482
481
|
travelTime?: UInt32,
|
|
483
|
-
discountedGood?:
|
|
482
|
+
discountedGood?: DiscountedItemInfo,
|
|
484
483
|
travelTimeBreakdown?: EstimatedTravelTime,
|
|
485
484
|
potentialDeals?: PotentialDeal[]
|
|
486
485
|
): CollectOption {
|
|
@@ -537,7 +536,7 @@ export function createExploreOption(
|
|
|
537
536
|
*/
|
|
538
537
|
export interface CollectAnalysisCallbacks {
|
|
539
538
|
getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>
|
|
540
|
-
getMarketPrices: (location: Coordinates) => Promise<
|
|
539
|
+
getMarketPrices: (location: Coordinates) => Promise<ItemPrice[]>
|
|
541
540
|
getGameSeed?: () => Checksum256Type
|
|
542
541
|
getState?: () => ServerContract.Types.state_row
|
|
543
542
|
}
|
|
@@ -583,10 +582,10 @@ export async function analyzeCollectOptions(
|
|
|
583
582
|
)
|
|
584
583
|
|
|
585
584
|
if (hasCargo && dealsAtOrigin.length > 0) {
|
|
586
|
-
const cargoGoodIds = new Set(cargo.map((c) => Number(c.
|
|
585
|
+
const cargoGoodIds = new Set(cargo.map((c) => Number(c.item_id)))
|
|
587
586
|
|
|
588
587
|
for (const deal of dealsAtOrigin.slice(0, 3)) {
|
|
589
|
-
const dealGoodId = Number(deal.
|
|
588
|
+
const dealGoodId = Number(deal.item.id)
|
|
590
589
|
if (cargoGoodIds.has(dealGoodId)) {
|
|
591
590
|
continue
|
|
592
591
|
}
|
|
@@ -768,10 +767,10 @@ export async function analyzeCollectOptions(
|
|
|
768
767
|
if (!hasCargo && dealsAtOrigin.length > 0) {
|
|
769
768
|
for (const deal of dealsAtOrigin.slice(0, 3)) {
|
|
770
769
|
const option: CollectOption = {
|
|
771
|
-
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}`,
|
|
772
771
|
type: 'sell-and-trade',
|
|
773
|
-
title: `Trade ${deal.
|
|
774
|
-
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})`,
|
|
775
774
|
reason: `${deal.marginPercent.toFixed(0)}% margin, ${deal.profitPerSecond.toFixed(
|
|
776
775
|
1
|
|
777
776
|
)}/s profit rate`,
|
|
@@ -805,7 +804,7 @@ export async function analyzeCollectOptions(
|
|
|
805
804
|
dest: Location
|
|
806
805
|
travelTime: UInt32
|
|
807
806
|
travelTimeBreakdown: EstimatedTravelTime
|
|
808
|
-
discountedGood?:
|
|
807
|
+
discountedGood?: DiscountedItemInfo
|
|
809
808
|
bestDiscount: number
|
|
810
809
|
potentialDeals?: PotentialDeal[]
|
|
811
810
|
score: number
|
|
@@ -822,11 +821,11 @@ export async function analyzeCollectOptions(
|
|
|
822
821
|
unloadMass,
|
|
823
822
|
})
|
|
824
823
|
|
|
825
|
-
let discountedGood:
|
|
824
|
+
let discountedGood: DiscountedItemInfo | undefined
|
|
826
825
|
let bestDiscount = 0
|
|
827
826
|
|
|
828
827
|
if (gameSeed && state) {
|
|
829
|
-
const allGoods =
|
|
828
|
+
const allGoods = getItems()
|
|
830
829
|
for (const good of allGoods) {
|
|
831
830
|
const rarity = getRarity(gameSeed, state.seed, dest.coordinates, good.id)
|
|
832
831
|
if (rarity.minMultiplier < 1.0) {
|
|
@@ -863,8 +862,8 @@ export async function analyzeCollectOptions(
|
|
|
863
862
|
)
|
|
864
863
|
|
|
865
864
|
const potentialDeals: PotentialDeal[] = destDeals.map((d) => ({
|
|
866
|
-
goodId: Number(d.
|
|
867
|
-
goodName: d.
|
|
865
|
+
goodId: Number(d.item.id),
|
|
866
|
+
goodName: d.item.item.name,
|
|
868
867
|
destinationCoords: d.destination.coordinates,
|
|
869
868
|
marginPercent: d.marginPercent,
|
|
870
869
|
profitPerSecond: d.profitPerSecond,
|
package/src/trading/deal.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
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 {
|
|
6
6
|
distanceBetweenCoordinates,
|
|
7
7
|
type EstimatedTravelTime,
|
|
8
8
|
estimateTravelTime,
|
|
9
|
-
hasEnergyForDistance,
|
|
10
9
|
} from '../travel/travel'
|
|
11
10
|
import {calculateProfitPerSecond, calculateTradeProfit, isProfitable} from './trade'
|
|
12
11
|
|
|
@@ -18,8 +17,8 @@ export interface Deal {
|
|
|
18
17
|
origin: Location
|
|
19
18
|
/** Destination location */
|
|
20
19
|
destination: Location
|
|
21
|
-
/**
|
|
22
|
-
|
|
20
|
+
/** Item to trade */
|
|
21
|
+
item: ItemPrice
|
|
23
22
|
/** Distance between origin and destination */
|
|
24
23
|
distance: UInt64
|
|
25
24
|
/** Available supply at origin */
|
|
@@ -69,7 +68,7 @@ export async function findDealsForShip(
|
|
|
69
68
|
ship: Ship,
|
|
70
69
|
originLocation: Coordinates,
|
|
71
70
|
getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>,
|
|
72
|
-
getMarketPrices: (location: Coordinates) => Promise<
|
|
71
|
+
getMarketPrices: (location: Coordinates) => Promise<ItemPrice[]>,
|
|
73
72
|
options: FindDealsOptions = {}
|
|
74
73
|
): Promise<Deal[]> {
|
|
75
74
|
const {
|
|
@@ -124,7 +123,7 @@ export async function findDealsForShip(
|
|
|
124
123
|
balance !== undefined
|
|
125
124
|
? balance.dividing(originGood.price)
|
|
126
125
|
: UInt64.from(Number.MAX_SAFE_INTEGER)
|
|
127
|
-
const canHaul = effectiveAvailableMass.dividing(originGood.
|
|
126
|
+
const canHaul = effectiveAvailableMass.dividing(originGood.item.mass)
|
|
128
127
|
const supplyLimit = UInt64.from(originGood.supply)
|
|
129
128
|
|
|
130
129
|
// Find minimum of canAfford, canHaul, supplyLimit
|
|
@@ -135,7 +134,7 @@ export async function findDealsForShip(
|
|
|
135
134
|
if (maxQuantity.equals(UInt64.zero)) continue
|
|
136
135
|
|
|
137
136
|
// Calculate travel time with cargo (includes recharge + load time)
|
|
138
|
-
const cargoMass = originGood.
|
|
137
|
+
const cargoMass = originGood.item.mass.multiplying(maxQuantity)
|
|
139
138
|
const availableSpaceUInt = UInt64.from(availableSpace)
|
|
140
139
|
const baseMass =
|
|
141
140
|
availableSpace !== undefined
|
|
@@ -162,7 +161,7 @@ export async function findDealsForShip(
|
|
|
162
161
|
deals.push({
|
|
163
162
|
origin,
|
|
164
163
|
destination: destLocation,
|
|
165
|
-
|
|
164
|
+
item: originGood,
|
|
166
165
|
distance,
|
|
167
166
|
supply: originGood.supply,
|
|
168
167
|
buyPrice: originGood.price,
|
|
@@ -191,7 +190,7 @@ export async function findBestDeal(
|
|
|
191
190
|
ship: Ship,
|
|
192
191
|
originLocation: Coordinates,
|
|
193
192
|
getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>,
|
|
194
|
-
getMarketPrices: (location: Coordinates) => Promise<
|
|
193
|
+
getMarketPrices: (location: Coordinates) => Promise<ItemPrice[]>,
|
|
195
194
|
options: FindDealsOptions = {}
|
|
196
195
|
): Promise<Deal | undefined> {
|
|
197
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
|
@@ -29,8 +29,9 @@ import {
|
|
|
29
29
|
MIN_ORBITAL_ALTITUDE,
|
|
30
30
|
PRECISION,
|
|
31
31
|
ShipLike,
|
|
32
|
+
TaskType,
|
|
32
33
|
} from '../types'
|
|
33
|
-
import {
|
|
34
|
+
import {getItem} from '../market/items'
|
|
34
35
|
import {hasSystem} from '../utils/system'
|
|
35
36
|
|
|
36
37
|
export function calc_orbital_altitude(mass: number): number {
|
|
@@ -133,7 +134,7 @@ export function calc_flighttime(distance: UInt64Type, acceleration: number): UIn
|
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
export function calc_loader_flighttime(ship: ShipLike, mass: UInt64, altitude?: number): UInt32 {
|
|
136
|
-
const z = altitude ?? ship.
|
|
137
|
+
const z = altitude ?? ship.coordinates.z?.toNumber() ?? calc_orbital_altitude(Number(mass))
|
|
137
138
|
return calc_flighttime(z, calc_loader_acceleration(ship, mass))
|
|
138
139
|
}
|
|
139
140
|
|
|
@@ -157,14 +158,14 @@ export function calc_acceleration(thrust: number, mass: number): number {
|
|
|
157
158
|
export function calc_ship_mass(ship: ShipLike, cargos: CargoMassInfo[]): UInt64 {
|
|
158
159
|
const mass = UInt64.from(0)
|
|
159
160
|
|
|
160
|
-
mass.add(ship.
|
|
161
|
+
mass.add(ship.hullmass)
|
|
161
162
|
|
|
162
163
|
if (ship.loaders.quantity.gt(UInt32.zero)) {
|
|
163
164
|
mass.add(ship.loaders.mass.multiplying(ship.loaders.quantity))
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
for (const cargo of cargos) {
|
|
167
|
-
mass.add(
|
|
168
|
+
mass.add(getItem(cargo.item_id).mass.multiplying(cargo.quantity))
|
|
168
169
|
}
|
|
169
170
|
|
|
170
171
|
return mass
|
|
@@ -182,9 +183,9 @@ export function calculateTransferTime(
|
|
|
182
183
|
let mass = UInt64.from(0)
|
|
183
184
|
|
|
184
185
|
for (const cargo of cargos) {
|
|
185
|
-
const qty = quantities?.get(Number(cargo.
|
|
186
|
+
const qty = quantities?.get(Number(cargo.item_id)) ?? 0
|
|
186
187
|
if (qty > 0) {
|
|
187
|
-
const good_mass =
|
|
188
|
+
const good_mass = getItem(cargo.item_id).mass
|
|
188
189
|
const cargo_mass = good_mass.multiplying(qty)
|
|
189
190
|
mass = UInt64.from(mass).adding(cargo_mass)
|
|
190
191
|
}
|
|
@@ -230,12 +231,12 @@ export function calculateLoadTimeBreakdown(
|
|
|
230
231
|
let mass_load = UInt64.from(0)
|
|
231
232
|
|
|
232
233
|
for (const cargo of cargos) {
|
|
233
|
-
const goodId = Number(cargo.
|
|
234
|
+
const goodId = Number(cargo.item_id)
|
|
234
235
|
const loadQty = loadQuantities?.get(goodId) ?? 0
|
|
235
236
|
const unloadQty = unloadQuantities?.get(goodId) ?? 0
|
|
236
237
|
|
|
237
238
|
if (loadQty > 0 || unloadQty > 0) {
|
|
238
|
-
const good =
|
|
239
|
+
const good = getItem(cargo.item_id)
|
|
239
240
|
|
|
240
241
|
if (loadQty > 0) {
|
|
241
242
|
const cargo_mass = good.mass.multiplying(loadQty)
|
|
@@ -358,6 +359,66 @@ export interface TransferEntity {
|
|
|
358
359
|
}
|
|
359
360
|
}
|
|
360
361
|
|
|
362
|
+
export interface HasScheduleAndLocation {
|
|
363
|
+
coordinates: ServerContract.ActionParams.Type.coordinates
|
|
364
|
+
schedule?: ServerContract.Types.schedule
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export function getFlightOrigin(
|
|
368
|
+
entity: HasScheduleAndLocation,
|
|
369
|
+
flightTaskIndex: number
|
|
370
|
+
): ServerContract.ActionParams.Type.coordinates {
|
|
371
|
+
if (!entity.schedule) return entity.coordinates
|
|
372
|
+
|
|
373
|
+
let origin = entity.coordinates
|
|
374
|
+
for (let i = 0; i < flightTaskIndex && i < entity.schedule.tasks.length; i++) {
|
|
375
|
+
const task = entity.schedule.tasks[i]
|
|
376
|
+
if (task.type.equals(TaskType.TRAVEL) && task.coordinates) {
|
|
377
|
+
origin = task.coordinates
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return origin
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export function getDestinationLocation(
|
|
384
|
+
entity: HasScheduleAndLocation
|
|
385
|
+
): ServerContract.ActionParams.Type.coordinates | undefined {
|
|
386
|
+
if (!entity.schedule) return undefined
|
|
387
|
+
|
|
388
|
+
for (let i = entity.schedule.tasks.length - 1; i >= 0; i--) {
|
|
389
|
+
const task = entity.schedule.tasks[i]
|
|
390
|
+
if (task.type.equals(TaskType.TRAVEL) && task.coordinates) {
|
|
391
|
+
return task.coordinates
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return undefined
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export function getPositionAt(
|
|
398
|
+
entity: HasScheduleAndLocation,
|
|
399
|
+
taskIndex: number,
|
|
400
|
+
taskProgress: number
|
|
401
|
+
): ServerContract.ActionParams.Type.coordinates {
|
|
402
|
+
if (!entity.schedule || entity.schedule.tasks.length === 0 || taskIndex < 0) {
|
|
403
|
+
return entity.coordinates
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const task = entity.schedule.tasks[taskIndex]
|
|
407
|
+
|
|
408
|
+
if (!task.type.equals(TaskType.TRAVEL) || !task.coordinates) {
|
|
409
|
+
return getFlightOrigin(entity, taskIndex)
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const origin = getFlightOrigin(entity, taskIndex)
|
|
413
|
+
const destination = task.coordinates
|
|
414
|
+
|
|
415
|
+
const interpolated = lerp(origin, destination, taskProgress)
|
|
416
|
+
return {
|
|
417
|
+
x: Math.round(interpolated.x),
|
|
418
|
+
y: Math.round(interpolated.y),
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
361
422
|
export function calc_transfer_duration(
|
|
362
423
|
source: TransferEntity,
|
|
363
424
|
dest: TransferEntity,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {Name, UInt16, UInt32} from '@wharfkit/antelope'
|
|
2
|
+
import {ServerContract} from '../contracts'
|
|
3
|
+
|
|
4
|
+
export interface MovementCapability {
|
|
5
|
+
engines: ServerContract.Types.movement_stats
|
|
6
|
+
generator: ServerContract.Types.energy_stats
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface EnergyCapability {
|
|
10
|
+
energy: UInt16
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface StorageCapability {
|
|
14
|
+
capacity: UInt32
|
|
15
|
+
cargomass: UInt32
|
|
16
|
+
cargo: ServerContract.Types.cargo_item[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface LoaderCapability {
|
|
20
|
+
loaders: ServerContract.Types.loader_stats
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface TradeCapability {
|
|
24
|
+
trade: ServerContract.Types.trade_stats
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ExtractorCapability {
|
|
28
|
+
extractor: ServerContract.Types.extractor_stats
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface MassCapability {
|
|
32
|
+
hullmass: UInt32
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ScheduleCapability {
|
|
36
|
+
schedule?: ServerContract.Types.schedule
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface EntityCapabilities {
|
|
40
|
+
hullmass?: UInt32
|
|
41
|
+
capacity?: UInt32
|
|
42
|
+
engines?: ServerContract.Types.movement_stats
|
|
43
|
+
generator?: ServerContract.Types.energy_stats
|
|
44
|
+
loaders?: ServerContract.Types.loader_stats
|
|
45
|
+
trade?: ServerContract.Types.trade_stats
|
|
46
|
+
extractor?: ServerContract.Types.extractor_stats
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface EntityState {
|
|
50
|
+
owner: Name
|
|
51
|
+
location: ServerContract.Types.coordinates
|
|
52
|
+
energy?: UInt16
|
|
53
|
+
cargomass: UInt32
|
|
54
|
+
cargo: ServerContract.Types.cargo_item[]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function capsHasMovement(caps: EntityCapabilities): boolean {
|
|
58
|
+
return caps.engines !== undefined && caps.generator !== undefined
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function capsHasStorage(caps: EntityCapabilities): boolean {
|
|
62
|
+
return caps.capacity !== undefined
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function capsHasLoaders(caps: EntityCapabilities): boolean {
|
|
66
|
+
return caps.loaders !== undefined
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function capsHasTrade(caps: EntityCapabilities): boolean {
|
|
70
|
+
return caps.trade !== undefined
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function capsHasExtractor(caps: EntityCapabilities): boolean {
|
|
74
|
+
return caps.extractor !== undefined
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function capsHasMass(caps: EntityCapabilities): boolean {
|
|
78
|
+
return caps.hullmass !== undefined
|
|
79
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {Name} from '@wharfkit/antelope'
|
|
2
|
+
|
|
3
|
+
export const ENTITY_SHIP = Name.from('ship')
|
|
4
|
+
export const ENTITY_WAREHOUSE = Name.from('warehouse')
|
|
5
|
+
export const ENTITY_CONTAINER = Name.from('container')
|
|
6
|
+
|
|
7
|
+
export type EntityTypeName = 'ship' | 'warehouse' | 'container'
|
|
8
|
+
|
|
9
|
+
export interface EntityTraits {
|
|
10
|
+
typeName: Name
|
|
11
|
+
isMovable: boolean
|
|
12
|
+
hasEnergy: boolean
|
|
13
|
+
hasLoaders: boolean
|
|
14
|
+
hasTrade: boolean
|
|
15
|
+
notFoundError: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const shipTraits: EntityTraits = {
|
|
19
|
+
typeName: ENTITY_SHIP,
|
|
20
|
+
isMovable: true,
|
|
21
|
+
hasEnergy: true,
|
|
22
|
+
hasLoaders: true,
|
|
23
|
+
hasTrade: true,
|
|
24
|
+
notFoundError: 'ship not found',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const warehouseTraits: EntityTraits = {
|
|
28
|
+
typeName: ENTITY_WAREHOUSE,
|
|
29
|
+
isMovable: false,
|
|
30
|
+
hasEnergy: false,
|
|
31
|
+
hasLoaders: true,
|
|
32
|
+
hasTrade: false,
|
|
33
|
+
notFoundError: 'warehouse not found',
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const containerTraits: EntityTraits = {
|
|
37
|
+
typeName: ENTITY_CONTAINER,
|
|
38
|
+
isMovable: true,
|
|
39
|
+
hasEnergy: false,
|
|
40
|
+
hasLoaders: false,
|
|
41
|
+
hasTrade: false,
|
|
42
|
+
notFoundError: 'container not found',
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function getEntityTraits(entityType: Name | EntityTypeName): EntityTraits {
|
|
46
|
+
const typeName = typeof entityType === 'string' ? entityType : entityType.toString()
|
|
47
|
+
|
|
48
|
+
switch (typeName) {
|
|
49
|
+
case 'ship':
|
|
50
|
+
return shipTraits
|
|
51
|
+
case 'warehouse':
|
|
52
|
+
return warehouseTraits
|
|
53
|
+
case 'container':
|
|
54
|
+
return containerTraits
|
|
55
|
+
default:
|
|
56
|
+
throw new Error(`Unknown entity type: ${typeName}`)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function isShip(entity: {type?: Name}): boolean {
|
|
61
|
+
return entity.type?.equals(ENTITY_SHIP) ?? false
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function isWarehouse(entity: {type?: Name}): boolean {
|
|
65
|
+
return entity.type?.equals(ENTITY_WAREHOUSE) ?? false
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function isContainer(entity: {type?: Name}): boolean {
|
|
69
|
+
return entity.type?.equals(ENTITY_CONTAINER) ?? false
|
|
70
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {Name, UInt64} from '@wharfkit/antelope'
|
|
2
|
+
import {ServerContract} from '../contracts'
|
|
3
|
+
import {Coordinates} from '../types'
|
|
4
|
+
import {
|
|
5
|
+
EnergyCapability,
|
|
6
|
+
LoaderCapability,
|
|
7
|
+
MassCapability,
|
|
8
|
+
MovementCapability,
|
|
9
|
+
ScheduleCapability,
|
|
10
|
+
StorageCapability,
|
|
11
|
+
} from './capabilities'
|
|
12
|
+
|
|
13
|
+
export interface Entity {
|
|
14
|
+
id: UInt64
|
|
15
|
+
type: Name
|
|
16
|
+
owner: Name
|
|
17
|
+
entity_name: string
|
|
18
|
+
location: Coordinates | ServerContract.Types.coordinates
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type ShipEntity = Entity &
|
|
22
|
+
MovementCapability &
|
|
23
|
+
EnergyCapability &
|
|
24
|
+
StorageCapability &
|
|
25
|
+
LoaderCapability &
|
|
26
|
+
MassCapability &
|
|
27
|
+
ScheduleCapability & {
|
|
28
|
+
trade?: ServerContract.Types.trade_stats
|
|
29
|
+
extractor?: ServerContract.Types.extractor_stats
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type WarehouseEntity = Entity & StorageCapability & LoaderCapability & ScheduleCapability
|
|
33
|
+
|
|
34
|
+
export type ContainerEntity = Entity & StorageCapability & MassCapability & ScheduleCapability
|
|
35
|
+
|
|
36
|
+
export type AnyEntity = ShipEntity | WarehouseEntity | ContainerEntity
|