Merge remote-tracking branch 'public/master'

This commit is contained in:
Eidolon 2025-09-30 17:37:01 -05:00
commit fa787c4e8f
15 changed files with 87 additions and 31 deletions

View file

@ -1129,6 +1129,8 @@ struct player_t
boolean dotrickfx;
boolean stingfx;
UINT8 bumperinflate;
boolean mfdfinish; // Did you cross the finish line while just about to explode?
UINT8 ringboxdelay; // Delay until Ring Box auto-activates
UINT8 ringboxaward; // Where did we stop?

View file

@ -1593,6 +1593,7 @@ void F_StartGameEnd(void)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
F_WipeEndScreen();
F_RunWipe(wipe_level_toblack, wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false);
Music_Stop("credits");
nextmap = NEXTMAP_TITLE;
G_EndGame();

View file

@ -2312,6 +2312,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
UINT16 bigwaypointgap;
INT16 duelscore;
boolean mfdfinish;
roundconditions_t roundconditions;
boolean saveroundconditions;
@ -2406,6 +2408,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
totalring = players[player].totalring;
xtralife = players[player].xtralife;
mfdfinish = players[player].mfdfinish;
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_AUTOROULETTE|PF_ANALOGSTICK|PF_AUTORING));
pflags2 = (players[player].pflags2 & (PF2_SELFMUTE | PF2_SELFDEAFEN | PF2_SERVERTEMPMUTE | PF2_SERVERMUTE | PF2_SERVERDEAFEN | PF2_STRICTFASTFALL));
@ -2483,6 +2487,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
lastsafecheatcheck = 0;
bigwaypointgap = 0;
duelscore = 0;
mfdfinish = 0;
finalized = false;
@ -2675,6 +2680,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->xtralife = xtralife;
p->finalized = finalized;
p->mfdfinish = mfdfinish;
// SRB2kart
p->itemtype = itemtype;

View file

@ -5183,7 +5183,7 @@ static void K_drawKartPlayerCheck(void)
continue;
}
if ((checkplayer->invincibilitytimer <= 0) && (leveltime & 2))
if ((checkplayer->invincibilitytimer <= 0) && (leveltime & 2) && !(cv_reducevfx.value))
{
pnum++; // white frames
}

View file

@ -10891,7 +10891,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
}
INT32 fls = K_GetEffectiveFollowerSkin(player);
if (player->follower && fls >= 0 && fls < numfollowers)
if (player->follower && fls >= 0 && fls < numfollowers && cv_karthorns.value)
{
const follower_t *fl = &followers[fls];
S_StartSound(player->follower, fl->hornsound);

View file

@ -423,8 +423,8 @@ static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t *
--------------------------------------------------*/
void K_RunFinishLineBeam(void)
{
if ((gametyperules & GTR_ROLLINGSTART) || !(leveltime < starttime || rainbowstartavailable == true))
{
if ((gametyperules & GTR_ROLLINGSTART) || !(leveltime < starttime || rainbowstartavailable == true) || P_LevelIsFrozen())
{
return;
}

View file

@ -269,6 +269,8 @@ static int player_get(lua_State *L)
lua_pushboolean(L, plr->transfer);
else if (fastcmp(field,"markedfordeath"))
lua_pushboolean(L, plr->markedfordeath);
else if (fastcmp(field,"mfdfinish"))
lua_pushboolean(L, plr->mfdfinish);
else if (fastcmp(field,"incontrol"))
lua_pushboolean(L, plr->incontrol);
else if (fastcmp(field,"progressivethrust"))
@ -950,6 +952,8 @@ static int player_set(lua_State *L)
plr->transfer = luaL_checkboolean(L, 3);
else if (fastcmp(field,"markedfordeath"))
plr->markedfordeath = luaL_checkboolean(L, 3);
else if (fastcmp(field,"mfdfinish"))
plr->mfdfinish = luaL_checkboolean(L, 3);
else if (fastcmp(field,"dotrickfx"))
plr->dotrickfx = luaL_checkboolean(L, 3);
else if (fastcmp(field,"stingfx"))

View file

@ -1797,7 +1797,7 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
case UCRP_PREFIX_BONUSROUND:
return ((grandprixinfo.gp == true) && (grandprixinfo.eventmode == GPEVENT_BONUS));
case UCRP_PREFIX_TIMEATTACK:
return (modeattacking != ATTACKING_NONE);
return (modeattacking != ATTACKING_NONE && !(skins[player->skin]->flags & SF_HIVOLT));
case UCRP_PREFIX_PRISONBREAK:
return ((gametyperules & GTR_PRISONS) && battleprisons);
case UCRP_PREFIX_SEALEDSTAR:

View file

@ -292,7 +292,7 @@ void Obj_BulbTouched(mobj_t *special, mobj_t *toucher)
P_MoveOrigin(toucher, special->x, special->y, special->z);
toucher->player->nocontrol = 1;
P_SetTarget(&toucher->tracer, special);
toucher->flags &= ~MF_SHOOTABLE;
toucher->flags &= ~(MF_SHOOTABLE|MF_NOGRAVITY);
toucher->renderflags |= RF_DONTDRAW;
P_SetTarget(&special->target, toucher);
special->extravalue1 = spd;

View file

@ -220,6 +220,7 @@ void Obj_playerWPZTurbine(player_t *p)
}
mt = t->spawnpoint;
pmo->flags &= ~MF_NOGRAVITY;
opt1 = (mt->thing_args[0] != 0);

View file

@ -4104,8 +4104,6 @@ papercollision:
static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result)
{
extern consvar_t cv_showgremlins;
fixed_t mmomx = 0, mmomy = 0;
fixed_t oldmomx = mo->momx, oldmomy = mo->momy;
@ -4130,24 +4128,6 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result)
slidemo = mo;
bestslideline = result->line;
if (bestslideline == NULL && cv_showgremlins.value)
{
// debug
mobj_t*x = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK);
x->frame = FF_FULLBRIGHT | FF_ADD;
x->renderflags = RF_ALWAYSONTOP;
x->color = SKINCOLOR_RED;
CONS_Printf(
"GREMLIN: leveltime=%u x=%f y=%f z=%f angle=%f\n",
leveltime,
FixedToFloat(mo->x),
FixedToFloat(mo->y),
FixedToFloat(mo->z),
AngleToFloat(R_PointToAngle2(0, 0, oldmomx, oldmomy))
);
}
if (mo->health <= 0)
{
tmxmove = mo->momx;

View file

@ -9553,8 +9553,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
// it's still necessary to refresh SPR2 on skin changes.
P_SetMobjState(cur, (newperfect == true) ? S_KART_SIGL : S_KART_SIGN);
if (cv_shittysigns.value && cur->state != &states[S_KART_SIGL])
cur->sprite2 = P_GetSkinSprite2(skins[newplayer->skin], SPR2_SSIG, NULL);;
if ((cv_shittysigns.value || newplayer->mfdfinish) && cur->state != &states[S_KART_SIGL])
{
cur->sprite2 = P_GetSkinSprite2(skins[newplayer->skin], SPR2_SSIG, NULL);
}
}
}
else if (cur->state == &states[S_SIGN_ERROR])

View file

@ -701,6 +701,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT8(save->p, players[i].analoginput);
WRITEUINT8(save->p, players[i].markedfordeath);
WRITEUINT8(save->p, players[i].mfdfinish);
WRITEUINT8(save->p, players[i].dotrickfx);
WRITEUINT8(save->p, players[i].stingfx);
WRITEUINT8(save->p, players[i].bumperinflate);
@ -1379,6 +1380,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].analoginput = READUINT8(save->p);
players[i].markedfordeath = READUINT8(save->p);
players[i].mfdfinish = READUINT8(save->p);
players[i].dotrickfx = READUINT8(save->p);
players[i].stingfx = READUINT8(save->p);
players[i].bumperinflate = READUINT8(save->p);

View file

@ -15,6 +15,8 @@
#include "p_sweep.hpp"
#include "p_local.h"
#include "g_demo.h"
#include "r_main.h"
namespace
{
@ -30,6 +32,8 @@ void P_TestLine(line_t* ld)
line_t* P_SweepTestLines(fixed_t ax, fixed_t ay, fixed_t bx, fixed_t by, fixed_t r, vector2_t* return_normal)
{
extern consvar_t cv_showgremlins;
using namespace srb2::math;
using namespace srb2::sweep;
@ -60,13 +64,65 @@ line_t* P_SweepTestLines(fixed_t ax, fixed_t ay, fixed_t bx, fixed_t by, fixed_t
}
}
g_lines.clear();
if (!collision)
{
return nullptr;
line_t *line = nullptr;
if (!g_lines.empty() && !G_CompatLevel(0x000E))
{
// FIXME: This condition is a failsafe!
// SlopeAABBvsLine::vs_slope can sometimes report
// no collision despite P_CheckPosition saying otherwise.
// (Generally related to infinitesimal numbers or overflows.)
// When it reports no collision, that means no line and
// no normals to base the collision off of.
// Here we provide the last line checked and normals based on
// the line and the player's momentum angle.
// But the proper fix would be to make vs_slope work!!
line = g_lines.back();
angle_t lineangle = line->angle;
angle_t mobjangle = R_PointToAngle2(ax, ay, bx, by);
angle_t diff = lineangle - mobjangle;
lineangle += diff > ANGLE_180 ? -ANGLE_90 : ANGLE_90;
return_normal->x = FINECOSINE((lineangle >> ANGLETOFINESHIFT) & FINEMASK);
return_normal->y = FINESINE((lineangle >> ANGLETOFINESHIFT) & FINEMASK);
// Moving the gremlin debug here so that it
// still fires even when the workaround is used.
if (cv_showgremlins.value)
{
mobj_t *mo = g_tm.thing;
if (mo)
{
mobj_t *x = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK);
x->frame = FF_FULLBRIGHT | FF_ADD;
x->renderflags = RF_ALWAYSONTOP;
x->color = SKINCOLOR_RED;
CONS_Printf(
"GREMLIN: leveltime=%u x=%f y=%f z=%f momx=%f momy=%f momz=%f\n",
leveltime,
FixedToFloat(mo->x),
FixedToFloat(mo->y),
FixedToFloat(mo->z),
FixedToFloat(mo->momx),
FixedToFloat(mo->momy),
FixedToFloat(mo->momz)
);
}
}
}
g_lines.clear();
return line;
}
g_lines.clear();
return_normal->x = Fixed {collision->normal.x};
return_normal->y = Fixed {collision->normal.y};

View file

@ -1272,6 +1272,7 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
if (!player->spectator && (gametyperules & GTR_CIRCUIT)) // Special Race-like handling
{
K_UpdateAllPlayerPositions();
player->mfdfinish = player->markedfordeath;
}
if (!(gametyperules & GTR_SPHERES) && (player->pflags & PF_RINGLOCK) && grandprixinfo.gp)