chest commands, behavior log, better stability

This commit is contained in:
MaxRobinsonTheGreat 2024-09-27 17:03:00 -05:00
parent d44c99356f
commit de7883a0d2
4 changed files with 147 additions and 0 deletions

View file

@ -128,6 +128,16 @@ export class Agent {
const checkInterrupt = () => this.self_prompter.shouldInterrupt(self_prompt) || this.shut_up; const checkInterrupt = () => this.self_prompter.shouldInterrupt(self_prompt) || this.shut_up;
let behavior_log = this.bot.modes.flushBehaviorLog();
if (behavior_log !== '') {
const MAX_LOG = 500;
if (behavior_log.length > MAX_LOG) {
behavior_log = behavior_log.substring(behavior_log.length - MAX_LOG) + '...';
}
behavior_log = 'Recent behaviors log: \n' + behavior_log.substring(behavior_log.indexOf('\n'));
await this.history.add('system', behavior_log);
}
await this.history.add(source, message); await this.history.add(source, message);
this.history.save(); this.history.save();
@ -239,6 +249,10 @@ export class Agent {
this.bot.on('idle', () => { this.bot.on('idle', () => {
this.bot.clearControlStates(); this.bot.clearControlStates();
this.bot.pathfinder.stop(); // clear any lingering pathfinder this.bot.pathfinder.stop(); // clear any lingering pathfinder
if (this.bot.currentWindow) {
this.bot.chat('Closing window...');
this.bot.closeWindow(this.bot.currentWindow);
}
this.bot.modes.unPauseAll(); this.bot.modes.unPauseAll();
this.coder.executeResume(); this.coder.executeResume();
}); });

View file

@ -152,6 +152,36 @@ export const actionsList = [
await skills.equip(agent.bot, item_name); await skills.equip(agent.bot, item_name);
}) })
}, },
{
name: '!putInChest',
description: 'Put the given item in the nearest chest.',
params: {
'item_name': '(string) The name of the item to put in the chest.',
'num': '(number) The number of items to put in the chest.'
},
perform: wrapExecution(async (agent, item_name, num) => {
await skills.putInChest(agent.bot, item_name, num);
})
},
{
name: '!takeFromChest',
description: 'Take the given items from the nearest chest.',
params: {
'item_name': '(string) The name of the item to take.',
'num': '(number) The number of items to take.'
},
perform: wrapExecution(async (agent, item_name, num) => {
await skills.takeFromChest(agent.bot, item_name, num);
})
},
{
name: '!viewChest',
description: 'View the items/counts of the nearest chest.',
params: { },
perform: wrapExecution(async (agent) => {
await skills.viewChest(agent.bot);
})
},
{ {
name: '!discard', name: '!discard',
description: 'Discard the given item from the inventory.', description: 'Discard the given item from the inventory.',

View file

@ -201,6 +201,7 @@ export async function smeltItem(bot, itemName, num=1) {
break; break;
} }
} }
await bot.closeWindow(furnace);
if (placedFurnace) { if (placedFurnace) {
await collectBlock(bot, 'furnace', 1); await collectBlock(bot, 'furnace', 1);
@ -382,6 +383,12 @@ export async function collectBlock(bot, blockType, num=1, exclude=null) {
); );
} }
} }
const movements = new pf.Movements(bot);
movements.dontMineUnderFallingBlock = false;
blocks = blocks.filter(
block => movements.safeToBreak(block)
);
if (blocks.length === 0) { if (blocks.length === 0) {
if (collected === 0) if (collected === 0)
log(bot, `No ${blockType} nearby to collect.`); log(bot, `No ${blockType} nearby to collect.`);
@ -711,6 +718,94 @@ export async function discard(bot, itemName, num=-1) {
return true; return true;
} }
export async function putInChest(bot, itemName, num=-1) {
/**
* Put the given item in the nearest chest.
* @param {MinecraftBot} bot, reference to the minecraft bot.
* @param {string} itemName, the item or block name to put in the chest.
* @param {number} num, the number of items to put in the chest. Defaults to -1, which puts all items.
* @returns {Promise<boolean>} true if the item was put in the chest, false otherwise.
* @example
* await skills.putInChest(bot, "oak_log");
**/
let chest = world.getNearestBlock(bot, 'chest', 32);
if (!chest) {
log(bot, `Could not find a chest nearby.`);
return false;
}
let item = bot.inventory.items().find(item => item.name === itemName);
if (!item) {
log(bot, `You do not have any ${itemName} to put in the chest.`);
return false;
}
let to_put = num === -1 ? item.count : Math.min(num, item.count);
await goToPosition(bot, chest.position.x, chest.position.y, chest.position.z, 2);
const chestContainer = await bot.openContainer(chest);
await chestContainer.deposit(item.type, null, to_put);
await chestContainer.close();
log(bot, `Successfully put ${to_put} ${itemName} in the chest.`);
return true;
}
export async function takeFromChest(bot, itemName, num=-1) {
/**
* Take the given item from the nearest chest.
* @param {MinecraftBot} bot, reference to the minecraft bot.
* @param {string} itemName, the item or block name to take from the chest.
* @param {number} num, the number of items to take from the chest. Defaults to -1, which takes all items.
* @returns {Promise<boolean>} true if the item was taken from the chest, false otherwise.
* @example
* await skills.takeFromChest(bot, "oak_log");
* **/
let chest = world.getNearestBlock(bot, 'chest', 32);
if (!chest) {
log(bot, `Could not find a chest nearby.`);
return false;
}
await goToPosition(bot, chest.position.x, chest.position.y, chest.position.z, 2);
const chestContainer = await bot.openContainer(chest);
let item = chestContainer.containerItems().find(item => item.name === itemName);
if (!item) {
log(bot, `Could not find any ${itemName} in the chest.`);
await chestContainer.close();
return false;
}
let to_take = num === -1 ? item.count : Math.min(num, item.count);
await chestContainer.withdraw(item.type, null, to_take);
await chestContainer.close();
log(bot, `Successfully took ${to_take} ${itemName} from the chest.`);
return true;
}
export async function viewChest(bot) {
/**
* View the contents of the nearest chest.
* @param {MinecraftBot} bot, reference to the minecraft bot.
* @returns {Promise<boolean>} true if the chest was viewed, false otherwise.
* @example
* await skills.viewChest(bot);
* **/
let chest = world.getNearestBlock(bot, 'chest', 32);
if (!chest) {
log(bot, `Could not find a chest nearby.`);
return false;
}
await goToPosition(bot, chest.position.x, chest.position.y, chest.position.z, 2);
const chestContainer = await bot.openContainer(chest);
let items = chestContainer.containerItems();
if (items.length === 0) {
log(bot, `The chest is empty.`);
}
else {
log(bot, `The chest contains:`);
for (let item of items) {
log(bot, `${item.count} ${item.name}`);
}
}
await chestContainer.close();
return true;
}
export async function eat(bot, foodName="") { export async function eat(bot, foodName="") {
/** /**
* Eat the given item. If no item is given, it will eat the first food item in the bot's inventory. * Eat the given item. If no item is given, it will eat the first food item in the bot's inventory.

View file

@ -4,6 +4,7 @@ import * as mc from '../utils/mcdata.js';
import settings from '../../settings.js' import settings from '../../settings.js'
function say(agent, message) { function say(agent, message) {
agent.bot.modes.behavior_log += message + '\n';
if (agent.shut_up || !settings.narrate_behavior) return; if (agent.shut_up || !settings.narrate_behavior) return;
agent.bot.chat(message); agent.bot.chat(message);
} }
@ -261,6 +262,7 @@ class ModeController {
this.agent = agent; this.agent = agent;
this.modes_list = modes; this.modes_list = modes;
this.modes_map = {}; this.modes_map = {};
this.behavior_log = '';
for (let mode of this.modes_list) { for (let mode of this.modes_list) {
this.modes_map[mode.name] = mode; this.modes_map[mode.name] = mode;
} }
@ -320,6 +322,12 @@ class ModeController {
} }
} }
flushBehaviorLog() {
const log = this.behavior_log;
this.behavior_log = '';
return log;
}
getJson() { getJson() {
let res = {}; let res = {};
for (let mode of this.modes_list) { for (let mode of this.modes_list) {