From 66273898b7233bb33ce6145563c2b93361643903 Mon Sep 17 00:00:00 2001
From: toaster <rollerorbital@gmail.com>
Date: Thu, 17 Jan 2019 22:01:28 +0000
Subject: [PATCH] * Refactor all instances of `majormods = true;` to route
 through G_SetGameModified, and catch a few spots I missed in the process. *
 Make G_SetGameModified only console-print for major mods. * Add amnesty to
 "major mod" detection while loading files with custom savedatas. * Improved
 the console prints for command `isgamemodified`.

---
 src/d_main.c     |  4 +--
 src/d_netcmd.c   | 23 ++++++++---------
 src/d_netfil.c   |  2 +-
 src/dehacked.c   | 66 +++++++++++++++++++++++-------------------------
 src/filesrch.h   |  3 ++-
 src/g_game.c     | 12 ++++++---
 src/g_game.h     |  2 +-
 src/lua_script.c |  2 +-
 src/m_cheat.c    | 13 +++++-----
 src/m_menu.c     | 14 ++++++----
 src/p_setup.c    |  4 ++-
 src/w_wad.c      |  3 +++
 12 files changed, 80 insertions(+), 68 deletions(-)

diff --git a/src/d_main.c b/src/d_main.c
index f3539df74..fd85770ca 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -1162,7 +1162,7 @@ void D_SRB2Main(void)
 				if (s) // Check for NULL?
 				{
 					if (!W_VerifyNMUSlumps(s))
-						G_SetGameModified(true);
+						G_SetGameModified(true, false);
 					D_AddFile(s);
 				}
 			}
@@ -1189,7 +1189,7 @@ void D_SRB2Main(void)
 		else
 		{
 			if (!M_CheckParm("-server"))
-				G_SetGameModified(true);
+				G_SetGameModified(true, true);
 			autostart = true;
 		}
 	}
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index d6e78c911..244e3058a 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -2218,8 +2218,7 @@ static void Command_Map_f(void)
 	{
 		if (COM_CheckParm("-force"))
 		{
-			G_SetGameModified(false);
-			majormods = true;
+			G_SetGameModified(false, true);
 		}
 		else
 		{
@@ -3789,7 +3788,7 @@ static void Command_RunSOC(void)
 		if (!P_RunSOC(fn))
 			CONS_Printf(M_GetText("Could not find SOC.\n"));
 		else
-			G_SetGameModified(multiplayer);
+			G_SetGameModified(multiplayer, false);
 		return;
 	}
 
@@ -3843,7 +3842,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
 	}
 
 	P_RunSOC(filename);
-	G_SetGameModified(true);
+	G_SetGameModified(true, false);
 }
 
 /** Adds a pwad at runtime.
@@ -3880,7 +3879,7 @@ static void Command_Addfile(void)
 			CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
 			return;
 		}
-		G_SetGameModified(multiplayer);
+		G_SetGameModified(multiplayer, false);
 	}
 
 	// Add file on your client directly if it is trivial, or you aren't in a netgame.
@@ -4126,7 +4125,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
 		return;
 	}
 
-	G_SetGameModified(true);
+	G_SetGameModified(true, false);
 }
 
 static void Command_ListWADS_f(void)
@@ -4483,7 +4482,7 @@ static void Ringslinger_OnChange(void)
 	}
 
 	if (cv_ringslinger.value) // Only if it's been turned on
-		G_SetGameModified(multiplayer);
+		G_SetGameModified(multiplayer, true);
 }
 
 static void Gravity_OnChange(void)
@@ -4504,7 +4503,7 @@ static void Gravity_OnChange(void)
 #endif
 
 	if (!CV_IsSetToDefault(&cv_gravity))
-		G_SetGameModified(multiplayer);
+		G_SetGameModified(multiplayer, true);
 	gravity = cv_gravity.value;
 }
 
@@ -4900,7 +4899,7 @@ static void Fishcake_OnChange(void)
 	// so don't make modifiedgame always on!
 	if (cv_debug)
 	{
-		G_SetGameModified(multiplayer);
+		G_SetGameModified(multiplayer, true);
 	}
 
 	else if (cv_debug != cv_fishcake.value)
@@ -4917,11 +4916,11 @@ static void Fishcake_OnChange(void)
 static void Command_Isgamemodified_f(void)
 {
 	if (savemoddata)
-		CONS_Printf(M_GetText("modifiedgame is true, but you can save medal and record data in this mod.\n"));
+		CONS_Printf(M_GetText("The game is modified, but you can save medal and record data in this add-on.\n"));
 	else if (/*modifiedgame*/ majormods)
-		CONS_Printf(M_GetText("modifiedgame is true, extras will not be unlocked\n"));
+		CONS_Printf(M_GetText("Major add-ons have been loaded, so you cannot play record attack.\n"));
 	else
-		CONS_Printf(M_GetText("modifiedgame is false, you can unlock extras\n"));
+		CONS_Printf(M_GetText("No major add-ons are loaded. You can play record attack, earn medals and unlock extras.\n"));
 }
 
 static void Command_Cheats_f(void)
diff --git a/src/d_netfil.c b/src/d_netfil.c
index c7cfdbc11..99a058403 100644
--- a/src/d_netfil.c
+++ b/src/d_netfil.c
@@ -426,7 +426,7 @@ void CL_LoadServerFiles(void)
 		else if (fileneeded[i].status == FS_FOUND)
 		{
 			P_AddWadFile(fileneeded[i].filename);
-			G_SetGameModified(true);
+			G_SetGameModified(true, false);
 			fileneeded[i].status = FS_OPEN;
 		}
 		else if (fileneeded[i].status == FS_MD5SUMBAD)
diff --git a/src/dehacked.c b/src/dehacked.c
index 2e8ce562d..4edeb987c 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -21,6 +21,7 @@
 #include "w_wad.h"
 #include "m_menu.h"
 #include "m_misc.h"
+#include "filesrch.h" // for refreshdirmenu
 #include "f_finale.h"
 #include "dehacked.h"
 #include "st_stuff.h"
@@ -79,8 +80,6 @@ static powertype_t get_power(const char *word);
 boolean deh_loaded = false;
 static int dbg_line;
 
-static boolean gamedataadded = false;
-
 #ifdef DELFILE
 typedef struct undehacked_s
 {
@@ -3149,6 +3148,7 @@ static void readmaincfg(MYFILE *f)
 				strlcpy(gamedatafilename, word2, sizeof (gamedatafilename));
 				strlwr(gamedatafilename);
 				savemoddata = true;
+				majormods = false;
 
 				// Also save a time attack folder
 				filenamelen = strlen(gamedatafilename)-4;  // Strip off the extension
@@ -3161,7 +3161,7 @@ static void readmaincfg(MYFILE *f)
 				// can't use sprintf since there is %u in savegamename
 				strcatbf(savegamename, srb2home, PATHSEP);
 
-				gamedataadded = true;
+				refreshdirmenu |= REFRESHDIR_GAMEDATA;
 			}
 			else if (fastcmp(word, "RESETDATA"))
 			{
@@ -3392,8 +3392,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 	for (i = 0; i < NUMSFX; i++)
 		savesfxnames[i] = S_sfx[i].name;
 
-	gamedataadded = false;
-
 	// it doesn't test the version of SRB2 and version of dehacked file
 	dbg_line = -1; // start at -1 so the first line is 0.
 	while (!myfeof(f))
@@ -3427,21 +3425,21 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 			if (fastcmp(word, "FREESLOT"))
 			{
 				readfreeslots(f);
-				//majormods = true;
+				//G_SetGameModified(multiplayer, true);
 				continue;
 			}
 			else if (fastcmp(word, "MAINCFG"))
 			{
+				G_SetGameModified(multiplayer, true);
 				readmaincfg(f);
 				DEH_WriteUndoline(word, "", UNDO_HEADER);
-				majormods = true;
 				continue;
 			}
 			else if (fastcmp(word, "WIPES"))
 			{
 				readwipes(f);
 				DEH_WriteUndoline(word, "", UNDO_HEADER);
-				//majormods = true;
+				//G_SetGameModified(multiplayer, true);
 				continue;
 			}
 			word2 = strtok(NULL, " ");
@@ -3462,7 +3460,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 					ignorelines(f);
 				}
 				DEH_WriteUndoline(word, word2, UNDO_HEADER);
-				//majormods = true;
+				//G_SetGameModified(multiplayer, true);
 				continue;
 			}
 			if (word2)
@@ -3476,14 +3474,14 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 					// Read texture from spec file.
 					readtexture(f, word2);
 					DEH_WriteUndoline(word, word2, UNDO_HEADER);
-					//majormods = true;
+					//G_SetGameModified(multiplayer, true);
 				}
 				else if (fastcmp(word, "PATCH"))
 				{
 					// Read patch from spec file.
 					readpatch(f, word2, wad);
 					DEH_WriteUndoline(word, word2, UNDO_HEADER);
-					//majormods = true;
+					//G_SetGameModified(multiplayer, true);
 				}
 				else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
 				{
@@ -3492,7 +3490,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 					if (i < NUMMOBJTYPES && i >= 0)
 					{
 						if (i < (MT_FIRSTFREESLOT+freeslotusage[1][1]))
-							majormods = true; // affecting something earlier than the first freeslot allocated in this .wad? DENIED
+							G_SetGameModified(multiplayer, true); // affecting something earlier than the first freeslot allocated in this .wad? DENIED
 						readthing(f, i);
 					}
 					else
@@ -3505,7 +3503,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 /*				else if (fastcmp(word, "ANIMTEX"))
 				{
 					readAnimTex(f, i);
-					//majormods = true;
+					//G_SetGameModified(multiplayer, true);
 				}*/
 				else if (fastcmp(word, "LIGHT"))
 				{
@@ -3519,7 +3517,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 						ignorelines(f);
 					}
 					DEH_WriteUndoline(word, word2, UNDO_HEADER);
-					//majormods = true;
+					//G_SetGameModified(multiplayer, true);
 #endif
 				}
 				else if (fastcmp(word, "SPRITE"))
@@ -3535,7 +3533,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 						ignorelines(f);
 					}
 					DEH_WriteUndoline(word, word2, UNDO_HEADER);
-					//majormods = true;
+					//G_SetGameModified(multiplayer, true);
 #endif
 				}
 				else if (fastcmp(word, "LEVEL"))
@@ -3550,7 +3548,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 					if (i > 0 && i <= NUMMAPS)
 					{
 						if (mapheaderinfo[i])
-							majormods = true; // only mark as a major mod if it replaces an already-existing mapheaderinfo
+							G_SetGameModified(multiplayer, true); // only mark as a major mod if it replaces an already-existing mapheaderinfo
 						readlevelheader(f, i);
 					}
 					else
@@ -3570,7 +3568,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 						ignorelines(f);
 					}
 					DEH_WriteUndoline(word, word2, UNDO_HEADER);
-					//majormods = true; -- might have to reconsider in a future update
+					//G_SetGameModified(multiplayer, true); -- might have to reconsider in a future update
 				}
 				else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE"))
 				{
@@ -3579,7 +3577,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 					if (i < NUMSTATES && i >= 0)
 					{
 						if (i < (S_FIRSTFREESLOT+freeslotusage[0][1]))
-							majormods = true; // affecting something earlier than the first freeslot allocated in this .wad? DENIED
+							G_SetGameModified(multiplayer, true); // affecting something earlier than the first freeslot allocated in this .wad? DENIED
 						readframe(f, i);
 					}
 					else
@@ -3610,7 +3608,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 					}
 					else
 						deh_warning("pointer (Frame %d) : missing ')'", i);
-					majormods = true;
+					G_SetGameModified(multiplayer, true);
 				}*/
 				else if (fastcmp(word, "SOUND"))
 				{
@@ -3624,7 +3622,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 						ignorelines(f);
 					}
 					DEH_WriteUndoline(word, word2, UNDO_HEADER);
-					//majormods = true; -- ...this won't bite me in the ass later, will it?
+					//G_SetGameModified(multiplayer, true); -- ...this won't bite me in the ass later, will it?
 				}
 /*				else if (fastcmp(word, "SPRITE"))
 				{
@@ -3645,7 +3643,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 					}
 					else
 						deh_warning("Sprite %d doesn't exist",i);
-					//majormods = true;
+					//G_SetGameModified(multiplayer, true);
 				}*/
 				else if (fastcmp(word, "HUDITEM"))
 				{
@@ -3659,11 +3657,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 						ignorelines(f);
 					}
 					DEH_WriteUndoline(word, word2, UNDO_HEADER);
-					//majormods = true;
+					//G_SetGameModified(multiplayer, true);
 				}
 				else if (fastcmp(word, "EMBLEM"))
 				{
-					if (!gamedataadded)
+					if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
 					{
 						deh_warning("You must define a custom gamedata to use \"%s\"", word);
 						ignorelines(f);
@@ -3673,7 +3671,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 						if (numemblems < i)
 							numemblems = i;
 						reademblemdata(f, i);
-						majormods = true;
+						G_SetGameModified(multiplayer, true);
 					}
 					else
 					{
@@ -3684,7 +3682,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 				}
 				else if (fastcmp(word, "EXTRAEMBLEM"))
 				{
-					if (!gamedataadded)
+					if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
 					{
 						deh_warning("You must define a custom gamedata to use \"%s\"", word);
 						ignorelines(f);
@@ -3694,7 +3692,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 						if (numextraemblems < i)
 							numextraemblems = i;
 						readextraemblemdata(f, i);
-						majormods = true;
+						G_SetGameModified(multiplayer, true);
 					}
 					else
 					{
@@ -3705,7 +3703,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 				}
 				else if (fastcmp(word, "UNLOCKABLE"))
 				{
-					if (!gamedataadded)
+					if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
 					{
 						deh_warning("You must define a custom gamedata to use \"%s\"", word);
 						ignorelines(f);
@@ -3713,7 +3711,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 					else if (i > 0 && i <= MAXUNLOCKABLES)
 					{
 						readunlockable(f, i - 1);
-						majormods = true;
+						G_SetGameModified(multiplayer, true);
 					}
 					else
 					{
@@ -3724,7 +3722,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 				}
 				else if (fastcmp(word, "CONDITIONSET"))
 				{
-					if (!gamedataadded)
+					if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
 					{
 						deh_warning("You must define a custom gamedata to use \"%s\"", word);
 						ignorelines(f);
@@ -3732,7 +3730,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 					else if (i > 0 && i <= MAXCONDITIONSETS)
 					{
 						readconditionset(f, (UINT8)i);
-						majormods = true;
+						G_SetGameModified(multiplayer, true);
 					}
 					else
 					{
@@ -3761,7 +3759,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 				{
 					boolean clearall = (fastcmp(word2, "ALL"));
 
-					if (!gamedataadded)
+					if (!(refreshdirmenu & REFRESHDIR_GAMEDATA))
 					{
 						deh_warning("You must define a custom gamedata to use \"%s\"", word);
 						continue;
@@ -3788,7 +3786,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 					if (clearall || fastcmp(word2, "LEVELS"))
 						clear_levels();
 
-					majormods = true;
+					G_SetGameModified(multiplayer, true);
 				}
 				else
 					deh_warning("Unknown word: %s", word);
@@ -3800,8 +3798,8 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 			deh_warning("No word in this line: %s", s);
 	} // end while
 
-	if (gamedataadded)
-		G_LoadGameData();
+	/*if (gamedataadded) -- REFRESHDIR_GAMEDATA murdered this
+		G_LoadGameData();*/
 
 	dbg_line = -1;
 	if (deh_num_warning)
diff --git a/src/filesrch.h b/src/filesrch.h
index 4186271b0..01a528482 100644
--- a/src/filesrch.h
+++ b/src/filesrch.h
@@ -88,7 +88,8 @@ typedef enum
 	REFRESHDIR_WARNING = 4,
 	REFRESHDIR_ERROR = 8,
 	REFRESHDIR_NOTLOADED = 16,
-	REFRESHDIR_MAX = 32
+	REFRESHDIR_MAX = 32,
+	REFRESHDIR_GAMEDATA = 64
 } refreshdir_enum;
 
 void closefilemenu(boolean validsize);
diff --git a/src/g_game.c b/src/g_game.c
index a1ca4e733..789c5cc5b 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -16,6 +16,7 @@
 #include "d_main.h"
 #include "d_player.h"
 #include "f_finale.h"
+#include "filesrch.h" // for refreshdirmenu
 #include "p_setup.h"
 #include "p_saveg.h"
 #include "i_system.h"
@@ -753,16 +754,21 @@ void G_SetNightsRecords(void)
 }*/
 
 // for consistency among messages: this modifies the game and removes savemoddata.
-void G_SetGameModified(boolean silent)
+void G_SetGameModified(boolean silent, boolean major)
 {
-	if (modifiedgame && !savemoddata)
+	if ((majormods && modifiedgame && !savemoddata) || (refreshdirmenu & REFRESHDIR_GAMEDATA)) // new gamedata amnesty?
 		return;
 
 	modifiedgame = true;
 	savemoddata = false;
 
+	if (!major)
+		return;
+
+	majormods = true;
+
 	if (!silent)
-		CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to record statistics.\n"));
+		CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to play record attack.\n"));
 
 	// If in record attack recording, cancel it.
 	if (modeattacking)
diff --git a/src/g_game.h b/src/g_game.h
index 14dc12d01..793cfe956 100644
--- a/src/g_game.h
+++ b/src/g_game.h
@@ -227,7 +227,7 @@ boolean G_GetRetryFlag(void);
 void G_LoadGameData(void);
 void G_LoadGameSettings(void);
 
-void G_SetGameModified(boolean silent);
+void G_SetGameModified(boolean silent, boolean major);
 
 void G_SetGamestate(gamestate_t newstate);
 
diff --git a/src/lua_script.c b/src/lua_script.c
index d7c4a160e..1f87d33ee 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -213,7 +213,7 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
 	LUA_LoadFile(&f, name); // actually load file!
 
 	// Okay, we've modified the game beyond the point of no return.
-	majormods = true;
+	G_SetGameModified(multiplayer, true);
 
 	free(name);
 	Z_Free(f.data);
diff --git a/src/m_cheat.c b/src/m_cheat.c
index 499dac28d..acb53b227 100644
--- a/src/m_cheat.c
+++ b/src/m_cheat.c
@@ -121,7 +121,7 @@ static UINT8 cheatf_devmode(void)
 	S_StartSound(0, sfx_itemup);
 
 	// Just unlock all the things and turn on -debug and console devmode.
-	G_SetGameModified(false);
+	G_SetGameModified(false, false); // might need to revist the latter later
 	for (i = 0; i < MAXUNLOCKABLES; i++)
 		unlockables[i].unlocked = true;
 	devparm = true;
@@ -295,7 +295,7 @@ void Command_CheatNoClip_f(void)
 	plyr->pflags ^= PF_NOCLIP;
 	CONS_Printf(M_GetText("No Clipping %s\n"), plyr->pflags & PF_NOCLIP ? M_GetText("On") : M_GetText("Off"));
 
-	G_SetGameModified(multiplayer);
+	G_SetGameModified(multiplayer, true);
 }
 
 void Command_CheatGod_f(void)
@@ -310,7 +310,7 @@ void Command_CheatGod_f(void)
 	plyr->pflags ^= PF_GODMODE;
 	CONS_Printf(M_GetText("Sissy Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off"));
 
-	G_SetGameModified(multiplayer);
+	G_SetGameModified(multiplayer, true);
 }
 
 void Command_CheatNoTarget_f(void)
@@ -325,7 +325,7 @@ void Command_CheatNoTarget_f(void)
 	plyr->pflags ^= PF_INVIS;
 	CONS_Printf(M_GetText("SEP Field %s\n"), plyr->pflags & PF_INVIS ? M_GetText("On") : M_GetText("Off"));
 
-	G_SetGameModified(multiplayer);
+	G_SetGameModified(multiplayer, true);
 }
 
 void Command_Scale_f(void)
@@ -727,7 +727,7 @@ void Command_Devmode_f(void)
 		return;
 	}
 
-	G_SetGameModified(multiplayer);
+	G_SetGameModified(multiplayer, true);
 }
 
 /*void Command_Setrings_f(void)
@@ -1267,8 +1267,7 @@ void Command_ObjectPlace_f(void)
 	REQUIRE_SINGLEPLAYER;
 	REQUIRE_NOULTIMATE;
 
-	G_SetGameModified(multiplayer);
-	majormods = true;
+	G_SetGameModified(multiplayer, true);
 
 	// Entering objectplace?
 	if (!objectplacing)
diff --git a/src/m_menu.c b/src/m_menu.c
index e68027c61..b1d9ba093 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -4555,7 +4555,7 @@ static boolean prevmajormods = false;
 
 static void M_AddonsClearName(INT32 choice)
 {
-	if (majormods == prevmajormods || savemoddata)
+	if (!majormods || prevmajormods)
 	{
 		CLEARNAME;
 	}
@@ -4568,10 +4568,14 @@ static boolean M_AddonsRefresh(void)
 	if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true))
 	{
 		UNEXIST;
+		CLEARNAME;
 		return true;
 	}
 
-	if ((refreshdirmenu & REFRESHDIR_ADDFILE) || (majormods != prevmajormods && !savemoddata))
+	if (!majormods && prevmajormods)
+		prevmajormods = false;
+
+	if ((refreshdirmenu & REFRESHDIR_ADDFILE) || (majormods && !prevmajormods))
 	{
 		char *message = NULL;
 
@@ -4588,7 +4592,7 @@ static boolean M_AddonsRefresh(void)
 			S_StartSound(NULL, sfx_s224);
 			message = va("%c%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings"));
 		}
-		else if (majormods != prevmajormods && !savemoddata)
+		else if (majormods && !prevmajormods && !savemoddata)
 		{
 			S_StartSound(NULL, sfx_s221);
 			message = va("%c%s\x80\nGameplay has now been modified.\nIf you want to play record attack mode, restart the game to clear existing add-ons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
@@ -5141,7 +5145,7 @@ static void M_GetAllEmeralds(INT32 choice)
 	emeralds = ((EMERALD7)*2)-1;
 	M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING);
 
-	G_SetGameModified(multiplayer);
+	G_SetGameModified(multiplayer, true);
 }
 
 static void M_DestroyRobotsResponse(INT32 ch)
@@ -5152,7 +5156,7 @@ static void M_DestroyRobotsResponse(INT32 ch)
 	// Destroy all robots
 	P_DestroyRobots();
 
-	G_SetGameModified(multiplayer);
+	G_SetGameModified(multiplayer, true);
 }
 
 static void M_DestroyRobots(INT32 choice)
diff --git a/src/p_setup.c b/src/p_setup.c
index 0a59a2a94..fcb1ac786 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -3459,7 +3459,7 @@ boolean P_AddWadFile(const char *wadfilename)
 			if (num <= NUMMAPS && mapheaderinfo[num-1])
 			{
 				if (mapheaderinfo[num-1]->menuflags & LF2_EXISTSHACK)
-					majormods = true; // oops, double-defined - no record attack privileges for you
+					G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
 				mapheaderinfo[num-1]->menuflags |= LF2_EXISTSHACK;
 			}
 
@@ -3489,6 +3489,8 @@ boolean P_AddWadFile(const char *wadfilename)
 			SendNetXCmd(XD_EXITLEVEL, NULL, 0);
 	}
 
+	refreshdirmenu &= ~REFRESHDIR_GAMEDATA; // Under usual circumstances we'd wait for REFRESHDIR_GAMEDATA to disappear the next frame, but it's a bit too dangerous for that...
+
 	return true;
 }
 
diff --git a/src/w_wad.c b/src/w_wad.c
index 58a65191d..efa09ce43 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -34,6 +34,7 @@
 #include "z_zone.h"
 #include "fastcmp.h"
 
+#include "g_game.h" // G_LoadGameData
 #include "filesrch.h"
 
 #include "i_video.h" // rendermode
@@ -799,6 +800,8 @@ UINT16 W_InitFile(const char *filename)
 		break;
 	}
 
+	if (refreshdirmenu & REFRESHDIR_GAMEDATA)
+		G_LoadGameData();
 	DEH_UpdateMaxFreeslots();
 
 	W_InvalidateLumpnumCache();
-- 
GitLab