From 87a6743c0f0ba06415b43d6ed52d576696d5254e Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 22:20:28 -0800 Subject: [PATCH 1/8] Battle: replace bumper elimination win condition with points cap - Points cap is 3 * player count. E.g. for 3 players, the cap is 9 points. - Once a player gets enough points, they win! --- src/k_battle.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index 5cc3794fe..55e25c639 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,13 @@ void K_CheckBumpers(void) } return; } + else + { + if (toproundscore < (numingame * 3)) + { + return; + } + } if (numingame <= 1) { @@ -158,14 +157,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]); From deac3a373f9cfe13632e5f0f7265aeae7cbb3d0d Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 22 Feb 2023 00:06:24 -0800 Subject: [PATCH 2/8] Battle: replace Karma Bomb with death - Lose 2 points when you die. - Respawn with 3 bumpers. --- src/k_kart.c | 12 ++---------- src/p_inter.c | 7 +++++++ src/p_mobj.c | 6 ++---- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 32982cd2b..ae3dade94 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4170,22 +4170,14 @@ 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) + else { - CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); + P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); } } diff --git a/src/p_inter.c b/src/p_inter.c index 84f88b022..6cae648bd 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1170,8 +1170,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..795af53d8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11819,10 +11819,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); } } } From 9147a17bf3fa39b6704f90964fddaf822009ee9d Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 22 Feb 2023 00:16:23 -0800 Subject: [PATCH 3/8] Battle: change rankings priority Highest to lowest: 1. points 2. emeralds 3. bumpers --- src/k_kart.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index ae3dade94..aae6c9e3a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9285,22 +9285,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++; } From e6da831e3605a18a0cc1c211a3a58206716ca22a Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 22 Feb 2023 00:44:47 -0800 Subject: [PATCH 4/8] HUD target player with most points - Replace battlewanted global with g_hiscore, keeps track of the current highest number of points. - Adds HUD tracking for player(s) with the hiscore. - Should target both players in a tie. --- src/doomstat.h | 2 +- src/g_game.c | 2 +- src/k_battle.c | 2 ++ src/k_hud_track.cpp | 23 +++++++++++++++++++++++ src/k_kart.c | 1 - src/p_mobj.c | 4 ++++ src/p_saveg.c | 6 ++---- src/p_setup.c | 3 +-- 8 files changed, 34 insertions(+), 9 deletions(-) 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 e522d82e2..7dad67c30 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 55e25c639..c16158e80 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -139,6 +139,8 @@ void K_CheckBumpers(void) } else { + g_hiscore = toproundscore; + if (toproundscore < (numingame * 3)) { return; diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index a39a9a22c..bb00ee91a 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -226,6 +226,26 @@ void K_DrawTargetTracking(const TargetTracking& target) } } +bool is_player_tracking_target(const player_t *player) +{ + if (player == nullptr) + { + return false; + } + + 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 +254,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 aae6c9e3a..644e1035e 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) diff --git a/src/p_mobj.c b/src/p_mobj.c index 795af53d8..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; } diff --git a/src/p_saveg.c b/src/p_saveg.c index 6c27d8d91..73fe11c3a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4953,8 +4953,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); @@ -5125,8 +5124,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; From ec8e81ddb66e83cbe7b89953ca6072007a0d5f0a Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 22 Feb 2023 00:57:31 -0800 Subject: [PATCH 5/8] Always HUD track players in Duel mode --- src/k_hud_track.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index bb00ee91a..af9c4608f 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -8,6 +8,7 @@ #include "p_mobj.h" #include "r_fps.h" #include "r_main.h" +#include "st_stuff.h" #include "v_video.h" namespace @@ -233,6 +234,13 @@ bool is_player_tracking_target(const player_t *player) 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; From 368116bc59b9817c35a7a79c5551588b95983ff7 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 23 Feb 2023 01:06:07 -0800 Subject: [PATCH 6/8] Restrict HUD tracking on players - Gametyperules include both GTR_BUMPERS and GTR_CLOSERPLAYERS. - Break the Capsules or Boss modes must not be active. --- src/k_hud_track.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index af9c4608f..dbb5ce8d0 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -2,6 +2,8 @@ #include #include +#include "k_battle.h" +#include "k_boss.h" #include "k_hud.h" #include "m_fixed.h" #include "p_local.h" @@ -229,6 +231,16 @@ 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; From 01227814b93b6dd8415c4d32c403a4b21800cce5 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 23 Feb 2023 19:55:43 -0800 Subject: [PATCH 7/8] Refactor Battle points cap to use g_pointlimit Fixes players leaving mid-game lowering the point limit and instantly ending the match. see 94c811b55 --- src/k_battle.c | 17 ----------------- src/k_kart.c | 26 +++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index c16158e80..b34c7a151 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -140,11 +140,6 @@ void K_CheckBumpers(void) else { g_hiscore = toproundscore; - - if (toproundscore < (numingame * 3)) - { - return; - } } if (numingame <= 1) @@ -158,18 +153,6 @@ void K_CheckBumpers(void) return; } - - 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_kart.c b/src/k_kart.c index 644e1035e..7612a9ef5 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -11350,6 +11350,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)) { @@ -11361,7 +11364,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; } //} From ea4890b4b38915cfb46953cf7843608c5f9b0dda Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 24 Feb 2023 00:08:54 -0800 Subject: [PATCH 8/8] Simplify bumper death code flow --- src/k_kart.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 7612a9ef5..c9c2b0f7b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4172,12 +4172,9 @@ void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers) if (battlecapsules || bossinfo.valid) { player->pflags |= (PF_NOCONTEST|PF_ELIMINATED); - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); - } - else - { - P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); } + + P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); } K_CalculateBattleWanted();