From 9c4792ea80af51dd72a97c2e21d7aa16c23bd13c Mon Sep 17 00:00:00 2001 From: Putnam3145 Date: Mon, 13 Nov 2023 04:00:04 -0800 Subject: [PATCH] Some dynamic midround tweaking (#15841) * midround wizard, blob * make dynamic respect midround pref, too * Makes attempt_replacement not just make traitors * Tried to make it poll if you wanna be a wizard * something is going to happen in 1 minutes * i left it half finished! * This one seems a bit over the top --------- Co-authored-by: DeltaFire <46569814+DeltaFire15@users.noreply.github.com> --- .../dynamic/dynamic_rulesets_midround.dm | 102 ++++++++++++++---- code/modules/antagonists/wizard/wizard.dm | 28 ++++- 2 files changed, 105 insertions(+), 25 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index c14b7b1d0a..cbafe64eb5 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -15,6 +15,7 @@ var/restrict_ghost_roles = TRUE /// What mob type the ruleset is restricted to. var/required_type = /mob/living/carbon/human + var/should_use_midround_pref = TRUE var/list/living_players = list() var/list/living_antags = list() var/list/dead_players = list() @@ -23,6 +24,7 @@ /datum/dynamic_ruleset/midround/from_ghosts weight = 0 required_type = /mob/dead/observer + should_use_midround_pref = FALSE /// Whether the ruleset should call generate_ruleset_body or not. var/makeBody = TRUE /// The rule needs this many applicants to be properly executed. @@ -43,6 +45,9 @@ if (!M.client) // Are they connected? trimmed_list.Remove(M) continue + if(should_use_midround_pref && !(M.client.prefs.toggles & MIDROUND_ANTAG)) + trimmed_list.Remove(M) + continue if(!mode.check_age(M.client, minimum_required_age)) trimmed_list.Remove(M) continue @@ -106,10 +111,10 @@ return message_admins("Polling [possible_volunteers.len] players to apply for the [name] ruleset.") log_game("DYNAMIC: Polling [possible_volunteers.len] players to apply for the [name] ruleset.") + var/flag = antag_flag_override ? antag_flag_override : antag_flag + candidates = pollGhostCandidates("The mode is looking for volunteers to become [antag_flag] for [name]", flag, be_special_flag = flag, ignore_category = antag_flag, poll_time = 300) - candidates = pollGhostCandidates("The mode is looking for volunteers to become [antag_flag] for [name]", antag_flag, be_special_flag = antag_flag_override ? antag_flag_override : antag_flag, poll_time = 300) - - if(!candidates || candidates.len <= 0) + if(!length(candidates)) mode.dynamic_log("The ruleset [name] received no applications.") mode.executed_rules -= src attempt_replacement() @@ -164,19 +169,10 @@ /datum/dynamic_ruleset/midround/from_ghosts/proc/setup_role(datum/antagonist/new_role) return -/// Fired when there are no valid candidates. Will spawn a sleeper agent or latejoin traitor. +/// Fired when there are no valid candidates. Will try to roll again in a minute. /datum/dynamic_ruleset/midround/from_ghosts/proc/attempt_replacement() - var/datum/dynamic_ruleset/midround/autotraitor/sleeper_agent = new - - // Otherwise, it has a chance to fail. We don't want that, since this is already pretty unlikely. - sleeper_agent.has_failure_chance = FALSE - - mode.configure_ruleset(sleeper_agent) - - if (!mode.picking_specific_rule(sleeper_agent)) - return - - mode.picking_specific_rule(/datum/dynamic_ruleset/latejoin/infiltrator) + COOLDOWN_START(mode, midround_injection_cooldown, 1 MINUTES) + mode.forced_injection = TRUE ////////////////////////////////////////////// // // @@ -233,9 +229,8 @@ return ..() /datum/dynamic_ruleset/midround/autotraitor/execute() - var/mob/M = pick(living_players) + var/mob/M = pick_n_take(living_players) assigned += M - living_players -= M var/datum/antagonist/traitor/newTraitor = new M.mind.add_antag_datum(newTraitor) message_admins("[ADMIN_LOOKUPFLW(M)] was selected by the [name] ruleset and has been made into a midround traitor.") @@ -336,7 +331,7 @@ candidates -= player continue - if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0)) + if(player.mind && (player.mind.special_role || length(player.mind.antag_datums))) candidates -= player /datum/dynamic_ruleset/midround/malf/execute() @@ -355,6 +350,70 @@ M.add_ion_law(generate_ion_law()) return TRUE +////////////////////////////////////////////// +// // +// WIZARD (CREW) // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/midround/wizard + name = "Wizard" + antag_datum = /datum/antagonist/wizard + antag_flag = "wizard mid crew" + antag_flag_override = ROLE_WIZARD + protected_roles = list("Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + restricted_roles = list("AI", "Cyborg") + enemy_roles = list("Security Officer","Detective","Head of Security", "Captain") + required_enemies = list(0,0,0,0,0,0,0,0,0,0) + weight = 0 + cost = 20 + requirements = list(101,101,100,60,40,20,20,20,10,10) + repeatable = TRUE + var/datum/mind/wizard + +/datum/dynamic_ruleset/midround/wizard/trim_candidates() + ..() + candidates = living_players + for(var/mob/living/player as anything in candidates) + var/turf/player_turf = get_turf(player) + if(!player_turf || !is_station_level(player_turf.z)) + candidates -= player + continue + + if(player.mind && (player.mind.special_role || length(player.mind.antag_datums) > 0)) + candidates -= player + candidates = pollCandidates("Do you want to be a wizard?", antag_flag_override, be_special_flag = antag_flag_override, ignore_category = antag_flag_override, poll_time = 300) + +/datum/dynamic_ruleset/midround/wizard/ready(forced = FALSE) + if(GLOB.wizardstart.len == 0) + log_admin("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.") + message_admins("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.") + return FALSE + return ..() + +/datum/dynamic_ruleset/midround/wizard/execute() + var/mob/M = pick_n_take(living_players) + assigned += M + var/datum/antagonist/wizard/on_station/wiz = new + M.mind.add_antag_datum(wiz) + wizard = M.mind + message_admins("[ADMIN_LOOKUPFLW(M)] was selected by the [name] ruleset and has been made into a midround wizard.") + log_game("DYNAMIC: [key_name(M)] was selected by the [name] ruleset and has been made into a midround wizard.") + return TRUE + +/datum/dynamic_ruleset/midround/wizard/rule_process() + if(isliving(wizard.current) && wizard.current.stat!=DEAD) + return FALSE + for(var/obj/item/phylactery/P in GLOB.poi_list) //TODO : IsProperlyDead() + if(P.mind && P.mind.has_antag_datum(/datum/antagonist/wizard)) + return FALSE + + if(SSevents.wizardmode) //If summon events was active, turn it off + SSevents.toggleWizardmode() + SSevents.resetFrequency() + + return RULESET_STOP_PROCESSING + ////////////////////////////////////////////// // // // WIZARD (GHOST) // @@ -459,7 +518,7 @@ antag_flag = "clock mid" antag_flag_override = ROLE_SERVANT_OF_RATVAR protected_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") - restricted_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + restricted_roles = list("AI", "Cyborg") enemy_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") required_enemies = list(1,1,1,1,1,1,0,0,0,0) required_candidates = 2 @@ -536,6 +595,7 @@ name = "Blob Infection" antag_datum = /datum/antagonist/blob antag_flag = "blob mid" + antag_flag_override = ROLE_BLOB protected_roles = list("Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain") restricted_roles = list("Cyborg", "AI", "Positronic Brain") enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") @@ -559,11 +619,11 @@ candidates -= player /datum/dynamic_ruleset/midround/blob_infection/execute() - if(!candidates || !candidates.len) + if(!length(candidates)) return FALSE var/mob/living/carbon/human/blob_antag = pick_n_take(candidates) assigned += blob_antag.mind - blob_antag.mind.special_role = antag_flag + blob_antag.mind.special_role = antag_flag_override return ..() ////////////////////////////////////////////// diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index 63bb2b5b57..5e69bb3847 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -1,3 +1,7 @@ +#define WIZARD_DO_NOTHING 0 +#define WIZARD_QDEL_INVENTORY 1 +#define WIZARD_DROP_INVENTORY 2 + /datum/antagonist/wizard name = "Space Wizard" roundend_category = "wizards/witches" @@ -10,7 +14,8 @@ ui_name = "AntagInfoWizard" suicide_cry = "FOR THE FEDERATION!!" var/give_objectives = TRUE - var/strip = TRUE //strip before equipping + var/inventory_mode = WIZARD_QDEL_INVENTORY + var/change_species = TRUE var/allow_rename = TRUE var/datum/team/wizard/wiz_team //Only created if wizard summons apprentices var/move_to_lair = TRUE @@ -87,10 +92,14 @@ var/mob/living/carbon/human/H = owner.current if(!istype(H)) return - if(strip) - H.delete_equipment() + switch(inventory_mode) + if(WIZARD_QDEL_INVENTORY) + H.delete_equipment() + if(WIZARD_DROP_INVENTORY) + H.unequip_everything() //Wizards are human by default. Use the mirror if you want something else. - H.set_species(/datum/species/human) + if(change_species) + H.set_species(/datum/species/human) if(H.age < wiz_age) H.age = wiz_age H.equipOutfit(outfit_type) @@ -250,6 +259,17 @@ new_objective.owner = owner objectives += new_objective +/datum/antagonist/wizard/on_station + inventory_mode = WIZARD_DROP_INVENTORY + change_species = FALSE + +/datum/antagonist/wizard/on_station/on_gain() + var/datum/effect_system/smoke_spread/smoke = new + smoke.start() + smoke.set_up(2, get_turf(owner)) + owner.current.visible_message("[owner] suddenly disappears in a puff of smoke, leaving [owner.p_their()] clothes behind!", "You feel yourself being pulled away...") + return ..() + //Solo wizard report /datum/antagonist/wizard/roundend_report() var/list/parts = list()