diff --git a/src/index.ts b/src/index.ts index 7534b638..707023b0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -78,7 +78,7 @@ import { startLocalServer, unsupportedLocalServerFeatures } from './createLocalS import serverOptions from './defaultLocalServerOptions' import { customCommunication } from './customServer' import updateTime from './updateTime' -import { options } from './optionsStorage' +import { options, watchValue } from './optionsStorage' import { subscribeKey } from 'valtio/utils' import _ from 'lodash' import { contro } from './controls' @@ -146,10 +146,9 @@ const viewer: import('../prismarine-viewer/viewer/lib/viewer').Viewer = new View initPanoramaOptions(viewer) watchTexturepackInViewer(viewer) -const frameLimit = toNumber(localStorage.frameLimit) -let interval = frameLimit && 1000 / frameLimit -window.addEventListener('option-change', ({ detail }: any) => { - if (detail.name === 'frameLimit') interval = toNumber(detail.value) && 1000 / toNumber(detail.value) +let renderInterval: number +watchValue(options, (o) => { + renderInterval = o.frameLimit && 1000 / o.frameLimit }) let nextFrameFn = [] @@ -160,11 +159,11 @@ const renderFrame = (time: DOMHighResTimeStamp) => { if (window.stopLoop) return window.requestAnimationFrame(renderFrame) if (window.stopRender) return - if (interval) { + if (renderInterval) { delta += time - lastTime lastTime = time - if (delta > interval) { - delta = delta % interval + if (delta > renderInterval) { + delta = delta % renderInterval // continue rendering } else { return @@ -195,7 +194,6 @@ window.addEventListener('resize', () => { const loadingScreen = document.getElementById('loading-error-screen') const hud = document.getElementById('hud') -const optionsScrn = document.getElementById('options-screen') const pauseMenu = document.getElementById('pause-screen') let mouseMovePostHandle = (e) => { } @@ -214,7 +212,7 @@ function onCameraMove(e) { // todo: limit camera movement for now to avoid unexpected jumps if (now - lastMouseMove < 4) return lastMouseMove = now - let { mouseSensX, mouseSensY } = optionsScrn + let { mouseSensX, mouseSensY } = options if (mouseSensY === true) mouseSensY = mouseSensX // debugPitch.innerText = +debugPitch.innerText + e.movementX mouseMovePostHandle({ @@ -539,9 +537,8 @@ async function connect(connectOptions: { window.worldView = worldView setRenderDistance() - let fovSetting = optionsScrn.fov const updateFov = () => { - fovSetting = optionsScrn.fov + let fovSetting = options.fov // todo check values and add transition if (bot.controlState.sprint && !bot.controlState.sneak) { fovSetting += 5 @@ -553,6 +550,7 @@ async function connect(connectOptions: { viewer.camera.updateProjectionMatrix() } updateFov() + subscribeKey(options, 'fov', updateFov) subscribeKey(gameAdditionalState, 'isFlying', updateFov) subscribeKey(gameAdditionalState, 'isSprinting', updateFov) const defaultPlayerHeight = viewer.playerHeight @@ -560,7 +558,6 @@ async function connect(connectOptions: { viewer.playerHeight = gameAdditionalState.isSneaking ? defaultPlayerHeight - 0.3 : defaultPlayerHeight viewer.setFirstPersonCamera(bot.entity.position, bot.entity.yaw, bot.entity.pitch) }) - optionsScrn.addEventListener('fov_changed', updateFov) bot.on('physicsTick', () => updateCursor()) viewer.setVersion(version) diff --git a/src/menus/advanced_options_screen.js b/src/menus/advanced_options_screen.js index 79167db6..18d180a5 100644 --- a/src/menus/advanced_options_screen.js +++ b/src/menus/advanced_options_screen.js @@ -1,21 +1,17 @@ //@ts-check -const { html, css } = require('lit') -const { CommonOptionsScreen } = require('./options_store') +const { html, css, LitElement } = require('lit') const { commonCss, openURL } = require('./components/common') const { hideCurrentModal } = require('../globalState') const { toNumber, getScreenRefreshRate } = require('../utils') const { subscribe } = require('valtio') const { options } = require('../optionsStorage') -class AdvancedOptionsScreen extends CommonOptionsScreen { +class AdvancedOptionsScreen extends LitElement { /** @type {null | number} */ frameLimitMax = null constructor () { super() - this.defineOptions({ - frameLimit: { defaultValue: false, convertFn: (v) => toNumber(v) ?? false }, - }) subscribe(options, () => { this.requestUpdate() }) @@ -66,10 +62,10 @@ class AdvancedOptionsScreen extends CommonOptionsScreen { openURL('https://gist.github.com/zardoy/6e5ce377d2b4c1e322e660973da069cd')}>
- { + { const newVal = e.target.value - this.changeOption('frameLimit', newVal > this.frameLimitMax ? false : newVal) + options.frameLimit = newVal > this.frameLimitMax ? false : newVal this.requestUpdate() }}> { diff --git a/src/menus/components/button.js b/src/menus/components/button.js index 445f0833..b503c0d0 100644 --- a/src/menus/components/button.js +++ b/src/menus/components/button.js @@ -1,6 +1,6 @@ //@ts-check const widgetsGui = require('minecraft-assets/minecraft-assets/data/1.17.1/gui/widgets.png') -const { LitElement, html, css, unsafeCSS } = require('lit') +const { options } = require('../../optionsStorage') const audioContext = new window.AudioContext() const sounds = {} @@ -16,12 +16,8 @@ async function loadSound (path) { loadingSounds.splice(loadingSounds.indexOf(path), 1) } -async function playSound (path) { - let volume = 1 - const options = document.getElementById('options-screen') - if (options) { - volume = options.sound / 100 - } +export async function playSound (path) { + const volume = options.volume / 100 // todo? if (loadingSounds.includes(path)) return @@ -167,5 +163,3 @@ class Button extends LitElement { loadSound('click_stereo.mp3') window.customElements.define('pmui-button', Button) -const _playSound = playSound -export { _playSound as playSound } diff --git a/src/menus/options_screen.js b/src/menus/options_screen.js index 333e39b8..5db91dd5 100644 --- a/src/menus/options_screen.js +++ b/src/menus/options_screen.js @@ -1,15 +1,14 @@ const { LitElement, html, css } = require('lit') const { commonCss, isMobile } = require('./components/common') const { showModal, hideCurrentModal, isGameActive, miscUiState } = require('../globalState') -const { CommonOptionsScreen } = require('./options_store') const { toNumber, openFilePicker, setLoadingScreenStatus } = require('../utils') -const { options } = require('../optionsStorage') +const { options, watchValue } = require('../optionsStorage') const { subscribe } = require('valtio') const { subscribeKey } = require('valtio/utils') const { getResourcePackName, uninstallTexturePack } = require('../texturePack') const { fsState } = require('../loadSave') -class OptionsScreen extends CommonOptionsScreen { +class OptionsScreen extends LitElement { static get styles () { return css` ${commonCss} @@ -40,38 +39,16 @@ class OptionsScreen extends CommonOptionsScreen { ` } - static get properties () { - return { - mouseSensX: { type: Number }, - mouseSensY: { type: Number }, - chatWidth: { type: Number }, - chatHeight: { type: Number }, - chatScale: { type: Number }, - sound: { type: Number }, - fov: { type: Number }, - guiScale: { type: Number } - } - } - constructor () { super() - this.defineOptions({ - mouseSensX: { defaultValue: 50, convertFn: (v) => Math.floor(toNumber(v)) }, - mouseSensY: { defaultValue: 50, convertFn: (v) => Math.floor(toNumber(v)) }, - chatWidth: { defaultValue: 320, convertFn: (v) => toNumber(v) }, - chatHeight: { defaultValue: 180, convertFn: (v) => toNumber(v) }, - chatScale: { defaultValue: 100, convertFn: (v) => toNumber(v) }, - sound: { defaultValue: 50, convertFn: (v) => toNumber(v) }, - fov: { defaultValue: 75, convertFn: (v) => toNumber(v) }, - guiScale: { defaultValue: 3, convertFn: (v) => toNumber(v) }, + watchValue(options, o => { + document.documentElement.style.setProperty('--chatScale', `${o.chatScale / 100}`) + document.documentElement.style.setProperty('--chatWidth', `${o.chatWidth}px`) + document.documentElement.style.setProperty('--chatHeight', `${o.chatHeight}px`) + document.documentElement.style.setProperty('--guiScale', `${o.guiScale}`) }) - document.documentElement.style.setProperty('--chatScale', `${this.chatScale / 100}`) - document.documentElement.style.setProperty('--chatWidth', `${this.chatWidth}px`) - document.documentElement.style.setProperty('--chatHeight', `${this.chatHeight}px`) - document.documentElement.style.setProperty('--guiScale', `${this.guiScale}`) - subscribe(options, () => { this.requestUpdate() }) @@ -85,53 +62,47 @@ class OptionsScreen extends CommonOptionsScreen { render () { return html` -
+

Options

- { - this.changeOption('mouseSensX', e.target.value) + { + options.mouseSensX = +e.target.value }}> - { - this.changeOption('mouseSensY', e.target.value) + { + options.mouseSensY = +e.target.value }}>
- { - this.changeOption('chatWidth', e.target.value) - document.documentElement.style.setProperty('--chatWidth', `${this.chatWidth}px`) + { + options.chatWidth = +e.target.value }}> - { - this.changeOption('chatHeight', e.target.value) - document.documentElement.style.setProperty('--chatHeight', `${this.chatHeight}px`) + { + options.chatHeight = +e.target.value }}>
- { - this.changeOption('chatScale', e.target.value) - document.documentElement.style.setProperty('--chatScale', `${this.chatScale / 100}`) + { + options.chatScale = +e.target.value }}> - { - this.changeOption('sound', e.target.value) + { + options.volume = +e.target.value }}>
showModal(document.getElementById('keybinds-screen'))}> - { - this.changeOption('guiScale', e.target.value) - document.documentElement.style.setProperty('--guiScale', `${this.guiScale}`) + { + options.guiScale = +e.target.value }}>
{ options.renderDistance = +e.target.value }}> - { - this.changeOption('fov', e.target.value) - - this.dispatchEvent(new window.CustomEvent('fov_changed', { detail: { fov: this.fov }, })) + { + options.fov = +e.target.value }}>
diff --git a/src/menus/options_store.js b/src/menus/options_store.js deleted file mode 100644 index 078d39e3..00000000 --- a/src/menus/options_store.js +++ /dev/null @@ -1,33 +0,0 @@ -//@ts-check - -import { LitElement } from 'lit' - -export class CommonOptionsScreen extends LitElement { - options = {} - - defineOptions (props) { - for (const [name, { defaultValue, convertValue = (v) => v, convertFn = convertValue }] of Object.entries(props)) { - Object.defineProperty(this.options, name, { - get () { - let value = window.localStorage.getItem(name) ? convertFn(window.localStorage.getItem(name)) : defaultValue - if (isNaN(value)) value = defaultValue - return value - }, - set (value) { - window.localStorage.setItem(name, `${convertValue(value)}`) - } - }) - this[name] = this.options[name] - } - } - /** - * @param {string} name - * @param {any} value - */ - changeOption (name, value) { - this.options[name] = value - this[name] = this.options[name] - // todo migrate to it - window.dispatchEvent(new CustomEvent('option-change', { detail: { name, value } })) - } -} diff --git a/src/optionsStorage.ts b/src/optionsStorage.ts index c6715093..09201f70 100644 --- a/src/optionsStorage.ts +++ b/src/optionsStorage.ts @@ -8,18 +8,30 @@ const mergeAny: (arg1: T, arg2: any) => T = Object.assign const defaultOptions = { renderDistance: 4, + closeConfirmation: true, + autoFullScreen: false, + mouseRawInput: false, + autoExitFullscreen: false, + localUsername: 'wanderer', + mouseSensX: 50, + mouseSensY: 50 as number | true, + // mouseInvertX: false, + chatWidth: 320, + chatHeight: 180, + chatScale: 100, + volume: 50, + // fov: 70, + fov: 75, + guiScale: 3, + + frameLimit: false as number | false, alwaysBackupWorldBeforeLoading: undefined as boolean | undefined | null, alwaysShowMobileControls: false, maxMultiplayerRenderDistance: 6, excludeCommunicationDebugEvents: [], preventDevReloadWhilePlaying: false, - closeConfirmation: true, - autoFullScreen: false, - mouseRawInput: false, - autoExitFullscreen: false, numWorkers: 4, localServerOptions: {}, - localUsername: 'wanderer', preferLoadReadonly: false, disableLoadPrompts: false, guestUsername: 'guest', diff --git a/src/panorama.js b/src/panorama.js index 5bbd1df3..f7754730 100644 --- a/src/panorama.js +++ b/src/panorama.js @@ -5,6 +5,7 @@ import { miscUiState } from './globalState' import { fromTexturePackPath } from './texturePack' import fs from 'fs' import { subscribeKey } from 'valtio/utils' +import { options } from './optionsStorage' let panoramaCubeMap let panoramaUsesResourePack = false @@ -107,7 +108,7 @@ export async function addPanoramaCubeMap () { export function removePanorama () { if (!panoramaCubeMap) return - viewer.camera = new THREE.PerspectiveCamera(document.getElementById('options-screen').fov, window.innerWidth / window.innerHeight, 0.1, 1000) + viewer.camera = new THREE.PerspectiveCamera(options.fov, window.innerWidth / window.innerHeight, 0.1, 1000) viewer.camera.updateProjectionMatrix() viewer.scene.remove(panoramaCubeMap) }