Something went wrong. Try again.
Your trusty automation assistant in TLE Community misadventures!
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203import _ from 'lodash'
import { lacuna, call, findPlanets, eachPlanet, findBuilding, log, util,} from '@tlecommunity/super-core'
import { buildRoom, distance, scanOutward } from './starmap'
class SendProbes { constructor(options) { this.options = options
this.probesSent = 0 }
validateOptions() { return new Promise((resolve, reject) => { if (!this.options.planet) { reject('please specify a planet') } else { resolve(true) } }) }
async buildToFill(colony, sy, toBuild) { let quantity = await buildRoom(sy, toBuild)
if (quantity <= 0) { log.info(`No room to build more probes on ${colony.name}`) return }
if (quantity < toBuild) { log.info(`Only room for ${quantity} of ${toBuild} new probes on ${colony.name}`) }
let plural = util.handlePlurality(quantity, 'probe') log.info(`Building ${quantity} ${plural} on ${colony.name}`)
if (!this.options.dryRun) { await call(() => lacuna.shipyard.buildShips({ options: { autoselect: 'all', body_id: colony.id, building_id: sy.id, quantity, type: 'probe', }, }) ) } }
async handleColony(colony, buildings) { let obs = await findBuilding(buildings, 'Observatory') let sy = await findBuilding(buildings, 'Shipyard') let sp = await findBuilding(buildings, 'Space Port')
if (!obs || !sy || !sp) { log.info(`${colony.name} needs an Observatory, Shipyard and Space Port - skipping`) return }
let probed = await call(() => lacuna.observatory.getProbedStars({ building_id: obs.id, page_number: 1 }) ) let controlled = util.int(probed.star_count) let inTransit = util.int(probed.travelling) let max = util.int(probed.max_probes)
let ships = await call(() => lacuna.spacePort.viewAllShips({ building_id: sp.id, paging: { no_paging: 1 }, filter: { type: 'probe', task: 'Docked' }, }) ) let dockedProbes = ships.ships || [] let docked = dockedProbes.length
let freeCap = max - controlled - inTransit
if (freeCap <= 0) { log.info( `Observatory on ${colony.name} is at capacity (${controlled}/${max}, ${inTransit} inbound)` ) return }
let toBuild = freeCap - docked if (toBuild > 0) { await this.buildToFill(colony, sy, toBuild) }
let sendCount = Math.min(freeCap, docked) if (sendCount <= 0) { log.info(`No probes ready to send from ${colony.name} (${freeCap} slot(s) free)`) return }
let status = await call(() => lacuna.body.getStatus({ body_id: colony.id })) let origin = { x: util.int(status.body.x), y: util.int(status.body.y) }
let candidates = [] await scanOutward(origin, { maxRing: 2, enough: (n) => n >= sendCount * 4, collect: (star) => { if (star.bodies || star.station) { return false }
candidates.push({ id: star.id, name: star.name, x: util.int(star.x), y: util.int(star.y) }) return true }, })
candidates = _.sortBy(candidates, (s) => distance(origin, s))
let chosen = [] for (const star of candidates) { if (chosen.length >= sendCount) { break }
let incoming = await call(() => lacuna.map.checkStarForIncomingProbe({ star_id: star.id })) // The client coerces numeric strings to numbers, so compare numerically. if (incoming.incoming_probe && util.int(incoming.incoming_probe) !== 0) { continue }
chosen.push(star) }
if (chosen.length === 0) { log.info(`No unprobed stars in range of ${colony.name}`) return }
for (const star of chosen) { let dist = distance(origin, star).toFixed(1)
if (this.options.dryRun) { log.info(`Would send a probe from ${colony.name} to ${star.name} (${dist} away)`) this.probesSent++ continue }
let ship = dockedProbes.shift() if (!ship) { break }
try { await call(() => lacuna.spacePort.sendShip({ ship_id: ship.id, target: { star_id: star.id } }) ) this.probesSent++ log.info(`Sent a probe from ${colony.name} to ${star.name} (${dist} away)`) } catch (err) { log.error(`Couldn't send a probe to ${star.name}: ${err}`) dockedProbes.unshift(ship) } }
if (chosen.length < sendCount) { log.info( `Only found ${chosen.length} of ${sendCount} unprobed stars within range of ${colony.name}` ) } }
run() { return new Promise((resolve, reject) => { findPlanets(this.options.planet) .then((colonies) => { return eachPlanet(colonies, _.bind(this.handleColony, this), { force: true, }) }) .then(() => { if (this.probesSent > 0) { let plural = util.handlePlurality(this.probesSent, 'probe') resolve(`Sent ${this.probesSent} ${plural}`) } else { resolve(`Didn't send any probes`) } }) .catch(reject) }) }}
export default SendProbes