Additional P_SetTarget mobj_t pointer fixes on player struct

* CL_ClearPlayer (player departing server)
    - In GS_LEVEL, decrement refcount for all relevant pointer
    - Clearer comments
* G_PlayerReborn (initialisation before any player spawn)
    - Preserve skybox data and hoverhyudoro (except between maps)
    - Clean up follower handling
* Cross-codebase: use P_SetTarget for setting skybox-specific pointers, to match p_saveg.c
This commit is contained in:
toaster 2023-01-08 15:15:44 +00:00
parent cf609113f3
commit 2a87cfcdf1
4 changed files with 61 additions and 28 deletions

View file

@ -2521,31 +2521,45 @@ void CL_ClearPlayer(INT32 playernum)
{
int i;
if (players[playernum].follower)
{
K_RemoveFollower(&players[playernum]);
}
if (players[playernum].mo)
// Handle mobj_t pointers.
if (gamestate == GS_LEVEL)
{
P_RemoveMobj(players[playernum].mo);
if (players[playernum].follower)
{
K_RemoveFollower(&players[playernum]);
}
if (players[playernum].mo)
{
P_RemoveMobj(players[playernum].mo);
P_SetTarget(&players[playernum].mo, NULL);
}
P_SetTarget(&players[playernum].skybox.viewpoint, NULL);
P_SetTarget(&players[playernum].skybox.centerpoint, NULL);
P_SetTarget(&players[playernum].awayviewmobj, NULL);
P_SetTarget(&players[playernum].followmobj, NULL);
P_SetTarget(&players[playernum].hoverhyudoro, NULL);
P_SetTarget(&players[playernum].stumbleIndicator, NULL);
}
// Handle parties.
for (i = 0; i < MAXPLAYERS; ++i)
{
if (splitscreen_invitations[i] == playernum)
splitscreen_invitations[i] = -1;
}
splitscreen_invitations[playernum] = -1;
splitscreen_party_size[playernum] = 0;
splitscreen_original_party_size[playernum] = 0;
// Wipe the struct.
memset(&players[playernum], 0, sizeof (player_t));
// Handle values which should not be initialised to 0.
players[playernum].followerskin = -1; // don't have a ghost follower
players[playernum].fakeskin = players[playernum].lastfakeskin = MAXSKINS; // don't avoid eggman
// Handle post-cleanup.
RemoveAdminPlayer(playernum); // don't stay admin after you're gone
}

View file

@ -2217,7 +2217,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
boolean followerready;
INT32 followerskin;
UINT16 followercolor;
mobj_t *follower; // old follower, will probably be removed by the time we're dead but you never know.
mobj_t *hoverhyudoro;
mobj_t *skyboxviewpoint;
mobj_t *skyboxcenterpoint;
INT32 charflags;
UINT32 followitem;
@ -2342,8 +2346,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
khudfinish = 0;
khudcardanimation = 0;
starpostnum = 0;
follower = NULL;
}
else
{
@ -2391,15 +2393,25 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
starpostnum = players[player].starpostnum;
follower = players[player].follower;
pflags |= (players[player].pflags & (PF_STASIS|PF_ELIMINATED|PF_NOCONTEST|PF_FAULT|PF_LOSTLIFE));
}
if (!betweenmaps)
{
// Obliterate follower from existence (if valid memory)
follower = players[player].follower;
P_SetTarget(&players[player].follower, NULL);
P_SetTarget(&players[player].awayviewmobj, NULL);
P_SetTarget(&players[player].stumbleIndicator, NULL);
P_SetTarget(&players[player].followmobj, NULL);
hoverhyudoro = players[player].hoverhyudoro;
skyboxviewpoint = players[player].skybox.viewpoint;
skyboxcenterpoint = players[player].skybox.centerpoint;
}
else
{
follower = hoverhyudoro = NULL;
skyboxviewpoint = skyboxcenterpoint = NULL;
}
p = &players[player];
@ -2468,6 +2480,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
if (follower)
P_RemoveMobj(follower);
p->hoverhyudoro = hoverhyudoro;
p->skybox.viewpoint = skyboxviewpoint;
p->skybox.centerpoint = skyboxcenterpoint;
p->followerready = followerready;
p->followerskin = followerskin;
p->followercolor = followercolor;

View file

@ -11738,14 +11738,11 @@ void P_SpawnPlayer(INT32 playernum)
p->realtime = leveltime;
p->followitem = skins[p->skin].followitem;
//awayview stuff
p->awayviewmobj = NULL;
p->awayviewtics = 0;
p->skybox.viewpoint = skyboxviewpnts[0];
p->skybox.centerpoint = skyboxcenterpnts[0];
P_SetTarget(&p->follower, NULL); // cleanse follower from existence
if (p->jointime <= 1 || leveltime <= 1)
{
P_SetTarget(&p->skybox.viewpoint, skyboxviewpnts[0]);
P_SetTarget(&p->skybox.centerpoint, skyboxcenterpnts[0]);
}
if (K_PlayerShrinkCheat(p) == true)
{

View file

@ -2127,12 +2127,12 @@ static void P_SwitchSkybox(INT32 args, player_t *player, skybox_t *skybox)
{
if (args != TMS_CENTERPOINT) // Only viewpoint, or both.
{
player->skybox.viewpoint = skybox->viewpoint;
P_SetTarget(&player->skybox.viewpoint, skybox->viewpoint);
}
if (args != TMS_VIEWPOINT) // Only centerpoint, or both.
{
player->skybox.centerpoint = skybox->centerpoint;
P_SetTarget(&player->skybox.centerpoint, skybox->centerpoint);
}
}
@ -3016,22 +3016,28 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
INT32 viewid = line->args[0];
INT32 centerid = line->args[1];
mobj_t *set;
// set viewpoint mobj
if (line->args[2] != TMS_CENTERPOINT)
{
if (viewid >= 0 && viewid < 16)
skybox.viewpoint = skyboxviewpnts[viewid];
set = skyboxviewpnts[viewid];
else
skybox.viewpoint = NULL;
set = NULL;
P_SetTarget(&skybox.viewpoint, set);
}
// set centerpoint mobj
if (line->args[2] != TMS_VIEWPOINT)
{
if (centerid >= 0 && centerid < 16)
skybox.centerpoint = skyboxcenterpnts[centerid];
set = skyboxcenterpnts[centerid];
else
skybox.centerpoint = NULL;
set = NULL;
P_SetTarget(&skybox.centerpoint, set);
}
if (line->args[3]) // Applies to all players