Add legacy drifting for RR characters

Imitates V1 drifts using baked offsets; perfectly netsafe
This commit is contained in:
Anonimus 2025-09-12 14:46:45 -04:00
parent b702e17547
commit 04dd587ef4
8 changed files with 108 additions and 10 deletions

View file

@ -131,6 +131,11 @@ static void Skin2_OnChange(void);
static void Skin3_OnChange(void);
static void Skin4_OnChange(void);
static void Jitter_OnChange(void);
static void Jitter2_OnChange(void);
static void Jitter3_OnChange(void);
static void Jitter4_OnChange(void);
static void Follower_OnChange(void);
static void Follower2_OnChange(void);
static void Follower3_OnChange(void);
@ -272,6 +277,9 @@ static CV_PossibleValue_t sleeping_cons_t[] = {{0, "MIN"}, {1000/TICRATE, "MAX"}
static CV_PossibleValue_t pause_cons_t[] = {{0, "Server"}, {1, "All"}, {0, NULL}};
// Jon's lament
static CV_PossibleValue_t driftjitter_cons_t[] = {{0, "SRB2Kart"}, {1, "Ring Racers"}, {0, NULL}};
static consvar_t cv_dummyconsvar = CVAR_INIT ("dummyconsvar", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, DummyConsvar_OnChange);
consvar_t cv_restrictskinchange = CVAR_INIT ("restrictskinchange", "No", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL);
@ -375,6 +383,14 @@ consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save
};
#endif
// Drift jitter settings.
consvar_t cv_jitterlegacy[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("driftjitter", "Ring Racers", CV_SAVE|CV_CALL|CV_NOINIT, driftjitter_cons_t, Jitter_OnChange),
CVAR_INIT ("driftjitter2", "Ring Racers", CV_SAVE|CV_CALL|CV_NOINIT, driftjitter_cons_t, Jitter2_OnChange),
CVAR_INIT ("driftjitter3", "Ring Racers", CV_SAVE|CV_CALL|CV_NOINIT, driftjitter_cons_t, Jitter3_OnChange),
CVAR_INIT ("driftjitter4", "Ring Racers", CV_SAVE|CV_CALL|CV_NOINIT, driftjitter_cons_t, Jitter4_OnChange)
};
// SRB2kart
consvar_t cv_sneaker = CVAR_INIT ("sneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_rocketsneaker = CVAR_INIT ("rocketsneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
@ -1115,6 +1131,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_skin[i]);
CV_RegisterVar(&cv_follower[i]);
CV_RegisterVar(&cv_followercolor[i]);
CV_RegisterVar(&cv_jitterlegacy[i]);
}
// preferred number of players
@ -1711,7 +1728,8 @@ static void SendNameAndColor(UINT8 n)
&& cv_playercolor[n].value == player->skincolor
&& !strcmp(cv_skin[n].string, skins[player->skin].name)
&& cv_follower[n].value == player->followerskin
&& cv_followercolor[n].value == player->followercolor)
&& cv_followercolor[n].value == player->followercolor
&& ((boolean)((!cv_jitterlegacy[n].value) & 1)) == player->jitterlegacy)
return;
player->availabilities = R_GetSkinAvailabilities();
@ -1738,6 +1756,10 @@ static void SendNameAndColor(UINT8 n)
player->followercolor = cv_followercolor[n].value;
// Player jittering. Can't netsynch for hopefully obvious reasons.
// Inverted to prevent tedium.
player->jitterlegacy = (boolean)((!cv_jitterlegacy[n].value) & 1);
if (metalrecording && n == 0)
{ // Starring Metal Sonic as themselves, obviously.
SetPlayerSkinByNum(playernum, 5);
@ -1793,6 +1815,7 @@ static void SendNameAndColor(UINT8 n)
WRITEUINT16(p, (UINT16)cv_skin[n].value);
WRITESINT8(p, (SINT8)cv_follower[n].value);
WRITEUINT16(p, (UINT16)cv_followercolor[n].value);
WRITEUINT8(p, (UINT8)((!cv_jitterlegacy[n].value) & 1));
SendNetXCmdForPlayer(n, XD_NAMEANDCOLOR, buf, p - buf);
}
@ -1804,6 +1827,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
UINT16 color, followercolor;
UINT16 skin;
SINT8 follower;
boolean jitterlegacy;
SINT8 localplayer = -1;
UINT16 i;
@ -1834,6 +1858,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
skin = READUINT16(*cp);
follower = READSINT8(*cp);
followercolor = READUINT16(*cp);
jitterlegacy = READUINT8(*cp);
// set name
if (player_name_changes[playernum] < MAXNAMECHANGES)
@ -1842,6 +1867,9 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
SetPlayerName(playernum, name);
}
// Set jitter
p->jitterlegacy = jitterlegacy;
// set color
p->skincolor = color % numskincolors;
if (p->mo)
@ -6829,6 +6857,39 @@ static void Followercolor4_OnChange(void)
}
}
// Changes a player's jitter settings.
static void Jitter_OnChange(void)
{
if (!Playing())
return; // don't send anything there.
SendNameAndColor(0);
}
static void Jitter2_OnChange(void)
{
if (!Playing())
return; // don't send anything there.
SendNameAndColor(1);
}
static void Jitter3_OnChange(void)
{
if (!Playing())
return; // don't send anything there.
SendNameAndColor(2);
}
static void Jitter4_OnChange(void)
{
if (!Playing())
return; // don't send anything there.
SendNameAndColor(3);
}
/** Sends a skin change for the console player, unless that player is moving.
* \sa cv_skin, Skin2_OnChange, Color_OnChange
* \author Graue <graue@oceanbase.org>

View file

@ -29,6 +29,7 @@ extern consvar_t cv_playercolor[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_skin[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_follower[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_followercolor[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_jitterlegacy[MAXSPLITSCREENPLAYERS];
// preferred number of players
extern consvar_t cv_splitplayers;

View file

@ -565,6 +565,8 @@ struct player_t
// SRB2kart stuff
INT32 kartstuff[NUMKARTSTUFF];
INT32 karthud[NUMKARTHUD];
boolean jitterlegacy; // If true, makes Ring Racers characters jitter during drifts like
// SRB2Kart.
// Basic gameplay things
UINT8 position; // Used for Kart positions, mostly for deterministic stuff
@ -600,6 +602,7 @@ struct player_t
fixed_t driftcharge; // Charge your drift so you can release a burst of speed
UINT8 driftboost; // (0 to 125) - Boost you get from drifting
tic_t driftsparkGrowTimer;
tic_t driftelapsed; // Elapsed time spent during a drift.
SINT8 aizdriftstrat; // (-1 to 1) - Let go of your drift while boosting? Helper for the SICK STRATZ (sliptiding!) you have just unlocked
INT32 aizdrifttilt;

View file

@ -2467,6 +2467,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
UINT8 lastsafelap;
UINT8 lastsafestarpost;
UINT16 bigwaypointgap;
boolean jitterlegacy = false;
score = players[player].score;
lives = players[player].lives;
@ -2490,6 +2491,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
followercolor = players[player].followercolor;
followerskin = players[player].followerskin;
jitterlegacy = players[player].jitterlegacy;
availabilities = players[player].availabilities;
charflags = players[player].charflags;
@ -2689,6 +2692,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->eggmanblame = -1;
p->nocontrol = nocontrol;
p->kickstartaccel = kickstartaccel;
p->jitterlegacy = jitterlegacy;
p->ringvolume = 255;
p->ringtransparency = 255;

View file

@ -1565,17 +1565,21 @@ void K_KartMoveAnimation(player_t *player)
UINT16 buttons = K_GetKartButtons(player);
const boolean spinningwheels = (player->speed > 0);
const boolean lookback = ((buttons & BT_LOOKBACK) == BT_LOOKBACK);
const boolean skincompat = wadfiles[((skin_t *)player->mo->skin)->wadnum]->compatmode;
SINT8 turndir = intsign(player->cmd.turning);
SINT8 destGlanceDir = 0;
SINT8 drift = player->drift;
UINT8 spr2, glanceofs;
player->mo->rollingxoffset = 0;
player->mo->rollingyoffset = 0;
if (!lookback)
player->pflags &= ~PF_GAINAX;
// Sliptides: drift -> lookback frames
if (abs(player->aizdriftturn) >= ANGLE_90 && !wadfiles[((skin_t *)player->mo->skin)->wadnum]->compatmode)
if (abs(player->aizdriftturn) >= ANGLE_90 && !skincompat)
{
destGlanceDir = -(2*intsign(player->aizdriftturn));
player->glanceDir = destGlanceDir;
@ -1690,13 +1694,21 @@ void K_KartMoveAnimation(player_t *player)
if (onground && drift)
{
if (drift > 0)
turndir *= -1;
if ((player->jitterlegacy) && (!skincompat))
{
// Make RR characters imitate legacy jitters.
player->mo->rollingxoffset = ((player->driftelapsed & 1) * 2) * -intsign(drift);
}
else
{
if (drift > 0)
turndir *= -1;
if (turndir == -1)
spr2 += 2; // Inwards drift
else if (turndir == 1)
spr2 += 1; // Outwards drift
if (turndir == -1)
spr2 += 2; // Inwards drift
else if (turndir == 1)
spr2 += 1; // Outwards drift
}
}
else if (glanceofs)
spr2 += glanceofs+1;

View file

@ -2363,7 +2363,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
diff2 |= MD2_TID;
if (mobj->spritexscale != FRACUNIT || mobj->spriteyscale != FRACUNIT)
diff2 |= MD2_SPRITESCALE;
if (mobj->spritexoffset || mobj->spriteyoffset)
if (mobj->spritexoffset || mobj->spriteyoffset ||
mobj->rollingxoffset || mobj->rollingyoffset)
diff2 |= MD2_SPRITEOFFSET;
if (mobj->sprxoff || mobj->spryoff || mobj->sprzoff)
diff2 |= MD2_WORLDOFFSET;
@ -2605,6 +2606,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
{
WRITEFIXED(save->p, mobj->spritexoffset);
WRITEFIXED(save->p, mobj->spriteyoffset);
WRITEINT16(save->p, mobj->rollingxoffset);
WRITEINT16(save->p, mobj->rollingyoffset);
}
if (diff2 & MD2_WORLDOFFSET)
{
@ -3872,10 +3875,13 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
{
mobj->spritexoffset = READFIXED(save->p);
mobj->spriteyoffset = READFIXED(save->p);
mobj->rollingxoffset = READINT16(save->p);
mobj->rollingyoffset = READINT16(save->p);
}
else
{
mobj->spritexoffset = mobj->spriteyoffset = 0;
mobj->rollingxoffset = mobj->rollingyoffset = 0;
}
if (diff2 & MD2_WORLDOFFSET)
{

View file

@ -3839,6 +3839,16 @@ void P_PlayerThink(player_t *player)
player->airtime++;
}
// BlanKart: Track drifting time.
if (player->drift != 0)
{
player->driftelapsed++;
}
else
{
player->driftelapsed = 0;
}
cmd = &player->cmd;
// SRB2kart

View file

@ -857,7 +857,8 @@ boolean R_ThingIsFlashing(mobj_t *thing)
boolean R_ThingIsUsingBakedOffsets(mobj_t* thing)
{
return ((thing->bakexoff) || (thing->bakeyoff) || (thing->bakezoff) ||
(thing->bakexpiv) || (thing->bakeypiv) || (thing->bakezpiv));
(thing->bakexpiv) || (thing->bakeypiv) || (thing->bakezpiv) ||
(thing->rollingxoffset) || (thing->rollingyoffset));
}
UINT8 *R_GetSpriteTranslation(vissprite_t *vis)