diff options
author | Julien Dessaux | 2023-07-01 23:13:13 +0200 |
---|---|---|
committer | Julien Dessaux | 2023-07-01 23:13:13 +0200 |
commit | 36cc33f9e96a38ecea98ac8d26275b4828347d80 (patch) | |
tree | 653dcea7e656ec815fc0a1fa5664a6b89abccaa3 /nodejs/lib/ships.js | |
parent | Fixed prepared statements (diff) | |
download | spacetraders-36cc33f9e96a38ecea98ac8d26275b4828347d80.tar.gz spacetraders-36cc33f9e96a38ecea98ac8d26275b4828347d80.tar.bz2 spacetraders-36cc33f9e96a38ecea98ac8d26275b4828347d80.zip |
Moved the nodejs agent to its own subfolder to make room for my haskell agent
Diffstat (limited to 'nodejs/lib/ships.js')
-rw-r--r-- | nodejs/lib/ships.js | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/nodejs/lib/ships.js b/nodejs/lib/ships.js new file mode 100644 index 0000000..d75d78e --- /dev/null +++ b/nodejs/lib/ships.js @@ -0,0 +1,187 @@ +import * as api from './api.js'; +import * as dbConfig from '../database/config.js'; +import * as dbShips from '../database/ships.js'; +import * as dbSurveys from '../database/surveys.js'; +import * as systems from '../lib/systems.js'; + +export async function extract(ctx) { + const ship = dbShips.getShip(ctx.symbol); + const asteroidFields = await systems.type({symbol: ship.nav.systemSymbol, type: 'ASTEROID_FIELD'}); + // TODO if there are multiple fields, find the closest one? + await navigate({symbol: ctx.symbol, waypoint: asteroidFields[0].symbol}); + await orbit(ctx); + // TODO handle surveying? + const response = await api.send({endpoint: `/my/ships/${ctx.symbol}/extract`, method: 'POST'}); + if (response.error !== undefined) { + switch(response.error.code) { + case 4000: // ship is on cooldown + await api.sleep(response.error.data.cooldown.remainingSeconds * 1000); + return await extract(ctx); + case 4228: // ship is full + return null; + default: // yet unhandled error + throw response; + } + } else { + dbShips.setShipCargo(ctx.symbol, response.data.cargo); + await api.sleep(response.data.cooldown.remainingSeconds*1000); + } + return response; +} + +export async function dock(ctx) { + const ship = dbShips.getShip(ctx.symbol); + if (ship.nav.status === 'DOCKED') { + return null; + } + const response = await api.send({endpoint: `/my/ships/${ctx.symbol}/dock`, method: 'POST'}); + if (response.error !== undefined) { + switch(response.error.code) { + case 4214: // ship is in transit + await api.sleep(response.error.data.secondsToArrival * 1000); + return await dock(ctx); + default: // yet unhandled error + throw response; + } + } + dbShips.setShipNav(ctx.symbol, response.data.nav); + return response; +} + +function hasMount(shipSymbol, mountSymbol) { + const ship = dbShips.getShip(shipSymbol); + return ship.mounts.filter(s => s.symbol === mountSymbol).length > 0; +} + +export async function jump(ctx) { + // TODO + const response = await api.send({endpoint: `/my/ships/${ctx.ship}/jump`, method: 'POST', payload: { systemSymbol: ctx.system }}); + await api.sleep(response.data.cooldown.remainingSeconds*1000); + return response; +} + +export async function navigate(ctx) { + const ship = dbShips.getShip(ctx.symbol); + if (ship.nav.waypointSymbol === ctx.waypoint) { + return await orbit(ctx); + } + await orbit(ctx); + // TODO if we do not have enough fuel, make a stop to refuel along the way or drift to the destination + const response = await api.send({endpoint: `/my/ships/${ctx.symbol}/navigate`, method: 'POST', payload: { waypointSymbol: ctx.waypoint }}); + if (response.error !== undefined) { + switch(response.error.code) { + case 4214: // ship is in transit + await api.sleep(response.error.data.secondsToArrival * 1000); + return await navigate(ctx); + default: // yet unhandled error + throw response; + } + } + dbShips.setShipFuel(ctx.symbol, response.data.fuel); + dbShips.setShipNav(ctx.symbol, response.data.nav); + const delay = new Date(response.data.nav.route.arrival) - new Date(); + await api.sleep(delay); + response.data.nav.status = 'IN_ORBIT'; + dbShips.setShipNav(ctx.symbol, response.data.nav); + await refuel(ctx); + return response; +} + +export async function negotiate(ctx) { + // TODO + return await api.send({endpoint: `/my/ships/${ctx.ship}/negotiate/contract`, method: 'POST'}); +} + +export async function orbit(ctx) { + const ship = dbShips.getShip(ctx.symbol); + if (ship.nav.status === 'IN_ORBIT') { + return null; + } + const response = await api.send({endpoint: `/my/ships/${ctx.symbol}/orbit`, method: 'POST'}); + if (response.error !== undefined) { + switch(response.error.code) { + case 4214: // ship is in transit + await api.sleep(response.error.data.secondsToArrival * 1000); + return await orbit(ctx); + default: // yet unhandled error + throw response; + } + } + dbShips.setShipNav(ctx.symbol, response.data.nav); + return response; +} + +export async function purchase(ctx) { + const response = await api.send({endpoint: '/my/ships', method: 'POST', payload: { + shipType: ctx.shipType, + waypointSymbol: ctx.waypoint, + }}); + if (response.error !== undefined) { + throw response; + } + dbShips.setShip(response.data.ship); + return response.data; +} + +export async function refuel(ctx) { + const ship = dbShips.getShip(ctx.symbol); + if (ship.fuel.current >= ship.fuel.capacity * 0.9) { + return null; + } + // TODO check if our current waypoint has a marketplace (and sells fuel)? + await dock(ctx); + const response = await api.send({endpoint: `/my/ships/${ctx.symbol}/refuel`, method: 'POST'}); + if (response.error !== undefined) { + throw response; + } + dbShips.setShipFuel(ctx.symbol, response.data.fuel); + // TODO track credits + return response; +} + +export async function sell(ctx) { + // TODO check if our current waypoint has a marketplace (and sells fuel)? + await dock(ctx); + const ship = dbShips.getShip(ctx.symbol); + const response = await api.send({endpoint: `/my/ships/${ctx.symbol}/sell`, method: 'POST', payload: { symbol: ctx.good, units: ctx.units }}); + if (response.error !== undefined) { + throw response; + } + dbShips.setShipCargo(ctx.symbol, response.data.cargo); + // TODO track credits + return response; +} + +export async function ship(ctx) { + const response = await api.send({endpoint: `/my/ships/${ctx.symbol}`}); + if (response.error !== undefined) { + throw response; + } + dbShips.setShip(response.data); + return response; +} + +export async function survey(ctx) { + if (!hasMount(ctx.symbol, 'MOUNT_SURVEYOR_I')) { // we check if a surveyor is mounted on the ship + return null; + } + const ship = dbShips.getShip(ctx.symbol); + const asteroidFields = await systems.type({symbol: ship.nav.systemSymbol, type: 'ASTEROID_FIELD'}); + // TODO if there are multiple fields, find the closest one? + await navigate({symbol: ctx.symbol, waypoint: asteroidFields[0].symbol}); + await orbit(ctx); + const response = await api.send({endpoint: `/my/ships/${ctx.symbol}/survey`, method: 'POST'}); + api.debugLog(response); + if (response.error !== undefined) { + switch(response.error.code) { + case 4000: // ship is on cooldown + await api.sleep(response.error.data.cooldown.remainingSeconds * 1000); + return await survey(ctx); + default: // yet unhandled error + throw response; + } + } + dbSurveys.set(response.data.surveys[0]); + await api.sleep(response.data.cooldown.remainingSeconds*1000); + return response; +} |