A high-level, general purpose and modular minecraft bot using hot re-loadable (without restarting the bot!) plugins. Batteries included, launch to run!
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.
 

147 lines
4.0 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' && e.username !== 'Applezaus'
// const filterPassiveMobs = e => e.kind === 'Passive mobs'
const filterCreeper = e => e.mobType === 'Creeper'
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) {
if(filterCreeper(entityEnemy))
// Start attacking
// bot.off('time', lookForMobs)
// bot.on('physicTick', lookForMobs)
bot.pvp.attack(entityEnemy)
}
}
function guardSelf(entity) {
if (!cfg.guard.self || entity !== bot.entity || guardPos) return // Do nothing
// bot.chat("")
bot.chat((
() => { const a = ["ouch!", "oww!", "help", "", "", ""]; return a[Math.floor(Math.random() * a.length)] }
)())
console.info(bot.nearestEntity(filterallMobs))
// Only look for mobs within 10 blocks
const filter = e => e.position.distanceTo(bot.entity.position) < 10 && filterHostileMobs(e)
const entityEnemy = bot.nearestEntity(filter)
if (entityEnemy && !filterCreeper(entityEnemy)) {
// Start attacking
// bot.off('time', lookForMobs)
// bot.on('physicTick', lookForMobs)
bot.pvp.attack(entityEnemy)
}
}
// 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 }