import { html } from "lit"; import { customElement, query, state } from "lit/decorators.js"; import { translateText, TUTORIAL_VIDEO_URL } from "../client/Utils"; import { assetUrl } from "../core/AssetUrls"; import { UserSettings } from "../core/game/UserSettings"; import { BaseModal } from "./components/BaseModal"; import "./components/Difficulties"; import { modalHeader } from "./components/ui/ModalHeader"; import { Platform } from "./Platform"; import { TroubleshootingModal } from "./TroubleshootingModal"; @customElement("help-modal") export class HelpModal extends BaseModal { protected routerName = "help"; @state() private keybinds: Record = this.getKeybinds(); @query("#tutorial-video-iframe") private videoIframe?: HTMLIFrameElement; private getKeybinds(): Record { return new UserSettings().keybinds(Platform.isMac); } private getKeyLabel(code: string): string { if (!code) return ""; const specialLabels: Record = { ShiftLeft: "⇧ Shift", ShiftRight: "⇧ Shift", ControlLeft: "Ctrl", ControlRight: "Ctrl", AltLeft: "Alt", AltRight: "Alt", MetaLeft: "⌘", MetaRight: "⌘", Space: "Space", Escape: "Esc", Enter: "↵ Return", ArrowUp: "↑", ArrowDown: "↓", ArrowLeft: "←", ArrowRight: "→", Period: ">", Comma: "<", }; if (specialLabels[code]) return specialLabels[code]; if (code.startsWith("Key") && code.length === 4) return code.slice(3); if (code.startsWith("Digit")) return code.slice(5); if (code.startsWith("Numpad")) return `Num ${code.slice(6)}`; return code; } private renderKey(code: string) { const label = this.getKeyLabel(code); return html`${label}`; } protected renderHeaderSlot() { return modalHeader({ title: translateText("main.help"), onBack: () => this.close(), ariaLabel: translateText("common.back"), }); } protected renderBody() { const keybinds = this.keybinds; return html`

${translateText("help_modal.video_tutorial")}

${translateText("main.troubleshooting")}

${translateText("help_modal.troubleshooting_desc")}

${translateText("help_modal.hotkeys")}

${translateText("help_modal.table_key")} ${translateText("help_modal.table_action")}
${this.renderKey("Escape")} ${translateText("help_modal.action_esc")}
${this.renderKey("Enter")} ${translateText("help_modal.action_enter")}
${this.renderKey(keybinds.toggleView)} ${translateText("help_modal.action_alt_view")}
${this.renderKey(keybinds.coordinateGrid)} ${translateText("help_modal.action_coordinate_grid")}
${this.renderKey(keybinds.swapDirection)} ${translateText("help_modal.bomb_direction")}
${this.renderKey(keybinds.shiftKey)} +
${translateText("help_modal.action_attack_altclick")}
${this.renderKey(keybinds.modifierKey)} +
${translateText("help_modal.action_build")}
${this.renderKey(keybinds.altKey)} +
${translateText("help_modal.action_emote")}
${this.renderKey(keybinds.centerCamera)} ${translateText("help_modal.action_center")}
${this.renderKey(keybinds.pauseGame)} ${translateText("help_modal.action_pause_game")}
${this.renderKey(keybinds.gameSpeedDown)} ${this.renderKey(keybinds.gameSpeedUp)}
${translateText("help_modal.action_game_speed")}
${this.renderKey(keybinds.zoomOut)} ${this.renderKey(keybinds.zoomIn)}
${translateText("help_modal.action_zoom")}
${this.renderKey(keybinds.moveUp)} ${this.renderKey(keybinds.moveLeft)} ${this.renderKey(keybinds.moveDown)} ${this.renderKey(keybinds.moveRight)}
${translateText("help_modal.action_move_camera")}
${this.renderKey(keybinds.attackRatioDown)} ${this.renderKey(keybinds.attackRatioUp)}
${translateText("help_modal.action_ratio_change")}
${this.renderKey(keybinds.shiftKey)} +
${translateText("help_modal.action_ratio_change")}
${this.renderKey(keybinds.altKey)} + ${this.renderKey(keybinds.resetGfx)}
${translateText("help_modal.action_reset_gfx")}
${translateText("help_modal.action_auto_upgrade")}
${this.renderKey(keybinds.shiftKey)} + ${translateText("help_modal.drag")}
${translateText("help_modal.action_warship_multiselect")}
${this.renderKey(keybinds.selectAllWarships)} ${translateText("help_modal.action_warship_selectall")}

${translateText("help_modal.ui_section")}

${translateText("help_modal.ui_leaderboard")} Leaderboard

${translateText("help_modal.ui_leaderboard_desc")}

${translateText("help_modal.ui_control")} Control Panel

${translateText("help_modal.ui_control_desc")}

  • ${translateText("help_modal.ui_gold")}
  • ${translateText("help_modal.ui_attack_ratio")}
${translateText("help_modal.ui_events")}
Events Events Attack

${translateText("help_modal.ui_events_desc")}

  • ${translateText("help_modal.ui_events_alliance")}
  • ${translateText("help_modal.ui_events_attack")}
  • ${translateText("help_modal.ui_events_quickchat")}
${translateText("help_modal.ui_options")} Options

${translateText("help_modal.ui_options_desc")}

  • ${translateText("help_modal.option_timer")}
  • ${translateText("help_modal.option_speed")}
  • ${translateText("help_modal.option_pause")}
  • ${translateText("help_modal.option_settings")}
  • ${translateText("help_modal.option_exit")}
${translateText("help_modal.ui_playeroverlay")} Player Info

${translateText("help_modal.ui_playeroverlay_desc")}

${translateText("help_modal.radial_title")}

Radial Menu Radial Menu Ally

${translateText("help_modal.radial_desc")}

  • ${translateText("help_modal.radial_build")}
  • ${translateText("help_modal.radial_info")}
  • ${translateText("help_modal.radial_boat")}
  • ${translateText("help_modal.info_alliance")}
  • ${translateText("help_modal.ally_betray")}
  • ${translateText("help_modal.radial_donate_troops")}
  • ${translateText("help_modal.radial_donate_gold")}

${translateText("help_modal.info_title")}

${translateText("help_modal.info_enemy_panel")} Enemy Info

${translateText("help_modal.info_enemy_desc")}

  • ${translateText("help_modal.info_chat")}
  • ${translateText("help_modal.info_target")}
  • ${translateText("help_modal.info_alliance")}
  • ${translateText("help_modal.info_emoji")}
  • ${translateText("help_modal.info_trade")}
${translateText("help_modal.info_ally_panel")} Ally Info

${translateText("help_modal.info_ally_desc")}

  • ${translateText("help_modal.ally_betray")}
  • ${translateText("help_modal.ally_donate")}
  • ${translateText("help_modal.ally_donate_gold")}

${translateText("help_modal.build_menu_title")}

${translateText("help_modal.build_menu_desc")}

${translateText("help_modal.build_name")} ${translateText("help_modal.build_icon")} ${translateText("help_modal.build_desc")}
${translateText("help_modal.build_city")} ${translateText("help_modal.build_city_desc")}
${translateText("help_modal.build_defense")} ${translateText("help_modal.build_defense_desc")}
${translateText("help_modal.build_port")} ${translateText("help_modal.build_port_desc")}
${translateText("help_modal.build_factory")} ${translateText("help_modal.build_factory_desc")}
${translateText("help_modal.build_warship")} ${translateText("help_modal.build_warship_desc")}
${translateText("help_modal.build_silo")} ${translateText("help_modal.build_silo_desc")}
${translateText("help_modal.build_sam")} ${translateText("help_modal.build_sam_desc")}
${translateText("help_modal.build_atom")} ${translateText("help_modal.build_atom_desc")}
${translateText("help_modal.build_hydrogen")} ${translateText("help_modal.build_hydrogen_desc")}
${translateText("help_modal.build_mirv")} ${translateText("help_modal.build_mirv_desc")}

${translateText("help_modal.player_icons")}

${translateText("help_modal.icon_desc")}

Rank 1 ${translateText("help_modal.icon_crown")}
Traitor ${translateText("help_modal.icon_traitor")}
Ally ${translateText("help_modal.icon_ally")}
Embargo ${translateText("help_modal.icon_embargo")}
Request ${translateText("help_modal.icon_request")}
`; } openTroubleshooting() { const troubleshootingModal = document.querySelector( "troubleshooting-modal", ) as TroubleshootingModal; if ( !troubleshootingModal || !(troubleshootingModal instanceof TroubleshootingModal) ) { console.warn("Troubleshooting modal element not found"); return; } troubleshootingModal.open(); } protected onOpen(): void { this.keybinds = this.getKeybinds(); // Restore the video src when modal opens if (this.videoIframe) { this.videoIframe.src = TUTORIAL_VIDEO_URL; } } protected onClose(): void { // Clear the iframe src to stop video playback if (this.videoIframe) { this.videoIframe.src = ""; } } }