import { html } from "lit"; import { customElement, state } from "lit/decorators.js"; import { translateText } from "../client/Utils"; import { BaseModal } from "./components/BaseModal"; import "./components/Difficulties"; import "./components/Maps"; @customElement("help-modal") export class HelpModal extends BaseModal { @state() private keybinds: Record = this.getKeybinds(); private isKeybindObject(v: unknown): v is { value: string } { return ( typeof v === "object" && v !== null && "value" in v && typeof (v as any).value === "string" ); } private getKeybinds(): Record { let saved: Record = {}; try { const parsed = JSON.parse( localStorage.getItem("settings.keybinds") ?? "{}", ); saved = Object.fromEntries( Object.entries(parsed) .map(([k, v]) => { if (this.isKeybindObject(v)) return [k, v.value]; if (typeof v === "string") return [k, v]; return [k, undefined]; }) .filter(([, v]) => typeof v === "string" && v !== "Null"), ) as Record; } catch (e) { console.warn("Invalid keybinds JSON:", e); } const isMac = /Mac/.test(navigator.userAgent); return { toggleView: "Space", centerCamera: "KeyC", moveUp: "KeyW", moveDown: "KeyS", moveLeft: "KeyA", moveRight: "KeyD", zoomOut: "KeyQ", zoomIn: "KeyE", attackRatioDown: "KeyT", attackRatioUp: "KeyY", shiftKey: "ShiftLeft", modifierKey: isMac ? "MetaLeft" : "ControlLeft", altKey: "AltLeft", resetGfx: "KeyR", ...saved, }; } 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", ArrowUp: "↑", ArrowDown: "↓", ArrowLeft: "←", ArrowRight: "→", }; 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}`; } render() { const keybinds = this.keybinds; const content = html`
${translateText("main.instructions")}

${translateText("help_modal.hotkeys")}

${translateText("help_modal.table_key")} ${translateText("help_modal.table_action")}
${this.renderKey(keybinds.toggleView)} ${translateText("help_modal.action_alt_view")}
${this.renderKey("KeyU")} ${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.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")}

${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_pause")}
  • ${translateText("help_modal.option_timer")}
  • ${translateText("help_modal.option_exit")}
  • ${translateText("help_modal.option_settings")}
${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")}
`; if (this.inline) { return content; } return html` ${content} `; } protected onOpen(): void { this.keybinds = this.getKeybinds(); } }