import { html, LitElement } from "lit"; import { customElement, property, query, state } from "lit/decorators.js"; import structureIcon from "../../../../resources/images/CityIconWhite.svg"; import darkModeIcon from "../../../../resources/images/DarkModeIconWhite.svg"; import emojiIcon from "../../../../resources/images/EmojiIconWhite.svg"; import exitIcon from "../../../../resources/images/ExitIconWhite.svg"; import explosionIcon from "../../../../resources/images/ExplosionIconWhite.svg"; import mouseIcon from "../../../../resources/images/MouseIconWhite.svg"; import ninjaIcon from "../../../../resources/images/NinjaIconWhite.svg"; import settingsIcon from "../../../../resources/images/SettingIconWhite.svg"; import treeIcon from "../../../../resources/images/TreeIconWhite.svg"; import musicIcon from "../../../../resources/images/music.svg"; import { EventBus } from "../../../core/EventBus"; import { UserSettings } from "../../../core/game/UserSettings"; import { AlternateViewEvent, RefreshGraphicsEvent } from "../../InputHandler"; import { PauseGameEvent } from "../../Transport"; import { translateText } from "../../Utils"; import SoundManager from "../../sound/SoundManager"; import { Layer } from "./Layer"; export class ShowSettingsModalEvent { constructor( public readonly isVisible: boolean = true, public readonly shouldPause: boolean = false, public readonly isPaused: boolean = false, ) {} } @customElement("settings-modal") export class SettingsModal extends LitElement implements Layer { public eventBus: EventBus; public userSettings: UserSettings; @state() private isVisible: boolean = false; @state() private alternateView: boolean = false; @query(".modal-overlay") private modalOverlay!: HTMLElement; @property({ type: Boolean }) shouldPause = false; @property({ type: Boolean }) wasPausedWhenOpened = false; init() { SoundManager.setBackgroundMusicVolume( this.userSettings.backgroundMusicVolume(), ); SoundManager.setSoundEffectsVolume(this.userSettings.soundEffectsVolume()); this.eventBus.on(ShowSettingsModalEvent, (event) => { this.isVisible = event.isVisible; this.shouldPause = event.shouldPause; this.wasPausedWhenOpened = event.isPaused; this.pauseGame(true); }); } createRenderRoot() { return this; } connectedCallback() { super.connectedCallback(); window.addEventListener("click", this.handleOutsideClick, true); window.addEventListener("keydown", this.handleKeyDown); } disconnectedCallback() { window.removeEventListener("click", this.handleOutsideClick, true); window.removeEventListener("keydown", this.handleKeyDown); super.disconnectedCallback(); } private handleOutsideClick = (event: MouseEvent) => { if ( this.isVisible && this.modalOverlay && event.target === this.modalOverlay ) { this.closeModal(); } }; private handleKeyDown = (event: KeyboardEvent) => { if (this.isVisible && event.key === "Escape") { this.closeModal(); } }; public openModal() { this.isVisible = true; document.body.style.overflow = "hidden"; this.requestUpdate(); } public closeModal() { this.isVisible = false; document.body.style.overflow = ""; this.requestUpdate(); this.pauseGame(false); } private pauseGame(pause: boolean) { if (this.shouldPause && !this.wasPausedWhenOpened) this.eventBus.emit(new PauseGameEvent(pause)); } private onTerrainButtonClick() { this.alternateView = !this.alternateView; this.eventBus.emit(new AlternateViewEvent(this.alternateView)); this.requestUpdate(); } private onToggleEmojisButtonClick() { this.userSettings.toggleEmojis(); this.requestUpdate(); } private onToggleStructureSpritesButtonClick() { this.userSettings.toggleStructureSprites(); this.requestUpdate(); } private onToggleSpecialEffectsButtonClick() { this.userSettings.toggleFxLayer(); this.requestUpdate(); } private onToggleDarkModeButtonClick() { this.userSettings.toggleDarkMode(); this.eventBus.emit(new RefreshGraphicsEvent()); this.requestUpdate(); } private onToggleRandomNameModeButtonClick() { this.userSettings.toggleRandomName(); this.requestUpdate(); } private onToggleLeftClickOpensMenu() { this.userSettings.toggleLeftClickOpenMenu(); this.requestUpdate(); } private onTogglePerformanceOverlayButtonClick() { this.userSettings.togglePerformanceOverlay(); this.requestUpdate(); } private onExitButtonClick() { // redirect to the home page window.location.href = "/"; } private onVolumeChange(event: Event) { const volume = parseFloat((event.target as HTMLInputElement).value) / 100; this.userSettings.setBackgroundMusicVolume(volume); SoundManager.setBackgroundMusicVolume(volume); this.requestUpdate(); } private onSoundEffectsVolumeChange(event: Event) { const volume = parseFloat((event.target as HTMLInputElement).value) / 100; this.userSettings.setSoundEffectsVolume(volume); SoundManager.setSoundEffectsVolume(volume); this.requestUpdate(); } render() { if (!this.isVisible) { return null; } return html` `; } }