Add SPBs to battle mode

The ultimate means against camping
This commit is contained in:
Anonimus 2025-09-26 00:05:06 -04:00
parent 003bef11ae
commit eade241d3b
9 changed files with 89 additions and 23 deletions

View file

@ -383,6 +383,7 @@ const char *const GAMETYPERULE_LIST[] = {
"BATTLEODDS",
"PAPERITEMS",
"WANTED",
"WANTEDSPB",
"KARMA",
"ITEMARROWS",
"ITEMBREAKER",

View file

@ -489,30 +489,31 @@ enum GameTypeRules
GTR_BATTLEODDS = 1<<6, // ItemOdds used in this mode are for battling.
GTR_PAPERITEMS = 1<<7, // Replaces item boxes with paper item spawners.
GTR_WANTED = 1<<8, // Enables the wanted anti-camping system.
GTR_KARMA = 1<<9, // Enables the Karma system if you're out of bumpers.
GTR_ITEMARROWS = 1<<10, // Show item box arrows above players.
GTR_ITEMBREAKER = 1<<11, // Enables the use of Item Breaker in this Gamemode.
GTR_BATTLESTARTS = 1<<12, // Use Battle Mode start positions.
GTR_CLOSERPLAYERS = 1<<13, // Enables specfic gameplay tweaks with closer players.
GTR_BATTLEBOXES = 1<<14, // Itemboxes respawn differently.
GTR_WANTEDSPB = 1<<9, // Unleash Self-Propelled Bombs on Wanted players.
GTR_KARMA = 1<<10, // Enables the Karma system if you're out of bumpers.
GTR_ITEMARROWS = 1<<11, // Show item box arrows above players.
GTR_ITEMBREAKER = 1<<12, // Enables the use of Item Breaker in this Gamemode.
GTR_BATTLESTARTS = 1<<13, // Use Battle Mode start positions.
GTR_CLOSERPLAYERS = 1<<14, // Enables specfic gameplay tweaks with closer players.
GTR_BATTLEBOXES = 1<<15, // Itemboxes respawn differently.
GTR_POINTLIMIT = 1<<15, // Reaching point limit ends the round.
GTR_TIMELIMIT = 1<<16, // Reaching time limit ends the round.
GTR_OVERTIME = 1<<17, // Allow overtime behavior.
GTR_POINTLIMIT = 1<<16, // Reaching point limit ends the round.
GTR_TIMELIMIT = 1<<17, // Reaching time limit ends the round.
GTR_OVERTIME = 1<<18, // Allow overtime behavior.
// Custom gametype rules
GTR_TEAMS = 1<<18, // Teams are forced on.
GTR_NOTEAMS = 1<<19, // Teams are forced off.
GTR_TEAMSTARTS = 1<<20, // Use team-based start positions.
GTR_TEAMS = 1<<19, // Teams are forced on.
GTR_NOTEAMS = 1<<20, // Teams are forced off.
GTR_TEAMSTARTS = 1<<21, // Use team-based start positions.
// Grand Prix rules
//Free = 1<<21,
GTR_LIVES = 1<<22, // Lives system, players are forced to spectate during Game Over.
GTR_SPECIALBOTS = 1<<23, // Bot difficulty gets stronger between rounds, and the rival system is enabled.
//Free = 1<<22,
GTR_LIVES = 1<<23, // Lives system, players are forced to spectate during Game Over.
GTR_SPECIALBOTS = 1<<24, // Bot difficulty gets stronger between rounds, and the rival system is enabled.
// Misc
GTR_NOCOUNTDOWN = 1<<24, // Disables Countdown timer and control lock at the start of levels.
GTR_ENCORE = 1<<25, // Enable Encore mode.
GTR_NOCOUNTDOWN = 1<<25, // Disables Countdown timer and control lock at the start of levels.
GTR_ENCORE = 1<<26, // Enable Encore mode.
// free: to and including 1<<31
};
@ -670,6 +671,7 @@ extern boolean franticitems;
extern boolean encoremode, prevencoremode;
extern boolean comeback;
extern SINT8 mostwanted;
extern SINT8 battlewanted[4];
extern tic_t wantedcalcdelay;
extern tic_t indirectitemcooldown;

View file

@ -296,6 +296,7 @@ SINT8 pickedvote; // What vote the host rolls
// Server-sided, synched variables
SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points
SINT8 mostwanted; // The "most wanted" (first in line) player.
tic_t wantedcalcdelay; // Time before it recalculates WANTED
tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded
tic_t hyubgone; // Cooldown before hyudoro is allowed to be rerolled
@ -3373,7 +3374,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] =
// Race
GTR_CIRCUIT|GTR_BOTS|GTR_RINGS|GTR_ENCORE|GTR_RACEODDS,
// Battle
GTR_BUMPERS|GTR_POINTS|GTR_RINGS|GTR_KARMA|GTR_WANTED|GTR_ITEMARROWS|GTR_ITEMBREAKER|GTR_BATTLESTARTS|GTR_TIMELIMIT|GTR_POINTLIMIT|GTR_BATTLEODDS|GTR_CLOSERPLAYERS|GTR_BATTLEBOXES
GTR_BUMPERS|GTR_POINTS|GTR_RINGS|GTR_KARMA|GTR_WANTED|GTR_WANTEDSPB|GTR_ITEMARROWS|GTR_ITEMBREAKER|GTR_BATTLESTARTS|GTR_TIMELIMIT|GTR_POINTLIMIT|GTR_BATTLEODDS|GTR_CLOSERPLAYERS|GTR_BATTLEBOXES
};
//

View file

@ -55,6 +55,20 @@ boolean K_IsPlayerWanted(player_t *player)
return false;
}
boolean K_IsPlayerMostWanted(player_t *player)
{
if (mostwanted == -1)
return false;
if (!(gametyperules & GTR_WANTEDSPB))
return false;
if (player == &players[mostwanted])
return true;
return false;
}
void K_CalculateBattleWanted(void)
{
UINT8 numingame = 0, numwanted = 0;
@ -62,6 +76,8 @@ void K_CalculateBattleWanted(void)
UINT8 ties = 0, nextcamppos = 0;
UINT8 i, j;
mostwanted = -1;
if (!(gametyperules & GTR_WANTED))
{
memset(battlewanted, -1, sizeof (battlewanted));
@ -162,6 +178,10 @@ void K_CalculateBattleWanted(void)
if (ties < (numwanted-i)) // Is it still low enough after counting?
{
battlewanted[i] = camppos[nextcamppos];
if (!nextcamppos)
mostwanted = battlewanted[i];
nextcamppos++;
}
else

View file

@ -14,6 +14,7 @@ extern UINT8 numtargets;
INT32 K_StartingBumperCount(void);
boolean K_IsPlayerWanted(player_t *player);
boolean K_IsPlayerMostWanted(player_t *player);
void K_CalculateBattleWanted(void);
void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount);
void K_CheckBumpers(void);

View file

@ -1014,6 +1014,16 @@ UINT32 K_CalculatePDIS(const player_t *player, UINT8 numPlayers, boolean *spbrus
return pdis;
}
static boolean K_CanForceSPB(player_t *player, UINT32 pdis)
{
boolean battlecond, racecond;
battlecond = ((gametyperules & GTR_WANTED) && (gametyperules & GTR_WANTEDSPB) && (mostwanted != -1) && (!K_IsPlayerMostWanted(player)));
racecond = ((gametyperules & GTR_CIRCUIT) && player->position == 2 && pdis > SPBFORCEDIST);
return ((battlecond) || (racecond));
}
void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
{
INT32 i;
@ -1198,7 +1208,8 @@ void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
// SPECIAL CASE No. 6:
// Force SPB onto 2nd if they get too far behind
if ((gametyperules & GTR_CIRCUIT) && player->position == 2 && pdis > SPBFORCEDIST
// In battle, an SPB is forced onto players to target the "most wanted" player
if (K_CanForceSPB(player, pdis)
&& spbplace == -1 && !indirectitemcooldown && !dontforcespb
&& cv_selfpropelledbomb.value)
{

View file

@ -10775,7 +10775,8 @@ void A_SPBChase(mobj_t *actor)
return;
}
// Find the player with the best rank
// Find the player with the best rank. In gametypes with SPB forcing on WANTED
// players, find our most-wanted player.
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator || players[i].exiting)
@ -10790,7 +10791,15 @@ void A_SPBChase(mobj_t *actor)
if (players[i].kartstuff[k_respawn])
continue;*/ // respawning
if (players[i].position < bestrank)
if ((gametyperules & GTR_WANTED) && (gametyperules & GTR_WANTEDSPB))
{
if (K_IsPlayerMostWanted(&players[i]))
{
player = &players[i];
break;
}
}
else if (players[i].position < bestrank)
{
bestrank = players[i].position;
player = &players[i];
@ -10843,8 +10852,15 @@ void A_SPBChase(mobj_t *actor)
else if (actor->extravalue2-- <= 0)
actor->extravalue1 = 0; // back to SEEKING
if ((gametyperules & GTR_WANTED) && (gametyperules & GTR_WANTEDSPB))
{
spbplace = (actor->tracer->player - players);
}
else
{
spbplace = actor->tracer->player->position;
}
}
if ((K_RingsActive() == true) ) // Spawn rings to make up for the fact first has ring grabbing
{
@ -10961,8 +10977,16 @@ void A_SPBChase(mobj_t *actor)
&& playeringame[actor->lastlook]
&& !players[actor->lastlook].spectator
&& !players[actor->lastlook].exiting)
{
if ((gametyperules & GTR_WANTED) && (gametyperules & GTR_WANTEDSPB))
{
spbplace = actor->lastlook;
}
else
{
spbplace = players[actor->lastlook].position;
}
if (actor->extravalue2-- <= 0 && players[actor->lastlook].mo)
{
P_SetTarget(&actor->tracer, players[actor->lastlook].mo);

View file

@ -5388,6 +5388,9 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
WRITESINT8(save->p, speedscramble);
WRITESINT8(save->p, encorescramble);
// WANTED system
WRITESINT8(save->p, mostwanted);
for (i = 0; i < 4; i++)
WRITESINT8(save->p, battlewanted[i]);
@ -5774,6 +5777,7 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
speedscramble = READSINT8(save->p);
encorescramble = READSINT8(save->p);
mostwanted = READSINT8(save->p);
for (i = 0; i < 4; i++)
battlewanted[i] = READSINT8(save->p);

View file

@ -8206,6 +8206,8 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
for (i = 0; i < 4; i++)
battlewanted[i] = -1;
mostwanted = -1;
speedscramble = encorescramble = -1;
}