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.
115 lines
4.1 KiB
115 lines
4.1 KiB
// Load your dependency plugins. |
|
|
|
const {pathfinder} = require('mineflayer-pathfinder') |
|
// bot.loadPlugin(require('prismarine-viewer').mineflayer) |
|
// const mineflayerViewer = require('prismarine-viewer').mineflayer |
|
|
|
// Import required behaviors. |
|
const { |
|
StateTransition, |
|
BotStateMachine, |
|
EntityFilters, |
|
BehaviorFollowEntity, |
|
BehaviorLookAtEntity, |
|
BehaviorGetClosestEntity, |
|
NestedStateMachine, |
|
BehaviorIdle, |
|
StateMachineWebserver, |
|
} = require("mineflayer-statemachine"); |
|
|
|
// TODO chat |
|
|
|
|
|
|
|
// wait for our bot to login. |
|
function statemachineInit() { |
|
cfg.botAddress = new RegExp(`^${bot.username} (!.+)`) |
|
// This targets object is used to pass data between different states. It can be left empty. |
|
const targets = new Object(); |
|
|
|
// Create our states |
|
const getClosestPlayer = new BehaviorGetClosestEntity( |
|
bot, targets, entity => EntityFilters().PlayersOnly(entity) && bot.entity.position.distanceTo(entity.position) <= 50 ); // && a.username !== bot.username); |
|
const followPlayer = new BehaviorFollowEntity(bot, targets); |
|
const lookAtPlayer = new BehaviorLookAtEntity(bot, targets); |
|
const stay = new BehaviorIdle(); |
|
|
|
// Create our transitions |
|
const transitions = [ |
|
|
|
// We want to start following the player immediately after finding them. |
|
// Since getClosestPlayer finishes instantly, shouldTransition() should always return true. |
|
new StateTransition({ |
|
parent: getClosestPlayer, |
|
child: followPlayer, |
|
onTransition: (quiet) => quiet || bot.chat(`Hi ${targets.entity.username}!`), |
|
shouldTransition: () => bot.entity.position.distanceTo(targets.entity.position) <= 50, |
|
// shouldTransition: () => getClosestPlayer.distanceToTarget() < 100 || console.info("player too far!") && false, |
|
}), |
|
|
|
// If the distance to the player is less than two blocks, switch from the followPlayer |
|
// state to the lookAtPlayer state. |
|
new StateTransition({ |
|
parent: followPlayer, |
|
child: lookAtPlayer, |
|
// onTransition: () => console.log(targets), |
|
shouldTransition: () => followPlayer.distanceToTarget() < 2, |
|
}), |
|
|
|
// If the distance to the player is more than two blocks, switch from the lookAtPlayer |
|
// state to the followPlayer state. |
|
new StateTransition({ |
|
parent: lookAtPlayer, |
|
child: followPlayer, |
|
shouldTransition: () => lookAtPlayer.distanceToTarget() >= 5, |
|
}), |
|
new StateTransition({ |
|
parent: lookAtPlayer, |
|
child: stay, |
|
onTransition: () => bot.chat("ok, staying"), |
|
// shouldTransition: () => true, |
|
}), |
|
new StateTransition({ |
|
parent: stay, |
|
child: getClosestPlayer, |
|
// shouldTransition: () => Math.random() > 0.01, |
|
// shouldTransition: () => Math.random() > 0.1 && getClosestPlayer.distanceToTarget() < 2, |
|
}), |
|
]; |
|
|
|
// Now we just wrap our transition list in a nested state machine layer. We want the bot |
|
// to start on the getClosestPlayer state, so we'll specify that here. |
|
const rootLayer = new NestedStateMachine(transitions, getClosestPlayer, stay); |
|
|
|
// We can start our state machine simply by creating a new instance. |
|
cfg.stateMachines.follow = new BotStateMachine(bot, rootLayer); |
|
const webserver = new StateMachineWebserver(bot, cfg.stateMachines.follow); |
|
webserver.startServer(); |
|
|
|
// mineflayerViewer(bot, { port: 3000 }) |
|
// const path = [bot.entity.position.clone()] |
|
// bot.on('move', () => { |
|
// if (path[path.length - 1].distanceTo(bot.entity.position) > 1) { |
|
// path.push(bot.entity.position.clone()) |
|
// bot.viewer.drawLine('path', path) |
|
// } |
|
// }) |
|
} |
|
|
|
const load = (config) => { |
|
cfg = config |
|
bot = cfg.bot |
|
// cfg.inventory = { |
|
// auto: true, |
|
// quiet: false |
|
// } |
|
// bot.on('chat', inventory) |
|
bot.loadPlugin(pathfinder) |
|
// statemachineInit() |
|
} |
|
|
|
const unload = () => { |
|
// bot.off('chat', inventory) |
|
} |
|
|
|
module.exports = { load, unload } |