Skip to content

Commit

Permalink
waypoint updating
Browse files Browse the repository at this point in the history
  • Loading branch information
staff0rd committed Mar 31, 2024
1 parent 180fde3 commit ad6c13e
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 166 deletions.
36 changes: 0 additions & 36 deletions src/db/getOrPopulateMarkets.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/features/actors/mining-drone.ts
Expand Up @@ -15,7 +15,7 @@ export const miningDroneActorFactory = (
miningLocation: IWaypoint,
keep: TradeSymbol[],
) =>
decisionMaker(miningDrone, agent, act, async (ship: ShipEntity, agent: AgentEntity) => {
decisionMaker(miningDrone, false, agent, act, async (ship: ShipEntity, agent: AgentEntity) => {
await act.refuelShip(ship)
await act.jettisonUnwanted(miningDrone, keep)
if (ship.nav.waypointSymbol !== miningLocation.symbol) {
Expand Down
2 changes: 1 addition & 1 deletion src/features/actors/shuttle.ts
Expand Up @@ -14,7 +14,7 @@ export const shuttleActorFactory = (
miningLocation: IWaypoint,
ships: ShipEntity[],
sell: TradeSymbol[],
) => decisionMaker(shuttle, agent, act, shuttleLogicFactory(act, markets, miningLocation, ships, sell))
) => decisionMaker(shuttle, true, agent, act, shuttleLogicFactory(act, markets, miningLocation, ships, sell))

export const shuttleLogicFactory =
(
Expand Down
3 changes: 2 additions & 1 deletion src/features/ship/ship.entity.ts
Expand Up @@ -87,6 +87,7 @@ export class ShipEntity {
}

get label() {
return `${this.registration.role} (${this.symbol})`
const suffix = this.symbol.match(/-(.+$)/)?.[1] ?? ''
return `${this.registration.role}-${suffix}`
}
}
30 changes: 15 additions & 15 deletions src/features/status/actions/getActor.ts
Expand Up @@ -8,7 +8,8 @@ import { getEntityManager } from '../../../orm'
import { ShipActionType, ShipEntity } from '../../ship/ship.entity'
import { AgentEntity } from '../agent.entity'
import { apiFactory } from '../apiFactory'
import { writeCredits, writeExtraction, writeMarketTransaction, writeShipyardTransaction } from '../influxWrite'
import { writeCredits, writeExtraction, writeMyMarketTransaction, writeShipyardTransaction } from '../influxWrite'
import { updateWaypoint } from '../systemScan'
import { getClosest } from '../utils/getClosest'
import { shipArriving, shipCooldownRemaining } from '../utils/getCurrentFlightTime'
import { getSellLocations } from '../utils/getSellLocations'
Expand Down Expand Up @@ -80,7 +81,7 @@ export const getActor = async (agent: AgentEntity, api: ReturnType<typeof apiFac
} = await api.fleet.refuelShip(ship.symbol)
ship.fuel = fuel

writeMarketTransaction(resetDate, transaction, data)
writeMyMarketTransaction(resetDate, transaction, data)
await updateAgent(agent, { data })

log.info(
Expand All @@ -91,6 +92,12 @@ export const getActor = async (agent: AgentEntity, api: ReturnType<typeof apiFac
}
}

const updateCurrentWaypoint = async (ship: ShipEntity) => {
const em = getEntityManager()
const waypoint = await em.findOneOrFail(WaypointEntity, { symbol: ship.nav.waypointSymbol, resetDate: agent.resetDate })
await updateWaypoint(waypoint, api)
}

const orbitShip = async (ship: ShipEntity) => {
const {
data: {
Expand Down Expand Up @@ -260,7 +267,7 @@ export const getActor = async (agent: AgentEntity, api: ReturnType<typeof apiFac
symbol: p.symbol,
units: p.units,
})
writeMarketTransaction(resetDate, transaction, agent)
writeMyMarketTransaction(resetDate, transaction, agent)
log.info(
'ship',
`${ship.label} sold ${transaction.units} of ${transaction.tradeSymbol} for $${transaction.totalPrice.toLocaleString()}, now have $${agent.credits.toLocaleString()}`,
Expand Down Expand Up @@ -315,19 +322,11 @@ export const getActor = async (agent: AgentEntity, api: ReturnType<typeof apiFac
}
}

const purchaseShip = async (
buyer: ShipEntity,
shipType: ShipType,
shipyards: WaypointEntity[],
markets: WaypointEntity[],
ships: ShipEntity[],
) => {
const shipyardForType = shipyards.find((x) => x.shipyard?.shipTypes.map((s) => s.type).includes(shipType))
invariant(shipyardForType, `Expected to find a shipyard with ${shipType}`)
const shipyard = shipyards.find((x) => x.symbol === shipyardForType.symbol)
const purchaseShip = async (buyer: ShipEntity, shipType: ShipType, waypoints: WaypointEntity[], ships: ShipEntity[]) => {
const shipyard = waypoints.find((x) => x.shipyard?.shipTypes.map((s) => s.type).includes(shipType))
invariant(shipyard, `Expected to find a waypoint for the ${shipType} shipyard`)
if (buyer.nav.route.destination.symbol !== shipyardForType.symbol) {
await navigateShip(buyer, shipyard, markets)
if (buyer.nav.route.destination.symbol !== shipyard.symbol) {
await navigateShip(buyer, shipyard, waypoints)
return
}

Expand Down Expand Up @@ -364,5 +363,6 @@ export const getActor = async (agent: AgentEntity, api: ReturnType<typeof apiFac
updateShipAction,
transferGoods,
jettisonUnwanted,
updateCurrentWaypoint,
}
}
5 changes: 5 additions & 0 deletions src/features/status/decisionMaker.ts
Expand Up @@ -22,6 +22,7 @@ const createDecisionRateMonitor = () => {
}
export const decisionMaker = async (
ship: ShipEntity,
shouldUpdateWaypoint: boolean,
agent: AgentEntity,
act: Awaited<ReturnType<typeof getActor>>,
decisions: (ship: ShipEntity, agent: AgentEntity) => void,
Expand All @@ -33,6 +34,10 @@ export const decisionMaker = async (
try {
const { seconds, distance } = shipArriving(ship)
if (seconds <= 0) {
if (shouldUpdateWaypoint) {
await act.updateCurrentWaypoint(ship)
}

await decisions(ship, agent)
} else {
log.info('ship', `${ship.label} is not yet in position. Waiting for arrival ${distance}`)
Expand Down
35 changes: 26 additions & 9 deletions src/features/status/influxWrite.ts
Expand Up @@ -23,9 +23,21 @@ export const writePoint = <T, K extends keyof T>(
fields,
resetDate,
agentSymbol,
}: { measurementName: string; tags: K[]; fields: K[]; resetDate: string; agentSymbol: string },
timestamp = new Date().toISOString(),
}: {
measurementName: string
tags: K[]
fields: K[]
resetDate: string
agentSymbol: string
timestamp?: string
},
) => {
const point = new Point(measurementName)
if (timestamp) {
const date = new Date(timestamp)
point.timestamp(date)
}
Object.entries(lodash.pick(object, tags)).forEach(([key, value]) => {
point.tag(key, value as string)
})
Expand All @@ -37,14 +49,8 @@ export const writePoint = <T, K extends keyof T>(
influxWrite().writePoint(point)
}

export const writeMarketTransaction = (resetDate: string, transaction: MarketTransaction, agent: Agent) => {
writePoint(transaction, {
measurementName: 'market-transaction',
tags: ['waypointSymbol', 'shipSymbol', 'tradeSymbol', 'type'],
fields: ['units', 'pricePerUnit', 'totalPrice'],
resetDate,
agentSymbol: agent.symbol,
})
export const writeMyMarketTransaction = (resetDate: string, transaction: MarketTransaction, agent: Agent) => {
writeMarketTransaction(transaction, resetDate, agent.symbol)
writeCredits(agent, resetDate)
}

Expand Down Expand Up @@ -85,3 +91,14 @@ export const writeShipyardTransaction = (resetDate: string, transaction: Shipyar
})
writeCredits(agent, resetDate)
}

export function writeMarketTransaction(transaction: MarketTransaction, resetDate: string, agentSymbol: string) {
writePoint(transaction, {
measurementName: 'market-transaction',
tags: ['waypointSymbol', 'shipSymbol', 'tradeSymbol', 'type'],
fields: ['units', 'pricePerUnit', 'totalPrice'],
resetDate,
agentSymbol,
timestamp: transaction.timestamp,
})
}
47 changes: 9 additions & 38 deletions src/features/status/startup.ts
@@ -1,6 +1,4 @@
import lodash from 'lodash'
import { DefaultApiFactory, TradeSymbol } from '../../../api'
import { getOrPopulateMarkets } from '../../db/getOrPopulateMarkets'
import { updateShips } from '../../db/updateShips'
import { invariant } from '../../invariant'
import { log } from '../../logging/configure-logging'
Expand All @@ -10,7 +8,7 @@ import { ShipEntity } from '../ship/ship.entity'
import { getActor } from './actions/getActor'
import { getAgent } from './actions/getAgent'
import { decisionMaker } from './decisionMaker'
import { updateWaypoint } from './updateWaypoint'
import { systemScan } from './systemScan'

export type Position = { x: number; y: number }

Expand All @@ -31,21 +29,21 @@ export async function startup() {

const systemSymbol = commandShip.nav.systemSymbol

const { markets, shipyards } = await initSystem(api, resetDate, systemSymbol)
const waypoints = await systemScan(systemSymbol, resetDate, api)

const {
data: {
data: [engineeredAsteroid],
},
} = await api.systems.getSystemWaypoints(commandShip.nav.systemSymbol, undefined, 20, 'ENGINEERED_ASTEROID')

const miningDronesToPurchase = 15
const miningDronesToPurchase = 20
const shuttlesToPurchase = 1
const keep: TradeSymbol[] = ['IRON_ORE', 'COPPER_ORE', 'ALUMINUM_ORE']

const shuttleLogic = shuttleLogicFactory(act, markets, engineeredAsteroid, ships, keep)
const shuttleLogic = shuttleLogicFactory(act, waypoints, engineeredAsteroid, ships, keep)

await decisionMaker(commandShip, agent, act, async (ship: ShipEntity) => {
await decisionMaker(commandShip, true, agent, act, async (ship: ShipEntity) => {
if (!agent.contract || agent.contract.fulfilled) {
await act.getOrAcceptContract(ship)
return
Expand All @@ -59,57 +57,30 @@ export async function startup() {
const miningDrones = ships.filter((s) => s.frame.symbol === 'FRAME_DRONE')
// TODO: don't hardcode the price
if (miningDrones.length < miningDronesToPurchase && (agent.data?.credits ?? 0) > 50000) {
await act.purchaseShip(commandShip, 'SHIP_MINING_DRONE', shipyards, markets, ships)
await act.purchaseShip(commandShip, 'SHIP_MINING_DRONE', waypoints, ships)
return
} else {
const idleDrones = miningDrones.filter((s) => !s.isCommanded)
idleDrones.forEach((drone) => {
log.warn('command', `Spawning worker for ${drone.label}`)
drone.isCommanded = true
miningDroneActorFactory(drone, agent, act, markets, engineeredAsteroid, keep)
miningDroneActorFactory(drone, agent, act, waypoints, engineeredAsteroid, keep)
})
}

const shuttles = ships.filter((s) => s.frame.symbol === 'FRAME_SHUTTLE')
if (shuttles.length < shuttlesToPurchase) {
await act.purchaseShip(commandShip, 'SHIP_LIGHT_SHUTTLE', shipyards, markets, ships)
await act.purchaseShip(commandShip, 'SHIP_LIGHT_SHUTTLE', waypoints, ships)
return
} else {
const idleShuttles = shuttles.filter((s) => !s.isCommanded)
idleShuttles.forEach((ship) => {
log.warn('command', `Spawning worker for ${ship.label}`)
ship.isCommanded = true
shuttleActorFactory(ship, agent, act, markets, engineeredAsteroid, ships, keep)
shuttleActorFactory(ship, agent, act, waypoints, engineeredAsteroid, ships, keep)
})
}

await shuttleLogic(commandShip, agent)
})
}

const initSystem = async (api: Awaited<ReturnType<typeof getAgent>>['api'], resetDate: string, systemSymbol: string) => {
const {
data: { data: shipyardWaypoints, meta },
//@ts-expect-error because it is wrong
} = await api.systems.getSystemWaypoints(systemSymbol, undefined, 20, undefined, { traits: ['SHIPYARD'] })
invariant(meta.total < 21, 'Expected less than 21 shipyards')

const markets = await getOrPopulateMarkets(api, resetDate, systemSymbol)

const shipyards = await Promise.all(
shipyardWaypoints.map(async (waypoint) => {
const {
data: { data: shipyard },
} = await api.systems.getShipyard(systemSymbol, waypoint.symbol)
const data = lodash.omit(shipyard, 'transactions', 'symbol')
const result = await updateWaypoint(
resetDate,
waypoint.symbol,
{ modificationsFee: data.modificationsFee, shipTypes: data.shipTypes },
data.ships,
)
return result
}),
)
return { markets, shipyards }
}

0 comments on commit ad6c13e

Please sign in to comment.