From a5cdd23c00d502db63707937afd3d01adcaf8fe3 Mon Sep 17 00:00:00 2001
From: Rj Manhas <117674421+RjManhas@users.noreply.github.com>
Date: Mon, 24 Nov 2025 10:34:04 -0700
Subject: [PATCH] feat: added retaliate button (#2426)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #495
## Description:
Adds a button to quickly retaliate against a incoming attack
## Please complete the following:
- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
## Please put your Discord username so you can be contacted if a bug or
regression is found:
notifxy (1379678982676676639)
---
resources/lang/en.json | 1 +
src/client/graphics/layers/EventsDisplay.ts | 61 +++++++++++++++------
2 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/resources/lang/en.json b/resources/lang/en.json
index 5f6dac416..6f941c61c 100644
--- a/resources/lang/en.json
+++ b/resources/lang/en.json
@@ -575,6 +575,7 @@
},
"events_display": {
"retreating": "retreating",
+ "retaliate": "Retaliate",
"boat": "Boat",
"alliance_request_status": "{name} {status} your alliance request",
"alliance_accepted": "accepted",
diff --git a/src/client/graphics/layers/EventsDisplay.ts b/src/client/graphics/layers/EventsDisplay.ts
index 803f81e3f..c8276491e 100644
--- a/src/client/graphics/layers/EventsDisplay.ts
+++ b/src/client/graphics/layers/EventsDisplay.ts
@@ -35,6 +35,7 @@ import {
CancelBoatIntentEvent,
SendAllianceExtensionIntentEvent,
SendAllianceReplyIntentEvent,
+ SendAttackIntentEvent,
} from "../../Transport";
import { Layer } from "./Layer";
@@ -736,28 +737,54 @@ export class EventsDisplay extends LitElement implements Layer {
}
}
+ private handleRetaliate(attack: AttackUpdate) {
+ const attacker = this.game.playerBySmallID(attack.attackerID) as PlayerView;
+ if (!attacker) return;
+
+ const myPlayer = this.game.myPlayer();
+ if (!myPlayer) return;
+
+ // Launch counterattack with the same number of troops as the incoming attack
+ this.eventBus.emit(new SendAttackIntentEvent(attacker.id(), attack.troops));
+ }
+
private renderIncomingAttacks() {
return html`
${this.incomingAttacks.length > 0
? html`
- ${this.incomingAttacks.map(
- (attack) => html`
- ${this.renderButton({
- content: html`
- ${renderTroops(attack.troops)}
- ${(
- this.game.playerBySmallID(attack.attackerID) as PlayerView
- )?.name()}
- ${attack.retreating
- ? `(${translateText("events_display.retreating")}...)`
+