diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 65aaa36fbb9f..020efe8d0858 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -342,7 +342,13 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list( #define HUNTER_PACK_PSYKER "Psyker Shikaris" // This flag disables certain checks that presume antagonist datums mean 'baddie'. -#define FLAG_FAKE_ANTAG (1 << 0) +#define FLAG_FAKE_ANTAG (1 << 0) +/// monkestation addition: Whether the antagonist can see exploitable info on people they examine. +#define FLAG_CAN_SEE_EXPOITABLE_INFO (1 << 1) +// monkestation addition: The storyteller will ignore this antag datum as counting against the antag cap. +#define FLAG_ANTAG_CAP_IGNORE (1 << 2) +// monkestation addition: The storyteller will count everyone on this antag's team as a singular antag instead. +#define FLAG_ANTAG_CAP_TEAM (1 << 3) #define FREEDOM_IMPLANT_CHARGES 4 diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 5634f11b172c..5fb06027a5fc 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -287,7 +287,7 @@ GLOBAL_REAL(Master, /datum/controller/master) if(sleep_offline_after_initializations && CONFIG_GET(flag/resume_after_initializations)) world.sleep_offline = FALSE initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10 - SSgamemode.handle_picking_stroyteller() //monkestation edit + SSgamemode.handle_picking_storyteller() //monkestation edit /** * Initialize a given subsystem and handle the results. diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 19a346e3654c..9ea41eca4aba 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -54,7 +54,7 @@ GLOBAL_LIST_EMPTY(antagonists) /// The typepath for the outfit to show in the preview for the preferences menu. var/preview_outfit /// Flags for antags to turn on or off and check! - var/antag_flags = NONE + var/antag_flags = FLAG_CAN_SEE_EXPOITABLE_INFO // monkestation edit: allow antags to see exploitable info. /// If true, this antagonist can assign themself a new objective var/can_assign_self_objectives = FALSE /// Default to fill in when entering a custom objective. diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm index d3d5bf24b66c..ed32ca368d5a 100644 --- a/code/modules/antagonists/abductor/abductor.dm +++ b/code/modules/antagonists/abductor/abductor.dm @@ -7,6 +7,7 @@ show_in_antagpanel = FALSE //should only show subtypes show_to_ghosts = TRUE suicide_cry = "FOR THE MOTHERSHIP!!" // They can't even talk but y'know + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_TEAM // monkestation addition var/datum/team/abductor_team/team var/sub_role var/outfit diff --git a/code/modules/antagonists/blob/blob_minion.dm b/code/modules/antagonists/blob/blob_minion.dm index 9bf37e961d5d..3e3f7647bcfd 100644 --- a/code/modules/antagonists/blob/blob_minion.dm +++ b/code/modules/antagonists/blob/blob_minion.dm @@ -4,6 +4,7 @@ show_name_in_check_antagonists = TRUE show_to_ghosts = TRUE show_in_antagpanel = FALSE + antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition /// The blob core that this minion is attached to var/datum/weakref/overmind diff --git a/code/modules/antagonists/brother/brother.dm b/code/modules/antagonists/brother/brother.dm index 8218544a305e..22991570da91 100644 --- a/code/modules/antagonists/brother/brother.dm +++ b/code/modules/antagonists/brother/brother.dm @@ -8,6 +8,7 @@ ui_name = "AntagInfoBrother" suicide_cry = "FOR MY BROTHER!!" antag_moodlet = /datum/mood_event/focused + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_TEAM // monkestation addition VAR_PRIVATE datum/team/brother_team/team diff --git a/code/modules/antagonists/changeling/fallen_changeling.dm b/code/modules/antagonists/changeling/fallen_changeling.dm index c44c1b66cd3d..ba5d3c3976ba 100644 --- a/code/modules/antagonists/changeling/fallen_changeling.dm +++ b/code/modules/antagonists/changeling/fallen_changeling.dm @@ -6,6 +6,7 @@ job_rank = ROLE_CHANGELING antag_moodlet = /datum/mood_event/fallen_changeling antag_hud_name = "changeling" + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition /datum/mood_event/fallen_changeling description = "My powers! Where are my powers?!" diff --git a/code/modules/antagonists/heretic/heretic_monsters.dm b/code/modules/antagonists/heretic/heretic_monsters.dm index 4e76b11c90c6..db220e93bd5d 100644 --- a/code/modules/antagonists/heretic/heretic_monsters.dm +++ b/code/modules/antagonists/heretic/heretic_monsters.dm @@ -8,6 +8,7 @@ antag_hud_name = "heretic_beast" suicide_cry = "MY MASTER SMILES UPON ME!!" show_in_antagpanel = FALSE + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition /// Our master (a heretic)'s mind. var/datum/mind/master diff --git a/code/modules/antagonists/magic_servant/servant.dm b/code/modules/antagonists/magic_servant/servant.dm index f6ecaf80cf6c..8851776213fe 100644 --- a/code/modules/antagonists/magic_servant/servant.dm +++ b/code/modules/antagonists/magic_servant/servant.dm @@ -3,6 +3,7 @@ show_in_roundend = FALSE show_in_antagpanel = FALSE show_name_in_check_antagonists = TRUE + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition /datum/antagonist/magic_servant/proc/setup_master(mob/M) var/datum/objective/O = new("Serve [M.real_name].") diff --git a/code/modules/antagonists/pirate/pirate.dm b/code/modules/antagonists/pirate/pirate.dm index d499a8034d80..8812de960ddd 100644 --- a/code/modules/antagonists/pirate/pirate.dm +++ b/code/modules/antagonists/pirate/pirate.dm @@ -7,6 +7,7 @@ show_to_ghosts = TRUE suicide_cry = "FOR ME MATEYS!!" hijack_speed = 2 // That is without doubt the worst pirate I have ever seen. + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_TEAM // monkestation addition var/datum/team/pirate/crew /datum/antagonist/pirate/greet() diff --git a/code/modules/antagonists/pyro_slime/pyro_slime.dm b/code/modules/antagonists/pyro_slime/pyro_slime.dm index aed278d261d9..7f63d0f5482f 100644 --- a/code/modules/antagonists/pyro_slime/pyro_slime.dm +++ b/code/modules/antagonists/pyro_slime/pyro_slime.dm @@ -5,6 +5,7 @@ show_in_antagpanel = FALSE show_name_in_check_antagonists = TRUE show_to_ghosts = TRUE + antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition /datum/antagonist/pyro_slime/on_gain() forge_objectives() diff --git a/code/modules/antagonists/revolution/enemy_of_the_revolution.dm b/code/modules/antagonists/revolution/enemy_of_the_revolution.dm index 93a205a02cd2..0e20463d4898 100644 --- a/code/modules/antagonists/revolution/enemy_of_the_revolution.dm +++ b/code/modules/antagonists/revolution/enemy_of_the_revolution.dm @@ -7,6 +7,7 @@ name = "\improper Enemy of the Revolution" show_in_antagpanel = FALSE suicide_cry = "FOR NANOTRASEN, NOW AND FOREVER!!" + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition /datum/antagonist/enemy_of_the_revolution/forge_objectives() var/datum/objective/survive/survive = new diff --git a/code/modules/antagonists/sentient_creature/sentient_creature.dm b/code/modules/antagonists/sentient_creature/sentient_creature.dm index 4b68a288be12..000fa8b51aff 100644 --- a/code/modules/antagonists/sentient_creature/sentient_creature.dm +++ b/code/modules/antagonists/sentient_creature/sentient_creature.dm @@ -4,6 +4,7 @@ show_in_roundend = FALSE count_against_dynamic_roll_chance = FALSE ui_name = "AntagInfoSentient" + antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition /datum/antagonist/sentient_creature/get_preview_icon() var/icon/final_icon = icon('icons/mob/simple/pets.dmi', "corgi") diff --git a/code/modules/antagonists/space_dragon/space_carp.dm b/code/modules/antagonists/space_dragon/space_carp.dm index 0d06ea3991d9..ad84d0ee4337 100644 --- a/code/modules/antagonists/space_dragon/space_carp.dm +++ b/code/modules/antagonists/space_dragon/space_carp.dm @@ -5,6 +5,7 @@ show_in_antagpanel = FALSE show_name_in_check_antagonists = TRUE show_to_ghosts = TRUE + antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition /// The rift to protect var/datum/weakref/rift diff --git a/code/modules/antagonists/venus_human_trap/venus_human_trap.dm b/code/modules/antagonists/venus_human_trap/venus_human_trap.dm index c84f20d05965..04ffc1dcd51c 100644 --- a/code/modules/antagonists/venus_human_trap/venus_human_trap.dm +++ b/code/modules/antagonists/venus_human_trap/venus_human_trap.dm @@ -5,6 +5,7 @@ show_in_antagpanel = FALSE show_name_in_check_antagonists = TRUE show_to_ghosts = TRUE + antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition /datum/antagonist/venus_human_trap/on_gain() forge_objectives() diff --git a/code/modules/antagonists/wishgranter/wishgranter.dm b/code/modules/antagonists/wishgranter/wishgranter.dm index bfac673535af..d27ad3df8a10 100644 --- a/code/modules/antagonists/wishgranter/wishgranter.dm +++ b/code/modules/antagonists/wishgranter/wishgranter.dm @@ -4,6 +4,7 @@ show_name_in_check_antagonists = TRUE hijack_speed = 2 //You literally are here to do nothing else. Might as well be fast about it. suicide_cry = "HAHAHAHAHA!!" + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition /datum/antagonist/wishgranter/forge_objectives() var/datum/objective/hijack/hijack = new diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index f86c46f83b6c..f3f6c810baa9 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -38,6 +38,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key) antag_hud_name = "apprentice" show_in_roundend = FALSE show_name_in_check_antagonists = TRUE + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE // monkestation addition /// The wizard team this wizard minion is part of. var/datum/team/wizard/wiz_team diff --git a/code/modules/antagonists/xeno/xeno.dm b/code/modules/antagonists/xeno/xeno.dm index 115e40ca595c..eff0866999cf 100644 --- a/code/modules/antagonists/xeno/xeno.dm +++ b/code/modules/antagonists/xeno/xeno.dm @@ -66,6 +66,7 @@ return captive_team = new captive_team.progenitor = owner + antag_flags |= FLAG_ANTAG_CAP_IGNORE // monkestation edit: first captive xeno does not count against cap else if(!istype(new_team)) CRASH("Wrong xeno team type provided to create_team") diff --git a/code/modules/bitrunning/antagonists/cyber_police.dm b/code/modules/bitrunning/antagonists/cyber_police.dm index 73ff96ff7c8c..9d99520dec76 100644 --- a/code/modules/bitrunning/antagonists/cyber_police.dm +++ b/code/modules/bitrunning/antagonists/cyber_police.dm @@ -10,6 +10,7 @@ show_to_ghosts = TRUE suicide_cry = "ALT F4!" ui_name = "AntagInfoCyberAuth" + antag_flags = FLAG_ANTAG_CAP_IGNORE // monkestation addition /datum/antagonist/cyber_police/greet() . = ..() diff --git a/code/modules/events/ghost_role/alien_infestation.dm b/code/modules/events/ghost_role/alien_infestation.dm index 9b35b2145dcf..db3fd898e9ae 100644 --- a/code/modules/events/ghost_role/alien_infestation.dm +++ b/code/modules/events/ghost_role/alien_infestation.dm @@ -87,25 +87,26 @@ if(temp_vent_parent.other_atmos_machines.len > 20) vents += temp_vent - if(!vents.len) + if(!length(vents)) message_admins("An event attempted to spawn an alien but no suitable vents were found. Shutting down.") return MAP_ERROR - for(var/i in 1 to antag_count) - if(!length(candidates)) - break - - var/client/mob_client = pick_n_take_weighted(weighted_candidates) - var/mob/candidate = mob_client.mob - if(candidate.client) //I hate this - candidate.client.prefs.reset_antag_rep() + var/selected_count = 0 + while(length(weighted_candidates) && selected_count < antag_count) + var/client/candidate_ckey = pick_n_take_weighted(weighted_candidates) + var/client/candidate_client = GLOB.directory[candidate_ckey] + if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) + continue + var/mob/candidate = candidate_client.mob + candidate_client.prefs?.reset_antag_rep() if(!candidate.mind) candidate.mind = new /datum/mind(candidate.key) var/obj/vent = pick_n_take(vents) var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc) - new_xeno.key = candidate.key + new_xeno.ckey = candidate_ckey new_xeno.move_into_vent(vent) + selected_count++ message_admins("[ADMIN_LOOKUPFLW(new_xeno)] has been made into an alien by an event.") new_xeno.log_message("was spawned as an alien by an event.", LOG_GAME) diff --git a/monkestation/code/__DEFINES/antag_defines.dm b/monkestation/code/__DEFINES/antag_defines.dm deleted file mode 100644 index 33358561c55a..000000000000 --- a/monkestation/code/__DEFINES/antag_defines.dm +++ /dev/null @@ -1,2 +0,0 @@ -/// Whether the antagonist can see exploitable info on people they examine. -#define FLAG_CAN_SEE_EXPOITABLE_INFO (1<<1) diff --git a/monkestation/code/controllers/subsystem/job.dm b/monkestation/code/controllers/subsystem/job.dm index cbe28992efda..d3ca62b5b386 100644 --- a/monkestation/code/controllers/subsystem/job.dm +++ b/monkestation/code/controllers/subsystem/job.dm @@ -65,9 +65,10 @@ mass_adjust_antag_rep(cliented_list, 1) var/list/weighted_candidates = return_antag_rep_weight(candidates) - var/antag_selection_loops = SSgamemode.current_roundstart_event.get_antag_amount() - for(var/i in 1 to antag_selection_loops) + var/iter = 0 + while(iter < antag_selection_loops) + iter++ if(antag_selection_loops >= 100) log_storyteller("h_r_a failed, antag_selection_loops went over 100") return FALSE @@ -78,7 +79,11 @@ log_storyteller("h_r_a failed, below required candidates for selected roundstart event") return FALSE break - var/client/dead_client = pick_n_take_weighted(weighted_candidates) + var/candidate_ckey = pick_n_take_weighted(weighted_candidates) + var/client/dead_client = GLOB.directory[candidate_ckey] + if(QDELETED(dead_client)) + antag_selection_loops++ + continue var/mob/dead/new_player/candidate = dead_client.mob if(!candidate.mind || !istype(candidate)) antag_selection_loops++ @@ -105,12 +110,16 @@ continue var/mob/dead/new_player/candidate var/sanity = 0 - while(!candidate && length(weighted_candidates) && !sanity >= 100) + while(QDELETED(candidate) && length(weighted_candidates) && sanity < 100) sanity++ - candidate = pick_n_take_weighted(weighted_candidates) - if(!candidate.mind || !istype(candidate)) + var/candidate_ckey = pick_n_take_weighted(weighted_candidates) + var/client/candidate_client = GLOB.directory[candidate_ckey] + if(QDELETED(candidate_client)) + continue + candidate = candidate_client.mob + if(!isnewplayer(candidate) || QDELING(candidate) || QDELETED(candidate.mind)) candidate = null - if(!candidate) + if(QDELETED(candidate)) if(length(SSgamemode.roundstart_antag_minds) < SSgamemode.current_roundstart_event.base_antags) log_storyteller("h_r_a failed, removing unassigned antag player put us below current event minimum candidates and we were unable to find a replacement") return FALSE diff --git a/monkestation/code/modules/antagonists/_common/antag_datum.dm b/monkestation/code/modules/antagonists/_common/antag_datum.dm index 5995594cf332..177b48b11b54 100644 --- a/monkestation/code/modules/antagonists/_common/antag_datum.dm +++ b/monkestation/code/modules/antagonists/_common/antag_datum.dm @@ -1,6 +1,4 @@ /datum/antagonist - /// Allows antags to check exploitable info - antag_flags = FLAG_CAN_SEE_EXPOITABLE_INFO ///The list of keys that are valid to see our antag hud/of huds we can see var/list/hud_keys /// If this antagonist should be removed from the crew manifest upon gain. diff --git a/monkestation/code/modules/antagonists/clock_cult/antag_datums/clock_cultist.dm b/monkestation/code/modules/antagonists/clock_cult/antag_datums/clock_cultist.dm index 3c4ff85f2aa8..22beb4158965 100644 --- a/monkestation/code/modules/antagonists/clock_cult/antag_datums/clock_cultist.dm +++ b/monkestation/code/modules/antagonists/clock_cult/antag_datums/clock_cultist.dm @@ -203,6 +203,7 @@ /datum/antagonist/clock_cultist/eminence name = "Eminence" + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE give_slab = FALSE antag_moodlet = null communicate = null diff --git a/monkestation/code/modules/antagonists/evil_clone/evil_clone.dm b/monkestation/code/modules/antagonists/evil_clone/evil_clone.dm index a3b4bc9591db..f9616c0fa198 100644 --- a/monkestation/code/modules/antagonists/evil_clone/evil_clone.dm +++ b/monkestation/code/modules/antagonists/evil_clone/evil_clone.dm @@ -5,6 +5,7 @@ antagpanel_category = "Evil Clones" show_name_in_check_antagonists = TRUE show_to_ghosts = TRUE + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE /datum/antagonist/evil_clone/greet() . = ..() diff --git a/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_shaded.dm b/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_shaded.dm index ecaaaae89223..8384c6b6c1be 100644 --- a/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_shaded.dm +++ b/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_shaded.dm @@ -5,6 +5,7 @@ show_in_roundend = FALSE job_rank = ROLE_BLOODSUCKER antag_hud_name = "bloodsucker" + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE /obj/item/soulstone/bloodsucker theme = THEME_WIZARD diff --git a/monkestation/code/modules/bloodsuckers/vassals/ex_vassal.dm b/monkestation/code/modules/bloodsuckers/vassals/ex_vassal.dm index 0599972c219e..977ccdf851f8 100644 --- a/monkestation/code/modules/bloodsuckers/vassals/ex_vassal.dm +++ b/monkestation/code/modules/bloodsuckers/vassals/ex_vassal.dm @@ -12,6 +12,7 @@ silent = TRUE ui_name = FALSE hud_icon = 'monkestation/icons/bloodsuckers/bloodsucker_icons.dmi' + antag_flags = FLAG_ANTAG_CAP_IGNORE ///The revenge vassal that brought us into the fold. var/datum/antagonist/vassal/revenge/revenge_vassal diff --git a/monkestation/code/modules/bloodsuckers/vassals/vassal_datum.dm b/monkestation/code/modules/bloodsuckers/vassals/vassal_datum.dm index c2dd662cce12..72acb40a6d79 100644 --- a/monkestation/code/modules/bloodsuckers/vassals/vassal_datum.dm +++ b/monkestation/code/modules/bloodsuckers/vassals/vassal_datum.dm @@ -8,6 +8,7 @@ roundend_category = "vassals" antagpanel_category = "Bloodsucker" job_rank = ROLE_BLOODSUCKER + antag_flags = parent_type::antag_flags | FLAG_ANTAG_CAP_IGNORE antag_hud_name = "vassal" show_in_roundend = FALSE hud_icon = 'monkestation/icons/bloodsuckers/bloodsucker_icons.dmi' diff --git a/monkestation/code/modules/storytellers/antag_rep/helper_procs.dm b/monkestation/code/modules/storytellers/antag_rep/helper_procs.dm index 5970239e1287..86f54be69e97 100644 --- a/monkestation/code/modules/storytellers/antag_rep/helper_procs.dm +++ b/monkestation/code/modules/storytellers/antag_rep/helper_procs.dm @@ -37,27 +37,21 @@ GLOBAL_LIST_INIT(blessed_ckeys, list( ///give it a list of clients and the value aswell if it should be affected by multipliers and let er rip /proc/mass_adjust_antag_rep(list/clients, value, mulitplier = TRUE) for(var/client/listed_client as anything in clients) - if(!listed_client.prefs || !IS_CLIENT_OR_MOCK(listed_client)) + if(!IS_CLIENT_OR_MOCK(listed_client) || QDELETED(listed_client) || QDELETED(listed_client.prefs)) continue listed_client.prefs.adjust_antag_rep(value, mulitplier) /proc/return_antag_rep_weight(list/candidates) - var/list/returning_list = list() + . = list() for(var/anything in candidates) var/client/client_source if(ismob(anything)) var/mob/mob = anything client_source = mob.client - if(IS_CLIENT_OR_MOCK(anything)) + else if(IS_CLIENT_OR_MOCK(anything)) client_source = anything - if(!client_source) + if(QDELETED(client_source) || !client_source.ckey) continue + .[client_source.ckey] = client_source.prefs?.antag_rep || 10 - returning_list += client_source - var/return_value = 10 - if(client_source.prefs?.antag_rep) - return_value = client_source.prefs.antag_rep - returning_list[client_source] = return_value - - log_antag_rep("Returned Weighted List of [length(returning_list)]", list("before_weight" = candidates, "after_weight" = returning_list)) - return returning_list + log_antag_rep("Returned Weighted List of [length(.)]", list("before_weight" = candidates, "after_weight" = .)) diff --git a/monkestation/code/modules/storytellers/converted_events/_base_event.dm b/monkestation/code/modules/storytellers/converted_events/_base_event.dm index 84ae021d7840..0faa795d6aa3 100644 --- a/monkestation/code/modules/storytellers/converted_events/_base_event.dm +++ b/monkestation/code/modules/storytellers/converted_events/_base_event.dm @@ -240,9 +240,12 @@ var/list/weighted_candidates = return_antag_rep_weight(possible_candidates) - while(length(possible_candidates) && length(candidates) < antag_count) //both of these pick_n_take from possible_candidates so this should be fine + while(length(weighted_candidates) && length(candidates) < antag_count) //both of these pick_n_take from weighted_candidates so this should be fine if(prompted_picking) - var/client/picked_client = pick_n_take_weighted(weighted_candidates) + var/picked_ckey = pick_n_take_weighted(weighted_candidates) + var/client/picked_client = GLOB.directory[picked_ckey] + if(QDELETED(picked_client)) + continue var/mob/picked_mob = picked_client.mob log_storyteller("Prompted antag event mob: [picked_mob], special role: [picked_mob.mind?.special_role ? picked_mob.mind.special_role : "none"]") if(picked_mob) @@ -258,9 +261,10 @@ show_candidate_amount = FALSE, ) else - if(!length(weighted_candidates)) - break - var/client/picked_client = pick_n_take_weighted(weighted_candidates) + var/picked_ckey = pick_n_take_weighted(weighted_candidates) + var/client/picked_client = GLOB.directory[picked_ckey] + if(QDELETED(picked_client)) + continue var/mob/picked_mob = picked_client.mob log_storyteller("Picked antag event mob: [picked_mob], special role: [picked_mob.mind?.special_role ? picked_mob.mind.special_role : "none"]") candidates |= picked_mob @@ -353,22 +357,21 @@ ) var/list/weighted_candidates = return_antag_rep_weight(candidates) + var/selected_count = 0 + while(length(weighted_candidates) && selected_count < antag_count) + var/candidate_ckey = pick_n_take_weighted(weighted_candidates) + var/client/candidate_client = GLOB.directory[candidate_ckey] + if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) + continue + var/mob/candidate = candidate_client.mob - for(var/i in 1 to antag_count) - if(!length(weighted_candidates)) - break - - var/client/mob_client = pick_n_take_weighted(weighted_candidates) - var/mob/candidate = mob_client.mob - - if(candidate.client) //I hate this - candidate.client.prefs.reset_antag_rep() + candidate_client.prefs?.reset_antag_rep() if(!candidate.mind) candidate.mind = new /datum/mind(candidate.key) - var/mob/living/carbon/human/new_human = make_body(candidate) new_human.mind.special_role = antag_flag new_human.mind.restricted_roles = restricted_roles setup_minds += new_human.mind + selected_count++ setup = TRUE diff --git a/monkestation/code/modules/storytellers/converted_events/solo/ghosts/paradox_clone.dm b/monkestation/code/modules/storytellers/converted_events/solo/ghosts/paradox_clone.dm index 8a1a3223575a..5721f446cf30 100644 --- a/monkestation/code/modules/storytellers/converted_events/solo/ghosts/paradox_clone.dm +++ b/monkestation/code/modules/storytellers/converted_events/solo/ghosts/paradox_clone.dm @@ -52,26 +52,24 @@ ) var/list/weighted_candidates = return_antag_rep_weight(candidates) - - for(var/i in 1 to antag_count) - if(!length(candidates)) - break - - var/client/mob_client = pick_n_take(weighted_candidates) - var/mob/candidate = mob_client.mob - - if(candidate.client) //I hate this - candidate.client.prefs.reset_antag_rep() - + var/selected_count = 0 + while(length(weighted_candidates) && selected_count < antag_count) + var/client/candidate_ckey = pick_n_take_weighted(weighted_candidates) + var/client/candidate_client = GLOB.directory[candidate_ckey] + if(QDELETED(candidate_client) || QDELETED(candidate_client.mob)) + continue + var/mob/candidate = candidate_client.mob + candidate_client.prefs?.reset_antag_rep() if(!candidate.mind) candidate.mind = new /datum/mind(candidate.key) clone_victim = find_original() new_human = duplicate_object(clone_victim, pick(possible_spawns)) - new_human.key = candidate.key + new_human.ckey = candidate_ckey new_human.mind.special_role = antag_flag new_human.mind.restricted_roles = restricted_roles setup_minds += new_human.mind + selected_count++ setup = TRUE diff --git a/monkestation/code/modules/storytellers/gamemode_subsystem.dm b/monkestation/code/modules/storytellers/gamemode_subsystem.dm index 561149220487..01275488fc43 100644 --- a/monkestation/code/modules/storytellers/gamemode_subsystem.dm +++ b/monkestation/code/modules/storytellers/gamemode_subsystem.dm @@ -157,8 +157,6 @@ SUBSYSTEM_DEF(gamemode) var/ran_roundstart = FALSE var/list/triggered_round_events = list() - var/total_valid_antags = 0 - /datum/controller/subsystem/gamemode/Initialize(time, zlevel) // Populate event pools for(var/track in event_tracks) @@ -233,20 +231,29 @@ SUBSYSTEM_DEF(gamemode) var/cap = FLOOR((total_number / ANTAG_CAP_DENOMINATOR), 1) + ANTAG_CAP_FLAT return cap -/// Whether events can inject more antagonists into the round -/datum/controller/subsystem/gamemode/proc/can_inject_antags() - total_valid_antags = 0 - for(var/mob/checked_mob in GLOB.mob_list) - if(!checked_mob.mind) +/datum/controller/subsystem/gamemode/proc/get_antag_count() + . = 0 + var/list/already_counted = list() // Never count the same mind twice + for(var/datum/antagonist/antag as anything in GLOB.antagonists) + if(QDELETED(antag) || QDELETED(antag.owner) || already_counted[antag.owner]) continue - if(!checked_mob.mind.special_role) + if(!antag.count_against_dynamic_roll_chance || (antag.antag_flags & (FLAG_FAKE_ANTAG | FLAG_ANTAG_CAP_IGNORE))) continue - if(checked_mob.stat == DEAD) + if(antag.antag_flags & FLAG_ANTAG_CAP_TEAM) + var/datum/team/antag_team = antag.get_team() + if(antag_team) + if(already_counted[antag_team]) + continue + already_counted[antag_team] = TRUE + var/mob/antag_mob = antag.owner.current + if(QDELETED(antag_mob) || !antag_mob.key || antag_mob.stat == DEAD || antag_mob.client?.is_afk()) continue - total_valid_antags++ - + already_counted[antag.owner] = TRUE + .++ - return (get_antag_cap() > total_valid_antags) +/// Whether events can inject more antagonists into the round +/datum/controller/subsystem/gamemode/proc/can_inject_antags() + return (get_antag_cap() > get_antag_count()) /// Gets candidates for antagonist roles. /datum/controller/subsystem/gamemode/proc/get_candidates(be_special, job_ban, observers, ready_newplayers, living_players, required_time, inherit_required_time = TRUE, midround_antag_pref, no_antags = TRUE, list/restricted_roles, list/required_roles) @@ -798,7 +805,9 @@ SUBSYSTEM_DEF(gamemode) point_thresholds[EVENT_TRACK_ROLESET] = CONFIG_GET(number/roleset_point_threshold) point_thresholds[EVENT_TRACK_OBJECTIVES] = CONFIG_GET(number/objectives_point_threshold) -/datum/controller/subsystem/gamemode/proc/handle_picking_stroyteller() +/datum/controller/subsystem/gamemode/proc/handle_picking_storyteller() + if(CONFIG_GET(flag/disable_storyteller)) + return if(length(GLOB.clients) > MAX_POP_FOR_STORYTELLER_VOTE) secret_storyteller = TRUE selected_storyteller = pick_weight(get_valid_storytellers(TRUE)) @@ -867,23 +876,13 @@ SUBSYSTEM_DEF(gamemode) /// Panel containing information, variables and controls about the gamemode and scheduled event /datum/controller/subsystem/gamemode/proc/admin_panel(mob/user) update_crew_infos() - total_valid_antags = 0 - for(var/mob/checked_mob in GLOB.mob_list) - if(!checked_mob.mind) - continue - if(!checked_mob.mind.special_role) - continue - if(checked_mob.stat == DEAD) - continue - total_valid_antags++ - var/round_started = SSticker.HasRoundStarted() var/list/dat = list() dat += "Storyteller: [storyteller ? "[storyteller.name]" : "None"] " dat += " HALT Storyteller Event Panel Set Storyteller Refresh" dat += "
Storyteller determines points gained, event chances, and is the entity responsible for rolling events." dat += "
Active Players: [active_players] (Head: [head_crew], Sec: [sec_crew], Eng: [eng_crew], Med: [med_crew])" - dat += "
Antagonist Count vs Maximum: [total_valid_antags] / [get_antag_cap()]" + dat += "
Antagonist Count vs Maximum: [get_antag_count()] / [get_antag_cap()]" dat += "
" dat += "Main" dat += " Variables" diff --git a/monkestation/code/modules/storytellers/storytellers/_storyteller.dm b/monkestation/code/modules/storytellers/storytellers/_storyteller.dm index 4e84d41d794d..bd6486890c67 100644 --- a/monkestation/code/modules/storytellers/storytellers/_storyteller.dm +++ b/monkestation/code/modules/storytellers/storytellers/_storyteller.dm @@ -122,7 +122,7 @@ var/list/valid_events = list() // Determine which events are valid to pick for(var/datum/round_event_control/event as anything in mode.event_pools[track]) - var/players_amt = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1) + var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) if(event.can_spawn_event(players_amt)) if(QDELETED(event)) message_admins("[event.name] was deleted!") diff --git a/monkestation/code/modules/virology/disease/symtoms/restricted/stage1.dm b/monkestation/code/modules/virology/disease/symtoms/restricted/stage1.dm index ef13a61fc797..f63dace8b0ea 100644 --- a/monkestation/code/modules/virology/disease/symtoms/restricted/stage1.dm +++ b/monkestation/code/modules/virology/disease/symtoms/restricted/stage1.dm @@ -44,8 +44,9 @@ affected_mob.mind.transfer_to(new_mob) else new_mob.key = affected_mob.key - if(transformed_antag_datum) - new_mob.mind.add_antag_datum(transformed_antag_datum) + if(transformed_antag_datum && !QDELETED(new_mob.mind)) + var/datum/antagonist/given_antag = new_mob.mind.has_antag_datum(transformed_antag_datum) || new_mob.mind.add_antag_datum(transformed_antag_datum) + given_antag?.antag_flags |= FLAG_ANTAG_CAP_IGNORE // ensure they don't count against storyteller cap new_mob.name = affected_mob.real_name new_mob.real_name = new_mob.name new_mob.update_name_tag() @@ -78,6 +79,7 @@ name = "Xenomorph Transformation" new_form = /mob/living/carbon/alien/adult/hunter bantype = ROLE_ALIEN + transformed_antag_datum = /datum/antagonist/xeno /datum/symptom/transformation/slime name = "Advanced Mutation Transformation" diff --git a/tgstation.dme b/tgstation.dme index 45c14db10d3e..1c0e5c594676 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5790,7 +5790,6 @@ #include "interface\fonts\tiny_unicode.dm" #include "interface\fonts\vcr_osd_mono.dm" #include "monkestation\code\__DEFINES\_module_defines.dm" -#include "monkestation\code\__DEFINES\antag_defines.dm" #include "monkestation\code\__DEFINES\projectile.dm" #include "monkestation\code\__DEFINES\signals.dm" #include "monkestation\code\__HELPERS\_lists.dm"