add gotoposition/searchforentity, improved consume/giveplayer/gotoblock

This commit is contained in:
MaxRobinsonTheGreat 2024-12-05 15:30:25 -06:00
parent 132a535068
commit f068b4c7ce
2 changed files with 90 additions and 30 deletions

View file

@ -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);
})
},
{

View file

@ -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<boolean>} 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));
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<boolean>} 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.