/** * GoHomeState - Navigate the turtle back to its home position * After arrival, optionally transitions to dump inventory or another state */ import { BaseState } from './BaseState.js'; export class GoHomeState extends BaseState { constructor(turtle, data = {}) { super(turtle, data); this.reason = data.reason || 'manual'; // 'low_fuel', 'inventory_full', 'too_far', 'manual' this.returnState = data.returnState || null; // State to return to after going home this.returnData = data.returnData || {}; } get name() { return 'returning'; } get description() { return `Returning home (${this.reason})`; } async *act() { const home = this.turtle.homePosition; if (!home) { console.log(`[${this.turtle.id}] No home position set, going idle`); this.turtle.setState('idle'); return; } console.log(`[${this.turtle.id}] Going home: reason=${this.reason}`); // Navigate to home using D* Lite const navGen = this.navigateTo(home, { canMine: true }); for await (const _ of navGen) { if (this.cancelled) return; // Check fuel during return const fuel = await this.checkFuel(); if (fuel !== 'unlimited' && fuel < 100) { // Emergency refuel await this.tryRefuel(); } yield; } // Arrived home console.log(`[${this.turtle.id}] Arrived home`); // If we came home to dump inventory, do so if (this.reason === 'inventory_full') { this.turtle.setState('dumpInventory', { returnState: this.returnState, returnData: this.returnData, }); return; } // If we came home to refuel, try refueling if (this.reason === 'low_fuel') { this.turtle.setState('refueling', { returnState: this.returnState, returnData: this.returnData, }); return; } // If there's a return state, go to it if (this.returnState) { this.turtle.setState(this.returnState, this.returnData); return; } // Default: go idle this.turtle.setState('idle'); } getRecoveryData() { return { ...super.getRecoveryData(), data: { reason: this.reason, returnState: this.returnState, returnData: this.returnData, }, }; } }