diff --git a/src/doomstat.h b/src/doomstat.h index 3a9e4396d..b0375ffa2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -695,7 +695,7 @@ extern UINT8 gamespeed; extern boolean franticitems; extern boolean encoremode, prevencoremode; -extern SINT8 battlewanted[4]; +extern UINT32 g_hiscore; extern tic_t wantedcalcdelay; extern tic_t itemCooldowns[NUMKARTITEMS - 1]; extern tic_t mapreset; diff --git a/src/g_game.c b/src/g_game.c index 1919ecb0c..441f9e6c6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -297,7 +297,7 @@ SINT8 votes[MAXPLAYERS]; // Each player's vote SINT8 pickedvote; // What vote the host rolls // Server-sided, synched variables -SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points +UINT32 g_hiscore; // Highest score (points) achieved by anyone in game tic_t wantedcalcdelay; // Time before it recalculates WANTED tic_t itemCooldowns[NUMKARTITEMS - 1]; // Cooldowns to prevent item spawning tic_t mapreset; // Map reset delay when enough players have joined an empty game diff --git a/src/k_battle.c b/src/k_battle.c index 5cc3794fe..b34c7a151 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -91,8 +91,7 @@ void K_CheckBumpers(void) { UINT8 i; UINT8 numingame = 0; - SINT8 winnernum = -1; - UINT32 winnerscoreadd = 0, maxroundscore = 0; + UINT32 toproundscore = 0; UINT8 nobumpers = 0; if (!(gametyperules & GTR_BUMPERS)) @@ -110,23 +109,16 @@ void K_CheckBumpers(void) return; numingame++; - winnerscoreadd += players[i].roundscore; - if (players[i].roundscore > maxroundscore) + if (players[i].roundscore > toproundscore) { - maxroundscore = players[i].roundscore; + toproundscore = players[i].roundscore; } if (players[i].bumpers <= 0) // if you don't have any bumpers, you're probably not a winner { nobumpers++; - continue; } - else if (winnernum != -1) // TWO winners? that's dumb :V - return; - - winnernum = i; - winnerscoreadd -= players[i].roundscore; } if (battlecapsules || bossinfo.valid) @@ -145,6 +137,10 @@ void K_CheckBumpers(void) } return; } + else + { + g_hiscore = toproundscore; + } if (numingame <= 1) { @@ -157,26 +153,6 @@ void K_CheckBumpers(void) return; } - - if (winnernum > -1 && playeringame[winnernum]) - { - if ((players[winnernum].roundscore+winnerscoreadd) == maxroundscore) - winnerscoreadd++; // break ties if luigi wins by doing nothing - players[winnernum].roundscore += winnerscoreadd; - CONS_Printf(M_GetText("%s recieved %d point%s for winning!\n"), player_names[winnernum], winnerscoreadd, (winnerscoreadd == 1 ? "" : "s")); - } - - for (i = 0; i < MAXPLAYERS; i++) // This can't go in the earlier loop because winning adds points - K_KartUpdatePosition(&players[i]); - - for (i = 0; i < MAXPLAYERS; i++) // and it can't be merged with this loop because it needs to be all updated before exiting... multi-loops suck... - { - if (!playeringame[i]) - continue; - if (players[i].spectator) - continue; - P_DoPlayerExit(&players[i]); - } } void K_CheckEmeralds(player_t *player) diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index a39a9a22c..dbb5ce8d0 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -2,12 +2,15 @@ #include #include +#include "k_battle.h" +#include "k_boss.h" #include "k_hud.h" #include "m_fixed.h" #include "p_local.h" #include "p_mobj.h" #include "r_fps.h" #include "r_main.h" +#include "st_stuff.h" #include "v_video.h" namespace @@ -226,6 +229,43 @@ void K_DrawTargetTracking(const TargetTracking& target) } } +bool is_player_tracking_target(const player_t *player) +{ + if ((gametyperules & (GTR_BUMPERS|GTR_CLOSERPLAYERS)) != (GTR_BUMPERS|GTR_CLOSERPLAYERS)) + { + return false; + } + + if (battlecapsules || bossinfo.valid) + { + return false; + } + + if (player == nullptr) + { + return false; + } + + if (inDuel) + { + // Always draw targets in 1v1 but don't draw player's + // own target on their own viewport. + return player != stplyr; + } + + if (g_hiscore < 1) // SOMEONE should be scoring + { + return false; + } + + if (player->roundscore < g_hiscore) + { + return false; + } + + return true; +} + bool is_object_tracking_target(const mobj_t* mobj) { switch (mobj->type) @@ -234,6 +274,9 @@ bool is_object_tracking_target(const mobj_t* mobj) case MT_SPECIAL_UFO: return true; + case MT_PLAYER: + return is_player_tracking_target(mobj->player); + default: return false; } diff --git a/src/k_kart.c b/src/k_kart.c index 6a71fe356..64c403866 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -49,7 +49,6 @@ // franticitems is Frantic Mode items, bool // encoremode is Encore Mode (duh), bool // comeback is Battle Mode's karma comeback, also bool -// battlewanted is an array of the WANTED player nums, -1 for no player in that slot // mapreset is set when enough players fill an empty server boolean K_IsDuelItem(mobjtype_t type) @@ -4179,23 +4178,12 @@ void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers) } else if (player->bumpers == 0 && prevBumpers > 0) { - mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); - P_SetTarget(&karmahitbox->target, player->mo); - - karmahitbox->destscale = player->mo->destscale; - P_SetScale(karmahitbox, player->mo->scale); - - player->karmadelay = comebacktime; - if (battlecapsules || bossinfo.valid) { player->pflags |= (PF_NOCONTEST|PF_ELIMINATED); - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); - } - else if (netgame) - { - CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); } + + P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); } K_CalculateBattleWanted(); @@ -9305,22 +9293,22 @@ void K_KartUpdatePosition(player_t *player) UINT8 myEmeralds = K_NumEmeralds(player); UINT8 yourEmeralds = K_NumEmeralds(&players[i]); - if (yourEmeralds > myEmeralds) + // First compare all points + if (players[i].roundscore > player->roundscore) { - // Emeralds matter above all position++; } - else if (yourEmeralds == myEmeralds) + else if (players[i].roundscore == player->roundscore) { - // Bumpers are a tie breaker - if (players[i].bumpers > player->bumpers) + // Emeralds are a tie breaker + if (yourEmeralds > myEmeralds) { position++; } - else if (players[i].bumpers == player->bumpers) + else if (yourEmeralds == myEmeralds) { - // Score is the second tier tie breaker - if (players[i].roundscore > player->roundscore) + // Bumpers are the second tier tie breaker + if (players[i].bumpers > player->bumpers) { position++; } @@ -11378,6 +11366,9 @@ tic_t K_TimeLimitForGametype(void) UINT32 K_PointLimitForGametype(void) { const UINT32 gametypeDefault = gametypes[gametype]->pointlimit; + const UINT32 battleRules = GTR_BUMPERS|GTR_CLOSERPLAYERS|GTR_PAPERITEMS; + + UINT32 ptsCap = gametypeDefault; if (!(gametyperules & GTR_POINTLIMIT)) { @@ -11389,7 +11380,28 @@ UINT32 K_PointLimitForGametype(void) return cv_pointlimit.value; } - return gametypeDefault; + if (battlecapsules || bossinfo.valid) + { + return 0; + } + + if ((gametyperules & battleRules) == battleRules) + { + INT32 i; + + // It's frustrating that this shitty for-loop needs to + // be duplicated every time the players need to be + // counted. + for (i = 0; i < MAXPLAYERS; ++i) + { + if (D_IsPlayerHumanAndGaming(i)) + { + ptsCap += 3; + } + } + } + + return ptsCap; } //} diff --git a/src/p_inter.c b/src/p_inter.c index 3938b90d8..6e053a405 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1171,8 +1171,15 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } if (gametyperules & GTR_BUMPERS) + { K_CheckBumpers(); + if (target->player->roundscore > 1) + target->player->roundscore -= 2; + else + target->player->roundscore = 0; + } + target->player->trickpanel = 0; } diff --git a/src/p_mobj.c b/src/p_mobj.c index e04fe01c5..52e48da51 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5250,6 +5250,10 @@ static boolean P_IsTrackerType(INT32 type) case MT_SPECIAL_UFO: return true; + // Players sometimes get targeted with HUD tracking + case MT_PLAYER: + return true; + default: return false; } @@ -11819,10 +11823,8 @@ void P_SpawnPlayer(INT32 playernum) } else if (p->bumpers <= 0) { - mobj_t *karmahitbox = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_KARMAHITBOX); // Player hitbox is too small!! - P_SetTarget(&karmahitbox->target, mobj); - karmahitbox->destscale = mobj->scale; - P_SetScale(karmahitbox, mobj->scale); + p->bumpers = K_StartingBumperCount(); + K_SpawnPlayerBattleBumpers(p); } } } diff --git a/src/p_saveg.c b/src/p_saveg.c index 2e0838212..55fac75f5 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4957,8 +4957,7 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending) WRITESINT8(save->p, speedscramble); WRITESINT8(save->p, encorescramble); - for (i = 0; i < 4; i++) - WRITESINT8(save->p, battlewanted[i]); + WRITEUINT32(save->p, g_hiscore); // battleovertime_t WRITEUINT16(save->p, battleovertime.enabled); @@ -5129,8 +5128,7 @@ static inline boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading) speedscramble = READSINT8(save->p); encorescramble = READSINT8(save->p); - for (i = 0; i < 4; i++) - battlewanted[i] = READSINT8(save->p); + g_hiscore = READUINT32(save->p); // battleovertime_t battleovertime.enabled = READUINT16(save->p); diff --git a/src/p_setup.c b/src/p_setup.c index bedb39c78..0c8ddef6b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7042,8 +7042,7 @@ static void P_InitLevelSettings(void) franticitems = (boolean)cv_kartfrantic.value; } - for (i = 0; i < 4; i++) - battlewanted[i] = -1; + g_hiscore = 0; memset(&battleovertime, 0, sizeof(struct battleovertime)); speedscramble = encorescramble = -1;