feat: add duel countdown overlay (3-2-1-Fight!)

Parse SMSG_DUEL_COUNTDOWN to get the countdown duration, track the
start time, and render a large centered countdown overlay. Numbers
display in pulsing gold; transitions to pulsing red 'Fight!' for the
last 0.5 seconds. Countdown clears on SMSG_DUEL_COMPLETE.
This commit is contained in:
Kelsi 2026-03-12 05:06:14 -07:00
parent 29a989e1f4
commit c35bf8d953
4 changed files with 63 additions and 2 deletions

View file

@ -482,6 +482,7 @@ void GameScreen::render(game::GameHandler& gameHandler) {
renderBossFrames(gameHandler);
renderGroupInvitePopup(gameHandler);
renderDuelRequestPopup(gameHandler);
renderDuelCountdown(gameHandler);
renderLootRollPopup(gameHandler);
renderTradeRequestPopup(gameHandler);
renderTradeWindow(gameHandler);
@ -7488,6 +7489,47 @@ void GameScreen::renderDuelRequestPopup(game::GameHandler& gameHandler) {
ImGui::End();
}
void GameScreen::renderDuelCountdown(game::GameHandler& gameHandler) {
float remaining = gameHandler.getDuelCountdownRemaining();
if (remaining <= 0.0f) return;
ImVec2 displaySize = ImGui::GetIO().DisplaySize;
float screenW = displaySize.x > 0.0f ? displaySize.x : 1280.0f;
float screenH = displaySize.y > 0.0f ? displaySize.y : 720.0f;
auto* dl = ImGui::GetForegroundDrawList();
ImFont* font = ImGui::GetFont();
float fontSize = ImGui::GetFontSize();
// Show integer countdown or "Fight!" when under 0.5s
char buf[32];
if (remaining > 0.5f) {
snprintf(buf, sizeof(buf), "%d", static_cast<int>(std::ceil(remaining)));
} else {
snprintf(buf, sizeof(buf), "Fight!");
}
// Large font by scaling — use 4x font size for dramatic effect
float scale = 4.0f;
float scaledSize = fontSize * scale;
ImVec2 textSz = font->CalcTextSizeA(scaledSize, FLT_MAX, 0.0f, buf);
float tx = (screenW - textSz.x) * 0.5f;
float ty = screenH * 0.35f - textSz.y * 0.5f;
// Pulsing alpha: fades in and out per second
float pulse = 0.75f + 0.25f * std::sin(static_cast<float>(ImGui::GetTime()) * 6.28f);
uint8_t alpha = static_cast<uint8_t>(255 * pulse);
// Color: golden countdown, red "Fight!"
ImU32 color = (remaining > 0.5f)
? IM_COL32(255, 200, 50, alpha)
: IM_COL32(255, 60, 60, alpha);
// Drop shadow
dl->AddText(font, scaledSize, ImVec2(tx + 2.0f, ty + 2.0f), IM_COL32(0, 0, 0, alpha / 2), buf);
dl->AddText(font, scaledSize, ImVec2(tx, ty), color, buf);
}
void GameScreen::renderItemTextWindow(game::GameHandler& gameHandler) {
if (!gameHandler.isItemTextOpen()) return;