mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-07-02 22:55:20 +02:00
added defend, improved gotoplayer
This commit is contained in:
parent
4f48dea4f6
commit
ff9c241876
2 changed files with 75 additions and 19 deletions
|
@ -3,6 +3,7 @@ import * as world from '../world.js';
|
|||
|
||||
function wrapExecution(func) {
|
||||
return async function (agent, ...args) {
|
||||
await agent.coder.stop();
|
||||
agent.bot.output = '';
|
||||
agent.coder.executing = true;
|
||||
let res = await func(agent, ...args);
|
||||
|
@ -13,7 +14,6 @@ function wrapExecution(func) {
|
|||
}
|
||||
}
|
||||
|
||||
// const actionsList = [
|
||||
export const actionsList = [
|
||||
{
|
||||
name: '!newAction',
|
||||
|
@ -34,7 +34,7 @@ export const actionsList = [
|
|||
},
|
||||
{
|
||||
name: '!goToPlayer',
|
||||
description: 'Go to the nearest player. Ex: !goToPlayer("steve")',
|
||||
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);
|
||||
|
@ -42,7 +42,7 @@ export const actionsList = [
|
|||
},
|
||||
{
|
||||
name: '!followPlayer',
|
||||
description: 'Endlessly follow the nearest player. Ex: !followPlayer("stevie")',
|
||||
description: 'Endlessly follow the given player. 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);
|
||||
|
@ -66,5 +66,13 @@ export const actionsList = [
|
|||
perform: wrapExecution(async (agent, type) => {
|
||||
await skills.attackMob(agent.bot, type, true);
|
||||
})
|
||||
},
|
||||
{
|
||||
name: '!defend',
|
||||
description: 'Follow the given player and attack any nearby monsters.',
|
||||
params: {'player_name': '(string) The name of the player to defend.'},
|
||||
perform: wrapExecution(async (agent, player_name) => {
|
||||
await skills.defendPlayer(agent.bot, player_name);
|
||||
})
|
||||
}
|
||||
];
|
||||
|
|
|
@ -44,13 +44,15 @@ export async function smeltItem(bot, itemName, num=1) {
|
|||
/**
|
||||
* Puts 1 coal in furnace and smelts the given item name, waits until the furnace runs out of fuel or input items.
|
||||
* @param {MinecraftBot} bot, reference to the minecraft bot.
|
||||
* @param {string} itemName, the item name to smelt. Must contain "raw"
|
||||
* @param {string} itemName, the item name to smelt. Ores must contain "raw" like raw_iron.
|
||||
* @param {number} num, the number of items to smelt. Defaults to 1.
|
||||
* @returns {Promise<boolean>} true if the item was smelted, false otherwise. Fail
|
||||
* @example
|
||||
* await skills.smeltItem(bot, "raw_iron");
|
||||
* await skills.smeltItem(bot, "beef");
|
||||
**/
|
||||
if (!itemName.includes('raw')) {
|
||||
const foods = ['beef', 'chicken', 'cod', 'mutton', 'porkchop', 'rabbit', 'salmon', 'tropical_fish'];
|
||||
if (!itemName.includes('raw') && !foods.includes(itemName)) {
|
||||
log(bot, `Cannot smelt ${itemName}, must be a "raw" item, like "raw_iron".`);
|
||||
return false;
|
||||
} // TODO: allow cobblestone, sand, clay, etc.
|
||||
|
@ -166,6 +168,13 @@ export async function clearNearestFurnace(bot) {
|
|||
}
|
||||
|
||||
|
||||
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];
|
||||
if (weapon)
|
||||
bot.equip(weapon, 'hand');
|
||||
}
|
||||
|
||||
export async function attackMob(bot, mobType, kill=true) {
|
||||
/**
|
||||
* Attack mob of the given type.
|
||||
|
@ -177,16 +186,11 @@ export async function attackMob(bot, mobType, kill=true) {
|
|||
* await skills.attackMob(bot, "zombie", true);
|
||||
**/
|
||||
const mob = bot.nearestEntity(entity => entity.name && entity.name.toLowerCase() === mobType.toLowerCase());
|
||||
const attackable = ['animal', 'monster', 'mob'];
|
||||
if (mob && attackable.includes(mob.type)) {
|
||||
if (mob) {
|
||||
let pos = mob.position;
|
||||
console.log(bot.entity.position.distanceTo(pos))
|
||||
|
||||
// equip highest damage weapon
|
||||
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];
|
||||
if (weapon)
|
||||
await bot.equip(weapon, 'hand');
|
||||
equipHighestAttack(bot)
|
||||
|
||||
if (!kill) {
|
||||
if (bot.entity.position.distanceTo(pos) > 5) {
|
||||
|
@ -542,13 +546,10 @@ export async function goToPlayer(bot, username) {
|
|||
return false;
|
||||
}
|
||||
|
||||
let arrived = await goToPosition(bot, player.position.x, player.position.y, player.position.z);
|
||||
if (!arrived) {
|
||||
log(bot, `Failed to reach ${username}.`);
|
||||
return false;
|
||||
}
|
||||
log(bot, `You have reached the player at position ${player.position}.`);
|
||||
return true;
|
||||
bot.pathfinder.setMovements(new pf.Movements(bot));
|
||||
await bot.pathfinder.goto(new pf.goals.GoalFollow(player, 2), true);
|
||||
|
||||
log(bot, `You have reached ${username}.`);
|
||||
}
|
||||
|
||||
|
||||
|
@ -573,5 +574,52 @@ export async function followPlayer(bot, username) {
|
|||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function defendPlayer(bot, username) {
|
||||
/**
|
||||
* Defend the given player endlessly, attacking any nearby monsters. Will not return until the code is manually stopped.
|
||||
* @param {MinecraftBot} bot, reference to the minecraft bot.
|
||||
* @param {string} username, the username of the player to defend.
|
||||
* @returns {Promise<boolean>} true if the player was found, false otherwise.
|
||||
* @example
|
||||
* await skills.defendPlayer(bot, "bob");
|
||||
**/
|
||||
let player = bot.players[username].entity
|
||||
if (!player)
|
||||
return false;
|
||||
|
||||
bot.pathfinder.setMovements(new pf.Movements(bot));
|
||||
bot.pathfinder.setGoal(new pf.goals.GoalFollow(player, 5), true);
|
||||
log(bot, `Actively defending player ${username}.`);
|
||||
|
||||
while (!bot.interrupt_code) {
|
||||
if (bot.entity.position.distanceTo(player.position) < 10) {
|
||||
const mobs = getNearbyMobs(bot, 8).filter(mob => mob.type === 'mob' || mob.type === 'hostile');
|
||||
const mob = mobs.sort((a, b) => a.position.distanceTo(player.position) - b.position.distanceTo(player.position))[0]; // get closest to player
|
||||
if (mob) {
|
||||
bot.pathfinder.stop();
|
||||
log(bot, `Found ${mob.name}, attacking!`);
|
||||
bot.chat(`Found ${mob.name}, attacking!`);
|
||||
equipHighestAttack(bot);
|
||||
bot.pvp.attack(mob);
|
||||
while (getNearbyMobs(bot, 8).includes(mob)) {
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
console.log('attacking...')
|
||||
if (bot.interrupt_code || bot.entity.position.distanceTo(player.position) > 16) {
|
||||
console.log('stopping pvp...');
|
||||
bot.pvp.stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.log('resuming pathfinder...')
|
||||
bot.pathfinder.setMovements(new pf.Movements(bot));
|
||||
bot.pathfinder.setGoal(new pf.goals.GoalFollow(player, 5), true);
|
||||
}
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
Loading…
Add table
Reference in a new issue