@shipload/sdk 2.0.0-rc1 → 2.0.0-rc11
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 +1701 -1183
- package/lib/shipload.js +6746 -3447
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +6429 -3229
- package/lib/shipload.m.js.map +1 -1
- package/package.json +6 -6
- package/src/capabilities/crafting.ts +26 -0
- package/src/capabilities/gathering.ts +36 -0
- package/src/capabilities/guards.ts +38 -0
- package/src/capabilities/hauling.ts +22 -0
- package/src/capabilities/index.ts +8 -0
- package/src/capabilities/loading.ts +8 -0
- package/src/capabilities/modules.ts +57 -0
- package/src/capabilities/movement.ts +29 -0
- package/src/capabilities/storage.ts +72 -0
- package/src/contracts/server.ts +932 -314
- package/src/data/capabilities.ts +408 -0
- package/src/data/categories.ts +58 -0
- package/src/data/colors.ts +53 -0
- package/src/data/items.json +17 -0
- package/src/data/locations.ts +53 -0
- package/src/data/nebula-adjectives.json +211 -0
- package/src/data/nebula-nouns.json +151 -0
- package/src/data/recipes.ts +571 -0
- package/src/data/syllables.json +1386 -780
- package/src/data/tiers.ts +45 -0
- package/src/derivation/crafting.ts +197 -0
- package/src/derivation/index.ts +28 -0
- package/src/derivation/location-size.ts +15 -0
- package/src/derivation/resources.ts +142 -0
- package/src/derivation/stats.ts +146 -0
- package/src/derivation/stratum.ts +124 -0
- package/src/entities/cargo-utils.ts +46 -9
- package/src/entities/container.ts +106 -0
- package/src/entities/entity-inventory.ts +13 -13
- package/src/entities/inventory-accessor.ts +42 -0
- package/src/entities/location.ts +7 -188
- package/src/entities/makers.ts +72 -0
- package/src/entities/player.ts +1 -273
- package/src/entities/ship-deploy.ts +263 -0
- package/src/entities/ship.ts +93 -453
- package/src/entities/warehouse.ts +34 -148
- package/src/errors.ts +4 -4
- package/src/index-module.ts +226 -42
- package/src/managers/actions.ts +111 -79
- package/src/managers/context.ts +0 -9
- package/src/managers/entities.ts +22 -5
- package/src/managers/index.ts +0 -1
- package/src/managers/locations.ts +15 -79
- package/src/market/items.ts +30 -0
- package/src/nft/description.ts +175 -0
- package/src/nft/deserializers.ts +81 -0
- package/src/nft/index.ts +2 -0
- package/src/resolution/resolve-item.ts +313 -0
- package/src/scheduling/accessor.ts +82 -0
- package/src/scheduling/projection.ts +158 -54
- package/src/scheduling/schedule.ts +24 -0
- package/src/shipload.ts +0 -5
- package/src/travel/travel.ts +93 -19
- package/src/types/capabilities.ts +71 -0
- package/src/types/entity-traits.ts +69 -0
- package/src/types/entity.ts +39 -0
- package/src/types/index.ts +3 -0
- package/src/types.ts +76 -33
- package/src/utils/hash.ts +1 -1
- package/src/utils/system.ts +148 -11
- 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 -209
- package/src/market/rolls.ts +0 -8
- package/src/trading/collect.ts +0 -939
- package/src/trading/deal.ts +0 -208
- package/src/trading/trade.ts +0 -203
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {UInt64, UInt64Type} from '@wharfkit/antelope'
|
|
1
|
+
import {UInt32, UInt64, UInt64Type} from '@wharfkit/antelope'
|
|
2
2
|
import {EntityInventory} from './entity-inventory'
|
|
3
|
+
import {ServerContract} from '../contracts'
|
|
3
4
|
|
|
4
5
|
export interface CargoData {
|
|
5
6
|
cargo: EntityInventory[]
|
|
@@ -11,17 +12,11 @@ export function totalCargoMass(cargo: EntityInventory[]): UInt64 {
|
|
|
11
12
|
}, UInt64.from(0))
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
export function
|
|
15
|
-
return cargo.reduce((sum, c) => {
|
|
16
|
-
return sum.adding(c.totalCost)
|
|
17
|
-
}, UInt64.from(0))
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function getCargoForGood(
|
|
15
|
+
export function getCargoForItem(
|
|
21
16
|
cargo: EntityInventory[],
|
|
22
17
|
goodId: UInt64Type
|
|
23
18
|
): EntityInventory | undefined {
|
|
24
|
-
return cargo.find((c) => c.
|
|
19
|
+
return cargo.find((c) => c.item_id.equals(goodId))
|
|
25
20
|
}
|
|
26
21
|
|
|
27
22
|
export function hasSpace(
|
|
@@ -45,3 +40,45 @@ export function availableCapacity(currentMass: UInt64, maxCapacity: UInt64): UIn
|
|
|
45
40
|
export function isFull(currentMass: UInt64, maxCapacity: UInt64): boolean {
|
|
46
41
|
return currentMass.gte(maxCapacity)
|
|
47
42
|
}
|
|
43
|
+
|
|
44
|
+
export function afterRemoveItems(
|
|
45
|
+
cargo: ServerContract.Types.cargo_item[],
|
|
46
|
+
goodsToRemove: Array<{goodId: number; quantity: number}>
|
|
47
|
+
): EntityInventory[] {
|
|
48
|
+
if (cargo.length === 0) {
|
|
49
|
+
return []
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return cargo.map((item) => {
|
|
53
|
+
const removeItem = goodsToRemove.find((s) => Number(item.item_id) === s.goodId)
|
|
54
|
+
if (!removeItem) {
|
|
55
|
+
return new EntityInventory(item)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const currentQty = Number(item.quantity)
|
|
59
|
+
const newQty = Math.max(0, currentQty - removeItem.quantity)
|
|
60
|
+
|
|
61
|
+
return new EntityInventory(
|
|
62
|
+
ServerContract.Types.cargo_item.from({
|
|
63
|
+
item_id: item.item_id,
|
|
64
|
+
quantity: UInt32.from(newQty),
|
|
65
|
+
})
|
|
66
|
+
)
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function afterRemoveAllItems(cargo: ServerContract.Types.cargo_item[]): EntityInventory[] {
|
|
71
|
+
if (cargo.length === 0) {
|
|
72
|
+
return []
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return cargo.map(
|
|
76
|
+
(item) =>
|
|
77
|
+
new EntityInventory(
|
|
78
|
+
ServerContract.Types.cargo_item.from({
|
|
79
|
+
item_id: item.item_id,
|
|
80
|
+
quantity: UInt32.from(0),
|
|
81
|
+
})
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {UInt64, UInt64Type} from '@wharfkit/antelope'
|
|
2
|
+
import {ServerContract} from '../contracts'
|
|
3
|
+
import {CoordinatesType} from '../types'
|
|
4
|
+
import {Location} from './location'
|
|
5
|
+
import {ScheduleAccessor} from '../scheduling/accessor'
|
|
6
|
+
import * as schedule from '../scheduling/schedule'
|
|
7
|
+
|
|
8
|
+
export interface ContainerStateInput {
|
|
9
|
+
id: UInt64Type
|
|
10
|
+
owner: string
|
|
11
|
+
name: string
|
|
12
|
+
coordinates: CoordinatesType | {x: number; y: number; z?: number}
|
|
13
|
+
hullmass: number
|
|
14
|
+
capacity: number
|
|
15
|
+
cargomass?: number
|
|
16
|
+
schedule?: ServerContract.Types.schedule
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class Container extends ServerContract.Types.entity_info {
|
|
20
|
+
private _sched?: ScheduleAccessor
|
|
21
|
+
|
|
22
|
+
get name(): string {
|
|
23
|
+
return this.entity_name
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get sched(): ScheduleAccessor {
|
|
27
|
+
return (this._sched ??= new ScheduleAccessor(this))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get isIdle(): boolean {
|
|
31
|
+
return this.is_idle
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
isLoading(now: Date): boolean {
|
|
35
|
+
return schedule.isLoading(this, now)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
isUnloading(now: Date): boolean {
|
|
39
|
+
return schedule.isUnloading(this, now)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get location(): Location {
|
|
43
|
+
return Location.from(this.coordinates)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get totalMass(): UInt64 {
|
|
47
|
+
return UInt64.from(this.hullmass ?? 0).adding(this.cargomass)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get maxCapacity(): UInt64 {
|
|
51
|
+
return UInt64.from(this.capacity)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get availableCapacity(): UInt64 {
|
|
55
|
+
const cargo = UInt64.from(this.cargomass)
|
|
56
|
+
return cargo.gte(this.maxCapacity) ? UInt64.from(0) : this.maxCapacity.subtracting(cargo)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
hasSpace(additionalMass: UInt64): boolean {
|
|
60
|
+
return UInt64.from(this.cargomass).adding(additionalMass).lte(this.maxCapacity)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get isFull(): boolean {
|
|
64
|
+
return UInt64.from(this.cargomass).gte(this.maxCapacity)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get orbitalAltitude(): number {
|
|
68
|
+
return this.coordinates.z?.toNumber() || 0
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function computeContainerCapabilities(stats: Record<string, number>): {
|
|
73
|
+
hullmass: number
|
|
74
|
+
capacity: number
|
|
75
|
+
} {
|
|
76
|
+
const density = stats['density'] ?? 500
|
|
77
|
+
const strength = stats['strength'] ?? 500
|
|
78
|
+
const ductility = stats['ductility'] ?? 500
|
|
79
|
+
const purity = stats['purity'] ?? 500
|
|
80
|
+
|
|
81
|
+
const hullmass = 25000 + 75 * density
|
|
82
|
+
|
|
83
|
+
const statSum = strength + ductility + purity
|
|
84
|
+
const exponent = statSum / 2997
|
|
85
|
+
const capacity = Math.floor(1000000 * Math.pow(10, exponent))
|
|
86
|
+
|
|
87
|
+
return {hullmass, capacity}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function computeContainerT2Capabilities(stats: Record<string, number>): {
|
|
91
|
+
hullmass: number
|
|
92
|
+
capacity: number
|
|
93
|
+
} {
|
|
94
|
+
const strength = stats['strength'] ?? 0
|
|
95
|
+
const density = stats['density'] ?? 0
|
|
96
|
+
const ductility = stats['ductility'] ?? 0
|
|
97
|
+
const purity = stats['purity'] ?? 0
|
|
98
|
+
|
|
99
|
+
const hullmass = 20000 + 50 * density
|
|
100
|
+
|
|
101
|
+
const statSum = strength + ductility + purity
|
|
102
|
+
const exponent = statSum / 2500
|
|
103
|
+
const capacity = Math.floor(1500000 * Math.pow(10, exponent))
|
|
104
|
+
|
|
105
|
+
return {hullmass, capacity}
|
|
106
|
+
}
|
|
@@ -1,34 +1,34 @@
|
|
|
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 {
|
|
25
29
|
return UInt64.from(this.unitMass).multiplying(this.quantity)
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
get totalCost(): UInt64 {
|
|
29
|
-
return this.unit_cost.multiplying(this.quantity)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
32
|
get hasCargo(): boolean {
|
|
33
33
|
return UInt32.from(this.quantity).gt(UInt32.from(0))
|
|
34
34
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {UInt64, UInt64Type} from '@wharfkit/antelope'
|
|
2
|
+
import {EntityInventory} from './entity-inventory'
|
|
3
|
+
import {HasCargo} from '../capabilities/storage'
|
|
4
|
+
|
|
5
|
+
export type {HasCargo}
|
|
6
|
+
|
|
7
|
+
export class InventoryAccessor {
|
|
8
|
+
private _items?: EntityInventory[]
|
|
9
|
+
|
|
10
|
+
constructor(private readonly entity: HasCargo) {}
|
|
11
|
+
|
|
12
|
+
get items(): EntityInventory[] {
|
|
13
|
+
if (!this._items) {
|
|
14
|
+
this._items = this.entity.cargo.map((item) => new EntityInventory(item))
|
|
15
|
+
}
|
|
16
|
+
return this._items
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get totalMass(): UInt64 {
|
|
20
|
+
return this.items.reduce((sum, c) => sum.adding(c.totalMass), UInt64.from(0))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
forItem(goodId: UInt64Type): EntityInventory | undefined {
|
|
24
|
+
return this.items.find((c) => c.item_id.equals(goodId))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get sellable(): EntityInventory[] {
|
|
28
|
+
return this.items.filter((c) => c.hasCargo)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get hasSellable(): boolean {
|
|
32
|
+
return this.items.some((c) => c.hasCargo)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
get sellableCount(): number {
|
|
36
|
+
return this.items.filter((c) => c.hasCargo).length
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function createInventoryAccessor(entity: HasCargo): InventoryAccessor {
|
|
41
|
+
return new InventoryAccessor(entity)
|
|
42
|
+
}
|
package/src/entities/location.ts
CHANGED
|
@@ -1,35 +1,22 @@
|
|
|
1
|
-
import {Checksum256, Checksum256Type,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {hasSystem} from '../utils/system'
|
|
1
|
+
import {Checksum256, Checksum256Type, UInt16Type, UInt64} from '@wharfkit/antelope'
|
|
2
|
+
import {Coordinates, CoordinatesType, Distance, LocationType} from '../types'
|
|
3
|
+
import {getLocationType, hasSystem, isGatherableLocation} from '../utils/system'
|
|
5
4
|
import {findNearbyPlanets} from '../travel/travel'
|
|
6
5
|
|
|
7
|
-
/**
|
|
8
|
-
* Location helper class for working with game coordinates.
|
|
9
|
-
* Provides system detection, market price caching, nearby planet finding, and supply tracking.
|
|
10
|
-
*/
|
|
11
6
|
export class Location {
|
|
12
7
|
readonly coordinates: Coordinates
|
|
13
|
-
private _marketPrices?: GoodPrice[]
|
|
14
8
|
private _gameSeed?: Checksum256
|
|
15
9
|
private _hasSystem?: boolean
|
|
16
|
-
private _locationRows?: ServerContract.Types.location_row[]
|
|
17
10
|
private _epoch?: UInt64
|
|
18
11
|
|
|
19
12
|
constructor(coordinates: CoordinatesType) {
|
|
20
13
|
this.coordinates = Coordinates.from(coordinates)
|
|
21
14
|
}
|
|
22
15
|
|
|
23
|
-
/**
|
|
24
|
-
* Create a Location from coordinates
|
|
25
|
-
*/
|
|
26
16
|
static from(coordinates: CoordinatesType): Location {
|
|
27
17
|
return new Location(Coordinates.from(coordinates))
|
|
28
18
|
}
|
|
29
19
|
|
|
30
|
-
/**
|
|
31
|
-
* Check if this location has a system (planet)
|
|
32
|
-
*/
|
|
33
20
|
hasSystemAt(gameSeed: Checksum256Type): boolean {
|
|
34
21
|
const seed = Checksum256.from(gameSeed)
|
|
35
22
|
if (this._hasSystem === undefined || !this._gameSeed?.equals(seed)) {
|
|
@@ -39,200 +26,32 @@ export class Location {
|
|
|
39
26
|
return this._hasSystem
|
|
40
27
|
}
|
|
41
28
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*/
|
|
45
|
-
setMarketPrices(prices: GoodPrice[]): void {
|
|
46
|
-
this._marketPrices = prices
|
|
29
|
+
getLocationTypeAt(gameSeed: Checksum256Type): LocationType {
|
|
30
|
+
return getLocationType(gameSeed, this.coordinates)
|
|
47
31
|
}
|
|
48
32
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
*/
|
|
52
|
-
get marketPrices(): GoodPrice[] | undefined {
|
|
53
|
-
return this._marketPrices
|
|
33
|
+
isGatherableAt(gameSeed: Checksum256Type): boolean {
|
|
34
|
+
return isGatherableLocation(this.getLocationTypeAt(gameSeed))
|
|
54
35
|
}
|
|
55
36
|
|
|
56
|
-
/**
|
|
57
|
-
* Get price for a specific good (from cache)
|
|
58
|
-
*/
|
|
59
|
-
getPrice(goodId: UInt16Type): GoodPrice | undefined {
|
|
60
|
-
if (!this._marketPrices) return undefined
|
|
61
|
-
return this._marketPrices.find((p) => p.id.equals(goodId))
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Find nearby planets from this location
|
|
66
|
-
*/
|
|
67
37
|
findNearby(gameSeed: Checksum256Type, maxDistance: UInt16Type = 20): Distance[] {
|
|
68
38
|
return findNearbyPlanets(Checksum256.from(gameSeed), this.coordinates, maxDistance)
|
|
69
39
|
}
|
|
70
40
|
|
|
71
|
-
/**
|
|
72
|
-
* Check if this location equals another location
|
|
73
|
-
*/
|
|
74
41
|
equals(other: CoordinatesType | Location): boolean {
|
|
75
42
|
const otherCoords = other instanceof Location ? other.coordinates : Coordinates.from(other)
|
|
76
43
|
return this.coordinates.equals(otherCoords)
|
|
77
44
|
}
|
|
78
45
|
|
|
79
|
-
/**
|
|
80
|
-
* Set location rows (supply data) for this location
|
|
81
|
-
*/
|
|
82
|
-
setLocationRows(rows: ServerContract.Types.location_row[], epoch: UInt64): void {
|
|
83
|
-
this._locationRows = rows
|
|
84
|
-
this._epoch = epoch
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Get cached location rows (supply data)
|
|
89
|
-
*/
|
|
90
|
-
get locationRows(): ServerContract.Types.location_row[] | undefined {
|
|
91
|
-
return this._locationRows
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Get supply for a specific good at this location
|
|
96
|
-
* Returns undefined if location rows not cached or good not found
|
|
97
|
-
*/
|
|
98
|
-
getSupply(goodId: UInt16Type): UInt16 | undefined {
|
|
99
|
-
if (!this._locationRows) return undefined
|
|
100
|
-
const row = this._locationRows.find(
|
|
101
|
-
(r) => r.good_id.equals(goodId) && this._epoch && r.epoch.equals(this._epoch)
|
|
102
|
-
)
|
|
103
|
-
return row ? row.supply : undefined
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Get all available goods at this location (goods with supply > 0)
|
|
108
|
-
* Returns undefined if location rows not cached
|
|
109
|
-
*/
|
|
110
|
-
get availableGoods(): ServerContract.Types.location_row[] | undefined {
|
|
111
|
-
if (!this._locationRows) return undefined
|
|
112
|
-
return this._locationRows.filter(
|
|
113
|
-
(r) => this._epoch && r.epoch.equals(this._epoch) && r.supply.gt(UInt16.from(0))
|
|
114
|
-
)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Check if a specific good is available (has supply)
|
|
119
|
-
* Returns false if location rows not cached
|
|
120
|
-
*/
|
|
121
|
-
hasGood(goodId: UInt16Type): boolean {
|
|
122
|
-
const supply = this.getSupply(goodId)
|
|
123
|
-
return supply !== undefined && supply.gt(UInt16.from(0))
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Get the epoch for cached location data
|
|
128
|
-
*/
|
|
129
46
|
get epoch(): UInt64 | undefined {
|
|
130
47
|
return this._epoch
|
|
131
48
|
}
|
|
132
49
|
|
|
133
|
-
/**
|
|
134
|
-
* Check if cached data exists
|
|
135
|
-
*/
|
|
136
|
-
get hasCachedData(): boolean {
|
|
137
|
-
return this._marketPrices !== undefined || this._locationRows !== undefined
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Check if supply data is cached
|
|
142
|
-
*/
|
|
143
|
-
get hasSupplyData(): boolean {
|
|
144
|
-
return this._locationRows !== undefined
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Clear all cached data
|
|
149
|
-
*/
|
|
150
50
|
clearCache(): void {
|
|
151
|
-
this._marketPrices = undefined
|
|
152
|
-
this._locationRows = undefined
|
|
153
51
|
this._epoch = undefined
|
|
154
52
|
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Create optimistic Location with updated supply after purchase/sale.
|
|
158
|
-
* Matches contract: update_location_supply (delta can be positive or negative)
|
|
159
|
-
* Contract reference: market.cpp:53, 123-151
|
|
160
|
-
*
|
|
161
|
-
* @param goodId - Good ID to update supply for
|
|
162
|
-
* @param quantityDelta - Change in supply (negative for purchase, positive for sale)
|
|
163
|
-
* @returns New Location with updated supply in cached data
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* // After buying 10 units (supply decreases)
|
|
167
|
-
* const newLocation = location.withUpdatedSupply(1, -10)
|
|
168
|
-
*
|
|
169
|
-
* // After selling 5 units (supply increases)
|
|
170
|
-
* const newLocation = location.withUpdatedSupply(1, 5)
|
|
171
|
-
*/
|
|
172
|
-
withUpdatedSupply(goodId: UInt16Type, quantityDelta: number): Location {
|
|
173
|
-
const newLocation = Location.from(this.coordinates)
|
|
174
|
-
|
|
175
|
-
// Copy market prices if cached
|
|
176
|
-
if (this._marketPrices) {
|
|
177
|
-
newLocation._marketPrices = this._marketPrices.map((price) => {
|
|
178
|
-
if (price.id.equals(goodId)) {
|
|
179
|
-
const currentSupply = UInt16.from(price.supply)
|
|
180
|
-
const delta = UInt16.from(Math.abs(quantityDelta))
|
|
181
|
-
const newSupply =
|
|
182
|
-
quantityDelta < 0
|
|
183
|
-
? currentSupply.gte(delta)
|
|
184
|
-
? currentSupply.subtracting(delta)
|
|
185
|
-
: UInt16.from(0)
|
|
186
|
-
: currentSupply.adding(quantityDelta)
|
|
187
|
-
|
|
188
|
-
return GoodPrice.from({
|
|
189
|
-
id: price.id,
|
|
190
|
-
good: price.good,
|
|
191
|
-
price: price.price,
|
|
192
|
-
supply: newSupply,
|
|
193
|
-
})
|
|
194
|
-
}
|
|
195
|
-
return price
|
|
196
|
-
})
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Copy location rows if cached
|
|
200
|
-
if (this._locationRows && this._epoch) {
|
|
201
|
-
newLocation._locationRows = this._locationRows.map((row) => {
|
|
202
|
-
if (row.good_id.equals(goodId) && row.epoch.equals(this._epoch!)) {
|
|
203
|
-
const currentSupply = UInt16.from(row.supply)
|
|
204
|
-
const delta = UInt16.from(Math.abs(quantityDelta))
|
|
205
|
-
const newSupply =
|
|
206
|
-
quantityDelta < 0
|
|
207
|
-
? currentSupply.gte(delta)
|
|
208
|
-
? currentSupply.subtracting(delta)
|
|
209
|
-
: UInt16.from(0)
|
|
210
|
-
: currentSupply.adding(quantityDelta)
|
|
211
|
-
|
|
212
|
-
return ServerContract.Types.location_row.from({
|
|
213
|
-
id: row.id,
|
|
214
|
-
coordinates: row.coordinates,
|
|
215
|
-
epoch: row.epoch,
|
|
216
|
-
good_id: row.good_id,
|
|
217
|
-
supply: newSupply,
|
|
218
|
-
})
|
|
219
|
-
}
|
|
220
|
-
return row
|
|
221
|
-
})
|
|
222
|
-
newLocation._epoch = this._epoch
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Copy other cached data
|
|
226
|
-
newLocation._gameSeed = this._gameSeed
|
|
227
|
-
newLocation._hasSystem = this._hasSystem
|
|
228
|
-
|
|
229
|
-
return newLocation
|
|
230
|
-
}
|
|
231
53
|
}
|
|
232
54
|
|
|
233
|
-
/**
|
|
234
|
-
* Helper function to convert various coordinate types to Location
|
|
235
|
-
*/
|
|
236
55
|
export function toLocation(coords: CoordinatesType | Location): Location {
|
|
237
56
|
if (coords instanceof Location) {
|
|
238
57
|
return coords
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {Name, UInt16, UInt32, UInt64} from '@wharfkit/antelope'
|
|
2
|
+
import {ServerContract} from '../contracts'
|
|
3
|
+
import {Ship, ShipStateInput} from './ship'
|
|
4
|
+
import {Warehouse, WarehouseStateInput} from './warehouse'
|
|
5
|
+
import {Container, ContainerStateInput} from './container'
|
|
6
|
+
|
|
7
|
+
export function makeShip(state: ShipStateInput): Ship {
|
|
8
|
+
const info: Record<string, unknown> = {
|
|
9
|
+
type: Name.from('ship'),
|
|
10
|
+
id: UInt64.from(state.id),
|
|
11
|
+
owner: Name.from(state.owner),
|
|
12
|
+
entity_name: state.name,
|
|
13
|
+
coordinates: ServerContract.Types.coordinates.from(state.coordinates),
|
|
14
|
+
cargomass: UInt32.from(0),
|
|
15
|
+
cargo: state.cargo || [],
|
|
16
|
+
is_idle: !state.schedule,
|
|
17
|
+
current_task_elapsed: UInt32.from(0),
|
|
18
|
+
current_task_remaining: UInt32.from(0),
|
|
19
|
+
pending_tasks: [],
|
|
20
|
+
}
|
|
21
|
+
if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
|
|
22
|
+
if (state.capacity !== undefined) info.capacity = UInt32.from(state.capacity)
|
|
23
|
+
if (state.energy !== undefined) info.energy = UInt16.from(state.energy)
|
|
24
|
+
if (state.engines) info.engines = state.engines
|
|
25
|
+
if (state.generator) info.generator = state.generator
|
|
26
|
+
if (state.loaders) info.loaders = state.loaders
|
|
27
|
+
if (state.schedule) info.schedule = state.schedule
|
|
28
|
+
const entityInfo = ServerContract.Types.entity_info.from(info)
|
|
29
|
+
return new Ship(entityInfo)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function makeWarehouse(state: WarehouseStateInput): Warehouse {
|
|
33
|
+
const info: Record<string, unknown> = {
|
|
34
|
+
type: Name.from('warehouse'),
|
|
35
|
+
id: UInt64.from(state.id),
|
|
36
|
+
owner: Name.from(state.owner),
|
|
37
|
+
entity_name: state.name,
|
|
38
|
+
coordinates: ServerContract.Types.coordinates.from(state.coordinates),
|
|
39
|
+
capacity: UInt32.from(state.capacity),
|
|
40
|
+
cargomass: UInt32.from(0),
|
|
41
|
+
cargo: state.cargo || [],
|
|
42
|
+
is_idle: !state.schedule,
|
|
43
|
+
current_task_elapsed: UInt32.from(0),
|
|
44
|
+
current_task_remaining: UInt32.from(0),
|
|
45
|
+
pending_tasks: [],
|
|
46
|
+
}
|
|
47
|
+
if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
|
|
48
|
+
if (state.loaders) info.loaders = state.loaders
|
|
49
|
+
if (state.schedule) info.schedule = state.schedule
|
|
50
|
+
const entityInfo = ServerContract.Types.entity_info.from(info)
|
|
51
|
+
return new Warehouse(entityInfo)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function makeContainer(state: ContainerStateInput): Container {
|
|
55
|
+
const entityInfo = ServerContract.Types.entity_info.from({
|
|
56
|
+
type: Name.from('container'),
|
|
57
|
+
id: UInt64.from(state.id),
|
|
58
|
+
owner: Name.from(state.owner),
|
|
59
|
+
entity_name: state.name,
|
|
60
|
+
coordinates: ServerContract.Types.coordinates.from(state.coordinates),
|
|
61
|
+
hullmass: UInt32.from(state.hullmass),
|
|
62
|
+
capacity: UInt32.from(state.capacity),
|
|
63
|
+
cargomass: UInt32.from(state.cargomass || 0),
|
|
64
|
+
cargo: [],
|
|
65
|
+
is_idle: !state.schedule,
|
|
66
|
+
current_task_elapsed: UInt32.from(0),
|
|
67
|
+
current_task_remaining: UInt32.from(0),
|
|
68
|
+
pending_tasks: [],
|
|
69
|
+
schedule: state.schedule,
|
|
70
|
+
})
|
|
71
|
+
return new Container(entityInfo)
|
|
72
|
+
}
|