mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-08-10 17:25:34 +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) {
|
function wrapExecution(func) {
|
||||||
return async function (agent, ...args) {
|
return async function (agent, ...args) {
|
||||||
|
await agent.coder.stop();
|
||||||
agent.bot.output = '';
|
agent.bot.output = '';
|
||||||
agent.coder.executing = true;
|
agent.coder.executing = true;
|
||||||
let res = await func(agent, ...args);
|
let res = await func(agent, ...args);
|
||||||
|
@ -13,7 +14,6 @@ function wrapExecution(func) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// const actionsList = [
|
|
||||||
export const actionsList = [
|
export const actionsList = [
|
||||||
{
|
{
|
||||||
name: '!newAction',
|
name: '!newAction',
|
||||||
|
@ -34,7 +34,7 @@ export const actionsList = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '!goToPlayer',
|
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.'},
|
params: {'player_name': '(string) The name of the player to go to.'},
|
||||||
perform: wrapExecution(async (agent, player_name) => {
|
perform: wrapExecution(async (agent, player_name) => {
|
||||||
return await skills.goToPlayer(agent.bot, player_name);
|
return await skills.goToPlayer(agent.bot, player_name);
|
||||||
|
@ -42,7 +42,7 @@ export const actionsList = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '!followPlayer',
|
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.'},
|
params: {'player_name': '(string) The name of the player to follow.'},
|
||||||
perform: wrapExecution(async (agent, player_name) => {
|
perform: wrapExecution(async (agent, player_name) => {
|
||||||
await skills.followPlayer(agent.bot, player_name);
|
await skills.followPlayer(agent.bot, player_name);
|
||||||
|
@ -66,5 +66,13 @@ export const actionsList = [
|
||||||
perform: wrapExecution(async (agent, type) => {
|
perform: wrapExecution(async (agent, type) => {
|
||||||
await skills.attackMob(agent.bot, type, true);
|
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.
|
* 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 {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.
|
* @param {number} num, the number of items to smelt. Defaults to 1.
|
||||||
* @returns {Promise<boolean>} true if the item was smelted, false otherwise. Fail
|
* @returns {Promise<boolean>} true if the item was smelted, false otherwise. Fail
|
||||||
* @example
|
* @example
|
||||||
* await skills.smeltItem(bot, "raw_iron");
|
* 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".`);
|
log(bot, `Cannot smelt ${itemName}, must be a "raw" item, like "raw_iron".`);
|
||||||
return false;
|
return false;
|
||||||
} // TODO: allow cobblestone, sand, clay, etc.
|
} // 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) {
|
export async function attackMob(bot, mobType, kill=true) {
|
||||||
/**
|
/**
|
||||||
* Attack mob of the given type.
|
* Attack mob of the given type.
|
||||||
|
@ -177,16 +186,11 @@ export async function attackMob(bot, mobType, kill=true) {
|
||||||
* await skills.attackMob(bot, "zombie", true);
|
* await skills.attackMob(bot, "zombie", true);
|
||||||
**/
|
**/
|
||||||
const mob = bot.nearestEntity(entity => entity.name && entity.name.toLowerCase() === mobType.toLowerCase());
|
const mob = bot.nearestEntity(entity => entity.name && entity.name.toLowerCase() === mobType.toLowerCase());
|
||||||
const attackable = ['animal', 'monster', 'mob'];
|
if (mob) {
|
||||||
if (mob && attackable.includes(mob.type)) {
|
|
||||||
let pos = mob.position;
|
let pos = mob.position;
|
||||||
console.log(bot.entity.position.distanceTo(pos))
|
console.log(bot.entity.position.distanceTo(pos))
|
||||||
|
|
||||||
// equip highest damage weapon
|
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)
|
|
||||||
await bot.equip(weapon, 'hand');
|
|
||||||
|
|
||||||
if (!kill) {
|
if (!kill) {
|
||||||
if (bot.entity.position.distanceTo(pos) > 5) {
|
if (bot.entity.position.distanceTo(pos) > 5) {
|
||||||
|
@ -542,13 +546,10 @@ export async function goToPlayer(bot, username) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let arrived = await goToPosition(bot, player.position.x, player.position.y, player.position.z);
|
bot.pathfinder.setMovements(new pf.Movements(bot));
|
||||||
if (!arrived) {
|
await bot.pathfinder.goto(new pf.goals.GoalFollow(player, 2), true);
|
||||||
log(bot, `Failed to reach ${username}.`);
|
|
||||||
return false;
|
log(bot, `You have reached ${username}.`);
|
||||||
}
|
|
||||||
log(bot, `You have reached the player at position ${player.position}.`);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -573,5 +574,52 @@ export async function followPlayer(bot, username) {
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
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;
|
return true;
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue