From d3472196617cc5ae880babff60bb034695adba4a Mon Sep 17 00:00:00 2001 From: Moka Date: Thu, 14 Nov 2024 23:38:26 +0100 Subject: [PATCH] [UI] Ask Confirmation before disabling touch controls --- src/system/game-data.ts | 5 +- src/system/settings/settings.ts | 93 +++++++++++++------ .../settings/abstract-settings-ui-handler.ts | 14 ++- 3 files changed, 74 insertions(+), 38 deletions(-) diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 3e3a6ce8f8b..4cd7e796398 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -730,15 +730,16 @@ export class GameData { * Saves a setting to localStorage * @param setting string ideally of SettingKeys * @param valueIndex index of the setting's option + * @param fromSettings whether the function was called from the settings menu * @returns true */ - public saveSetting(setting: string, valueIndex: integer): boolean { + public saveSetting(setting: string, valueIndex: integer, fromSettings?: boolean): boolean { let settings: object = {}; if (localStorage.hasOwnProperty("settings")) { settings = JSON.parse(localStorage.getItem("settings")!); // TODO: is this bang correct? } - setSetting(this.scene, setting, valueIndex); + setSetting(this.scene, setting, valueIndex, fromSettings); settings[setting] = valueIndex; settings["gameVersion"] = this.scene.game.config.gameVersion; diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index d71edf603dd..018901ba33d 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -10,6 +10,7 @@ import { MoneyFormat } from "#enums/money-format"; import { PlayerGender } from "#enums/player-gender"; import { getIsInitialized, initI18n } from "#app/plugins/i18n"; import { ShopCursorTarget } from "#app/enums/shop-cursor-target"; +import { OptionSelectConfig } from "#app/ui/abstact-option-select-ui-handler"; function getTranslation(key: string): string { if (!getIsInitialized()) { @@ -344,13 +345,6 @@ export const Setting: Array = [ default: 1, type: SettingType.GENERAL }, - { - key: SettingKeys.Touch_Controls, - label: i18next.t("settings:touchControls"), - options: AUTO_DISABLED, - default: 0, - type: SettingType.GENERAL - }, { key: SettingKeys.Vibration, label: i18next.t("settings:vibrations"), @@ -358,6 +352,28 @@ export const Setting: Array = [ default: 0, type: SettingType.GENERAL }, + { + key: SettingKeys.Touch_Controls, + label: i18next.t("settings:touchControls"), + options: AUTO_DISABLED, + default: 0, + type: SettingType.GENERAL, + isHidden: () => !hasTouchscreen() + }, + { + key: SettingKeys.Move_Touch_Controls, + label: i18next.t("settings:moveTouchControls"), + options: [ + { + value: "Configure", + label: i18next.t("settings:change") + } + ], + default: 0, + type: SettingType.GENERAL, + activatable: true, + isHidden: () => !hasTouchscreen() + }, { key: SettingKeys.Language, label: i18next.t("settings:language"), @@ -643,20 +659,6 @@ export const Setting: Array = [ type: SettingType.AUDIO, requireReload: true }, - { - key: SettingKeys.Move_Touch_Controls, - label: i18next.t("settings:moveTouchControls"), - options: [ - { - value: "Configure", - label: i18next.t("settings:change") - } - ], - default: 0, - type: SettingType.GENERAL, - activatable: true, - isHidden: () => !hasTouchscreen() - }, { key: SettingKeys.Shop_Cursor_Target, label: i18next.t("settings:shopCursorTarget"), @@ -696,9 +698,11 @@ export function resetSettings(scene: BattleScene) { * @param scene current BattleScene * @param setting string ideally from SettingKeys * @param value value to update setting with + * @param fromSettings whether the function was called from the settings menu, meaning it is possible + * to access the handler and add extra interactions for the player * @returns true if successful, false if not */ -export function setSetting(scene: BattleScene, setting: string, value: integer): boolean { +export function setSetting(scene: BattleScene, setting: string, value: integer, fromSettings?: boolean): boolean { const index: number = settingIndex(setting); if (index === -1) { return false; @@ -832,10 +836,43 @@ export function setSetting(scene: BattleScene, setting: string, value: integer): } break; case SettingKeys.Touch_Controls: - scene.enableTouchControls = Setting[index].options[value].value !== "Disabled" && hasTouchscreen(); - const touchControls = document.getElementById("touchControls"); - if (touchControls) { - touchControls.classList.toggle("visible", scene.enableTouchControls); + const setTouchControlsVisibility = (scene: BattleScene) => { + const touchControls = document.getElementById("touchControls"); + if (touchControls) { + touchControls.classList.toggle("visible", scene.enableTouchControls); + } + }; + + if (fromSettings && Setting[index].options[value].value === "Disabled") { + const optionsConfig: OptionSelectConfig = { + yOffset: 24, + delay: 1000, + options: [ + { + label: i18next.t("settings:disableTouchControls"), + handler: () => { + scene.ui.revertMode(); + scene.enableTouchControls = false; + setTouchControlsVisibility(scene); + return true; + } + }, + { + label: i18next.t("settings:cancel"), + handler: () => { + scene.ui.revertMode(); + // Put the option cursor back to "Auto" and save that + (scene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true); + return true; + } + } + ] + }; + // Player moved to the "Disabled" option, show a confirmation window, with a 1s delay before being able to confirm + scene.ui.setOverlayMode(Mode.OPTION_SELECT, optionsConfig); + } else { + scene.enableTouchControls = Setting[index].options[value].value !== "Disabled" && hasTouchscreen(); + setTouchControlsVisibility(scene); } break; case SettingKeys.Vibration: @@ -846,10 +883,10 @@ export function setSetting(scene: BattleScene, setting: string, value: integer): break; case SettingKeys.Language: if (value) { - if (scene.ui) { + if (fromSettings) { const cancelHandler = () => { scene.ui.revertMode(); - (scene.ui.getHandler() as SettingsUiHandler).setOptionCursor(0, 0, true); + (scene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true); }; const changeLocaleHandler = (locale: string): boolean => { try { diff --git a/src/ui/settings/abstract-settings-ui-handler.ts b/src/ui/settings/abstract-settings-ui-handler.ts index 83219e1ef5a..e731a63862d 100644 --- a/src/ui/settings/abstract-settings-ui-handler.ts +++ b/src/ui/settings/abstract-settings-ui-handler.ts @@ -1,5 +1,4 @@ import BattleScene from "#app/battle-scene"; -import { hasTouchscreen, isMobile } from "#app/touch-controls"; import { TextStyle, addTextObject } from "#app/ui/text"; import { Mode } from "#app/ui/ui"; import UiHandler from "#app/ui/ui-handler"; @@ -326,19 +325,18 @@ export default class AbstractSettingsUiHandler extends UiHandler { /** * Set the option cursor to the specified position. * - * @param settingIndex - The index of the setting. + * @param settingIndex - The index of the setting or -1 to change the current setting * @param cursor - The cursor position to set. * @param save - Whether to save the setting to local storage. * @returns `true` if the option cursor was set successfully. */ setOptionCursor(settingIndex: number, cursor: number, save?: boolean): boolean { - const setting = this.settings[settingIndex]; - - if (setting.key === SettingKeys.Touch_Controls && cursor && hasTouchscreen() && isMobile()) { - this.getUi().playError(); - return false; + if (settingIndex === -1) { + settingIndex = this.cursor + this.scrollCursor; } + const setting = this.settings[settingIndex]; + const lastCursor = this.optionCursors[settingIndex]; const lastValueLabel = this.optionValueLabels[settingIndex][lastCursor]; @@ -352,7 +350,7 @@ export default class AbstractSettingsUiHandler extends UiHandler { newValueLabel.setShadowColor(this.getTextColor(TextStyle.SETTINGS_SELECTED, true)); if (save) { - this.scene.gameData.saveSetting(setting.key, cursor); + this.scene.gameData.saveSetting(setting.key, cursor, true); if (this.reloadSettings.includes(setting)) { this.reloadRequired = true; }