Merge branch 'really-relaxed' into 'master'

No lives in Relaxed

See merge request kart-krew-dev/ring-racers-internal!2683
This commit is contained in:
Oni VelocitOni 2025-07-19 00:19:22 +00:00
commit d964b66ca8
11 changed files with 115 additions and 43 deletions

View file

@ -3257,7 +3257,7 @@ void G_BeginLevelExit(void)
g_exit.losing = true;
g_exit.retry = false;
if (!G_GametypeAllowsRetrying() || skipstats != 0)
if (!G_GametypeAllowsRetrying() || skipstats != 0 || (grandprixinfo.gp && grandprixinfo.gamespeed == KARTSPEED_EASY))
{
g_exit.losing = false; // never force a retry
}
@ -3618,7 +3618,7 @@ boolean G_GametypeUsesLives(void)
if (modeattacking) // NOT in Record Attack
return false;
if (grandprixinfo.gp == true) // In Grand Prix
if (grandprixinfo.gp == true && grandprixinfo.gamespeed != KARTSPEED_EASY) // In Grand Prix
return true;
return false;
@ -4738,7 +4738,7 @@ static void G_DoCompleted(void)
}
}
if (grandprixinfo.gp == true && grandprixinfo.wonround == true && player->exiting && !retrying)
if (grandprixinfo.gp == true && grandprixinfo.wonround == true && player->exiting && (!retrying || grandprixinfo.gamespeed == KARTSPEED_EASY))
{
if (player->bot == true)
{

View file

@ -692,7 +692,7 @@ fixed_t K_BotRubberband(const player_t *player)
// mechanics adjustments, not from items, so kill some bot speed if they've got bad EXP.
if (player->gradingfactor < FRACUNIT && !(player->botvars.rival) && player->botvars.difficulty > 1)
{
UINT8 levelreduce = std::min<UINT8>(3, player->botvars.difficulty); // How much to drop the "effective level" of bots that are consistently behind
UINT8 levelreduce = std::min<UINT8>(3, player->botvars.difficulty/4); // How much to drop the "effective level" of bots that are consistently behind
expreduce = Easing_Linear((K_EffectiveGradingFactor(player) - MINGRADINGFACTOR) * 2, levelreduce*FRACUNIT, 0);
}
@ -704,11 +704,11 @@ fixed_t K_BotRubberband(const player_t *player)
if (cv_levelskull.value)
difficultyEase = FRACUNIT;
// Lv. 1: x0.65 avg
// Lv. 1: x0.75 avg
// Lv. MAX: x1.05 avg
const fixed_t rubberBase = Easing_OutSine(
difficultyEase,
FRACUNIT * 65 / 100,
FRACUNIT * 75 / 100,
FRACUNIT * 105 / 100
);

View file

@ -389,8 +389,9 @@ void K_UpdateGrandPrixBots(void)
if (players[i].botvars.diffincrease)
{
// CONS_Printf("in %d inc %d", players[i].botvars.difficulty, players[i].botvars.diffincrease);
if (players[i].botvars.diffincrease < 0)
players[i].botvars.difficulty = std::max(1, players[i].botvars.difficulty - players[i].botvars.diffincrease);
players[i].botvars.difficulty = std::max(1, players[i].botvars.difficulty + players[i].botvars.diffincrease);
else
players[i].botvars.difficulty += players[i].botvars.diffincrease;
@ -400,6 +401,7 @@ void K_UpdateGrandPrixBots(void)
}
players[i].botvars.diffincrease = 0;
// CONS_Printf("out %d\n", players[i].botvars.difficulty);
}
if (players[i].botvars.rival)
@ -630,13 +632,37 @@ void K_IncreaseBotDifficulty(player_t *bot)
rankNudge = 0;
break;
case GRADE_A:
if (grandprixinfo.gp && grandprixinfo.gamespeed == KARTSPEED_EASY)
rankNudge = 0;
else
rankNudge = 1;
rankNudge = 1;
break;
}
// RELAXED MODE:
// Continues don't drop bot difficulty, because we always advance.
// Bots will still level up from standard advancement; we need a
// much steeper rank nudge to keep difficulty at the right level.
if (grandprixinfo.gamespeed == KARTSPEED_EASY)
{
switch(averageRank)
{
case GRADE_E:
rankNudge = -4;
break;
case GRADE_D:
rankNudge = -2;
break;
case GRADE_C:
rankNudge = -1;
break;
case GRADE_B:
rankNudge = 0;
break;
case GRADE_A:
rankNudge = 1;
break;
}
}
increase += rankNudge;
if (increase <= 0)

View file

@ -533,6 +533,14 @@ fixed_t K_GetKartGameSpeedScalar(SINT8 value)
fixed_t base = ((13 + (3*value)) << FRACBITS) / 16;
fixed_t duel = overtimecheckpoints*(1<<FRACBITS)/32;
if (gametyperules & GTR_CIRCUIT && gametype != GT_TUTORIAL)
{
if (value == KARTSPEED_EASY)
{
base = 9*FRACUNIT/10;
}
}
return base + duel;
}
@ -3549,7 +3557,15 @@ static void K_GetKartBoostPower(player_t *player)
{
// Light weights have stronger boost stacking -- aka, better metabolism than heavies XD
const fixed_t maxmetabolismincrease = FRACUNIT/2;
const fixed_t metabolism = FRACUNIT - ((9-player->kartweight) * maxmetabolismincrease / 8);
fixed_t metabolism = FRACUNIT - ((9-player->kartweight) * maxmetabolismincrease / 8);
fixed_t softboostcap = 0;
fixed_t boostcapfactor = 3*FRACUNIT/4;
if (gamespeed == KARTSPEED_EASY && gametype != GT_TUTORIAL)
{
metabolism *= 2;
softboostcap = FRACUNIT/2;
}
fixed_t boostpower = FRACUNIT;
fixed_t speedboost = 0, accelboost = 0, handleboost = 0;
@ -3858,6 +3874,13 @@ static void K_GetKartBoostPower(player_t *player)
player->boostpower = boostpower;
// G1 race: Reduce high boosts
if (softboostcap && speedboost > softboostcap)
{
fixed_t leftover = speedboost - softboostcap;
speedboost = softboostcap + FixedMul(leftover, boostcapfactor);
}
// value smoothing
if (speedboost > player->speedboost)
{
@ -4247,6 +4270,9 @@ boolean K_PvPAmpReward(UINT32 award, player_t *attacker, player_t *defender)
award -= (delta * award / range / 2);
}
if (!K_PlayerUsesBotMovement(attacker) && K_PlayerUsesBotMovement(defender))
award /= 2;
return award;
}

View file

@ -646,6 +646,9 @@ fixed_t K_CalculateGPPercent(gpRank_t *rankData)
rankData->scoreRings +
rankData->scoreContinues;
if (rankData->scoreTotal < 0)
rankData->scoreTotal = 0;
const fixed_t percent = FixedDiv(rankData->scoreTotal, total);
return percent;

View file

@ -1152,6 +1152,10 @@ static boolean K_ShouldPlayerAllowItem(kartitems_t item, const player_t *player)
if (K_EffectiveGradingFactor(player) < K_RequiredXPForItem(item))
return false;
// Expert items are G2+ only, no Top in Relaxed!
if (K_RequiredXPForItem(item) >= FRACUNIT && gamespeed == KARTSPEED_EASY)
return false;
return !K_IsItemFirstOnly(item);
}
}

View file

@ -618,7 +618,8 @@ boolean level_tally_t::IncrementLine(void)
value = &displayStat[i];
lives_check = (
stats[i] == TALLY_STAT_TOTALRINGS // Rings also shows the Lives.
G_GametypeUsesLives()
&& stats[i] == TALLY_STAT_TOTALRINGS // Rings also shows the Lives.
&& livesAdded < owner->xtralife // Don't check if we've maxxed out!
);
@ -849,6 +850,7 @@ void level_tally_t::Tick(void)
if (IncrementLine() == true)
{
if (grandprixinfo.gp == true // In GP
&& G_GametypeUsesLives()
&& lines >= lineCount // Finished the bonuses
&& livesAdded < owner->xtralife // Didn't max out by other causes
)
@ -1294,41 +1296,44 @@ void level_tally_t::Draw(void)
case TALLY_STAT_TOTALRINGS:
{
drawer_text
.x(184.0 * frac)
.x((G_GametypeUsesLives() ? 184.0 : 200.0) * frac)
.align(srb2::Draw::Align::kCenter)
.text(va("%d", displayStat[i]));
srb2::Draw lives_drawer = drawer_text
.xy(221.0 * frac, -1.0 * frac);
const skincolornum_t color = static_cast<skincolornum_t>(owner->skincolor);
lives_drawer
.x(r_splitscreen ? -7.0 : -2.0)
.colormap(owner->skin, color)
.patch(faceprefix[owner->skin][r_splitscreen ? FACE_MINIMAP : FACE_RANK]);
UINT8 lives_num = std::min(owner->lives + livesAdded, 10);
if (xtraBlink > 0 && (xtraBlink & 1) == 0 && livesAdded > 0)
if (G_GametypeUsesLives())
{
lives_num = 0;
}
srb2::Draw lives_drawer = drawer_text
.xy(221.0 * frac, -1.0 * frac);
if (lives_num > 0)
{
if (r_splitscreen)
const skincolornum_t color = static_cast<skincolornum_t>(owner->skincolor);
lives_drawer
.x(r_splitscreen ? -7.0 : -2.0)
.colormap(owner->skin, color)
.patch(faceprefix[owner->skin][r_splitscreen ? FACE_MINIMAP : FACE_RANK]);
UINT8 lives_num = std::min(owner->lives + livesAdded, 10);
if (xtraBlink > 0 && (xtraBlink & 1) == 0 && livesAdded > 0)
{
lives_drawer = lives_drawer
.xy(6.0, 2.0)
.align(srb2::Draw::Align::kLeft);
}
else
{
lives_drawer = lives_drawer
.xy(17.0, 1.0)
.font(srb2::Draw::Font::kThinTimer);
lives_num = 0;
}
lives_drawer.text("{}", lives_num);
if (lives_num > 0)
{
if (r_splitscreen)
{
lives_drawer = lives_drawer
.xy(6.0, 2.0)
.align(srb2::Draw::Align::kLeft);
}
else
{
lives_drawer = lives_drawer
.xy(17.0, 1.0)
.font(srb2::Draw::Font::kThinTimer);
}
lives_drawer.text("{}", lives_num);
}
}
break;

View file

@ -188,10 +188,10 @@ void Dummygpdifficulty_OnChange(void)
switch (cv_dummygpdifficulty.value)
{
case KARTSPEED_EASY:
tooltip = "Low-stakes racing at \x83Gear 1""\x80"". Take a drive and \x83""enjoy the sights!";
tooltip = "Low-stakes racing at \x83Gear 1""\x80"". \x83No placement requirements\x80.";
break;
case KARTSPEED_NORMAL:
tooltip = "Aim for the prize at\x82 Gear 2\x80. Can you \x82surpass your limits?";
tooltip = "Aim for the prize at\x82 Gear 2\x80. Place \x82""4th or better\x80 to advance!";
break;
case KARTSPEED_HARD:
tooltip = "Challenge fierce competition at\x87 Gear 3\x80. For\x87 thrill-seekers!";

View file

@ -1612,6 +1612,10 @@ boolean P_CheckRacers(void)
const boolean griefed = (spectateGriefed > 0);
boolean eliminateLast = (!K_CanChangeRules(true) || (cv_karteliminatelast.value != 0));
if (grandprixinfo.gp && grandprixinfo.gamespeed == KARTSPEED_EASY)
eliminateLast = false;
boolean allHumansDone = true;
//boolean allBotsDone = true;

View file

@ -55,6 +55,7 @@
#include "k_battle.h" // battleprisons
#include "k_endcam.h" // K_EndCameraIsFreezing()
#include "k_race.h" // K_SpawnFinishEXP
#include "k_grandprix.h" // grandprixinfo
// Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog
#include <errno.h>
@ -2076,6 +2077,8 @@ static void K_HandleLapIncrement(player_t *player)
{
S_StartSound(player->mo, sfx_s23c);
player->startboost = 125;
if (!K_PlayerUsesBotMovement(player) && grandprixinfo.gp)
player->startboost /= 2;
K_SpawnDriftBoostExplosion(player, 4);
K_SpawnDriftElectricSparks(player, SKINCOLOR_SILVER, false);

View file

@ -716,7 +716,8 @@ void P_EndingMusic(void)
{
jingle = "_lose";
if (G_GametypeAllowsRetrying() == true)
// Sort of ugly, this composite check is effictively "does gametype force retry": Relaxed allows you to place low.
if (G_GametypeAllowsRetrying() == true && !(grandprixinfo.gp && grandprixinfo.gamespeed == KARTSPEED_EASY && gametyperules & GTR_CIRCUIT))
{
// A retry will be happening
nointer = true;