Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Player hitbox fixes #3382

Merged
merged 12 commits into from
Jul 13, 2024
2 changes: 1 addition & 1 deletion examples/place_end_crystal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ bot.on('chat', async (ign, msg) => {
const { x: aboveX, y: aboveY, z: aboveZ } = block.position.offset(0, 1, 0)
const blockBoundingBox = new AABB(aboveX, aboveY, aboveZ, aboveX + 1, aboveY + 2, aboveZ + 1)
const entityAABBs = Object.values(bot.entities).map(entity => {
// taken from taken from https://github.com/PrismarineJS/prismarine-physics/blob/d145e54a4bb8604300258badd7563f59f2101922/index.js#L92
// taken from https://github.com/PrismarineJS/prismarine-physics/blob/d145e54a4bb8604300258badd7563f59f2101922/index.js#L92
const w = entity.height / 2
const { x, y, z } = entity.position
return new AABB(-w, 0, -w, w, entity.height, w).offset(x, y, z)
Expand Down
2 changes: 1 addition & 1 deletion lib/plugins/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ function inject (bot, { version, storageBuilder, hideErrors }) {
// if passed in block is within line of sight to the bot, returns true
// also works on anything with a position value
function canSeeBlock (block) {
const headPos = bot.entity.position.offset(0, bot.entity.height, 0)
const headPos = bot.entity.position.offset(0, bot.entity.eyeHeight, 0)
const range = headPos.distanceTo(block.position)
const dir = block.position.offset(0.5, 0.5, 0.5).minus(headPos)
const match = (inputBlock, iter) => {
Expand Down
10 changes: 5 additions & 5 deletions lib/plugins/digging.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ function inject (bot) {
)
} else if (digFace === 'raycast') {
// Check faces that could be seen from the current position. If the delta is smaller then 0.5 that means the
// bot cam most likely not see the face as the block is 1 block thick
// this could be false for blocks that have a smaller bounding box then 1x1x1
// bot can most likely not see the face as the block is 1 block thick
// this could be false for blocks that have a smaller bounding box than 1x1x1
const dx = bot.entity.position.x - (block.position.x + 0.5)
const dy = bot.entity.position.y + bot.entity.height - (block.position.y + 0.5)
const dy = bot.entity.position.y + bot.entity.eyeHeight - (block.position.y + 0.5)
const dz = bot.entity.position.z - (block.position.z + 0.5)
// Check y first then x and z
const visibleFaces = {
Expand All @@ -63,7 +63,7 @@ function inject (bot) {
0.5 + (i === 'y' ? visibleFaces[i] * 0.5 : 0),
0.5 + (i === 'z' ? visibleFaces[i] * 0.5 : 0)
)
const startPos = bot.entity.position.offset(0, bot.entity.height, 0)
const startPos = bot.entity.position.offset(0, bot.entity.eyeHeight, 0)
const rayBlock = bot.world.raycast(startPos, targetPos.clone().subtract(startPos).normalize(), 5)
if (rayBlock) {
if (startPos.distanceTo(rayBlock.intersect) < startPos.distanceTo(targetPos)) {
Expand Down Expand Up @@ -94,7 +94,7 @@ function inject (bot) {
for (const i in validFaces) {
const tPos = validFaces[i].targetPos
const cDist = new Vec3(tPos.x, tPos.y, tPos.z).distanceSquared(
bot.entity.position.offset(0, bot.entity.height, 0)
bot.entity.position.offset(0, bot.entity.eyeHeight, 0)
)
if (distSqrt > cDist) {
closest = validFaces[i]
Expand Down
22 changes: 16 additions & 6 deletions lib/plugins/entities.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
const { Vec3 } = require('vec3')
const conv = require('../conversions')
const NAMED_ENTITY_HEIGHT = 1.62
const NAMED_ENTITY_WIDTH = 0.6
const CROUCH_HEIGHT = NAMED_ENTITY_HEIGHT - 0.08
// These values are only accurate for versions 1.14 and above (crouch hitbox changes)
// Todo: hitbox sizes for sleeping, swimming/crawling, and flying with elytra
const PLAYER_HEIGHT = 1.8
const CROUCH_HEIGHT = 1.5
const PLAYER_WIDTH = 0.6
const PLAYER_EYEHEIGHT = 1.62
const CROUCH_EYEHEIGHT = 1.27

module.exports = inject

Expand Down Expand Up @@ -102,6 +106,9 @@ function inject (bot) {
bot.entity.username = bot._client.username
bot.entity.type = 'player'
bot.entity.name = 'player'
bot.entity.height = PLAYER_HEIGHT
bot.entity.width = PLAYER_WIDTH
bot.entity.eyeHeight = PLAYER_EYEHEIGHT
})

bot._client.on('entity_equipment', (packet) => {
Expand Down Expand Up @@ -130,11 +137,13 @@ function inject (bot) {
})

bot.on('entityCrouch', (entity) => {
entity.eyeHeight = CROUCH_EYEHEIGHT
entity.height = CROUCH_HEIGHT
})

bot.on('entityUncrouch', (entity) => {
entity.height = NAMED_ENTITY_HEIGHT
entity.eyeHeight = PLAYER_EYEHEIGHT
entity.height = PLAYER_HEIGHT
})

bot._client.on('collect', (packet) => {
Expand Down Expand Up @@ -184,8 +193,9 @@ function inject (bot) {
entity.username = bot.uuidToUsername[uuid]
entity.uuid = uuid
updateEntityPos(entity, pos)
entity.height = NAMED_ENTITY_HEIGHT
entity.width = NAMED_ENTITY_WIDTH
entity.eyeHeight = PLAYER_EYEHEIGHT
entity.height = PLAYER_HEIGHT
entity.width = PLAYER_WIDTH
if (bot.players[entity.username] !== undefined && !bot.players[entity.username].entity) {
bot.players[entity.username].entity = entity
}
Expand Down
6 changes: 4 additions & 2 deletions lib/plugins/physics.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) {
}

bot.lookAt = async (point, force) => {
const delta = point.minus(bot.entity.position.offset(0, bot.entity.height, 0))
const delta = point.minus(bot.entity.position.offset(0, bot.entity.eyeHeight, 0))
const yaw = Math.atan2(-delta.x, -delta.z)
const groundDistance = Math.sqrt(delta.x * delta.x + delta.z * delta.z)
const pitch = Math.atan2(delta.y, groundDistance)
Expand All @@ -332,7 +332,9 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) {

// player position and look (clientbound)
bot._client.on('position', (packet) => {
bot.entity.height = 1.62
// Is this necessary? Feels like it might wrongly overwrite hitbox size sometimes
// e.g. when crouching/crawling/swimming. Can someone confirm?
bot.entity.height = 1.8

// Velocity is only set to 0 if the flag is not set, otherwise keep current velocity
const vel = bot.entity.velocity
Expand Down
4 changes: 2 additions & 2 deletions lib/plugins/ray_trace.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = (bot) => {
.filter(entity => entity.type !== 'object' && entity.username !== bot.username && entity.position.distanceTo(bot.entity.position) <= maxDistance)

const dir = new Vec3(-Math.sin(bot.entity.yaw) * Math.cos(bot.entity.pitch), Math.sin(bot.entity.pitch), -Math.cos(bot.entity.yaw) * Math.cos(bot.entity.pitch))
const iterator = new RaycastIterator(bot.entity.position.offset(0, bot.entity.height, 0), dir.normalize(), maxDistance)
const iterator = new RaycastIterator(bot.entity.position.offset(0, bot.entity.eyeHeight, 0), dir.normalize(), maxDistance)

let targetEntity = null
let targetDist = maxDistance
Expand All @@ -37,7 +37,7 @@ module.exports = (bot) => {
const entity = entities[i]
const w = entity.width / 2

const shapes = [[-w, 0, -w, w, entity.height + (entity.type === 'player' ? 0.18 : 0), w]]
const shapes = [[-w, 0, -w, w, entity.height, w]]
const intersect = iterator.intersect(shapes, entity.position)
if (intersect) {
const entityDir = entity.position.minus(bot.entity.position) // Can be combined into 1 line
Expand Down
Loading