You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
5.1 KiB
170 lines
5.1 KiB
const mineflayer = require('mineflayer') |
|
const { pathfinder, Movements, goals } = require('mineflayer-pathfinder') |
|
const pvp = require('mineflayer-pvp').plugin |
|
|
|
let cfg = {} |
|
let bot = {} |
|
let guardPos |
|
|
|
const filterAllMobs = e => e.type === 'mob' |
|
const filterPlayers = e => e.type === 'player' |
|
const filterMods = e => e.type === 'player' && [cfg.mods].includes(e.username) |
|
// const filterPassiveMobs = e => e.kind === 'Passive mobs' |
|
const filterCreeper = e => e.mobType === 'Creeper' |
|
// const filterCreeperOrEndermen = e => ['Creeper', 'EndderMen'].includes(e.mobType) //TODO endmen hostile by default? |
|
const filterHostileMobs = e => e.kind === 'Hostile mobs' |
|
// // not needed if detecting by kind |
|
// && e.mobType !== 'Armor Stand' // Mojang classifies armor stands as mobs for some reason? |
|
|
|
// Assign the given location to be guarded |
|
function guardArea(pos) { |
|
if (pos) { |
|
cfg.guard.pos = guardPos = pos |
|
// Check for new enemies to attack |
|
// bot.off('physicTick', lookForMobs) |
|
bot.off('time', lookForMobs) |
|
bot.on('time', lookForMobs) |
|
} |
|
|
|
// We are not currently in combat, move to the guard pos |
|
if (!bot.pvp.target && guardPos) { |
|
moveToGuardPos() |
|
} |
|
} |
|
|
|
// Cancel all pathfinder and combat |
|
function stopGuarding() { |
|
guardPos = cfg.guard.pos = null |
|
bot.pvp.stop() |
|
bot.pathfinder.setGoal(null) |
|
bot.off('time', lookForMobs) |
|
// bot.off('physicTick', lookForMobs) |
|
} |
|
|
|
// Pathfinder to the guard position |
|
function moveToGuardPos() { |
|
const mcData = require('minecraft-data')(bot.version) |
|
bot.pathfinder.setMovements(new Movements(bot, mcData)) |
|
bot.pathfinder.setGoal(new goals.GoalBlock(guardPos.x, guardPos.y, guardPos.z)) |
|
} |
|
|
|
// Called when the bot has killed it's target. |
|
// () => { |
|
// if (guardPos) { |
|
// moveToGuardPos() |
|
// } |
|
// }) |
|
|
|
function lookForMobs() { |
|
if (!guardPos) return // Do nothing if bot is not guarding anything |
|
|
|
// Only look for mobs within 16 blocks |
|
const filter = e => e.position.distanceTo(bot.entity.position) < 16 && filterHostileMobs(e) |
|
|
|
const entityEnemy = bot.nearestEntity(filter) |
|
if (entityEnemy && !filterCreeper(entityEnemy)) { |
|
// if(filterCreeper(entityEnemy)) |
|
// Start attacking |
|
// bot.off('time', lookForMobs) |
|
// bot.on('physicTick', lookForMobs) |
|
bot.pvp.movements.canDig = !!cfg.move && cfg.move.canDig |
|
bot.pvp.attack(entityEnemy) |
|
} else if (entityEnemy) { |
|
bot.lookAt( |
|
entityEnemy.position |
|
) |
|
cfg.quiet || bot.chat("AH! A creeper! They creep me out!") |
|
} |
|
} |
|
|
|
function guardSelf(entity) { |
|
if (!cfg.guard.self || entity !== bot.entity || guardPos) return // Do nothing |
|
// bot.chat("") |
|
const hurtMessages = [ |
|
"ouch!", "oww!", "help", "monster!" |
|
] |
|
const hurtMessagesPlayer = [ |
|
"leave me alone!", "don't hurt me!", "bully!", "go away!", "stop", "no stop", "stop it", "murderer!", |
|
"what have i ever done to you? :(", |
|
] |
|
console.info(bot.nearestEntity(filterAllMobs)) |
|
|
|
// Only look for mobs within 5 blocks |
|
// const filter = e => e.position.distanceTo(bot.entity.position) < 5 && filterHostileMobs(e) || filterPlayers(e) && !filterMods(e)//anarchy |
|
const filter = e => e.position.distanceTo(bot.entity.position) < 5 && filterHostileMobs(e) |
|
|
|
const entityEnemy = bot.nearestEntity(filter) |
|
|
|
cfg.quiet || 0.2 < Math.random() && entityEnemy && bot.chat( |
|
// TODO use fuzzy message function |
|
filterPlayers(entityEnemy) ? |
|
hurtMessagesPlayer[Math.floor(Math.random() * hurtMessagesPlayer.length)] |
|
: |
|
hurtMessages[Math.floor(Math.random() * hurtMessages.length)] |
|
|
|
) |
|
|
|
if (entityEnemy && !filterCreeper(entityEnemy)) { |
|
// Start attacking |
|
// bot.off('time', lookForMobs) |
|
// bot.on('physicTick', lookForMobs) |
|
bot.pvp.attack(entityEnemy) |
|
bot.pvp.movements.canDig = !!cfg.move && cfg.move.canDig |
|
} |
|
} |
|
|
|
// bot.on('physicTick', lookForMobs) |
|
|
|
// Listen for player commands |
|
// bot.on('chat', (username, message) => { |
|
// // Guard the location the player is standing |
|
// if (message === 'guard') { |
|
// const player = bot.players[username] |
|
|
|
// if (!player) { |
|
// bot.chat("I can't see you.") |
|
// return |
|
// } |
|
|
|
// bot.chat('I will guard that location.') |
|
// guardArea(player.entity.position) |
|
// } |
|
|
|
// // Stop guarding |
|
// if (message === 'stop') { |
|
// bot.chat('I will no longer guard this area.') |
|
// stopGuarding() |
|
// } |
|
// }) |
|
|
|
const load = (config) => { |
|
cfg = config |
|
bot = cfg.bot |
|
cfg.guard = { |
|
pos: null, |
|
auto: true, |
|
self: true, |
|
} |
|
|
|
guardPos = cfg.guard.pos |
|
|
|
|
|
bot.loadPlugin(pathfinder) |
|
bot.loadPlugin(pvp) |
|
|
|
bot.on('stoppedAttacking', guardArea) |
|
bot.on('entityHurt', guardSelf) |
|
// bot.on("time", guardArea) |
|
|
|
} |
|
|
|
const unload = () => { |
|
stopGuarding() |
|
bot.off('time', lookForMobs) |
|
// bot.off('physicTick', lookForMobs) |
|
bot.off('stoppedAttacking', guardArea) |
|
bot.off('entityHurt', guardSelf) |
|
// bot.off("time", guardArea) |
|
} |
|
|
|
module.exports = { load, unload, guardArea, guardSelf, stopGuarding } |