// states/Idle.js const { getBot } = require('../core/context'); const { GoalNear } = require('mineflayer-pathfinder').goals; const { getHomeZone } = require('../memory/locations'); const db = require('../db'); module.exports = async function Idle() { const bot = getBot(); console.log('[STATE] Idle'); getHomeZone(db, async (err, zone) => { const fallbackCenter = { x: 100, y: 64, z: 100 }; const fallbackBounds = { x: 20, y: 10, z: 20 }; const center = zone?.center || fallbackCenter; const bounds = zone?.bounds || fallbackBounds; const safeRadius = Math.min(bounds.x, bounds.z); const actionRoll = Math.floor(Math.random() * 3); if (actionRoll === 0) { const grass = bot.findBlock({ matching: block => block.name === 'tall_grass', maxDistance: safeRadius }); if (grass) { await bot.pathfinder.setGoal(new GoalNear(grass.position.x, grass.position.y, grass.position.z, 1)); try { await bot.dig(grass); bot.chat("Trimming grass."); } catch {} } } else if (actionRoll === 1) { const crops = bot.findBlocks({ matching: block => ['wheat', 'carrots', 'potatoes'].includes(block.name), maxDistance: safeRadius, count: 5 }); for (const pos of crops) { const crop = bot.blockAt(pos); if (crop.metadata === 7) { await bot.pathfinder.setGoal(new GoalNear(pos.x, pos.y, pos.z, 1)); try { await bot.dig(crop); bot.chat("Harvesting a crop."); // TODO: Replanting logic needs to be added here. This might be a state or a task.. not sure yet. } catch {} break; } } } else { const mob = Object.values(bot.entities).find(e => e.type === 'mob' && e.position.distanceTo(bot.entity.position) <= safeRadius && e.username !== bot.username ); if (mob) { bot.chat(`Engaging ${mob.name}.`); bot.attack(mob); } else { const dx = Math.floor(Math.random() * safeRadius * 2 - safeRadius); const dz = Math.floor(Math.random() * safeRadius * 2 - safeRadius); const pos = bot.entity.position.offset(dx, 0, dz); bot.pathfinder.setGoal(new GoalNear(pos.x, pos.y, pos.z, 1)); } } }); };