From a9ad14008e5dd0f3b647b404d6846833ed3c4fd3 Mon Sep 17 00:00:00 2001 From: extremeheat Date: Thu, 8 Apr 2021 01:32:20 -0400 Subject: [PATCH] viewer: add sprint, sneaking --- examples/viewer/client/BotViewer.js | 31 ++++++++--- examples/viewer/client/movements.js | 80 +++++++++++++++++++++++------ examples/viewer/index.js | 9 ++-- package.json | 1 + 4 files changed, 96 insertions(+), 25 deletions(-) diff --git a/examples/viewer/client/BotViewer.js b/examples/viewer/client/BotViewer.js index 867fccb..57f9d16 100644 --- a/examples/viewer/client/BotViewer.js +++ b/examples/viewer/client/BotViewer.js @@ -2,7 +2,7 @@ const { Viewer, MapControls } = require('prismarine-viewer/viewer') // const { Vec3 } = require('vec3') const { ClientProvider } = require('./ClientProvider') -const { ProxyProvider } = require('./ProxyProvider') +// const { ProxyProvider } = require('./ProxyProvider') global.THREE = require('three') const MCVER = '1.16.1' @@ -61,12 +61,29 @@ class BotViewer { }) }) - this.bot.on('startSprint', () => { - this.viewer.camera.fov += 20 - }) - this.bot.on('stopSprint', () => { - this.viewer.camera.fov -= 20 - }) + const oldFov = this.viewer.camera.fov + const sprintFov = this.viewer.camera.fov + 20 + const sneakFov = this.viewer.camera.fov - 10 + + const onSprint = () => { + this.viewer.camera.fov = sprintFov + this.viewer.camera.updateProjectionMatrix() + } + + const onSneak = () => { + this.viewer.camera.fov = sneakFov + this.viewer.camera.updateProjectionMatrix() + } + + const onRelease = () => { + this.viewer.camera.fov = oldFov + this.viewer.camera.updateProjectionMatrix() + } + + this.bot.on('startSprint', onSprint) + this.bot.on('startSneak', onSneak) + this.bot.on('stopSprint', onRelease) + this.bot.on('stopSneak', onRelease) this.controls.update() diff --git a/examples/viewer/client/movements.js b/examples/viewer/client/movements.js index 0fdb76e..d359bea 100644 --- a/examples/viewer/client/movements.js +++ b/examples/viewer/client/movements.js @@ -5,6 +5,7 @@ const vec3 = require('vec3') const PHYSICS_INTERVAL_MS = 50 const PHYSICS_TIMESTEP = PHYSICS_INTERVAL_MS / 1000 +const AXES = ['forward', 'back', 'left', 'right'] class MovementManager { // Server auth movement : we send inputs, server calculates position & sends back @@ -38,7 +39,7 @@ class MovementManager { if (this.serverMovements) { globalThis.movePayload = { pitch: r2d(this.player.entity.pitch), - yaw: r2d(this.player.entity.yaw), // r2d(this.player.entity.yaw), + yaw: r2d(this.player.entity.yaw), position: { x: this.lastPos.x, y: this.lastPos.y + 1.62, @@ -48,7 +49,7 @@ class MovementManager { x: inputState.left ? 1 : (inputState.right ? -1 : 0), z: inputState.up ? 1 : (inputState.down ? -1 : 0) }, - head_yaw: r2d(this.player.entity.yaw), // r2d(this.player.entity.headYaw), + head_yaw: r2d(this.player.entity.yaw), input_data: inputState, input_mode: 'mouse', play_mode: 'screen', @@ -93,6 +94,7 @@ class MovementManager { startSneak: false, stopSneak: false }, + sprinting: false, jumpTicks: 0, jumpQueued: false, downJump: false @@ -185,36 +187,80 @@ class MovementManager { }, PHYSICS_INTERVAL_MS) } + get sprinting() { + return this.player.sprinting + } + + set sprinting(val) { + this.player.events.startSprint = val + this.player.events.stopSprint = !val + if (val && !this.player.sprinting) { + this.bot.emit('startSprint') + } else { + this.bot.emit('stopSprint') + } + this.player.sprinting = val + } + + _lastInput = { control: '', time: 0 } + /** * Sets the active control state and also keeps track of key toggles. * @param {'forward' | 'back' | 'left' | 'right' | 'jump' | 'sprint' | 'sneak'} control * @param {boolean} state */ - setControlState (control, state) { + setControlState (control, state, time = Date.now()) { // HACK ! switch left and right, fixes control issue if (control === 'left') control = 'right' else if (control === 'right') control = 'left' if (this.controls[control] === state) return - if (control === 'sprint') { - this.player.events.startSprint = state - this.player.events.stopSprint = !state - if (state) this.bot.emit('startSprint') - else this.bot.emit('stopSprint') - this.controls.sprint = true - } else if (control === 'sneak') { - this.player.events.startSneak = state - this.player.events.stopSneak = !state - this.controls.sprint = true - } else { - this.controls[control] = state + + const isAxis = AXES.includes(control) + let hasOtherAxisKeyDown = false + for (const c of AXES) { + if (this.controls[c] && c != control) { + hasOtherAxisKeyDown = true + } } + + if (control === 'sprint') { + if (state && hasOtherAxisKeyDown) { // sprint down + a axis movement key + this.sprinting = true + } else if ((!state || !hasOtherAxisKeyDown) && this.sprinting) { // sprint up or movement key up & current sprinting + this.bot.emit('stopSprint') + this.sprinting = false + } + } else if (isAxis && this.controls.sprint) { + if (!state && !hasOtherAxisKeyDown) { + this.sprinting = false + } else if (state && !hasOtherAxisKeyDown) { + this.sprinting = true + } + } else if (control === 'sneak') { + if (state) { + this.player.events.startSneak = true + this.bot.emit('startSneak') + } else { + this.player.events.stopSneak = true + this.bot.emit('stopSneak') + } + } else if (control === 'forward' && this._lastInput.control === 'forward' && (Date.now() - this._lastInput.time) < 100 && !this.controls.sprint) { + // double tap forward within 0.5 seconds, toggle sprint + // this.controls.sprint = true + // this.sprinting = true + } + + this._lastInput = { control, time } + this.controls[control] = state } stopPhys () { clearInterval(this.physicsLoop) } + // Called when a proxy player sends a PlayerInputPacket. We need to apply these inputs tick-by-tick + // as these packets are sent by the client every tick. pushInputState (state, yaw, pitch) { const yawRad = d2r(yaw) const pitchRad = d2r(pitch) @@ -232,6 +278,9 @@ class MovementManager { globalThis.debugYaw = [yaw, yawRad] } + + // Called when a proxy player sends a PlayerInputPacket. We need to apply these inputs tick-by-tick + // as these packets are sent by the client every tick. pushCameraControl (state, id = 1) { let { x, y, z } = state.position if (id === 1) y -= 1.62 // account for player bb @@ -247,6 +296,7 @@ class MovementManager { if (tick) this.tick = tick } + // User has moved the camera. Update the movements stored. onViewerCameraMove (newYaw, newPitch, newHeadYaw) { this.lastRot = { x: newYaw, y: newPitch, z: newHeadYaw } } diff --git a/examples/viewer/index.js b/examples/viewer/index.js index 5d17e38..954d4b6 100644 --- a/examples/viewer/index.js +++ b/examples/viewer/index.js @@ -1,7 +1,7 @@ const path = require('path') const { app, BrowserWindow, globalShortcut } = require('electron') -function createMainWindow () { +function createMainWindow() { const window = new BrowserWindow({ webPreferences: { nodeIntegration: true, @@ -27,10 +27,13 @@ function createMainWindow () { } app.on('ready', () => { - createMainWindow() + const win = createMainWindow() globalShortcut.register('CommandOrControl+W', () => { - // no op + win.webContents.sendInputEvent({ + type: 'keyDown', + keyCode: 'W' + }) }) }) diff --git a/package.json b/package.json index 51cdac9..e6371bd 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@xboxreplay/xboxlive-auth": "^3.3.3", "asn1": "^0.2.4", "browserify-cipher": "^1.0.1", + "bedrock-provider": "^1.0.0", "debug": "^4.3.1", "ec-pem": "^0.18.0", "jsonwebtoken": "^8.5.1",