diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 1d6d64efb2a..a9a1955ad2d 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -85,10 +85,14 @@ //randomised elements #define RANDOM_NAME "random_name" +#define RANDOM_NAME_ANTAG "random_name_antag" #define RANDOM_BODY "random_body" +#define RANDOM_BODY_ANTAG "random_body_antag" #define RANDOM_SPECIES "random_species" #define RANDOM_GENDER "random_gender" +#define RANDOM_GENDER_ANTAG "random_gender_antag" #define RANDOM_AGE "random_age" +#define RANDOM_AGE_ANTAG "random_age_antag" #define RANDOM_UNDERWEAR "random_underwear" #define RANDOM_UNDERWEAR_COLOR "random_underwear_color" #define RANDOM_UNDERSHIRT "random_undershirt" @@ -100,4 +104,4 @@ #define RANDOM_FACIAL_HAIR_COLOR "random_facial_hair_color" #define RANDOM_FACIAL_HAIRSTYLE "random_facial_hairstyle" #define RANDOM_SKIN_TONE "random_skin_tone" -#define RANDOM_EYE_COLOR "random_eye_color" \ No newline at end of file +#define RANDOM_EYE_COLOR "random_eye_color" diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 8026afae47b..5635cd7b3e7 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -18,6 +18,7 @@ GLOBAL_LIST_EMPTY(drones_list) GLOBAL_LIST_EMPTY(dead_mob_list) //all dead mobs, including clientless. Excludes /mob/dead/new_player GLOBAL_LIST_EMPTY(joined_player_list) //all clients that have joined the game at round-start or as a latejoin. GLOBAL_LIST_EMPTY(new_player_list) //all /mob/dead/new_player, in theory all should have clients and those that don't are in the process of spawning and get deleted when done. +GLOBAL_LIST_EMPTY(pre_setup_antags) //minds that have been picked as antag by the gamemode. removed as antag datums are set. GLOBAL_LIST_EMPTY(silicon_mobs) //all silicon mobs GLOBAL_LIST_EMPTY(mob_living_list) //all instances of /mob/living and subtypes GLOBAL_LIST_EMPTY(carbon_list) //all instances of /mob/living/carbon and subtypes, notably does not contain brains or simple animals diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index e25c4f7716f..5405133e4f0 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -45,7 +45,12 @@ bro.restricted_roles = restricted_jobs log_game("[key_name(bro)] has been selected as a Brother") pre_brother_teams += team - return ..() + . = ..() + if(.) //To ensure the game mode is going ahead + for(var/teams in pre_brother_teams) + for(var/antag in teams) + GLOB.pre_setup_antags += antag + return /datum/game_mode/traitor/bros/post_setup() for(var/datum/team/brother_team/team in pre_brother_teams) @@ -53,6 +58,7 @@ team.forge_brother_objectives() for(var/datum/mind/M in team.members) M.add_antag_datum(/datum/antagonist/brother, team) + GLOB.pre_setup_antags -= M team.update_name() brother_teams += pre_brother_teams return ..() diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index e6524309d92..da872601855 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -51,10 +51,11 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th changelings += changeling changeling.special_role = ROLE_CHANGELING changeling.restricted_roles = restricted_jobs - return 1 + GLOB.pre_setup_antags += changeling + return TRUE else setup_error = "Not enough changeling candidates" - return 0 + return FALSE /datum/game_mode/changeling/post_setup() //Decide if it's ok for the lings to have a team objective @@ -75,6 +76,7 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th var/datum/antagonist/changeling/new_antag = new() new_antag.team_mode = TRUE changeling.add_antag_datum(new_antag) + GLOB.pre_setup_antags -= changeling ..() /datum/game_mode/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index ef9b710d7b0..96ed649251d 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -51,13 +51,18 @@ changeling.special_role = ROLE_CHANGELING changelings += changeling changeling.restricted_roles = restricted_jobs - return ..() + . = ..() + if(.) //To ensure the game mode is going ahead + for(var/antag in changelings) + GLOB.pre_setup_antags += antag + return else - return 0 + return FALSE /datum/game_mode/traitor/changeling/post_setup() for(var/datum/mind/changeling in changelings) changeling.add_antag_datum(/datum/antagonist/changeling) + GLOB.pre_setup_antags -= changeling return ..() /datum/game_mode/traitor/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 00e77dc0cfc..5f9d3649010 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -174,9 +174,10 @@ Credit where due: servant.assigned_role = ROLE_SERVANT_OF_RATVAR servant.special_role = ROLE_SERVANT_OF_RATVAR starter_servants-- + GLOB.pre_setup_antags += servant ark_time = 30 + round((roundstart_player_count / 5)) //In minutes, how long the Ark will wait before activation ark_time = min(ark_time, 35) //35 minute maximum for the activation timer - return 1 + return TRUE /datum/game_mode/clockwork_cult/post_setup() var/list/spread_out_spawns = GLOB.servant_spawns.Copy() @@ -191,20 +192,21 @@ Credit where due: greet_servant(L) equip_servant(L) add_servant_of_ratvar(L, TRUE) + GLOB.pre_setup_antags -= S var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar //that's a mouthful G.final_countdown(ark_time) ..() - return 1 + return TRUE /datum/game_mode/clockwork_cult/proc/greet_servant(mob/M) //Description of their role if(!M) - return 0 + return FALSE to_chat(M, "You are a servant of Ratvar, the Clockwork Justiciar!") to_chat(M, "You have approximately [ark_time] minutes until the Ark activates.") to_chat(M, "Unlock Script scripture by converting a new servant.") to_chat(M, "Application scripture will be unlocked halfway until the Ark's activation.") M.playsound_local(get_turf(M), 'sound/ambience/antag/clockcultalr.ogg', 100, FALSE, pressure_affected = FALSE) - return 1 + return TRUE /datum/game_mode/proc/equip_servant(mob/living/M) //Grants a clockwork slab to the mob, with one of each component if(!M || !ishuman(M)) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 091f40cda08..202bc0faafe 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -83,6 +83,8 @@ log_game("[key_name(cultist)] has been selected as a cultist") if(cultists_to_cult.len>=required_enemies) + for(var/antag in cultists_to_cult) + GLOB.pre_setup_antags += antag return TRUE else setup_error = "Not enough cultist candidates" @@ -94,6 +96,7 @@ for(var/datum/mind/cult_mind in cultists_to_cult) add_cultist(cult_mind, 0, equip=TRUE, cult_team = main_cult) + GLOB.pre_setup_antags -= cult_mind main_cult.setup_objectives() //Wait until all cultists are assigned to make sure none will be chosen as sacrifice. diff --git a/code/game/gamemodes/devil/devil_game_mode.dm b/code/game/gamemodes/devil/devil_game_mode.dm index 024fe24a63b..09b8326d5c2 100644 --- a/code/game/gamemodes/devil/devil_game_mode.dm +++ b/code/game/gamemodes/devil/devil_game_mode.dm @@ -47,15 +47,17 @@ if(devils.len < required_enemies) setup_error = "Not enough devil candidates" - return 0 - return 1 + return FALSE + for(var/antag in devils) + GLOB.pre_setup_antags += antag + return TRUE /datum/game_mode/devil/post_setup() for(var/datum/mind/devil in devils) post_setup_finalize(devil) ..() - return 1 + return TRUE /datum/game_mode/devil/generate_report() return "Infernal creatures have been seen nearby offering great boons in exchange for souls. This is considered theft against Nanotrasen, as all employment contracts contain a lien on the \ @@ -63,6 +65,7 @@ /datum/game_mode/devil/proc/post_setup_finalize(datum/mind/devil) add_devil(devil.current, ascendable = TRUE) //Devil gamemode devils are ascendable. + GLOB.pre_setup_antags -= devil add_devil_objectives(devil,2) /proc/is_devil(mob/living/M) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index fe4aa64304c..3445d0ee1bb 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -110,6 +110,7 @@ /datum/dynamic_ruleset/proc/execute() for(var/datum/mind/M in assigned) M.add_antag_datum(antag_datum) + GLOB.pre_setup_antags -= M return TRUE /// Here you can perform any additional checks you want. (such as checking the map etc) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index cd839214057..532100547f9 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -28,6 +28,7 @@ assigned += M.mind M.mind.special_role = ROLE_TRAITOR M.mind.restricted_roles = restricted_roles + GLOB.pre_setup_antags += M.mind return TRUE /datum/dynamic_ruleset/roundstart/traitor/rule_process() @@ -77,6 +78,7 @@ team.add_member(bro.mind) bro.mind.special_role = "brother" bro.mind.restricted_roles = restricted_roles + GLOB.pre_setup_antags += bro.mind pre_brother_teams += team return TRUE @@ -86,6 +88,7 @@ team.forge_brother_objectives() for(var/datum/mind/M in team.members) M.add_antag_datum(/datum/antagonist/brother, team) + GLOB.pre_setup_antags -= M team.update_name() mode.brother_teams += pre_brother_teams return TRUE @@ -116,6 +119,7 @@ assigned += M.mind M.mind.restricted_roles = restricted_roles M.mind.special_role = ROLE_CHANGELING + GLOB.pre_setup_antags += M.mind return TRUE /datum/dynamic_ruleset/roundstart/changeling/execute() @@ -135,6 +139,7 @@ var/datum/antagonist/changeling/new_antag = new antag_datum() new_antag.team_mode = team_mode changeling.add_antag_datum(new_antag) + GLOB.pre_setup_antags -= changeling return TRUE ////////////////////////////////////////////// @@ -173,7 +178,7 @@ assigned += M.mind M.mind.assigned_role = ROLE_WIZARD M.mind.special_role = ROLE_WIZARD - + return TRUE /datum/dynamic_ruleset/roundstart/wizard/execute() @@ -218,6 +223,7 @@ assigned += M.mind M.mind.special_role = ROLE_CULTIST M.mind.restricted_roles = restricted_roles + GLOB.pre_setup_antags += M.mind return TRUE /datum/dynamic_ruleset/roundstart/bloodcult/execute() @@ -227,6 +233,7 @@ new_cultist.cult_team = main_cult new_cultist.give_equipment = TRUE M.add_antag_datum(new_cultist) + GLOB.pre_setup_antags -= M main_cult.setup_objectives() return TRUE @@ -361,6 +368,7 @@ assigned += M.mind M.mind.restricted_roles = restricted_roles M.mind.special_role = antag_flag + GLOB.pre_setup_antags += M.mind return TRUE /datum/dynamic_ruleset/roundstart/revs/execute() @@ -371,6 +379,7 @@ new_head.give_hud = TRUE new_head.remove_clumsy = TRUE M.add_antag_datum(new_head,revolution) + GLOB.pre_setup_antags -= M revolution.update_objectives() revolution.update_heads() SSshuttle.registerHostileEnvironment(src) @@ -480,6 +489,7 @@ assigned += servant.mind servant.mind.assigned_role = ROLE_SERVANT_OF_RATVAR servant.mind.special_role = ROLE_SERVANT_OF_RATVAR + GLOB.pre_setup_antags += servant.mind ark_time = 30 + round((number_players / 5)) ark_time = min(ark_time, 35) return TRUE @@ -496,6 +506,7 @@ greet_servant(S) equip_servant(S) add_servant_of_ratvar(S, TRUE) + GLOB.pre_setup_antags -= S.mind var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar //that's a mouthful G.final_countdown(ark_time) return TRUE @@ -601,6 +612,7 @@ assigned += devil.mind devil.mind.special_role = ROLE_DEVIL devil.mind.restricted_roles = restricted_roles + GLOB.pre_setup_antags += devil.mind log_game("[key_name(devil)] has been selected as a devil") return TRUE @@ -608,6 +620,7 @@ /datum/dynamic_ruleset/roundstart/devil/execute() for(var/datum/mind/devil in assigned) add_devil(devil.current, ascendable = TRUE) + GLOB.pre_setup_antags -= devil add_devil_objectives(devil,2) return TRUE diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 23924107fa9..cca64be11d8 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -55,6 +55,8 @@ setup_error = "Not enough headrev candidates" return FALSE + for(var/antag in headrev_candidates) + GLOB.pre_setup_antags += antag return TRUE /datum/game_mode/revolution/post_setup() @@ -97,6 +99,7 @@ new_head.give_hud = TRUE new_head.remove_clumsy = TRUE rev_mind.add_antag_datum(new_head,revolution) + GLOB.pre_setup_antags -= rev_mind revolution.update_objectives() revolution.update_heads() diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index fe8948ed0d6..81813188f32 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -63,6 +63,9 @@ setup_error = "Not enough traitor candidates" return FALSE else + for(var/antag in pre_traitors) + GLOB.pre_setup_antags += antag + to_chat(world, "Added [antag] to pre-antag list") return TRUE @@ -70,6 +73,7 @@ for(var/datum/mind/traitor in pre_traitors) var/datum/antagonist/traitor/new_antag = new antag_datum() addtimer(CALLBACK(traitor, /datum/mind.proc/add_antag_datum, new_antag), rand(10,100)) + GLOB.pre_setup_antags -= traitor if(!exchange_blue) exchange_blue = -1 //Block latejoiners from getting exchange objectives ..() diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index ca4478a6b4b..feb29d1e51a 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -48,6 +48,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/uses_glasses_colour = 0 //character preferences + var/slot_randomized //keeps track of round-to-round randomization of the character slot, prevents overwriting var/real_name //our character's name var/gender = MALE //gender of character (well duh) var/age = 30 //age of character @@ -137,6 +138,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) /datum/preferences/proc/ShowChoices(mob/user) if(!user || !user.client) return + if(slot_randomized) + load_character(default_slot) // Reloads the character slot. Prevents random features from overwriting the slot if saved. + slot_randomized = FALSE update_preview_icon() var/list/dat = list("
") @@ -182,8 +186,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(is_banned_from(user.ckey, "Appearance")) dat += "You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game.
" dat += "Random Name " - dat += "Always Random Name: [(randomise[RANDOM_NAME]) ? "Yes" : "No"]
" - dat += "Name: " + dat += "Always Random Name: [(randomise[RANDOM_NAME]) ? "Yes" : "No"]" + dat += "When Antagonist: [(randomise[RANDOM_NAME_ANTAG]) ? "Yes" : "No"]" + dat += "
Name: " dat += "[real_name]
" if(!(AGENDER in pref_species.species_traits)) @@ -195,10 +200,14 @@ GLOBAL_LIST_EMPTY(preferences_datums) else dispGender = "Other" dat += "Gender: [dispGender]" - dat += "Always Random Gender: [(randomise[RANDOM_GENDER]) ? "Yes" : "No"]" + if(randomise[RANDOM_BODY] || randomise[RANDOM_BODY_ANTAG]) //doesn't work unless random body + dat += "Always Random Gender: [(randomise[RANDOM_GENDER]) ? "Yes" : "No"]" + dat += "When Antagonist: [(randomise[RANDOM_GENDER_ANTAG]) ? "Yes" : "No"]" dat += "
Age: [age]" - dat += "Always Random Age: [(randomise[RANDOM_AGE]) ? "Yes" : "No"]" + if(randomise[RANDOM_BODY] || randomise[RANDOM_BODY_ANTAG]) //doesn't work unless random body + dat += "Always Random Age: [(randomise[RANDOM_AGE]) ? "Yes" : "No"]" + dat += "When Antagonist: [(randomise[RANDOM_AGE_ANTAG]) ? "Yes" : "No"]" dat += "

Special Names:
" var/old_group @@ -220,7 +229,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "

Body

" dat += "Random Body " - dat += "Always Random Body: [(randomise[RANDOM_BODY]) ? "Yes" : "No"]
" + dat += "Always Random Body: [(randomise[RANDOM_BODY]) ? "Yes" : "No"]" + dat += "When Antagonist: [(randomise[RANDOM_BODY_ANTAG]) ? "Yes" : "No"]
" dat += "
" @@ -1561,15 +1571,17 @@ GLOBAL_LIST_EMPTY(preferences_datums) ShowChoices(user) return 1 -/datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1, roundstart_checks = TRUE, character_setup = FALSE) +/datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1, roundstart_checks = TRUE, character_setup = FALSE, antagonist = FALSE) if(randomise[RANDOM_SPECIES] && !character_setup) random_species() - if(randomise[RANDOM_BODY] && !character_setup) - random_character(gender) + if((randomise[RANDOM_BODY] || randomise[RANDOM_BODY_ANTAG] && antagonist) && !character_setup) + slot_randomized = TRUE + random_character(gender, antagonist) - if(randomise[RANDOM_NAME] && !character_setup) + if((randomise[RANDOM_NAME] || randomise[RANDOM_NAME_ANTAG] && antagonist) && !character_setup) + slot_randomized = TRUE real_name = pref_species.random_name(gender) if(roundstart_checks) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index e70957e325f..d013fdaf18b 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -481,7 +481,12 @@ if(frn) client.prefs.random_character() client.prefs.real_name = client.prefs.pref_species.random_name(gender,1) - client.prefs.copy_to(H) + + var/is_antag + if(mind in GLOB.pre_setup_antags) + is_antag = TRUE + + client.prefs.copy_to(H, antagonist = is_antag) H.dna.update_dna_identity() if(mind) if(transfer_after) diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index 547918295d8..7dd7a596c25 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -1,15 +1,15 @@ //The mob should have a gender you want before running this proc. Will run fine without H -/datum/preferences/proc/random_character(gender_override) +/datum/preferences/proc/random_character(gender_override, antag_override = FALSE) if(randomise[RANDOM_SPECIES]) random_species() else if(randomise[RANDOM_NAME]) real_name = pref_species.random_name(gender,1) - if(gender_override && !(randomise[RANDOM_GENDER])) + if(gender_override && !(randomise[RANDOM_GENDER] || randomise[RANDOM_GENDER_ANTAG] && antag_override)) gender = gender_override else - gender = pick(MALE,FEMALE) - if(randomise[RANDOM_AGE]) + gender = pick(MALE,FEMALE,PLURAL) + if(randomise[RANDOM_AGE] || randomise[RANDOM_AGE_ANTAG] && antag_override) age = rand(AGE_MIN,AGE_MAX) if(randomise[RANDOM_UNDERWEAR]) underwear = random_underwear(gender) @@ -74,4 +74,4 @@ COMPILE_OVERLAYS(mannequin) parent.show_character_previews(new /mutable_appearance(mannequin)) - unset_busy_human_dummy(DUMMY_HUMAN_SLOT_PREFERENCES) \ No newline at end of file + unset_busy_human_dummy(DUMMY_HUMAN_SLOT_PREFERENCES)