improved unstuck mode, goal resuming

This commit is contained in:
MaxRobinsonTheGreat 2024-10-10 17:40:00 -05:00
parent 05fcc9967c
commit 5482a5dc7e
3 changed files with 40 additions and 34 deletions

View file

@ -102,6 +102,7 @@ export class Coder {
if (this.agent.bot.interrupt_code)
return interrupt_return;
console.log(messages)
this.agent.bot.modes.pause('unstuck');
let res = await this.agent.prompter.promptCoding(JSON.parse(JSON.stringify(messages)));
if (this.agent.bot.interrupt_code)
return interrupt_return;
@ -132,6 +133,7 @@ export class Coder {
agent_history.add('system', 'Failed to stage code, something is wrong.');
return {success: false, message: null, interrupted: false, timedout: false};
}
this.agent.bot.modes.unpause('unstuck');
code_return = await this.execute(async ()=>{
return await execution_file.main(this.agent.bot);
}, settings.code_timeout_mins);
@ -158,11 +160,12 @@ export class Coder {
}
async executeResume(func=null, timeout=10) {
if (func != null) { // start new resume
const new_resume = func != null;
if (new_resume) { // start new resume
this.resume_func = func;
this.resume_name = this.cur_action_name;
}
if (this.resume_func != null && this.agent.isIdle() && !this.agent.self_prompter.on) {
if (this.resume_func != null && this.agent.isIdle() && (!this.agent.self_prompter.on || new_resume)) {
this.cur_action_name = this.resume_name;
let res = await this.execute(this.resume_func, timeout);
this.cur_action_name = '';

View file

@ -181,6 +181,7 @@ export async function smeltItem(bot, itemName, num=1) {
let total = 0;
let collected_last = true;
let smelted_item = null;
bot.mods.pause('unstuck');
await new Promise(resolve => setTimeout(resolve, 200));
while (total < num) {
await new Promise(resolve => setTimeout(resolve, 10000));
@ -202,6 +203,7 @@ export async function smeltItem(bot, itemName, num=1) {
}
}
await bot.closeWindow(furnace);
bot.mods.unpause('unstuck');
if (placedFurnace) {
await collectBlock(bot, 'furnace', 1);
@ -560,10 +562,14 @@ export async function placeBlock(bot, blockType, x, y, z, placeOn='bottom', dont
return true;
}
let block = bot.inventory.items().find(item => item.name === blockType);
let item_name = blockType;
if (item_name == "redstone_wire")
item_name = "redstone";
let block = bot.inventory.items().find(item => item.name === item_name);
if (!block && bot.game.gameMode === 'creative') {
await bot.creative.setInventorySlot(36, mc.makeItem(blockType, 1)); // 36 is first hotbar slot
block = bot.inventory.items().find(item => item.name === blockType);
await bot.creative.setInventorySlot(36, mc.makeItem(item_name, 1)); // 36 is first hotbar slot
block = bot.inventory.items().find(item => item.name === item_name);
}
if (!block) {
log(bot, `Don't have any ${blockType} to place.`);
@ -624,7 +630,7 @@ export async function placeBlock(bot, blockType, x, y, z, placeOn='bottom', dont
const pos = bot.entity.position;
const pos_above = pos.plus(Vec3(0,1,0));
const dont_move_for = ['torch', 'redstone_torch', 'redstone', 'lever', 'button', 'rail', 'detector_rail', 'powered_rail', 'activator_rail', 'tripwire_hook', 'tripwire', 'water_bucket'];
const dont_move_for = ['torch', 'redstone_torch', 'redstone_wire', 'lever', 'button', 'rail', 'detector_rail', 'powered_rail', 'activator_rail', 'tripwire_hook', 'tripwire', 'water_bucket'];
if (!dont_move_for.includes(blockType) && (pos.distanceTo(targetBlock.position) < 1 || pos_above.distanceTo(targetBlock.position) < 1)) {
// too close
let goal = new pf.goals.GoalNear(targetBlock.position.x, targetBlock.position.y, targetBlock.position.z, 2);
@ -964,34 +970,20 @@ export async function followPlayer(bot, username, distance=4) {
bot.pathfinder.setGoal(new pf.goals.GoalFollow(player, distance), true);
log(bot, `You are now actively following player ${username}.`);
let last_time = Date.now();
let stuck_time = 0;
let last_pos = bot.entity.position.clone();
while (!bot.interrupt_code) {
await new Promise(resolve => setTimeout(resolve, 500));
const delta = Date.now() - last_time;
// in cheat mode, if the distance is too far, teleport to the player
if (bot.modes.isOn('cheat') && bot.entity.position.distanceTo(player.position) > 100 && player.isOnGround) {
await goToPlayer(bot, username);
}
if (bot.modes.isOn('unstuck')) {
const far_away = bot.entity.position.distanceTo(player.position) > distance + 1;
if (far_away && bot.entity.position.distanceTo(last_pos) <= 2) {
stuck_time += delta;
if (stuck_time > 10000) {
log(bot, `Got stuck, attempting to move away.`);
bot.pathfinder.stop();
await moveAway(bot, 4);
return false;
const is_nearby = bot.entity.position.distanceTo(player.position) <= distance + 1;
if (is_nearby)
bot.modes.pause('unstuck');
else
bot.modes.unpause('unstuck');
}
}
else {
stuck_time = 0;
last_pos = bot.entity.position.clone();
}
}
last_time = Date.now();
}
return true;
}
@ -1066,6 +1058,7 @@ export async function stay(bot) {
* await skills.stay(bot);
**/
bot.modes.pause('self_preservation');
bot.modes.pause('unstuck');
bot.modes.pause('cowardice');
bot.modes.pause('self_defense');
bot.modes.pause('hunting');

View file

@ -77,7 +77,7 @@ const modes = [
{
name: 'unstuck',
description: 'Attempt to get unstuck when in the same place for a while. Interrupts some actions.',
interrupts: ['collectBlocks', 'goToPlayer', 'collectAllBlocks', 'goToPlace'],
interrupts: ['all'],
on: true,
active: false,
prev_location: null,
@ -86,7 +86,11 @@ const modes = [
last_time: Date.now(),
max_stuck_time: 20,
update: async function (agent) {
if (agent.isIdle()) return;
if (agent.isIdle()) {
this.prev_location = null;
this.stuck_time = 0;
return; // don't get stuck when idle
}
const bot = agent.bot;
if (this.prev_location && this.prev_location.distanceTo(bot.entity.position) < this.distance) {
this.stuck_time += (Date.now() - this.last_time) / 1000;
@ -98,7 +102,9 @@ const modes = [
if (this.stuck_time > this.max_stuck_time) {
say(agent, 'I\'m stuck!');
execute(this, agent, async () => {
const crashTimeout = setTimeout(() => { throw new Error('Bot was stuck and could not get unstuck.'); }, 10000);
await skills.moveAway(bot, 5);
clearTimeout(crashTimeout);
});
}
this.last_time = Date.now();
@ -287,6 +293,17 @@ class ModeController {
this.modes_map[mode_name].paused = true;
}
unpause(mode_name) {
this.modes_map[mode_name].paused = false;
}
unPauseAll() {
for (let mode of this.modes_list) {
if (mode.paused) console.log(`Unpausing mode ${mode.name}`);
mode.paused = false;
}
}
getMiniDocs() { // no descriptions
let res = 'Agent Modes:';
for (let mode of this.modes_list) {
@ -305,13 +322,6 @@ class ModeController {
return res;
}
unPauseAll() {
for (let mode of this.modes_list) {
if (mode.paused) console.log(`Unpausing mode ${mode.name}`);
mode.paused = false;
}
}
async update() {
if (this.agent.isIdle()) {
this.unPauseAll();