From feac9ab424392873a652c7bc1481aa44c5931982 Mon Sep 17 00:00:00 2001 From: MaxRobinsonTheGreat Date: Mon, 5 Feb 2024 19:08:08 -0600 Subject: [PATCH] various improvements --- src/agent/coder.js | 2 +- src/agent/commands/actions.js | 20 +++++++++++++------- src/agent/library/skills.js | 29 +++++++++++++++++------------ src/examples.json | 12 ++++++++---- 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/agent/coder.js b/src/agent/coder.js index aca2f5c..08c7121 100644 --- a/src/agent/coder.js +++ b/src/agent/coder.js @@ -99,7 +99,7 @@ export class Coder { let system_message = "You are a minecraft mineflayer bot that plays minecraft by writing javascript codeblocks. Given the conversation between you and the user, use the provided skills and world functions to write your code in a codeblock. Example response: ``` // your code here ``` You will then be given a response to your code. If you are satisfied with the response, respond without a codeblock in a conversational way. If something went wrong, write another codeblock and try to fix the problem."; system_message += getSkillDocs(); - system_message += "\n\nExamples:\nUser zZZn98: come here \nAssistant: I am going to navigate to zZZn98. ```\nawait skills.goToPlayer(bot, 'zZZn98');```\nSystem: Code execution finished successfully.\nAssistant: Done."; + system_message += "\n\nExamples:\nUser zZZn98: come here \nAssistant: I am going to navigate to zZZn98. ```\nawait skills.goToPlayer(bot, 'zZZn98', 3);```\nSystem: Code execution finished successfully.\nAssistant: Done."; let messages = await agent_history.getHistory(this.examples); diff --git a/src/agent/commands/actions.js b/src/agent/commands/actions.js index d9b88cf..d89b2a7 100644 --- a/src/agent/commands/actions.js +++ b/src/agent/commands/actions.js @@ -73,18 +73,24 @@ export const actionsList = [ }, { name: '!goToPlayer', - description: 'Go to the given player. Ex: !goToPlayer("steve")', - params: {'player_name': '(string) The name of the player to go to.'}, - perform: wrapExecution(async (agent, player_name) => { - return await skills.goToPlayer(agent.bot, player_name); + description: 'Go to the given player. Ex: !goToPlayer("steve", 3)', + params: { + 'player_name': '(string) The name of the player to go to.', + 'closeness': '(number) How close to get to the player.' + }, + perform: wrapExecution(async (agent, player_name, closeness) => { + return await skills.goToPlayer(agent.bot, player_name, closeness); }) }, { name: '!followPlayer', description: 'Endlessly follow the given player. Will defend that player if self_defense mode is on. Ex: !followPlayer("stevie")', - params: {'player_name': '(string) The name of the player to follow.'}, - perform: wrapExecution(async (agent, player_name) => { - await skills.followPlayer(agent.bot, player_name); + params: { + 'player_name': '(string) The name of the player to follow.', + 'follow_dist': '(number) The distance to follow from.' + }, + perform: wrapExecution(async (agent, player_name, follow_dist) => { + await skills.followPlayer(agent.bot, player_name, follow_dist); }, -1, 'followPlayer') }, { diff --git a/src/agent/library/skills.js b/src/agent/library/skills.js index d5abb0b..06892cf 100644 --- a/src/agent/library/skills.js +++ b/src/agent/library/skills.js @@ -27,11 +27,16 @@ async function autoLight(bot) { return false; } -function equipHighestAttack(bot) { - let weapons = bot.inventory.items().filter(item => item.name.includes('sword') || item.name.includes('axe') || item.name.includes('pickaxe') || item.name.includes('shovel')); - let weapon = weapons.sort((a, b) => b.attackDamage - a.attackDamage)[0]; +async function equipHighestAttack(bot) { + let weapons = bot.inventory.items().filter(item => item.name.includes('sword') || (item.name.includes('axe') && !item.name.includes('pickaxe'))); + if (weapons.length === 0) + weapons = bot.inventory.items().filter(item => item.name.includes('pickaxe') || item.name.includes('shovel')); + if (weapons.length === 0) + return; + weapons.sort((a, b) => a.attackDamage < b.attackDamage); + let weapon = weapons[0]; if (weapon) - bot.equip(weapon, 'hand'); + await bot.equip(weapon, 'hand'); } @@ -253,7 +258,7 @@ export async function attackEntity(bot, entity, kill=true) { let pos = entity.position; console.log(bot.entity.position.distanceTo(pos)) - equipHighestAttack(bot) + await equipHighestAttack(bot) if (!kill) { if (bot.entity.position.distanceTo(pos) > 5) { @@ -291,7 +296,7 @@ export async function defendSelf(bot, range=9) { let attacked = false; let enemy = world.getNearestEntityWhere(bot, entity => mc.isHostile(entity), range); while (enemy) { - equipHighestAttack(bot); + await equipHighestAttack(bot); if (bot.entity.position.distanceTo(enemy.position) > 4 && enemy.name !== 'creeper' && enemy.name !== 'phantom') { try { bot.pathfinder.setMovements(new pf.Movements(bot)); @@ -429,7 +434,7 @@ export async function breakBlockAt(bot, x, y, z) { let movements = new pf.Movements(bot); movements.canPlaceOn = false; movements.allow1by1towers = false; - bot.pathfinder.setMovements(); + bot.pathfinder.setMovements(movements); await bot.pathfinder.goto(new pf.goals.GoalNear(pos.x, pos.y, pos.z, 4)); } await bot.dig(block, true); @@ -639,11 +644,12 @@ export async function goToPosition(bot, x, y, z, min_distance=2) { } -export async function goToPlayer(bot, username) { +export async function goToPlayer(bot, username, distance=3) { /** * Navigate to the given player. * @param {MinecraftBot} bot, reference to the minecraft bot. * @param {string} username, the username of the player to navigate to. + * @param {number} distance, the goal distance to the player. * @returns {Promise} true if the player was found, false otherwise. * @example * await skills.goToPlayer(bot, "player"); @@ -656,13 +662,13 @@ export async function goToPlayer(bot, username) { } bot.pathfinder.setMovements(new pf.Movements(bot)); - await bot.pathfinder.goto(new pf.goals.GoalFollow(player, 3), true); + await bot.pathfinder.goto(new pf.goals.GoalFollow(player, distance), true); log(bot, `You have reached ${username}.`); } -export async function followPlayer(bot, username) { +export async function followPlayer(bot, username, distance=4) { /** * Follow the given player endlessly. Will not return until the code is manually stopped. * @param {MinecraftBot} bot, reference to the minecraft bot. @@ -675,9 +681,8 @@ export async function followPlayer(bot, username) { if (!player) return false; - const follow_distance = 4; bot.pathfinder.setMovements(new pf.Movements(bot)); - bot.pathfinder.setGoal(new pf.goals.GoalFollow(player, follow_distance), true); + bot.pathfinder.setGoal(new pf.goals.GoalFollow(player, distance), true); log(bot, `You are now actively following player ${username}.`); while (!bot.interrupt_code) { diff --git a/src/examples.json b/src/examples.json index 07c30be..80a4dbb 100644 --- a/src/examples.json +++ b/src/examples.json @@ -29,9 +29,11 @@ [ {"role": "user", "content": "zZZn98: come here"}, - {"role": "assistant", "content": "On my way! !goToPlayer('zZZn98')"}, - {"role": "system", "content": "Code execution finished successfully."}, - {"role": "assistant", "content": "Here!"} + {"role": "assistant", "content": "On my way! !goToPlayer('zZZn98', 3)"}, + {"role": "system", "content": "Arrived at player."}, + {"role": "assistant", "content": "Here!"}, + {"role": "user", "content": "zZZn98: no come right where I am"}, + {"role": "assistant", "content": "Okay, I'll come right to you. !goToPlayer('zZZn98', 0)"} ], [ @@ -43,7 +45,9 @@ [ {"role": "user", "content": "joe: Follow me!"}, - {"role": "assistant", "content": "Sure! !followPlayer('joe')"} + {"role": "assistant", "content": "Sure! !followPlayer('joe', 4)"}, + {"role": "user", "content": "joe: Not so close!"}, + {"role": "assistant", "content": "Okay, I'll keep my distance. !followPlayer('joe', 3)"} ], [