const { Movements } = require('mineflayer-pathfinder') const v = require('vec3') let cfg = {} let bot = {} // let moving let pathfinder let mcData let movements = [] function initMoves(bot = bot, mcData = bot.mcData) { console.info(movements) if (movements.length > 0) { bot.pathfinder.setMovements(movements.defaultMove) return console.warn("movements already initialized!") } let defaultMove = new Movements(bot, mcData) defaultMove.canDig = false defaultMove.scafoldingBlocks.push(mcData.blocksByName.slime_block.id) defaultMove.blocksCantBreak.add(mcData.blocksByName.glass.id) defaultMove.blocksToAvoid.add(mcData.blocksByName.magma_block.id) movements.push(defaultMove) movements.defaultMove = movements[0] bot.pathfinder.setMovements(defaultMove) } function moveNear(pos, distance = 3) { const { GoalNear } = require('mineflayer-pathfinder').goals cfg.quiet || bot.chat(`moving to ${pos}`) pos = v(pos) bot.pathfinder.setMovements(movements.defaultMove) bot.pathfinder.setGoal(new GoalNear(pos.x, pos.y, pos.z, distance)) } function moveXZ(pos) { const { GoalXZ } = require('mineflayer-pathfinder').goals cfg.quiet || bot.chat(`moving to ${pos}`) if (Array.isArray(pos) && pos.length == 2) { pos = v(pos[0], 0, pos[1]) } pos = v(pos) console.log(pos) bot.pathfinder.setMovements(movements.defaultMove) bot.pathfinder.setGoal(new GoalXZ(pos.x, pos.z)) } function follow(entity, dynamic = true, distance = 3) { console.assert(entity) const { GoalFollow } = require('mineflayer-pathfinder').goals cfg.quiet && console.log(entity) || bot.chat( `following ${entity.type }: ${entity.username || entity.displayName }${dynamic ? "" : " once"}` ) entity = entity.entity ? entity.entity : entity // console.log(entity) bot.pathfinder.setMovements(movements.defaultMove) bot.pathfinder.setGoal(new GoalFollow(entity, distance), dynamic) } function hit(blockOrEntity) { bot.chat(`hitting ${entity.name || entity.type}`) } function goalReached(goal) { console.log(goal) const entity = goal?.entity let entityInfo = "" if (entity) { entityInfo += entity.type + ": " switch (entity.type) { case "player": entityInfo += entity.username break; default: break; } } cfg.quiet || bot.chat(`goal reached: ${entityInfo}; pos: [x:${goal?.x}, y:${goal?.y}, z:${goal?.z}]`) } function stop() { bot.pathfinder.setGoal(null) bot.stopDigging() } const load = (config) => { cfg = config bot = cfg.bot cfg.move = { // auto: true, canDig: false, // list: ["hello", "wassup"], quiet: !!cfg.quiet, movements: [] } mcData = bot.mcData || (bot.mcData = require('minecraft-data')(bot.version)) pathfinder = bot.pathfinder || bot.loadPlugin(require('mineflayer-pathfinder').pathfinder) // initMoves(bot, mcData) setTimeout(initMoves, 500, bot, mcData) bot.on('goal_reached', goalReached) } const unload = () => { stop() bot.off('goal_reached', goalReached) } module.exports = { load, unload, stop, initMoves, moveNear, moveXZ, follow }