From a97a608dce441e7472b06cf22c38448bc135fd24 Mon Sep 17 00:00:00 2001 From: kanekane0448 Date: Fri, 4 Apr 2025 19:15:59 +0200 Subject: [PATCH] Add Alt + Click hotkey for sending emotes (#408) ## Description: Allows the player to Alt + Click to send emotes to other players or themself in order to ease communication. Of course, the hotkey can be something different. Alt + Click is just a suggestion. ![image](https://github.com/user-attachments/assets/9762c4f0-f62d-4c39-ba35-468ac3f5ddaa) ## Please complete the following: - [ x ] I have added screenshots for all UI updates - [ x ] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [ x ] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors ## Please put your Discord username so you can be contacted if a bug or regression is found: kanekane0448 PS: The new emoji table looks really good! --------- Co-authored-by: kanekane0448 --- resources/lang/en.json | 1 + src/client/HelpModal.ts | 4 +++ src/client/InputHandler.ts | 10 ++++++ src/client/Main.ts | 2 +- src/client/graphics/GameRenderer.ts | 7 ++++- src/client/graphics/layers/EmojiTable.ts | 40 ++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 2 deletions(-) diff --git a/resources/lang/en.json b/resources/lang/en.json index cedf01779..024878fad 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -22,6 +22,7 @@ "action_alt_view": "Alternate view (terrain/countries)", "action_attack_altclick": "Attack (when left click is set to open menu)", "action_build": "Open build menu", + "action_emote": "Open emote menu", "action_center": "Center camera on player", "action_zoom": "Zoom out/in", "action_move_camera": "Move camera", diff --git a/src/client/HelpModal.ts b/src/client/HelpModal.ts index bbf842eb9..8de819377 100644 --- a/src/client/HelpModal.ts +++ b/src/client/HelpModal.ts @@ -46,6 +46,10 @@ export class HelpModal extends LitElement { Ctrl + left click ${translateText("help_modal.action_build")} + + Alt + left click + ${translateText("help_modal.action_emote")} + C ${translateText("help_modal.action_center")} diff --git a/src/client/InputHandler.ts b/src/client/InputHandler.ts index 806bc6cf8..ae495e9fe 100644 --- a/src/client/InputHandler.ts +++ b/src/client/InputHandler.ts @@ -69,6 +69,12 @@ export class ShowBuildMenuEvent implements GameEvent { public readonly y: number, ) {} } +export class ShowEmojiMenuEvent implements GameEvent { + constructor( + public readonly x: number, + public readonly y: number, + ) {} +} export class AttackRatioEvent implements GameEvent { constructor(public readonly attackRatio: number) {} @@ -292,6 +298,10 @@ export class InputHandler { this.eventBus.emit(new ShowBuildMenuEvent(event.clientX, event.clientY)); return; } + if (event.altKey) { + this.eventBus.emit(new ShowEmojiMenuEvent(event.clientX, event.clientY)); + return; + } const dist = Math.abs(event.x - this.lastPointerDownX) + diff --git a/src/client/Main.ts b/src/client/Main.ts index 6b4b623c9..e2637e4ae 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -10,7 +10,6 @@ import "./DarkModeButton"; import { DarkModeButton } from "./DarkModeButton"; import "./FlagInput"; import { FlagInput } from "./FlagInput"; -import { GameStartingModal } from "./GameStartingModal"; import "./GoogleAdElement"; import GoogleAdElement from "./GoogleAdElement"; import { HelpModal } from "./HelpModal"; @@ -27,6 +26,7 @@ import { UsernameInput } from "./UsernameInput"; import { generateCryptoRandomUUID } from "./Utils"; import "./components/baseComponents/Button"; import "./components/baseComponents/Modal"; +import { GameStartingModal } from "./gameStartingModal"; import "./styles.css"; export interface JoinLobbyEvent { diff --git a/src/client/graphics/GameRenderer.ts b/src/client/graphics/GameRenderer.ts index 5f76b79e7..9207067b4 100644 --- a/src/client/graphics/GameRenderer.ts +++ b/src/client/graphics/GameRenderer.ts @@ -2,8 +2,8 @@ import { consolex } from "../../core/Consolex"; import { EventBus } from "../../core/EventBus"; import { ClientID } from "../../core/Schemas"; import { GameView } from "../../core/game/GameView"; -import { GameStartingModal } from "../GameStartingModal"; import { RefreshGraphicsEvent as RedrawGraphicsEvent } from "../InputHandler"; +import { GameStartingModal } from "../gameStartingModal"; import { TransformHandler } from "./TransformHandler"; import { UIState } from "./UIState"; import { BuildMenu } from "./layers/BuildMenu"; @@ -47,6 +47,11 @@ export function createRenderer( if (!emojiTable || !(emojiTable instanceof EmojiTable)) { consolex.error("EmojiTable element not found in the DOM"); } + emojiTable.eventBus = eventBus; + emojiTable.transformHandler = transformHandler; + emojiTable.game = game; + emojiTable.initEventBus(); + const buildMenu = document.querySelector("build-menu") as BuildMenu; if (!buildMenu || !(buildMenu instanceof BuildMenu)) { consolex.error("BuildMenu element not found in the DOM"); diff --git a/src/client/graphics/layers/EmojiTable.ts b/src/client/graphics/layers/EmojiTable.ts index 06edeecb0..5db92c866 100644 --- a/src/client/graphics/layers/EmojiTable.ts +++ b/src/client/graphics/layers/EmojiTable.ts @@ -1,5 +1,12 @@ import { LitElement, css, html } from "lit"; import { customElement, state } from "lit/decorators.js"; +import { EventBus } from "../../../core/EventBus"; +import { AllPlayers } from "../../../core/game/Game"; +import { GameView, PlayerView } from "../../../core/game/GameView"; +import { TerraNulliusImpl } from "../../../core/game/TerraNulliusImpl"; +import { ShowEmojiMenuEvent } from "../../InputHandler"; +import { SendEmojiIntentEvent } from "../../Transport"; +import { TransformHandler } from "../TransformHandler"; const emojiTable: string[][] = [ ["😀", "😊", "🥰", "😇", "😎"], @@ -17,6 +24,10 @@ const emojiTable: string[][] = [ @customElement("emoji-table") export class EmojiTable extends LitElement { + public eventBus: EventBus; + public transformHandler: TransformHandler; + public game: GameView; + static styles = css` :host { display: block; @@ -96,6 +107,35 @@ export class EmojiTable extends LitElement { @state() private _hidden = true; + initEventBus() { + this.eventBus.on(ShowEmojiMenuEvent, (e) => { + const cell = this.transformHandler.screenToWorldCoordinates(e.x, e.y); + if (!this.game.isValidCoord(cell.x, cell.y)) { + return; + } + + const tile = this.game.ref(cell.x, cell.y); + if (!this.game.hasOwner(tile)) { + return; + } + + const targetPlayer = this.game.owner(tile); + // maybe redundant due to owner check but better safe than sorry + if (targetPlayer instanceof TerraNulliusImpl) { + return; + } + + this.showTable((emoji) => { + const recipient = + targetPlayer == this.game.myPlayer() + ? AllPlayers + : (targetPlayer as PlayerView); + this.eventBus.emit(new SendEmojiIntentEvent(recipient, emoji)); + this.hideTable(); + }); + }); + } + private onEmojiClicked: (emoji: string) => void = () => {}; render() {