From 1d83dddab8f561b8d6275d9a1e77df6ef0b022c9 Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Tue, 3 Sep 2024 01:08:59 -0700 Subject: [PATCH] WIP: Timer Duel --- src/d_player.h | 1 + src/g_game.c | 12 +++++++++++ src/k_hud.cpp | 50 +++++++++++++++++++++++++++++---------------- src/k_kart.c | 47 +++++++++++++++++++++++++++++++++++------- src/k_kart.h | 6 ++++++ src/lua_playerlib.c | 4 ++++ src/p_inter.c | 2 ++ src/p_saveg.c | 2 ++ 8 files changed, 99 insertions(+), 25 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 6d6a7b8bb..d3facfed7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -927,6 +927,7 @@ struct player_t INT32 checkpointId; // Players respawn here, objects/checkpoint.cpp INT16 duelscore; + tic_t dueltimer; UINT8 ctfteam; // 0 == Spectator, 1 == Red, 2 == Blue diff --git a/src/g_game.c b/src/g_game.c index 56991ea59..6b2ff35fe 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2179,6 +2179,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) UINT8 lastsafecheatcheck; UINT16 bigwaypointgap; + INT16 duelscore; + tic_t dueltimer; + roundconditions_t roundconditions; boolean saveroundconditions; @@ -2334,6 +2337,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) bigwaypointgap = 0; tallyactive = false; + + dueltimer = 15*TICRATE; + duelscore = 0; } else { @@ -2384,6 +2390,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) lastsafecheatcheck = players[player].lastsafecheatcheck; bigwaypointgap = players[player].bigwaypointgap; + duelscore = players[player].duelscore; + dueltimer = players[player].dueltimer; + tallyactive = players[player].tally.active; if (tallyactive) { @@ -2521,6 +2530,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->griefValue = griefValue; p->griefStrikes = griefStrikes; + p->dueltimer = dueltimer; + p->duelscore = duelscore; + memcpy(&p->itemRoulette, &itemRoulette, sizeof (p->itemRoulette)); memcpy(&p->respawn, &respawn, sizeof (p->respawn)); diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 8918e3233..b8272f3b0 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -2628,11 +2628,38 @@ void PositionFacesInfo::draw_1p() ; else if (gametyperules & GTR_CIRCUIT) { - INT32 pos = players[rankplayer[i]].position; - if (pos < 0 || pos > MAXPLAYERS) - pos = 0; - // Draws the little number over the face - V_DrawScaledPatch(FACE_X-5, Y+10, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_facenum[pos]); + if (inDuel) + { + INT32 flags = V_HUDTRANS | V_SLIDEIN | V_SNAPTOLEFT; + + colormap = NULL; + + if (K_PlayerLosingDuel(&players[rankplayer[i]]) || players[rankplayer[i]].dueltimer == 0) + { + colormap = R_GetTranslationColormap(TC_RAINBOW, (players[rankplayer[i]].dueltimer == 0) ? SKINCOLOR_CRIMSON : SKINCOLOR_TANGERINE, GTC_CACHE); + flags |= V_STRINGDANCE; + } + + V_DrawStringScaled( + (FACE_X - 5) * FRACUNIT, + (Y + 10) * FRACUNIT, + FRACUNIT, + FRACUNIT, + FRACUNIT, + flags, + colormap, + PINGF_FONT, + va("%02d.%02d", players[rankplayer[i]].dueltimer/TICRATE, (players[rankplayer[i]].dueltimer%TICRATE)*100/TICRATE) + ); + } + else + { + INT32 pos = players[rankplayer[i]].position; + if (pos < 0 || pos > MAXPLAYERS) + pos = 0; + // Draws the little number over the face + V_DrawScaledPatch(FACE_X-5, Y+10, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_facenum[pos]); + } } else if (gametyperules & GTR_POINTLIMIT) { @@ -2997,19 +3024,6 @@ static void K_drawKartLaps(void) // I do not understand the way this system of offsets is laid out at all, // so it's probably going to be pretty bad to maintain. Sorry. - if (inDuel) - { - UINT32 flashflag = (stplyr->duelscore >= 0) ? V_BLUEMAP : V_REDMAP; - if (leveltime % 2) - if (abs(stplyr->duelscore) >= 2) - flashflag = V_YELLOWMAP; - - if (stplyr->duelscore >= 0) - V_DrawCenteredString(BASEVIDWIDTH/2, 5, flashflag, va("+%d", stplyr->duelscore)); - else - V_DrawCenteredString(BASEVIDWIDTH/2, 5, flashflag, va("%d", stplyr->duelscore)); - } - if (numlaps != 1) { if (r_splitscreen > 1) diff --git a/src/k_kart.c b/src/k_kart.c index 1fa198003..6d3fa23c6 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4147,19 +4147,23 @@ void K_CheckpointCrossAward(player_t *player) K_AwardPlayerRings(player, (player->bot ? 20 : 10), true); // Update Duel scoring. - if (inDuel && player->position == 1) + if (inDuel) { player->duelscore += 1; + + if (player->position == 1) + { + tic_t effectiveleveltime = min(leveltime, DUELTIMER_NOBONUS); + player->dueltimer += Easing_Linear(effectiveleveltime*FRACUNIT/DUELTIMER_NOBONUS, DUELTIMER_BONUS, 0); + player->dueltimer = min(player->dueltimer, DUELTIMER_MAX); + } + for (UINT8 i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] && !players[i].spectator && &players[i] != player) + { players[i].duelscore -= 1; - } - - if (player->duelscore == 3) - { - P_DoPlayerExit(player, 0); - P_DoAllPlayersExit(PF_NOCONTEST, 0); + } } } @@ -7616,6 +7620,19 @@ SINT8 K_GetTotallyRandomResult(UINT8 useodds) return i; } +boolean K_PlayerLosingDuel(player_t *player) +{ + for (UINT8 i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator && &players[i] != player) + { + if (players[i].duelscore > player->duelscore) + return true; + } + } + return false; +} + mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT16 amount) { mobj_t *drop = P_SpawnMobj(x, y, z, MT_FLOATINGITEM); @@ -9385,6 +9402,22 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->invincibilitytimer--; } + if (inDuel && K_PlayerLosingDuel(player)) + { + if (player->dueltimer) + { + player->dueltimer--; + if (!(player->dueltimer % 4) && P_IsDisplayPlayer(player)) + S_StartSound(NULL, sfx_s3k55); + + if (player->dueltimer == 0) + { + P_DoTimeOver(player); + P_DoAllPlayersExit(0, false); + } + } + } + if (!player->invincibilitytimer) player->invincibilityextensions = 0; diff --git a/src/k_kart.h b/src/k_kart.h index bf73ffcf2..38e80016e 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -88,6 +88,11 @@ Make sure this matches the actual number of states #define AUTORESPAWN_TIME (10*TICRATE) #define AUTORESPAWN_THRESHOLD (7*TICRATE) +#define DUELTIMER_START (10*TICRATE) +#define DUELTIMER_BONUS (2*TICRATE) +#define DUELTIMER_MAX (3*DUELTIMER_START/2) +#define DUELTIMER_NOBONUS (60*TICRATE) + angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); boolean K_IsDuelItem(mobjtype_t type); @@ -203,6 +208,7 @@ void K_SpawnDriftElectricSparks(player_t *player, int color, boolean shockwave); void K_KartUpdatePosition(player_t *player); void K_UpdateAllPlayerPositions(void); SINT8 K_GetTotallyRandomResult(UINT8 useodds); +boolean K_PlayerLosingDuel(player_t *player); mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT16 amount); mobj_t *K_FlingPaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT16 amount); void K_DropPaperItem(player_t *player, UINT8 itemtype, UINT16 itemamount); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 59796ac60..c0bf2df4b 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -677,6 +677,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->cheatchecknum); else if (fastcmp(field,"duelscore")) lua_pushinteger(L, plr->duelscore); + else if (fastcmp(field,"dueltimer")) + lua_pushinteger(L, plr->dueltimer); else if (fastcmp(field,"lastsidehit")) lua_pushinteger(L, plr->lastsidehit); else if (fastcmp(field,"lastlinehit")) @@ -1250,6 +1252,8 @@ static int player_set(lua_State *L) plr->cheatchecknum = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"duelscore")) plr->duelscore = (INT16)luaL_checkinteger(L, 3); + else if (fastcmp(field,"dueltimer")) + plr->dueltimer = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"lastsidehit")) plr->lastsidehit = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"lastlinehit")) diff --git a/src/p_inter.c b/src/p_inter.c index 8464cf0b9..7b5c69b57 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1544,6 +1544,8 @@ boolean P_CheckRacers(void) const boolean griefed = (spectateGriefed > 0); boolean eliminateLast = (!K_CanChangeRules(true) || (cv_karteliminatelast.value != 0)); + if (inDuel) + eliminateLast = false; boolean allHumansDone = true; //boolean allBotsDone = true; diff --git a/src/p_saveg.c b/src/p_saveg.c index 1b697bd66..711d6632d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -285,6 +285,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEINT32(save->p, players[i].exp); WRITEUINT16(save->p, players[i].gradingpointnum); WRITEINT16(save->p, players[i].duelscore); + WRITEUINT32(save->p, players[i].dueltimer); WRITEINT32(save->p, players[i].cheatchecknum); WRITEINT32(save->p, players[i].checkpointId); @@ -957,6 +958,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].exp = READINT32(save->p); players[i].gradingpointnum = READUINT16(save->p); players[i].duelscore = READINT16(save->p); + players[i].dueltimer = READUINT32(save->p); players[i].cheatchecknum = READINT32(save->p); players[i].checkpointId = READINT32(save->p);