Unhardcode more behaviour as gametyperules

This commit is contained in:
NepDisk 2025-09-25 21:23:58 -04:00
parent 1f2cc02db4
commit 3778520ee6
6 changed files with 48 additions and 44 deletions

View file

@ -387,6 +387,8 @@ const char *const GAMETYPERULE_LIST[] = {
"ITEMARROWS",
"ITEMBREAKER",
"BATTLESTARTS",
"CLOSERPLAYERS",
"BATTLEBOXES",
"POINTLIMIT",
"TIMELIMIT",
"OVERTIME",

View file

@ -493,24 +493,26 @@ enum GameTypeRules
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_POINTLIMIT = 1<<13, // Reaching point limit ends the round.
GTR_TIMELIMIT = 1<<14, // Reaching time limit ends the round.
GTR_OVERTIME = 1<<15, // Allow overtime behavior.
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.
// Custom gametype rules
GTR_TEAMS = 1<<16, // Teams are forced on.
GTR_NOTEAMS = 1<<17, // Teams are forced off.
GTR_TEAMSTARTS = 1<<18, // Use team-based start positions.
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.
// Grand Prix rules
//Free = 1<<19,
GTR_LIVES = 1<<20, // Lives system, players are forced to spectate during Game Over.
GTR_SPECIALBOTS = 1<<21, // Bot difficulty gets stronger between rounds, and the rival system is enabled.
//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.
// Misc
GTR_NOCOUNTDOWN = 1<<22, // Disables Countdown timer and control lock at the start of levels.
GTR_ENCORE = 1<<23, // Enable Encore mode.
GTR_NOCOUNTDOWN = 1<<24, // Disables Countdown timer and control lock at the start of levels.
GTR_ENCORE = 1<<25, // Enable Encore mode.
// free: to and including 1<<31
};

View file

@ -3373,7 +3373,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_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
};
//

View file

@ -2056,7 +2056,7 @@ static boolean K_drawKartPositionFaces(void)
V_DrawScaledPatch(FACE_X+left, Y+top, V_HUDTRANS|V_SNAPTOLEFT, highlight);
}
if (gametype == GT_BATTLE && players[rankplayer[i]].bumper <= 0)
if ((gametyperules & GTR_BUMPERS) && players[rankplayer[i]].bumper <= 0)
V_DrawScaledPatch(FACE_X-4, Y-3, V_HUDTRANS|V_SNAPTOLEFT, kp_ranknobumpers);
else
{
@ -2282,7 +2282,7 @@ INT32 K_DrawNeoTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines
colormap
);
/*if (gametype == GT_BATTLE && players[tab[i].num].bumper > 0) -- not enough space for this
/*if ((gametyperules & GTR_BUMPERS) && players[tab[i].num].bumper > 0) -- not enough space for this
{
INT32 bumperx = x+19;
V_DrawMappedPatch(bumperx-2, y-4, 0, kp_tinybumper[0], colormap);
@ -2529,7 +2529,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
V_DrawMappedPatch(x+facerank->leftoffset, y-4+facerank->topoffset, 0, facerank, colormap);
/*if (gametype == GT_BATTLE && players[tab[i].num].bumper > 0) -- not enough space for this
/*if ((gametyperules & GTR_BUMPERS) && players[tab[i].num].bumper > 0) -- not enough space for this
{
INT32 bumperx = x+19;
V_DrawMappedPatch(bumperx-2, y-4, 0, kp_tinybumper[0], colormap);
@ -2546,7 +2546,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
V_DrawScaledPatch(x+highlight->leftoffset, y-4+highlight->topoffset, 0, highlight);
}
if (gametype == GT_BATTLE && players[tab[i].num].bumper <= 0)
if ((gametyperules & GTR_BUMPERS) && players[tab[i].num].bumper <= 0)
V_DrawScaledPatch(x-4, y-7, 0, kp_ranknobumpers);
else
{
@ -2692,7 +2692,7 @@ static void K_drawKartAccessibilityIcons(INT32 fx)
if ((cv_newspeedometer.value == 0 || cv_newspeedometer.value == 2) && !K_RingsActive())
fy += 18;
if (gametype == GT_BATTLE)
if ((gametyperules & GTR_BUMPERS) && !(gametyperules & GTR_CIRCUIT))
fy -= 4;
}
}
@ -2783,7 +2783,7 @@ static void K_drawKartSpeedometer(void)
if (cv_speed_xoffset.value == 0 && cv_speed_yoffset.value == 0)
{
if (gametype == GT_BATTLE)
if ((gametyperules & GTR_BUMPERS) && !(gametyperules & GTR_CIRCUIT))
battleoffset = -4;
if (K_RingsActive() == true)
@ -2912,7 +2912,7 @@ static void K_drawRingMeter(void)
if (cv_speed_xoffset.value == 0 && cv_speed_yoffset.value == 0)
{
if (gametype == GT_BATTLE)
if ((gametyperules & GTR_BUMPERS) && !(gametyperules & GTR_CIRCUIT))
ringoffsety -= 4;
if (itembreaker)
@ -3134,6 +3134,10 @@ static void K_drawKartWanted(void)
else if (!r_splitscreen)
{
basex -= 48;
// Position Number offset....
if (gametyperules & GTR_CIRCUIT)
basex -= 30;
}
}
else if (r_splitscreen == 3) // 4P splitscreen...
@ -4166,7 +4170,7 @@ static void K_drawKartMinimap(void)
// Target reticule
if ((gametype == GT_RACE && players[i].position == spbplace)
|| (gametype == GT_BATTLE && K_IsPlayerWanted(&players[i])))
|| ((gametyperules & GTR_WANTED) && K_IsPlayerWanted(&players[i])))
{
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, NULL);
}
@ -4422,7 +4426,7 @@ static void K_drawKartMinimap(void)
// Target reticule
if ((gametype == GT_RACE && players[localplayers[i]].position == spbplace)
|| (gametype == GT_BATTLE && K_IsPlayerWanted(&players[localplayers[i]])))
|| ((gametyperules & GTR_WANTED) && K_IsPlayerWanted(&players[localplayers[i]])))
{
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, NULL);
}
@ -5528,7 +5532,7 @@ static void K_DrawClusterDebugger(void)
INT32 vflags = V_6WIDTHSPACE|V_ALLOWLOWERCASE;
if (K_UsingLegacyCheckpoints() && !(gametype == GT_BATTLE))
if (K_UsingLegacyCheckpoints())
{
V_DrawThinString(8, 136, vflags, va("Cluster player: %s", player_names[clusterid]));
V_DrawThinString(8, 146, vflags, va("X: %f, Y: %f, Z: %f, Dist. from cluster: %d", FIXED_TO_FLOAT(clusterpoint.x), FIXED_TO_FLOAT(clusterpoint.y), FIXED_TO_FLOAT(clusterpoint.z), stplyr->distancefromcluster));
@ -5587,7 +5591,7 @@ void K_drawKartHUD(void)
K_drawKartNameTags();
// Draw WANTED status
if (gametype == GT_BATTLE)
if (gametyperules & GTR_WANTED)
{
if (LUA_HudEnabled(hud_wanted))
K_drawKartWanted();
@ -5672,7 +5676,7 @@ void K_drawKartHUD(void)
{
K_drawBossHealthBar();
}
else if (gametype == GT_RACE) // Race-only elements (not currently gametyperuleable)
else if (gametyperules & GTR_CIRCUIT) // Race-only elements
{
if (!islonesome)
{
@ -5752,7 +5756,7 @@ void K_drawKartHUD(void)
if (modeattacking || freecam) // everything after here is MP and debug only
return;
if (gametype == GT_BATTLE && !r_splitscreen && (stplyr->karthud[khud_yougotem] % 2)) // * YOU GOT EM *
if ((gametyperules & GTR_KARMA) && !r_splitscreen && (stplyr->karthud[khud_yougotem] % 2)) // * YOU GOT EM *
V_DrawScaledPatch(BASEVIDWIDTH/2 - (kp_yougotem->width/2), 32, V_HUDTRANS, kp_yougotem);
// Draw FREE PLAY.

View file

@ -940,9 +940,8 @@ static void K_UpdateDraft(player_t *player)
minDist = cv_kartdrafting_closedeadzone.value * player->mo->scale;
if (gametype == GT_BATTLE)
if (gametyperules & GTR_CLOSERPLAYERS)
{
// TODO: gametyperules
minDist /= 4;
draftdistance *= 2;
leniency *= 4;
@ -1036,9 +1035,8 @@ static void K_UpdateDraft(player_t *player)
fixed_t add = (FRACUNIT/200) + ((9 - player->kartspeed+(player->kartspeed/3)) * ((3*FRACUNIT)/1600));
player->draftpower += add;
if (gametype == GT_BATTLE)
if (gametyperules & GTR_CLOSERPLAYERS)
{
// TODO: gametyperules
// Double gain in Battle
player->draftpower += add;
}
@ -2358,7 +2356,7 @@ UINT16 K_GetInvincibilityTime(player_t *player)
return BASEINVINTIME;
}
if (K_UsingLegacyCheckpoints() && !(gametype == GT_BATTLE))
if (K_UsingLegacyCheckpoints())
{
// Legacy waypointing is janky and finicky, so tack on a safety-net multiplier.
// If an invincible player gets ahead of the cluster player, bottlenecking activates
@ -7193,7 +7191,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->eggmanexplode)
{
if (player->spectator || (gametype == GT_BATTLE && !player->bumper))
if (player->spectator || ((gametyperules & GTR_BUMPERS) && !player->bumper))
player->eggmanexplode = 0;
else
{
@ -9232,7 +9230,7 @@ static UINT32 K_UpdateDistanceFromCluster(player_t *player)
tinypoptarget = (pingame < 3) ? first : second;
if (K_UsingLegacyCheckpoints() && !(gametype == GT_BATTLE))
if (K_UsingLegacyCheckpoints())
{
// Compare yourself against the cluster player to determine the distance.
@ -9604,7 +9602,7 @@ static vector3_t *K_FindPlayerCluster(fixed_t eps, INT32 (*func)(player_t *, fix
void K_UpdateClusterPoints(void)
{
// Get the player cluster.
if (K_UsingLegacyCheckpoints() && !(gametype == GT_BATTLE))
if (K_UsingLegacyCheckpoints())
{
K_FindPlayerClusterLegacy();
}
@ -9643,7 +9641,7 @@ void K_UpdateAllPlayerPositions(void)
{
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
{
if (K_UsingLegacyCheckpoints() && !(gametype == GT_BATTLE))
if (K_UsingLegacyCheckpoints())
K_KartLegacyUpdatePosition(&players[i]);
else
K_KartUpdatePosition(&players[i]);
@ -10090,10 +10088,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
{
if ((buttons & BT_ATTACK) && (player->itemflags & IF_HOLDREADY))
{
// TODO: gametyperules
const SINT8 incr = gametype == GT_BATTLE ? 3 : 2;
const SINT8 metincr = gametype == GT_BATTLE ? 4 : 3;
const SINT8 comincr = gametype == GT_BATTLE ? 10 : 4;
const SINT8 incr = (gametyperules & GTR_CLOSERPLAYERS) ? 3 : 2;
const SINT8 metincr = (gametyperules & GTR_CLOSERPLAYERS) ? 4 : 3;
const SINT8 comincr = (gametyperules & GTR_CLOSERPLAYERS) ? 10 : 4;
if (player->flamestore == 0)
{
@ -10480,8 +10477,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->mo->destscale = FixedMul(player->mo->destscale, SHRINK_SCALE);
}
// TODO: gametyperules
player->growshrinktimer = (gametype == GT_BATTLE ? 8 : 12) * TICRATE;
player->growshrinktimer = (gametyperules & GTR_CLOSERPLAYERS ? 8 : 12) * TICRATE;
if (player->invincibilitytimer > 0)
{
@ -10742,14 +10738,14 @@ bubbledeflate:
player->mo->renderflags &= ~RF_DONTDRAW;
}
if (gametype == GT_BATTLE && player->bumper <= 0) // dead in match? you da bomb
if ((gametyperules & GTR_KARMA) && player->bumper <= 0) // dead in match? you da bomb
{
K_DropItems(player); //K_StripItems(player);
K_StripOther(player);
player->mo->renderflags |= RF_GHOSTLY;
player->flashing = player->karmadelay;
}
else if (gametype == GT_RACE || player->bumper > 0)
else if ((player->bumper > 0) || ((gametyperules & GTR_CIRCUIT) && !(gametyperules & GTR_KARMA)))
{
player->mo->renderflags &= ~(RF_TRANSMASK|RF_BRIGHTMASK);
}

View file

@ -9324,7 +9324,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
statenum_t state = (mobj->state-states);
if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator
|| (gametyperules & GTR_CIRCUIT || mobj->target->player->bumper))
|| mobj->target->player->bumper || !(gametyperules & GTR_KARMA))
{
P_RemoveMobj(mobj);
return false;
@ -12115,7 +12115,7 @@ void P_RespawnSpecials(void)
INT32 time = 30*TICRATE; // Respawn things in empty dedicated servers
mapthing_t *mthing = NULL;
if (gametype == GT_BATTLE && numgotboxes >= (4*nummapboxes/5) && !itembreaker) // Battle Mode respawns all boxes in a different way
if ((gametyperules & GTR_BATTLEBOXES) && numgotboxes >= (4*nummapboxes/5) && !itembreaker) // Battle Mode respawns all boxes in a different way
{
thinker_t *th;