From 668d4a368506f6b06edcccb78f55b3868eb14cb5 Mon Sep 17 00:00:00 2001 From: MayaTheShy Date: Fri, 20 Feb 2026 02:12:56 -0500 Subject: [PATCH] feat: Enhance Turtle class with new properties and real-time event handling for peripherals and inventory --- server/Turtle.js | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/server/Turtle.js b/server/Turtle.js index 3f435cd..9fdd781 100644 --- a/server/Turtle.js +++ b/server/Turtle.js @@ -53,8 +53,13 @@ export class Turtle extends EventEmitter { this._homePosition = null; this._facing = 0; this._fuel = 0; + this._fuelLimit = 100000; this._inventory = {}; + this._selectedSlot = 1; this._label = null; + this._peripherals = {}; // { side: { types: [...], data: {...} } } + this._error = null; + this._warning = null; // State machine this._state = null; @@ -127,6 +132,49 @@ export class Turtle extends EventEmitter { this._emitUpdate(); } + get peripherals() { + return this._peripherals; + } + + set peripherals(value) { + this._peripherals = value; + this._emitUpdate(); + } + + get selectedSlot() { + return this._selectedSlot; + } + + set selectedSlot(value) { + this._selectedSlot = value; + } + + get fuelLimit() { + return this._fuelLimit; + } + + set fuelLimit(value) { + this._fuelLimit = value; + } + + get error() { + return this._error; + } + + set error(value) { + this._error = value; + if (value) this._emitUpdate(); + } + + get warning() { + return this._warning; + } + + set warning(value) { + this._warning = value; + if (value) this._emitUpdate(); + } + get stateName() { return this._state?.name || 'idle'; } @@ -245,6 +293,53 @@ export class Turtle extends EventEmitter { this.emit('sendCommand', command); } + // ========== Real-time Event Handling ========== + + /** + * Handle real-time events from the turtle (inventory, peripherals, etc.) + * These come via the webbridge as separate event messages. + */ + handleEvent(eventType, eventData) { + switch (eventType) { + case 'INVENTORY_UPDATE': + this._inventory = eventData; + this._emitUpdate(); + break; + case 'PERIPHERAL_ATTACHED': + // Merge new peripherals + this._peripherals = { ...this._peripherals, ...eventData }; + this._emitUpdate(); + break; + case 'PERIPHERAL_DETACHED': + // eventData is the side name string + if (typeof eventData === 'string' && this._peripherals[eventData]) { + const { [eventData]: _, ...rest } = this._peripherals; + this._peripherals = rest; + this._emitUpdate(); + } + break; + default: + console.log(`[Turtle ${this.id}] Unknown event type: ${eventType}`); + } + } + + /** + * Check if turtle has a peripheral with the given type name + */ + hasPeripheral(typeName) { + return Object.values(this._peripherals).some(p => + p.types && p.types.includes(typeName) + ); + } + + /** + * Get the chunk coordinates for this turtle's position + */ + get chunk() { + if (!this._position) return null; + return [Math.floor(this._position.x / 16), Math.floor(this._position.z / 16)]; + } + /** * Handle a response from the turtle (matched by UUID) */