diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 09b5be572f..9cabc16a45 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -41,11 +41,13 @@
#define ROLE_GHOSTCAFE "ghostcafe"
#define ROLE_MINOR_ANTAG "minorantag"
#define ROLE_RESPAWN "respawnsystem"
+/// Not an actual antag. Lets players force all antags off.
+#define ROLE_NO_ANTAGONISM "NO_ANTAGS"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
//(in game days played) to play that role
GLOBAL_LIST_INIT(special_roles, list(
- ROLE_SYNDICATE,
+ ROLE_NO_ANTAGONISM,
ROLE_TRAITOR = /datum/game_mode/traitor,
ROLE_BROTHER = /datum/game_mode/traitor/bros,
ROLE_OPERATIVE = /datum/game_mode/nuclear,
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 610db63b1b..5ea99da479 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -420,7 +420,7 @@
for(var/mob/dead/new_player/player in players)
if(player.client && player.ready == PLAYER_READY_TO_PLAY)
- if((role in player.client.prefs.be_special) && (ROLE_SYNDICATE in player.client.prefs.be_special))
+ if((role in player.client.prefs.be_special) && !(ROLE_NO_ANTAGONISM in player.client.prefs.be_special))
if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player)) //Nodrak/Carn: Antag Job-bans
if(age_check(player.client)) //Must be older than the minimum age
candidates += player.mind // Get a list of all the people who want to be the antagonist for this round
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 151b271d9e..257a520af8 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -54,7 +54,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/tip_delay = 500 //tip delay in milliseconds
//Antag preferences
- var/list/be_special = list() //Special role selection
+ var/list/be_special = list() //Special role selection. ROLE_SYNDICATE being missing means they will never be antag!
var/tmp/old_be_special = 0 //Bitflag version of be_special, used to update old savefiles and nothing more
//If it's 0, that's good, if it's anything but 0, the owner of this prefs file's antag choices were,
//autocorrected this round, not that you'd need to check that.
@@ -851,6 +851,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
for (var/i in GLOB.special_roles)
+ if(i == ROLE_NO_ANTAGONISM)
+ dat += "DISABLE ALL ANTAGONISM [(i in be_special) ? "YES" : "NO"]
"
+ continue
if(jobban_isbanned(user, i))
dat += "Be [capitalize(i)]: BANNED
"
else
@@ -863,7 +866,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(days_remaining)
dat += "Be [capitalize(i)]: \[IN [days_remaining] DAYS]
"
else
- dat += "Be [i == ROLE_SYNDICATE ? "Antag": capitalize(i)]: [(i in be_special) ? "Enabled" : "Disabled"]
"
+ dat += "Be [capitalize(i)]: [(i in be_special) ? "Enabled" : "Disabled"]
"
dat += "Midround Antagonist: [(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]
"
dat += "
"
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 812e8c4821..b8959d93aa 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
-#define SAVEFILE_VERSION_MAX 48
+#define SAVEFILE_VERSION_MAX 50
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -288,6 +288,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(current_version < 48) //unlockable loadout items but we need to clear bad data from a mistake
S["unlockable_loadout"] = list()
+ if(current_version < 50)
+ var/list/L
+ S["be_special"] >> L
+ if(islist(L))
+ L -= ROLE_SYNDICATE
+ S["be_special"] << L
+
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
return