diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm index 4d2ff951ea..8916316f9a 100644 --- a/code/game/antagonist/antagonist.dm +++ b/code/game/antagonist/antagonist.dm @@ -60,7 +60,8 @@ /datum/antagonist/proc/get_candidates(var/ghosts_only) candidates = list() // Clear. candidates = ticker.mode.get_players_for_role(role_type, id) - // Prune restricted jobs and status. Broke it up for readability. + // Prune restricted status. Broke it up for readability. + // Note that this is done before jobs are handed out. for(var/datum/mind/player in candidates) if(ghosts_only && !istype(player.current, /mob/dead)) candidates -= player @@ -98,6 +99,10 @@ if(!candidates.len) return 0 + // Not sure if this is necessary, just in case. + pending_antagonists = candidates + candidates = list() + //Grab candidates randomly until we have enough. while(candidates.len && pending_antagonists.len < cur_max) var/datum/mind/player = pick(candidates) @@ -105,10 +110,18 @@ candidates -= player return 1 +//Drafting players into the antagonist role must be done when antagonists are finalized. +//This ensures that if a player is a candidate for multiple antag roles, they do not prevent other +//players from being selected for all of the other antag roles that the player was not selected for. /datum/antagonist/proc/finalize_spawn() - if(!pending_antagonists || !pending_antagonists.len) + if(!pending_antagonists) return - for(var/datum/mind/player in pending_antagonists) + + while(pending_antagonists.len && current_antagonists.len < cur_max) + var/datum/mind/player = pick(pending_antagonists) + pending_antagonists -= player + + //Check for restricted job status since players will have been assigned jobs by this point. + //Or if the player has already been given an antag role. if(can_become_antag(player) && !player.special_role) add_antagonist(player,0,0,1) - pending_antagonists.Cut() diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index e8962eb294..5d5244fcc0 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -249,8 +249,6 @@ var/global/list/additional_antag_types = list() var/datum/antagonist/main_antags = antag_templates[1] var/list/candidates = main_antags.get_candidates() if(candidates.len >= required_enemies) - for(var/datum/antagonist/antag in antag_templates) - antag.attempt_spawn() return 1 return 0 @@ -264,6 +262,17 @@ var/global/list/additional_antag_types = list() var/datum/event_container/EMajor = event_manager.event_containers[EVENT_LEVEL_MAJOR] EMajor.delay_modifier = event_delay_mod_major +/datum/game_mode/proc/pre_setup() + //antag roles that replace jobs need to be assigned before the job controller hands out jobs. + if(antag_templates) + for(var/datum/antagonist/antag in antag_templates) + antag.attempt_spawn() //selects antag role candidates + + if(antag.flags & ANTAG_OVERRIDE_JOB) + antag.finalize_spawn() + if(antag.is_latejoin_template()) + latejoin_templates |= antag + ///post_setup() /datum/game_mode/proc/post_setup() @@ -277,6 +286,7 @@ var/global/list/additional_antag_types = list() spawn(rand(100,150)) announce_ert_disabled() + //Assign all antag types for this game mode. Any players spawned as antags earlier should have been removed from the pending list, so no need to worry about those. if(antag_templates && antag_templates.len) for(var/datum/antagonist/antag in antag_templates) antag.finalize_spawn() diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 422e3acd63..d9a91cb57d 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -91,6 +91,8 @@ var/global/datum/controller/gameticker/ticker else src.mode = config.pick_mode(master_mode) + src.mode.pre_setup() + job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly. if(!mode_started && !src.mode.can_start())