LookAtMySuitBot/js/node_modules/mineflayer-pathfinder/lib/physics.js

124 lines
3.9 KiB
JavaScript

const { PlayerState } = require('prismarine-physics')
class Physics {
constructor (bot) {
this.bot = bot
this.world = { getBlock: (pos) => { return bot.blockAt(pos, false) } }
}
/**
*
* @param {function} goal A function is the goal has been reached or not
* @param {function} controller Controller that can change the current control State for the next tick
* @param {number} ticks Number of ticks to simulate
* @param {object} state Starting control state to begin the simulation with
* @returns { import('prismarine-physics').PlayerState } A player state of the final simulation tick
*/
simulateUntil (goal, controller = () => {}, ticks = 1, state = null) {
if (!state) {
const simulationControl = {
forward: this.bot.controlState.forward,
back: this.bot.controlState.back,
left: this.bot.controlState.left,
right: this.bot.controlState.right,
jump: this.bot.controlState.jump,
sprint: this.bot.controlState.sprint,
sneak: this.bot.controlState.sneak
}
state = new PlayerState(this.bot, simulationControl)
}
for (let i = 0; i < ticks; i++) {
controller(state, i)
this.bot.physics.simulatePlayer(state, this.world)
if (state.isInLava) return state
if (goal(state)) return state
}
return state
}
simulateUntilNextTick () {
return this.simulateUntil(() => false, () => {}, 1)
}
simulateUntilOnGround (ticks = 5) {
return this.simulateUntil(state => state.onGround, () => {}, ticks)
}
canStraightLine (path, sprint = false) {
const reached = this.getReached(path)
const state = this.simulateUntil(reached, this.getController(path[0], false, sprint), 200)
if (reached(state)) return true
if (sprint) {
if (this.canSprintJump(path, 0)) return false
} else {
if (this.canWalkJump(path, 0)) return false
}
for (let i = 1; i < 7; i++) {
if (sprint) {
if (this.canSprintJump(path, i)) return true
} else {
if (this.canWalkJump(path, i)) return true
}
}
return false
}
canStraightLineBetween (n1, n2) {
const reached = (state) => {
const delta = n2.minus(state.pos)
const r2 = 0.15 * 0.15
return (delta.x * delta.x + delta.z * delta.z) <= r2 && Math.abs(delta.y) < 0.001 && (state.onGround || state.isInWater)
}
const simulationControl = {
forward: this.bot.controlState.forward,
back: this.bot.controlState.back,
left: this.bot.controlState.left,
right: this.bot.controlState.right,
jump: this.bot.controlState.jump,
sprint: this.bot.controlState.sprint,
sneak: this.bot.controlState.sneak
}
const state = new PlayerState(this.bot, simulationControl)
state.pos.update(n1)
this.simulateUntil(reached, this.getController(n2, false, true), Math.floor(5 * n1.distanceTo(n2)), state)
return reached(state)
}
canSprintJump (path, jumpAfter = 0) {
const reached = this.getReached(path)
const state = this.simulateUntil(reached, this.getController(path[0], true, true, jumpAfter), 20)
return reached(state)
}
canWalkJump (path, jumpAfter = 0) {
const reached = this.getReached(path)
const state = this.simulateUntil(reached, this.getController(path[0], true, false, jumpAfter), 20)
return reached(state)
}
getReached (path) {
return (state) => {
const delta = path[0].minus(state.pos)
return Math.abs(delta.x) <= 0.35 && Math.abs(delta.z) <= 0.35 && Math.abs(delta.y) < 1
}
}
getController (nextPoint, jump, sprint, jumpAfter = 0) {
return (state, tick) => {
const dx = nextPoint.x - state.pos.x
const dz = nextPoint.z - state.pos.z
state.yaw = Math.atan2(-dx, -dz)
state.control.forward = true
state.control.jump = jump && tick >= jumpAfter
state.control.sprint = sprint
}
}
}
module.exports = Physics