From e06e0dcb3a1c55bcb5ca8c89e56dcec9805cfe59 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 20 Jan 2024 18:53:14 -0800 Subject: [PATCH] Battle: emerald win HUD polish - Bigger - Aligned to the Tally boxes - Each emerald slides in one-by-one over the duration of the Tally - Flash after the final emerald slides into place --- src/hud/emerald-win.cpp | 85 ++++++++++++++++++++++++++++++++--------- src/k_battle.c | 10 +++-- src/k_battle.h | 2 +- src/k_hud.cpp | 18 ++++++--- src/k_hud.h | 2 +- src/p_saveg.c | 4 +- 6 files changed, 90 insertions(+), 31 deletions(-) diff --git a/src/hud/emerald-win.cpp b/src/hud/emerald-win.cpp index f304b0f4e..df7ee7319 100644 --- a/src/hud/emerald-win.cpp +++ b/src/hud/emerald-win.cpp @@ -1,41 +1,90 @@ +#include + #include "../v_draw.hpp" #include "../doomdef.h" #include "../i_time.h" +#include "../k_battle.h" #include "../k_hud.h" +#include "../m_easing.h" +#include "../m_fixed.h" +#include "../p_tick.h" #include "../screen.h" using srb2::Draw; -void K_drawEmeraldWin(void) +namespace { - constexpr float kScale = 0.25; - constexpr int kH = 72 * kScale; - constexpr int kYPad = 12; - constexpr int kWidth = 34 + 4; - if (I_GetTime() % 3) +fixed_t interval(tic_t t, tic_t s, tic_t d) +{ + return (std::min(std::max(t, s) - s, d) * FRACUNIT) / d; +} + +}; // namespace + +void K_drawEmeraldWin(boolean overlay) +{ + if (leveltime < g_emeraldWin) { return; } - Draw row = Draw(BASEVIDWIDTH / 2, BASEVIDHEIGHT / 2).scale(kScale).flags(V_ADD); + constexpr float kScale = 0.5; + constexpr int kWidth = (69 + 4) * 2 * kScale; + constexpr int kMid = (72 * kScale) / 2; + constexpr int kYOffset = (68 * kScale) - kMid; + + constexpr int kTop = 86; + constexpr int kBot = 129; + + constexpr tic_t kDelay = 24; + constexpr tic_t kSlide = 12; + + constexpr tic_t kFlashStart = (6 * kDelay) + kSlide; + constexpr tic_t kFlash = 10; + + INT32 flags = 0; + + tic_t t = leveltime - g_emeraldWin; + + if (overlay) + { + if (t >= kFlashStart && t - kFlashStart <= kFlash) + { + flags = V_ADD | (Easing_InOutSine(interval(t, kFlashStart, kFlash), 0, 9) << V_ALPHASHIFT); + } + else + { + return; + } + } + else + { + flags = (I_GetTime() & 1) ? V_ADD : 0; + } + + patch_t* emer = Draw::cache_patch("EMRCA0"); + Draw row = Draw(BASEVIDWIDTH / 2, kYOffset).scale(kScale).flags(flags); //Draw(0, row.y()).size(BASEVIDWIDTH, 1).fill(35); - Draw top = row.y(-kYPad); - Draw bot = row.xy(-kWidth / 2, kH + kYPad); + Draw top = row.y(kTop); + Draw bot = row.xy(-kWidth / 2, kBot); - auto put = [](Draw& row, int x, int n) + auto put = [&](Draw& row, int offscreen, int x, int n) { - row.x(x * kWidth).colormap(static_cast(SKINCOLOR_CHAOSEMERALD1 + n)).patch("EMRCA0"); + row + .xy(x * kWidth, Easing_OutSine(interval(t, kDelay * n, kSlide), offscreen, 0)) + .colormap(static_cast(SKINCOLOR_CHAOSEMERALD1 + n)) + .patch(emer); }; - put(top, -1, 3); - put(top, 0, 0); - put(top, 1, 4); + put(top, -kTop - kMid, -1, 3); + put(top, -kTop - kMid, 0, 0); + put(top, -kTop - kMid, 1, 4); - put(bot, -1, 5); - put(bot, 0, 1); - put(bot, 1, 2); - put(bot, 2, 6); + put(bot, 200 - kBot + kMid, -1, 5); + put(bot, 200 - kBot + kMid, 0, 1); + put(bot, 200 - kBot + kMid, 1, 2); + put(bot, 200 - kBot + kMid, 2, 6); } diff --git a/src/k_battle.c b/src/k_battle.c index 544490ee7..811c9fc37 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -43,7 +43,7 @@ UINT8 maptargets = 0; // Capsules in map UINT8 numtargets = 0; // Capsules busted // Battle: someone won by collecting all 7 Chaos Emeralds -boolean g_emeraldWin = false; +tic_t g_emeraldWin = 0; INT32 K_StartingBumperCount(void) { @@ -210,7 +210,11 @@ void K_CheckEmeralds(player_t *player) player->roundscore = 100; // lmao P_DoAllPlayersExit(0, false); - g_emeraldWin = true; + + // TODO: this would be better if the timing lived in + // Tally code. But I didn't do it that, so this just + // shittily approximates syncing up with Tally. + g_emeraldWin = leveltime + (3*TICRATE); } UINT16 K_GetChaosEmeraldColor(UINT32 emeraldType) @@ -884,7 +888,7 @@ void K_BattleInit(boolean singleplayercontext) g_battleufo.due = starttime; g_battleufo.previousId = Obj_RandomBattleUFOSpawnerID() - 1; - g_emeraldWin = false; + g_emeraldWin = 0; } UINT8 K_Bumpers(player_t *player) diff --git a/src/k_battle.h b/src/k_battle.h index 623553b63..cb15921ae 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -31,7 +31,7 @@ extern struct battleufo extern boolean battleprisons; extern INT32 nummapboxes, numgotboxes; // keep track of spawned battle mode items extern UINT8 maptargets, numtargets; -extern boolean g_emeraldWin; +extern tic_t g_emeraldWin; INT32 K_StartingBumperCount(void); boolean K_IsPlayerWanted(player_t *player); diff --git a/src/k_hud.cpp b/src/k_hud.cpp index e1eb0a4b8..e3ed12f52 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -5851,10 +5851,16 @@ void K_drawKartHUD(void) K_drawKartFirstPerson(); // Draw full screen stuff that turns off the rest of the HUD - if (mapreset && R_GetViewNumber() == 0) + if (R_GetViewNumber() == 0) { - K_drawChallengerScreen(); - return; + if (mapreset) + { + K_drawChallengerScreen(); + return; + } + + if (g_emeraldWin) + K_drawEmeraldWin(false); } if (!demo.title) @@ -6069,15 +6075,15 @@ void K_drawKartHUD(void) K_drawSpectatorHUD(false); } + if (R_GetViewNumber() == 0 && g_emeraldWin) + K_drawEmeraldWin(true); + if (modeattacking || freecam) // everything after here is MP and debug only return; if ((gametyperules & GTR_KARMA) && !r_splitscreen && (stplyr->karthud[khud_yougotem] % 2)) // * YOU GOT EM * V_DrawScaledPatch(BASEVIDWIDTH/2 - (SHORT(kp_yougotem->width)/2), 32, V_HUDTRANS, kp_yougotem); - if (g_emeraldWin) - K_drawEmeraldWin(); - // Draw FREE PLAY. K_drawKartFreePlay(); diff --git a/src/k_hud.h b/src/k_hud.h index 839827d3d..d91d0c5c0 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -47,7 +47,7 @@ void K_drawSpectatorHUD(boolean director); void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, UINT8 mode); void K_drawKart2PTimestamp(void); void K_drawKart4PTimestamp(void); -void K_drawEmeraldWin(void); +void K_drawEmeraldWin(boolean overlay); void K_DrawMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, UINT16 map, const UINT8 *colormap); void K_DrawLikeMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, patch_t *patch, const UINT8 *colormap); void K_drawTargetHUD(const vector3_t *origin, player_t *player); diff --git a/src/p_saveg.c b/src/p_saveg.c index 712a7d9d4..64659573a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -6471,7 +6471,7 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending) WRITEINT32(save->p, numgotboxes); WRITEUINT8(save->p, numtargets); WRITEUINT8(save->p, battleprisons); - WRITEUINT8(save->p, g_emeraldWin); + WRITEUINT32(save->p, g_emeraldWin); WRITEUINT8(save->p, gamespeed); WRITEUINT8(save->p, numlaps); @@ -6657,7 +6657,7 @@ static boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading) numgotboxes = READINT32(save->p); numtargets = READUINT8(save->p); battleprisons = (boolean)READUINT8(save->p); - g_emeraldWin = (boolean)READUINT8(save->p); + g_emeraldWin = (tic_t)READUINT32(save->p); gamespeed = READUINT8(save->p); numlaps = READUINT8(save->p);