diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm index 8916316f9a3..08d21673c7f 100644 --- a/code/game/antagonist/antagonist.dm +++ b/code/game/antagonist/antagonist.dm @@ -77,6 +77,7 @@ /datum/antagonist/proc/attempt_random_spawn() attempt_spawn(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB)) + finalize_spawn() /datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player) if(!can_late_spawn()) @@ -89,6 +90,11 @@ add_antagonist(player,0,1,0,1,1) return +//Selects players that will be spawned in the antagonist role from the potential candidates +//Selected players are added to the pending_antagonists lists. +//Attempting to spawn an antag role with ANTAG_OVERRIDE_JOB should be done before jobs are assigned, +//so that they do not occupy regular job slots. All other antag roles should be spawned after jobs are +//assigned, so that job restrictions can be respected. /datum/antagonist/proc/attempt_spawn(var/ghosts_only) // Get the raw list of potential players. @@ -99,29 +105,43 @@ 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) - pending_antagonists |= player candidates -= player + draft_antagonist(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/draft_antagonist(var/datum/mind/player) + //Check if the player can join in this antag role, or if the player has already been given an antag role. + if(can_become_antag(player) && !player.special_role) + return 0 + + pending_antagonists |= player + + //Ensure that antags with ANTAG_OVERRIDE_JOB do not occupy job slots. + if(flags & ANTAG_OVERRIDE_JOB) + player.assigned_role = role_text + + //Ensure that a player cannot be drafted for multiple antag roles, taking up slots for antag roles that they will not fill. + player.special_role = role_text + + return 1 + +//Spawns all pending_antagonists. This is done separately from attempt_spawn in case the game mode setup fails. /datum/antagonist/proc/finalize_spawn() if(!pending_antagonists) return - while(pending_antagonists.len && current_antagonists.len < cur_max) - var/datum/mind/player = pick(pending_antagonists) + for(var/datum/mind/player in 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) + add_antagonist(player,0,0,1) + +//Resets all pending_antagonists, clearing their special_role (and assigned_role if ANTAG_OVERRIDE_JOB is set) +/datum/antagonist/proc/reset() + for(var/datum/mind/player in pending_antagonists) + if(flags & ANTAG_OVERRIDE_JOB) + player.assigned_role = null + player.special_role = null + pending_antagonists.Cut() diff --git a/code/game/antagonist/antagonist_add.dm b/code/game/antagonist/antagonist_add.dm index c16ea0a7c9f..7815167d6fe 100644 --- a/code/game/antagonist/antagonist_add.dm +++ b/code/game/antagonist/antagonist_add.dm @@ -9,6 +9,8 @@ return 0 current_antagonists |= player + + //do this again, just in case if(flags & ANTAG_OVERRIDE_JOB) player.assigned_role = role_text player.special_role = role_text diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 5047562e902..3ed80e11548 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -185,14 +185,9 @@ var/global/list/additional_antag_types = list() /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 + for(var/datum/antagonist/antag in antag_templates) + if(antag.flags & ANTAG_OVERRIDE_JOB) + antag.attempt_spawn() ///post_setup() /datum/game_mode/proc/post_setup() @@ -208,11 +203,12 @@ var/global/list/additional_antag_types = list() 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() - if(antag.is_latejoin_template()) - latejoin_templates |= antag + for(var/datum/antagonist/antag in antag_templates) + if(!(antag.flags & ANTAG_OVERRIDE_JOB)) + antag.attempt_spawn() + antag.finalize_spawn() + if(antag.is_latejoin_template()) + latejoin_templates |= antag if(emergency_shuttle && auto_recall_shuttle) emergency_shuttle.auto_recall = 1 @@ -223,6 +219,10 @@ var/global/list/additional_antag_types = list() feedback_set_details("server_ip","[world.internet_address]:[world.port]") return 1 +/datum/game_mode/proc/fail_setup() + for(var/datum/antagonist/antag in antag_templates) + antag.reset() + /datum/game_mode/proc/announce_ert_disabled() if(!ert_disabled) return diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 70fd6eb1992..614d181795d 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -98,6 +98,7 @@ var/global/datum/controller/gameticker/ticker if(!mode_started && !src.mode.can_start()) world << "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby." current_state = GAME_STATE_PREGAME + mode.fail_setup() mode = null job_master.ResetOccupations() return 0 diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index ef217b16f96..37fc52eda80 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -52,4 +52,4 @@ var/const/commandos_possible = 6 //if more Commandos are needed in the future usr << "Looks like someone beat you to it." return - team.attempt_spawn(1) + team.attempt_random_spawn() diff --git a/code/modules/lighting/light_source.dm b/code/modules/lighting/light_source.dm index ce2ee837a62..73a65f064fc 100644 --- a/code/modules/lighting/light_source.dm +++ b/code/modules/lighting/light_source.dm @@ -51,8 +51,8 @@ /datum/light_source/proc/destroy() destroyed = 1 force_update() - if(source_atom) source_atom.light_sources -= src - if(top_atom) top_atom.light_sources -= src + if(source_atom && source_atom.light_sources) source_atom.light_sources -= src + if(top_atom && top_atom.light_sources) top_atom.light_sources -= src /datum/light_source/proc/update(atom/new_top_atom) if(new_top_atom && new_top_atom != top_atom) @@ -62,7 +62,7 @@ if(!top_atom.light_sources) top_atom.light_sources = list() top_atom.light_sources += src - if(!needs_update) + if(!needs_update) //Incase we're already updating either way. lighting_update_lights += src needs_update = 1 @@ -130,16 +130,16 @@ #if LIGHTING_FALLOFF == 1 //circular #define LUM_DISTANCE(swapvar, O, T) swapvar = (O.x - T.x)**2 + (O.y - T.y)**2 + LIGHTING_HEIGHT #if LIGHTING_LAMBERTIAN == 1 - #define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / light_range)) * (1 / sqrt(swapvar + 1))) + #define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / max(1,light_range))) * (1 / sqrt(swapvar + 1))) #else - #define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / light_range) + #define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / max(1,light_range)) #endif #elif LIGHTING_FALLOFF == 2 //square #define LUM_DISTANCE(swapvar, O, T) swapvar = abs(O.x - T.x) + abs(O.y - T.y) + LIGHTING_HEIGHT #if LIGHTING_LAMBERTIAN == 1 - #define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / light_range)) * (1 / sqrt(swapvar**2 + 1))) + #define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / max(1,light_range))) * (1 / sqrt(swapvar**2 + 1))) #else - #define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / light_range) + #define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / max(1,light_range)) #endif #endif @@ -203,7 +203,6 @@ FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING) view += T //Filter out turfs. END_FOR_DVIEW - //This is the part where we calculate new turfs (if any) var/list/new_turfs = view - effect_turf //This will result with all the tiles that are added. for(var/turf/T in new_turfs) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 39904901459..9413fa4fc5d 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -185,10 +185,6 @@ return valid_facial_hairstyles -/proc/q() - var/mob/living/carbon/human/H = usr - H.change_appearance(APPEARANCE_ALL) - /mob/living/carbon/human/proc/force_update_limbs() for(var/obj/item/organ/external/O in organs) O.sync_colour_to_human(src)