Fix alliance renewal prompt incorrectly dismissed for both players (#3297)

## Description:

NOTE: Applies to current main / beta version. Needs to be included in
v30.

When a player clicked "Renew Alliance", the `AllianceExtensionUpdate`
broadcast caused both players' renewal prompts to be removed, even the
one who hadn't yet acted. This happened because
`onAllianceExtensionEvent` called `removeAllianceRenewalEvents`
unconditionally on every client.

This PR fixes the behavior by calling `removeAllianceRenewalEvents` only
for the player that executed the action.

## 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:

deshack_82603
This commit is contained in:
Mattia Migliorini
2026-02-26 04:12:58 +01:00
committed by GitHub
parent bd3db55a22
commit 7b785ea79a
2 changed files with 70 additions and 0 deletions
@@ -626,6 +626,8 @@ export class EventsDisplay extends LitElement implements Layer {
}
private onAllianceExtensionEvent(update: AllianceExtensionUpdate) {
const myPlayer = this.game.myPlayer();
if (!myPlayer || myPlayer.smallID() !== update.playerID) return;
this.removeAllianceRenewalEvents(update.allianceID);
this.requestUpdate();
}
@@ -1,3 +1,5 @@
import { GameUpdateType } from "../../../../src/core/game/GameUpdates";
vi.mock("lit", () => ({
html: () => {},
LitElement: class {},
@@ -102,6 +104,72 @@ describe("EventsDisplay - alliance renewal cleanup (allianceID based)", () => {
expect(remaining[0].allianceID).toBe(allianceCD);
});
test("onAllianceExtensionEvent removes renewal when playerID matches myPlayer", () => {
const display = new EventsDisplay();
const allianceID = 42;
const mySmallID = 7;
(display as any).game = {
myPlayer: () => ({ smallID: () => mySmallID }),
};
(display as any).requestUpdate = () => {};
(display as any).events = [makeRenewal(allianceID, mySmallID)];
(display as any).onAllianceExtensionEvent({
type: GameUpdateType.AllianceExtension,
playerID: mySmallID,
allianceID,
});
const remaining = (display as any).events;
expect(remaining.some((e: any) => e.allianceID === allianceID)).toBe(false);
});
test("onAllianceExtensionEvent keeps renewal when playerID does not match myPlayer", () => {
const display = new EventsDisplay();
const allianceID = 42;
const mySmallID = 7;
const otherSmallID = 9;
(display as any).game = {
myPlayer: () => ({ smallID: () => mySmallID }),
};
(display as any).requestUpdate = () => {};
(display as any).events = [makeRenewal(allianceID, mySmallID)];
(display as any).onAllianceExtensionEvent({
type: "AllianceExtension",
playerID: otherSmallID,
allianceID,
});
const remaining = (display as any).events;
expect(remaining.some((e: any) => e.allianceID === allianceID)).toBe(true);
});
test("onAllianceExtensionEvent keeps renewal when myPlayer is null", () => {
const display = new EventsDisplay();
const allianceID = 42;
(display as any).game = {
myPlayer: () => null,
};
(display as any).requestUpdate = () => {};
(display as any).events = [makeRenewal(allianceID, 1)];
(display as any).onAllianceExtensionEvent({
type: "AllianceExtension",
playerID: 1,
allianceID,
});
const remaining = (display as any).events;
expect(remaining.some((e: any) => e.allianceID === allianceID)).toBe(true);
});
test("does not affect non-RENEW_ALLIANCE events", () => {
const display = new EventsDisplay();