2020-12-21 16:08:38 +00:00
|
|
|
const mineflayer = require('mineflayer')
|
|
|
|
const { pathfinder, Movements, goals } = require('mineflayer-pathfinder')
|
|
|
|
const pvp = require('mineflayer-pvp').plugin
|
|
|
|
|
|
|
|
let cfg = {}
|
|
|
|
let bot = {}
|
|
|
|
let guardPos
|
|
|
|
|
2020-12-22 06:28:44 +00:00
|
|
|
const filterAllMobs = e => e.type === 'mob'
|
|
|
|
const filterPlayers = e => e.type === 'player'
|
|
|
|
const filterMods = e => e.type === 'player' && [cfg.mods].includes(e.username)
|
2020-12-21 16:08:38 +00:00
|
|
|
// const filterPassiveMobs = e => e.kind === 'Passive mobs'
|
|
|
|
const filterCreeper = e => e.mobType === 'Creeper'
|
2020-12-22 06:28:44 +00:00
|
|
|
// const filterCreeperOrEndermen = e => ['Creeper', 'EndderMen'].includes(e.mobType) //TODO endmen hostile by default?
|
2020-12-21 16:08:38 +00:00
|
|
|
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)
|
2020-12-22 06:28:44 +00:00
|
|
|
if (entityEnemy && !filterCreeper(entityEnemy)) {
|
|
|
|
// if(filterCreeper(entityEnemy))
|
2020-12-21 16:08:38 +00:00
|
|
|
// Start attacking
|
|
|
|
// bot.off('time', lookForMobs)
|
|
|
|
// bot.on('physicTick', lookForMobs)
|
2020-12-22 06:28:44 +00:00
|
|
|
bot.pvp.movements.canDig = !!cfg.move && cfg.move.canDig
|
2020-12-21 16:08:38 +00:00
|
|
|
bot.pvp.attack(entityEnemy)
|
2020-12-22 06:28:44 +00:00
|
|
|
} else if (entityEnemy) {
|
|
|
|
bot.lookAt(
|
|
|
|
// (new v.Vec3(0, 1, 0)).add(
|
|
|
|
entityEnemy.position
|
|
|
|
// )
|
|
|
|
)
|
|
|
|
cfg.quiet || bot.chat("AH! A creeper! They creep me out!")
|
2020-12-21 16:08:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function guardSelf(entity) {
|
|
|
|
if (!cfg.guard.self || entity !== bot.entity || guardPos) return // Do nothing
|
|
|
|
// bot.chat("")
|
2020-12-22 06:28:44 +00:00
|
|
|
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)
|
2020-12-21 16:08:38 +00:00
|
|
|
|
2020-12-22 06:28:44 +00:00
|
|
|
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)]
|
2020-12-21 16:08:38 +00:00
|
|
|
|
2020-12-22 06:28:44 +00:00
|
|
|
)
|
2020-12-21 16:08:38 +00:00
|
|
|
|
|
|
|
if (entityEnemy && !filterCreeper(entityEnemy)) {
|
|
|
|
// Start attacking
|
|
|
|
// bot.off('time', lookForMobs)
|
|
|
|
// bot.on('physicTick', lookForMobs)
|
|
|
|
bot.pvp.attack(entityEnemy)
|
2020-12-22 06:28:44 +00:00
|
|
|
bot.pvp.movements.canDig = !!cfg.move && cfg.move.canDig
|
2020-12-21 16:08:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 }
|