import { html, LitElement } from "lit"; import { customElement, property, query, state } from "lit/decorators.js"; import { crazyGamesSDK } from "src/client/CrazyGamesSDK"; import { PauseGameIntentEvent } from "src/client/Transport"; import { assetUrl } from "../../../core/AssetUrls"; import { EventBus } from "../../../core/EventBus"; import { UserSettings } from "../../../core/game/UserSettings"; import { Controller } from "../../Controller"; import { AlternateViewEvent, RefreshGraphicsEvent, ToggleRenderDebugGuiEvent, } from "../../InputHandler"; import { translateText } from "../../Utils"; import { SetBackgroundMusicVolumeEvent, SetSoundEffectsVolumeEvent, } from "../../sound/Sounds"; import { ShowGraphicsSettingsModalEvent } from "./GraphicsSettingsModal"; const structureIcon = assetUrl("images/CityIconWhite.svg"); const cursorPriceIcon = assetUrl("images/CursorPriceIconWhite.svg"); const darkModeIcon = assetUrl("images/DarkModeIconWhite.svg"); const emojiIcon = assetUrl("images/EmojiIconWhite.svg"); const exitIcon = assetUrl("images/ExitIconWhite.svg"); const explosionIcon = assetUrl("images/ExplosionIconWhite.svg"); const mouseIcon = assetUrl("images/MouseIconWhite.svg"); const ninjaIcon = assetUrl("images/NinjaIconWhite.svg"); const settingsIcon = assetUrl("images/SettingIconWhite.svg"); const sirenIcon = assetUrl("images/SirenIconWhite.svg"); const swordIcon = assetUrl("images/SwordIconWhite.svg"); const treeIcon = assetUrl("images/TreeIconWhite.svg"); const musicIcon = assetUrl("images/music.svg"); 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 Controller { 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() { 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; this.requestUpdate(); } public closeModal({ keepPause = false }: { keepPause?: boolean } = {}) { this.isVisible = false; this.requestUpdate(); if (!keepPause) this.pauseGame(false); } private pauseGame(pause: boolean) { if (this.shouldPause && !this.wasPausedWhenOpened) { if (pause) { crazyGamesSDK.gameplayStop(); } else { crazyGamesSDK.gameplayStart(); } this.eventBus.emit(new PauseGameIntentEvent(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 onToggleAlertFrameButtonClick() { this.userSettings.toggleAlertFrame(); 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 onToggleCursorCostLabelButtonClick() { this.userSettings.toggleCursorCostLabel(); this.requestUpdate(); } private onToggleAttackingTroopsOverlayButtonClick() { this.userSettings.toggleAttackingTroopsOverlay(); this.requestUpdate(); } private onTogglePerformanceOverlayButtonClick() { this.userSettings.togglePerformanceOverlay(); this.requestUpdate(); } private onRenderDebugGuiButtonClick() { this.eventBus.emit(new ToggleRenderDebugGuiEvent()); this.closeModal(); } private onGraphicsSettingsButtonClick() { this.eventBus.emit( new ShowGraphicsSettingsModalEvent( true, this.shouldPause, this.wasPausedWhenOpened, ), ); this.closeModal({ keepPause: true }); } 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); this.eventBus.emit(new SetBackgroundMusicVolumeEvent(volume)); this.requestUpdate(); } private onSoundEffectsVolumeChange(event: Event) { const volume = parseFloat((event.target as HTMLInputElement).value) / 100; this.userSettings.setSoundEffectsVolume(volume); this.eventBus.emit(new SetSoundEffectsVolumeEvent(volume)); this.requestUpdate(); } render() { if (!this.isVisible) { return null; } return html`
`; } }