mirror of
https://github.com/PrismarineJS/prismarine-web-client.git
synced 2025-03-19 00:29:53 -04:00
Fix dig/place logic (#148)
This commit is contained in:
parent
1c1a66c57a
commit
0506f5a70d
2 changed files with 115 additions and 125 deletions
136
index.js
136
index.js
|
@ -8,6 +8,7 @@ require('./lib/playerlist')
|
|||
require('./lib/debugmenu')
|
||||
|
||||
const net = require('net')
|
||||
const Cursor = require('./lib/cursor')
|
||||
|
||||
// Workaround for process.versions.node not existing in the browser
|
||||
process.versions.node = '14.0.0'
|
||||
|
@ -41,12 +42,6 @@ document.body.appendChild(renderer.domElement)
|
|||
// Create viewer
|
||||
const viewer = new Viewer(renderer)
|
||||
|
||||
const textures = []
|
||||
|
||||
const loader = new THREE.TextureLoader()
|
||||
|
||||
let breakStartTime
|
||||
|
||||
// Menu panorama background
|
||||
function getPanoramaMesh () {
|
||||
const geometry = new THREE.SphereGeometry(500, 60, 40)
|
||||
|
@ -71,7 +66,7 @@ let panoramaMesh = getPanoramaMesh()
|
|||
viewer.scene.add(panoramaMesh)
|
||||
|
||||
// Browser animation loop
|
||||
const animate = () => {
|
||||
let animate = () => {
|
||||
window.requestAnimationFrame(animate)
|
||||
viewer.update()
|
||||
renderer.render(viewer.scene, viewer.camera)
|
||||
|
@ -210,92 +205,24 @@ async function connect (options) {
|
|||
|
||||
initVR(bot, renderer, viewer)
|
||||
|
||||
const cursor = new Cursor(viewer, renderer)
|
||||
animate = () => {
|
||||
window.requestAnimationFrame(animate)
|
||||
viewer.update()
|
||||
cursor.update(bot)
|
||||
debugMenu.cursorBlock = cursor.cursorBlock
|
||||
renderer.render(viewer.scene, viewer.camera)
|
||||
}
|
||||
|
||||
// Link WorldView and Viewer
|
||||
viewer.listen(worldView)
|
||||
worldView.listenToBot(bot)
|
||||
worldView.init(bot.entity.position)
|
||||
|
||||
// Create cursor mesh
|
||||
const boxGeometry = new THREE.BoxBufferGeometry(1.001, 1.001, 1.001)
|
||||
const cursorMesh = new THREE.LineSegments(new THREE.EdgesGeometry(boxGeometry), new THREE.LineBasicMaterial({ color: 0 }))
|
||||
viewer.scene.add(cursorMesh)
|
||||
|
||||
function updateCursor () {
|
||||
const cursorBlock = bot.blockAtCursor()
|
||||
debugMenu.cursorBlock = cursorBlock
|
||||
if (!cursorBlock || !bot.canDigBlock(cursorBlock)) {
|
||||
cursorMesh.visible = false
|
||||
return
|
||||
} else {
|
||||
cursorMesh.visible = true
|
||||
}
|
||||
cursorMesh.position.set(cursorBlock.position.x + 0.5, cursorBlock.position.y + 0.5, cursorBlock.position.z + 0.5)
|
||||
}
|
||||
|
||||
// Create block break mesh
|
||||
|
||||
const material = new THREE.MeshBasicMaterial({
|
||||
transparent: true,
|
||||
alphaTest: 0.1
|
||||
})
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const texture = loader.load('textures/' + viewer.version + '/blocks/destroy_stage_' + i + '.png')
|
||||
texture.magFilter = THREE.NearestFilter
|
||||
texture.minFilter = THREE.NearestFilter
|
||||
textures.push(texture)
|
||||
}
|
||||
|
||||
const geometry = new THREE.BoxGeometry(1.001, 1.001, 1.001)
|
||||
const blockBreakMesh = new THREE.Mesh(geometry, material)
|
||||
viewer.scene.add(blockBreakMesh)
|
||||
blockBreakMesh.visible = false
|
||||
|
||||
async function updateBreakMesh (x, y, z, time) {
|
||||
const thisBreakStartTime = new Date().getTime()
|
||||
breakStartTime = thisBreakStartTime
|
||||
console.log('updating break mesh')
|
||||
blockBreakMesh.position.set(x + 0.5, y + 0.5, z + 0.5)
|
||||
// eslint-disable-next-line promise/param-names
|
||||
const timer = ms => new Promise(res => setTimeout(res, ms))
|
||||
|
||||
const animate = async () => {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
if (thisBreakStartTime !== breakStartTime) break
|
||||
await timer(time / 10)
|
||||
console.log('At stage ' + i)
|
||||
blockBreakMesh.material.map = textures[i]
|
||||
blockBreakMesh.visible = true
|
||||
}
|
||||
hideBreakMesh()
|
||||
updateCursor()
|
||||
}
|
||||
animate()
|
||||
}
|
||||
|
||||
function hideBreakMesh () {
|
||||
console.log('hiding break mesh & canceling loop')
|
||||
breakStartTime = new Date().getTime()
|
||||
blockBreakMesh.visible = false
|
||||
}
|
||||
|
||||
bot.on('diggingAborted', () => {
|
||||
console.log('digging aborted')
|
||||
hideBreakMesh()
|
||||
keepMouseDownAction = false
|
||||
})
|
||||
|
||||
bot.on('diggingCompleted', () => {
|
||||
console.log('digging completed')
|
||||
hideBreakMesh()
|
||||
})
|
||||
|
||||
// Bot position callback
|
||||
|
||||
function botPosition () {
|
||||
viewer.setFirstPersonCamera(bot.entity.position, bot.entity.yaw, bot.entity.pitch)
|
||||
worldView.updatePosition(bot.entity.position)
|
||||
updateCursor()
|
||||
}
|
||||
bot.on('move', botPosition)
|
||||
botPosition()
|
||||
|
@ -308,7 +235,6 @@ async function connect (options) {
|
|||
bot.entity.yaw -= e.movementX * window.settings.mouseSensXValue
|
||||
|
||||
viewer.setFirstPersonCamera(null, bot.entity.yaw, bot.entity.pitch)
|
||||
updateCursor()
|
||||
}
|
||||
|
||||
function changeCallback () {
|
||||
|
@ -380,46 +306,6 @@ async function connect (options) {
|
|||
}
|
||||
}, false)
|
||||
|
||||
async function sleep (ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
let keepMouseDownAction = false
|
||||
document.addEventListener('mousedown', async (e) => {
|
||||
if (document.pointerLockElement !== renderer.domElement) return
|
||||
|
||||
keepMouseDownAction = true
|
||||
while (keepMouseDownAction) { // eslint-disable-line
|
||||
const cursorBlock = bot.blockAtCursor()
|
||||
if (!cursorBlock) {
|
||||
await sleep(100)
|
||||
continue
|
||||
}
|
||||
|
||||
if (e.button === 0) {
|
||||
if (bot.canDigBlock(cursorBlock)) {
|
||||
updateBreakMesh(cursorBlock.position.x, cursorBlock.position.y, cursorBlock.position.z, bot.digTime(cursorBlock))
|
||||
await bot.dig(cursorBlock, 'ignore')
|
||||
} else {
|
||||
await sleep(100)
|
||||
continue
|
||||
}
|
||||
} else if (e.button === 2) {
|
||||
const vecArray = [new Vec3(0, -1, 0), new Vec3(0, 1, 0), new Vec3(0, 0, -1), new Vec3(0, 0, 1), new Vec3(-1, 0, 0), new Vec3(1, 0, 0)]
|
||||
const vec = vecArray[cursorBlock.face]
|
||||
|
||||
const delta = cursorBlock.intersect.minus(cursorBlock.position)
|
||||
await bot._placeBlockWithOptions(cursorBlock, vec, { delta, forceLook: 'ignore' })
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}, false)
|
||||
|
||||
document.addEventListener('mouseup', (e) => {
|
||||
keepMouseDownAction = false
|
||||
bot.stopDigging()
|
||||
}, false)
|
||||
|
||||
loadingScreen.status = 'Done!'
|
||||
console.log(loadingScreen.status) // only do that because it's read in index.html and npm run fix complains.
|
||||
|
||||
|
|
104
lib/cursor.js
Normal file
104
lib/cursor.js
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* global THREE performance */
|
||||
|
||||
const { Vec3 } = require('vec3')
|
||||
|
||||
class Cursor {
|
||||
constructor (viewer, renderer) {
|
||||
// Init state
|
||||
this.buttons = [false, false, false]
|
||||
this.lastButtons = [false, false, false]
|
||||
this.breakStartTime = 0
|
||||
this.cursorBlock = null
|
||||
|
||||
// Setup graphics
|
||||
const blockGeometry = new THREE.BoxGeometry(1.001, 1.001, 1.001)
|
||||
this.cursorMesh = new THREE.LineSegments(new THREE.EdgesGeometry(blockGeometry), new THREE.LineBasicMaterial({ color: 0 }))
|
||||
this.cursorMesh.visible = false
|
||||
viewer.scene.add(this.cursorMesh)
|
||||
|
||||
const loader = new THREE.TextureLoader()
|
||||
this.breakTextures = []
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const texture = loader.load('textures/' + viewer.version + '/blocks/destroy_stage_' + i + '.png')
|
||||
texture.magFilter = THREE.NearestFilter
|
||||
texture.minFilter = THREE.NearestFilter
|
||||
this.breakTextures.push(texture)
|
||||
}
|
||||
const breakMaterial = new THREE.MeshBasicMaterial({
|
||||
transparent: true,
|
||||
alphaTest: 0.1
|
||||
})
|
||||
this.blockBreakMesh = new THREE.Mesh(blockGeometry, breakMaterial)
|
||||
this.blockBreakMesh.visible = false
|
||||
viewer.scene.add(this.blockBreakMesh)
|
||||
|
||||
// Setup events
|
||||
document.addEventListener('mouseup', (e) => {
|
||||
this.buttons[e.button] = false
|
||||
})
|
||||
document.addEventListener('mousedown', (e) => {
|
||||
if (document.pointerLockElement !== renderer.domElement) return
|
||||
this.buttons[e.button] = true
|
||||
})
|
||||
}
|
||||
|
||||
update (bot) {
|
||||
let cursorBlock = bot.blockAtCursor(6)
|
||||
if (!bot.canDigBlock(cursorBlock)) cursorBlock = null
|
||||
|
||||
let cursorChanged = !cursorBlock !== !this.cursorBlock
|
||||
if (cursorBlock && this.cursorBlock) {
|
||||
cursorChanged = !cursorBlock.position.equals(this.cursorBlock.position)
|
||||
}
|
||||
|
||||
// Place
|
||||
if (cursorBlock && this.buttons[2] && (!this.lastButtons[2] || cursorChanged)) {
|
||||
const vecArray = [new Vec3(0, -1, 0), new Vec3(0, 1, 0), new Vec3(0, 0, -1), new Vec3(0, 0, 1), new Vec3(-1, 0, 0), new Vec3(1, 0, 0)]
|
||||
const delta = cursorBlock.intersect.minus(cursorBlock.position)
|
||||
bot._placeBlockWithOptions(cursorBlock, vecArray[cursorBlock.face], { delta, forceLook: 'ignore' })
|
||||
}
|
||||
|
||||
// Start break
|
||||
if (cursorBlock && this.buttons[0] && (!this.lastButtons[0] || cursorChanged)) {
|
||||
this.breakStartTime = performance.now()
|
||||
try {
|
||||
bot.dig(cursorBlock, 'ignore')
|
||||
} catch {} // we don't care if its aborted
|
||||
}
|
||||
|
||||
// Stop break
|
||||
if (!this.buttons[0] && this.lastButtons[0]) {
|
||||
try {
|
||||
bot.stopDigging() // this shouldnt throw anything...
|
||||
} catch {} // to be reworked in mineflayer, then remove the try here
|
||||
}
|
||||
|
||||
// Show break animation
|
||||
if (cursorBlock && this.buttons[0]) {
|
||||
const elapsed = performance.now() - this.breakStartTime
|
||||
const time = bot.digTime(cursorBlock)
|
||||
const state = Math.floor((elapsed / time) * 10)
|
||||
this.blockBreakMesh.position.set(cursorBlock.position.x + 0.5, cursorBlock.position.y + 0.5, cursorBlock.position.z + 0.5)
|
||||
this.blockBreakMesh.material.map = this.breakTextures[state]
|
||||
this.blockBreakMesh.visible = true
|
||||
} else {
|
||||
this.blockBreakMesh.visible = false
|
||||
}
|
||||
|
||||
// Show cursor
|
||||
if (!cursorBlock) {
|
||||
this.cursorMesh.visible = false
|
||||
} else {
|
||||
this.cursorMesh.visible = true
|
||||
this.cursorMesh.position.set(cursorBlock.position.x + 0.5, cursorBlock.position.y + 0.5, cursorBlock.position.z + 0.5)
|
||||
}
|
||||
|
||||
// Update state
|
||||
this.cursorBlock = cursorBlock
|
||||
this.lastButtons[0] = this.buttons[0]
|
||||
this.lastButtons[1] = this.buttons[1]
|
||||
this.lastButtons[2] = this.buttons[2]
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Cursor
|
Loading…
Reference in a new issue