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

Update digging.js for state changes #3136

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 54 additions & 45 deletions lib/plugins/digging.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,23 @@ module.exports = inject

function inject (bot) {
let swingInterval = null
let waitTimeout = null
let waitInterval = null

let diggingTask = createDoneTask()

bot.targetDigBlock = null
bot.lastDigTime = null
bot.digPercentage = 0
bot.lastHeldItemName = ''
if (bot.heldItem) { bot.lastHeldItemName = bot.heldItem.name }
bot.on('heldItemChanged', () => {
let nameToCompare = ''
if (bot.heldItem) { nameToCompare = bot.heldItem.name }
if (bot.lastHeldItemName != nameToCompare) {
bot.lastHeldItemName = nameToCompare
bot.digPercentage = 0
}
})

async function dig (block, forceLook, digFace) {
if (block === null || block === undefined) {
Expand All @@ -36,17 +47,15 @@ function inject (bot) {
} else if (digFace.z) {
diggingFace = digFace.z > 0 ? BlockFaces.SOUTH : BlockFaces.NORTH
}
await bot.lookAt(
block.position.offset(0.5, 0.5, 0.5).offset(digFace.x * 0.5, digFace.y * 0.5, digFace.z * 0.5),
forceLook
)
await bot.lookAt(block.position.offset(0.5, 0.5, 0.5).offset(digFace.x * 0.5, digFace.y * 0.5, digFace.z * 0.5), forceLook)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

} 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
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 dz = bot.entity.position.z - (block.position.z + 0.5)
const dx = bot.entity.position.x - block.position.x + 0.5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

const dy = bot.entity.position.y - block.position.y - 0.5 + bot.entity.height // -0.5 because the bot position
// is calculated from the block position that is inside its feet so 0.5 - 1 = -0.5
const dz = bot.entity.position.z - block.position.z + 0.5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is incorrect

// Check y first then x and z
const visibleFaces = {
y: Math.sign(Math.abs(dy) > 0.5 ? dy : 0),
Expand All @@ -57,20 +66,12 @@ function inject (bot) {
for (const i in visibleFaces) {
if (!visibleFaces[i]) continue // skip as this face is not visible
// target position on the target block face. -> 0.5 + (current face) * 0.5
const targetPos = block.position.offset(
0.5 + (i === 'x' ? visibleFaces[i] * 0.5 : 0),
0.5 + (i === 'y' ? visibleFaces[i] * 0.5 : 0),
0.5 + (i === 'z' ? visibleFaces[i] * 0.5 : 0)
)
const targetPos = block.position.offset(0.5 + (i === 'x' ? visibleFaces[i] * 0.5 : 0), 0.5 + (i === 'y' ? visibleFaces[i] * 0.5 : 0), 0.5 + (i === 'z' ? visibleFaces[i] * 0.5 : 0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

const startPos = bot.entity.position.offset(0, bot.entity.height, 0)
const rayBlock = bot.world.raycast(startPos, targetPos.clone().subtract(startPos).normalize(), 5)
if (rayBlock) {
const rayPos = rayBlock.position
if (
rayPos.x === block.position.x &&
rayPos.y === block.position.y &&
rayPos.z === block.position.z
) {
if (rayPos.x === block.position.x && rayPos.y === block.position.y && rayPos.z === block.position.z) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

// console.info(rayBlock)
validFaces.push({
face: rayBlock.face,
Expand All @@ -85,9 +86,7 @@ function inject (bot) {
let distSqrt = 999
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)
)
const cDist = new Vec3(tPos.x, tPos.y, tPos.z).distanceSquared(bot.entity.position.offset(0, bot.entity.height, 0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

if (distSqrt > cDist) {
closest = validFaces[i]
distSqrt = cDist
Expand All @@ -111,19 +110,37 @@ function inject (bot) {
face: diggingFace // default face is 1 (top)
})
const waitTime = bot.digTime(block)
waitTimeout = setTimeout(finishDigging, waitTime)
// waitInterval = setTimeout(finishDigging, waitTime)
if (waitInterval) { clearInterval(waitInterval) }
// bot.digPercentage = (50 / bot.digTime(block));
// bot.referenceTime = window.performance.now();
waitInterval = setInterval(() => { //! !!!
bot.digPercentage += (50 / bot.digTime(block))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does the vanilla client follow this algorithm when state change while digging ? do you have a reference ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not this exact algorithm but it mimics what I've seen in game, and I've yet to see something abnormal from it.

// bot.digPercentage += (Math.abs(bot.referenceTime - window.performance.now()) / bot.digTime(block));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented code

// console.log(Math.abs(bot.referenceTime - window.performance.now()) + ", " + bot.digPercentage);
// bot.referenceTime = window.performance.now();
if (bot.digPercentage >= 1.0) {
// console.log("broke it");
finishDigging()
}
}, 50)
bot.targetDigBlock = block
bot.swingArm()

swingInterval = setInterval(() => {
bot.swingArm()
}, 350)
if (bot.targetDigBlock) {
bot.swingArm()
} else {
clearInterval(swingInterval)
}
}, 250)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the change from 350 to 250 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Vakore can you change this back or give w reason to why you changed the interval?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the interval to fix the arm swing bug


function finishDigging () {
bot.digPercentage = 0
clearInterval(swingInterval)
clearTimeout(waitTimeout)
clearInterval(waitInterval)
swingInterval = null
waitTimeout = null
waitInterval = null
if (bot.targetDigBlock) {
bot._client.write('block_dig', {
status: 2, // finish digging
Expand All @@ -137,15 +154,17 @@ function inject (bot) {
}

const eventName = `blockUpdate:${block.position}`
// console.log(bot.digPercentage + "% " + eventName);
bot.on(eventName, onBlockUpdate)

bot.stopDigging = () => {
if (!bot.targetDigBlock) return
bot.removeListener(eventName, onBlockUpdate)
clearInterval(swingInterval)
clearTimeout(waitTimeout)
bot.digPercentage = 0
clearInterval(waitInterval)
swingInterval = null
waitTimeout = null
waitInterval = null
bot._client.write('block_dig', {
status: 1, // cancel digging
location: bot.targetDigBlock.position,
Expand All @@ -162,13 +181,14 @@ function inject (bot) {
function onBlockUpdate (oldBlock, newBlock) {
// vanilla server never actually interrupt digging, but some server send block update when you start digging
// so ignore block update if not air
// All block update listeners receive (null, null) when the world is unloaded. So newBlock can be null.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove this comment?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably on accident.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the comment back?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a more updated version of digging.js on the discord. Search for attachments from 'Vakore', unable to do stuff with npm rn.

if (newBlock?.type !== 0) return
if (!newBlock) return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't change anything, see the ? below
you can remove this change

if (newBlock.type !== 0) return
bot.removeListener(eventName, onBlockUpdate)
clearInterval(swingInterval)
clearTimeout(waitTimeout)
clearInterval(waitInterval)
swingInterval = null
waitTimeout = null
waitInterval = null
bot.digPercentage = 0.0
bot.targetDigBlock = null
bot.lastDigTime = performance.now()
bot.emit('diggingCompleted', newBlock)
Expand All @@ -185,11 +205,7 @@ function inject (bot) {
})

function canDigBlock (block) {
return (
block &&
block.diggable &&
block.position.offset(0.5, 0.5, 0.5).distanceTo(bot.entity.position.offset(0, 1.65, 0)) <= 5.1
)
return block && block.diggable && block.position.offset(0.5, 0.5, 0.5).distanceTo(bot.entity.position.offset(0, 1.65, 0)) <= 5.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

}

function digTime (block) {
Expand All @@ -212,14 +228,7 @@ function inject (bot) {
}

const creative = bot.game.gameMode === 'creative'
return block.digTime(
type,
creative,
bot.entity.isInWater,
!bot.entity.onGround,
enchantments,
bot.entity.effects
)
return block.digTime(type, creative, bot.entity.isInWater, !bot.entity.onGround, enchantments, bot.entity.effects)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

}

bot.dig = dig
Expand Down