From 2a87cfcdf14bb6626dfdbc2121f1b0e020c6aa9b Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 8 Jan 2023 15:15:44 +0000 Subject: [PATCH] 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 --- src/d_clisrv.c | 32 +++++++++++++++++++++++--------- src/g_game.c | 26 +++++++++++++++++++++----- src/p_mobj.c | 13 +++++-------- src/p_spec.c | 18 ++++++++++++------ 4 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1553f7f2c..151fdb436 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -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 } diff --git a/src/g_game.c b/src/g_game.c index 6cea62b1a..9746633a5 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -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; diff --git a/src/p_mobj.c b/src/p_mobj.c index 24d881471..982339858 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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) { diff --git a/src/p_spec.c b/src/p_spec.c index 47afb87be..0757a8238 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -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