Merge branch 'buff-sliptide' into 'master'

Make sliptiding actually good

See merge request KartKrew/Kart!1020
This commit is contained in:
Oni 2023-03-07 08:49:46 +00:00
commit e4ba544994
12 changed files with 269 additions and 15 deletions

View file

@ -2561,6 +2561,7 @@ void CL_ClearPlayer(INT32 playernum)
P_SetTarget(&players[playernum].followmobj, NULL);
P_SetTarget(&players[playernum].hoverhyudoro, NULL);
P_SetTarget(&players[playernum].stumbleIndicator, NULL);
P_SetTarget(&players[playernum].sliptideZipIndicator, NULL);
}
// Handle parties.

View file

@ -681,7 +681,12 @@ struct player_t
UINT8 tripwireReboundDelay; // When failing Tripwire, brieftly lock out speed-based tripwire pass (anti-cheese)
UINT16 sliptideZip; // How long is our chained sliptide? Grant a proportional boost when it's over.
UINT8 sliptideZipDelay; // How long since the last sliptide? Only boost once you've been straightened out for a bit.
UINT16 sliptideZipBoost; // The actual boost granted from sliptideZip.
mobj_t *stumbleIndicator;
mobj_t *sliptideZipIndicator;
#ifdef HWRENDER
fixed_t fovadd; // adjust FOV for hw rendering

View file

@ -3304,6 +3304,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_MAGICIANBOXTOP",
"S_MAGICIANBOXBOTTOM",
"S_SLIPTIDEZIP",
// Signpost sparkles
"S_SIGNSPARK1",
"S_SIGNSPARK2",
@ -5323,6 +5325,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_MONITOR_PART",
"MT_MONITOR_SHARD",
"MT_MAGICIANBOX",
"MT_SLIPTIDEZIP",
"MT_SIGNSPARKLE",

View file

@ -4687,7 +4687,7 @@ void G_SaveGameData(void)
UINT8 btemp;
savebuffer_t save = {0};
if (!gamedata->loaded)
if (gamedata == NULL || !gamedata->loaded)
return; // If never loaded (-nodata), don't save
if (usedCheats)

View file

@ -552,6 +552,8 @@ char sprnames[NUMSPRITES + 1][5] =
"IMDB", // Item Monitor Small Shard (Debris)
"MTWK", // Item Monitor Glass Twinkle
"SLPT", // Sliptide zip indicator
"WIPD", // Wipeout dust trail
"DRIF", // Drift Sparks
"BDRF", // Brake drift sparks
@ -3930,6 +3932,8 @@ state_t states[NUMSTATES] =
{SPR_MGBT, FF_FLOORSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_MAGICIANBOX_TOP
{SPR_MGBB, FF_FLOORSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_MAGICIANBOX_BOTTOM
{SPR_SLPT, FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_SLIPTIDEZIP
{SPR_SGNS, FF_ADD|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1
{SPR_SGNS, FF_ADD|FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2
{SPR_SGNS, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_SIGNSPARK4}, // S_SIGNSPARK3
@ -22583,6 +22587,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
{ // MT_SLIPTIDEZIP
-1, // doomednum
S_SLIPTIDEZIP, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
20*FRACUNIT, // radius
20*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
{ // MT_SIGNSPARKLE
-1, // doomednum

View file

@ -1103,6 +1103,8 @@ typedef enum sprite
SPR_IMDB, // Item Monitor Small Shard (Debris)
SPR_MTWK, // Item Monitor Glass Twinkle
SPR_SLPT, // Sliptide zip indicator
SPR_WIPD, // Wipeout dust trail
SPR_DRIF, // Drift Sparks
SPR_BDRF, // Brake drift sparks
@ -4339,6 +4341,8 @@ typedef enum state
S_MAGICIANBOX_TOP,
S_MAGICIANBOX_BOTTOM,
S_SLIPTIDEZIP,
// Signpost sparkles
S_SIGNSPARK1,
S_SIGNSPARK2,
@ -6394,6 +6398,7 @@ typedef enum mobj_type
MT_MONITOR_PART,
MT_MONITOR_SHARD,
MT_MAGICIANBOX,
MT_SLIPTIDEZIP,
MT_SIGNSPARKLE,

View file

@ -1828,6 +1828,11 @@ static void K_SpawnGenericSpeedLines(player_t *player, boolean top)
fast->colorized = true;
fast->renderflags |= RF_ADD;
}
else if (player->sliptideZipBoost)
{
fast->color = SKINCOLOR_WHITE;
fast->colorized = true;
}
}
void K_SpawnNormalSpeedLines(player_t *player)
@ -3030,6 +3035,10 @@ fixed_t K_GetSpindashChargeSpeed(player_t *player)
return val;
}
// v2 almost broke sliptiding when it fixed turning bugs!
// This value is fine-tuned to feel like v1 again without reverting any of those changes.
#define SLIPTIDEHANDLING 7*FRACUNIT/8
// sets boostpower, speedboost, accelboost, and handleboost to whatever we need it to be
static void K_GetKartBoostPower(player_t *player)
{
@ -3037,10 +3046,6 @@ static void K_GetKartBoostPower(player_t *player)
const fixed_t maxmetabolismincrease = FRACUNIT/2;
const fixed_t metabolism = FRACUNIT - ((9-player->kartweight) * maxmetabolismincrease / 8);
// v2 almost broke sliptiding when it fixed turning bugs!
// This value is fine-tuned to feel like v1 again without reverting any of those changes.
const fixed_t sliptidehandling = FRACUNIT/2;
fixed_t boostpower = FRACUNIT;
fixed_t speedboost = 0, accelboost = 0, handleboost = 0;
UINT8 numboosts = 0;
@ -3059,13 +3064,16 @@ static void K_GetKartBoostPower(player_t *player)
boostpower = (4*boostpower)/5;
// Note: Handling will ONLY stack when sliptiding!
// > (NB 2023-03-06: This was previously unintentionally applied while drifting as well.)
// > (This only affected drifts where you were under the effect of multiple handling boosts.)
// > (Revisit if Growvinciblity or sneaker-panels + power items feel too heavy while drifting!)
// When you're not, it just uses the best instead of adding together, like the old behavior.
#define ADDBOOST(s,a,h) { \
numboosts++; \
speedboost += FixedDiv(s, FRACUNIT + (metabolism * (numboosts-1))); \
accelboost += FixedDiv(a, FRACUNIT + (metabolism * (numboosts-1))); \
if (player->aizdriftstrat) \
handleboost += FixedDiv(h, FRACUNIT + (metabolism * (numboosts-1))); \
if (K_Sliptiding(player)) \
handleboost += FixedDiv(h, FRACUNIT + (metabolism * (numboosts-1))/4); \
else \
handleboost = max(h, handleboost); \
}
@ -3075,18 +3083,18 @@ static void K_GetKartBoostPower(player_t *player)
UINT8 i;
for (i = 0; i < player->numsneakers; i++)
{
ADDBOOST(FRACUNIT/2, 8*FRACUNIT, sliptidehandling); // + 50% top speed, + 800% acceleration, +50% handling
ADDBOOST(FRACUNIT/2, 8*FRACUNIT, SLIPTIDEHANDLING); // + 50% top speed, + 800% acceleration, +50% handling
}
}
if (player->invincibilitytimer) // Invincibility
{
ADDBOOST(3*FRACUNIT/8, 3*FRACUNIT, sliptidehandling/2); // + 37.5% top speed, + 300% acceleration, +25% handling
ADDBOOST(3*FRACUNIT/8, 3*FRACUNIT, SLIPTIDEHANDLING/2); // + 37.5% top speed, + 300% acceleration, +25% handling
}
if (player->growshrinktimer > 0) // Grow
{
ADDBOOST(0, 0, sliptidehandling/2); // + 0% top speed, + 0% acceleration, +25% handling
ADDBOOST(0, 0, SLIPTIDEHANDLING/2); // + 0% top speed, + 0% acceleration, +25% handling
}
if (player->flamedash) // Flame Shield dash
@ -3095,10 +3103,16 @@ static void K_GetKartBoostPower(player_t *player)
ADDBOOST(
dash, // + infinite top speed
3*FRACUNIT, // + 300% acceleration
FixedMul(FixedDiv(dash, FRACUNIT/2), sliptidehandling/2) // + infinite handling
FixedMul(FixedDiv(dash, FRACUNIT/2), SLIPTIDEHANDLING/2) // + infinite handling
);
}
if (player->sliptideZipBoost)
{
// NB: This is intentionally under the 25% threshold required to initiate a sliptide
ADDBOOST(13*FRACUNIT/20, 4*FRACUNIT, 2*SLIPTIDEHANDLING/5); // + 65% top speed, + 400% acceleration, +20% handling
}
if (player->spindashboost) // Spindash boost
{
const fixed_t MAXCHARGESPEED = K_GetSpindashChargeSpeed(player);
@ -3114,7 +3128,7 @@ static void K_GetKartBoostPower(player_t *player)
if (player->startboost) // Startup Boost
{
ADDBOOST(FRACUNIT, 4*FRACUNIT, sliptidehandling); // + 100% top speed, + 400% acceleration, +50% handling
ADDBOOST(FRACUNIT, 4*FRACUNIT, SLIPTIDEHANDLING); // + 100% top speed, + 400% acceleration, +50% handling
}
if (player->driftboost) // Drift Boost
@ -3144,7 +3158,7 @@ static void K_GetKartBoostPower(player_t *player)
if (player->gateBoost) // SPB Juicebox boost
{
ADDBOOST(3*FRACUNIT/4, 4*FRACUNIT, sliptidehandling/2); // + 75% top speed, + 400% acceleration, +25% handling
ADDBOOST(3*FRACUNIT/4, 4*FRACUNIT, SLIPTIDEHANDLING/2); // + 75% top speed, + 400% acceleration, +25% handling
}
if (player->ringboost) // Ring Boost
@ -3923,6 +3937,31 @@ void K_InitStumbleIndicator(player_t *player)
P_SetTarget(&new->target, player->mo);
}
void K_InitSliptideZipIndicator(player_t *player)
{
mobj_t *new = NULL;
if (player == NULL)
{
return;
}
if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true)
{
return;
}
if (player->stumbleIndicator != NULL && P_MobjWasRemoved(player->sliptideZipIndicator) == false)
{
P_RemoveMobj(player->sliptideZipIndicator);
}
new = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SLIPTIDEZIP);
P_SetTarget(&player->sliptideZipIndicator, new);
P_SetTarget(&new->target, player->mo);
}
void K_UpdateStumbleIndicator(player_t *player)
{
const angle_t fudge = ANG15;
@ -4025,6 +4064,78 @@ void K_UpdateStumbleIndicator(player_t *player)
}
}
static boolean K_IsLosingSliptideZip(player_t *player)
{
if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true)
return true;
if (!K_Sliptiding(player) && player->drift == 0 && P_IsObjectOnGround(player->mo) && player->sneakertimer == 0)
return true;
return false;
}
void K_UpdateSliptideZipIndicator(player_t *player)
{
mobj_t *mobj = NULL;
if (player == NULL)
{
return;
}
if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true)
{
return;
}
if (player->stumbleIndicator == NULL || P_MobjWasRemoved(player->stumbleIndicator) == true)
{
K_InitSliptideZipIndicator(player);
return;
}
mobj = player->sliptideZipIndicator;
angle_t momentumAngle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
P_MoveOrigin(mobj, player->mo->x - FixedMul(40*mapobjectscale, FINECOSINE(momentumAngle >> ANGLETOFINESHIFT)),
player->mo->y - FixedMul(40*mapobjectscale, FINESINE(momentumAngle >> ANGLETOFINESHIFT)),
player->mo->z + (player->mo->height / 2));
mobj->angle = momentumAngle + ANGLE_90;
P_SetScale(mobj, 3 * player->mo->scale / 2);
// No stored boost
if (player->sliptideZip == 0)
{
mobj->renderflags |= RF_DONTDRAW;
mobj->frame = 7;
return;
}
mobj->renderflags &= ~RF_DONTDRAW;
UINT32 chargeFrame = 7 - min(7, player->sliptideZip / 10);
UINT32 decayFrame = min(7, player->sliptideZipDelay / 5);
if (max(chargeFrame, decayFrame) > mobj->frame)
mobj->frame++;
else if (max(chargeFrame, decayFrame) < mobj->frame)
mobj->frame--;
mobj->renderflags &= ~RF_TRANSMASK;
mobj->renderflags |= RF_PAPERSPRITE;
if (K_IsLosingSliptideZip(player))
{
// Decay timer's ticking
mobj->rollangle += 3*ANG30/4;
if (leveltime % 2 == 0)
mobj->renderflags |= RF_TRANS50;
}
else
{
// Storing boost
mobj->rollangle += 3*ANG15/4;
}
}
static boolean K_LastTumbleBounceCondition(player_t *player)
{
return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 60);
@ -7535,7 +7646,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->sneakertimer || player->ringboost
|| player->driftboost || player->startboost
|| player->eggmanexplode || player->trickboost
|| player->gateBoost)
|| player->gateBoost || player->sliptideZipBoost)
{
#if 0
if (player->invincibilitytimer)
@ -7797,6 +7908,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
player->startboost--;
}
if (player->sliptideZipBoost > 0 && onground == true)
{
player->sliptideZipBoost--;
}
if (player->spindashboost)
{
player->spindashboost--;
@ -8166,6 +8282,8 @@ void K_KartPlayerAfterThink(player_t *player)
K_UpdateStumbleIndicator(player);
K_UpdateSliptideZipIndicator(player);
// Move held objects (Bananas, Orbinaut, etc)
K_MoveHeldObjects(player);
@ -9258,7 +9376,7 @@ static void K_KartDrift(player_t *player, boolean onground)
player->pflags &= ~PF_DRIFTEND;
}
if ((player->handleboost == 0)
if ((player->handleboost < (SLIPTIDEHANDLING/2))
|| (!player->steering)
|| (!player->aizdriftstrat)
|| (player->steering > 0) != (player->aizdriftstrat > 0))
@ -9272,6 +9390,8 @@ static void K_KartDrift(player_t *player, boolean onground)
{
K_SpawnAIZDust(player);
player->sliptideZip++;
if (abs(player->aizdrifttilt) < ANGLE_22h)
{
player->aizdrifttilt =
@ -9289,6 +9409,40 @@ static void K_KartDrift(player_t *player, boolean onground)
if (!K_Sliptiding(player))
{
if (K_IsLosingSliptideZip(player) && player->sliptideZip > 0)
{
player->sliptideZipDelay++;
if (player->sliptideZipDelay > TICRATE)
{
fixed_t maxZipPower = 2*FRACUNIT;
fixed_t minZipPower = 1*FRACUNIT;
fixed_t powerSpread = maxZipPower - minZipPower;
int minPenalty = 2*1 + (9-9); // Kinda doing a similar thing to driftspark stage timers here.
int maxPenalty = 2*9 + (9-1); // 1/9 gets max, 9/1 gets min, everyone else gets something in between.
int penaltySpread = maxPenalty - minPenalty;
int yourPenalty = 2*player->kartspeed + (9 - player->kartweight); // And like driftsparks, speed hurts double.
yourPenalty -= minPenalty; // Normalize; minimum penalty should take away 0 power.
fixed_t yourPowerReduction = FixedDiv(yourPenalty * FRACUNIT, penaltySpread * FRACUNIT);
fixed_t yourPower = maxZipPower - FixedMul(yourPowerReduction, powerSpread);
int yourBoost = FixedInt(FixedMul(yourPower, player->sliptideZip * FRACUNIT));
/*
CONS_Printf("SZ %d MZ %d mZ %d pwS %d mP %d MP %d peS %d yPe %d yPR %d yPw %d yB %d\n",
player->sliptideZip, maxZipPower, minZipPower, powerSpread, minPenalty, maxPenalty, penaltySpread, yourPenalty, yourPowerReduction, yourPower, yourBoost);
*/
player->sliptideZipBoost += yourBoost;
K_SpawnDriftBoostExplosion(player, 0);
player->sliptideZip = 0;
player->sliptideZipDelay = 0;
S_StartSound(player->mo, sfx_s3kb6);
}
}
player->aizdrifttilt -= player->aizdrifttilt / 4;
player->aizdriftturn -= player->aizdriftturn / 4;
@ -9297,6 +9451,10 @@ static void K_KartDrift(player_t *player, boolean onground)
if (abs(player->aizdriftturn) < ANGLE_11hh)
player->aizdriftturn = 0;
}
else
{
player->sliptideZipDelay = 0;
}
if (player->drift
&& ((buttons & BT_BRAKE)
@ -9775,6 +9933,9 @@ static void K_KartSpindashWind(mobj_t *parent)
P_SetTarget(&wind->target, parent);
if (parent->player && parent->player->sliptideZipBoost)
P_SetScale(wind, wind->scale * 2);
if (parent->momx || parent->momy)
wind->angle = R_PointToAngle2(0, 0, parent->momx, parent->momy);
else
@ -9850,6 +10011,11 @@ static void K_KartSpindash(player_t *player)
K_KartSpindashWind(player->mo);
}
if ((player->sliptideZipBoost > 0) && (spawnWind == true))
{
K_KartSpindashWind(player->mo);
}
if (player->spindashboost > (TICRATE/2))
{
K_KartSpindashDust(player->mo);

View file

@ -99,7 +99,9 @@ angle_t K_StumbleSlope(angle_t angle, angle_t pitch, angle_t roll);
void K_StumblePlayer(player_t *player);
boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir);
void K_InitStumbleIndicator(player_t *player);
void K_InitSliptideZipIndicator(player_t *player);
void K_UpdateStumbleIndicator(player_t *player);
void K_UpdateSliptideZipIndicator(player_t *player);
INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
void K_DebtStingPlayer(player_t *player, mobj_t *source);
void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers);

View file

@ -161,6 +161,7 @@ void K_DoIngameRespawn(player_t *player)
player->ringboost = 0;
player->driftboost = player->strongdriftboost = 0;
player->gateBoost = 0;
player->sliptideZip = player->sliptideZipBoost = player->sliptideZipDelay = 0;
K_TumbleInterrupt(player);
P_ResetPlayer(player);

View file

@ -308,6 +308,12 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->tripwireLeniency);
else if (fastcmp(field,"tripwireReboundDelay"))
lua_pushinteger(L, plr->tripwireReboundDelay);
else if (fastcmp(field,"sliptideZip"))
lua_pushinteger(L, plr->sliptideZip);
else if (fastcmp(field,"sliptideZipDelay"))
lua_pushinteger(L, plr->sliptideZipDelay);
else if (fastcmp(field,"sliptideZipBoost"))
lua_pushinteger(L, plr->sliptideZipBoost);
/*
else if (fastcmp(field,"itemroulette"))
lua_pushinteger(L, plr->itemroulette);
@ -686,6 +692,12 @@ static int player_set(lua_State *L)
plr->tripwireLeniency = luaL_checkinteger(L, 3);
else if (fastcmp(field,"tripwireReboundDelay"))
plr->tripwireReboundDelay = luaL_checkinteger(L, 3);
else if (fastcmp(field,"sliptideZip"))
plr->sliptideZip = luaL_checkinteger(L, 3);
else if (fastcmp(field,"sliptideZipDelay"))
plr->sliptideZipDelay = luaL_checkinteger(L, 3);
else if (fastcmp(field,"sliptideZipBoost"))
plr->sliptideZipBoost = luaL_checkinteger(L, 3);
/*
else if (fastcmp(field,"itemroulette"))
plr->itemroulette = luaL_checkinteger(L, 3);

View file

@ -11857,6 +11857,8 @@ void P_SpawnPlayer(INT32 playernum)
K_InitStumbleIndicator(p);
K_InitSliptideZipIndicator(p);
if (gametyperules & GTR_ITEMARROWS)
{
mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height + 16*FRACUNIT, MT_PLAYERARROW);

View file

@ -67,6 +67,7 @@ typedef enum
SKYBOXCENTER = 0x10,
HOVERHYUDORO = 0x20,
STUMBLE = 0x40,
SLIPTIDEZIP = 0x80
} player_saveflags;
static inline void P_ArchivePlayer(savebuffer_t *save)
@ -218,6 +219,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
if (players[i].stumbleIndicator)
flags |= STUMBLE;
if (players[i].sliptideZipIndicator)
flags |= SLIPTIDEZIP;
WRITEUINT16(save->p, flags);
if (flags & SKYBOXVIEW)
@ -238,6 +242,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
if (flags & STUMBLE)
WRITEUINT32(save->p, players[i].stumbleIndicator->mobjnum);
if (flags & SLIPTIDEZIP)
WRITEUINT32(save->p, players[i].sliptideZipIndicator->mobjnum);
WRITEUINT32(save->p, (UINT32)players[i].followitem);
WRITEUINT32(save->p, players[i].charflags);
@ -397,6 +404,10 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT8(save->p, players[i].tripwireReboundDelay);
WRITEUINT16(save->p, players[i].sliptideZip);
WRITEUINT8(save->p, players[i].sliptideZipDelay);
WRITEUINT16(save->p, players[i].sliptideZipBoost);
// respawnvars_t
WRITEUINT8(save->p, players[i].respawn.state);
WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].respawn.wp));
@ -607,6 +618,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
if (flags & STUMBLE)
players[i].stumbleIndicator = (mobj_t *)(size_t)READUINT32(save->p);
if (flags & SLIPTIDEZIP)
players[i].sliptideZipIndicator = (mobj_t *)(size_t)READUINT32(save->p);
players[i].followitem = (mobjtype_t)READUINT32(save->p);
//SetPlayerSkinByNum(i, players[i].skin);
@ -767,6 +781,10 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].tripwireReboundDelay = READUINT8(save->p);
players[i].sliptideZip = READUINT16(save->p);
players[i].sliptideZipDelay = READUINT8(save->p);
players[i].sliptideZipBoost = READUINT16(save->p);
// respawnvars_t
players[i].respawn.state = READUINT8(save->p);
players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save->p);
@ -4746,6 +4764,13 @@ static void P_RelinkPointers(void)
if (!P_SetTarget(&players[i].stumbleIndicator, P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "stumbleIndicator not found on player %d\n", i);
}
if (players[i].sliptideZipIndicator)
{
temp = (UINT32)(size_t)players[i].sliptideZipIndicator;
players[i].sliptideZipIndicator = NULL;
if (!P_SetTarget(&players[i].sliptideZipIndicator, P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "sliptideZipIndicator not found on player %d\n", i);
}
}
}