expanded self_preservation, fixed pausing/interrupting

This commit is contained in:
MaxRobinsonTheGreat 2024-04-20 22:22:26 -05:00
parent 2aeebac0cd
commit b33c70e8e1
2 changed files with 48 additions and 16 deletions

View file

@ -257,7 +257,7 @@ export async function attackNearest(bot, mobType, kill=true) {
* await skills.attackNearest(bot, "zombie", true);
**/
bot.modes.pause('cowardice');
const mob = bot.nearestEntity(entity => entity.name && entity.name.toLowerCase() === mobType.toLowerCase());
const mob = world.getNearbyEntities(bot, 24).find(entity => entity.name === mobType);
if (mob) {
return await attackEntity(bot, mob, kill);
}
@ -290,7 +290,7 @@ export async function attackEntity(bot, entity, kill=true) {
}
else {
bot.pvp.attack(entity);
while (world.getNearbyEntities(bot, 16).includes(entity)) {
while (world.getNearbyEntities(bot, 24).includes(entity)) {
await new Promise(resolve => setTimeout(resolve, 1000));
if (bot.interrupt_code) {
bot.pvp.stop();
@ -703,6 +703,7 @@ export async function goToPlayer(bot, username, distance=3) {
* await skills.goToPlayer(bot, "player");
**/
bot.modes.pause('self_defense');
bot.modes.pause('cowardice');
let player = bot.players[username].entity
if (!player) {
log(bot, `Could not find ${username}.`);
@ -795,6 +796,7 @@ export async function stay(bot) {
* @example
* await skills.stay(bot);
**/
bot.modes.pause('self_preservation');
bot.modes.pause('cowardice');
bot.modes.pause('self_defense');
bot.modes.pause('hunting');

View file

@ -17,42 +17,56 @@ import * as mc from '../utils/mcdata.js';
const modes = [
{
name: 'self_preservation',
description: 'Respond to drowning, burning, and damage at low health.',
description: 'Respond to drowning, burning, and damage at low health. Interrupts other actions.',
interrupts: ['all'],
on: true,
active: false,
fall_blocks: ['sand', 'gravel', 'concrete_powder'], // includes matching substrings like 'sandstone' and 'red_sand'
update: async function (agent) {
let block = agent.bot.blockAt(agent.bot.entity.position);
let blockAbove = agent.bot.blockAt(agent.bot.entity.position.offset(0, 1, 0));
const bot = agent.bot;
const block = bot.blockAt(bot.entity.position);
const blockAbove = bot.blockAt(bot.entity.position.offset(0, 1, 0));
if (blockAbove.name === 'water' || blockAbove.name === 'flowing_water') {
// does not call execute so does not interrupt other actions
agent.bot.setControlState('jump', true);
if (!bot.pathfinder.goal) {
bot.setControlState('jump', true);
}
}
if (block.name === 'lava' || block.name === 'flowing_lava' || block.name === 'fire') {
else if (this.fall_blocks.some(name => blockAbove.name.includes(name))) {
execute(this, agent, async () => {
let nearestWater = world.getNearestBlock(agent.bot, 'water', 20);
await skills.moveAway(bot, 2);
});
}
else if (block.name === 'lava' || block.name === 'flowing_lava' || block.name === 'fire' ||
blockAbove.name === 'lava' || blockAbove.name === 'flowing_lava' || blockAbove.name === 'fire') {
bot.chat('I\'m on fire!'); // TODO: gets stuck in lava
execute(this, agent, async () => {
let nearestWater = world.getNearestBlock(bot, 'water', 20);
if (nearestWater) {
let pos = nearestWater.position;
bot.pathfinder.setMovements(new pf.Movements(bot));
await bot.pathfinder.goto(new pf.goals.GoalNear(pos.x, pos.y, pos.z, 4));
const pos = nearestWater.position;
await skills.goToPosition(bot, pos.x, pos.y, pos.z, 0.2);
bot.chat('Ahhhh that\'s better!');
}
else {
await skills.moveAway(agent.bot, 10);
await skills.moveAway(bot, 5);
}
});
}
else if (agent.bot.health < 5 && agent.bot.lastDamageTime < Date.now() - 3000) {
else if (Date.now() - bot.lastDamageTime < 3000 && (bot.health < 5 || bot.lastDamageTaken >= bot.health)) {
bot.chat('I\'m dying!');
execute(this, agent, async () => {
await skills.moveAway(agent.bot, 20);
await skills.moveAway(bot, 20);
});
}
else if (agent.isIdle()) {
bot.clearControlStates(); // clear jump if not in danger or doing anything else
}
}
},
{
name: 'cowardice',
description: 'Run away from enemies. Interrupts other actions.',
interrupts: ['all'], // Todo: don't interrupt attack actions
dont_interrupt: ['followPlayer'],
interrupts: ['all'],
on: true,
active: false,
update: async function (agent) {
@ -251,6 +265,22 @@ class ModeController {
if (mode.active) break;
}
}
getJson() {
let res = {};
for (let mode of this.modes_list) {
res[mode.name] = mode.on;
}
return res;
}
loadJson(json) {
for (let mode of this.modes_list) {
if (json[mode.name] != undefined) {
mode.on = json[mode.name];
}
}
}
}
export function initModes(agent) {