Updated Idle and Observe logic, and added combat engagement and task locking.
All checks were successful
Deploy Cletus Bot / deploy (push) Successful in 26s
All checks were successful
Deploy Cletus Bot / deploy (push) Successful in 26s
This commit is contained in:
parent
d8ee8d6728
commit
ff43ffc5de
3 changed files with 86 additions and 9 deletions
|
|
@ -2,6 +2,8 @@
|
||||||
let bot = null;
|
let bot = null;
|
||||||
let stateMachine = null;
|
let stateMachine = null;
|
||||||
let lastChat = null;
|
let lastChat = null;
|
||||||
|
let activeTask = null;
|
||||||
|
let combatLocked = false;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setBot: (instance) => { bot = instance; },
|
setBot: (instance) => { bot = instance; },
|
||||||
|
|
@ -16,8 +18,12 @@ module.exports = {
|
||||||
setDB: (dbInstance) => { db = dbInstance; },
|
setDB: (dbInstance) => { db = dbInstance; },
|
||||||
getDB: () => db,
|
getDB: () => db,
|
||||||
|
|
||||||
getContextSnapshot: () => ({
|
getContextSnapshot: () => ({ bot, lastChat }),
|
||||||
bot,
|
|
||||||
lastChat
|
setActiveTask: (taskName) => { activeTask = taskName; },
|
||||||
})
|
clearActiveTask: () => { activeTask = null; },
|
||||||
|
getActiveTask: () => activeTask,
|
||||||
|
|
||||||
|
setCombatLock: (value) => { combatLocked = value; },
|
||||||
|
isCombatLocked: () => combatLocked
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// states/Idle.js
|
// states/Idle.js
|
||||||
const { getBot } = require('../core/context');
|
const { getBot, getActiveTask, isCombatLocked } = require('../core/context');
|
||||||
|
|
||||||
const { GoalNear } = require('mineflayer-pathfinder').goals;
|
const { GoalNear } = require('mineflayer-pathfinder').goals;
|
||||||
const { getHomeZone } = require('../memory/locations');
|
const { getHomeZone } = require('../memory/locations');
|
||||||
|
|
@ -7,9 +7,34 @@ const db = require('../db');
|
||||||
|
|
||||||
module.exports = async function Idle() {
|
module.exports = async function Idle() {
|
||||||
const bot = getBot();
|
const bot = getBot();
|
||||||
|
|
||||||
|
if (getActiveTask() || isCombatLocked()) {
|
||||||
|
console.log('[IDLE] Skipping — locked by task or combat.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
console.log('[STATE] Idle');
|
console.log('[STATE] Idle');
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
|
||||||
|
// Follow and observe a player that is close by. This should eventually become a method to help the player.
|
||||||
|
const players = Object.values(bot.players).filter(p => p.username !== bot.username && p.entity);
|
||||||
|
if (players.length > 0) {
|
||||||
|
const target = players[0].entity;
|
||||||
|
const distance = bot.entity.position.distanceTo(target.position);
|
||||||
|
|
||||||
|
if (distance > 5 || distance < 2) {
|
||||||
|
bot.chat(`Following ${players[0].username}...`);
|
||||||
|
bot.pathfinder.setGoal(new GoalNear(target.position.x, target.position.y, target.position.z, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
getStateMachine().transition('Observe');
|
||||||
|
resolve();
|
||||||
|
}, 10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
getHomeZone(db, async (err, zone) => {
|
getHomeZone(db, async (err, zone) => {
|
||||||
const fallbackCenter = { x: 100, y: 64, z: 100 };
|
const fallbackCenter = { x: 100, y: 64, z: 100 };
|
||||||
const fallbackBounds = { x: 20, y: 10, z: 20 };
|
const fallbackBounds = { x: 20, y: 10, z: 20 };
|
||||||
|
|
@ -20,12 +45,15 @@ module.exports = async function Idle() {
|
||||||
|
|
||||||
const actionRoll = Math.floor(Math.random() * 3);
|
const actionRoll = Math.floor(Math.random() * 3);
|
||||||
|
|
||||||
|
|
||||||
|
// Randomize an action to do things around the home area.
|
||||||
if (actionRoll === 0) {
|
if (actionRoll === 0) {
|
||||||
const grass = bot.findBlock({
|
const grass = bot.findBlock({
|
||||||
matching: block => block.name === 'tall_grass',
|
matching: block => block.name === 'tall_grass',
|
||||||
maxDistance: safeRadius
|
maxDistance: safeRadius
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Cut grass
|
||||||
if (grass) {
|
if (grass) {
|
||||||
await bot.pathfinder.setGoal(new GoalNear(grass.position.x, grass.position.y, grass.position.z, 1));
|
await bot.pathfinder.setGoal(new GoalNear(grass.position.x, grass.position.y, grass.position.z, 1));
|
||||||
try {
|
try {
|
||||||
|
|
@ -34,6 +62,7 @@ module.exports = async function Idle() {
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// manage a farm by harvesting crops.
|
||||||
} else if (actionRoll === 1) {
|
} else if (actionRoll === 1) {
|
||||||
const crops = bot.findBlocks({
|
const crops = bot.findBlocks({
|
||||||
matching: block => ['wheat', 'carrots', 'potatoes'].includes(block.name),
|
matching: block => ['wheat', 'carrots', 'potatoes'].includes(block.name),
|
||||||
|
|
@ -54,6 +83,7 @@ module.exports = async function Idle() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find and attack mobs.
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const mob = Object.values(bot.entities).find(e =>
|
const mob = Object.values(bot.entities).find(e =>
|
||||||
|
|
@ -63,8 +93,24 @@ module.exports = async function Idle() {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (mob) {
|
if (mob) {
|
||||||
|
context.setCombatLock(true);
|
||||||
bot.chat(`Engaging ${mob.name}.`);
|
bot.chat(`Engaging ${mob.name}.`);
|
||||||
bot.attack(mob);
|
bot.attack(mob);
|
||||||
|
|
||||||
|
bot.once('death', () => {
|
||||||
|
context.setCombatLock(false);
|
||||||
|
bot.chat("I died. Lock released.");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Monitor mobs and release combat lock when clear
|
||||||
|
const checkClear = setInterval(() => {
|
||||||
|
const nearbyMobs = Object.values(bot.entities).filter(e => e.type === 'mob');
|
||||||
|
if (nearbyMobs.length === 0) {
|
||||||
|
context.setCombatLock(false);
|
||||||
|
clearInterval(checkClear);
|
||||||
|
bot.chat("Area is clear.");
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
} else {
|
} else {
|
||||||
const dx = Math.floor(Math.random() * safeRadius * 2 - safeRadius);
|
const dx = Math.floor(Math.random() * safeRadius * 2 - safeRadius);
|
||||||
const dz = Math.floor(Math.random() * safeRadius * 2 - safeRadius);
|
const dz = Math.floor(Math.random() * safeRadius * 2 - safeRadius);
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,39 @@ const config = require('../config.json');
|
||||||
|
|
||||||
module.exports = async function Observe() {
|
module.exports = async function Observe() {
|
||||||
const bot = getBot();
|
const bot = getBot();
|
||||||
|
|
||||||
|
if (getActiveTask() || isCombatLocked()) {
|
||||||
|
console.log('[OBSERVE] Skipping — locked by task or combat.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
console.log('[STATE] Observe');
|
console.log('[STATE] Observe');
|
||||||
|
|
||||||
// Example: count nearby entities. I will need to add way more to this observe file later.
|
// Example: count nearby entities. I will need to add way more to this observe file later.
|
||||||
const entities = Object.values(bot.entities).filter(e => e.type === 'mob');
|
const entities = Object.values(bot.entities).filter(e => e.type === 'mob');
|
||||||
const msg = `I see ${entities.length} mobs nearby. What should I do?`;
|
if (entities.length > 0) {
|
||||||
const response = await chatWithAI(msg, config.ai);
|
context.setCombatLock(true);
|
||||||
|
bot.chat(`Noticed ${entities.length} mob(s), engaging...`);
|
||||||
|
|
||||||
bot.chat(response);
|
const mob = entities[0];
|
||||||
|
bot.attack(mob);
|
||||||
|
|
||||||
|
bot.once('death', () => {
|
||||||
|
context.setCombatLock(false);
|
||||||
|
bot.chat("I died. Lock released.");
|
||||||
|
});
|
||||||
|
|
||||||
|
const checkClear = setInterval(() => {
|
||||||
|
const remaining = Object.values(bot.entities).filter(e => e.type === 'mob');
|
||||||
|
if (remaining.length === 0) {
|
||||||
|
context.setCombatLock(false);
|
||||||
|
clearInterval(checkClear);
|
||||||
|
bot.chat("Area is clear.");
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
return; // skip rest of Observe state
|
||||||
|
}
|
||||||
|
|
||||||
await logSurroundings();
|
await logSurroundings();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue