mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-04-21 21:52:07 +02:00
expanded self_preservation, fixed pausing/interrupting
This commit is contained in:
parent
2aeebac0cd
commit
b33c70e8e1
2 changed files with 48 additions and 16 deletions
|
@ -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');
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue