@shipload/sdk 0.3.3 → 0.3.5
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 +66 -30
- package/lib/shipload.js +280 -119
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +262 -115
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -1
- package/src/contracts/server.ts +36 -12
- package/src/epoch.ts +2 -2
- package/src/goods.ts +57 -46
- package/src/market.ts +7 -6
- package/src/shipload.ts +48 -13
- package/src/travel.ts +178 -18
- package/src/types.ts +12 -7
package/src/shipload.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {APIClient, UInt64} from '@wharfkit/antelope'
|
|
2
|
-
import {
|
|
1
|
+
import {APIClient, UInt16Type, UInt64} from '@wharfkit/antelope'
|
|
2
|
+
import {Distance, GoodPrice} from './types'
|
|
3
3
|
import {marketprice, marketprices} from './market'
|
|
4
4
|
import {PlatformContract, ServerContract} from './contracts'
|
|
5
5
|
import {ERROR_SYSTEM_NOT_INITIALIZED} from './errors'
|
|
6
6
|
import {ChainDefinition} from '@wharfkit/session'
|
|
7
7
|
import ContractKit, {Contract} from '@wharfkit/contract'
|
|
8
|
+
import {findNearbyPlanets, hasSystem, travelplan} from './travel'
|
|
8
9
|
|
|
9
10
|
interface ShiploadOptions {
|
|
10
11
|
platformContractName?: string
|
|
@@ -13,8 +14,8 @@ interface ShiploadOptions {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
interface ShiploadConstructorOptions extends ShiploadOptions {
|
|
16
|
-
platformContract
|
|
17
|
-
serverContract
|
|
17
|
+
platformContract?: Contract
|
|
18
|
+
serverContract?: Contract
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export class Shipload {
|
|
@@ -22,10 +23,8 @@ export class Shipload {
|
|
|
22
23
|
public server: Contract
|
|
23
24
|
public platform: Contract
|
|
24
25
|
|
|
25
|
-
constructor(
|
|
26
|
-
|
|
27
|
-
{client, platformContract, serverContract}: ShiploadConstructorOptions
|
|
28
|
-
) {
|
|
26
|
+
constructor(chain: ChainDefinition, constructorOptions?: ShiploadConstructorOptions) {
|
|
27
|
+
const {client, platformContract, serverContract} = constructorOptions || {}
|
|
29
28
|
this.client = client || new APIClient({url: chain.url})
|
|
30
29
|
|
|
31
30
|
this.platform = platformContract
|
|
@@ -37,11 +36,14 @@ export class Shipload {
|
|
|
37
36
|
: new ServerContract.Contract({client: this.client})
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
static async load(
|
|
39
|
+
static async load(
|
|
40
|
+
chain: ChainDefinition,
|
|
41
|
+
shiploadOptions?: ShiploadOptions
|
|
42
|
+
): Promise<Shipload> {
|
|
41
43
|
let platform: Contract = new PlatformContract.Contract({
|
|
42
44
|
client: new APIClient({url: chain.url}),
|
|
43
45
|
})
|
|
44
|
-
if (shiploadOptions
|
|
46
|
+
if (shiploadOptions?.platformContractName) {
|
|
45
47
|
const client = shiploadOptions.client || new APIClient({url: chain.url})
|
|
46
48
|
const contractKit = new ContractKit({client})
|
|
47
49
|
platform = await contractKit.load(shiploadOptions.platformContractName)
|
|
@@ -50,7 +52,7 @@ export class Shipload {
|
|
|
50
52
|
let server: Contract = new ServerContract.Contract({
|
|
51
53
|
client: new APIClient({url: chain.url}),
|
|
52
54
|
})
|
|
53
|
-
if (shiploadOptions
|
|
55
|
+
if (shiploadOptions?.serverContractName) {
|
|
54
56
|
const client = shiploadOptions.client || new APIClient({url: chain.url})
|
|
55
57
|
const contractKit = new ContractKit({client})
|
|
56
58
|
server = await contractKit.load(shiploadOptions.serverContractName)
|
|
@@ -79,15 +81,48 @@ export class Shipload {
|
|
|
79
81
|
return state
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
async marketprice(
|
|
84
|
+
async marketprice(
|
|
85
|
+
location: ServerContract.ActionParams.Type.coordinates,
|
|
86
|
+
good_id: number
|
|
87
|
+
): Promise<UInt64> {
|
|
83
88
|
const game = await this.getGame()
|
|
84
89
|
const state = await this.getState()
|
|
85
90
|
return marketprice(location, good_id, game.config.seed, state.seed)
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
async marketprices(
|
|
93
|
+
async marketprices(
|
|
94
|
+
location: ServerContract.ActionParams.Type.coordinates
|
|
95
|
+
): Promise<GoodPrice[]> {
|
|
89
96
|
const game = await this.getGame()
|
|
90
97
|
const state = await this.getState()
|
|
91
98
|
return marketprices(location, game.config.seed, state.seed)
|
|
92
99
|
}
|
|
100
|
+
|
|
101
|
+
async hasSystem(location: ServerContract.ActionParams.Type.coordinates): Promise<boolean> {
|
|
102
|
+
const game = await this.getGame()
|
|
103
|
+
return hasSystem(game.config.seed, location)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async findNearbyPlanets(
|
|
107
|
+
origin: ServerContract.ActionParams.Type.coordinates,
|
|
108
|
+
maxDistance: UInt16Type = 20
|
|
109
|
+
): Promise<Distance[]> {
|
|
110
|
+
const game = await this.getGame()
|
|
111
|
+
return findNearbyPlanets(game.config.seed, origin, maxDistance)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async travelplan(
|
|
115
|
+
ship: ServerContract.Types.ship_row,
|
|
116
|
+
origin: ServerContract.ActionParams.Type.coordinates,
|
|
117
|
+
destination: ServerContract.ActionParams.Type.coordinates,
|
|
118
|
+
recharge = false
|
|
119
|
+
): Promise<ServerContract.Types.travel_plan> {
|
|
120
|
+
const game = await this.getGame()
|
|
121
|
+
const cargos = await this.server.table('cargo').all({
|
|
122
|
+
from: ship.id,
|
|
123
|
+
to: ship.id,
|
|
124
|
+
index_position: 'secondary',
|
|
125
|
+
})
|
|
126
|
+
return travelplan(game, ship, cargos, origin, destination, recharge)
|
|
127
|
+
}
|
|
93
128
|
}
|
package/src/travel.ts
CHANGED
|
@@ -1,13 +1,33 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BlockTimestamp,
|
|
3
|
+
Checksum256,
|
|
4
|
+
Int64,
|
|
5
|
+
Int64Type,
|
|
6
|
+
UInt32,
|
|
7
|
+
UInt32Type,
|
|
8
|
+
UInt64,
|
|
9
|
+
UInt64Type,
|
|
10
|
+
} from '@wharfkit/antelope'
|
|
2
11
|
|
|
3
|
-
import {ServerContract} from './contracts'
|
|
12
|
+
import {PlatformContract, ServerContract} from './contracts'
|
|
4
13
|
import {hash512} from './hash'
|
|
5
|
-
import {Distance} from './types'
|
|
14
|
+
import {Distance, PRECISION} from './types'
|
|
15
|
+
import {getGood} from './goods'
|
|
6
16
|
|
|
7
|
-
export function
|
|
17
|
+
export function travelplanDuration(travelplan: ServerContract.Types.travel_plan) {
|
|
18
|
+
return UInt32.from(travelplan.flighttime)
|
|
19
|
+
.adding(travelplan.rechargetime)
|
|
20
|
+
.adding(travelplan.loadtime)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function distanceTraveled(
|
|
24
|
+
ship: ServerContract.Types.ship_row,
|
|
25
|
+
current: Date = new Date()
|
|
26
|
+
): number {
|
|
8
27
|
if (ship.travelplan) {
|
|
9
|
-
const {departure
|
|
10
|
-
|
|
28
|
+
const {departure} = ship.travelplan
|
|
29
|
+
const duration = travelplanDuration(ship.travelplan)
|
|
30
|
+
return (+current - +departure.toDate()) / (Number(duration) * 1000)
|
|
11
31
|
}
|
|
12
32
|
return 0
|
|
13
33
|
}
|
|
@@ -15,19 +35,19 @@ export function distanceTraveled(ship: ServerContract.Types.ship_row): number {
|
|
|
15
35
|
export function distanceBetweenCoordinates(
|
|
16
36
|
origin: ServerContract.ActionParams.Type.coordinates,
|
|
17
37
|
destination: ServerContract.ActionParams.Type.coordinates
|
|
18
|
-
):
|
|
38
|
+
): UInt64 {
|
|
19
39
|
return distanceBetweenPoints(origin.x, origin.y, destination.x, destination.y)
|
|
20
40
|
}
|
|
21
41
|
|
|
22
42
|
export function distanceBetweenPoints(
|
|
23
|
-
x1:
|
|
24
|
-
y1:
|
|
25
|
-
x2:
|
|
26
|
-
y2:
|
|
27
|
-
):
|
|
43
|
+
x1: Int64Type,
|
|
44
|
+
y1: Int64Type,
|
|
45
|
+
x2: Int64Type,
|
|
46
|
+
y2: Int64Type
|
|
47
|
+
): UInt64 {
|
|
28
48
|
const x = Math.pow(x1 - x2, 2)
|
|
29
49
|
const y = Math.pow(y1 - y2, 2)
|
|
30
|
-
return
|
|
50
|
+
return UInt64.from(Math.sqrt(x + y) * PRECISION)
|
|
31
51
|
}
|
|
32
52
|
|
|
33
53
|
export function lerp(
|
|
@@ -48,7 +68,7 @@ export function rotation(
|
|
|
48
68
|
return Math.atan2(destination.y - origin.y, destination.x - origin.x) * (180 / Math.PI) + 90
|
|
49
69
|
}
|
|
50
70
|
|
|
51
|
-
export function
|
|
71
|
+
export function hasSystem(
|
|
52
72
|
seed: Checksum256,
|
|
53
73
|
coordinates: ServerContract.ActionParams.Type.coordinates
|
|
54
74
|
): boolean {
|
|
@@ -59,23 +79,29 @@ export function hasPlanet(
|
|
|
59
79
|
export function findNearbyPlanets(
|
|
60
80
|
seed: Checksum256,
|
|
61
81
|
origin: ServerContract.ActionParams.Type.coordinates,
|
|
62
|
-
maxDistance:
|
|
82
|
+
maxDistance: UInt64Type = 20 * PRECISION
|
|
63
83
|
): Distance[] {
|
|
84
|
+
// console.log(String(seed), String(maxDistance), JSON.stringify(origin))
|
|
64
85
|
const nearbySystems: Distance[] = []
|
|
65
86
|
|
|
66
|
-
const max =
|
|
87
|
+
const max = UInt64.from(maxDistance / PRECISION)
|
|
67
88
|
const xMin = Int64.from(origin.x).subtracting(max)
|
|
68
89
|
const xMax = Int64.from(origin.x).adding(max)
|
|
69
90
|
const yMin = Int64.from(origin.y).subtracting(max)
|
|
70
91
|
const yMax = Int64.from(origin.y).adding(max)
|
|
71
92
|
|
|
93
|
+
// console.log('xMin', Number(xMin))
|
|
94
|
+
// console.log('xMax', Number(xMax))
|
|
95
|
+
// console.log('yMin', Number(yMin))
|
|
96
|
+
// console.log('yMax', Number(yMax))
|
|
97
|
+
|
|
72
98
|
for (let x = Number(xMin); x <= Number(xMax); x++) {
|
|
73
99
|
for (let y = Number(yMin); y <= Number(yMax); y++) {
|
|
74
100
|
const samePlace = x === origin.x && y === origin.y
|
|
75
101
|
if (!samePlace) {
|
|
76
102
|
const distance = distanceBetweenPoints(origin.x, origin.y, x, y)
|
|
77
|
-
if (Number(distance) <= Number(
|
|
78
|
-
const system =
|
|
103
|
+
if (Number(distance) <= Number(maxDistance)) {
|
|
104
|
+
const system = hasSystem(seed, {x, y})
|
|
79
105
|
if (system) {
|
|
80
106
|
nearbySystems.push({origin, destination: {x, y}, distance})
|
|
81
107
|
}
|
|
@@ -86,3 +112,137 @@ export function findNearbyPlanets(
|
|
|
86
112
|
|
|
87
113
|
return nearbySystems
|
|
88
114
|
}
|
|
115
|
+
export function travelplan(
|
|
116
|
+
game: PlatformContract.Types.game_row,
|
|
117
|
+
ship: ServerContract.Types.ship_row,
|
|
118
|
+
cargos: ServerContract.Types.cargo_row[],
|
|
119
|
+
origin: ServerContract.ActionParams.Type.coordinates,
|
|
120
|
+
destination: ServerContract.ActionParams.Type.coordinates,
|
|
121
|
+
recharge: boolean
|
|
122
|
+
): ServerContract.Types.travel_plan {
|
|
123
|
+
const valid = hasSystem(game.config.seed, destination)
|
|
124
|
+
if (!valid) {
|
|
125
|
+
throw new Error('Invalid destination')
|
|
126
|
+
}
|
|
127
|
+
const distance = distanceBetweenCoordinates(origin, destination)
|
|
128
|
+
const mass = calc_ship_mass(ship, cargos) // Total mass of ship_id
|
|
129
|
+
const loadtime = calc_ship_loadtime(ship, cargos)
|
|
130
|
+
const flighttime = calc_ship_flighttime(ship, mass, distance)
|
|
131
|
+
const rechargetime = recharge ? calc_ship_rechargetime(ship) : 0
|
|
132
|
+
const energyusage = calc_energyusage(ship.stats.drain, flighttime) // Energy usage from ship and flighttime
|
|
133
|
+
|
|
134
|
+
return ServerContract.Types.travel_plan.from({
|
|
135
|
+
departure: BlockTimestamp.fromDate(new Date()),
|
|
136
|
+
destination,
|
|
137
|
+
loadtime,
|
|
138
|
+
flighttime,
|
|
139
|
+
rechargetime,
|
|
140
|
+
// TODO: Remove below, used for debugging
|
|
141
|
+
distance,
|
|
142
|
+
energyusage,
|
|
143
|
+
mass,
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function calc_rechargetime(
|
|
148
|
+
capacity: UInt32Type,
|
|
149
|
+
energy: UInt32Type,
|
|
150
|
+
recharge: UInt32Type
|
|
151
|
+
): UInt32 {
|
|
152
|
+
return UInt32.from(capacity).subtracting(energy).dividing(recharge)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function calc_ship_rechargetime(ship: ServerContract.Types.ship_row): UInt32 {
|
|
156
|
+
return calc_rechargetime(ship.stats.capacity, ship.state.energy, ship.stats.recharge)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// uint32_t server::calc_ship_rechargetime(const ship_row ship)
|
|
160
|
+
// {
|
|
161
|
+
// return calc_rechargetime(ship.stats.capacity, ship.state.energy, ship.stats.recharge);
|
|
162
|
+
// }
|
|
163
|
+
|
|
164
|
+
export function calc_ship_loadtime(
|
|
165
|
+
ship: ServerContract.Types.ship_row,
|
|
166
|
+
cargos: ServerContract.Types.cargo_row[]
|
|
167
|
+
): UInt32 {
|
|
168
|
+
const loadtime = UInt32.from(0)
|
|
169
|
+
|
|
170
|
+
const mass_load = UInt64.from(0)
|
|
171
|
+
const mass_unload = UInt64.from(0)
|
|
172
|
+
for (const cargo of cargos) {
|
|
173
|
+
const cargo_delta = Number(cargo.quantity) - Number(cargo.loaded)
|
|
174
|
+
if (cargo_delta !== 0) {
|
|
175
|
+
const good_mass = getGood(cargo.good_id).mass
|
|
176
|
+
const cargo_mass = good_mass.multiplying(Math.abs(cargo_delta))
|
|
177
|
+
|
|
178
|
+
if (cargo_delta > 0) {
|
|
179
|
+
mass_load.add(cargo_mass)
|
|
180
|
+
} else {
|
|
181
|
+
mass_unload.add(cargo_mass)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (Number(mass_load) > 0 || Number(mass_unload) > 0) {
|
|
187
|
+
mass_load.add(ship.loaders.mass)
|
|
188
|
+
loadtime.add(calc_loader_flighttime(ship, mass_load))
|
|
189
|
+
|
|
190
|
+
mass_unload.add(ship.loaders.mass)
|
|
191
|
+
loadtime.add(calc_loader_flighttime(ship, mass_unload))
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return loadtime.dividing(ship.loaders.quantity)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function calc_flighttime(distance: UInt64Type, acceleration: number): UInt32 {
|
|
198
|
+
return UInt32.from(2 * Math.sqrt(Number(distance) / acceleration))
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export function calc_loader_flighttime(ship: ServerContract.Types.ship_row, mass: UInt64): UInt32 {
|
|
202
|
+
return calc_flighttime(ship.stats.orbit, calc_loader_acceleration(ship, mass))
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function calc_loader_acceleration(
|
|
206
|
+
ship: ServerContract.Types.ship_row,
|
|
207
|
+
mass: UInt64
|
|
208
|
+
): number {
|
|
209
|
+
return calc_acceleration(Number(ship.loaders.thrust), Number(mass) + Number(ship.loaders.mass))
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export function calc_ship_flighttime(
|
|
213
|
+
ship: ServerContract.Types.ship_row,
|
|
214
|
+
mass: UInt64,
|
|
215
|
+
distance: UInt64
|
|
216
|
+
): UInt32 {
|
|
217
|
+
const acceleration = calc_ship_acceleration(ship, mass)
|
|
218
|
+
return calc_flighttime(distance, acceleration)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function calc_ship_acceleration(ship: ServerContract.Types.ship_row, mass: UInt64): number {
|
|
222
|
+
return calc_acceleration(Number(ship.stats.thrust), Number(mass))
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export function calc_acceleration(thrust: number, mass: number): number {
|
|
226
|
+
return (thrust / mass) * PRECISION
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function calc_ship_mass(
|
|
230
|
+
ship: ServerContract.Types.ship_row,
|
|
231
|
+
cargos: ServerContract.Types.cargo_row[]
|
|
232
|
+
): UInt64 {
|
|
233
|
+
const mass = UInt64.from(ship.stats.mass)
|
|
234
|
+
|
|
235
|
+
if (Number(ship.loaders.quantity) > 0) {
|
|
236
|
+
mass.add(ship.loaders.mass.multiplying(ship.loaders.quantity))
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
for (const cargo of cargos) {
|
|
240
|
+
mass.add(getGood(cargo.good_id).mass.multiplying(cargo.quantity))
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return mass
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export function calc_energyusage(drain: UInt32Type, flighttime: UInt32Type): UInt32 {
|
|
247
|
+
return UInt32.from(drain).multiplying(flighttime)
|
|
248
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import {UInt16, UInt64} from '@wharfkit/antelope'
|
|
1
|
+
import {UInt16, UInt16Type, UInt64, UInt64Type} from '@wharfkit/antelope'
|
|
2
2
|
import {ServerContract} from './contracts'
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
x: number
|
|
6
|
-
y: number
|
|
7
|
-
}
|
|
4
|
+
export const PRECISION = 10000
|
|
8
5
|
|
|
9
|
-
export interface CameraPosition extends
|
|
6
|
+
export interface CameraPosition extends ServerContract.ActionParams.Type.coordinates {
|
|
10
7
|
z: number
|
|
11
8
|
}
|
|
12
9
|
|
|
@@ -29,7 +26,15 @@ export interface Good {
|
|
|
29
26
|
mass: UInt64
|
|
30
27
|
}
|
|
31
28
|
|
|
29
|
+
export interface GoodType {
|
|
30
|
+
id: UInt16Type
|
|
31
|
+
name: string
|
|
32
|
+
description: string
|
|
33
|
+
base_price: UInt64Type
|
|
34
|
+
mass: UInt64Type
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
export interface GoodPrice {
|
|
33
|
-
|
|
38
|
+
good: Good
|
|
34
39
|
price: UInt64
|
|
35
40
|
}
|