From ca66656b5c33400c610cb7133363473afa83486b Mon Sep 17 00:00:00 2001 From: tnhnblgl <51187395+tnhnblgl@users.noreply.github.com> Date: Tue, 20 May 2025 01:29:40 +0300 Subject: [PATCH] Display alliance timer in player panel (#805) ## Description: Below Traitor: , There will be Alliance Status. And will display timer, after timer ends will show Alliance Expired. Also this Alliance Status will only show if player had alliance. ## 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: dovg --- resources/lang/en.json | 1 + src/client/graphics/layers/PlayerPanel.ts | 44 +++++++++++++++++++++++ src/core/GameRunner.ts | 4 +++ src/core/game/Game.ts | 1 + 4 files changed, 50 insertions(+) diff --git a/resources/lang/en.json b/resources/lang/en.json index b2a282a55..390baf730 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -403,6 +403,7 @@ "gold": "Gold", "troops": "Troops", "traitor": "Traitor", + "alliance_time_remaining": "Time Remaining", "embargo": "Stopped trading with you", "nuke": "Nukes sent by them to you", "start_trade": "Start trading", diff --git a/src/client/graphics/layers/PlayerPanel.ts b/src/client/graphics/layers/PlayerPanel.ts index e7f046e25..c37659e78 100644 --- a/src/client/graphics/layers/PlayerPanel.ts +++ b/src/client/graphics/layers/PlayerPanel.ts @@ -45,6 +45,9 @@ export class PlayerPanel extends LitElement implements Layer { @state() private isVisible: boolean = false; + @state() + private allianceExpiryText: string | null = null; + public show(actions: PlayerActions, tile: TileRef) { this.actions = actions; this.tile = tile; @@ -170,11 +173,38 @@ export class PlayerPanel extends LitElement implements Layer { const myPlayer = this.g.myPlayer(); if (myPlayer !== null && myPlayer.isAlive()) { this.actions = await myPlayer.actions(this.tile); + + if (this.actions?.interaction?.allianceCreatedAtTick !== undefined) { + const createdAt = this.actions.interaction.allianceCreatedAtTick; + const durationTicks = this.g.config().allianceDuration(); + const expiryTick = createdAt + durationTicks; + const remainingTicks = expiryTick - this.g.ticks(); + + if (remainingTicks > 0) { + const remainingSeconds = Math.max( + 0, + Math.floor(remainingTicks / 10), + ); // 10 ticks per second + this.allianceExpiryText = this.formatDuration(remainingSeconds); + } + } else { + this.allianceExpiryText = null; + } this.requestUpdate(); } } } + private formatDuration(totalSeconds: number): string { + if (totalSeconds <= 0) return "0s"; + const minutes = Math.floor(totalSeconds / 60); + const seconds = totalSeconds % 60; + let time = ""; + if (minutes > 0) time += `${minutes}m `; + time += `${seconds}s`; + return time.trim(); + } + getTotalNukesSent(otherId: PlayerID): number { const stats = this.g.player(otherId).stats(); if (!stats) { @@ -309,6 +339,20 @@ export class PlayerPanel extends LitElement implements Layer { + ${this.allianceExpiryText !== null + ? html` +