From c4f6d85b44810f6ed203e4b778ff2bfc05a9126b Mon Sep 17 00:00:00 2001 From: Incoming Date: Fri, 24 Apr 2015 15:40:42 -0400 Subject: [PATCH] Any roundtype can now take advantage of continuous/non-continuous settings as well as the mulligan antag system. (as a reminder at this point the mulligan system only creates lings and/or traitors) A generic check for antags now exists in check_finished, and overrides a lot of checks in specific modes. Specific checks are still needed if you have special means of determining antag viability (blob cores), or things to do when specific antags die (summon events). In situations where mulligans are on but fail, the round will usually lurch on as "extended" but in wizard/malf/blob/ragin mages the round will end then and there. This mirrors current behavior. Config settings are fully customizable and for the most part defaults mirror existing behaviors: Revolution, Shadowling, Gang, Ragin Mages and Monkey are noncontinuous and will end with the death of all antagonists. * There is a change here in shadowling in that rounds with living thralls but no living shadowlings will continue until the thralls are delt with, as they can still raise their dead master. * Abductors not ending with the death of all ayyliens if there are still probe victims around is likewise a change. If the dev of abduction would rather have it default the other way, we can do that. * Monkey being noncontinuous is a change, but given how monkey mode works, it really only makes sense. All modes that are continous use the mulligan system by default, remember that this will only come into effect if EVERY antagonist dies, so modes with many antagonists are very likely to only mulligan extremely rarely because if even one isn't slaughtered and is instead brigged or otherwise neutralized nonfatally the mulligan will never come. A nice little bonus for security not to kill everyone! Fixes a bug where shuttle stranding could occur in continous rev modes (not something on by default) Probably buggy as hell in initial commit. Please no quick merge --- code/game/gamemodes/abduction/abduction.dm | 8 ----- code/game/gamemodes/blob/blob.dm | 1 + code/game/gamemodes/blob/blob_finish.dm | 9 ----- code/game/gamemodes/game_mode.dm | 34 ++++++++++++++++--- .../game/gamemodes/malfunction/malfunction.dm | 10 +----- code/game/gamemodes/revolution/revolution.dm | 6 +++- code/game/gamemodes/shadowling/shadowling.dm | 22 ------------ code/game/gamemodes/wizard/raginmages.dm | 2 +- code/game/gamemodes/wizard/wizard.dm | 22 +----------- code/modules/admin/player_panel.dm | 9 ++--- config/game_options.txt | 30 ++++++++++++++-- 11 files changed, 69 insertions(+), 84 deletions(-) diff --git a/code/game/gamemodes/abduction/abduction.dm b/code/game/gamemodes/abduction/abduction.dm index cd605c9e280..b8fb97076c2 100644 --- a/code/game/gamemodes/abduction/abduction.dm +++ b/code/game/gamemodes/abduction/abduction.dm @@ -236,19 +236,11 @@ /datum/game_mode/abduction/check_finished() - var/all_dead = 1 for(var/team_number=1,team_number<=teams,team_number++) - var/datum/mind/smind = scientists[team_number] - if(smind.current) - var/mob/living/M = smind.current - if(M.stat != DEAD) - all_dead = 0 var/obj/machinery/abductor/console/con = get_team_console(team_number) var/datum/objective/objective = team_objectives[team_number] if (con.experiment.points > objective.target_amount) return 1 - if(all_dead) - return 1 return ..() /datum/game_mode/abduction/declare_completion() diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 207805d235b..ded9ed324f2 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -15,6 +15,7 @@ var/list/blob_nodes = list() required_enemies = 1 recommended_enemies = 1 + round_ends_with_antag_death = 1 restricted_jobs = list("Cyborg", "AI") var/declared = 0 diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm index aec57627778..c0987cabce1 100644 --- a/code/game/gamemodes/blob/blob_finish.dm +++ b/code/game/gamemodes/blob/blob_finish.dm @@ -1,8 +1,4 @@ /datum/game_mode/blob/check_finished() - if(replacementmode && round_converted == 2) - return replacementmode.check_finished() - if(round_converted) - return ..() if(infected_crew.len > burst)//Some blobs have yet to burst return 0 if(blobwincount <= blobs.len)//Blob took over @@ -14,11 +10,6 @@ SSshuttle.emergency.mode = SHUTTLE_DOCKED SSshuttle.emergency.timer = world.time priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority") - - if(config.midround_antag["blob"]) - round_converted = convert_roundtype() - if(!round_converted) - return 1 return ..() return 1 if(station_was_nuked)//Nuke went off diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 2e3654f7b6a..0d4911cb471 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -19,6 +19,7 @@ var/probability = 1 var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm var/explosion_in_progress = 0 //sit back and relax + var/round_ends_with_antag_death = 0 //flags the "one verse the station" antags as such var/list/datum/mind/modePlayer = new var/list/datum/mind/antag_candidates = list() // List of possible starting antags goes here var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist @@ -29,6 +30,7 @@ var/pre_setup_before_jobs = 0 var/antag_flag = null //preferences flag such as BE_WIZARD that need to be turned on for players to be antag var/datum/mind/sacrifice_target = null + var/mob/living/living_antag_player = null var/list/datum/game_mode/replacementmode = null var/round_converted = 0 //0: round not converted, 1: round going to convert, 2: round converted var/reroll_friendly //During mode conversion only these are in the running @@ -97,16 +99,16 @@ ///convert_roundtype() ///Allows rounds to basically be "rerolled" should the initial premise fall through /datum/game_mode/proc/convert_roundtype() - var/living_crew = 0 + var/list/living_crew = list() for(var/mob/Player in mob_list) if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) &&!isbrain(Player)) - living_crew++ - if(living_crew / joined_player_list.len <= config.midround_antag_life_check) //If a lot of the player base died, we start fresh + living_crew += Player + if(living_crew.len / joined_player_list.len <= config.midround_antag_life_check) //If a lot of the player base died, we start fresh message_admins("Convert_roundtype failed due to too many dead people. Limit is [config.midround_antag_life_check * 100]% living crew") return null - var/list/datum/game_mode/runnable_modes = config.get_runnable_midround_modes(living_crew) + var/list/datum/game_mode/runnable_modes = config.get_runnable_midround_modes(living_crew.len) var/list/datum/game_mode/usable_modes = list() for(var/datum/game_mode/G in runnable_modes) if(G.reroll_friendly) @@ -167,8 +169,32 @@ /datum/game_mode/proc/check_finished() //to be called by ticker + if(replacementmode && round_converted == 2) + return replacementmode.check_finished() if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME || station_was_nuked) return 1 + if(!round_converted && (!config.continuous[config_tag] || (config.continuous[config_tag] && config.midround_antag[config_tag]))) //Non-continuous or continous with replacement antags + if(living_antag_player && living_antag_player.mind && living_antag_player.stat != DEAD && !isnewplayer(living_antag_player) &&!isbrain(living_antag_player)) + return 0 //A resource saver: once we find someone who has to die for all antags to be dead, we can just keep checking them, cycling over everyone only when we lose our mark. + + for(var/mob/living/Player in living_mob_list) + if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) &&!isbrain(Player)) + if(Player.mind.special_role) //Someone's still antaging! + living_antag_player = Player + return 0 + + if(!config.continuous[config_tag]) + return 1 + + else + round_converted = convert_roundtype() + if(!round_converted) + if(round_ends_with_antag_death) + return 1 + else + config.midround_antag[config_tag] = 0 + return 0 + return 0 diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm index 7271875daee..1531ac36613 100644 --- a/code/game/gamemodes/malfunction/malfunction.dm +++ b/code/game/gamemodes/malfunction/malfunction.dm @@ -10,7 +10,7 @@ recommended_enemies = 1 pre_setup_before_jobs = 1 enemy_minimum_age = 30 //Same as AI minimum age - + round_ends_with_antag_death = 1 var/AI_win_timeleft = 5400 //started at 5400, in case I change this for testing round end. var/malf_mode_declared = 0 @@ -170,10 +170,6 @@ /datum/game_mode/malfunction/check_finished() - if(replacementmode && round_converted == 2) - return replacementmode.check_finished() - if(round_converted == 1) //No reason to waste resources - return ..() //Check for evacuation/nuke if (station_captured && !to_nuke_or_not_to_nuke) return 1 if (is_malf_ai_dead() || !check_ai_loc()) @@ -186,10 +182,6 @@ malf_mode_declared = 0 if(get_security_level() == "delta") set_security_level("red") - if(config.midround_antag["malfunction"]) - round_converted = convert_roundtype() - if(!round_converted) - return 1 return ..() else return 1 diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 553df633bf8..d6f8e63cf8e 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -213,11 +213,15 @@ if(config.continuous["revolution"]) if(finished != 0) SSshuttle.emergencyNoEscape = 0 + if(SSshuttle.emergency.mode == SHUTTLE_STRANDED) + SSshuttle.emergency.mode = SHUTTLE_DOCKED + SSshuttle.emergency.timer = world.time + priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority") return ..() if(finished != 0) return 1 else - return 0 + return ..() /////////////////////////////////////////////////// //Deals with converting players to the revolution// diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 372ee45ff10..902a17c4a14 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -157,28 +157,6 @@ Made by Xhuis new_thrall_mind.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_hivemind return 1 - - -/* - GAME FINISH CHECKS -*/ - - -/datum/game_mode/shadowling/check_finished() - var/shadows_alive = 0 //and then shadowling was kill - for(var/datum/mind/shadow in shadows) //but what if shadowling was not kill? - if(!istype(shadow.current,/mob/living/carbon/human) && !istype(shadow.current,/mob/living/simple_animal/ascendant_shadowling)) - continue - if(shadow.current.stat == DEAD) - continue - shadows_alive++ - if(shadows_alive) - return ..() - else - shadowling_dead = 1 //but shadowling was kill :( - return 1 - - /datum/game_mode/shadowling/proc/check_shadow_victory() var/success = 0 //Did they win? if(shadow_objectives.Find("enthrall")) diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index d0d350d86d7..6f19d7cdd0d 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -60,7 +60,7 @@ else if(mages_made >= max_mages) finished = 1 - return 1 + return ..() else make_more_mages() return ..() diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index ddce2321c47..1d2d5d5a98f 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -10,6 +10,7 @@ recommended_enemies = 1 pre_setup_before_jobs = 1 enemy_minimum_age = 14 + round_ends_with_antag_death = 1 var/use_huds = 0 var/finished = 0 @@ -171,37 +172,16 @@ /datum/game_mode/wizard/check_finished() - if(replacementmode && round_converted == 2) - return replacementmode.check_finished() - - if(round_converted == 1 || !wizards) //No reason to waste resources - return ..() //Check for evacuation/nuke - for(var/datum/mind/wizard in wizards) if(!wizard.current) continue if(wizard.current.stat != DEAD) return ..() - for(var/datum/mind/traitor in traitors) - if(!traitor.current) - continue - if(traitor.current.stat != DEAD) - return ..() - - if(!config.continuous["wizard"]) - return 1 - if(SSevent.wizardmode) //If summon events was active, turn it off SSevent.toggleWizardmode() SSevent.resetFrequency() - if(config.midround_antag["wizard"]) - round_converted = convert_roundtype() - if(!round_converted) - finished = 1 - return 1 - return ..() /datum/game_mode/wizard/declare_completion() diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index dc82a42143a..03bad1dedf0 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -305,8 +305,6 @@ usr << browse(dat, "window=players;size=600x480") /datum/admins/proc/check_antagonists() - var/list/supported_continuous_modes = list("revolution", "gang", "wizard", "malfunction", "blob") - var/list/supported_midround_antag_modes = list("wizard", "malfunction", "blob") if (ticker && ticker.current_state >= GAME_STATE_PLAYING) var/dat = "Round Status

Round Status

" dat += "Current Game Mode: [ticker.mode.name]
" @@ -324,11 +322,8 @@ else dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]
" dat += "Continuous Round Status
" - if(!ticker.mode.config_tag in supported_continuous_modes) - dat += "Continue if antagonists die" - else - dat += "[config.continuous[ticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]" - if(config.continuous[ticker.mode.config_tag] && ticker.mode.config_tag in supported_midround_antag_modes) + dat += "[config.continuous[ticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]" + if(config.continuous[ticker.mode.config_tag]) dat += ", [config.midround_antag[ticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]
" else dat += "
" diff --git a/config/game_options.txt b/config/game_options.txt index ae06f1b3675..cc2a9c13d1d 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -100,20 +100,46 @@ PROBABILITY SANDBOX 0 ## Toggles for continuous modes. ## Modes that aren't continuous will end the instant all antagonists are dead. -## Unlisted modes are not currently supported for noncontinous play +CONTINUOUS TRAITOR +CONTINUOUS TRAITORCHAN +CONTINUOUS DOUBLE_AGENTS +#CONTINUOUS NUCLEAR #CONTINUOUS REVOLUTION +#CONTINUOUS SHADOWLING +#CONTINUOUS GANG +CONTINUOUS CULT +CONTINUOUS CHANGELING CONTINUOUS WIZARD CONTINUOUS MALFUNCTION CONTINUOUS BLOB +#CONTINUOUS RAGINMAGES +#CONTINUOUS MONKEY + +##Note: do not toggle continuous off for these modes, as they have no antagonists and would thus end immediately! + +CONTINUOUS METEOR +CONTINUOUS EXTENDED + ## Toggles for allowing midround antagonists (aka mulligan antagonists). ## In modes that are continuous, if all antagonists should die then a new set of antagonists will be created. -## Only the listed modes are currently supported for this system +MIDROUND_ANTAG TRAITOR +MIDROUND_ANTAG TRAITORCHAN +MIDROUND_ANTAG DOUBLE_AGENTS +#MIDROUND_ANTAG NUCLEAR +#MIDROUND_ANTAG REVOLUTION +#MIDROUND_ANTAG SHADOWLING +#MIDROUND_ANTAG GANG +MIDROUND_ANTAG CULT +MIDROUND_ANTAG CHANGELING MIDROUND_ANTAG WIZARD MIDROUND_ANTAG MALFUNCTION MIDROUND_ANTAG BLOB +#MIDROUND_ANTAG RAGINMAGES +#MIDROUND_ANTAG MONKEY + ## The amount of time it takes for the emergency shuttle to be called, from round start. SHUTTLE_REFUEL_DELAY 12000