@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/src/shipload.ts CHANGED
@@ -1,10 +1,11 @@
1
- import {APIClient, UInt64} from '@wharfkit/antelope'
2
- import {Coordinates, GoodPrice} from './types'
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: Contract
17
- serverContract: Contract
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
- chain: ChainDefinition,
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(chain: ChainDefinition, shiploadOptions: ShiploadOptions): Promise<Shipload> {
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.platformContractName) {
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.serverContractName) {
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(location: Coordinates, good_id: number): Promise<UInt64> {
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(location: Coordinates): Promise<GoodPrice[]> {
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 {Checksum256, Int64, UInt16, UInt16Type, UInt64, UInt64Type} from '@wharfkit/antelope'
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 distanceTraveled(ship: ServerContract.Types.ship_row): number {
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, duration} = ship.travelplan
10
- return (+new Date() - +departure.toDate()) / (Number(duration) * 1000)
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
- ): UInt16 {
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: UInt64Type,
24
- y1: UInt64Type,
25
- x2: UInt64Type,
26
- y2: UInt64Type
27
- ): UInt16 {
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 UInt16.from(Math.sqrt(x + y))
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 hasPlanet(
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: UInt16Type = 20
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 = UInt16.from(maxDistance)
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(max)) {
78
- const system = hasPlanet(seed, {x, y})
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 interface Coordinates {
5
- x: number
6
- y: number
7
- }
4
+ export const PRECISION = 10000
8
5
 
9
- export interface CameraPosition extends Coordinates {
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
- id: UInt16
38
+ good: Good
34
39
  price: UInt64
35
40
  }