Merge branch 'toast-micro' into 'master'

Assorted minor fixes

See merge request kart-krew-dev/ring-racers-internal!2779
This commit is contained in:
Oni VelocitOni 2025-08-29 02:43:10 +00:00
commit ca8e46b0ea
12 changed files with 164 additions and 118 deletions

View file

@ -910,7 +910,7 @@ void F_IntroTicker(void)
ResetSkipSequences();
CV_StealthSetValue(&cv_kartbot, 9);
CV_StealthSetValue(&cv_maxplayers, 8);
D_MapChange(G_RandMap(TOL_RACE, UINT16_MAX-1, true, false, NULL), GT_RACE, (cv_kartencore.value == 1), true, 0, false, false);
D_MapChange(G_RandMap(TOL_RACE, UINT16_MAX-1, true, false, NULL)+1, GT_RACE, (cv_kartencore.value == 1), true, 0, false, false);
return;
}
@ -1118,7 +1118,7 @@ boolean F_IntroResponder(event_t *event)
}
// Quick skips for development/testing. See F_IntroTicker.
if (!demo.playback)
if (!demo.playback && skippableallowed)
{
switch(key)
{

View file

@ -49,6 +49,7 @@
#include "md5.h" // demo checksums
#include "p_saveg.h" // savebuffer_t
#include "g_party.h"
#include "k_director.h" // K_DirectorIsEnabled
#include "core/json.hpp"
// SRB2Kart
@ -4315,7 +4316,11 @@ boolean G_CheckDemoTitleEntry(void)
if (menuactive || chat_on)
return false;
if (!G_PlayerInputDown(0, gc_b, 0) && !G_PlayerInputDown(0, gc_x, 0))
// Input conflict
if (gamestate == GS_LEVEL && camera[0].freecam)
return false;
if (!G_PlayerInputDown(0, gc_b, 0))
return false;
demo.willsave = true;

View file

@ -3932,7 +3932,11 @@ tryAgain:
continue;
}
if (numPlayers == 2 && gametype == GT_RACE && ((mapheaderinfo[i]->levelflags & LF_SECTIONRACE) == LF_SECTIONRACE))
// TODO - We don't have guaranteed access to gametype/rules of TOL.
// If revising in future and willing to break this function open,
// this should be checking for GTR_CIRCUIT and not cooperative
// (but K_Cooperative also won't be correct inside this func).
if (numPlayers == 2 && gametype != GT_SPECIAL && ((mapheaderinfo[i]->levelflags & LF_SECTIONRACE) == LF_SECTIONRACE))
{
// Duel doesn't support sprints.
continue;

View file

@ -6448,7 +6448,7 @@ static void K_drawKartMinimap(void)
}
}
if (gametype == GT_BATTLE && Obj_GetNextUFOSpawner() != NULL)
if ((gametyperules & GTR_PAPERITEMS) && Obj_GetNextUFOSpawner() != NULL)
{
const INT32 prevsplitflags = splitflags;
mobj_t *spawner = Obj_GetNextUFOSpawner();

View file

@ -3119,7 +3119,7 @@ fixed_t K_PlayerTripwireSpeedThreshold(const player_t *player)
UINT32 distance = K_GetItemRouletteDistance(player, 8);
if (gametype == GT_RACE && M_NotFreePlay() && !modeattacking)
if ((gametyperules & GTR_CIRCUIT) && !K_Cooperative() && M_NotFreePlay() && !modeattacking)
{
if (distance < SCAMDIST) // Players near 1st need more speed!
{
@ -3401,58 +3401,64 @@ void K_SpawnWaterRunParticles(mobj_t *mobj)
y2 = y2 + P_ReturnThrustY(mobj, forwardangle, playerVisualRadius);
// Left
// underlay
water = P_SpawnMobj(x1, y1,
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY);
water->angle = forwardangle - ANGLE_180 - ANGLE_22h;
water->destscale = trailScale;
water->momx = mobj->momx;
water->momy = mobj->momy;
water->momz = mobj->momz;
P_SetScale(water, trailScale);
P_SetMobjState(water, curUnderlayFrame);
P_SetTarget(&water->owner, mobj);
water->renderflags |= RF_REDUCEVFX;
if (!mobj->player || mobj->player->aizdriftstrat <= 0)
{
// underlay
water = P_SpawnMobj(x1, y1,
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY);
water->angle = forwardangle - ANGLE_180 - ANGLE_22h;
water->destscale = trailScale;
water->momx = mobj->momx;
water->momy = mobj->momy;
water->momz = mobj->momz;
P_SetScale(water, trailScale);
P_SetMobjState(water, curUnderlayFrame);
P_SetTarget(&water->owner, mobj);
water->renderflags |= RF_REDUCEVFX;
// overlay
water = P_SpawnMobj(x1, y1,
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL);
water->angle = forwardangle - ANGLE_180 - ANGLE_22h;
water->destscale = trailScale;
water->momx = mobj->momx;
water->momy = mobj->momy;
water->momz = mobj->momz;
P_SetScale(water, trailScale);
P_SetMobjState(water, curOverlayFrame);
P_SetTarget(&water->owner, mobj);
water->renderflags |= RF_REDUCEVFX;
// overlay
water = P_SpawnMobj(x1, y1,
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL);
water->angle = forwardangle - ANGLE_180 - ANGLE_22h;
water->destscale = trailScale;
water->momx = mobj->momx;
water->momy = mobj->momy;
water->momz = mobj->momz;
P_SetScale(water, trailScale);
P_SetMobjState(water, curOverlayFrame);
P_SetTarget(&water->owner, mobj);
water->renderflags |= RF_REDUCEVFX;
}
// Right
// Underlay
water = P_SpawnMobj(x2, y2,
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY);
water->angle = forwardangle - ANGLE_180 + ANGLE_22h;
water->destscale = trailScale;
water->momx = mobj->momx;
water->momy = mobj->momy;
water->momz = mobj->momz;
P_SetScale(water, trailScale);
P_SetMobjState(water, curUnderlayFrame);
P_SetTarget(&water->owner, mobj);
water->renderflags |= RF_REDUCEVFX;
if (!mobj->player || mobj->player->aizdriftstrat >= 0)
{
// Underlay
water = P_SpawnMobj(x2, y2,
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY);
water->angle = forwardangle - ANGLE_180 + ANGLE_22h;
water->destscale = trailScale;
water->momx = mobj->momx;
water->momy = mobj->momy;
water->momz = mobj->momz;
P_SetScale(water, trailScale);
P_SetMobjState(water, curUnderlayFrame);
P_SetTarget(&water->owner, mobj);
water->renderflags |= RF_REDUCEVFX;
// Overlay
water = P_SpawnMobj(x2, y2,
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL);
water->angle = forwardangle - ANGLE_180 + ANGLE_22h;
water->destscale = trailScale;
water->momx = mobj->momx;
water->momy = mobj->momy;
water->momz = mobj->momz;
P_SetScale(water, trailScale);
P_SetMobjState(water, curOverlayFrame);
P_SetTarget(&water->owner, mobj);
water->renderflags |= RF_REDUCEVFX;
// Overlay
water = P_SpawnMobj(x2, y2,
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL);
water->angle = forwardangle - ANGLE_180 + ANGLE_22h;
water->destscale = trailScale;
water->momx = mobj->momx;
water->momy = mobj->momy;
water->momz = mobj->momz;
P_SetScale(water, trailScale);
P_SetMobjState(water, curOverlayFrame);
P_SetTarget(&water->owner, mobj);
water->renderflags |= RF_REDUCEVFX;
}
if (!S_SoundPlaying(mobj, sfx_s3kdbs))
{
@ -4618,7 +4624,7 @@ static void K_HandleRaceSplits(player_t *player, tic_t time, UINT8 checkpoint)
void K_CheckpointCrossAward(player_t *player)
{
if (gametype != GT_RACE)
if (!(gametyperules & GTR_CIRCUIT) || K_Cooperative())
return;
if (!demo.playback && G_TimeAttackStart())
@ -10578,7 +10584,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->follower && fls >= 0 && fls < numfollowers)
{
const follower_t *fl = &followers[fls];
S_StartSound(NULL, fl->hornsound);
S_StartSound(player->follower, fl->hornsound);
}
S_StartSound(player->mo, sfx_kc33);

View file

@ -2383,7 +2383,9 @@ void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p)
if (p != NULL)
{
V_DrawFixedPatch((x+30)*FRACUNIT, (y+84)*FRACUNIT, FRACUNIT, 0, pwrlv, colormap);
V_DrawCenteredTimerString(x+30, y+87, 0, va("%d", p->wins));
K_DrawGameControl(x+30, y+87, 0, va("%d", p->wins), 1,
(p->wins >= 1000 ? TINYTIMER_FONT : TIMER_FONT),
0);
}
@ -6424,11 +6426,11 @@ void M_DrawPause(void)
K_DrawGameControl(4, 184 - 60 + offset/2, 0, "<left> <right> <up> <down> Steering", 0, TINY_FONT, 0);
K_DrawGameControl(4, 184 - 45 + offset/2, 0, "<a> Accelerate", 0, TINY_FONT, 0);
K_DrawGameControl(4, 184 - 30 + offset/2, 0, "<b> Look Back", 0, TINY_FONT, 0);
K_DrawGameControl(4, 184 - 15 + offset/2, 0, "<c> Spindash", 0, TINY_FONT, 0);
K_DrawGameControl(4, 184 - 0 + offset/2, 0, "<l> Item/Rings", 0, TINY_FONT, 0);
K_DrawGameControl(4, 184 - 15 + offset/2, 0, "<c> Spin Dash", 0, TINY_FONT, 0);
K_DrawGameControl(4, 184 - 0 + offset/2, 0, "<l> Item / Rings", 0, TINY_FONT, 0);
K_DrawGameControl(90, 184 - 45 + offset/2, 0, "<x> Brake", 0, TINY_FONT, 0);
K_DrawGameControl(90, 184 - 30 + offset/2, 0, "<y> Respawn", 0, TINY_FONT, 0);
K_DrawGameControl(90, 184 - 30 + offset/2, 0, "<y> Bail / Burst", 0, TINY_FONT, 0);
K_DrawGameControl(90, 184 - 15 + offset/2, 0, "<z> Dialogue / Action", 0, TINY_FONT, 0);
K_DrawGameControl(90, 184 - 0 + offset/2, 0, "<r> Drift", 0, TINY_FONT, 0);
}
@ -8763,6 +8765,7 @@ static void M_DrawStatsMaps(void)
i = -1;
const boolean allowsealed = M_SecretUnlocked(SECRET_SPECIALATTACK, true);
const boolean allowencore = M_SecretUnlocked(SECRET_ENCORE, true);
const boolean allowspb = M_SecretUnlocked(SECRET_SPBATTACK, true);
boolean allowtime = false;
@ -8790,7 +8793,11 @@ static void M_DrawStatsMaps(void)
if (mapheaderinfo[mnum]->typeoflevel & TOL_TUTORIAL)
str = "TUTORIAL MODE";
else if (mapheaderinfo[mnum]->cup)
else if (mapheaderinfo[mnum]->cup
&& (!(mapheaderinfo[mnum]->typeoflevel & TOL_SPECIAL) // not special
|| gamedata->sealedswaps[GDMAX_SEALEDSWAPS-1] != NULL // all found
|| mapheaderinfo[mnum]->cup->id >= basenumkartcupheaders // custom content
|| allowsealed)) // true order
str = va("%s CUP", mapheaderinfo[mnum]->cup->realname);
else
str = "LOST & FOUND";

View file

@ -26,7 +26,20 @@ static boolean M_StatisticsAddMap(UINT16 map, cupheader_t *cup, boolean *headere
if (!mapheaderinfo[map])
return false;
if (mapheaderinfo[map]->cup != cup)
if (mapheaderinfo[map]->typeoflevel & TOL_SPECIAL)
{
if (gamedata->sealedswaps[GDMAX_SEALEDSWAPS-1] != NULL // all found
|| (mapheaderinfo[map]->cup
&& mapheaderinfo[map]->cup->id >= basenumkartcupheaders) // custom content
|| M_SecretUnlocked(SECRET_SPECIALATTACK, true)) // true order
{
if (mapheaderinfo[map]->cup != cup)
return false;
}
else if (cup) // Appear under Lost & Found until you've ordered them.
return false;
}
else if (mapheaderinfo[map]->cup != cup)
return false;
if (((mapheaderinfo[map]->typeoflevel & TOL_TUTORIAL) == TOL_TUTORIAL) != tutorial)

View file

@ -1603,6 +1603,8 @@ void M_GonerPlayground(INT32 choice)
multiplayer = true;
levellist.newgametype = GT_TUTORIAL;
levellist.netgame = false;
M_MenuToLevelPreamble(0, false);
D_MapChange(

View file

@ -584,7 +584,11 @@ void Obj_CheckpointThink(mobj_t* end)
void Obj_CrossCheckpoints(player_t* player, fixed_t old_x, fixed_t old_y)
{
if (player->exiting || player->laps == 0) // can't cross checkpoints when exiting, or before the first lap starts
if (player->exiting
|| (
(gametyperules & GTR_CIRCUIT)
&& (player->laps == 0)
))
{
return;
}

View file

@ -1922,6 +1922,44 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
}
}
if (target->player->spectator == false)
{
UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[(target->player-players)]].flags
: skins[target->player->skin]->flags;
if (skinflags & SF_IRONMAN)
{
target->skin = skins[target->player->skin];
target->player->charflags = skinflags;
K_SpawnMagicianParticles(target, 5);
S_StartSound(target, sfx_slip);
}
target->renderflags &= ~RF_DONTDRAW;
}
K_DropEmeraldsFromPlayer(target->player, target->player->emeralds);
target->player->carry = CR_NONE;
K_KartResetPlayerColor(target->player);
P_ResetPlayer(target->player);
#define PlayerPointerRemove(field) \
if (P_MobjWasRemoved(field) == false) \
{ \
P_RemoveMobj(field); \
P_SetTarget(&field, NULL); \
}
PlayerPointerRemove(target->player->stumbleIndicator);
PlayerPointerRemove(target->player->wavedashIndicator);
PlayerPointerRemove(target->player->trickIndicator);
#undef PlayerPointerRemove
if (gametyperules & GTR_BUMPERS)
{
if (battleovertime.enabled >= 10*TICRATE) // Overtime Barrier is armed
@ -2684,7 +2722,6 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
if (modeattacking & ATTACKING_SPB)
{
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
return true;
}
@ -2700,6 +2737,9 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
// disappearifies, but still gotta put items back in play
break;
case DMG_TIMEOVER:
player->pflags |= PF_ELIMINATED;
//FALLTHRU
default:
// Everything else REALLY kills
if (leveltime < starttime)
@ -2709,52 +2749,6 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
break;
}
if (player->spectator == false)
{
UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[(player-players)]].flags
: skins[player->skin]->flags;
if (skinflags & SF_IRONMAN)
{
player->mo->skin = skins[player->skin];
player->charflags = skinflags;
K_SpawnMagicianParticles(player->mo, 5);
S_StartSound(player->mo, sfx_slip);
}
player->mo->renderflags &= ~RF_DONTDRAW;
}
K_DropEmeraldsFromPlayer(player, player->emeralds);
//K_SetHitLagForObjects(player->mo, inflictor, source, MAXHITLAGTICS, true);
player->carry = CR_NONE;
K_KartResetPlayerColor(player);
P_ResetPlayer(player);
P_SetPlayerMobjState(player->mo, player->mo->info->deathstate);
#define PlayerPointerRemove(field) \
if (P_MobjWasRemoved(field) == false) \
{ \
P_RemoveMobj(field); \
P_SetTarget(&field, NULL); \
}
PlayerPointerRemove(player->stumbleIndicator);
PlayerPointerRemove(player->wavedashIndicator);
PlayerPointerRemove(player->trickIndicator);
#undef PlayerPointerRemove
if (type == DMG_TIMEOVER)
{
player->pflags |= PF_ELIMINATED;
}
return true;
}

View file

@ -34,7 +34,7 @@
#include "p_setup.h" // NiGHTS grading
#include "r_fps.h"
#include "m_random.h" // random index
#include "m_cond.h" // item finder
#include "k_director.h" // K_DirectorIsEnabled
#ifdef HWRENDER
#include "hardware/hw_main.h"
@ -1498,11 +1498,22 @@ void ST_DrawServerSplash(boolean timelimited)
void ST_DrawSaveReplayHint(INT32 flags)
{
K_DrawGameControl(
BASEVIDWIDTH - 2, 2, 0,
(demo.willsave && demo.titlename[0]) ? "Replay will be saved. <b> Change title" : "<b> or <x> Save replay",
2, TINY_FONT, flags|V_YELLOWMAP
);
const char *text;
if (gamestate == GS_LEVEL && camera[0].freecam)
{
text = va(
"<c> Disable Freecam to <b_pressed> %s replay",
(demo.willsave && demo.titlename[0])
? "rename"
: "save"
);
}
else if (demo.willsave && demo.titlename[0])
text = "Replay will be saved. <b> Change title";
else
text = "<b> Save replay";
K_DrawGameControl(BASEVIDWIDTH - 2, 2, 0, text, 2, TINY_FONT, flags|V_YELLOWMAP);
}
static fixed_t ST_CalculateFadeIn(player_t *player)

View file

@ -1070,7 +1070,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
c &= 255;
RGBA_t color = pMasterPalette[c];
RGBA_t color = pLocalPalette[c];
UINT8 r = (color.rgba & 0xFF);
UINT8 g = (color.rgba & 0xFF00) >> 8;
UINT8 b = (color.rgba & 0xFF0000) >> 16;
@ -1262,7 +1262,7 @@ void V_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 c)
{
auto builder = g_2d.begin_verts();
const RGBA_t color = pMasterPalette[c];
const RGBA_t color = pLocalPalette[c];
const float r = ((color.rgba & 0xFF000000) >> 24) / 255.f;
const float g = ((color.rgba & 0xFF0000) >> 16) / 255.f;
const float b = ((color.rgba & 0xFF00) >> 8) / 255.f;