diff --git a/src/agent/commands/actions.js b/src/agent/commands/actions.js index 3b91bee..65ad3b7 100644 --- a/src/agent/commands/actions.js +++ b/src/agent/commands/actions.js @@ -99,15 +99,38 @@ export const actionsList = [ }, true) }, { - name: '!goToBlock', - description: 'Go to the nearest block of a given type.', + name: '!goToPosition', + description: 'Go to the given x, y, z location.', + params: { + 'x': {type: 'float', description: 'The x coordinate.', domain: [0, Infinity]}, + 'y': {type: 'float', description: 'The y coordinate.', domain: [-64, 320]}, + 'z': {type: 'float', description: 'The z coordinate.', domain: [0, Infinity]}, + 'closeness': {type: 'float', description: 'How close to get to the location.', domain: [0, Infinity]} + }, + perform: runAsAction(async (agent, x, y, z, closeness) => { + await skills.goToPosition(agent.bot, x, y, z, closeness); + }) + }, + { + name: '!searchForBlock', + description: 'Find and go to the nearest block of a given type in a given range.', params: { 'type': { type: 'BlockName', description: 'The block type to go to.' }, - 'closeness': { type: 'float', description: 'How close to get to the block.', domain: [0, Infinity] }, 'search_range': { type: 'float', description: 'The range to search for the block.', domain: [0, 512] } }, - perform: runAsAction(async (agent, type, closeness, range) => { - await skills.goToNearestBlock(agent.bot, type, closeness, range); + perform: runAsAction(async (agent, block_type, range) => { + await skills.goToNearestBlock(agent.bot, block_type, 4, range); + }) + }, + { + name: '!searchForEntity', + description: 'Find and go to the nearest entity of a given type in a given range.', + params: { + 'type': { type: 'string', description: 'The type of entity to go to.' }, + 'search_range': { type: 'float', description: 'The range to search for the entity.', domain: [0, 512] } + }, + perform: runAsAction(async (agent, entity_type, range) => { + await skills.goToNearestEntity(agent.bot, entity_type, 4, range); }) }, { @@ -129,7 +152,7 @@ export const actionsList = [ } }, { - name: '!goToPlace', + name: '!goToRememberedPlace', description: 'Go to a saved location.', params: {'name': { type: 'string', description: 'The name of the location to go to.' }}, perform: runAsAction(async (agent, name) => { @@ -150,11 +173,7 @@ export const actionsList = [ 'num': { type: 'int', description: 'The number of items to give.', domain: [1, Number.MAX_SAFE_INTEGER] } }, perform: runAsAction(async (agent, player_name, item_name, num) => { - const modes = agent.bot.modes; - modes.pause('item_collecting'); await skills.giveToPlayer(agent.bot, item_name, player_name, num); - await new Promise(resolve => setTimeout(resolve, 3000)); - modes.unpause('item_collecting'); }) }, { @@ -162,8 +181,7 @@ export const actionsList = [ description: 'Eat/drink the given item.', params: {'item_name': { type: 'ItemName', description: 'The name of the item to consume.' }}, perform: runAsAction(async (agent, item_name) => { - await agent.bot.consume(item_name); - skills.log(agent.bot, `Consumed ${item_name}.`); + await skills.consume(agent.bot, item_name); }) }, { diff --git a/src/agent/library/skills.js b/src/agent/library/skills.js index c6cde51..7c8819f 100644 --- a/src/agent/library/skills.js +++ b/src/agent/library/skills.js @@ -310,8 +310,6 @@ export async function attackEntity(bot, entity, kill=true) { **/ let pos = entity.position; - console.log(bot.entity.position.distanceTo(pos)) - await equipHighestAttack(bot) if (!kill) { @@ -758,7 +756,7 @@ export async function discard(bot, itemName, num=-1) { log(bot, `You do not have any ${itemName} to discard.`); return false; } - log(bot, `Successfully discarded ${discarded} ${itemName}.`); + log(bot, `Discarded ${discarded} ${itemName}.`); return true; } @@ -850,23 +848,19 @@ export async function viewChest(bot) { return true; } -export async function eat(bot, foodName="") { +export async function consume(bot, itemName="") { /** - * Eat the given item. If no item is given, it will eat the first food item in the bot's inventory. + * Eat/drink the given item. * @param {MinecraftBot} bot, reference to the minecraft bot. - * @param {string} item, the item to eat. + * @param {string} itemName, the item to eat/drink. * @returns {Promise} true if the item was eaten, false otherwise. * @example * await skills.eat(bot, "apple"); **/ let item, name; - if (foodName) { - item = bot.inventory.items().find(item => item.name === foodName); - name = foodName; - } - else { - item = bot.inventory.items().find(item => item.foodRecovery > 0); - name = "food"; + if (itemName) { + item = bot.inventory.items().find(item => item.name === itemName); + name = itemName; } if (!item) { log(bot, `You do not have any ${name} to eat.`); @@ -874,7 +868,7 @@ export async function eat(bot, foodName="") { } await bot.equip(item, 'hand'); await bot.consume(); - log(bot, `Successfully ate ${item.name}.`); + log(bot, `Consumed ${item.name}.`); return true; } @@ -895,13 +889,41 @@ export async function giveToPlayer(bot, itemType, username, num=1) { log(bot, `Could not find ${username}.`); return false; } - await goToPlayer(bot, username); + await goToPlayer(bot, username, 3); + // if we are 2 below the player + log(bot, bot.entity.position.y, player.position.y); + if (bot.entity.position.y < player.position.y - 1) { + await goToPlayer(bot, username, 1); + } + // if we are too close, make some distance + if (bot.entity.position.distanceTo(player.position) < 2) { + let goal = new pf.goals.GoalNear(player.position.x, player.position.y, player.position.z, 2); + let inverted_goal = new pf.goals.GoalInvert(goal); + bot.pathfinder.setMovements(new pf.Movements(bot)); + await bot.pathfinder.goto(inverted_goal); + } await bot.lookAt(player.position); if (await discard(bot, itemType, num)) { - log(bot, `${num} ${itemType} has been given to ${username}.`); - await new Promise(resolve => setTimeout(resolve, 2000)); - return true; + let given = false; + bot.once('playerCollect', (collector, collected) => { + console.log(collected.name); + if (collector.username === username) { + log(bot, `${username} recieved ${itemType}.`); + given = true; + } + }); + let start = Date.now(); + while (!given && !bot.interrupt_code) { + await new Promise(resolve => setTimeout(resolve, 500)); + if (given) { + return true; + } + if (Date.now() - start > 3000) { + break; + } + } } + log(bot, `Failed to give ${itemType} to ${username}, it was never received.`); return false; } @@ -961,6 +983,26 @@ export async function goToNearestBlock(bot, blockType, min_distance=2, range=64 } +export async function goToNearestEntity(bot, entityType, min_distance=2, range=64) { + /** + * Navigate to the nearest entity of the given type. + * @param {MinecraftBot} bot, reference to the minecraft bot. + * @param {string} entityType, the type of entity to navigate to. + * @param {number} min_distance, the distance to keep from the entity. Defaults to 2. + * @param {number} range, the range to look for the entity. Defaults to 64. + * @returns {Promise} true if the entity was reached, false otherwise. + **/ + let entity = world.getNearestEntityWhere(bot, entity => entity.name === entityType, range); + if (!entity) { + log(bot, `Could not find any ${entityType} in ${range} blocks.`); + return false; + } + let distance = bot.entity.position.distanceTo(entity.position); + log(bot, `Found ${entityType} ${distance} blocks away.`); + await goToPosition(bot, entity.position.x, entity.position.y, entity.position.z, min_distance); + return true; +} + export async function goToPlayer(bot, username, distance=3) { /** * Navigate to the given player.