From 8d7572741938e3369a709d45f717f68bfc5f111c Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 23 Aug 2025 21:47:46 +0100 Subject: [PATCH 1/2] Fix writing followers into demos Does not require a demoversion bump, was a plain mistake in write condition. Previously dependent on whether the memory of `player->follower` - a mobj_t reference - was nonzero, instead of the actual followerskin ID. We essentially got REALLY lucky that TA properly saved 'em currently so we don't have to do a ton of hex editing just to make them visible again --- src/g_demo.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/g_demo.cpp b/src/g_demo.cpp index c4ceaa65d..9307cd93b 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -2231,13 +2231,10 @@ void G_BeginRecording(void) demobuf.p += copy_fixed_buf(demobuf.p, skincolors[player->skincolor].name, g_buffer_sizes.color_name); // Save follower's skin name - // PS: We must check for 'follower' to determine if the followerskin is valid. It's going to be 0 if we don't have a follower, but 0 is also absolutely a valid follower! - // Doesn't really matter if the follower mobj is valid so long as it exists in a way or another. - - if (player->follower) - demobuf.p += copy_fixed_buf(demobuf.p, followers[player->followerskin].name, g_buffer_sizes.skin_name); + if (player->followerskin == -1) + demobuf.p += copy_fixed_buf(demobuf.p, "None", g_buffer_sizes.skin_name); else - demobuf.p += copy_fixed_buf(demobuf.p, "None", g_buffer_sizes.skin_name); // Say we don't have one, then. + demobuf.p += copy_fixed_buf(demobuf.p, followers[player->followerskin].name, g_buffer_sizes.skin_name); // Save follower's colour for (j = (numskincolors+2)-1; j > 0; j--) From 48a155f8e75d8a9385a333f4e96b7e8bf033eb1e Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 23 Aug 2025 21:49:10 +0100 Subject: [PATCH 2/2] Fix Auto-Ring follower fallback - Move `followerready`'s first set from `K_SetFollowerByNum` (which isn't called if your follower is -1, the exact case Goddess is supposed to help us with) to `G_UpdatePlayerPreferences`, which is always called whenever the follower ID is validated on join - Cache "Goddess"' followerskin ID by cribbing from `r_skins` and `R_DefaultBotSkin` --- src/g_game.c | 2 ++ src/k_follower.c | 30 ++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index db732acc2..2f84b4ef0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1801,6 +1801,8 @@ void G_FixCamera(UINT8 view) void G_UpdatePlayerPreferences(player_t *const player) { + player->followerready = true; // we are ready to perform follower related actions in the player thinker, now. + if (demo.playback) return; diff --git a/src/k_follower.c b/src/k_follower.c index 4f8183f8c..f3033bb3c 100644 --- a/src/k_follower.c +++ b/src/k_follower.c @@ -176,8 +176,6 @@ void K_SetFollowerByNum(INT32 playernum, INT32 skinnum) { player_t *player = &players[playernum]; - player->followerready = true; // we are ready to perform follower related actions in the player thinker, now. - if (skinnum >= -1 && skinnum <= numfollowers) // Make sure it exists! { /* @@ -898,6 +896,26 @@ void K_FollowerHornTaunt(player_t *taunter, player_t *victim, boolean mysticmelo } } +#define AUTORINGFOLLOWERNAME "goddess" +static INT32 K_AutoRingFollower(void) +{ + static INT32 autoringfollower = -2; + + if (autoringfollower == -2) + { + autoringfollower = K_FollowerAvailable(AUTORINGFOLLOWERNAME); + + if (autoringfollower == -2) + { + // This shouldn't happen, but just in case + autoringfollower = -1; + } + } + + return (INT32)autoringfollower; +} +#undef AUTORINGFOLLOWERNAME + /*-------------------------------------------------- INT32 K_GetEffectiveFollowerSkin(const player_t *player); @@ -905,8 +923,8 @@ void K_FollowerHornTaunt(player_t *taunter, player_t *victim, boolean mysticmelo --------------------------------------------------*/ INT32 K_GetEffectiveFollowerSkin(const player_t *player) { - if ((player->pflags & PF_AUTORING) && player->followerskin == -1) - return K_FollowerAvailable("Goddess"); - else - return player->followerskin; + if (player->followerskin == -1 && ((player->pflags & PF_AUTORING) == PF_AUTORING)) + return K_AutoRingFollower(); + + return player->followerskin; }