From 07064298b0d51d45e961883f33be07d9eefa29ac Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 20 Oct 2019 18:54:17 -0700 Subject: [PATCH 001/121] Dynamic voting (draft) --- .../configuration/entries/game_options.dm | 2 ++ code/controllers/subsystem/ticker.dm | 2 +- code/controllers/subsystem/vote.dm | 23 +++++++++++++++++-- config/game_options.txt | 3 +++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index cfd57b4850..29bb7671ae 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -364,3 +364,5 @@ /datum/config_entry/number/auto_transfer_delay config_entry_value = 72000 min_val = 0 + +/datum/config_entry/flag/dynamic_voting diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 14e1e86f7d..ccdf98a71f 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -479,7 +479,7 @@ SUBSYSTEM_DEF(ticker) if(SSticker.timeLeft < 900) SSticker.timeLeft = 900 SSticker.modevoted = TRUE - SSvote.initiate_vote("roundtype","server",TRUE) + SSvote.initiate_vote(CONFIG_GET(flag/dynamic_voting) ? "dynamic" : "roundtype","server",TRUE) /datum/controller/subsystem/ticker/Recover() current_state = SSticker.current_state diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 2f56c69384..d32ece5aa8 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -87,7 +87,7 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/proc/announce_result() var/list/winners = get_result() var/text - var/was_roundtype_vote = mode == "roundtype" + var/was_roundtype_vote = mode == "roundtype" || mode == "dynamic" if(winners.len > 0) if(question) text += "[question]" @@ -124,6 +124,12 @@ SUBSYSTEM_DEF(vote) message_admins(admintext) return . +#define PEACE2 "Very Calm" +#define PEACE1 "Somewhat Calm" +#define INDIFFERENT "Balanced" +#define CHAOS1"Somewhat chaotic" +#define CHAOS2 "Very chaotic" + /datum/controller/subsystem/vote/proc/result() . = announce_result() var/restart = 0 @@ -146,6 +152,17 @@ SUBSYSTEM_DEF(vote) restart = 1 else GLOB.master_mode = . + if("dynamic") + if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. + return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") + GLOB.dynamic_forced_extended = .=="extended" + if(GLOB.dynamic_forced_extended) + return message_admins("Dynamic extended has been voted for.") + var/mean = (choices["extended"]*-2+choices[PEACE2]*-2+choices[PEACE1]*-1+choices[CHAOS1]*1+choices[CHAOS2]*2)/voted.len + var/variance=(((-2-mean)**2)*choices["extended"]+((-2-mean)**2)*choices[PEACE2]+((-1-mean)**2)*choices[PEACE1]+((0-mean)**2)*choices[INDIFFERENT]+((1-mean)**2)*choices[CHAOS1]+((2-mean)**2)*choices[CHAOS2])/voted.len //Sorry. Im sorry. Im trying to remove it + GLOB.dynamic_curve_centre = mean*(5/2) + GLOB.dynamic_curve_width = max(variance,0.5) + message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") var/datum/map_config/VM = config.maplist[.] message_admins("The map has been voted for and will change to: [VM.map_name]") @@ -213,6 +230,8 @@ SUBSYSTEM_DEF(vote) choices[i] = 0 if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote choices.Add("secret", "extended") + if("dynamic") + choices.Add("extended",PEACE2,PEACE1,INDIFFERENT,CHAOS1,CHAOS2) if("custom") question = stripped_input(usr,"What is the vote for?") if(!question) @@ -369,4 +388,4 @@ SUBSYSTEM_DEF(vote) else if(owner.ckey) var/datum/player_details/P = GLOB.player_details[owner.ckey] if(P) - P.player_actions -= src \ No newline at end of file + P.player_actions -= src diff --git a/config/game_options.txt b/config/game_options.txt index 2e346ce0ac..80887164ff 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -547,3 +547,6 @@ MONKEYCAP 64 ## Uncomment to use TG-style combat #DISABLE_STAMBUFFER + +#Replaces standard extended/secret dichotomy with extended and 5 levels of chaos using dynamic. +DYNAMIC_VOTING From 933e4c58123d0882fefb0e9a185563a00c8d97e9 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 20 Oct 2019 18:57:25 -0700 Subject: [PATCH 002/121] grammar --- code/controllers/subsystem/vote.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index d32ece5aa8..2f84e0194a 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -124,8 +124,8 @@ SUBSYSTEM_DEF(vote) message_admins(admintext) return . -#define PEACE2 "Very Calm" -#define PEACE1 "Somewhat Calm" +#define PEACE2 "Very calm" +#define PEACE1 "Somewhat calm" #define INDIFFERENT "Balanced" #define CHAOS1"Somewhat chaotic" #define CHAOS2 "Very chaotic" From d1326398ddf79f6c952230371a46d2c9773f8aa1 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 20 Oct 2019 19:00:22 -0700 Subject: [PATCH 003/121] make extended vote majority instead of plurality --- code/controllers/subsystem/vote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 2f84e0194a..23d4d3f134 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -155,7 +155,7 @@ SUBSYSTEM_DEF(vote) if("dynamic") if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") - GLOB.dynamic_forced_extended = .=="extended" + GLOB.dynamic_forced_extended = choices["extended"]/voted.len > 0.5 if(GLOB.dynamic_forced_extended) return message_admins("Dynamic extended has been voted for.") var/mean = (choices["extended"]*-2+choices[PEACE2]*-2+choices[PEACE1]*-1+choices[CHAOS1]*1+choices[CHAOS2]*2)/voted.len From 770d95ce8316314c7845a21a9e2eb042897b34ff Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 20 Oct 2019 19:05:24 -0700 Subject: [PATCH 004/121] rename indifferent to balanced also, remember ur spaces --- code/controllers/subsystem/vote.dm | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 23d4d3f134..937889ca2c 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -126,8 +126,8 @@ SUBSYSTEM_DEF(vote) #define PEACE2 "Very calm" #define PEACE1 "Somewhat calm" -#define INDIFFERENT "Balanced" -#define CHAOS1"Somewhat chaotic" +#define BALANCED "Balanced" +#define CHAOS1 "Somewhat chaotic" #define CHAOS2 "Very chaotic" /datum/controller/subsystem/vote/proc/result() @@ -159,7 +159,7 @@ SUBSYSTEM_DEF(vote) if(GLOB.dynamic_forced_extended) return message_admins("Dynamic extended has been voted for.") var/mean = (choices["extended"]*-2+choices[PEACE2]*-2+choices[PEACE1]*-1+choices[CHAOS1]*1+choices[CHAOS2]*2)/voted.len - var/variance=(((-2-mean)**2)*choices["extended"]+((-2-mean)**2)*choices[PEACE2]+((-1-mean)**2)*choices[PEACE1]+((0-mean)**2)*choices[INDIFFERENT]+((1-mean)**2)*choices[CHAOS1]+((2-mean)**2)*choices[CHAOS2])/voted.len //Sorry. Im sorry. Im trying to remove it + var/variance=(((-2-mean)**2)*choices["extended"]+((-2-mean)**2)*choices[PEACE2]+((-1-mean)**2)*choices[PEACE1]+((0-mean)**2)*choices[BALANCED]+((1-mean)**2)*choices[CHAOS1]+((2-mean)**2)*choices[CHAOS2])/voted.len //Sorry. Im sorry. Im trying to remove it GLOB.dynamic_curve_centre = mean*(5/2) GLOB.dynamic_curve_width = max(variance,0.5) message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") @@ -231,7 +231,7 @@ SUBSYSTEM_DEF(vote) if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote choices.Add("secret", "extended") if("dynamic") - choices.Add("extended",PEACE2,PEACE1,INDIFFERENT,CHAOS1,CHAOS2) + choices.Add("extended",PEACE2,PEACE1,BALANCED,CHAOS1,CHAOS2) if("custom") question = stripped_input(usr,"What is the vote for?") if(!question) @@ -389,3 +389,9 @@ SUBSYSTEM_DEF(vote) var/datum/player_details/P = GLOB.player_details[owner.ckey] if(P) P.player_actions -= src + +#undef PEACE2 +#undef PEACE1 +#undef BALANCED +#undef CHAOS1 +#undef CHAOS2 From 0a000f3165875ace0d8b89ef909cadb59170a5a2 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 21 Oct 2019 01:05:18 -0700 Subject: [PATCH 005/121] Division by zero. --- code/controllers/subsystem/vote.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 937889ca2c..91a19fda1d 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -155,6 +155,9 @@ SUBSYSTEM_DEF(vote) if("dynamic") if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") + GLOB.master_mode = "dynamic" + if(voted.len==0) + return message_admins("Nobody voted in the extended vote; using default dynamic settings.") GLOB.dynamic_forced_extended = choices["extended"]/voted.len > 0.5 if(GLOB.dynamic_forced_extended) return message_admins("Dynamic extended has been voted for.") From da7d4345b5bdcaa07662de1ef5d9abe15329cb23 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 21 Oct 2019 03:18:27 -0700 Subject: [PATCH 006/121] Added a toggle dynamic vote verb for admins. --- code/modules/admin/admin.dm | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 555c35980d..004ab9e17e 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -686,6 +686,19 @@ log_admin("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/admins/proc/toggledynamicvote() + set category = "Server" + set desc="Switches between secret/extended and dynamic voting" + set name="Toggle Dynamic Vote" + CONFIG_SET(flag/dynamic_voting,!CONFIG_GET(flag/dynamic_voting)) + if (CONFIG_GET(flag/dynamic_voting)) + to_chat(world, "Vote is now between extended and dynamic chaos.") + else + to_chat(world, "Vote is now between extended and secret.") + log_admin("[key_name(usr)] toggled dynamic voting.") + message_admins("[key_name_admin(usr)] toggled dynamic voting.") + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dynamic Voting", "[CONFIG_GET(flag/dynamic_voting) ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + /datum/admins/proc/unprison(mob/M in GLOB.mob_list) set category = "Admin" set name = "Unprison" From 74ca1a9ccfafbed7080db26b2c3b69533f69ecf3 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 21 Oct 2019 04:56:06 -0700 Subject: [PATCH 007/121] concept: actually let admins do it --- code/modules/admin/admin_verbs.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 626fa7f66f..a9b3b9208c 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -122,6 +122,7 @@ GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer()) /client/proc/everyone_random, /datum/admins/proc/toggleAI, /datum/admins/proc/toggleMulticam, + /datum/admins/proc/toggledynamicvote, /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ /client/proc/cmd_debug_del_all, /client/proc/toggle_random_events, From 296ce4fb78b45fbc6f088591420d5967068b26b2 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 21 Oct 2019 05:18:44 -0700 Subject: [PATCH 008/121] suggested changes --- code/modules/admin/admin.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 004ab9e17e..0235431705 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -690,14 +690,15 @@ set category = "Server" set desc="Switches between secret/extended and dynamic voting" set name="Toggle Dynamic Vote" - CONFIG_SET(flag/dynamic_voting,!CONFIG_GET(flag/dynamic_voting)) - if (CONFIG_GET(flag/dynamic_voting)) + var/prev_dynamic_voting = CONFIG_GET(flag/dynamic_voting) + CONFIG_SET(flag/dynamic_voting,!prev_dynamic_voting) + if (!prev_dynamic_voting) to_chat(world, "Vote is now between extended and dynamic chaos.") else to_chat(world, "Vote is now between extended and secret.") - log_admin("[key_name(usr)] toggled dynamic voting.") + log_admin("[key_name(usr)] [prev_dynamic_voting ? "disabled" : "enabled"] dynamic voting.") message_admins("[key_name_admin(usr)] toggled dynamic voting.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dynamic Voting", "[CONFIG_GET(flag/dynamic_voting) ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dynamic Voting", "[prev_dynamic_voting ? "Disabled" : "Enabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/unprison(mob/M in GLOB.mob_list) set category = "Admin" From d96976fc5958a0e51b0e04910a687861f20d182f Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 22 Oct 2019 00:34:14 -0700 Subject: [PATCH 009/121] Added dynamic vote logging --- code/controllers/subsystem/vote.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 91a19fda1d..9aa3910ab6 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -166,6 +166,7 @@ SUBSYSTEM_DEF(vote) GLOB.dynamic_curve_centre = mean*(5/2) GLOB.dynamic_curve_width = max(variance,0.5) message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") + log_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") var/datum/map_config/VM = config.maplist[.] message_admins("The map has been voted for and will change to: [VM.map_name]") From 33232fba3af7e31df632ac94184279e13a42e8d7 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 22 Oct 2019 00:45:30 -0700 Subject: [PATCH 010/121] s --- code/controllers/subsystem/vote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 9aa3910ab6..bb47af3c95 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -166,7 +166,7 @@ SUBSYSTEM_DEF(vote) GLOB.dynamic_curve_centre = mean*(5/2) GLOB.dynamic_curve_width = max(variance,0.5) message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") - log_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") + log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") var/datum/map_config/VM = config.maplist[.] message_admins("The map has been voted for and will change to: [VM.map_name]") From e3b901fd23b32313398c82299650e1ff4aaf0ac3 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 5 Nov 2019 23:45:59 -0800 Subject: [PATCH 011/121] Makes malf AI its own ruleset in dynamic. --- .../dynamic/dynamic_rulesets_midround.dm | 2 +- .../dynamic/dynamic_rulesets_roundstart.dm | 56 ++++++++++++++++++- config/game_options.txt | 12 ++-- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index f24301d716..cab5582d16 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -225,7 +225,7 @@ /datum/dynamic_ruleset/midround/malf name = "Malfunctioning AI" - config_tag = "malf_ai" + config_tag = "malf_ai_midround" antag_datum = /datum/antagonist/traitor antag_flag = ROLE_MALF enemy_roles = list("Security Officer", "Warden","Detective","Head of Security", "Captain", "Scientist", "Chemist", "Research Director", "Chief Engineer") diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 6a9aefa996..688fed657a 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -13,7 +13,7 @@ antag_datum = /datum/antagonist/traitor/ minimum_required_age = 0 protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster", "Cyborg") - restricted_roles = list("Cyborg") + restricted_roles = list("Cyborg", "AI") required_candidates = 1 weight = 5 cost = 10 @@ -41,6 +41,60 @@ log_game("DYNAMIC: Checking if we can turn someone into a traitor.") mode.picking_specific_rule(/datum/dynamic_ruleset/midround/autotraitor) +////////////////////////////////////////////// +// // +// SYNDICATE TRAITORS // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/roundstart/malf_ai + name = "Malfunctioning AI" + config_tag = "malf_ai" + antag_datum = /datum/antagonist/traitor + antag_flag = ROLE_MALF + enemy_roles = list("Security Officer", "Warden","Detective","Head of Security", "Captain", "Scientist", "Chemist", "Research Director", "Chief Engineer") + exclusive_roles = list("AI") + required_enemies = list(4,4,4,4,4,4,2,2,2,0) + required_candidates = 1 + weight = 1 + cost = 35 + requirements = list(101,101,80,70,60,60,50,50,40,40) + high_population_requirement = 35 + required_type = /mob/living/silicon/ai + +/datum/dynamic_ruleset/roundstart/malf_ai/trim_candidates() + ..() + candidates = candidates[CURRENT_LIVING_PLAYERS] + for(var/mob/living/player in candidates) + if(!isAI(player)) + candidates -= player + continue + if(is_centcom_level(player.z)) + candidates -= player + continue + if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0)) + candidates -= player + +/datum/dynamic_ruleset/roundstart/malf_ai/execute() + if(!candidates || !candidates.len) + return FALSE + var/mob/living/silicon/ai/M = pick(candidates) + candidates -= M + assigned += M.mind + var/datum/antagonist/traitor/AI = new + M.mind.special_role = antag_flag + M.mind.add_antag_datum(AI) + return TRUE + +/datum/dynamic_ruleset/roundstart/malf_ai/rule_process() + if (autotraitor_cooldown > 0) + autotraitor_cooldown-- + else + autotraitor_cooldown = 450 // 15 minutes + message_admins("Checking if we can turn someone into a traitor.") + log_game("DYNAMIC: Checking if we can turn someone into a traitor.") + mode.picking_specific_rule(/datum/dynamic_ruleset/midround/autotraitor) + ////////////////////////////////////////// // // // BLOOD BROTHERS // diff --git a/config/game_options.txt b/config/game_options.txt index c06845cde3..56b1bbca6e 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -280,6 +280,7 @@ DYNAMIC_POP_PER_REQUIREMENT 6 ## 1 -> 9, probability for this rule to be picked against other rules. ## Note that requirements must also be met, and some requirements are impossible to meet. DYNAMIC_WEIGHT TRAITOR 5 +DYNAMIC_WEIGHT MALF_AI 1 DYNAMIC_WEIGHT TRAITORBRO 4 DYNAMIC_WEIGHT CHANGELING 3 DYNAMIC_WEIGHT WIZARD 1 @@ -296,7 +297,7 @@ DYNAMIC_WEIGHT METEOR 3 ## Midround antags DYNAMIC_WEIGHT MIDROUND_TRAITOR 7 -DYNAMIC_WEIGHT MALF_AI 3 +DYNAMIC_WEIGHT MIDROUND_MALF_AI 3 DYNAMIC_WEIGHT MIDROUND_WIZARD 1 DYNAMIC_WEIGHT MIDROUND_NUCLEAR 5 DYNAMIC_WEIGHT BLOB 4 @@ -309,6 +310,7 @@ DYNAMIC_WEIGHT LATEJOIN_REVOLUTION 2 ## Threat cost. This is decreased from the mode's threat when the rule is executed. DYNAMIC_COST TRAITOR 10 +DYNAMIC_COST MALF_AI 35 DYNAMIC_COST TRAITORBRO 10 DYNAMIC_COST CHANGELING 30 DYNAMIC_COST WIZARD 30 @@ -325,7 +327,7 @@ DYNAMIC_COST METEOR 0 ## Midround antags DYNAMIC_COST MIDROUND_TRAITOR 10 -DYNAMIC_COST MALF_AI 35 +DYNAMIC_COST MIDROUND_MALF_AI 35 DYNAMIC_COST MIDROUND_WIZARD 20 DYNAMIC_COST MIDROUND_NUCLEAR 35 DYNAMIC_COST BLOB 10 @@ -341,6 +343,7 @@ DYNAMIC_COST LATEJOIN_REVOLUTION 20 ## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-5, 30 at 6-11 etc. DYNAMIC_REQUIREMENTS TRAITOR 10 10 10 10 10 10 10 10 10 10 DYNAMIC_REQUIREMENTS TRAITORBRO 40 30 30 20 20 15 15 15 10 10 +DYNAMIC_REQUIREMENTS MALF_AI 101 101 80 70 60 60 50 50 40 40 DYNAMIC_REQUIREMENTS CHANGELING 80 70 60 50 40 20 20 10 10 10 DYNAMIC_REQUIREMENTS WIZARD 90 90 70 40 30 20 10 10 10 10 DYNAMIC_REQUIREMENTS CULT 100 90 80 60 40 30 10 10 10 10 @@ -356,7 +359,7 @@ DYNAMIC_REQUIREMENTS METEOR 101 101 101 101 101 101 101 101 101 101 ## Midround antags DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 50 40 30 20 10 10 10 10 10 10 -DYNAMIC_REQUIREMENTS MALF_AI 101 101 80 70 60 60 50 50 40 40 +DYNAMIC_REQUIREMENTS MIDROUND_MALF_AI 101 101 80 70 60 60 50 50 40 40 DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 70 40 30 20 10 10 10 10 DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 60 40 30 20 10 10 DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 30 20 10 10 @@ -369,6 +372,7 @@ DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 30 20 20 20 20 20 ## An alternative, static requirement used instead when pop is over mode's high_pop_limit. DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MALF_AI 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITORBRO 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT CHANGELING 10 DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 10 @@ -385,7 +389,7 @@ DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR 101 ## Midround antags DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_TRAITOR 10 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MALF_AI 35 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_MALF_AI 35 DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_WIZARD 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 10 DYNAMIC_HIGH_POPULATION_REQUIREMENT BLOB 50 From 13bc121306f5fd925a07e964d560e9187c2fe733 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 5 Nov 2019 23:52:26 -0800 Subject: [PATCH 012/121] Makes sure that actually works. --- code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 688fed657a..b87ba8b66a 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -43,7 +43,7 @@ ////////////////////////////////////////////// // // -// SYNDICATE TRAITORS // +// MALF AI // // // ////////////////////////////////////////////// @@ -60,7 +60,7 @@ cost = 35 requirements = list(101,101,80,70,60,60,50,50,40,40) high_population_requirement = 35 - required_type = /mob/living/silicon/ai + var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) /datum/dynamic_ruleset/roundstart/malf_ai/trim_candidates() ..() From 401bbbd8ab15ceacdc4e90f222bdaf94218f7023 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 00:07:52 -0800 Subject: [PATCH 013/121] Reduced vote to just extended vs calm vs chaos. --- code/controllers/subsystem/vote.dm | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index bb47af3c95..84588836a5 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -124,11 +124,8 @@ SUBSYSTEM_DEF(vote) message_admins(admintext) return . -#define PEACE2 "Very calm" -#define PEACE1 "Somewhat calm" -#define BALANCED "Balanced" -#define CHAOS1 "Somewhat chaotic" -#define CHAOS2 "Very chaotic" +#define PEACE "calm" +#define CHAOS "chaotic" /datum/controller/subsystem/vote/proc/result() . = announce_result() @@ -157,14 +154,14 @@ SUBSYSTEM_DEF(vote) return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") GLOB.master_mode = "dynamic" if(voted.len==0) - return message_admins("Nobody voted in the extended vote; using default dynamic settings.") + return message_admins("Nobody voted in the dynamic vote; using default dynamic settings.") GLOB.dynamic_forced_extended = choices["extended"]/voted.len > 0.5 if(GLOB.dynamic_forced_extended) return message_admins("Dynamic extended has been voted for.") - var/mean = (choices["extended"]*-2+choices[PEACE2]*-2+choices[PEACE1]*-1+choices[CHAOS1]*1+choices[CHAOS2]*2)/voted.len - var/variance=(((-2-mean)**2)*choices["extended"]+((-2-mean)**2)*choices[PEACE2]+((-1-mean)**2)*choices[PEACE1]+((0-mean)**2)*choices[BALANCED]+((1-mean)**2)*choices[CHAOS1]+((2-mean)**2)*choices[CHAOS2])/voted.len //Sorry. Im sorry. Im trying to remove it - GLOB.dynamic_curve_centre = mean*(5/2) - GLOB.dynamic_curve_width = max(variance,0.5) + var/mean = (choices["extended"]*-1+choices[PEACE]*-1+choices[CHAOS])/voted.len + GLOB.dynamic_curve_centre = mean*5 + var/variance=(((-1-mean)**2)*choices["extended"]+((-1-mean)**2)*choices[PEACE]+((1-mean)**2)*choices[CHAOS])/voted.len //Sorry. Im sorry. Im trying to remove it + GLOB.dynamic_curve_width = CLAMP(variance*4,0.5,4) message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") @@ -235,7 +232,7 @@ SUBSYSTEM_DEF(vote) if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote choices.Add("secret", "extended") if("dynamic") - choices.Add("extended",PEACE2,PEACE1,BALANCED,CHAOS1,CHAOS2) + choices.Add("extended",PEACE,CHAOS) if("custom") question = stripped_input(usr,"What is the vote for?") if(!question) From c354b17afe67713a0b678c9f185c09fe3d59c098 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 00:13:39 -0800 Subject: [PATCH 014/121] Also deobfuscates dynamic vote --- code/controllers/subsystem/ticker.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index ccdf98a71f..c29ddcde4c 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -479,7 +479,8 @@ SUBSYSTEM_DEF(ticker) if(SSticker.timeLeft < 900) SSticker.timeLeft = 900 SSticker.modevoted = TRUE - SSvote.initiate_vote(CONFIG_GET(flag/dynamic_voting) ? "dynamic" : "roundtype","server",TRUE) + var/dynamic = CONFIG_GET(flag/dynamic_voting) + SSvote.initiate_vote(dynamic ? "dynamic" : "roundtype","server",!dynamic) /datum/controller/subsystem/ticker/Recover() current_state = SSticker.current_state From b240956c4c9611b76faa929fdfd7238fa02513f9 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 00:21:47 -0800 Subject: [PATCH 015/121] Okay, just peace vs chaos. --- code/controllers/subsystem/vote.dm | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 84588836a5..bfa0088cdb 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -155,12 +155,9 @@ SUBSYSTEM_DEF(vote) GLOB.master_mode = "dynamic" if(voted.len==0) return message_admins("Nobody voted in the dynamic vote; using default dynamic settings.") - GLOB.dynamic_forced_extended = choices["extended"]/voted.len > 0.5 - if(GLOB.dynamic_forced_extended) - return message_admins("Dynamic extended has been voted for.") - var/mean = (choices["extended"]*-1+choices[PEACE]*-1+choices[CHAOS])/voted.len + var/mean = (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*5 - var/variance=(((-1-mean)**2)*choices["extended"]+((-1-mean)**2)*choices[PEACE]+((1-mean)**2)*choices[CHAOS])/voted.len //Sorry. Im sorry. Im trying to remove it + var/variance=(((-1-mean)**2)*choices[PEACE]+((1-mean)**2)*choices[CHAOS])/voted.len GLOB.dynamic_curve_width = CLAMP(variance*4,0.5,4) message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") @@ -232,7 +229,7 @@ SUBSYSTEM_DEF(vote) if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote choices.Add("secret", "extended") if("dynamic") - choices.Add("extended",PEACE,CHAOS) + choices.Add(PEACE,CHAOS) if("custom") question = stripped_input(usr,"What is the vote for?") if(!question) From a5b3d49facb224cb515539b2222976f8cce3db2e Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 01:03:43 -0800 Subject: [PATCH 016/121] actually it's gotta be delayed --- .../gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index b87ba8b66a..463c372f0c 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -47,7 +47,7 @@ // // ////////////////////////////////////////////// -/datum/dynamic_ruleset/roundstart/malf_ai +/datum/dynamic_ruleset/roundstart/delayed/malf_ai name = "Malfunctioning AI" config_tag = "malf_ai" antag_datum = /datum/antagonist/traitor @@ -60,9 +60,10 @@ cost = 35 requirements = list(101,101,80,70,60,60,50,50,40,40) high_population_requirement = 35 + required_type = /mob/living/silicon/ai var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) -/datum/dynamic_ruleset/roundstart/malf_ai/trim_candidates() +/datum/dynamic_ruleset/roundstart/delayed/malf_ai/trim_candidates() ..() candidates = candidates[CURRENT_LIVING_PLAYERS] for(var/mob/living/player in candidates) @@ -75,7 +76,7 @@ if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0)) candidates -= player -/datum/dynamic_ruleset/roundstart/malf_ai/execute() +/datum/dynamic_ruleset/roundstart/delayed/malf_ai/execute() if(!candidates || !candidates.len) return FALSE var/mob/living/silicon/ai/M = pick(candidates) @@ -86,7 +87,7 @@ M.mind.add_antag_datum(AI) return TRUE -/datum/dynamic_ruleset/roundstart/malf_ai/rule_process() +/datum/dynamic_ruleset/roundstart/delayed/malf_ai/rule_process() if (autotraitor_cooldown > 0) autotraitor_cooldown-- else From 39bdbde0673cdbfd585c2d7adcf28cd55db8423c Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 01:26:30 -0800 Subject: [PATCH 017/121] Makes summon (X) cost threat in dynamic --- .../antagonists/wizard/equipment/spellbook.dm | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index bb7ffdc85d..b8380c60a2 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -482,6 +482,10 @@ /datum/spellbook_entry/summon/guns/IsAvailible() if(!SSticker.mode) // In case spellbook is placed on map return 0 + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + if(mode.threat < CONFIG_GET(number/summon_guns_requirement)) + return 0 return !CONFIG_GET(flag/no_summon_guns) /datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) @@ -490,6 +494,9 @@ active = 1 playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1) to_chat(user, "You have cast summon guns!") + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + mode.spend_threat(CONFIG_GET(number/summon_guns_cost)) return 1 /datum/spellbook_entry/summon/magic @@ -499,6 +506,10 @@ /datum/spellbook_entry/summon/magic/IsAvailible() if(!SSticker.mode) // In case spellbook is placed on map return 0 + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + if(mode.threat < CONFIG_GET(number/summon_magic_requirement)) + return 0 return !CONFIG_GET(flag/no_summon_magic) /datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) @@ -507,6 +518,9 @@ active = 1 playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1) to_chat(user, "You have cast summon magic!") + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + mode.spend_threat(CONFIG_GET(number/summon_magic_cost)) return 1 /datum/spellbook_entry/summon/events @@ -517,6 +531,10 @@ /datum/spellbook_entry/summon/events/IsAvailible() if(!SSticker.mode) // In case spellbook is placed on map return 0 + if(istype(SSticker.mode,/datum/game_mode/dynamic) && times == 0) + var/datum/game_mode/dynamic/mode = SSticker.mode + if(mode.threat < CONFIG_GET(number/summon_events_requirement)) + return 0 return !CONFIG_GET(flag/no_summon_events) /datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) @@ -525,6 +543,9 @@ times++ playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1) to_chat(user, "You have cast summon events.") + if(istype(SSticker.mode,/datum/game_mode/dynamic) && times == 0) + var/datum/game_mode/dynamic/mode = SSticker.mode + mode.spend_threat(CONFIG_GET(number/summon_events_cost)) return 1 /datum/spellbook_entry/summon/events/GetInfo() From 8e38a6a9ba37a0ee9cefbf813b9bf7c5ca8957be Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 01:26:58 -0800 Subject: [PATCH 018/121] WOW THIS IS IMPORTANT --- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index cab5582d16..bdd37cb56b 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -225,7 +225,7 @@ /datum/dynamic_ruleset/midround/malf name = "Malfunctioning AI" - config_tag = "malf_ai_midround" + config_tag = "midround_malf_ai" antag_datum = /datum/antagonist/traitor antag_flag = ROLE_MALF enemy_roles = list("Security Officer", "Warden","Detective","Head of Security", "Captain", "Scientist", "Chemist", "Research Director", "Chief Engineer") From 708f1e4731753aee5acc145d906c63ef5fa9832c Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 01:31:43 -0800 Subject: [PATCH 019/121] Actually added stuff to the config. --- .../configuration/entries/game_options.dm | 24 +++++++++++++++++++ config/game_options.txt | 16 +++++++++++++ 2 files changed, 40 insertions(+) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 36b57a4b7c..e11f33c021 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -411,3 +411,27 @@ /datum/config_entry/keyed_list/dynamic_high_population_requirement key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_NUM + +/datum/config_entry/number/dynamic_summon_guns_requirement + config_entry_value = 10 + min_val = 0 + +/datum/config_entry/number/dynamic_summon_guns_cost + config_entry_value = 5 + min_val = 0 + +/datum/config_entry/number/dynamic_summon_magic_requirement + config_entry_value = 10 + min_val = 0 + +/datum/config_entry/number/dynamic_summon_magic_cost + config_entry_value = 5 + min_val = 0 + +/datum/config_entry/number/dynamic_summon_events_requirement + config_entry_value = 20 + min_val = 0 + +/datum/config_entry/number/dynamic_summon_events_cost + config_entry_value = 10 + min_val = 0 diff --git a/config/game_options.txt b/config/game_options.txt index c06845cde3..2f008cf365 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -396,6 +396,22 @@ DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 10 DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_REVOLUTION 50 +## Dynamic wizard stuff + +## How much threat level is required to buy summon guns. Setting to 0 makes it always available. +DYNAMIC_SUMMON_GUNS_REQUIREMENT 10 + +## How much summon guns reduces the round's remaining threat. Setting to 0 makes it cost none. +DYNAMIC_SUMMON_GUNS_COST 5 + +## As above, but for summon magic +DYNAMIC_SUMMON_MAGIC_REQUIREMENT 10 +DYNAMIC_SUMMON_MAGIC_COST 5 + +## As above, but for summon events +DYNAMIC_SUMMON_EVENTS_REQUIREMENT 20 +DYNAMIC_SUMMON_EVENTS_COST 10 + ## AI ### ## Allow the AI job to be picked. From 97493690d35bd2f0be93d680b9384cd7a1d1cbe2 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 01:34:36 -0800 Subject: [PATCH 020/121] hmm, also important --- .../antagonists/wizard/equipment/spellbook.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index b8380c60a2..ab37997e50 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -484,7 +484,7 @@ return 0 if(istype(SSticker.mode,/datum/game_mode/dynamic)) var/datum/game_mode/dynamic/mode = SSticker.mode - if(mode.threat < CONFIG_GET(number/summon_guns_requirement)) + if(mode.threat < CONFIG_GET(number/dynamic_summon_guns_requirement)) return 0 return !CONFIG_GET(flag/no_summon_guns) @@ -496,7 +496,7 @@ to_chat(user, "You have cast summon guns!") if(istype(SSticker.mode,/datum/game_mode/dynamic)) var/datum/game_mode/dynamic/mode = SSticker.mode - mode.spend_threat(CONFIG_GET(number/summon_guns_cost)) + mode.spend_threat(CONFIG_GET(number/dynamic_summon_guns_cost)) return 1 /datum/spellbook_entry/summon/magic @@ -508,7 +508,7 @@ return 0 if(istype(SSticker.mode,/datum/game_mode/dynamic)) var/datum/game_mode/dynamic/mode = SSticker.mode - if(mode.threat < CONFIG_GET(number/summon_magic_requirement)) + if(mode.threat < CONFIG_GET(number/dynamic_summon_magic_requirement)) return 0 return !CONFIG_GET(flag/no_summon_magic) @@ -520,7 +520,7 @@ to_chat(user, "You have cast summon magic!") if(istype(SSticker.mode,/datum/game_mode/dynamic)) var/datum/game_mode/dynamic/mode = SSticker.mode - mode.spend_threat(CONFIG_GET(number/summon_magic_cost)) + mode.spend_threat(CONFIG_GET(number/dynamic_summon_magic_cost)) return 1 /datum/spellbook_entry/summon/events @@ -533,7 +533,7 @@ return 0 if(istype(SSticker.mode,/datum/game_mode/dynamic) && times == 0) var/datum/game_mode/dynamic/mode = SSticker.mode - if(mode.threat < CONFIG_GET(number/summon_events_requirement)) + if(mode.threat < CONFIG_GET(number/dynamic_summon_events_requirement)) return 0 return !CONFIG_GET(flag/no_summon_events) @@ -545,7 +545,7 @@ to_chat(user, "You have cast summon events.") if(istype(SSticker.mode,/datum/game_mode/dynamic) && times == 0) var/datum/game_mode/dynamic/mode = SSticker.mode - mode.spend_threat(CONFIG_GET(number/summon_events_cost)) + mode.spend_threat(CONFIG_GET(number/dynamic_summon_events_cost)) return 1 /datum/spellbook_entry/summon/events/GetInfo() From 92db306ca92444bbb5e433720c5a3b49da71a1e4 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 02:03:51 -0800 Subject: [PATCH 021/121] disable ling whoops. --- config/game_options.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/game_options.txt b/config/game_options.txt index 654aaf65cf..c63f4d03d2 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -335,7 +335,7 @@ DYNAMIC_COST LATEJOIN_REVOLUTION 20 ## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-5, 30 at 6-11 etc. DYNAMIC_REQUIREMENTS TRAITOR 10 10 10 10 10 10 10 10 10 10 DYNAMIC_REQUIREMENTS TRAITORBRO 40 30 30 20 20 15 15 15 10 10 -DYNAMIC_REQUIREMENTS CHANGELING 80 70 60 50 40 20 20 10 10 10 +DYNAMIC_REQUIREMENTS CHANGELING 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS WIZARD 90 90 70 40 30 20 10 10 10 10 DYNAMIC_REQUIREMENTS CULT 100 90 80 60 40 30 10 10 10 10 DYNAMIC_REQUIREMENTS NUCLEAR 90 90 90 80 60 40 30 20 10 10 @@ -364,7 +364,7 @@ DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 30 20 20 20 20 20 ## An alternative, static requirement used instead when pop is over mode's high_pop_limit. DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 10 DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITORBRO 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CHANGELING 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT CHANGELING 101 DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 10 DYNAMIC_HIGH_POPULATION_REQUIREMENT CULT 10 DYNAMIC_HIGH_POPULATION_REQUIREMENT NUCLEAR 10 From cda716509859bbfd7613e013f6a11ef9c25cda66 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 02:06:21 -0800 Subject: [PATCH 022/121] balance changes (oh no) --- config/game_options.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/game_options.txt b/config/game_options.txt index c63f4d03d2..fe191f245d 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -259,7 +259,7 @@ EVENTS_MIN_PLAYERS_MUL 1 ### DYNAMIC MODE ### ## How many roundstart players required for high population override to take effect. -DYNAMIC_HIGH_POP_LIMIT 55 +DYNAMIC_HIGH_POP_LIMIT 80 #80 instead of 55 because fewer robust players ## Pop range per requirement. ## If the value is five the range is: @@ -269,7 +269,7 @@ DYNAMIC_HIGH_POP_LIMIT 55 ## If it is seven the range is: ## 0-6, 7-13, 14-20, 21-27, 28-34, 35-41, 42-48, 49-55, 56-62, 63+ ## Options outside this range can be used, of course. -DYNAMIC_POP_PER_REQUIREMENT 6 +DYNAMIC_POP_PER_REQUIREMENT 9 # 9 instead of 6 because 1/3 of players are probably not doing much? ## 1 -> 9, probability for this rule to be picked against other rules. ## Note that requirements must also be met, and some requirements are impossible to meet. From c532bcd484d0b196b86416dc4488617fb92c545f Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 02:13:13 -0800 Subject: [PATCH 023/121] makes all enemy-required rulesets require more enemies --- .../gamemodes/dynamic/dynamic_rulesets_latejoin.dm | 2 +- .../gamemodes/dynamic/dynamic_rulesets_midround.dm | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index fde020a3ae..838ca3ec62 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -79,7 +79,7 @@ antag_flag_override = ROLE_REV restricted_roles = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") enemy_roles = list("AI", "Cyborg", "Security Officer","Detective","Head of Security", "Captain", "Warden") - required_enemies = list(2,2,1,1,1,1,1,0,0,0) + required_enemies = list(4,4,3,3,3,3,3,2,2,1) required_candidates = 1 weight = 2 cost = 20 diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 56b6e57c4d..1b4594de2c 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -230,7 +230,7 @@ antag_flag = ROLE_MALF enemy_roles = list("Security Officer", "Warden","Detective","Head of Security", "Captain", "Scientist", "Chemist", "Research Director", "Chief Engineer") exclusive_roles = list("AI") - required_enemies = list(4,4,4,4,4,4,2,2,2,0) + required_enemies = list(6,6,6,4,4,4,2,2,2,1) required_candidates = 1 weight = 3 cost = 35 @@ -282,7 +282,7 @@ antag_datum = /datum/antagonist/wizard antag_flag = ROLE_WIZARD enemy_roles = list("Security Officer","Detective","Head of Security", "Captain") - required_enemies = list(2,2,1,1,1,1,1,0,0,0) + required_enemies = list(4,4,3,2,2,1,1,0,0,0) required_candidates = 1 weight = 1 cost = 20 @@ -315,7 +315,7 @@ antag_flag = ROLE_OPERATIVE antag_datum = /datum/antagonist/nukeop enemy_roles = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain") - required_enemies = list(3,3,3,3,3,2,1,1,0,0) + required_enemies = list(5,5,4,3,3,2,2,2,1,1) required_candidates = 5 weight = 5 cost = 35 @@ -359,7 +359,7 @@ antag_datum = /datum/antagonist/blob antag_flag = ROLE_BLOB enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") - required_enemies = list(2,2,1,1,1,1,1,0,0,0) + required_enemies = list(3,3,2,2,2,1,1,1,1,0) required_candidates = 1 weight = 4 cost = 10 @@ -383,7 +383,7 @@ antag_datum = /datum/antagonist/xeno antag_flag = ROLE_ALIEN enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") - required_enemies = list(2,2,1,1,1,1,1,0,0,0) + required_enemies = list(3,3,2,2,1,1,1,1,1,0) required_candidates = 1 weight = 3 cost = 10 From 6197d2b956b3df7438706073114f9d04beb0a6ac Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 02:41:03 -0800 Subject: [PATCH 024/121] ton of unsolicited balance changes 1. DYNAMIC_POP_PER_REQUIREMENT increased from 6 to 9, to account for ERPers by the playercount stuff 2. increased cost of cult, nuclear, revs a bit 3. Made extended slightly more likely at all pop levels, ramping up at ever lower (doesn't matter nearly as much below 25) 4. allowed clock cult --- config/game_options.txt | 56 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/config/game_options.txt b/config/game_options.txt index fe191f245d..7fed97bb74 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -275,7 +275,7 @@ DYNAMIC_POP_PER_REQUIREMENT 9 # 9 instead of 6 because 1/3 of players are probab ## Note that requirements must also be met, and some requirements are impossible to meet. DYNAMIC_WEIGHT TRAITOR 5 DYNAMIC_WEIGHT TRAITORBRO 4 -DYNAMIC_WEIGHT CHANGELING 3 +DYNAMIC_WEIGHT CHANGELING 1 DYNAMIC_WEIGHT WIZARD 1 DYNAMIC_WEIGHT CULT 3 DYNAMIC_WEIGHT NUCLEAR 3 @@ -306,9 +306,9 @@ DYNAMIC_COST TRAITOR 10 DYNAMIC_COST TRAITORBRO 10 DYNAMIC_COST CHANGELING 30 DYNAMIC_COST WIZARD 30 -DYNAMIC_COST CULT 30 -DYNAMIC_COST NUCLEAR 40 -DYNAMIC_COST REVOLUTION 35 +DYNAMIC_COST CULT 35 +DYNAMIC_COST NUCLEAR 45 +DYNAMIC_COST REVOLUTION 40 # All below are impossible-by-default DYNAMIC_COST EXTENDED 0 DYNAMIC_COST CLOCKWORK_CULT 0 @@ -331,44 +331,44 @@ DYNAMIC_COST LATEJOIN_TRAITOR 5 DYNAMIC_COST LATEJOIN_REVOLUTION 20 ## Rule will not be generated with threat levels below requirement at a pop value. Pop values are determined by dynamic's pop-per-requirement. -## By default it's 0-5, 6-11, 12-17, 18-23, 24-29, 30-35, 36-41, 42-47, 48-53, 54+. -## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-5, 30 at 6-11 etc. -DYNAMIC_REQUIREMENTS TRAITOR 10 10 10 10 10 10 10 10 10 10 -DYNAMIC_REQUIREMENTS TRAITORBRO 40 30 30 20 20 15 15 15 10 10 +## By default it's 0-8, 9-17, 18-26, 27-35, 36-44, 45-53, 54-60, 61-69, 70-78, 79+. +## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-8, 30 at 9-17 etc. +DYNAMIC_REQUIREMENTS TRAITOR 40 30 20 15 15 15 15 15 15 15 +DYNAMIC_REQUIREMENTS TRAITORBRO 50 40 30 20 20 15 15 15 15 15 DYNAMIC_REQUIREMENTS CHANGELING 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS WIZARD 90 90 70 40 30 20 10 10 10 10 -DYNAMIC_REQUIREMENTS CULT 100 90 80 60 40 30 10 10 10 10 -DYNAMIC_REQUIREMENTS NUCLEAR 90 90 90 80 60 40 30 20 10 10 -DYNAMIC_REQUIREMENTS REVOLUTION 101 101 70 40 30 20 10 10 10 10 +DYNAMIC_REQUIREMENTS WIZARD 100 90 70 40 30 20 15 15 15 15 +DYNAMIC_REQUIREMENTS CULT 100 90 80 60 40 30 15 15 15 15 +DYNAMIC_REQUIREMENTS NUCLEAR 100 90 90 80 60 40 30 20 15 15 +DYNAMIC_REQUIREMENTS REVOLUTION 101 101 70 40 30 20 15 15 15 15 # All below are impossible-by-default DYNAMIC_REQUIREMENTS EXTENDED 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 101 101 101 101 101 101 101 101 101 101 +DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 100 90 80 60 40 30 15 15 15 15 DYNAMIC_REQUIREMENTS CLOWNOPS 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS DEVIL 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS MONKEY 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS METEOR 101 101 101 101 101 101 101 101 101 101 ## Midround antags -DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 50 40 30 20 10 10 10 10 10 10 +DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 50 40 30 20 15 15 15 15 15 15 DYNAMIC_REQUIREMENTS MALF_AI 101 101 80 70 60 60 50 50 40 40 -DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 70 40 30 20 10 10 10 10 -DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 60 40 30 20 10 10 -DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 30 20 10 10 -DYNAMIC_REQUIREMENTS XENOS 101 101 101 70 50 40 20 15 10 10 -DYNAMIC_REQUIREMENTS NIGHTMARE 101 101 101 70 50 40 20 15 10 10 +DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 70 40 30 20 15 15 15 15 +DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 60 40 30 20 15 15 +DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 30 20 15 15 +DYNAMIC_REQUIREMENTS XENOS 101 101 101 70 50 40 20 15 15 15 +DYNAMIC_REQUIREMENTS NIGHTMARE 101 101 101 70 50 40 20 15 15 15 ## Latejoin antags -DYNAMIC_REQUIREMENTS LATEJOIN_TRAITOR 40 30 20 10 10 10 10 10 10 10 +DYNAMIC_REQUIREMENTS LATEJOIN_TRAITOR 40 30 20 15 15 15 15 15 15 15 DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 30 20 20 20 20 20 ## An alternative, static requirement used instead when pop is over mode's high_pop_limit. -DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITORBRO 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT CHANGELING 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 10 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CULT 10 -DYNAMIC_HIGH_POPULATION_REQUIREMENT NUCLEAR 10 -DYNAMIC_HIGH_POPULATION_REQUIREMENT REVOLUTION 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT CULT 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT NUCLEAR 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT REVOLUTION 15 # All below are impossible-by-default DYNAMIC_HIGH_POPULATION_REQUIREMENT EXTENDED 101 DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOCKWORK_CULT 101 @@ -378,16 +378,16 @@ DYNAMIC_HIGH_POPULATION_REQUIREMENT MONKEY 101 DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR 101 ## Midround antags -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_TRAITOR 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_TRAITOR 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT MALF_AI 35 DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_WIZARD 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT BLOB 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT XENOS 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 50 ## Latejoin antags -DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_REVOLUTION 50 ## AI ### From b9359de02f0573437b8989fe3956dffe68d8d2c7 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 05:01:00 -0800 Subject: [PATCH 025/121] Made the curve make more sense with dichotomic voting. --- code/controllers/subsystem/vote.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index bfa0088cdb..55cd9c3f4f 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -157,8 +157,8 @@ SUBSYSTEM_DEF(vote) return message_admins("Nobody voted in the dynamic vote; using default dynamic settings.") var/mean = (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*5 - var/variance=(((-1-mean)**2)*choices[PEACE]+((1-mean)**2)*choices[CHAOS])/voted.len - GLOB.dynamic_curve_width = CLAMP(variance*4,0.5,4) + var/magic_curve_constant = (4-(abs(choices[PEACE]-choices[CHAOS])/(voted.len)))*10 //magic as hell. + GLOB.dynamic_curve_width = CLAMP(4-magic_curve_constant,0.5,4) message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") From 1c4256f28fd9ce247885b281ea4f1a3a81ee88ec Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 16:28:28 -0800 Subject: [PATCH 026/121] actually fuck this config's its own file now --- .../configuration/entries/dynamic.dm | 41 +++++ .../configuration/entries/game_options.dm | 42 ----- config/config.txt | 1 + config/dynamic_config.txt | 141 +++++++++++++++++ config/game_options.txt | 146 ------------------ 5 files changed, 183 insertions(+), 188 deletions(-) create mode 100644 code/controllers/configuration/entries/dynamic.dm create mode 100644 config/dynamic_config.txt diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm new file mode 100644 index 0000000000..1bc2581103 --- /dev/null +++ b/code/controllers/configuration/entries/dynamic.dm @@ -0,0 +1,41 @@ +/datum/config_entry/flag/dynamic_voting + +/datum/config_entry/number/dynamic_high_pop_limit + config_entry_value = 55 + min_val = 1 + +/datum/config_entry/number/dynamic_pop_per_requirement + config_entry_value = 6 + min_val = 1 + +/datum/config_entry/number/dynamic_midround_delay_min + config_entry_value = 15 + min_val = 1 + +/datum/config_entry/number/dynamic_midround_delay_max + config_entry_value = 35 + min_val = 1 + +/datum/config_entry/number/dynamic_latejoin_delay_min + config_entry_value = 5 + min_val = 1 + +/datum/config_entry/number/dynamic_latejoin_delay_max + config_entry_value = 25 + min_val = 1 + +/datum/config_entry/keyed_list/dynamic_cost + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM + +/datum/config_entry/keyed_list/dynamic_weight + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM + +/datum/config_entry/keyed_list/dynamic_requirements + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM_LIST + +/datum/config_entry/keyed_list/dynamic_high_population_requirement + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 0ba52c23f1..80c179d639 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -371,45 +371,3 @@ /datum/config_entry/number/auto_transfer_delay config_entry_value = 72000 min_val = 0 - -/datum/config_entry/flag/dynamic_voting - -/datum/config_entry/number/dynamic_high_pop_limit - config_entry_value = 55 - min_val = 1 - -/datum/config_entry/number/dynamic_pop_per_requirement - config_entry_value = 6 - min_val = 1 - -/datum/config_entry/number/dynamic_midround_delay_min - config_entry_value = 15 - min_val = 1 - -/datum/config_entry/number/dynamic_midround_delay_max - config_entry_value = 35 - min_val = 1 - -/datum/config_entry/number/dynamic_latejoin_delay_min - config_entry_value = 5 - min_val = 1 - -/datum/config_entry/number/dynamic_latejoin_delay_max - config_entry_value = 25 - min_val = 1 - -/datum/config_entry/keyed_list/dynamic_cost - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_NUM - -/datum/config_entry/keyed_list/dynamic_weight - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_NUM - -/datum/config_entry/keyed_list/dynamic_requirements - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_NUM_LIST - -/datum/config_entry/keyed_list/dynamic_high_population_requirement - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_NUM diff --git a/config/config.txt b/config/config.txt index 0501d1fd2f..e71c2587b7 100644 --- a/config/config.txt +++ b/config/config.txt @@ -5,6 +5,7 @@ $include dbconfig.txt $include comms.txt $include antag_rep.txt $include donator_groupings.txt +$include dynamic_config.txt # You can use the @ character at the beginning of a config option to lock it from being edited in-game # Example usage: diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt new file mode 100644 index 0000000000..f364b80bfd --- /dev/null +++ b/config/dynamic_config.txt @@ -0,0 +1,141 @@ +## Injection delays: how long (in minutes) will pass before a midround or latejoin antag is injected. +DYNAMIC_MIDROUND_DELAY_MIN 15 +DYNAMIC_MIDROUND_DELAY_MAX 35 +DYNAMIC_LATEJOIN_DELAY_MIN 5 +DYNAMIC_LATEJOIN_DELAY_MAX 25 + +## How many roundstart players required for high population override to take effect. +DYNAMIC_HIGH_POP_LIMIT 80 #80 instead of 55 because fewer robust players + +## Pop range per requirement. +## If the value is five the range is: +## 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-54, 45+ +## If it is six the range is: +## 0-5, 6-11, 12-17, 18-23, 24-29, 30-35, 36-41, 42-47, 48-53, 54+ +## If it is seven the range is: +## 0-6, 7-13, 14-20, 21-27, 28-34, 35-41, 42-48, 49-55, 56-62, 63+ +## Options outside this range can be used, of course. +DYNAMIC_POP_PER_REQUIREMENT 9 # 9 instead of 6 because 1/3 of players are probably not doing much? + +## 1 -> 9, probability for this rule to be picked against other rules. +## Note that requirements must also be met, and some requirements are impossible to meet. +DYNAMIC_WEIGHT TRAITOR 5 +DYNAMIC_WEIGHT MALF_AI 1 +DYNAMIC_WEIGHT TRAITORBRO 4 +DYNAMIC_WEIGHT CHANGELING 1 +DYNAMIC_WEIGHT WIZARD 1 +DYNAMIC_WEIGHT CULT 3 +DYNAMIC_WEIGHT NUCLEAR 3 +DYNAMIC_WEIGHT REVOLUTION 2 +# All below are impossible-by-default +DYNAMIC_WEIGHT EXTENDED 3 +DYNAMIC_WEIGHT CLOCKWORK_CULT 3 +DYNAMIC_WEIGHT CLOWNOPS 3 +DYNAMIC_WEIGHT DEVIL 3 +DYNAMIC_WEIGHT MONKEY 3 +DYNAMIC_WEIGHT METEOR 3 + +## Midround antags +DYNAMIC_WEIGHT MIDROUND_TRAITOR 7 +DYNAMIC_WEIGHT MIDROUND_MALF_AI 3 +DYNAMIC_WEIGHT MIDROUND_WIZARD 1 +DYNAMIC_WEIGHT MIDROUND_NUCLEAR 5 +DYNAMIC_WEIGHT BLOB 4 +DYNAMIC_WEIGHT XENOS 3 +DYNAMIC_WEIGHT NIGHTMARE 3 + +## Latejoin antags +DYNAMIC_WEIGHT LATEJOIN_TRAITOR 7 +DYNAMIC_WEIGHT LATEJOIN_REVOLUTION 2 + +## Threat cost. This is decreased from the mode's threat when the rule is executed. +DYNAMIC_COST TRAITOR 10 +DYNAMIC_COST MALF_AI 35 +DYNAMIC_COST TRAITORBRO 10 +DYNAMIC_COST CHANGELING 30 +DYNAMIC_COST WIZARD 30 +DYNAMIC_COST CULT 35 +DYNAMIC_COST NUCLEAR 45 +DYNAMIC_COST REVOLUTION 40 +# All below are impossible-by-default +DYNAMIC_COST EXTENDED 0 +DYNAMIC_COST CLOCKWORK_CULT 0 +DYNAMIC_COST CLOWNOPS 40 +DYNAMIC_COST DEVIL 0 +DYNAMIC_COST MONKEY 0 +DYNAMIC_COST METEOR 0 + +## Midround antags +DYNAMIC_COST MIDROUND_TRAITOR 10 +DYNAMIC_COST MIDROUND_MALF_AI 35 +DYNAMIC_COST MIDROUND_WIZARD 20 +DYNAMIC_COST MIDROUND_NUCLEAR 35 +DYNAMIC_COST BLOB 10 +DYNAMIC_COST XENOS 10 +DYNAMIC_COST NIGHTMARE 10 + +## Latejoin antags +DYNAMIC_COST LATEJOIN_TRAITOR 5 +DYNAMIC_COST LATEJOIN_REVOLUTION 20 + +## Rule will not be generated with threat levels below requirement at a pop value. Pop values are determined by dynamic's pop-per-requirement. +## By default it's 0-8, 9-17, 18-26, 27-35, 36-44, 45-53, 54-60, 61-69, 70-78, 79+. +## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-8, 30 at 9-17 etc. +DYNAMIC_REQUIREMENTS TRAITOR 40 30 20 15 15 15 15 15 15 15 +DYNAMIC_REQUIREMENTS TRAITORBRO 50 40 30 20 20 15 15 15 15 15 +DYNAMIC_REQUIREMENTS MALF_AI 101 101 80 70 60 60 50 50 40 40 +DYNAMIC_REQUIREMENTS CHANGELING 101 101 101 101 101 101 101 101 101 101 +DYNAMIC_REQUIREMENTS WIZARD 100 90 70 40 30 20 15 15 15 15 +DYNAMIC_REQUIREMENTS CULT 100 90 80 60 40 30 15 15 15 15 +DYNAMIC_REQUIREMENTS NUCLEAR 100 90 90 80 60 40 30 20 15 15 +DYNAMIC_REQUIREMENTS REVOLUTION 101 101 70 40 30 20 15 15 15 15 +# All below are impossible-by-default +DYNAMIC_REQUIREMENTS EXTENDED 101 101 101 101 101 101 101 101 101 101 +DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 100 90 80 60 40 30 15 15 15 15 +DYNAMIC_REQUIREMENTS CLOWNOPS 101 101 101 101 101 101 101 101 101 101 +DYNAMIC_REQUIREMENTS DEVIL 101 101 101 101 101 101 101 101 101 101 +DYNAMIC_REQUIREMENTS MONKEY 101 101 101 101 101 101 101 101 101 101 +DYNAMIC_REQUIREMENTS METEOR 101 101 101 101 101 101 101 101 101 101 + +## Midround antags +DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 50 40 30 20 15 15 15 15 15 15 +DYNAMIC_REQUIREMENTS MIDROUND_MALF_AI 101 101 80 70 60 60 50 50 40 40 +DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 70 40 30 20 15 15 15 15 +DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 60 40 30 20 15 15 +DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 30 20 15 15 +DYNAMIC_REQUIREMENTS XENOS 101 101 101 70 50 40 20 15 15 15 +DYNAMIC_REQUIREMENTS NIGHTMARE 101 101 101 70 50 40 20 15 15 15 + +## Latejoin antags +DYNAMIC_REQUIREMENTS LATEJOIN_TRAITOR 40 30 20 15 15 15 15 15 15 15 +DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 30 20 20 20 20 20 + +## An alternative, static requirement used instead when pop is over mode's high_pop_limit. +DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MALF_AI 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITORBRO 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT CHANGELING 101 +DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT CULT 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT NUCLEAR 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT REVOLUTION 15 +# All below are impossible-by-default +DYNAMIC_HIGH_POPULATION_REQUIREMENT EXTENDED 101 +DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOCKWORK_CULT 101 +DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOWNOPS 101 +DYNAMIC_HIGH_POPULATION_REQUIREMENT DEVIL 101 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MONKEY 101 +DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR 101 + +## Midround antags +DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_TRAITOR 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_MALF_AI 35 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_WIZARD 50 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT BLOB 50 +DYNAMIC_HIGH_POPULATION_REQUIREMENT XENOS 50 +DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 50 + +## Latejoin antags +DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_REVOLUTION 50 diff --git a/config/game_options.txt b/config/game_options.txt index 8fe5ae4382..38242aa2ea 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -254,152 +254,6 @@ EVENTS_MIN_TIME_MUL 1 ## Set to 0 to make dangerous events avaliable for all populations. EVENTS_MIN_PLAYERS_MUL 1 - - -### DYNAMIC MODE ### - -## Injection delays: how long (in minutes) will pass before a midround or latejoin antag is injected. -DYNAMIC_MIDROUND_DELAY_MIN 15 -DYNAMIC_MIDROUND_DELAY_MAX 35 -DYNAMIC_LATEJOIN_DELAY_MIN 5 -DYNAMIC_LATEJOIN_DELAY_MAX 25 - -## How many roundstart players required for high population override to take effect. -DYNAMIC_HIGH_POP_LIMIT 80 #80 instead of 55 because fewer robust players - -## Pop range per requirement. -## If the value is five the range is: -## 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-54, 45+ -## If it is six the range is: -## 0-5, 6-11, 12-17, 18-23, 24-29, 30-35, 36-41, 42-47, 48-53, 54+ -## If it is seven the range is: -## 0-6, 7-13, 14-20, 21-27, 28-34, 35-41, 42-48, 49-55, 56-62, 63+ -## Options outside this range can be used, of course. -DYNAMIC_POP_PER_REQUIREMENT 9 # 9 instead of 6 because 1/3 of players are probably not doing much? - -## 1 -> 9, probability for this rule to be picked against other rules. -## Note that requirements must also be met, and some requirements are impossible to meet. -DYNAMIC_WEIGHT TRAITOR 5 -DYNAMIC_WEIGHT MALF_AI 1 -DYNAMIC_WEIGHT TRAITORBRO 4 -DYNAMIC_WEIGHT CHANGELING 1 -DYNAMIC_WEIGHT WIZARD 1 -DYNAMIC_WEIGHT CULT 3 -DYNAMIC_WEIGHT NUCLEAR 3 -DYNAMIC_WEIGHT REVOLUTION 2 -# All below are impossible-by-default -DYNAMIC_WEIGHT EXTENDED 3 -DYNAMIC_WEIGHT CLOCKWORK_CULT 3 -DYNAMIC_WEIGHT CLOWNOPS 3 -DYNAMIC_WEIGHT DEVIL 3 -DYNAMIC_WEIGHT MONKEY 3 -DYNAMIC_WEIGHT METEOR 3 - -## Midround antags -DYNAMIC_WEIGHT MIDROUND_TRAITOR 7 -DYNAMIC_WEIGHT MIDROUND_MALF_AI 3 -DYNAMIC_WEIGHT MIDROUND_WIZARD 1 -DYNAMIC_WEIGHT MIDROUND_NUCLEAR 5 -DYNAMIC_WEIGHT BLOB 4 -DYNAMIC_WEIGHT XENOS 3 -DYNAMIC_WEIGHT NIGHTMARE 3 - -## Latejoin antags -DYNAMIC_WEIGHT LATEJOIN_TRAITOR 7 -DYNAMIC_WEIGHT LATEJOIN_REVOLUTION 2 - -## Threat cost. This is decreased from the mode's threat when the rule is executed. -DYNAMIC_COST TRAITOR 10 -DYNAMIC_COST MALF_AI 35 -DYNAMIC_COST TRAITORBRO 10 -DYNAMIC_COST CHANGELING 30 -DYNAMIC_COST WIZARD 30 -DYNAMIC_COST CULT 35 -DYNAMIC_COST NUCLEAR 45 -DYNAMIC_COST REVOLUTION 40 -# All below are impossible-by-default -DYNAMIC_COST EXTENDED 0 -DYNAMIC_COST CLOCKWORK_CULT 0 -DYNAMIC_COST CLOWNOPS 40 -DYNAMIC_COST DEVIL 0 -DYNAMIC_COST MONKEY 0 -DYNAMIC_COST METEOR 0 - -## Midround antags -DYNAMIC_COST MIDROUND_TRAITOR 10 -DYNAMIC_COST MIDROUND_MALF_AI 35 -DYNAMIC_COST MIDROUND_WIZARD 20 -DYNAMIC_COST MIDROUND_NUCLEAR 35 -DYNAMIC_COST BLOB 10 -DYNAMIC_COST XENOS 10 -DYNAMIC_COST NIGHTMARE 10 - -## Latejoin antags -DYNAMIC_COST LATEJOIN_TRAITOR 5 -DYNAMIC_COST LATEJOIN_REVOLUTION 20 - -## Rule will not be generated with threat levels below requirement at a pop value. Pop values are determined by dynamic's pop-per-requirement. -## By default it's 0-8, 9-17, 18-26, 27-35, 36-44, 45-53, 54-60, 61-69, 70-78, 79+. -## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-8, 30 at 9-17 etc. -DYNAMIC_REQUIREMENTS TRAITOR 40 30 20 15 15 15 15 15 15 15 -DYNAMIC_REQUIREMENTS TRAITORBRO 50 40 30 20 20 15 15 15 15 15 -DYNAMIC_REQUIREMENTS MALF_AI 101 101 80 70 60 60 50 50 40 40 -DYNAMIC_REQUIREMENTS CHANGELING 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS WIZARD 100 90 70 40 30 20 15 15 15 15 -DYNAMIC_REQUIREMENTS CULT 100 90 80 60 40 30 15 15 15 15 -DYNAMIC_REQUIREMENTS NUCLEAR 100 90 90 80 60 40 30 20 15 15 -DYNAMIC_REQUIREMENTS REVOLUTION 101 101 70 40 30 20 15 15 15 15 -# All below are impossible-by-default -DYNAMIC_REQUIREMENTS EXTENDED 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 100 90 80 60 40 30 15 15 15 15 -DYNAMIC_REQUIREMENTS CLOWNOPS 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS DEVIL 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS MONKEY 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS METEOR 101 101 101 101 101 101 101 101 101 101 - -## Midround antags -DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 50 40 30 20 15 15 15 15 15 15 -DYNAMIC_REQUIREMENTS MIDROUND_MALF_AI 101 101 80 70 60 60 50 50 40 40 -DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 70 40 30 20 15 15 15 15 -DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 60 40 30 20 15 15 -DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 30 20 15 15 -DYNAMIC_REQUIREMENTS XENOS 101 101 101 70 50 40 20 15 15 15 -DYNAMIC_REQUIREMENTS NIGHTMARE 101 101 101 70 50 40 20 15 15 15 - -## Latejoin antags -DYNAMIC_REQUIREMENTS LATEJOIN_TRAITOR 40 30 20 15 15 15 15 15 15 15 -DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 30 20 20 20 20 20 - -## An alternative, static requirement used instead when pop is over mode's high_pop_limit. -DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MALF_AI 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITORBRO 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CHANGELING 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CULT 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT NUCLEAR 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT REVOLUTION 15 -# All below are impossible-by-default -DYNAMIC_HIGH_POPULATION_REQUIREMENT EXTENDED 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOCKWORK_CULT 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOWNOPS 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT DEVIL 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MONKEY 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR 101 - -## Midround antags -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_TRAITOR 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_MALF_AI 35 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_WIZARD 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT BLOB 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT XENOS 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 50 - -## Latejoin antags -DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_REVOLUTION 50 - ## AI ### ## Allow the AI job to be picked. From a83901a8b0eaec88b544aa58f94eab664a9c1580 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 16:30:07 -0800 Subject: [PATCH 027/121] and finished the wizard change merge --- .../configuration/entries/dynamic.dm | 25 +++++++++++++++++++ config/dynamic_config.txt | 16 ++++++++++++ 2 files changed, 41 insertions(+) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 1bc2581103..2791941dd3 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -39,3 +39,28 @@ /datum/config_entry/keyed_list/dynamic_high_population_requirement key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_NUM + + +/datum/config_entry/number/dynamic_summon_guns_requirement + config_entry_value = 10 + min_val = 0 + +/datum/config_entry/number/dynamic_summon_guns_cost + config_entry_value = 5 + min_val = 0 + +/datum/config_entry/number/dynamic_summon_magic_requirement + config_entry_value = 10 + min_val = 0 + +/datum/config_entry/number/dynamic_summon_magic_cost + config_entry_value = 5 + min_val = 0 + +/datum/config_entry/number/dynamic_summon_events_requirement + config_entry_value = 20 + min_val = 0 + +/datum/config_entry/number/dynamic_summon_events_cost + config_entry_value = 10 + min_val = 0 diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index f364b80bfd..90c2233c54 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -139,3 +139,19 @@ DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 50 ## Latejoin antags DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_REVOLUTION 50 + +## Dynamic wizard stuff + +## How much threat level is required to buy summon guns. Setting to 0 makes it always available. +DYNAMIC_SUMMON_GUNS_REQUIREMENT 10 + +## How much summon guns reduces the round's remaining threat. Setting to 0 makes it cost none. +DYNAMIC_SUMMON_GUNS_COST 5 + +## As above, but for summon magic +DYNAMIC_SUMMON_MAGIC_REQUIREMENT 10 +DYNAMIC_SUMMON_MAGIC_COST 5 + +## As above, but for summon events +DYNAMIC_SUMMON_EVENTS_REQUIREMENT 20 +DYNAMIC_SUMMON_EVENTS_COST 10 From e03fc2fe5eb7ce3b4920e9efac122b9136e25ff0 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 17:14:48 -0800 Subject: [PATCH 028/121] removed blood brothers from dynamic --- config/dynamic_config.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 90c2233c54..55e1c8cc44 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -82,7 +82,7 @@ DYNAMIC_COST LATEJOIN_REVOLUTION 20 ## By default it's 0-8, 9-17, 18-26, 27-35, 36-44, 45-53, 54-60, 61-69, 70-78, 79+. ## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-8, 30 at 9-17 etc. DYNAMIC_REQUIREMENTS TRAITOR 40 30 20 15 15 15 15 15 15 15 -DYNAMIC_REQUIREMENTS TRAITORBRO 50 40 30 20 20 15 15 15 15 15 +DYNAMIC_REQUIREMENTS TRAITORBRO 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS MALF_AI 101 101 80 70 60 60 50 50 40 40 DYNAMIC_REQUIREMENTS CHANGELING 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS WIZARD 100 90 70 40 30 20 15 15 15 15 @@ -140,6 +140,15 @@ DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_REVOLUTION 50 +## Dynamic traitor stuff + +## Requirements for "hijack the shuttle" goals. +DYNAMIC_HIJACK_REQUIREMENTS 101 101 101 95 80 70 60 50 40 30 + +DYNAMIC_HIJACK_HIGH_POPULATION_REQUIREMENT 25 + +DYNAMIC_HIJACK_COST 10 + ## Dynamic wizard stuff ## How much threat level is required to buy summon guns. Setting to 0 makes it always available. From b4741adb22001a4484eb5afe5ab5606e1cee822a Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 17:20:28 -0800 Subject: [PATCH 029/121] FULLY removed BB from dynamic --- config/dynamic_config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 55e1c8cc44..f034037f26 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -113,7 +113,7 @@ DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 30 20 20 20 20 20 ## An alternative, static requirement used instead when pop is over mode's high_pop_limit. DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT MALF_AI 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITORBRO 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITORBRO 101 DYNAMIC_HIGH_POPULATION_REQUIREMENT CHANGELING 101 DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT CULT 15 From 33f76630084feed9d4c3061d3d838fb5d836d299 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 17:20:56 -0800 Subject: [PATCH 030/121] this is probably required for compile --- code/controllers/configuration/entries/dynamic.dm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 2791941dd3..2d3f8f7be4 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -40,7 +40,14 @@ key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_NUM +/datum/config_entry/number_list/dynamic_hijack_requirements +/datum/config_entry/number/dynamic_hijack_high_population_requirement + config_entry_value = 25 + +/datum/config_entry/number/dynamic_hijack_cost + config_entry_value = 5 + /datum/config_entry/number/dynamic_summon_guns_requirement config_entry_value = 10 min_val = 0 From 6f1a7de4546cd9fe2c3aaa3721283549d0a380ae Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 17:30:54 -0800 Subject: [PATCH 031/121] this too, wowee --- tgstation.dme | 1 + 1 file changed, 1 insertion(+) diff --git a/tgstation.dme b/tgstation.dme index 0ab92d863d..4fd1b6c4f3 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -223,6 +223,7 @@ #include "code\controllers\configuration\entries\comms.dm" #include "code\controllers\configuration\entries\dbconfig.dm" #include "code\controllers\configuration\entries\donator.dm" +#include "code\controllers\configuration\entries\dynamic.dm" #include "code\controllers\configuration\entries\game_options.dm" #include "code\controllers\configuration\entries\general.dm" #include "code\controllers\subsystem\acid.dm" From 3bdbb04ea2895d58794f73f806f3e271092876b9 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 17:31:39 -0800 Subject: [PATCH 032/121] Made hijack require threat threshold, spend threat --- code/modules/antagonists/traitor/datum_traitor.dm | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index e43c2f6254..ef37e9f9c3 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -72,7 +72,17 @@ /datum/antagonist/traitor/proc/forge_human_objectives() var/is_hijacker = FALSE - if (GLOB.joined_player_list.len >= 30) // Less murderboning on lowpop thanks + var/datum/game_mode/dynamic/mode + var/is_dynamic = FALSE + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + mode = SSticker.mode + is_dynamic = TRUE + if(GLOB.joined_player_list>=GLOB.dynamic_high_pop_limit) + is_hijacker = prob(10) && mode.threat_level > CONFIG_GET(number/dynamic_hijack_high_population_requirement) + else + var/indice_pop = min(10,round(GLOB.joined_player_list/mode.pop_per_requirement)+1) + is_hijacker = prob(10) && (mode.threat_level >= CONFIG_GET(number_list/dynamic_hijack_requirements)[indice_pop]) + else if (GLOB.joined_player_list.len >= 30) // Less murderboning on lowpop thanks is_hijacker = prob(10) var/martyr_chance = prob(20) var/objective_count = is_hijacker //Hijacking counts towards number of objectives @@ -93,6 +103,8 @@ var/datum/objective/hijack/hijack_objective = new hijack_objective.owner = owner add_objective(hijack_objective) + if(is_dynamic) + mode.spend_threat(CONFIG_GET(number/dynamic_hijack_cost)) return From 44ad4662ebc3c4623525209b4b29e2ff67d8954e Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 18:07:26 -0800 Subject: [PATCH 033/121] fewer double roundstart antags --- code/controllers/configuration/entries/dynamic.dm | 10 ++++++++++ code/game/gamemodes/dynamic/dynamic.dm | 4 ++++ config/dynamic_config.txt | 8 ++++++++ 3 files changed, 22 insertions(+) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 2d3f8f7be4..08384d2d94 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -40,6 +40,16 @@ key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_NUM +/datum/config_entry/number_list/dynamic_second_rule_requirements + +/datum/config_entry/number_list/dynamic_third_rule_requirements + +/datum/config_entry/number/dynamic_second_rule_high_pop_requirement + config_entry_value = 50 + +/datum/config_entry/number/dynamic_third_rule_high_pop_requirement + config_entry_value = 70 + /datum/config_entry/number_list/dynamic_hijack_requirements /datum/config_entry/number/dynamic_hijack_high_population_requirement diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index ca009f76ad..cf7830c0e6 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -110,6 +110,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) /datum/game_mode/dynamic/New() // i have NO IDEA if this is the proper way to do this. ..() pop_per_requirement = CONFIG_GET(number/dynamic_pop_per_requirement) + second_rule_req = CONFIG_GET(number_list/dynamic_second_rule_requirements) + third_rule_req = CONFIG_GET(number_list/dynamic_third_rule_requirements) + high_pop_second_rule_req = CONFIG_GET(number/dynamic_second_rule_high_pop_requirement) + high_pop_third_rule_req = CONFIG_GET(number/dynamic_third_rule_high_pop_requirement) GLOB.dynamic_high_pop_limit = CONFIG_GET(number/dynamic_high_pop_limit) GLOB.dynamic_latejoin_delay_min = CONFIG_GET(number/dynamic_latejoin_delay_min)*600 GLOB.dynamic_latejoin_delay_max = CONFIG_GET(number/dynamic_latejoin_delay_max)*600 diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index f034037f26..aa966af30b 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -7,6 +7,14 @@ DYNAMIC_LATEJOIN_DELAY_MAX 25 ## How many roundstart players required for high population override to take effect. DYNAMIC_HIGH_POP_LIMIT 80 #80 instead of 55 because fewer robust players +## Threat requirements for a second roundstart ruleset being drafted +DYNAMIC_SECOND_RULE_REQUIREMENTS 101 101 101 101 100 90 80 70 60 50 +## Threat requirements for a *third* roundstart ruleset being drafted +DYNAMIC_THIRD_RULE_REQUIREMENTS 101 101 101 101 101 100 90 80 70 60 +## As above, but if there's 79+ players +DYNAMIC_SECOND_RULE_HIGH_POP_REQUIREMENT 50 +DYNAMIC_THIRD_RULE_HIGH_POP_REQUIREMENT 60 + ## Pop range per requirement. ## If the value is five the range is: ## 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-54, 45+ From eb9c8c9aca8e7c3e65b5d786bdba337546a59806 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 18:07:39 -0800 Subject: [PATCH 034/121] made glorious death spend threat --- code/controllers/configuration/entries/dynamic.dm | 3 +++ code/modules/antagonists/traitor/datum_traitor.dm | 2 ++ config/dynamic_config.txt | 2 ++ 3 files changed, 7 insertions(+) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 08384d2d94..0fa7bc81d8 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -58,6 +58,9 @@ /datum/config_entry/number/dynamic_hijack_cost config_entry_value = 5 +/datum/config_entry/number/dynamic_glorious_death_cost + config_entry_value = 5 + /datum/config_entry/number/dynamic_summon_guns_requirement config_entry_value = 10 min_val = 0 diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index ef37e9f9c3..019ed249ec 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -118,6 +118,8 @@ var/datum/objective/martyr/martyr_objective = new martyr_objective.owner = owner add_objective(martyr_objective) + if(is_dynamic) + mode.spend_threat(CONFIG_GET(number/dynamic_glorious_death_cost)) return else diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index aa966af30b..10f3044627 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -157,6 +157,8 @@ DYNAMIC_HIJACK_HIGH_POPULATION_REQUIREMENT 25 DYNAMIC_HIJACK_COST 10 +DYNAMIC_GLORIOUS_DEATH_COST 5 + ## Dynamic wizard stuff ## How much threat level is required to buy summon guns. Setting to 0 makes it always available. From 58603140f9b28a33ec16b234175f71cccfc2ff7f Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 22:03:18 -0800 Subject: [PATCH 035/121] wow, .len, very cool --- code/modules/antagonists/traitor/datum_traitor.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 019ed249ec..4b5cb94ad9 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -77,11 +77,11 @@ if(istype(SSticker.mode,/datum/game_mode/dynamic)) mode = SSticker.mode is_dynamic = TRUE - if(GLOB.joined_player_list>=GLOB.dynamic_high_pop_limit) - is_hijacker = prob(10) && mode.threat_level > CONFIG_GET(number/dynamic_hijack_high_population_requirement) + if(GLOB.joined_player_list.len>=GLOB.dynamic_high_pop_limit) + is_hijacker = (prob(10) && mode.threat_level > CONFIG_GET(number/dynamic_hijack_high_population_requirement)) else - var/indice_pop = min(10,round(GLOB.joined_player_list/mode.pop_per_requirement)+1) - is_hijacker = prob(10) && (mode.threat_level >= CONFIG_GET(number_list/dynamic_hijack_requirements)[indice_pop]) + var/indice_pop = min(10,round(GLOB.joined_player_list.len/mode.pop_per_requirement)+1) + is_hijacker = (prob(10) && (mode.threat_level >= CONFIG_GET(number_list/dynamic_hijack_requirements)[indice_pop])) else if (GLOB.joined_player_list.len >= 30) // Less murderboning on lowpop thanks is_hijacker = prob(10) var/martyr_chance = prob(20) From 5298e5863e3005467d6b33e7d356c0faec8609f8 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 22:09:07 -0800 Subject: [PATCH 036/121] no more supercults/supernukies in dynamic --- code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 463c372f0c..b69133a710 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -264,7 +264,6 @@ cost = 30 requirements = list(100,90,80,60,40,30,10,10,10,10) high_population_requirement = 10 - pop_per_requirement = 5 flags = HIGHLANDER_RULESET var/cultist_cap = list(2,2,2,3,3,4,4,4,4,4) var/datum/team/cult/main_cult @@ -325,7 +324,6 @@ cost = 40 requirements = list(90,90,90,80,60,40,30,20,10,10) high_population_requirement = 10 - pop_per_requirement = 5 flags = HIGHLANDER_RULESET var/operative_cap = list(2,2,2,3,3,3,4,4,5,5) var/datum/team/nuclear/nuke_team From 85fd53d61595a0bc5ce0dce467b89278b8678341 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 22:19:57 -0800 Subject: [PATCH 037/121] actually let's add the extended voting back in, see how that does --- code/controllers/subsystem/vote.dm | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 5644a9f2cb..4f65d37c4a 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -155,10 +155,15 @@ SUBSYSTEM_DEF(vote) GLOB.master_mode = "dynamic" if(voted.len==0) return message_admins("Nobody voted in the dynamic vote; using default dynamic settings.") - var/mean = (choices[PEACE]*-1+choices[CHAOS])/voted.len + GLOB.dynamic_forced_extended = choices["extended"]/voted.len > 0.5 + if(GLOB.dynamic_forced_extended) + to_chat(world,"Dynamic extended has been voted for.") + return message_admins("Dynamic extended has been voted for.") + var/mean = (choices["extended"]*-1+choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*5 - var/magic_curve_constant = (4-(abs(choices[PEACE]-choices[CHAOS])/(voted.len)))*10 //magic as hell. + var/magic_curve_constant = (4-(abs((choices[PEACE]+choices["extended"])-choices[CHAOS])/(voted.len)))*8 //magic as hell. GLOB.dynamic_curve_width = CLAMP(4-magic_curve_constant,0.5,4) + to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") @@ -239,7 +244,7 @@ SUBSYSTEM_DEF(vote) if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote choices.Add("secret", "extended") if("dynamic") - choices.Add(PEACE,CHAOS) + choices.Add("extended",PEACE,CHAOS) if("custom") question = stripped_input(usr,"What is the vote for?") if(!question) @@ -398,8 +403,5 @@ SUBSYSTEM_DEF(vote) if(P) P.player_actions -= src -#undef PEACE2 -#undef PEACE1 -#undef BALANCED -#undef CHAOS1 -#undef CHAOS2 +#undef PEACE +#undef CHAOS From c94c6295ab7041c8c78bd0d304f7d2a93eb4813f Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 22:37:16 -0800 Subject: [PATCH 038/121] let's try making the votes SWING --- code/controllers/subsystem/vote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 4f65d37c4a..73cc6fac3d 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -160,7 +160,7 @@ SUBSYSTEM_DEF(vote) to_chat(world,"Dynamic extended has been voted for.") return message_admins("Dynamic extended has been voted for.") var/mean = (choices["extended"]*-1+choices[PEACE]*-1+choices[CHAOS])/voted.len - GLOB.dynamic_curve_centre = mean*5 + GLOB.dynamic_curve_centre = mean*20 var/magic_curve_constant = (4-(abs((choices[PEACE]+choices["extended"])-choices[CHAOS])/(voted.len)))*8 //magic as hell. GLOB.dynamic_curve_width = CLAMP(4-magic_curve_constant,0.5,4) to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") From 3a48b7238090181a90e93a6affbe25efd9423f32 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 6 Nov 2019 22:39:39 -0800 Subject: [PATCH 039/121] fixed a comment --- config/game_options.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/game_options.txt b/config/game_options.txt index 38242aa2ea..43464a829c 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -558,5 +558,5 @@ MONKEYCAP 64 ## Uncomment to use TG-style combat #DISABLE_STAMBUFFER -#Replaces standard extended/secret dichotomy with extended and 5 levels of chaos using dynamic. +#Replaces standard extended/secret dichotomy with extended and calm/chaotic votes for dynamic. DYNAMIC_VOTING From b25b2cdf290c467b61472c9c09f853ec2f132d7e Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 01:48:03 -0800 Subject: [PATCH 040/121] tweaked the numbers and choices a little. --- code/controllers/subsystem/vote.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 73cc6fac3d..67822395f7 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -124,7 +124,8 @@ SUBSYSTEM_DEF(vote) message_admins(admintext) return . -#define PEACE "calm" +#define EXTENDED "calm" +#define PEACE "balanced" #define CHAOS "chaotic" /datum/controller/subsystem/vote/proc/result() @@ -161,7 +162,7 @@ SUBSYSTEM_DEF(vote) return message_admins("Dynamic extended has been voted for.") var/mean = (choices["extended"]*-1+choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 - var/magic_curve_constant = (4-(abs((choices[PEACE]+choices["extended"])-choices[CHAOS])/(voted.len)))*8 //magic as hell. + var/magic_curve_constant = (4-(abs((choices[PEACE]+choices["extended"])-choices[CHAOS])/(voted.len)))*4 //magic as hell. GLOB.dynamic_curve_width = CLAMP(4-magic_curve_constant,0.5,4) to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") From 2503d0db90153dd83b9a6f52f01c2ce61cdc394a Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 01:48:21 -0800 Subject: [PATCH 041/121] Hacked together a default for second_rule_req and third_rule_req --- code/game/gamemodes/dynamic/dynamic.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index cf7830c0e6..d69798bf9d 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -112,6 +112,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) pop_per_requirement = CONFIG_GET(number/dynamic_pop_per_requirement) second_rule_req = CONFIG_GET(number_list/dynamic_second_rule_requirements) third_rule_req = CONFIG_GET(number_list/dynamic_third_rule_requirements) + if(second_rule_req.len<10) + second_rule_req = list(101, 101, 101, 101, 100, 90, 80, 70, 60, 50) + if(third_rule_req.len<10) + third_rule_req = list(101, 101, 101, 101, 101, 100, 90, 80, 70, 60) high_pop_second_rule_req = CONFIG_GET(number/dynamic_second_rule_high_pop_requirement) high_pop_third_rule_req = CONFIG_GET(number/dynamic_third_rule_high_pop_requirement) GLOB.dynamic_high_pop_limit = CONFIG_GET(number/dynamic_high_pop_limit) From 9a8fb3e0d244da0254b5e66c7b208acb99f91ee3 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 03:50:49 -0800 Subject: [PATCH 042/121] 4-'ing twice --- code/controllers/subsystem/vote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 67822395f7..98735411bd 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -163,7 +163,7 @@ SUBSYSTEM_DEF(vote) var/mean = (choices["extended"]*-1+choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 var/magic_curve_constant = (4-(abs((choices[PEACE]+choices["extended"])-choices[CHAOS])/(voted.len)))*4 //magic as hell. - GLOB.dynamic_curve_width = CLAMP(4-magic_curve_constant,0.5,4) + GLOB.dynamic_curve_width = CLAMP(magic_curve_constant,0.5,4) to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") From 34015969e8b1bfa8a35db44361acd8cded10d798 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 16:35:40 -0800 Subject: [PATCH 043/121] changed misleading message --- code/modules/admin/topic.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index b0b9190556..fad8749808 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1449,9 +1449,7 @@ if(GLOB.master_mode != "dynamic") return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - var/new_centre = input(usr,"Change the centre of the dynamic mode threat curve. A negative value will give a more peaceful round ; a positive value, a round with higher threat. Any number between -5 and +5 is allowed.", "Change curve centre", null) as num - if (new_centre < -5 || new_centre > 5) - return alert(usr, "Only values between -5 and +5 are allowed.", null, null, null, null) + var/new_centre = input(usr,"Change the centre of the dynamic mode threat curve. A negative value will give a more peaceful round ; a positive value, a round with higher threat. Any number is allowed. This is adjusted by dynamic voting.", "Change curve centre", null) as num log_admin("[key_name(usr)] changed the distribution curve center to [new_centre].") message_admins("[key_name(usr)] changed the distribution curve center to [new_centre]", 1) From 1a2d21d897adb2e1ea4ee59d1d340a67985ae50a Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 16:38:23 -0800 Subject: [PATCH 044/121] massive rebalance --- config/dynamic_config.txt | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 10f3044627..7f13a5674e 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -44,13 +44,13 @@ DYNAMIC_WEIGHT MONKEY 3 DYNAMIC_WEIGHT METEOR 3 ## Midround antags -DYNAMIC_WEIGHT MIDROUND_TRAITOR 7 -DYNAMIC_WEIGHT MIDROUND_MALF_AI 3 +DYNAMIC_WEIGHT MIDROUND_TRAITOR 3 +DYNAMIC_WEIGHT MIDROUND_MALF_AI 2 DYNAMIC_WEIGHT MIDROUND_WIZARD 1 -DYNAMIC_WEIGHT MIDROUND_NUCLEAR 5 -DYNAMIC_WEIGHT BLOB 4 -DYNAMIC_WEIGHT XENOS 3 -DYNAMIC_WEIGHT NIGHTMARE 3 +DYNAMIC_WEIGHT MIDROUND_NUCLEAR 1 +DYNAMIC_WEIGHT BLOB 6 +DYNAMIC_WEIGHT XENOS 7 +DYNAMIC_WEIGHT NIGHTMARE 9 ## Latejoin antags DYNAMIC_WEIGHT LATEJOIN_TRAITOR 7 @@ -67,7 +67,7 @@ DYNAMIC_COST NUCLEAR 45 DYNAMIC_COST REVOLUTION 40 # All below are impossible-by-default DYNAMIC_COST EXTENDED 0 -DYNAMIC_COST CLOCKWORK_CULT 0 +DYNAMIC_COST CLOCKWORK_CULT 35 DYNAMIC_COST CLOWNOPS 40 DYNAMIC_COST DEVIL 0 DYNAMIC_COST MONKEY 0 @@ -89,29 +89,29 @@ DYNAMIC_COST LATEJOIN_REVOLUTION 20 ## Rule will not be generated with threat levels below requirement at a pop value. Pop values are determined by dynamic's pop-per-requirement. ## By default it's 0-8, 9-17, 18-26, 27-35, 36-44, 45-53, 54-60, 61-69, 70-78, 79+. ## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-8, 30 at 9-17 etc. -DYNAMIC_REQUIREMENTS TRAITOR 40 30 20 15 15 15 15 15 15 15 +DYNAMIC_REQUIREMENTS TRAITOR 101 101 100 90 80 70 60 50 50 50 DYNAMIC_REQUIREMENTS TRAITORBRO 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS MALF_AI 101 101 80 70 60 60 50 50 40 40 +DYNAMIC_REQUIREMENTS MALF_AI 101 101 101 101 101 100 90 80 70 60 DYNAMIC_REQUIREMENTS CHANGELING 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS WIZARD 100 90 70 40 30 20 15 15 15 15 -DYNAMIC_REQUIREMENTS CULT 100 90 80 60 40 30 15 15 15 15 -DYNAMIC_REQUIREMENTS NUCLEAR 100 90 90 80 60 40 30 20 15 15 -DYNAMIC_REQUIREMENTS REVOLUTION 101 101 70 40 30 20 15 15 15 15 +DYNAMIC_REQUIREMENTS WIZARD 101 101 101 100 90 80 70 60 50 50 +DYNAMIC_REQUIREMENTS CULT 101 101 101 100 90 80 70 60 50 50 +DYNAMIC_REQUIREMENTS NUCLEAR 101 101 101 100 90 80 70 60 50 50 +DYNAMIC_REQUIREMENTS REVOLUTION 101 101 101 101 100 90 80 70 60 50 # All below are impossible-by-default DYNAMIC_REQUIREMENTS EXTENDED 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 100 90 80 60 40 30 15 15 15 15 +DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 101 101 101 100 90 80 70 60 50 50 DYNAMIC_REQUIREMENTS CLOWNOPS 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS DEVIL 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS MONKEY 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS METEOR 101 101 101 101 101 101 101 101 101 101 ## Midround antags -DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 50 40 30 20 15 15 15 15 15 15 -DYNAMIC_REQUIREMENTS MIDROUND_MALF_AI 101 101 80 70 60 60 50 50 40 40 -DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 70 40 30 20 15 15 15 15 -DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 60 40 30 20 15 15 -DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 30 20 15 15 -DYNAMIC_REQUIREMENTS XENOS 101 101 101 70 50 40 20 15 15 15 +DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 30 25 20 15 15 15 15 15 15 15 +DYNAMIC_REQUIREMENTS MIDROUND_MALF_AI 101 101 80 70 60 60 50 50 50 50 +DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 70 50 50 50 50 40 30 30 +DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 60 50 50 50 50 50 +DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 50 50 50 50 +DYNAMIC_REQUIREMENTS XENOS 101 101 101 70 50 50 50 50 50 50 DYNAMIC_REQUIREMENTS NIGHTMARE 101 101 101 70 50 40 20 15 15 15 ## Latejoin antags @@ -119,17 +119,17 @@ DYNAMIC_REQUIREMENTS LATEJOIN_TRAITOR 40 30 20 15 15 15 15 15 15 15 DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 30 20 20 20 20 20 ## An alternative, static requirement used instead when pop is over mode's high_pop_limit. -DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MALF_AI 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 50 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MALF_AI 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITORBRO 101 DYNAMIC_HIGH_POPULATION_REQUIREMENT CHANGELING 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CULT 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT NUCLEAR 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT REVOLUTION 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 50 +DYNAMIC_HIGH_POPULATION_REQUIREMENT CULT 50 +DYNAMIC_HIGH_POPULATION_REQUIREMENT NUCLEAR 50 +DYNAMIC_HIGH_POPULATION_REQUIREMENT REVOLUTION 50 # All below are impossible-by-default DYNAMIC_HIGH_POPULATION_REQUIREMENT EXTENDED 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOCKWORK_CULT 101 +DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOCKWORK_CULT 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOWNOPS 101 DYNAMIC_HIGH_POPULATION_REQUIREMENT DEVIL 101 DYNAMIC_HIGH_POPULATION_REQUIREMENT MONKEY 101 From 1df51d29f1bbab956c2c4351c1642b9424fcba8f Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 16:41:51 -0800 Subject: [PATCH 045/121] make it calm vs chaotic again. --- code/controllers/subsystem/vote.dm | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 98735411bd..455627aae8 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -124,8 +124,7 @@ SUBSYSTEM_DEF(vote) message_admins(admintext) return . -#define EXTENDED "calm" -#define PEACE "balanced" +#define PEACE "calm" #define CHAOS "chaotic" /datum/controller/subsystem/vote/proc/result() @@ -156,13 +155,9 @@ SUBSYSTEM_DEF(vote) GLOB.master_mode = "dynamic" if(voted.len==0) return message_admins("Nobody voted in the dynamic vote; using default dynamic settings.") - GLOB.dynamic_forced_extended = choices["extended"]/voted.len > 0.5 - if(GLOB.dynamic_forced_extended) - to_chat(world,"Dynamic extended has been voted for.") - return message_admins("Dynamic extended has been voted for.") - var/mean = (choices["extended"]*-1+choices[PEACE]*-1+choices[CHAOS])/voted.len + var/mean = (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 - var/magic_curve_constant = (4-(abs((choices[PEACE]+choices["extended"])-choices[CHAOS])/(voted.len)))*4 //magic as hell. + var/magic_curve_constant = (4-(abs((choices[PEACE])-choices[CHAOS])/(voted.len)))*4 //magic as hell. GLOB.dynamic_curve_width = CLAMP(magic_curve_constant,0.5,4) to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") @@ -245,7 +240,7 @@ SUBSYSTEM_DEF(vote) if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote choices.Add("secret", "extended") if("dynamic") - choices.Add("extended",PEACE,CHAOS) + choices.Add(PEACE,CHAOS) if("custom") question = stripped_input(usr,"What is the vote for?") if(!question) From 6064df9cd7d07a0e74202a7ba17c7ae18c02d444 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 20:26:23 -0800 Subject: [PATCH 046/121] more tweaks to requirements --- config/dynamic_config.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 7f13a5674e..3baf81a991 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -107,7 +107,7 @@ DYNAMIC_REQUIREMENTS METEOR 101 101 101 101 101 101 101 101 101 101 ## Midround antags DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 30 25 20 15 15 15 15 15 15 15 -DYNAMIC_REQUIREMENTS MIDROUND_MALF_AI 101 101 80 70 60 60 50 50 50 50 +DYNAMIC_REQUIREMENTS MIDROUND_MALF_AI 101 101 70 50 50 50 40 30 30 30 DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 70 50 50 50 50 40 30 30 DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 60 50 50 50 50 50 DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 50 50 50 50 @@ -139,10 +139,10 @@ DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR 101 DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_TRAITOR 15 DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_MALF_AI 35 DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_WIZARD 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 35 DYNAMIC_HIGH_POPULATION_REQUIREMENT BLOB 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT XENOS 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 50 +DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 15 ## Latejoin antags DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 15 From aab2c4cd3c6ec4f72ce35ed9175b758262ca6dfb Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 20:34:02 -0800 Subject: [PATCH 047/121] Added logging to wizard/traitor extra threat spending. --- code/modules/antagonists/traitor/datum_traitor.dm | 8 ++++++-- .../antagonists/wizard/equipment/spellbook.dm | 12 +++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 4b5cb94ad9..55f9fe483b 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -104,7 +104,9 @@ hijack_objective.owner = owner add_objective(hijack_objective) if(is_dynamic) - mode.spend_threat(CONFIG_GET(number/dynamic_hijack_cost)) + var/threat_spent = CONFIG_GET(number/dynamic_hijack_cost) + mode.spend_threat(threat_spent) + mode.threat_log += "[worldtime2text()]: Traitor spent [threat_spent] on hijack." return @@ -119,7 +121,9 @@ martyr_objective.owner = owner add_objective(martyr_objective) if(is_dynamic) - mode.spend_threat(CONFIG_GET(number/dynamic_glorious_death_cost)) + var/threat_spent = CONFIG_GET(number/dynamic_hijack_cost) + mode.spend_threat(threat_spent) + mode.threat_log += "[worldtime2text()]: Traitor spent [threat_spent] on glorious death." return else diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index ab37997e50..71b92feec6 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -496,7 +496,9 @@ to_chat(user, "You have cast summon guns!") if(istype(SSticker.mode,/datum/game_mode/dynamic)) var/datum/game_mode/dynamic/mode = SSticker.mode - mode.spend_threat(CONFIG_GET(number/dynamic_summon_guns_cost)) + var/threat_spent = CONFIG_GET(number/dynamic_summon_guns_cost) + mode.spend_threat(threat_spent) + mode.threat_log += "[worldtime2text()]: Wizard spent [threat_spent] on summon guns." return 1 /datum/spellbook_entry/summon/magic @@ -520,7 +522,9 @@ to_chat(user, "You have cast summon magic!") if(istype(SSticker.mode,/datum/game_mode/dynamic)) var/datum/game_mode/dynamic/mode = SSticker.mode - mode.spend_threat(CONFIG_GET(number/dynamic_summon_magic_cost)) + var/threat_spent = CONFIG_GET(number/dynamic_summon_magic_cost) + mode.spend_threat(threat_spent) + mode.threat_log += "[worldtime2text()]: Wizard spent [threat_spent] on summon magic." return 1 /datum/spellbook_entry/summon/events @@ -545,7 +549,9 @@ to_chat(user, "You have cast summon events.") if(istype(SSticker.mode,/datum/game_mode/dynamic) && times == 0) var/datum/game_mode/dynamic/mode = SSticker.mode - mode.spend_threat(CONFIG_GET(number/dynamic_summon_events_cost)) + var/threat_spent = CONFIG_GET(number/dynamic_summon_events_cost) + mode.spend_threat(threat_spent) + mode.threat_log += "[worldtime2text()]: Wizard spent [threat_spent] on summon events." return 1 /datum/spellbook_entry/summon/events/GetInfo() From 518eb1419cf6b514f52e7485b3b3ae42256d8db7 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 22:53:47 -0800 Subject: [PATCH 048/121] wrong paren placement wowee --- code/controllers/subsystem/vote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 455627aae8..8f280140a0 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -157,7 +157,7 @@ SUBSYSTEM_DEF(vote) return message_admins("Nobody voted in the dynamic vote; using default dynamic settings.") var/mean = (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 - var/magic_curve_constant = (4-(abs((choices[PEACE])-choices[CHAOS])/(voted.len)))*4 //magic as hell. + var/magic_curve_constant = (4-(abs((choices[PEACE])-choices[CHAOS])/(voted.len)*4)) //magic as hell. GLOB.dynamic_curve_width = CLAMP(magic_curve_constant,0.5,4) to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") From 134820dbf673226a8527cb1d143c426bb3a42729 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 23:20:38 -0800 Subject: [PATCH 049/121] Hardcoded default config values. --- code/game/gamemodes/dynamic/dynamic.dm | 8 ++--- .../dynamic/dynamic_rulesets_latejoin.dm | 4 +-- .../dynamic/dynamic_rulesets_midround.dm | 24 ++++++------- .../dynamic/dynamic_rulesets_roundstart.dm | 36 +++++++++---------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index d69798bf9d..59b6bcd0b7 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -71,13 +71,13 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) * If it is seven the range is: * 0-6, 7-13, 14-20, 21-27, 28-34, 35-41, 42-48, 49-55, 56-62, 63+ */ - var/pop_per_requirement = 6 + var/pop_per_requirement = 9 /// The requirement used for checking if a second rule should be selected. - var/list/second_rule_req = list(100, 100, 80, 70, 60, 50, 30, 20, 10, 0) + var/list/second_rule_req = list(101, 101, 101, 101, 100, 90, 80, 70, 60, 50) /// The requirement used for checking if a third rule should be selected. - var/list/third_rule_req = list(100, 100, 100, 90, 80, 70, 60, 50, 40, 30) + var/list/third_rule_req = list(101, 101, 101, 101, 101, 100, 90, 80, 70, 60) /// Threat requirement for a second ruleset when high pop override is in effect. - var/high_pop_second_rule_req = 40 + var/high_pop_second_rule_req = 50 /// Threat requirement for a third ruleset when high pop override is in effect. var/high_pop_third_rule_req = 60 /// Number of players who were ready on roundstart. diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 838ca3ec62..192cca3a4b 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -60,8 +60,8 @@ required_candidates = 1 weight = 7 cost = 5 - requirements = list(40,30,20,10,10,10,10,10,10,10) - high_population_requirement = 10 + requirements = list(40,30,20,15,15,15,15,15,15,15) + high_population_requirement = 15 repeatable = TRUE flags = TRAITOR_RULESET diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index c13ba9fd80..7ba3388736 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -177,9 +177,9 @@ required_candidates = 1 weight = 7 cost = 10 - requirements = list(50,40,30,20,10,10,10,10,10,10) + requirements = list(30,25,20,15,15,15,15,15,15,15) repeatable = TRUE - high_population_requirement = 10 + high_population_requirement = 15 flags = TRAITOR_RULESET /datum/dynamic_ruleset/midround/autotraitor/acceptable(population = 0, threat = 0) @@ -232,10 +232,10 @@ exclusive_roles = list("AI") required_enemies = list(6,6,6,4,4,4,2,2,2,1) required_candidates = 1 - weight = 3 + weight = 2 cost = 35 - requirements = list(101,101,80,70,60,60,50,50,40,40) - high_population_requirement = 35 + requirements = list(101,101,70,50,50,50,40,30,30,30) + high_population_requirement = 30 required_type = /mob/living/silicon/ai var/ion_announce = 33 var/removeDontImproveChance = 10 @@ -286,8 +286,8 @@ required_candidates = 1 weight = 1 cost = 20 - requirements = list(90,90,70,40,30,20,10,10,10,10) - high_population_requirement = 50 + requirements = list(90,90,70,50,50,50,50,40,30,30) + high_population_requirement = 30 repeatable = TRUE /datum/dynamic_ruleset/midround/from_ghosts/wizard/ready(forced = FALSE) @@ -319,8 +319,8 @@ required_candidates = 5 weight = 5 cost = 35 - requirements = list(90,90,90,80,60,40,30,20,10,10) - high_population_requirement = 10 + requirements = list(90,90,90,80,70,60,50,40,40,40) + high_population_requirement = 40 var/operative_cap = list(2,2,3,3,4,5,5,5,5,5) var/datum/team/nuclear/nuke_team flags = HIGHLANDER_RULESET @@ -363,7 +363,7 @@ required_candidates = 1 weight = 4 cost = 10 - requirements = list(101,101,101,80,60,50,30,20,10,10) + requirements = list(101,101,101,80,60,50,50,50,50,50) high_population_requirement = 50 repeatable = TRUE @@ -387,7 +387,7 @@ required_candidates = 1 weight = 3 cost = 10 - requirements = list(101,101,101,70,50,40,20,15,10,10) + requirements = list(101,101,101,70,50,50,50,50,50,50) high_population_requirement = 50 repeatable = TRUE var/list/vents = list() @@ -435,7 +435,7 @@ required_candidates = 1 weight = 3 cost = 10 - requirements = list(101,101,101,70,50,40,20,15,10,10) + requirements = list(101,101,101,70,50,40,20,15,15,15) high_population_requirement = 50 repeatable = TRUE var/list/spawn_locs = list() diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index b69133a710..e95f809fb8 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -17,8 +17,8 @@ required_candidates = 1 weight = 5 cost = 10 - requirements = list(10,10,10,10,10,10,10,10,10,10) - high_population_requirement = 10 + requirements = list(101,101,100,90,80,70,60,50,50,50) + high_population_requirement = 50 var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) /datum/dynamic_ruleset/roundstart/traitor/pre_execute() @@ -58,8 +58,8 @@ required_candidates = 1 weight = 1 cost = 35 - requirements = list(101,101,80,70,60,60,50,50,40,40) - high_population_requirement = 35 + requirements = list(101,101,101,101,101,100,90,80,70,60) + high_population_requirement = 50 required_type = /mob/living/silicon/ai var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) @@ -112,8 +112,8 @@ required_candidates = 2 weight = 4 cost = 10 - requirements = list(40,30,30,20,20,15,15,15,10,10) - high_population_requirement = 15 + requirements = list(101,101,101,101,101,101,101,101,101,101) + high_population_requirement = 101 var/list/datum/team/brother_team/pre_brother_teams = list() var/const/team_amount = 2 // Hard limit on brother teams if scaling is turned off var/const/min_team_size = 2 @@ -165,7 +165,7 @@ required_candidates = 1 weight = 3 cost = 30 - requirements = list(80,70,60,50,40,20,20,10,10,10) + requirements = list(101,101,101,101,101,101,101,101,101,101) high_population_requirement = 10 var/team_mode_probability = 30 @@ -215,8 +215,8 @@ required_candidates = 1 weight = 1 cost = 30 - requirements = list(90,90,70,40,30,20,10,10,10,10) - high_population_requirement = 10 + requirements = list(101,101,101,100,90,80,70,60,50,50) + high_population_requirement = 50 var/list/roundstart_wizards = list() /datum/dynamic_ruleset/roundstart/wizard/acceptable(population=0, threat=0) @@ -262,8 +262,8 @@ required_candidates = 2 weight = 3 cost = 30 - requirements = list(100,90,80,60,40,30,10,10,10,10) - high_population_requirement = 10 + requirements = list(101,101,101,100,90,80,70,60,50,50) + high_population_requirement = 50 flags = HIGHLANDER_RULESET var/cultist_cap = list(2,2,2,3,3,4,4,4,4,4) var/datum/team/cult/main_cult @@ -322,8 +322,8 @@ required_candidates = 5 weight = 3 cost = 40 - requirements = list(90,90,90,80,60,40,30,20,10,10) - high_population_requirement = 10 + requirements = list(101,101,101,100,90,80,70,60,50,50) + high_population_requirement = 50 flags = HIGHLANDER_RULESET var/operative_cap = list(2,2,2,3,3,3,4,4,5,5) var/datum/team/nuclear/nuke_team @@ -412,8 +412,8 @@ required_candidates = 3 weight = 2 cost = 35 - requirements = list(101,101,70,40,30,20,10,10,10,10) - high_population_requirement = 10 + requirements = list(101,101,101,100,90,80,70,60,50,50) + high_population_requirement = 50 delay = 5 MINUTES flags = HIGHLANDER_RULESET // I give up, just there should be enough heads with 35 players... @@ -523,9 +523,9 @@ restricted_roles = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") required_candidates = 4 weight = 3 - cost = 0 - requirements = list(101,101,101,101,101,101,101,101,101,101) - high_population_requirement = 101 + cost = 35 + requirements = list(101,101,101,100,90,80,70,60,50,50) + high_population_requirement = 50 flags = HIGHLANDER_RULESET var/ark_time From 8e00f633b849118f15d3300774aa95c3266a6c94 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 23:38:51 -0800 Subject: [PATCH 050/121] Made curve width formula be less stupid, less admin spam --- code/controllers/subsystem/vote.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 8f280140a0..605782535b 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -157,10 +157,8 @@ SUBSYSTEM_DEF(vote) return message_admins("Nobody voted in the dynamic vote; using default dynamic settings.") var/mean = (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 - var/magic_curve_constant = (4-(abs((choices[PEACE])-choices[CHAOS])/(voted.len)*4)) //magic as hell. - GLOB.dynamic_curve_width = CLAMP(magic_curve_constant,0.5,4) + GLOB.dynamic_curve_width = CLAMP(4-abs(mean*3.5),0.5,4) to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") - message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") var/datum/map_config/VM = config.maplist[.] From d795df1150be2cba6533c29dc05de266dbec11a1 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 7 Nov 2019 23:39:17 -0800 Subject: [PATCH 051/121] made warops part of the dynamic system, in dynamic --- code/controllers/configuration/entries/dynamic.dm | 8 ++++++++ .../nukeop/equipment/nuclear_challenge.dm | 13 +++++++++++++ config/dynamic_config.txt | 7 ++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 0fa7bc81d8..0ca48258d8 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -84,3 +84,11 @@ /datum/config_entry/number/dynamic_summon_events_cost config_entry_value = 10 min_val = 0 + +/datum/config_entry/number/dynamic_warops_requirement + config_entry_value = 60 + min_val = 0 + +/datum/config_entry/number/dynamic_warops_cost + config_entry_value = 10 + min_val = 0 diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm index 779dfb43a7..9441236692 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm @@ -74,6 +74,11 @@ GLOBAL_VAR_INIT(war_declared, FALSE) new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS - tc_malus + CEILING(PLAYER_SCALING * actual_players, 1)) CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY)) + if(istype(SSticker.mode, /datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + var/threat_spent = CONFIG_GET(number/dynamic_warops_cost) + mode.spend_threat(threat_spent) + mode.threat_log += "[worldtime2text()]: Nuke ops spent [threat_spent] on war ops." SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1) qdel(src) @@ -94,6 +99,14 @@ GLOBAL_VAR_INIT(war_declared, FALSE) if(board.moved) to_chat(user, "The shuttle has already been moved! You have forfeit the right to declare war.") return FALSE + if(istype(SSticker.mode, /datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + if(mode.threat_level < CONFIG_GET(number/dynamic_warops_requirement)) + to_chat(user, "Due to the dynamic space in which the station resides, you are too deep into Nanotrasen territory to reasonably go loud.") + return FALSE + else if(mode.threat < CONFIG_GET(number/dynamic_warops_cost)) + to_chat(user, "Due to recent threats on the station, Nanotrasen is looking too closely for a war declaration to be wise.") + return FALSE return TRUE /obj/item/nuclear_challenge/clownops diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 3baf81a991..d43fa9e685 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -109,7 +109,7 @@ DYNAMIC_REQUIREMENTS METEOR 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 30 25 20 15 15 15 15 15 15 15 DYNAMIC_REQUIREMENTS MIDROUND_MALF_AI 101 101 70 50 50 50 40 30 30 30 DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 70 50 50 50 50 40 30 30 -DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 60 50 50 50 50 50 +DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 70 60 50 40 40 40 DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 50 50 50 50 DYNAMIC_REQUIREMENTS XENOS 101 101 101 70 50 50 50 50 50 50 DYNAMIC_REQUIREMENTS NIGHTMARE 101 101 101 70 50 40 20 15 15 15 @@ -174,3 +174,8 @@ DYNAMIC_SUMMON_MAGIC_COST 5 ## As above, but for summon events DYNAMIC_SUMMON_EVENTS_REQUIREMENT 20 DYNAMIC_SUMMON_EVENTS_COST 10 + +## This requirement uses threat level, rather than current threat, which is why it's higher. +DYNAMIC_WAROPS_REQUIREMENT 60 + +DYNAMIC_WAROPS_COST 10 From 912ca97d290551da2af4916100b33482e9ead5d8 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 03:44:22 -0800 Subject: [PATCH 052/121] Added a preference that auto-votes at extremely low weight. --- code/__DEFINES/preferences.dm | 7 +++++++ code/controllers/subsystem/vote.dm | 21 ++++++++++++++++++--- code/modules/client/preferences.dm | 10 ++++++++++ code/modules/client/preferences_savefile.dm | 3 +++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 0992b2e586..7a284ff1a0 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -75,3 +75,10 @@ #define JP_LOW 1 #define JP_MEDIUM 2 #define JP_HIGH 3 + +//Chaos levels for dynamic voting +#define CHAOS_NONE "None (Extended)" +#define CHAOS_LOW "Low" +#define CHAOS_MED "Medium" +#define CHAOS_HIGH "High" +#define CHAOS_MAX "Maximum" diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 605782535b..f87d3a9c25 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -153,9 +153,24 @@ SUBSYSTEM_DEF(vote) if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") GLOB.master_mode = "dynamic" - if(voted.len==0) - return message_admins("Nobody voted in the dynamic vote; using default dynamic settings.") - var/mean = (choices[PEACE]*-1+choices[CHAOS])/voted.len + var/mean = 0 + var/voters = 0 + for(var/client/c in GLOB.clients) + var/vote = c.prefs.preferred_chaos + if(vote) + voters += 1 + switch(vote) + if(CHAOS_NONE) + mean -= 0.1 + if(CHAOS_LOW) + mean -= 0.05 + if(CHAOS_HIGH) + mean += 0.05 + if(CHAOS_MAX) + mean += 0.1 + mean/=voters + if(voted.len != 0) + mean += (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 GLOB.dynamic_curve_width = CLAMP(4-abs(mean*3.5),0.5,4) to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index edec4d74a6..90b47aa53b 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -58,6 +58,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/inquisitive_ghost = 1 var/allow_midround_antag = 1 var/preferred_map = null + var/preferred_chaos = null var/pda_style = MONO var/pda_color = "#808000" var/pda_skin = PDA_SKIN_ALT @@ -834,6 +835,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Screen Shake: [(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]
" if (user && user.client && !user.client.prefs.screenshake==0) dat += "Damage Screen Shake: [(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]
" + var/p_chaos + if (!preferred_chaos) + p_chaos = "No preference" + else + p_chaos = preferred_chaos + dat += "Preferred Chaos Amount: [p_chaos]
" dat += "
" dat += "" dat += "" @@ -1996,6 +2003,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) if (pickedmap) preferred_map = maplist[pickedmap] + if ("preferred_chaos") + var/pickedchaos = input(user, "Choose your preferred level of chaos. This will help with dynamic threat level ratings.", "Character Preference") as null|anything in list(CHAOS_NONE,CHAOS_LOW,CHAOS_MED,CHAOS_HIGH,CHAOS_MAX) + preferred_chaos = pickedchaos if ("clientfps") var/desiredfps = input(user, "Choose your desired fps. (0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num if (!isnull(desiredfps)) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 98ef2ed0e8..29ea8f5821 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -183,6 +183,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["autostand"] >> autostand S["cit_toggles"] >> cit_toggles S["lewdchem"] >> lewdchem + S["preferred_chaos"] >> preferred_chaos + //try to fix any outdated data if necessary if(needs_update >= 0) @@ -278,6 +280,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["autostand"], autostand) WRITE_FILE(S["cit_toggles"], cit_toggles) WRITE_FILE(S["lewdchem"], lewdchem) + WRITE_FILE(S["preferred_chaos"], preferred_chaos) return 1 From 26cb5acce54784f1436e2531795125ef5e811ec9 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 04:25:26 -0800 Subject: [PATCH 053/121] Updated flavor text to better represent balance. --- code/game/gamemodes/dynamic/dynamic.dm | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 59b6bcd0b7..2a9271aa8f 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -201,7 +201,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) /datum/game_mode/dynamic/send_intercept() . = "Central Command Status Summary
" switch(round(threat_level)) - if(0 to 19) + if(0 to 30) update_playercounts() if(!current_players[CURRENT_LIVING_ANTAGS].len) . += "Peaceful Waypoint
" @@ -209,22 +209,27 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) else . += "Core Territory
" . += "Your station orbits within reliably mundane, secure space. Although Nanotrasen has a firm grip on security in your region, the valuable resources and strategic position aboard your station make it a potential target for infiltrations. Monitor crew for non-loyal behavior, but expect a relatively tame shift free of large-scale destruction. We expect great things from your station." - if(20 to 39) + set_security_level(SEC_LEVEL_GREEN) + if(31 to 49) . += "Anomalous Exogeology
" . += "Although your station lies within what is generally considered Nanotrasen-controlled space, the course of its orbit has caused it to cross unusually close to exogeological features with anomalous readings. Although these features offer opportunities for our research department, it is known that these little understood readings are often correlated with increased activity from competing interstellar organizations and individuals, among them the Wizard Federation and Cult of the Geometer of Blood - all known competitors for Anomaly Type B sites. Exercise elevated caution." - if(40 to 65) + set_security_level(SEC_LEVEL_GREEN) + if(50 to 65) . += "Contested System
" . += "Your station's orbit passes along the edge of Nanotrasen's sphere of influence. While subversive elements remain the most likely threat against your station, hostile organizations are bolder here, where our grip is weaker. Exercise increased caution against elite Syndicate strike forces, or Executives forbid, some kind of ill-conceived unionizing attempt." - if(66 to 79) + set_security_level(SEC_LEVEL_BLUE) . += "Uncharted Space
" . += "Congratulations and thank you for participating in the NT 'Frontier' space program! Your station is actively orbiting a high value system far from the nearest support stations. Little is known about your region of space, and the opportunity to encounter the unknown invites greater glory. You are encouraged to elevate security as necessary to protect Nanotrasen assets." + set_security_level(SEC_LEVEL_BLUE) if(80 to 99) . += "Black Orbit
" . += "As part of a mandatory security protocol, we are required to inform you that as a result of your orbital pattern directly behind an astrological body (oriented from our nearest observatory), your station will be under decreased monitoring and support. It is anticipated that your extreme location and decreased surveillance could pose security risks. Avoid unnecessary risks and attempt to keep your station in one piece." + set_security_level(SEC_LEVEL_AMBER) if(100) . += "Impending Doom
" . += "Your station is somehow in the middle of hostile territory, in clear view of any enemy of the corporation. Your likelihood to survive is low, and station destruction is expected and almost inevitable. Secure any sensitive material and neutralize any enemy you will come across. It is important that you at least try to maintain the station.
" . += "Good luck." + set_security_level(SEC_LEVEL_RED) if(station_goals.len) . += "
Special Orders for [station_name()]:" @@ -234,8 +239,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) print_command_report(., "Central Command Status Summary", announce=FALSE) priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", "intercept") - if(GLOB.security_level < SEC_LEVEL_BLUE) - set_security_level(SEC_LEVEL_BLUE) // Yes, this is copy pasted from game_mode /datum/game_mode/dynamic/check_finished(force_ending) From e1437717033c80a02c16da9bf64e0a54e2f0ff85 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 04:25:52 -0800 Subject: [PATCH 054/121] Made antag injection happen more often, initial injection later. --- .../configuration/entries/dynamic.dm | 17 ++++++++++++ code/game/gamemodes/dynamic/dynamic.dm | 26 ++++++++++++++----- config/dynamic_config.txt | 9 +++++-- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 0ca48258d8..6c8c9ff5a9 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -24,6 +24,23 @@ config_entry_value = 25 min_val = 1 +/datum/config_entry/number/dynamic_first_midround_delay_min + config_entry_value = 20 + min_val = 1 + +/datum/config_entry/number/dynamic_first_midround_delay_max + config_entry_value = 40 + min_val = 1 + +/datum/config_entry/number/dynamic_first_latejoin_delay_min + config_entry_value = 10 + min_val = 1 + +/datum/config_entry/number/dynamic_first_latejoin_delay_max + config_entry_value = 30 + min_val = 1 + + /datum/config_entry/keyed_list/dynamic_cost key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_NUM diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 2a9271aa8f..3f16c78d6c 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -12,10 +12,17 @@ // -- Injection delays GLOBAL_VAR_INIT(dynamic_latejoin_delay_min, (5 MINUTES)) -GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (25 MINUTES)) +GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (15 MINUTES)) -GLOBAL_VAR_INIT(dynamic_midround_delay_min, (15 MINUTES)) -GLOBAL_VAR_INIT(dynamic_midround_delay_max, (35 MINUTES)) +GLOBAL_VAR_INIT(dynamic_midround_delay_min, (10 MINUTES)) +GLOBAL_VAR_INIT(dynamic_midround_delay_max, (30 MINUTES)) + +// -- Roundstart injection delays +GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_min, (10 MINUTES)) +GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_max, (30 MINUTES)) + +GLOBAL_VAR_INIT(dynamic_first_midround_delay_min, (20 MINUTES)) +GLOBAL_VAR_INIT(dynamic_first_midround_delay_max, (40 MINUTES)) // Are HIGHLANDER_RULESETs allowed to stack? GLOBAL_VAR_INIT(dynamic_no_stacking, TRUE) @@ -123,6 +130,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) GLOB.dynamic_latejoin_delay_max = CONFIG_GET(number/dynamic_latejoin_delay_max)*600 GLOB.dynamic_midround_delay_min = CONFIG_GET(number/dynamic_midround_delay_min)*600 GLOB.dynamic_midround_delay_max = CONFIG_GET(number/dynamic_midround_delay_max)*600 + GLOB.dynamic_first_latejoin_delay_min = CONFIG_GET(number/dynamic_first_latejoin_delay_min)*600 + GLOB.dynamic_first_latejoin_delay_max = CONFIG_GET(number/dynamic_first_latejoin_delay_max)*600 + GLOB.dynamic_first_midround_delay_min = CONFIG_GET(number/dynamic_first_midround_delay_min)*600 + GLOB.dynamic_first_midround_delay_max = CONFIG_GET(number/dynamic_first_midround_delay_max)*600 /datum/game_mode/dynamic/admin_panel() var/list/dat = list("Game Mode Panel

Game Mode Panel

") @@ -218,6 +229,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) . += "Contested System
" . += "Your station's orbit passes along the edge of Nanotrasen's sphere of influence. While subversive elements remain the most likely threat against your station, hostile organizations are bolder here, where our grip is weaker. Exercise increased caution against elite Syndicate strike forces, or Executives forbid, some kind of ill-conceived unionizing attempt." set_security_level(SEC_LEVEL_BLUE) + if(65 to 79) . += "Uncharted Space
" . += "Congratulations and thank you for participating in the NT 'Frontier' space program! Your station is actively orbiting a high value system far from the nearest support stations. Little is known about your region of space, and the opportunity to encounter the unknown invites greater glory. You are encouraged to elevate security as necessary to protect Nanotrasen assets." set_security_level(SEC_LEVEL_BLUE) @@ -305,11 +317,11 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) else generate_threat() - var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_latejoin_delay_max + GLOB.dynamic_latejoin_delay_min) - latejoin_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_latejoin_delay_min, GLOB.dynamic_latejoin_delay_max)) + world.time + var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_latejoin_delay_max + GLOB.dynamic_first_latejoin_delay_min) + latejoin_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_first_latejoin_delay_min, GLOB.dynamic_first_latejoin_delay_max)) + world.time - var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_midround_delay_max + GLOB.dynamic_midround_delay_min) - midround_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_midround_delay_min, GLOB.dynamic_midround_delay_max)) + world.time + var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_midround_delay_min + GLOB.dynamic_first_midround_delay_max) + midround_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_first_midround_delay_min, GLOB.dynamic_first_midround_delay_max)) + world.time log_game("DYNAMIC: Dynamic Mode initialized with a Threat Level of... [threat_level]!") return TRUE diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index d43fa9e685..ab51bfdfc7 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -1,9 +1,14 @@ ## Injection delays: how long (in minutes) will pass before a midround or latejoin antag is injected. -DYNAMIC_MIDROUND_DELAY_MIN 15 -DYNAMIC_MIDROUND_DELAY_MAX 35 +DYNAMIC_MIDROUND_DELAY_MIN 5 +DYNAMIC_MIDROUND_DELAY_MAX 25 DYNAMIC_LATEJOIN_DELAY_MIN 5 DYNAMIC_LATEJOIN_DELAY_MAX 25 +DYNAMIC_FIRST_MIDROUND_DELAY_MIN 20 +DYNAMIC_FIRST_MIDROUND_DELAY_MAX 40 +DYNAMIC_FIRST_LATEJOIN_DELAY_MIN 10 +DYNAMIC_FIRST_LATEJOIN_DELAY_MAX 30 + ## How many roundstart players required for high population override to take effect. DYNAMIC_HIGH_POP_LIMIT 80 #80 instead of 55 because fewer robust players From c06c3a262b863b1a30dc34edf022d87b7fc89e9b Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 05:49:36 -0800 Subject: [PATCH 055/121] ported (commented out) dynamic vampire ruleset from 413 --- .../dynamic/dynamic_rulesets_latejoin.dm | 30 ++++++++++++++++++ .../dynamic/dynamic_rulesets_roundstart.dm | 31 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 192cca3a4b..c072754b7d 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -110,3 +110,33 @@ new_head = M.mind.add_antag_datum(new_head) new_head.rev_team.max_headrevs = 1 // Only one revhead if it is latejoin. return TRUE + +////////////////////////////////////////////// +// // +// VAMPIRE // +// // +////////////////////////////////////////////// + +/* +/datum/dynamic_ruleset/latejoin/vampire + name = "vampire" + config_tag = "vampire_latejoin" + antag_flag = ROLE_VAMPIRE + antag_datum = ANTAG_DATUM_VAMPIRE + protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain") + restricted_roles = list("AI", "Cyborg") + required_candidates = 1 + weight = 5 + cost = 15 + requirements = list(80,70,60,50,40,20,20,15,15,15) + repeatable = TRUE + high_population_requirement = 15 + +/datum/dynamic_ruleset/latejoin/vampire/pre_execute() + var/mob/M = pick(candidates) + candidates -= M + assigned += M.mind + M.mind.restricted_roles = restricted_roles + M.mind.special_role = ROLE_VAMPIRE + return TRUE +/* diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index e95f809fb8..36d0052ee5 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -796,3 +796,34 @@ var/ramp_up_final = CLAMP(round(meteorminutes/rampupdelta), 1, 10) spawn_meteors(ramp_up_final, wavetype) + +////////////////////////////////////////////// +// // +// VAMPIRE // +// // +////////////////////////////////////////////// + +/* +/datum/dynamic_ruleset/roundstart/vampire + name = "vampire" + config_tag = "vampire" + antag_flag = ROLE_VAMPIRE + antag_datum = ANTAG_DATUM_VAMPIRE + protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain") + restricted_roles = list("AI", "Cyborg") + required_candidates = 1 + weight = 3 + cost = 30 + requirements = list(101,101,100,90,80,70,60,50,50,50) + high_population_requirement = 50 + +/datum/dynamic_ruleset/roundstart/vampire/pre_execute() + var/num_vampires = min(round(mode.candidates.len / 10) + 1, candidates.len) + for (var/i = 1 to num_vampires) + var/mob/M = pick(candidates) + candidates -= M + assigned += M.mind + M.mind.restricted_roles = restricted_roles + M.mind.special_role = ROLE_VAMPIRE + return TRUE +*/ From 825ef80b9d8bfa8d9c98547f86c78afc6cd51cd7 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 06:33:31 -0800 Subject: [PATCH 056/121] started transferring some events from events to dynamic antags --- .../dynamic/dynamic_rulesets_midround.dm | 68 ++++++++++++++++++- .../antagonists/disease/disease_event.dm | 1 + .../revenant/revenant_spawn_event.dm | 1 + .../antagonists/slaughter/slaughterevent.dm | 1 + .../antagonists/swarmer/swarmer_event.dm | 1 + code/modules/events/abductor.dm | 2 +- code/modules/events/alien_infestation.dm | 2 +- code/modules/events/blob.dm | 2 +- code/modules/events/nightmare.dm | 1 + code/modules/events/pirates.dm | 2 +- code/modules/events/spider_infestation.dm | 1 + code/modules/events/vent_clog.dm | 1 + code/modules/ninja/ninja_event.dm | 1 + 13 files changed, 79 insertions(+), 5 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 7ba3388736..ef9f9cf2d6 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -100,7 +100,7 @@ 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.") - candidates = pollGhostCandidates("The mode is looking for volunteers to become [antag_flag] for [name]", antag_flag, SSticker.mode, antag_flag, poll_time = 300) + candidates = pollGhostCandidates("The mode is looking for volunteers to become a [name]", antag_flag, SSticker.mode, antag_flag, poll_time = 300) if(!candidates || candidates.len <= 0) message_admins("The ruleset [name] received no applications.") @@ -465,3 +465,69 @@ message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a Nightmare by the midround ruleset.") log_game("DYNAMIC: [key_name(S)] was spawned as a Nightmare by the midround ruleset.") return S + +/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease + name = "Sentient Disease" + config_tag = "sentient_disease" + antag_flag = ROLE_ALIEN + enemy_roles = list("Virologist","Chief Medical Officer","Captain","Chemist") + required_enemies = list(2,1,1,1,0,0,0,0,0,0) + required_candidates = 1 + weight = 4 + cost = 5 + requirements = list(30,30,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"! + high_population_requirement = 5 + +/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/generate_ruleset_body(mob/applicant) + var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center()) + applicant.transfer_ckey(virus, FALSE) + INVOKE_ASYNC(virus, /mob/camera/disease/proc/pick_name) + message_admins("[ADMIN_LOOKUPFLW(virus)] has been made into a sentient disease by the midround ruleset.") + log_game("[key_name(virus)] was spawned as a sentient disease by the midround ruleset.") + return virus + +/datum/dynamic_ruleset/midround/from_ghosts/revenant + name = "Revenant" + config_tag = "revenant" + antag_flag = ROLE_REVENANT + enemy_roles = list("Chief Engineer","Station Engineer","Captain","Chaplain") + required_enemies = list(2,1,1,1,0,0,0,0,0,0) + required_candidates = 1 + weight = 4 + cost = 5 + requirements = list(30,30,30,30,20,15,15,15,15,15) + high_population_requirement = 15 + +/datum/dynamic_ruleset/midround/from_ghosts/revenant/ready() + if(dead_players < REVENANT_SPAWN_THRESHOLD) + message_admins("Dynamic attempted to spawn a revenant, but there were only [deadMobs]/[REVENANT_SPAWN_THRESHOLD] dead mobs.") + return FALSE + return ..() + +/datum/dynamic_ruleset/midround/from_ghosts/revenant/execute() + for(var/mob/living/L in GLOB.dead_mob_list) //look for any dead bodies + var/turf/T = get_turf(L) + if(T && is_station_level(T.z)) + spawn_locs += T + if(!spawn_locs.len || spawn_locs.len < 15) //look for any morgue trays, crematoriums, ect if there weren't alot of dead bodies on the station to pick from + for(var/obj/structure/bodycontainer/bc in GLOB.bodycontainers) + var/turf/T = get_turf(bc) + if(T && is_station_level(T.z)) + spawn_locs += T + if(!spawn_locs.len) //If we can't find any valid spawnpoints, try the carp spawns + for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) + if(isturf(L.loc)) + spawn_locs += L.loc + if(!spawn_locs.len) //If we can't find either, just spawn the revenant at the player's location + spawn_locs += get_turf(selected) + if(!spawn_locs.len) //If we can't find THAT, then just give up and cry + return FALSE + return ..() + +/datum/dynamic_ruleset/midround/from_ghosts/revenant/generate_ruleset_body(mob/applicant) + var/mob/living/simple_animal/revenant/revvie = new(pick(spawn_locs)) + selected.transfer_ckey(revvie, FALSE) + message_admins("[ADMIN_LOOKUPFLW(revvie)] has been made into a revenant by the midround ruleset.") + log_game("[key_name(revvie)] was spawned as a revenant by the midround ruleset.") + return revvie + diff --git a/code/modules/antagonists/disease/disease_event.dm b/code/modules/antagonists/disease/disease_event.dm index 385cee998b..4365fd7538 100644 --- a/code/modules/antagonists/disease/disease_event.dm +++ b/code/modules/antagonists/disease/disease_event.dm @@ -3,6 +3,7 @@ name = "Spawn Sentient Disease" typepath = /datum/round_event/ghost_role/sentient_disease weight = 7 + gamemode_blacklist = list("dynamic") max_occurrences = 1 min_players = 5 diff --git a/code/modules/antagonists/revenant/revenant_spawn_event.dm b/code/modules/antagonists/revenant/revenant_spawn_event.dm index cb534b6613..7bb7f1aa76 100644 --- a/code/modules/antagonists/revenant/revenant_spawn_event.dm +++ b/code/modules/antagonists/revenant/revenant_spawn_event.dm @@ -4,6 +4,7 @@ name = "Spawn Revenant" // Did you mean 'griefghost'? typepath = /datum/round_event/ghost_role/revenant weight = 7 + gamemode_blacklist = list("dynamic") max_occurrences = 1 min_players = 5 diff --git a/code/modules/antagonists/slaughter/slaughterevent.dm b/code/modules/antagonists/slaughter/slaughterevent.dm index 6ace6a0536..069795cfb8 100644 --- a/code/modules/antagonists/slaughter/slaughterevent.dm +++ b/code/modules/antagonists/slaughter/slaughterevent.dm @@ -3,6 +3,7 @@ typepath = /datum/round_event/ghost_role/slaughter weight = 1 //Very rare max_occurrences = 1 + gamemode_blacklist = list("dynamic") earliest_start = 1 HOURS min_players = 20 diff --git a/code/modules/antagonists/swarmer/swarmer_event.dm b/code/modules/antagonists/swarmer/swarmer_event.dm index e086485a49..04ce151b95 100644 --- a/code/modules/antagonists/swarmer/swarmer_event.dm +++ b/code/modules/antagonists/swarmer/swarmer_event.dm @@ -3,6 +3,7 @@ typepath = /datum/round_event/spawn_swarmer weight = 7 max_occurrences = 1 //Only once okay fam + gamemode_blacklist = list("dynamic") earliest_start = 30 MINUTES min_players = 15 diff --git a/code/modules/events/abductor.dm b/code/modules/events/abductor.dm index aee49abcc0..25a5cb2ffa 100755 --- a/code/modules/events/abductor.dm +++ b/code/modules/events/abductor.dm @@ -4,7 +4,7 @@ weight = 10 max_occurrences = 1 min_players = 20 - gamemode_blacklist = list("nuclear","wizard","revolution") + gamemode_blacklist = list("nuclear","wizard","revolution","dynamic") /datum/round_event/ghost_role/abductor minimum_required = 2 diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index 762371886c..69e9a974eb 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -2,7 +2,7 @@ name = "Alien Infestation" typepath = /datum/round_event/ghost_role/alien_infestation weight = 5 - + gamemode_blacklist = list("dynamic") min_players = 10 max_occurrences = 1 diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index d2a5c27883..6bf44596eb 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -7,7 +7,7 @@ earliest_start = 60 MINUTES min_players = 40 - gamemode_blacklist = list("blob") //Just in case a blob survives that long + gamemode_blacklist = list("blob","dynamic") //Just in case a blob survives that long /datum/round_event/ghost_role/blob announceWhen = -1 diff --git a/code/modules/events/nightmare.dm b/code/modules/events/nightmare.dm index 698f5130f1..6e5512a617 100644 --- a/code/modules/events/nightmare.dm +++ b/code/modules/events/nightmare.dm @@ -2,6 +2,7 @@ name = "Spawn Nightmare" typepath = /datum/round_event/ghost_role/nightmare max_occurrences = 1 + gamemode_blacklist = list("dynamic") min_players = 20 /datum/round_event/ghost_role/nightmare diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index 477655db8b..45055f2e3a 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -5,7 +5,7 @@ max_occurrences = 1 min_players = 10 earliest_start = 30 MINUTES - gamemode_blacklist = list("nuclear") + gamemode_blacklist = list("nuclear","dynamic") /datum/round_event_control/pirates/preRunEvent() if (!SSmapping.empty_space) diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index a6c333145e..8c6b3e23a5 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -2,6 +2,7 @@ name = "Spider Infestation" typepath = /datum/round_event/spider_infestation weight = 5 + gamemode_blacklist = list("dynamic") max_occurrences = 1 min_players = 15 diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index 0deb880674..79487a024c 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -3,6 +3,7 @@ typepath = /datum/round_event/vent_clog weight = 10 max_occurrences = 3 + gamemode_blacklist = list("dynamic") min_players = 25 /datum/round_event/vent_clog diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm index ccd9b765c1..f166717aaf 100644 --- a/code/modules/ninja/ninja_event.dm +++ b/code/modules/ninja/ninja_event.dm @@ -14,6 +14,7 @@ Contents: typepath = /datum/round_event/ghost_role/ninja max_occurrences = 1 earliest_start = 40 MINUTES + gamemode_blacklist = list("dynamic") min_players = 15 /datum/round_event/ghost_role/ninja From cfcf89ebf1229ef4fea25e666eb157af51d70a71 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 15:44:38 -0800 Subject: [PATCH 057/121] Dynamic controls lots of events now (when active)! --- .../dynamic/dynamic_rulesets_midround.dm | 235 +++++++++++++++++- .../antagonists/swarmer/swarmer_event.dm | 1 - code/modules/events/ion_storm.dm | 1 + 3 files changed, 235 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index ef9f9cf2d6..ed595d3218 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -20,6 +20,11 @@ /// Whether the ruleset should call generate_ruleset_body or not. var/makeBody = TRUE +/datum/dynamic_ruleset/midround/event // Doesn't assume an antag + required_type = /mob + var/typepath // typepath of the event + var/triggering + /datum/dynamic_ruleset/midround/trim_candidates() // Unlike the previous two types, these rulesets are not meant for /mob/dead/new_player // And since I want those rulesets to be as flexible as possible, I'm not gonna put much here, @@ -161,6 +166,31 @@ /datum/dynamic_ruleset/midround/from_ghosts/proc/setup_role(datum/antagonist/new_role) return +/datum/dynamic_ruleset/midround/event/trim_list(list/L = list()) + return L.Copy() // we're not drafting ghosts here + +/datum/dynamic_ruleset/midround/event/ready(forced = FALSE) + return TRUE + +// acceptable() takes the place of canSpawnEvent + +/datum/dynamic_ruleset/midround/event/proc/preRunEvent() + if(!ispath(typepath, /datum/round_event)) + return EVENT_CANT_RUN + return EVENT_READY + +/datum/dynamic_ruleset/midround/event/proc/runEvent() + var/datum/round_event/E = new typepath() + E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1) + // E.control = src // can't be done! we just don't use events that require these, those can be from_ghost almost always + + testing("[time2text(world.time, "hh:mm:ss")] [E.type]") + if(alertadmins) + deadchat_broadcast("[name] has just been triggered by dynamic!") //STOP ASSUMING IT'S BADMINS! + log_game("Random Event triggering: [name] ([typepath])") + + return E + ////////////////////////////////////////////// // // // SYNDICATE TRAITORS // @@ -490,13 +520,14 @@ name = "Revenant" config_tag = "revenant" antag_flag = ROLE_REVENANT - enemy_roles = list("Chief Engineer","Station Engineer","Captain","Chaplain") + enemy_roles = list("Chief Engineer","Station Engineer","Captain","Chaplain","AI") required_enemies = list(2,1,1,1,0,0,0,0,0,0) required_candidates = 1 weight = 4 cost = 5 requirements = list(30,30,30,30,20,15,15,15,15,15) high_population_requirement = 15 + var/list/spawn_locs = list() /datum/dynamic_ruleset/midround/from_ghosts/revenant/ready() if(dead_players < REVENANT_SPAWN_THRESHOLD) @@ -531,3 +562,205 @@ log_game("[key_name(revvie)] was spawned as a revenant by the midround ruleset.") return revvie +/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon + name = "Slaughter Demon" + config_tag = "slaughter_demon" + antag_flag = ROLE_ALIEN + enemy_roles = list("Security Officer","Shaft Miner","Head of Security","Captain","Janitor","AI","Cyborg") + required_enemies = list(3,2,2,2,2,1,1,1,1,0) + required_candidates = 1 + weight = 4 + cost = 15 + requirements = list(101,101,101,90,80,70,60,50,40,30) + high_population_requirement = 30 + var/list/spawn_locs = list() + +/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/execute() + for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) + if(isturf(L.loc)) + spawn_locs += L.loc + + if(!(spawn_locs.len)) + message_admins("No valid spawn locations found for slaughter demon, aborting...") + return FALSE + return ..() + +/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/generate_ruleset_body(mob/applicant) + var/datum/mind/player_mind = new /datum/mind(applicant.key) + player_mind.active = 1 + var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter((pick(spawn_locs))) + var/mob/living/simple_animal/slaughter/S = new (holder) + S.holder = holder + player_mind.transfer_to(S) + player_mind.assigned_role = "Slaughter Demon" + player_mind.special_role = "Slaughter Demon" + player_mind.add_antag_datum(/datum/antagonist/slaughter) + to_chat(S, S.playstyle_string) + to_chat(S, "You are currently not currently in the same plane of existence as the station. Blood Crawl near a blood pool to manifest.") + SEND_SOUND(S, 'sound/magic/demon_dies.ogg') + message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a slaughter demon by dynamic.") + log_game("[key_name(S)] was spawned as a slaughter demon by dynamic.") + return S + +/datum/dynamic_ruleset/midround/from_ghosts/abductors + name = "Abductors" + config_tag = "abductors" + antag_flag = ROLE_ABDUCTOR + // Has two antagonist flags, in fact + enemy_roles = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain") + required_enemies = list(3,3,2,2,1,1,0,0,0,0) + required_candidates = 2 + weight = 8 + cost = 10 + requirements = list(80,80,70,50,40,30,30,20,15,15) + high_population_requirement = 15 + var/datum/team/abductor_team/team + +/datum/dynamic_ruleset/midround/from_ghosts/abductors/acceptable(population=0, threat=0) + if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules) + return FALSE // Unavailable if nuke ops were already sent at roundstart. yes, this is intentional for abductors too. + return ..() + +/datum/dynamic_ruleset/midround/from_ghosts/abductors/execute() + var/datum/team/abductor_team/team = new + if(team.team_number > ABDUCTOR_MAX_TEAMS) + return FALSE + return ..() + +/datum/dynamic_ruleset/midround/from_ghosts/abductors/finish_setup(mob/new_character, index) + switch(index) + if(1) // yeah this seems like a baffling anti-pattern but it's actually the best way to do this, shit you not + var/mob/living/carbon/human/agent = new_character + agent.mind.add_antag_datum(/datum/antagonist/abductor/agent, team) + log_game("[key_name(scientist)] has been selected as [T.name] abductor scientist.") + if(2) + var/mob/living/carbon/human/scientist = new_character + scientist.mind.add_antag_datum(/datum/antagonist/abductor/scientist, team) + log_game("[key_name(agent)] has been selected as [T.name] abductor agent.") + +/datum/dynamic_ruleset/midround/from_ghosts/ninja + name = "Space Ninja" + config_tag = "ninja" + antag_flag = ROLE_NINJA + enemy_roles = list("Security Officer","Head of Security","Captain","AI","Cyborg") + required_enemies = list(3,2,2,2,2,1,1,1,1,0) + required_candidates = 1 + weight = 4 + cost = 15 + requirements = list(101,101,101,90,80,70,60,50,40,30) + high_population_requirement = 30 + var/list/spawn_locs = list() + +/datum/dynamic_ruleset/midround/from_ghosts/ninja/execute() + if(!spawn_loc) + var/list/spawn_locs = list() + for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) + if(isturf(L.loc)) + spawn_locs += L.loc + if(!(spawn_locs.len)) + return FALSE + spawn_loc = pick(spawn_locs) + if(!spawn_loc) + return FALSE + return ..() + +/datum/dynamic_ruleset/midround/from_ghosts/ninja/generate_ruleset_body(mob/applicant) + var/key = applicant.key + + //Prepare ninja player mind + var/datum/mind/Mind = new /datum/mind(key) + Mind.assigned_role = ROLE_NINJA + Mind.special_role = ROLE_NINJA + Mind.active = 1 + + //spawn the ninja and assign the candidate + var/mob/living/carbon/human/Ninja = create_space_ninja(spawn_loc) + Mind.transfer_to(Ninja) + var/datum/antagonist/ninja/ninjadatum = new + ninjadatum.helping_station = pick(TRUE,FALSE) + if(ninjadatum.helping_station) + mode.refund_threat(5) + Mind.add_antag_datum(ninjadatum) + + if(Ninja.mind != Mind) //something has gone wrong! + throw EXCEPTION("Ninja created with incorrect mind") + + message_admins("[ADMIN_LOOKUPFLW(Ninja)] has been made into a ninja by dynamic.") + log_game("[key_name(Ninja)] was spawned as a ninja by dynamic.") + return Ninja + +/datum/dynamic_ruleset/midround/event/spiders + name = "Spider Infestation" + config_tag = "spiders" + typepath = /datum/round_event/spider_infestation + enemy_roles = list("AI","Security Officer","Head of Security","Captain") + required_enemies = list(2,2,1,1,0,0,0,0,0,0) + weight = 5 + cost = 10 + requirements = list(70,60,50,50,40,40,40,30,20,15) + high_population_requirement = 15 + +/datum/dynamic_ruleset/midround/event/ventclog + name = "Clogged Vents: Normal" + config_tag = "ventclog_normal" + typepath = /datum/round_event/vent_clog + enemy_roles = list("Chemist","Medical Doctor","Chief Medical Officer") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + cost = 2 + requirements = list(5,5,5,5,5,5,5,5,5,5) // yes, can happen on fake-extended + high_population_requirement = 5 + +/datum/dynamic_ruleset/midround/event/ventclog/threatening + name = "Clogged Vents: Threatening" + config_tag = "ventclog_threatening" + typepath = /datum/round_event/vent_clog/threatening + required_enemies = list(2,2,1,1,1,1,0,0,0,0) + cost = 5 + requirements = list(15,15,15,15,15,15,15,15,15,15) // doesn't really scale with pop, so + high_population_requirement = 15 + +/datum/dynamic_ruleset/midround/event/ventclog/catastrophic + name = "Clogged Vents: Catastrophic" + config_tag = "ventclog_catostrophic" + typepath = /datum/round_event/vent_clog/catastrophic + required_enemies = list(3,3,3,2,2,2,1,1,1,1) + cost = 15 + requirements = list(30,30,30,30,30,30,30,30,30,30) + high_population_requirement = 30 + +/datum/dynamic_ruleset/midround/event/ion_storm + name = "Ion Storm" + config_tag = "ion_storm" + typepath = /datum/round_event/ion_storm + enemy_roles = list("Research Director","Captain","Chief Engineer") + required_enemies = list(1,1,0,0,0,0,0,0,0,0) + cost = 3 + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + +/datum/dynamic_ruleset/midround/event/meteor_wave + name = "Meteor Wave: Normal" + config_tag = "meteor_wave_normal" + typepath = /datum/round_event/meteor_wave + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Captain","Cyborg") + required_enemies = list(2,2,2,2,2,2,2,2,2,2) + cost = 15 + requirements = list(60,50,40,30,30,30,30,30,30,30) + high_population_requirement = 30 + +/datum/dynamic_ruleset/midround/event/meteor_wave/threatening + name = "Meteor Wave: Threatening" + config_tag = "meteor_wave_threatening" + typepath = /datum/round_event/meteor_wave/threatening + cost = 25 + requirements = list(80,70,60,50,40,40,40,40,40,40) + high_population_requirement = 40 + +/datum/dynamic_ruleset/midround/event/meteor_wave/catastrophic + name = "Meteor Wave: Catastrophic" + config_tag = "meteor_wave_catastrophic" + typepath = /datum/round_event/meteor_wave/catastrophic + cost = 40 + requirements = list(101,100,90,80,70,60,50,50,50,50) + high_population_requirement = 50 + diff --git a/code/modules/antagonists/swarmer/swarmer_event.dm b/code/modules/antagonists/swarmer/swarmer_event.dm index 04ce151b95..e086485a49 100644 --- a/code/modules/antagonists/swarmer/swarmer_event.dm +++ b/code/modules/antagonists/swarmer/swarmer_event.dm @@ -3,7 +3,6 @@ typepath = /datum/round_event/spawn_swarmer weight = 7 max_occurrences = 1 //Only once okay fam - gamemode_blacklist = list("dynamic") earliest_start = 30 MINUTES min_players = 15 diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index cd7c0e3b1f..40364483bf 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -3,6 +3,7 @@ /datum/round_event_control/ion_storm name = "Ion Storm" typepath = /datum/round_event/ion_storm + gamemode_blacklist = list("dynamic") weight = 15 min_players = 2 From 9607eb4c57bb7e1d731a23d406caa8db971aa993 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 15:45:35 -0800 Subject: [PATCH 058/121] wowee --- code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index c072754b7d..8c5562288f 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -139,4 +139,4 @@ M.mind.restricted_roles = restricted_roles M.mind.special_role = ROLE_VAMPIRE return TRUE -/* +*/ From 385789fc58c2977cdde4e8ac60d77dac00f74f57 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 15:53:19 -0800 Subject: [PATCH 059/121] errors hooray --- .../dynamic/dynamic_rulesets_midround.dm | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index ed595d3218..b93262bdc6 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -1,3 +1,6 @@ +#define REVENANT_SPAWN_THRESHOLD 20 +#define ABDUCTOR_MAX_TEAMS 4 // blame TG for not using the defines files + ////////////////////////////////////////////// // // // MIDROUND RULESETS // @@ -185,8 +188,7 @@ // E.control = src // can't be done! we just don't use events that require these, those can be from_ghost almost always testing("[time2text(world.time, "hh:mm:ss")] [E.type]") - if(alertadmins) - deadchat_broadcast("[name] has just been triggered by dynamic!") //STOP ASSUMING IT'S BADMINS! + deadchat_broadcast("[name] has just been triggered by dynamic!") log_game("Random Event triggering: [name] ([typepath])") return E @@ -530,7 +532,10 @@ var/list/spawn_locs = list() /datum/dynamic_ruleset/midround/from_ghosts/revenant/ready() - if(dead_players < REVENANT_SPAWN_THRESHOLD) + var/deadMobs = 0 + for(var/mob/M in GLOB.dead_mob_list) + deadMobs++ + if(deadMobs < REVENANT_SPAWN_THRESHOLD) message_admins("Dynamic attempted to spawn a revenant, but there were only [deadMobs]/[REVENANT_SPAWN_THRESHOLD] dead mobs.") return FALSE return ..() @@ -549,15 +554,13 @@ for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) if(isturf(L.loc)) spawn_locs += L.loc - if(!spawn_locs.len) //If we can't find either, just spawn the revenant at the player's location - spawn_locs += get_turf(selected) if(!spawn_locs.len) //If we can't find THAT, then just give up and cry return FALSE return ..() /datum/dynamic_ruleset/midround/from_ghosts/revenant/generate_ruleset_body(mob/applicant) var/mob/living/simple_animal/revenant/revvie = new(pick(spawn_locs)) - selected.transfer_ckey(revvie, FALSE) + applicant.transfer_ckey(revvie, FALSE) message_admins("[ADMIN_LOOKUPFLW(revvie)] has been made into a revenant by the midround ruleset.") log_game("[key_name(revvie)] was spawned as a revenant by the midround ruleset.") return revvie @@ -632,11 +635,11 @@ if(1) // yeah this seems like a baffling anti-pattern but it's actually the best way to do this, shit you not var/mob/living/carbon/human/agent = new_character agent.mind.add_antag_datum(/datum/antagonist/abductor/agent, team) - log_game("[key_name(scientist)] has been selected as [T.name] abductor scientist.") + log_game("[key_name(agent)] has been selected as [team.name] abductor agent.") if(2) var/mob/living/carbon/human/scientist = new_character scientist.mind.add_antag_datum(/datum/antagonist/abductor/scientist, team) - log_game("[key_name(agent)] has been selected as [T.name] abductor agent.") + log_game("[key_name(scientist)] has been selected as [team.name] abductor scientist.") /datum/dynamic_ruleset/midround/from_ghosts/ninja name = "Space Ninja" @@ -650,6 +653,7 @@ requirements = list(101,101,101,90,80,70,60,50,40,30) high_population_requirement = 30 var/list/spawn_locs = list() + var/spawn_loc /datum/dynamic_ruleset/midround/from_ghosts/ninja/execute() if(!spawn_loc) @@ -764,3 +768,5 @@ requirements = list(101,100,90,80,70,60,50,50,50,50) high_population_requirement = 50 +#undef ABDUCTOR_MAX_TEAMS +#undef REVENANT_SPAWN_THRESHOLD From e592658a4c668b6c53e9006172e0364ce9a4aebe Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 15:56:15 -0800 Subject: [PATCH 060/121] important organization comments --- .../dynamic/dynamic_rulesets_midround.dm | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index b93262bdc6..f344bd8d18 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -498,6 +498,13 @@ log_game("DYNAMIC: [key_name(S)] was spawned as a Nightmare by the midround ruleset.") return S +////////////////////////////////////////////// +// // +// SENTIENT DISEASE // +// // +////////////////////////////////////////////// + + /datum/dynamic_ruleset/midround/from_ghosts/sentient_disease name = "Sentient Disease" config_tag = "sentient_disease" @@ -518,6 +525,13 @@ log_game("[key_name(virus)] was spawned as a sentient disease by the midround ruleset.") return virus +////////////////////////////////////////////// +// // +// REVENANT // +// // +////////////////////////////////////////////// + + /datum/dynamic_ruleset/midround/from_ghosts/revenant name = "Revenant" config_tag = "revenant" @@ -565,6 +579,13 @@ log_game("[key_name(revvie)] was spawned as a revenant by the midround ruleset.") return revvie +////////////////////////////////////////////// +// // +// SLAUGHTER DEMON // +// // +////////////////////////////////////////////// + + /datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon name = "Slaughter Demon" config_tag = "slaughter_demon" @@ -641,6 +662,12 @@ scientist.mind.add_antag_datum(/datum/antagonist/abductor/scientist, team) log_game("[key_name(scientist)] has been selected as [team.name] abductor scientist.") +////////////////////////////////////////////// +// // +// SPACE NINJA // +// // +////////////////////////////////////////////// + /datum/dynamic_ruleset/midround/from_ghosts/ninja name = "Space Ninja" config_tag = "ninja" @@ -693,6 +720,12 @@ log_game("[key_name(Ninja)] was spawned as a ninja by dynamic.") return Ninja +////////////////////////////////////////////// +// // +// SPIDERS // +// // +////////////////////////////////////////////// + /datum/dynamic_ruleset/midround/event/spiders name = "Spider Infestation" config_tag = "spiders" @@ -704,6 +737,12 @@ requirements = list(70,60,50,50,40,40,40,30,20,15) high_population_requirement = 15 +////////////////////////////////////////////// +// // +// CLOGGED VENTS // +// // +////////////////////////////////////////////// + /datum/dynamic_ruleset/midround/event/ventclog name = "Clogged Vents: Normal" config_tag = "ventclog_normal" @@ -732,6 +771,12 @@ requirements = list(30,30,30,30,30,30,30,30,30,30) high_population_requirement = 30 +////////////////////////////////////////////// +// // +// ION STORM // +// // +////////////////////////////////////////////// + /datum/dynamic_ruleset/midround/event/ion_storm name = "Ion Storm" config_tag = "ion_storm" @@ -742,6 +787,12 @@ requirements = list(5,5,5,5,5,5,5,5,5,5) high_population_requirement = 5 +////////////////////////////////////////////// +// // +// METEORS // +// // +////////////////////////////////////////////// + /datum/dynamic_ruleset/midround/event/meteor_wave name = "Meteor Wave: Normal" config_tag = "meteor_wave_normal" From 90a05e8c96818e7aa5692b344599724300bf8636 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 16:02:54 -0800 Subject: [PATCH 061/121] sorry abductors ilu --- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index f344bd8d18..e7077f32c3 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -626,6 +626,12 @@ log_game("[key_name(S)] was spawned as a slaughter demon by dynamic.") return S +////////////////////////////////////////////// +// // +// ABDUCTORS // +// // +////////////////////////////////////////////// + /datum/dynamic_ruleset/midround/from_ghosts/abductors name = "Abductors" config_tag = "abductors" From 053a660a60e3bc42f87acfa3f0884ae0cc7022a8 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 16:09:00 -0800 Subject: [PATCH 062/121] New stuff to config --- config/dynamic_config.txt | 58 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index ab51bfdfc7..b16c3dbaa4 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -53,9 +53,22 @@ DYNAMIC_WEIGHT MIDROUND_TRAITOR 3 DYNAMIC_WEIGHT MIDROUND_MALF_AI 2 DYNAMIC_WEIGHT MIDROUND_WIZARD 1 DYNAMIC_WEIGHT MIDROUND_NUCLEAR 1 -DYNAMIC_WEIGHT BLOB 6 -DYNAMIC_WEIGHT XENOS 7 -DYNAMIC_WEIGHT NIGHTMARE 9 +DYNAMIC_WEIGHT BLOB 3 +DYNAMIC_WEIGHT XENOS 3 +DYNAMIC_WEIGHT NIGHTMARE 3 +DYNAMIC_WEIGHT SENTIENT_DISEASE 6 +DYNAMIC_WEIGHT REVENANT 3 +DYNAMIC_WEIGHT SLAUGHTER_DEMON 2 +DYNAMIC_WEIGHT ABDUCTORS 8 +DYNAMIC_WEIGHT SPACE_NINJA 3 +DYNAMIC_WEIGHT SPIDERS 5 +DYNAMIC_WEIGHT VENTCLOG_NORMAL 7 +DYNAMIC_WEIGHT VENTCLOG_THREATENING 5 +DYNAMIC_WEIGHT VENTCLOG_CATASTROPHIC 3 +DYNAMIC_WEIGHT ION_STORM 4 +DYNAMIC_WEIGHT METEOR_WAVE_NORMAL 3 +DYNAMIC_WEIGHT METEOR_WAVE_THREATENING 2 +DYNAMIC_WEIGHT METEOR_WAVE_CATASTROPHIC 1 ## Latejoin antags DYNAMIC_WEIGHT LATEJOIN_TRAITOR 7 @@ -86,6 +99,19 @@ DYNAMIC_COST MIDROUND_NUCLEAR 35 DYNAMIC_COST BLOB 10 DYNAMIC_COST XENOS 10 DYNAMIC_COST NIGHTMARE 10 +DYNAMIC_COST SENTIENT_DISEASE 5 +DYNAMIC_COST REVENANT 5 +DYNAMIC_COST SLAUGHTER_DEMON 15 +DYNAMIC_COST ABDUCTORS 10 +DYNAMIC_COST SPACE_NINJA 15 +DYNAMIC_COST SPIDERS 10 +DYNAMIC_COST VENTCLOG_NORMAL 2 +DYNAMIC_COST VENTCLOG_THREATENING 5 +DYNAMIC_COST VENTCLOG_CATASTROPHIC 15 +DYNAMIC_COST ION_STORM 3 +DYNAMIC_COST METEOR_WAVE_NORMAL 15 +DYNAMIC_COST METEOR_WAVE_THREATENING 25 +DYNAMIC_COST METEOR_WAVE_CATASTROPHIC 40 ## Latejoin antags DYNAMIC_COST LATEJOIN_TRAITOR 5 @@ -118,6 +144,19 @@ DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 70 60 50 40 40 40 DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 50 50 50 50 DYNAMIC_REQUIREMENTS XENOS 101 101 101 70 50 50 50 50 50 50 DYNAMIC_REQUIREMENTS NIGHTMARE 101 101 101 70 50 40 20 15 15 15 +DYNAMIC_REQUIREMENTS SENTIENT_DISEASE 30 30 20 20 15 10 10 10 10 5 +DYNAMIC_REQUIREMENTS REVENANT 30 30 30 30 20 15 15 15 15 15 +DYNAMIC_REQUIREMENTS SLAUGHTER_DEMON 101 101 101 90 80 70 60 50 40 30 +DYNAMIC_REQUIREMENTS ABDUCTORS 80 80 70 50 40 30 30 20 15 15 +DYNAMIC_REQUIREMENTS SPACE_NINJA 101 101 101 90 80 70 60 50 40 30 +DYNAMIC_REQUIREMENTS SPIDERS 70 60 50 50 40 40 40 30 20 15 +DYNAMIC_REQUIREMENTS VENTCLOG_NORMAL 5 5 5 5 5 5 5 5 5 5 +DYNAMIC_REQUIREMENTS VENTCLOG_THREATENING 15 15 15 15 15 15 15 15 15 15 +DYNAMIC_REQUIREMENTS VENTCLOG_CATASTROPHIC 30 30 30 30 30 30 30 30 30 30 +DYNAMIC_REQUIREMENTS ION_STORM 5 5 5 5 5 5 5 5 5 5 +DYNAMIC_REQUIREMENTS METEOR_WAVE_NORMAL 60 50 40 30 30 30 30 30 30 30 +DYNAMIC_REQUIREMENTS METEOR_WAVE_THREATENING 80 70 60 50 40 40 40 40 40 40 +DYNAMIC_REQUIREMENTS METEOR_WAVE_CATASTROPHIC 101 100 90 80 70 60 50 50 50 50 ## Latejoin antags DYNAMIC_REQUIREMENTS LATEJOIN_TRAITOR 40 30 20 15 15 15 15 15 15 15 @@ -148,6 +187,19 @@ DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 35 DYNAMIC_HIGH_POPULATION_REQUIREMENT BLOB 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT XENOS 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 15 +DYNAMIC_REQUIREMENTS SENTIENT_DISEASE 5 +DYNAMIC_REQUIREMENTS REVENANT 15 +DYNAMIC_REQUIREMENTS SLAUGHTER_DEMON 30 +DYNAMIC_REQUIREMENTS ABDUCTORS 15 +DYNAMIC_REQUIREMENTS SPACE_NINJA 30 +DYNAMIC_REQUIREMENTS SPIDERS 15 +DYNAMIC_REQUIREMENTS VENTCLOG_NORMAL 5 +DYNAMIC_REQUIREMENTS VENTCLOG_THREATENING 15 +DYNAMIC_REQUIREMENTS VENTCLOG_CATASTROPHIC 30 +DYNAMIC_REQUIREMENTS ION_STORM 5 +DYNAMIC_REQUIREMENTS METEOR_WAVE_NORMAL 30 +DYNAMIC_REQUIREMENTS METEOR_WAVE_THREATENING 40 +DYNAMIC_REQUIREMENTS METEOR_WAVE_CATASTROPHIC 50 ## Latejoin antags DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 15 From 5c3dc7a49792023c8a4dace8bf5cfecf028dcf5d Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 16:23:29 -0800 Subject: [PATCH 063/121] more repeatability! --- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index e7077f32c3..353261821b 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -645,6 +645,7 @@ requirements = list(80,80,70,50,40,30,30,20,15,15) high_population_requirement = 15 var/datum/team/abductor_team/team + repeatable = TRUE /datum/dynamic_ruleset/midround/from_ghosts/abductors/acceptable(population=0, threat=0) if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules) @@ -758,6 +759,7 @@ cost = 2 requirements = list(5,5,5,5,5,5,5,5,5,5) // yes, can happen on fake-extended high_population_requirement = 5 + repeatable = TRUE /datum/dynamic_ruleset/midround/event/ventclog/threatening name = "Clogged Vents: Threatening" @@ -767,6 +769,7 @@ cost = 5 requirements = list(15,15,15,15,15,15,15,15,15,15) // doesn't really scale with pop, so high_population_requirement = 15 + repeatable = TRUE /datum/dynamic_ruleset/midround/event/ventclog/catastrophic name = "Clogged Vents: Catastrophic" @@ -776,6 +779,7 @@ cost = 15 requirements = list(30,30,30,30,30,30,30,30,30,30) high_population_requirement = 30 + repeatable = TRUE ////////////////////////////////////////////// // // @@ -792,6 +796,7 @@ cost = 3 requirements = list(5,5,5,5,5,5,5,5,5,5) high_population_requirement = 5 + repeatable = TRUE ////////////////////////////////////////////// // // @@ -808,6 +813,7 @@ cost = 15 requirements = list(60,50,40,30,30,30,30,30,30,30) high_population_requirement = 30 + repeatable = TRUE /datum/dynamic_ruleset/midround/event/meteor_wave/threatening name = "Meteor Wave: Threatening" @@ -816,6 +822,7 @@ cost = 25 requirements = list(80,70,60,50,40,40,40,40,40,40) high_population_requirement = 40 + repeatable = TRUE /datum/dynamic_ruleset/midround/event/meteor_wave/catastrophic name = "Meteor Wave: Catastrophic" @@ -824,6 +831,7 @@ cost = 40 requirements = list(101,100,90,80,70,60,50,50,50,50) high_population_requirement = 50 + repeatable = TRUE #undef ABDUCTOR_MAX_TEAMS #undef REVENANT_SPAWN_THRESHOLD From 11c2e4f38c19b07e3e2c9e9fe301e3d9525484f5 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 16:26:22 -0800 Subject: [PATCH 064/121] massively boost midround injection amounts --- code/game/gamemodes/dynamic/dynamic.dm | 8 +++++--- config/dynamic_config.txt | 10 +++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 3f16c78d6c..ed67b018e8 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -11,14 +11,14 @@ #define RULESET_STOP_PROCESSING 1 // -- Injection delays -GLOBAL_VAR_INIT(dynamic_latejoin_delay_min, (5 MINUTES)) -GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (15 MINUTES)) +GLOBAL_VAR_INIT(dynamic_latejoin_delay_min, (10 MINUTES)) +GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (30 MINUTES)) GLOBAL_VAR_INIT(dynamic_midround_delay_min, (10 MINUTES)) GLOBAL_VAR_INIT(dynamic_midround_delay_max, (30 MINUTES)) // -- Roundstart injection delays -GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_min, (10 MINUTES)) +GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_min, (2 MINUTES)) GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_max, (30 MINUTES)) GLOBAL_VAR_INIT(dynamic_first_midround_delay_min, (20 MINUTES)) @@ -632,6 +632,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) drafted_rules[rule] = rule.get_weight() if (drafted_rules.len > 0) picking_midround_latejoin_rule(drafted_rules) + else + midround_injection_cooldown = (midround_injection_cooldown + world.time)/2 /// Updates current_players. /datum/game_mode/dynamic/proc/update_playercounts() diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index b16c3dbaa4..0a7ab2e393 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -1,12 +1,12 @@ ## Injection delays: how long (in minutes) will pass before a midround or latejoin antag is injected. -DYNAMIC_MIDROUND_DELAY_MIN 5 -DYNAMIC_MIDROUND_DELAY_MAX 25 -DYNAMIC_LATEJOIN_DELAY_MIN 5 -DYNAMIC_LATEJOIN_DELAY_MAX 25 +DYNAMIC_MIDROUND_DELAY_MIN 10 +DYNAMIC_MIDROUND_DELAY_MAX 30 +DYNAMIC_LATEJOIN_DELAY_MIN 10 +DYNAMIC_LATEJOIN_DELAY_MAX 30 DYNAMIC_FIRST_MIDROUND_DELAY_MIN 20 DYNAMIC_FIRST_MIDROUND_DELAY_MAX 40 -DYNAMIC_FIRST_LATEJOIN_DELAY_MIN 10 +DYNAMIC_FIRST_LATEJOIN_DELAY_MIN 2 DYNAMIC_FIRST_LATEJOIN_DELAY_MAX 30 ## How many roundstart players required for high population override to take effect. From 0077e163e46afd26cc3cad20b7d8ec28a98d3abe Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 16:26:55 -0800 Subject: [PATCH 065/121] Made roundstart traitors always possible at >=60 threat --- code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 36d0052ee5..4cfeb498b0 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -17,7 +17,7 @@ required_candidates = 1 weight = 5 cost = 10 - requirements = list(101,101,100,90,80,70,60,50,50,50) + requirements = list(60,60,50,50,50,50,50,50,50,50) high_population_requirement = 50 var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) From b95184ce65ce69dff192d56dd0226fc7a9eff5ea Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 16:42:01 -0800 Subject: [PATCH 066/121] might be better if events actually run --- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 353261821b..2cc9f0f287 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -175,14 +175,7 @@ /datum/dynamic_ruleset/midround/event/ready(forced = FALSE) return TRUE -// acceptable() takes the place of canSpawnEvent - -/datum/dynamic_ruleset/midround/event/proc/preRunEvent() - if(!ispath(typepath, /datum/round_event)) - return EVENT_CANT_RUN - return EVENT_READY - -/datum/dynamic_ruleset/midround/event/proc/runEvent() +/datum/dynamic_ruleset/midround/event/execute() var/datum/round_event/E = new typepath() E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1) // E.control = src // can't be done! we just don't use events that require these, those can be from_ghost almost always From ac677be4f18d325051c6c5c5bf38583ac7468063 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 16:47:51 -0800 Subject: [PATCH 067/121] Made the roundstart flavor make a bit more sense. --- code/game/gamemodes/dynamic/dynamic.dm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index ed67b018e8..be01becaba 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -249,8 +249,11 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) G.on_report() . += G.get_report() - print_command_report(., "Central Command Status Summary", announce=FALSE) - priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", "intercept") + if(GLOB.security_level >= SEC_LEVEL_BLUE) + print_command_report(., "Central Command Status Summary", announce=FALSE) + priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", "intercept") + else + print_command_report(., "Central Command Status Summary", announce=TRUE) // Yes, this is copy pasted from game_mode /datum/game_mode/dynamic/check_finished(force_ending) From a912c6729f93b314772f396741aa8023af412acd Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 20:42:58 -0800 Subject: [PATCH 068/121] okay none of that i guess --- .../dynamic/dynamic_rulesets_roundstart.dm | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 4cfeb498b0..fe8b54775f 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -796,34 +796,3 @@ var/ramp_up_final = CLAMP(round(meteorminutes/rampupdelta), 1, 10) spawn_meteors(ramp_up_final, wavetype) - -////////////////////////////////////////////// -// // -// VAMPIRE // -// // -////////////////////////////////////////////// - -/* -/datum/dynamic_ruleset/roundstart/vampire - name = "vampire" - config_tag = "vampire" - antag_flag = ROLE_VAMPIRE - antag_datum = ANTAG_DATUM_VAMPIRE - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain") - restricted_roles = list("AI", "Cyborg") - required_candidates = 1 - weight = 3 - cost = 30 - requirements = list(101,101,100,90,80,70,60,50,50,50) - high_population_requirement = 50 - -/datum/dynamic_ruleset/roundstart/vampire/pre_execute() - var/num_vampires = min(round(mode.candidates.len / 10) + 1, candidates.len) - for (var/i = 1 to num_vampires) - var/mob/M = pick(candidates) - candidates -= M - assigned += M.mind - M.mind.restricted_roles = restricted_roles - M.mind.special_role = ROLE_VAMPIRE - return TRUE -*/ From d10a317b427b3c5905d0621c5d0bd7dc36b7e3e8 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 21:09:24 -0800 Subject: [PATCH 069/121] Made vote consensus way stronger --- code/controllers/subsystem/vote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index f87d3a9c25..37bc84a401 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -172,7 +172,7 @@ SUBSYSTEM_DEF(vote) if(voted.len != 0) mean += (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 - GLOB.dynamic_curve_width = CLAMP(4-abs(mean*3.5),0.5,4) + GLOB.dynamic_curve_width = CLAMP(4-abs(mean*10),0.5,4) to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") From b23b5c02f4ae30ef4ec99b27138ec8c18bb2c427 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 21:09:37 -0800 Subject: [PATCH 070/121] Improved roundstart report flavor --- code/game/gamemodes/dynamic/dynamic.dm | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index be01becaba..04d7f3d9e0 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -213,17 +213,12 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) . = "Central Command Status Summary
" switch(round(threat_level)) if(0 to 30) - update_playercounts() - if(!current_players[CURRENT_LIVING_ANTAGS].len) - . += "Peaceful Waypoint
" - . += "Your station orbits deep within controlled, core-sector systems and serves as a waypoint for routine traffic through Nanotrasen's trade empire. Due to the combination of high security, interstellar traffic, and low strategic value, it makes any direct threat of violence unlikely. Your primary enemies will be incompetence and bored crewmen: try to organize team-building events to keep staffers interested and productive." - else - . += "Core Territory
" - . += "Your station orbits within reliably mundane, secure space. Although Nanotrasen has a firm grip on security in your region, the valuable resources and strategic position aboard your station make it a potential target for infiltrations. Monitor crew for non-loyal behavior, but expect a relatively tame shift free of large-scale destruction. We expect great things from your station." + . += "Peaceful Waypoint
" + . += "Your station orbits deep within controlled, core-sector systems and serves as a waypoint for routine traffic through Nanotrasen's trade empire. Due to the combination of high security, interstellar traffic, and low strategic value, it makes any direct threat of violence unlikely. Your primary enemies will be incompetence and bored crewmen: try to organize team-building events to keep staffers interested and productive. However, even deep in our territory there may be subversive elements, especially for such a high-value target as your station. Keep an eye out, but don't expect much trouble." set_security_level(SEC_LEVEL_GREEN) if(31 to 49) - . += "Anomalous Exogeology
" - . += "Although your station lies within what is generally considered Nanotrasen-controlled space, the course of its orbit has caused it to cross unusually close to exogeological features with anomalous readings. Although these features offer opportunities for our research department, it is known that these little understood readings are often correlated with increased activity from competing interstellar organizations and individuals, among them the Wizard Federation and Cult of the Geometer of Blood - all known competitors for Anomaly Type B sites. Exercise elevated caution." + . += "Core Territory
" + . += "Your station orbits within reliably mundane, secure space. Although Nanotrasen has a firm grip on security in your region, the valuable resources and strategic position aboard your station make it a potential target for infiltrations. Monitor crew for non-loyal behavior, but expect a relatively tame shift free of large-scale destruction. We expect great things from your station." set_security_level(SEC_LEVEL_GREEN) if(50 to 65) . += "Contested System
" @@ -249,11 +244,11 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) G.on_report() . += G.get_report() + print_command_report(., "Central Command Status Summary", announce=FALSE) if(GLOB.security_level >= SEC_LEVEL_BLUE) - print_command_report(., "Central Command Status Summary", announce=FALSE) priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", "intercept") else - print_command_report(., "Central Command Status Summary", announce=TRUE) + priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no likely threats to [station_name()]. Have a secure shift!", "Security Report", "commandreport") // Yes, this is copy pasted from game_mode /datum/game_mode/dynamic/check_finished(force_ending) From e21d34de7886eb8fc9402de3cacba9484e9f1c19 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 8 Nov 2019 23:19:16 -0800 Subject: [PATCH 071/121] MORE! MORE! MORE! --- code/game/gamemodes/dynamic/dynamic.dm | 6 +++--- config/dynamic_config.txt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 04d7f3d9e0..34b263c6bd 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -14,15 +14,15 @@ GLOBAL_VAR_INIT(dynamic_latejoin_delay_min, (10 MINUTES)) GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (30 MINUTES)) -GLOBAL_VAR_INIT(dynamic_midround_delay_min, (10 MINUTES)) -GLOBAL_VAR_INIT(dynamic_midround_delay_max, (30 MINUTES)) +GLOBAL_VAR_INIT(dynamic_midround_delay_min, (5 MINUTES)) +GLOBAL_VAR_INIT(dynamic_midround_delay_max, (15 MINUTES)) // -- Roundstart injection delays GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_min, (2 MINUTES)) GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_max, (30 MINUTES)) GLOBAL_VAR_INIT(dynamic_first_midround_delay_min, (20 MINUTES)) -GLOBAL_VAR_INIT(dynamic_first_midround_delay_max, (40 MINUTES)) +GLOBAL_VAR_INIT(dynamic_first_midround_delay_max, (30 MINUTES)) // Are HIGHLANDER_RULESETs allowed to stack? GLOBAL_VAR_INIT(dynamic_no_stacking, TRUE) diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 0a7ab2e393..a03bf238b8 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -1,11 +1,11 @@ ## Injection delays: how long (in minutes) will pass before a midround or latejoin antag is injected. -DYNAMIC_MIDROUND_DELAY_MIN 10 -DYNAMIC_MIDROUND_DELAY_MAX 30 +DYNAMIC_MIDROUND_DELAY_MIN 5 +DYNAMIC_MIDROUND_DELAY_MAX 15 DYNAMIC_LATEJOIN_DELAY_MIN 10 DYNAMIC_LATEJOIN_DELAY_MAX 30 DYNAMIC_FIRST_MIDROUND_DELAY_MIN 20 -DYNAMIC_FIRST_MIDROUND_DELAY_MAX 40 +DYNAMIC_FIRST_MIDROUND_DELAY_MAX 30 DYNAMIC_FIRST_LATEJOIN_DELAY_MIN 2 DYNAMIC_FIRST_LATEJOIN_DELAY_MAX 30 From 80448c0abb4b4df7180c9ac25e120d3b299eb0d9 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 00:40:54 -0800 Subject: [PATCH 072/121] wow, totally the wrong proc, very cool --- .../dynamic/dynamic_rulesets_midround.dm | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 2cc9f0f287..222f2fc791 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -538,16 +538,15 @@ high_population_requirement = 15 var/list/spawn_locs = list() -/datum/dynamic_ruleset/midround/from_ghosts/revenant/ready() +/datum/dynamic_ruleset/midround/from_ghosts/revenant/ready(forced = FALSE) var/deadMobs = 0 for(var/mob/M in GLOB.dead_mob_list) deadMobs++ if(deadMobs < REVENANT_SPAWN_THRESHOLD) message_admins("Dynamic attempted to spawn a revenant, but there were only [deadMobs]/[REVENANT_SPAWN_THRESHOLD] dead mobs.") return FALSE - return ..() - -/datum/dynamic_ruleset/midround/from_ghosts/revenant/execute() + if(required_candidates > (dead_players.len + list_observers.len)) + return FALSE for(var/mob/living/L in GLOB.dead_mob_list) //look for any dead bodies var/turf/T = get_turf(L) if(T && is_station_level(T.z)) @@ -592,12 +591,14 @@ high_population_requirement = 30 var/list/spawn_locs = list() -/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/execute() +/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/ready(forced = FALSE) + if(required_candidates > (dead_players.len + list_observers.len)) + return FALSE for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) if(isturf(L.loc)) spawn_locs += L.loc - if(!(spawn_locs.len)) + if(!spawn_locs.len) message_admins("No valid spawn locations found for slaughter demon, aborting...") return FALSE return ..() @@ -645,8 +646,10 @@ return FALSE // Unavailable if nuke ops were already sent at roundstart. yes, this is intentional for abductors too. return ..() -/datum/dynamic_ruleset/midround/from_ghosts/abductors/execute() - var/datum/team/abductor_team/team = new +/datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE) + if(required_candidates > (dead_players.len + list_observers.len)) + return FALSE + team = new /datum/team/abductor_team if(team.team_number > ABDUCTOR_MAX_TEAMS) return FALSE return ..() @@ -682,13 +685,15 @@ var/list/spawn_locs = list() var/spawn_loc -/datum/dynamic_ruleset/midround/from_ghosts/ninja/execute() +/datum/dynamic_ruleset/midround/from_ghosts/ninja/ready(forced = FALSE) + if(required_candidates > (dead_players.len + list_observers.len)) + return FALSE if(!spawn_loc) var/list/spawn_locs = list() for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) if(isturf(L.loc)) spawn_locs += L.loc - if(!(spawn_locs.len)) + if(!spawn_locs.len) return FALSE spawn_loc = pick(spawn_locs) if(!spawn_loc) From d0d469a45af581cb4a6d60b79a668dcbca5ec7ac Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 01:00:35 -0800 Subject: [PATCH 073/121] Better roundend logging --- code/__HELPERS/roundend.dm | 4 ++-- code/game/gamemodes/dynamic/dynamic.dm | 15 +++++++++++---- .../dynamic/dynamic_rulesets_midround.dm | 4 ++-- .../nukeop/equipment/nuclear_challenge.dm | 2 +- code/modules/antagonists/traitor/datum_traitor.dm | 4 ++-- .../antagonists/wizard/equipment/spellbook.dm | 6 +++--- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 8e59106d98..233ea22631 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -313,8 +313,8 @@ parts += "[FOURSPACES]Threat level: [mode.threat_level]" parts += "[FOURSPACES]Threat left: [mode.threat]" parts += "[FOURSPACES]Executed rules:" - for(var/datum/dynamic_ruleset/rule in mode.executed_rules) - parts += "[FOURSPACES][FOURSPACES][rule.ruletype] - [rule.name]: -[rule.cost] threat" + for(var/str in mode.threat_log) + parts += "[FOURSPACES][FOURSPACES][str]" return parts.Join("
") /client/proc/roundend_report_file() diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 34b263c6bd..dff34df50a 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -64,6 +64,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/threat = 0 /// Running information about the threat. Can store text or datum entries. var/list/threat_log = list() + /// As above, but with info such as refunds. + var/list/threat_log_verbose = list() /// List of roundstart rules used for selecting the rules. var/list/roundstart_rules = list() /// List of latejoin rules used for selecting the rules. @@ -266,6 +268,11 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if(rule.flags & HIGHLANDER_RULESET) return rule.check_finished() +/datum/game_mode/dynamic/proc/log_threat(var/log_str,var/verbose = FALSE) + threat_log_verbose += ("[worldtime2text()]: "+log_str) + if(!verbose) + threat_log += log_str + /datum/game_mode/dynamic/proc/show_threatlog(mob/admin) if(!SSticker.HasRoundStarted()) alert("The round hasn't started yet!") @@ -276,7 +283,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/list/out = list("Threat LogThreat Log
Starting Threat: [threat_level]
") - for(var/entry in threat_log) + for(var/entry in threat_log_verbose) if(istext(entry)) out += "[entry]
" @@ -461,7 +468,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) starting_rule.trim_candidates() if (starting_rule.pre_execute()) spend_threat(starting_rule.cost) - threat_log += "[worldtime2text()]: Roundstart [starting_rule.name] spent [starting_rule.cost]" + log_threat("Roundstart [starting_rule.name] spent [starting_rule.cost]") if(starting_rule.flags & HIGHLANDER_RULESET) highlander_executed = TRUE else if(starting_rule.flags & ONLY_RULESET) @@ -526,7 +533,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if (rule.execute()) log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") spend_threat(rule.cost) - threat_log += "[worldtime2text()]: [rule.ruletype] [rule.name] spent [rule.cost]" + log_threat("[rule.ruletype] [rule.name] spent [rule.cost]") if(rule.flags & HIGHLANDER_RULESET) highlander_executed = TRUE else if(rule.flags & ONLY_RULESET) @@ -575,7 +582,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) new_rule.trim_candidates() if (new_rule.ready(forced)) spend_threat(new_rule.cost) - threat_log += "[worldtime2text()]: Forced rule [new_rule.name] spent [new_rule.cost]" + log_threat("Rule [new_rule.name] spent [new_rule.cost]") if (new_rule.execute()) // This should never fail since ready() returned 1 if(new_rule.flags & HIGHLANDER_RULESET) highlander_executed = TRUE diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 222f2fc791..16d556c795 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -114,7 +114,7 @@ message_admins("The ruleset [name] received no applications.") log_game("DYNAMIC: The ruleset [name] received no applications.") mode.refund_threat(cost) - mode.threat_log += "[worldtime2text()]: Rule [name] refunded [cost] (no applications)" + mode.log_threat("[worldtime2text()]: Rule [name] refunded [cost] (no applications)",verbose=TRUE) mode.executed_rules -= src return @@ -130,7 +130,7 @@ if(i == 1) // We have found no candidates so far and we are out of applicants. mode.refund_threat(cost) - mode.threat_log += "[worldtime2text()]: Rule [name] refunded [cost] (all applications invalid)" + mode.log_threat("[worldtime2text()]: Rule [name] refunded [cost] (all applications invalid)",verbose=TRUE) mode.executed_rules -= src break var/mob/applicant = pick(candidates) diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm index 9441236692..219084d3e0 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm @@ -78,7 +78,7 @@ GLOBAL_VAR_INIT(war_declared, FALSE) var/datum/game_mode/dynamic/mode = SSticker.mode var/threat_spent = CONFIG_GET(number/dynamic_warops_cost) mode.spend_threat(threat_spent) - mode.threat_log += "[worldtime2text()]: Nuke ops spent [threat_spent] on war ops." + mode.log_threat("Nuke ops spent [threat_spent] on war ops.") SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1) qdel(src) diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 55f9fe483b..9a3aa19377 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -106,7 +106,7 @@ if(is_dynamic) var/threat_spent = CONFIG_GET(number/dynamic_hijack_cost) mode.spend_threat(threat_spent) - mode.threat_log += "[worldtime2text()]: Traitor spent [threat_spent] on hijack." + mode.log_threat("[owner.name] spent [threat_spent] on hijack.") return @@ -123,7 +123,7 @@ if(is_dynamic) var/threat_spent = CONFIG_GET(number/dynamic_hijack_cost) mode.spend_threat(threat_spent) - mode.threat_log += "[worldtime2text()]: Traitor spent [threat_spent] on glorious death." + mode.log_threat("[owner.name] spent [threat_spent] on glorious death.") return else diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index 71b92feec6..ef0974f73c 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -498,7 +498,7 @@ var/datum/game_mode/dynamic/mode = SSticker.mode var/threat_spent = CONFIG_GET(number/dynamic_summon_guns_cost) mode.spend_threat(threat_spent) - mode.threat_log += "[worldtime2text()]: Wizard spent [threat_spent] on summon guns." + mode.log_threat("Wizard spent [threat_spent] on summon guns.") return 1 /datum/spellbook_entry/summon/magic @@ -524,7 +524,7 @@ var/datum/game_mode/dynamic/mode = SSticker.mode var/threat_spent = CONFIG_GET(number/dynamic_summon_magic_cost) mode.spend_threat(threat_spent) - mode.threat_log += "[worldtime2text()]: Wizard spent [threat_spent] on summon magic." + mode.log_threat("Wizard spent [threat_spent] on summon magic.") return 1 /datum/spellbook_entry/summon/events @@ -551,7 +551,7 @@ var/datum/game_mode/dynamic/mode = SSticker.mode var/threat_spent = CONFIG_GET(number/dynamic_summon_events_cost) mode.spend_threat(threat_spent) - mode.threat_log += "[worldtime2text()]: Wizard spent [threat_spent] on summon events." + mode.log_threat("Wizard spent [threat_spent] on summon events.") return 1 /datum/spellbook_entry/summon/events/GetInfo() From 428ea5e5e14ad44913d425c63225637174b438b6 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 03:12:36 -0800 Subject: [PATCH 074/121] Nuke disk being still now generates threat --- code/__HELPERS/roundend.dm | 2 + code/game/gamemodes/dynamic/dynamic.dm | 7 ++- .../nukeop/equipment/nuclearbomb.dm | 47 ++++++++++++++----- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 233ea22631..46b36e429d 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -315,6 +315,8 @@ parts += "[FOURSPACES]Executed rules:" for(var/str in mode.threat_log) parts += "[FOURSPACES][FOURSPACES][str]" + for(var/entry in mode.threat_tallies) + parts += "[FOURSPACES][FOURSPACES][entry] added [mode.threat_tallies[entry]]" return parts.Join("
") /client/proc/roundend_report_file() diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index dff34df50a..e872ee1915 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -62,6 +62,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/threat_level = 0 /// Set at the beginning of the round. Spent by the mode to "purchase" rules. var/threat = 0 + /// Starting threat level, for things that increase it but can bring it back down. + var/initial_threat_level = 0 + /// Things that cause a rolling threat adjustment to be displayed at roundend. + var/list/threat_tallies = list() /// Running information about the threat. Can store text or datum entries. var/list/threat_log = list() /// As above, but with info such as refunds. @@ -281,7 +285,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if(!check_rights(R_ADMIN)) return - var/list/out = list("Threat LogThreat Log
Starting Threat: [threat_level]
") + var/list/out = list("Threat LogThreat Log
Starting Threat: [initial_threat_level]
") for(var/entry in threat_log_verbose) if(istext(entry)) @@ -328,6 +332,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_midround_delay_min + GLOB.dynamic_first_midround_delay_max) midround_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_first_midround_delay_min, GLOB.dynamic_first_midround_delay_max)) + world.time log_game("DYNAMIC: Dynamic Mode initialized with a Threat Level of... [threat_level]!") + initial_threat_level = threat_level return TRUE /datum/game_mode/dynamic/pre_setup() diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index add3c1d9b0..d271c6c24c 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -583,6 +583,8 @@ This is here to make the tiles around the station mininuke change when it's arme . = ..() AddComponent(/datum/component/stationloving, !fake) +#define STATIONARY_DISK_STRING "Stationary Nuke Disk" + /obj/item/disk/nuclear/process() if(fake) STOP_PROCESSING(SSobj, src) @@ -590,21 +592,42 @@ This is here to make the tiles around the station mininuke change when it's arme var/turf/newturf = get_turf(src) if(newturf && lastlocation == newturf) if(last_disk_move < world.time - 5000 && prob((world.time - 5000 - last_disk_move)*0.0001)) - var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control - if(istype(loneop)) - loneop.weight += 1 - if(loneop.weight % 5 == 0) - message_admins("[src] is stationary in [ADMIN_VERBOSEJMP(newturf)]. The weight of Lone Operative is now [loneop.weight].") - log_game("[src] is stationary for too long in [loc_name(newturf)], and has increased the weight of the Lone Operative event to [loneop.weight].") + if(istype(SSticker.mode, /datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + mode.create_threat(0.1) + if(round(mode.threat) == mode.threat) + message_admins("[src] is stationary in [ADMIN_VERBOSEJMP(newturf)]. The dynamic threat rating has increased to [mode.threat].") + log_game("[src] is stationary for too long in [loc_name(newturf)], and has increased dynamic threat to [mode.threat].") + if(!(STATIONARY_DISK_STRING in mode.threat_tallies)) + mode.threat_tallies[STATIONARY_DISK_STRING] = 0 + mode.threat_tallies[STATIONARY_DISK_STRING] += 0.1 + else + var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control + if(istype(loneop)) + loneop.weight += 1 + if(loneop.weight % 5 == 0) + message_admins("[src] is stationary in [ADMIN_VERBOSEJMP(newturf)]. The weight of Lone Operative is now [loneop.weight].") + log_game("[src] is stationary for too long in [loc_name(newturf)], and has increased the weight of the Lone Operative event to [loneop.weight].") else lastlocation = newturf last_disk_move = world.time - var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control - if(istype(loneop) && prob(loneop.weight)) - loneop.weight = max(loneop.weight - 1, 0) - if(loneop.weight % 5 == 0) - message_admins("[src] is on the move (currently in [ADMIN_VERBOSEJMP(newturf)]). The weight of Lone Operative is now [loneop.weight].") - log_game("[src] being on the move has reduced the weight of the Lone Operative event to [loneop.weight].") + if(istype(SSticker.mode, /datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + if(STATIONARY_DISK_STRING in mode.threat_tallies) + mode.threat_tallies[STATIONARY_DISK_STRING] -= 0.1 + mode.spend_threat(0.1) + mode.threat_level = max(mode.threat_level-0.1,mode.initial_threat_level) + if(mode.threat_tallies[STATIONARY_DISK_STRING] == 0) + mode.threat_tallies -= STATIONARY_DISK_STRING + else + var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control + if(istype(loneop) && prob(loneop.weight)) + loneop.weight = max(loneop.weight - 1, 0) + if(loneop.weight % 5 == 0) + message_admins("[src] is on the move (currently in [ADMIN_VERBOSEJMP(newturf)]). The weight of Lone Operative is now [loneop.weight].") + log_game("[src] being on the move has reduced the weight of the Lone Operative event to [loneop.weight].") + +#undef STATIONARY_DISK_STRING /obj/item/disk/nuclear/examine(mob/user) . = ..() From a7302dfbc4f60aa7edbbf3a8819099cccd3461c9 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 03:13:37 -0800 Subject: [PATCH 075/121] less terrible admin spam --- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 16d556c795..cbb2ee61b6 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -543,7 +543,6 @@ for(var/mob/M in GLOB.dead_mob_list) deadMobs++ if(deadMobs < REVENANT_SPAWN_THRESHOLD) - message_admins("Dynamic attempted to spawn a revenant, but there were only [deadMobs]/[REVENANT_SPAWN_THRESHOLD] dead mobs.") return FALSE if(required_candidates > (dead_players.len + list_observers.len)) return FALSE @@ -599,7 +598,6 @@ spawn_locs += L.loc if(!spawn_locs.len) - message_admins("No valid spawn locations found for slaughter demon, aborting...") return FALSE return ..() From 68e18ea92f7ab37a96e5f5c307d023fee5eae1f4 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 04:07:38 -0800 Subject: [PATCH 076/121] m o r e --- code/modules/events/anomaly_bluespace.dm | 1 + code/modules/events/anomaly_flux.dm | 1 + code/modules/events/anomaly_grav.dm | 2 ++ code/modules/events/anomaly_pyro.dm | 1 + code/modules/events/anomaly_vortex.dm | 1 + code/modules/events/brand_intelligence.dm | 1 + code/modules/events/carp_migration.dm | 1 + code/modules/events/communications_blackout.dm | 1 + code/modules/events/dust.dm | 1 + code/modules/events/electrical_storm.dm | 1 + code/modules/events/heart_attack.dm | 1 + code/modules/events/radiation_storm.dm | 1 + 12 files changed, 13 insertions(+) diff --git a/code/modules/events/anomaly_bluespace.dm b/code/modules/events/anomaly_bluespace.dm index 8fc1a7ab3d..bb9f319c6b 100644 --- a/code/modules/events/anomaly_bluespace.dm +++ b/code/modules/events/anomaly_bluespace.dm @@ -3,6 +3,7 @@ typepath = /datum/round_event/anomaly/anomaly_bluespace max_occurrences = 1 weight = 5 + gamemode_blacklist = list("dynamic") /datum/round_event/anomaly/anomaly_bluespace startWhen = 3 diff --git a/code/modules/events/anomaly_flux.dm b/code/modules/events/anomaly_flux.dm index 73562e49e5..63e4b087e7 100644 --- a/code/modules/events/anomaly_flux.dm +++ b/code/modules/events/anomaly_flux.dm @@ -5,6 +5,7 @@ min_players = 10 max_occurrences = 5 weight = 20 + gamemode_blacklist = list("dynamic") /datum/round_event/anomaly/anomaly_flux startWhen = 10 diff --git a/code/modules/events/anomaly_grav.dm b/code/modules/events/anomaly_grav.dm index 6e9014f13c..fa327700f2 100644 --- a/code/modules/events/anomaly_grav.dm +++ b/code/modules/events/anomaly_grav.dm @@ -3,6 +3,8 @@ typepath = /datum/round_event/anomaly/anomaly_grav max_occurrences = 5 weight = 20 + gamemode_blacklist = list("dynamic") + /datum/round_event/anomaly/anomaly_grav startWhen = 3 diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm index 988ccadb76..cee7f7a224 100644 --- a/code/modules/events/anomaly_pyro.dm +++ b/code/modules/events/anomaly_pyro.dm @@ -3,6 +3,7 @@ typepath = /datum/round_event/anomaly/anomaly_pyro max_occurrences = 5 weight = 20 + gamemode_blacklist = list("dynamic") /datum/round_event/anomaly/anomaly_pyro startWhen = 3 diff --git a/code/modules/events/anomaly_vortex.dm b/code/modules/events/anomaly_vortex.dm index 2550dc191e..b46852ad4f 100644 --- a/code/modules/events/anomaly_vortex.dm +++ b/code/modules/events/anomaly_vortex.dm @@ -5,6 +5,7 @@ min_players = 20 max_occurrences = 2 weight = 5 + gamemode_blacklist = list("dynamic") /datum/round_event/anomaly/anomaly_vortex startWhen = 10 diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index d422a0aa4f..ce4ac9c0d4 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -5,6 +5,7 @@ min_players = 15 max_occurrences = 1 + gamemode_blacklist = list("dynamic") /datum/round_event/brand_intelligence announceWhen = 21 diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index 5a592d7f34..69af30ca6d 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -5,6 +5,7 @@ min_players = 2 earliest_start = 10 MINUTES max_occurrences = 6 + gamemode_blacklist = list("dynamic") /datum/round_event/carp_migration announceWhen = 3 diff --git a/code/modules/events/communications_blackout.dm b/code/modules/events/communications_blackout.dm index da4eff9f39..ccd519b7e1 100644 --- a/code/modules/events/communications_blackout.dm +++ b/code/modules/events/communications_blackout.dm @@ -2,6 +2,7 @@ name = "Communications Blackout" typepath = /datum/round_event/communications_blackout weight = 30 + gamemode_blacklist = list("dynamic") /datum/round_event/communications_blackout announceWhen = 1 diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm index c22f8cc0d7..090dc95cd6 100644 --- a/code/modules/events/dust.dm +++ b/code/modules/events/dust.dm @@ -5,6 +5,7 @@ max_occurrences = 1000 earliest_start = 0 MINUTES alertadmins = 0 + gamemode_blacklist = list("dynamic") /datum/round_event/space_dust startWhen = 1 diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm index 10936409f9..affbb419df 100644 --- a/code/modules/events/electrical_storm.dm +++ b/code/modules/events/electrical_storm.dm @@ -5,6 +5,7 @@ min_players = 5 weight = 40 alertadmins = 0 + gamemode_blacklist = list("dynamic") /datum/round_event/electrical_storm var/lightsoutAmount = 1 diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm index 7f9c09dfd9..8db2d98bf0 100644 --- a/code/modules/events/heart_attack.dm +++ b/code/modules/events/heart_attack.dm @@ -4,6 +4,7 @@ weight = 20 max_occurrences = 2 min_players = 40 // To avoid shafting lowpop + gamemode_blacklist = list("dynamic") /datum/round_event/heart_attack/start() var/list/heart_attack_contestants = list() diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 60e4e0e4b8..705eea5409 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -2,6 +2,7 @@ name = "Radiation Storm" typepath = /datum/round_event/radiation_storm max_occurrences = 1 + gamemode_blacklist = list("dynamic") /datum/round_event/radiation_storm From f1801b9531e25eda8f23840bc969e933af024216 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 04:07:48 -0800 Subject: [PATCH 077/121] also pirates --- .../dynamic/dynamic_rulesets_midround.dm | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index cbb2ee61b6..9864ca894c 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -723,6 +723,22 @@ log_game("[key_name(Ninja)] was spawned as a ninja by dynamic.") return Ninja +/datum/dynamic_ruleset/midround/event/pirates + name = "Pirates" + config_tag = "pirates" + typepath = /datum/round_event/pirates + enemy_roles = list("AI","Security Officer","Head of Security","Captain") + required_enemies = list(2,2,1,1,0,0,0,0,0,0) + weight = 5 + cost = 10 + requirements = list(70,60,50,50,40,40,40,30,20,15) + high_population_requirement = 15 + +/datum/dynamic_ruleset/midround/event/pirates/ready(forced = FALSE) + if (!SSmapping.empty_space) + return FALSE + return ..() + ////////////////////////////////////////////// // // // SPIDERS // @@ -829,5 +845,162 @@ high_population_requirement = 50 repeatable = TRUE +////////////////////////////////////////////// +// // +// ANOMALIES // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/midround/event/anomaly_bluespace + name = "Anomaly: Bluespace" + config_tag = "anomaly_bluespace" + typepath = /datum/round_event/anomaly/anomaly_bluespace + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + cost = 3 + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/anomaly_flux + name = "Anomaly: Hyper-Energetic Flux" + config_tag = "anomaly_flux" + typepath = /datum/round_event/anomaly/anomaly_flux + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + cost = 5 + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/anomaly_gravitational + name = "Anomaly: Gravitational" + config_tag = "anomaly_gravitational" + typepath = /datum/round_event/anomaly/anomaly_grav + cost = 3 + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/anomaly_pyroclastic + name = "Anomaly: Pyroclastic" + config_tag = "anomaly_pyroclastic" + typepath = /datum/round_event/anomaly/anomaly_pyro + cost = 5 + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") + required_enemies = list(1,1,1,1,1,1,1,1,1,1) + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/anomaly_vortex + name = "Anomaly: Vortex" + config_tag = "anomaly_vortex" + typepath = /datum/round_event/anomaly/anomaly_vortex + cost = 5 + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") + required_enemies = list(1,1,1,1,1,1,1,1,1,1) + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/brand_intelligence + name = "Brand Intelligence" + config_tag = "brand_intelligence" + typepath = /datum/round_event/anomaly/anomaly_vortex + cost = 5 + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") + required_enemies = list(1,1,1,1,1,1,1,1,1,1) + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/carp_migration + name = "Carp Migration" + config_tag = "carp_migration" + typepath = /datum/round_event/carp_migration + cost = 5 + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") + required_enemies = list(1,1,1,1,1,1,1,1,1,1) + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/communications_blackout + name = "Communications Blackout" + config_tag = "communications_blackout" + typepath = /datum/round_event/communications_blackout + cost = 5 + enemy_roles = list("Chief Engineer","Station Engineer") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/processor_overload + name = "Processer Overload" + config_tag = "processor_overload" + typepath = /datum/round_event/processor_overload + cost = 5 + enemy_roles = list("Chief Engineer","Station Engineer") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/space_dust + name = "Minor Space Dust" + config_tag = "space_dust" + typepath = /datum/round_event/space_dust + cost = 3 + enemy_roles = list("Chief Engineer","Station Engineer") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/major_dust + name = "Major Space Dust" + config_tag = "major_dust" + typepath = /datum/round_event/meteor_wave/major_dust + cost = 10 + enemy_roles = list("Chief Engineer","Station Engineer") + required_enemies = list(2,2,2,2,2,2,2,2,2,2) + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/electrical_storm + name = "Electrical Storm" + config_tag = "electrical_storm" + typepath = /datum/round_event/electrical_storm + cost = 1 + enemy_roles = list("Chief Engineer","Station Engineer") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/heart_attack + name = "Random Heart Attack" + config_tag = "heart_attack" + typepath = /datum/round_event/heart_attack + cost = 1 + enemy_roles = list("Medical Doctor","Chief Medical Officer") + required_enemies = list(2,2,2,2,2,2,2,2,2,2) + requirements = list(101,101,101,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/midround/event/radiation_storm + name = "Radiation Storm" + config_tag = "heart_attack" + typepath = /datum/round_event/radiation_storm + cost = 3 + enemy_roles = list("Chemist","Chief Medical Officer","Geneticist","Medical Doctor","AI","Captain") + required_enemies = list(1,1,1,1,1,1,1,1,1,1) + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + #undef ABDUCTOR_MAX_TEAMS #undef REVENANT_SPAWN_THRESHOLD From 48761a9889bfd69feeb9e808615ea5c8b3e947e6 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 04:19:49 -0800 Subject: [PATCH 078/121] aaa config --- .../dynamic/dynamic_rulesets_midround.dm | 26 ++--- config/dynamic_config.txt | 98 +++++++++++++++---- 2 files changed, 94 insertions(+), 30 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 9864ca894c..512420f3b1 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -869,7 +869,7 @@ enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain") required_enemies = list(1,1,1,0,0,0,0,0,0,0) cost = 5 - requirements = list(10,10,10,10,10,10,10,10,10,10) + requirements = list(5,5,5,5,5,5,5,5,5,5) high_population_requirement = 10 repeatable = TRUE @@ -904,13 +904,19 @@ high_population_requirement = 10 repeatable = TRUE +////////////////////////////////////////////// +// // +// WOW THAT'S A LOT OF EVENTS // +// // +////////////////////////////////////////////// + /datum/dynamic_ruleset/midround/event/brand_intelligence name = "Brand Intelligence" config_tag = "brand_intelligence" - typepath = /datum/round_event/anomaly/anomaly_vortex - cost = 5 + typepath = /datum/round_event/brand_intelligence + cost = 2 enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") - required_enemies = list(1,1,1,1,1,1,1,1,1,1) + required_enemies = list(1,1,1,1,0,0,0,0,0,0) requirements = list(10,10,10,10,10,10,10,10,10,10) high_population_requirement = 10 repeatable = TRUE @@ -919,9 +925,7 @@ name = "Carp Migration" config_tag = "carp_migration" typepath = /datum/round_event/carp_migration - cost = 5 - enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") - required_enemies = list(1,1,1,1,1,1,1,1,1,1) + cost = 4 requirements = list(10,10,10,10,10,10,10,10,10,10) high_population_requirement = 10 repeatable = TRUE @@ -930,7 +934,7 @@ name = "Communications Blackout" config_tag = "communications_blackout" typepath = /datum/round_event/communications_blackout - cost = 5 + cost = 4 enemy_roles = list("Chief Engineer","Station Engineer") required_enemies = list(1,1,1,0,0,0,0,0,0,0) requirements = list(5,5,5,5,5,5,5,5,5,5) @@ -941,7 +945,7 @@ name = "Processer Overload" config_tag = "processor_overload" typepath = /datum/round_event/processor_overload - cost = 5 + cost = 4 enemy_roles = list("Chief Engineer","Station Engineer") required_enemies = list(1,1,1,0,0,0,0,0,0,0) requirements = list(5,5,5,5,5,5,5,5,5,5) @@ -985,7 +989,7 @@ name = "Random Heart Attack" config_tag = "heart_attack" typepath = /datum/round_event/heart_attack - cost = 1 + cost = 3 enemy_roles = list("Medical Doctor","Chief Medical Officer") required_enemies = list(2,2,2,2,2,2,2,2,2,2) requirements = list(101,101,101,5,5,5,5,5,5,5) @@ -994,7 +998,7 @@ /datum/dynamic_ruleset/midround/event/radiation_storm name = "Radiation Storm" - config_tag = "heart_attack" + config_tag = "radiation_storm" typepath = /datum/round_event/radiation_storm cost = 3 enemy_roles = list("Chemist","Chief Medical Officer","Geneticist","Medical Doctor","AI","Captain") diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index a03bf238b8..953b761e5b 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -53,22 +53,37 @@ DYNAMIC_WEIGHT MIDROUND_TRAITOR 3 DYNAMIC_WEIGHT MIDROUND_MALF_AI 2 DYNAMIC_WEIGHT MIDROUND_WIZARD 1 DYNAMIC_WEIGHT MIDROUND_NUCLEAR 1 -DYNAMIC_WEIGHT BLOB 3 -DYNAMIC_WEIGHT XENOS 3 +DYNAMIC_WEIGHT BLOB 2 +DYNAMIC_WEIGHT XENOS 2 DYNAMIC_WEIGHT NIGHTMARE 3 DYNAMIC_WEIGHT SENTIENT_DISEASE 6 DYNAMIC_WEIGHT REVENANT 3 -DYNAMIC_WEIGHT SLAUGHTER_DEMON 2 +DYNAMIC_WEIGHT SLAUGHTER_DEMON 1 DYNAMIC_WEIGHT ABDUCTORS 8 -DYNAMIC_WEIGHT SPACE_NINJA 3 +DYNAMIC_WEIGHT SPACE_NINJA 2 DYNAMIC_WEIGHT SPIDERS 5 -DYNAMIC_WEIGHT VENTCLOG_NORMAL 7 +DYNAMIC_WEIGHT VENTCLOG_NORMAL 5 DYNAMIC_WEIGHT VENTCLOG_THREATENING 5 -DYNAMIC_WEIGHT VENTCLOG_CATASTROPHIC 3 +DYNAMIC_WEIGHT VENTCLOG_CATASTROPHIC 5 DYNAMIC_WEIGHT ION_STORM 4 DYNAMIC_WEIGHT METEOR_WAVE_NORMAL 3 DYNAMIC_WEIGHT METEOR_WAVE_THREATENING 2 DYNAMIC_WEIGHT METEOR_WAVE_CATASTROPHIC 1 +DYNAMIC_WEIGHT PIRATES 2 +DYNAMIC_WEIGHT ANOMALY_BLUESPACE 7 +DYNAMIC_WEIGHT ANOMALY_FLUX 7 +DYNAMIC_WEIGHT ANOMALY_GRAVITATIONAL 7 +DYNAMIC_WEIGHT ANOMALY_PYROCLASTIC 7 +DYNAMIC_WEIGHT ANOMALY_VORTEX 7 +DYNAMIC_WEIGHT BRAND_INTELLIGENCE 3 +DYNAMIC_WEIGHT CARP_MIGRATION 7 +DYNAMIC_WEIGHT COMMUNICATIONS_BLACKOUT 6 +DYNAMIC_WEIGHT PROCESSOR_OVERLOAD 6 +DYNAMIC_WEIGHT SPACE_DUST 5 +DYNAMIC_WEIGHT MAJOR_DUST 2 +DYNAMIC_WEIGHT ELECTRICAL_STORM 8 +DYNAMIC_WEIGHT HEART_ATTACK 8 +DYNAMIC_WEIGHT RADIATION_STORM 5 ## Latejoin antags DYNAMIC_WEIGHT LATEJOIN_TRAITOR 7 @@ -112,6 +127,21 @@ DYNAMIC_COST ION_STORM 3 DYNAMIC_COST METEOR_WAVE_NORMAL 15 DYNAMIC_COST METEOR_WAVE_THREATENING 25 DYNAMIC_COST METEOR_WAVE_CATASTROPHIC 40 +DYNAMIC_COST PIRATES 10 +DYNAMIC_COST ANOMALY_BLUESPACE 3 +DYNAMIC_COST ANOMALY_FLUX 2 +DYNAMIC_COST ANOMALY_GRAVITATIONAL 3 +DYNAMIC_COST ANOMALY_PYROCLASTIC 5 +DYNAMIC_COST ANOMALY_VORTEX 5 +DYNAMIC_COST BRAND_INTELLIGENCE 5 +DYNAMIC_COST CARP_MIGRATION 3 +DYNAMIC_COST COMMUNICATIONS_BLACKOUT 5 +DYNAMIC_COST PROCESSOR_OVERLOAD 5 +DYNAMIC_COST SPACE_DUST 5 +DYNAMIC_COST MAJOR_DUST 10 +DYNAMIC_COST ELECTRICAL_STORM 1 +DYNAMIC_COST HEART_ATTACK 1 +DYNAMIC_COST RADIATION_STORM 3 ## Latejoin antags DYNAMIC_COST LATEJOIN_TRAITOR 5 @@ -157,6 +187,21 @@ DYNAMIC_REQUIREMENTS ION_STORM 5 5 5 5 5 5 5 5 5 5 DYNAMIC_REQUIREMENTS METEOR_WAVE_NORMAL 60 50 40 30 30 30 30 30 30 30 DYNAMIC_REQUIREMENTS METEOR_WAVE_THREATENING 80 70 60 50 40 40 40 40 40 40 DYNAMIC_REQUIREMENTS METEOR_WAVE_CATASTROPHIC 101 100 90 80 70 60 50 50 50 50 +DYNAMIC_REQUIREMENTS PIRATES 70 60 50 50 40 40 40 30 20 15 +DYNAMIC_REQUIREMENTS ANOMALY_BLUESPACE 5 5 5 5 5 5 5 5 5 5 +DYNAMIC_REQUIREMENTS ANOMALY_FLUX 5 5 5 5 5 5 5 5 5 5 +DYNAMIC_REQUIREMENTS ANOMALY_GRAVITATIONAL 5 5 5 5 5 5 5 5 5 5 +DYNAMIC_REQUIREMENTS ANOMALY_PYROCLASTIC 10 10 10 10 10 10 10 10 10 10 +DYNAMIC_REQUIREMENTS ANOMALY_VORTEX 10 10 10 10 10 10 10 10 10 10 +DYNAMIC_REQUIREMENTS BRAND_INTELLIGENCE 10 10 10 10 10 10 10 10 10 10 +DYNAMIC_REQUIREMENTS CARP_MIGRATION 10 10 10 10 10 10 10 10 10 10 +DYNAMIC_REQUIREMENTS COMMUNICATIONS_BLACKOUT 5 5 5 5 5 5 5 5 5 5 +DYNAMIC_REQUIREMENTS PROCESSOR_OVERLOAD 5 5 5 5 5 5 5 5 5 5 +DYNAMIC_REQUIREMENTS SPACE_DUST 5 5 5 5 5 5 5 5 5 5 +DYNAMIC_REQUIREMENTS MAJOR_DUST 10 10 10 10 10 10 10 10 10 10 +DYNAMIC_REQUIREMENTS ELECTRICAL_STORM 5 5 5 5 5 5 5 5 5 5 +DYNAMIC_REQUIREMENTS HEART_ATTACK 5 5 5 5 5 5 5 5 5 5 +DYNAMIC_REQUIREMENTS RADIATION_STORM 5 5 5 5 5 5 5 5 5 5 ## Latejoin antags DYNAMIC_REQUIREMENTS LATEJOIN_TRAITOR 40 30 20 15 15 15 15 15 15 15 @@ -187,19 +232,34 @@ DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 35 DYNAMIC_HIGH_POPULATION_REQUIREMENT BLOB 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT XENOS 50 DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 15 -DYNAMIC_REQUIREMENTS SENTIENT_DISEASE 5 -DYNAMIC_REQUIREMENTS REVENANT 15 -DYNAMIC_REQUIREMENTS SLAUGHTER_DEMON 30 -DYNAMIC_REQUIREMENTS ABDUCTORS 15 -DYNAMIC_REQUIREMENTS SPACE_NINJA 30 -DYNAMIC_REQUIREMENTS SPIDERS 15 -DYNAMIC_REQUIREMENTS VENTCLOG_NORMAL 5 -DYNAMIC_REQUIREMENTS VENTCLOG_THREATENING 15 -DYNAMIC_REQUIREMENTS VENTCLOG_CATASTROPHIC 30 -DYNAMIC_REQUIREMENTS ION_STORM 5 -DYNAMIC_REQUIREMENTS METEOR_WAVE_NORMAL 30 -DYNAMIC_REQUIREMENTS METEOR_WAVE_THREATENING 40 -DYNAMIC_REQUIREMENTS METEOR_WAVE_CATASTROPHIC 50 +DYNAMIC_HIGH_POPULATION_REQUIREMENT SENTIENT_DISEASE 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT REVENANT 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT SLAUGHTER_DEMON 30 +DYNAMIC_HIGH_POPULATION_REQUIREMENT ABDUCTORS 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT SPACE_NINJA 30 +DYNAMIC_HIGH_POPULATION_REQUIREMENT SPIDERS 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT VENTCLOG_NORMAL 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT VENTCLOG_THREATENING 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT VENTCLOG_CATASTROPHIC 30 +DYNAMIC_HIGH_POPULATION_REQUIREMENT ION_STORM 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR_WAVE_NORMAL 30 +DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR_WAVE_THREATENING 40 +DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR_WAVE_CATASTROPHIC 50 +DYNAMIC_HIGH_POPULATION_REQUIREMENT PIRATES 15 +DYNAMIC_HIGH_POPULATION_REQUIREMENT ANOMALY_BLUESPACE 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT ANOMALY_FLUX 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT ANOMALY_GRAVITATIONAL 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT ANOMALY_PYROCLASTIC 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT ANOMALY_VORTEX 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT BRAND_INTELLIGENCE 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT CARP_MIGRATION 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT COMMUNICATIONS_BLACKOUT 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT PROCESSOR_OVERLOAD 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT SPACE_DUST 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT MAJOR_DUST 10 +DYNAMIC_HIGH_POPULATION_REQUIREMENT ELECTRICAL_STORM 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT HEART_ATTACK 5 +DYNAMIC_HIGH_POPULATION_REQUIREMENT RADIATION_STORM 5 ## Latejoin antags DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 15 From 6de835f5e3622448212d4540cf29163ca5b94207 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 04:39:14 -0800 Subject: [PATCH 079/121] Assassination is less likely at lower threats. --- code/controllers/configuration/entries/dynamic.dm | 3 +++ code/modules/antagonists/traitor/datum_traitor.dm | 13 ++++++++++++- config/dynamic_config.txt | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 6c8c9ff5a9..a59f3a6954 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -78,6 +78,9 @@ /datum/config_entry/number/dynamic_glorious_death_cost config_entry_value = 5 +/datum/config_entry/number/dynamic_assassinate_cost + config_entry_value = 2 + /datum/config_entry/number/dynamic_summon_guns_requirement config_entry_value = 10 min_val = 0 diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 9a3aa19377..7eb60d27b9 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -159,7 +159,18 @@ /datum/antagonist/traitor/proc/forge_single_human_objective() //Returns how many objectives are added .=1 - if(prob(50)) + var/assassin_prob = 50 + var/is_dynamic = FALSE + var/datum/game_mode/dynamic/mode + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + mode = SSticker.mode + is_dynamic = TRUE + assassin_prob = mode.threat_level*(2/3) + if(prob(assassin_prob)) + if(is_dynamic) + var/threat_spent = CONFIG_GET(number/dynamic_assassinate_cost) + spend_threat(threat_spent) + mode.log_threat("[owner.name] spent [threat_spent] on an assassination target.") var/list/active_ais = active_ais() if(active_ais.len && prob(100/GLOB.joined_player_list.len)) var/datum/objective/destroy/destroy_objective = new diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 953b761e5b..e62bc38059 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -276,6 +276,8 @@ DYNAMIC_HIJACK_COST 10 DYNAMIC_GLORIOUS_DEATH_COST 5 +DYNAMIC_ASSASSINATE_COST 2 + ## Dynamic wizard stuff ## How much threat level is required to buy summon guns. Setting to 0 makes it always available. From fdcc4af3032f72714ba80d3563f86c59d3cd1744 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 04:40:25 -0800 Subject: [PATCH 080/121] mm, yes, compile BEFORE committing --- code/modules/antagonists/traitor/datum_traitor.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 7eb60d27b9..39e6617099 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -169,7 +169,7 @@ if(prob(assassin_prob)) if(is_dynamic) var/threat_spent = CONFIG_GET(number/dynamic_assassinate_cost) - spend_threat(threat_spent) + mode.spend_threat(threat_spent) mode.log_threat("[owner.name] spent [threat_spent] on an assassination target.") var/list/active_ais = active_ais() if(active_ais.len && prob(100/GLOB.joined_player_list.len)) From 3c39fc4df97a14c1602e3fdf52e2de25392068ab Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 14:52:47 -0800 Subject: [PATCH 081/121] i overtuned it. time to go back down --- .../gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 8 ++++---- config/dynamic_config.txt | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index fe8b54775f..12aad6c484 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -58,7 +58,7 @@ required_candidates = 1 weight = 1 cost = 35 - requirements = list(101,101,101,101,101,100,90,80,70,60) + requirements = list(101,101,101,100,90,80,70,60,50,50) high_population_requirement = 50 required_type = /mob/living/silicon/ai var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) @@ -215,7 +215,7 @@ required_candidates = 1 weight = 1 cost = 30 - requirements = list(101,101,101,100,90,80,70,60,50,50) + requirements = list(101,101,101,60,50,50,50,50,50,50) high_population_requirement = 50 var/list/roundstart_wizards = list() @@ -322,7 +322,7 @@ required_candidates = 5 weight = 3 cost = 40 - requirements = list(101,101,101,100,90,80,70,60,50,50) + requirements = list(100,90,80,70,60,50,50,50,50,50) high_population_requirement = 50 flags = HIGHLANDER_RULESET var/operative_cap = list(2,2,2,3,3,3,4,4,5,5) @@ -412,7 +412,7 @@ required_candidates = 3 weight = 2 cost = 35 - requirements = list(101,101,101,100,90,80,70,60,50,50) + requirements = list(101,101,101,80,70,60,50,50,50,50) high_population_requirement = 50 delay = 5 MINUTES flags = HIGHLANDER_RULESET diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index e62bc38059..09a28dcd87 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -150,14 +150,14 @@ DYNAMIC_COST LATEJOIN_REVOLUTION 20 ## Rule will not be generated with threat levels below requirement at a pop value. Pop values are determined by dynamic's pop-per-requirement. ## By default it's 0-8, 9-17, 18-26, 27-35, 36-44, 45-53, 54-60, 61-69, 70-78, 79+. ## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-8, 30 at 9-17 etc. -DYNAMIC_REQUIREMENTS TRAITOR 101 101 100 90 80 70 60 50 50 50 +DYNAMIC_REQUIREMENTS TRAITOR 50 50 50 50 50 50 50 50 50 50 DYNAMIC_REQUIREMENTS TRAITORBRO 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS MALF_AI 101 101 101 101 101 100 90 80 70 60 +DYNAMIC_REQUIREMENTS MALF_AI 101 101 101 100 90 80 70 60 50 50 DYNAMIC_REQUIREMENTS CHANGELING 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS WIZARD 101 101 101 100 90 80 70 60 50 50 +DYNAMIC_REQUIREMENTS WIZARD 101 101 101 60 50 50 50 50 50 50 DYNAMIC_REQUIREMENTS CULT 101 101 101 100 90 80 70 60 50 50 -DYNAMIC_REQUIREMENTS NUCLEAR 101 101 101 100 90 80 70 60 50 50 -DYNAMIC_REQUIREMENTS REVOLUTION 101 101 101 101 100 90 80 70 60 50 +DYNAMIC_REQUIREMENTS NUCLEAR 101 101 101 70 60 50 50 50 50 50 +DYNAMIC_REQUIREMENTS REVOLUTION 101 101 101 80 70 60 50 50 50 50 # All below are impossible-by-default DYNAMIC_REQUIREMENTS EXTENDED 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 101 101 101 100 90 80 70 60 50 50 From 392e628f3f674e17fbe0651b3a8bd1a9ae7f8a54 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 14:58:38 -0800 Subject: [PATCH 082/121] lowered maximum curve width a good deal --- code/controllers/subsystem/vote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 37bc84a401..a4544c6572 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -172,7 +172,7 @@ SUBSYSTEM_DEF(vote) if(voted.len != 0) mean += (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 - GLOB.dynamic_curve_width = CLAMP(4-abs(mean*10),0.5,4) + GLOB.dynamic_curve_width = CLAMP(3-abs(mean*10),0.5,4) to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") From 139e9a9da87c9d13f2c417a862730bcd4a9f08a1 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 16:03:40 -0800 Subject: [PATCH 083/121] reobfuscates dynamic vote --- code/controllers/subsystem/ticker.dm | 2 +- code/controllers/subsystem/vote.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 0b8edef1ad..6f619fef0b 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -480,7 +480,7 @@ SUBSYSTEM_DEF(ticker) SSticker.timeLeft = 900 SSticker.modevoted = TRUE var/dynamic = CONFIG_GET(flag/dynamic_voting) - SSvote.initiate_vote(dynamic ? "dynamic" : "roundtype","server",!dynamic) + SSvote.initiate_vote(dynamic ? "dynamic" : "roundtype","server",TRUE) /datum/controller/subsystem/ticker/Recover() current_state = SSticker.current_state diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index a4544c6572..a4634622c9 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -173,7 +173,7 @@ SUBSYSTEM_DEF(vote) mean += (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 GLOB.dynamic_curve_width = CLAMP(3-abs(mean*10),0.5,4) - to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") + message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") var/datum/map_config/VM = config.maplist[.] From b5c58ec1d81dfaa747e3645173c0f563df0bae25 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 16:56:31 -0800 Subject: [PATCH 084/121] Weighted antags higher, made zero-antag midround injection chance higher --- code/game/gamemodes/dynamic/dynamic.dm | 2 +- config/dynamic_config.txt | 56 +++++++++++++------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index e872ee1915..5a6250662e 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -676,7 +676,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/high_pop_factor = (current_players[CURRENT_LIVING_PLAYERS].len >= GLOB.dynamic_high_pop_limit) var/max_pop_per_antag = max(5,15 - round(threat_level/10) - round(current_players[CURRENT_LIVING_PLAYERS].len/(high_pop_factor ? 10 : 5))) if (!current_players[CURRENT_LIVING_ANTAGS].len) - chance += 50 // No antags at all? let's boost those odds! + chance += 80 // No antags at all? let's boost those odds! else var/current_pop_per_antag = current_players[CURRENT_LIVING_PLAYERS].len / current_players[CURRENT_LIVING_ANTAGS].len if (current_pop_per_antag > max_pop_per_antag) diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 09a28dcd87..df9acef64b 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -49,41 +49,41 @@ DYNAMIC_WEIGHT MONKEY 3 DYNAMIC_WEIGHT METEOR 3 ## Midround antags -DYNAMIC_WEIGHT MIDROUND_TRAITOR 3 -DYNAMIC_WEIGHT MIDROUND_MALF_AI 2 -DYNAMIC_WEIGHT MIDROUND_WIZARD 1 -DYNAMIC_WEIGHT MIDROUND_NUCLEAR 1 -DYNAMIC_WEIGHT BLOB 2 -DYNAMIC_WEIGHT XENOS 2 -DYNAMIC_WEIGHT NIGHTMARE 3 +DYNAMIC_WEIGHT MIDROUND_TRAITOR 7 +DYNAMIC_WEIGHT MIDROUND_MALF_AI 8 +DYNAMIC_WEIGHT MIDROUND_WIZARD 9 +DYNAMIC_WEIGHT MIDROUND_NUCLEAR 9 +DYNAMIC_WEIGHT BLOB 8 +DYNAMIC_WEIGHT XENOS 8 +DYNAMIC_WEIGHT NIGHTMARE 8 DYNAMIC_WEIGHT SENTIENT_DISEASE 6 -DYNAMIC_WEIGHT REVENANT 3 -DYNAMIC_WEIGHT SLAUGHTER_DEMON 1 +DYNAMIC_WEIGHT REVENANT 6 +DYNAMIC_WEIGHT SLAUGHTER_DEMON 4 DYNAMIC_WEIGHT ABDUCTORS 8 -DYNAMIC_WEIGHT SPACE_NINJA 2 +DYNAMIC_WEIGHT SPACE_NINJA 8 DYNAMIC_WEIGHT SPIDERS 5 -DYNAMIC_WEIGHT VENTCLOG_NORMAL 5 -DYNAMIC_WEIGHT VENTCLOG_THREATENING 5 -DYNAMIC_WEIGHT VENTCLOG_CATASTROPHIC 5 -DYNAMIC_WEIGHT ION_STORM 4 +DYNAMIC_WEIGHT VENTCLOG_NORMAL 3 +DYNAMIC_WEIGHT VENTCLOG_THREATENING 3 +DYNAMIC_WEIGHT VENTCLOG_CATASTROPHIC 3 +DYNAMIC_WEIGHT ION_STORM 7 DYNAMIC_WEIGHT METEOR_WAVE_NORMAL 3 DYNAMIC_WEIGHT METEOR_WAVE_THREATENING 2 DYNAMIC_WEIGHT METEOR_WAVE_CATASTROPHIC 1 -DYNAMIC_WEIGHT PIRATES 2 -DYNAMIC_WEIGHT ANOMALY_BLUESPACE 7 -DYNAMIC_WEIGHT ANOMALY_FLUX 7 -DYNAMIC_WEIGHT ANOMALY_GRAVITATIONAL 7 -DYNAMIC_WEIGHT ANOMALY_PYROCLASTIC 7 -DYNAMIC_WEIGHT ANOMALY_VORTEX 7 -DYNAMIC_WEIGHT BRAND_INTELLIGENCE 3 +DYNAMIC_WEIGHT PIRATES 8 +DYNAMIC_WEIGHT ANOMALY_BLUESPACE 2 +DYNAMIC_WEIGHT ANOMALY_FLUX 2 +DYNAMIC_WEIGHT ANOMALY_GRAVITATIONAL 2 +DYNAMIC_WEIGHT ANOMALY_PYROCLASTIC 2 +DYNAMIC_WEIGHT ANOMALY_VORTEX 2 +DYNAMIC_WEIGHT BRAND_INTELLIGENCE 1 DYNAMIC_WEIGHT CARP_MIGRATION 7 -DYNAMIC_WEIGHT COMMUNICATIONS_BLACKOUT 6 -DYNAMIC_WEIGHT PROCESSOR_OVERLOAD 6 -DYNAMIC_WEIGHT SPACE_DUST 5 -DYNAMIC_WEIGHT MAJOR_DUST 2 -DYNAMIC_WEIGHT ELECTRICAL_STORM 8 -DYNAMIC_WEIGHT HEART_ATTACK 8 -DYNAMIC_WEIGHT RADIATION_STORM 5 +DYNAMIC_WEIGHT COMMUNICATIONS_BLACKOUT 2 +DYNAMIC_WEIGHT PROCESSOR_OVERLOAD 2 +DYNAMIC_WEIGHT SPACE_DUST 2 +DYNAMIC_WEIGHT MAJOR_DUST 1 +DYNAMIC_WEIGHT ELECTRICAL_STORM 2 +DYNAMIC_WEIGHT HEART_ATTACK 2 +DYNAMIC_WEIGHT RADIATION_STORM 1 ## Latejoin antags DYNAMIC_WEIGHT LATEJOIN_TRAITOR 7 From d78bc94b4930017a7ec5b9a2235c52be96c0ec4b Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 17:34:01 -0800 Subject: [PATCH 085/121] Better logging of why-no-roundstart --- code/game/gamemodes/dynamic/dynamic.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 5a6250662e..07ec3432fa 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -403,7 +403,9 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) rule.trim_candidates() if (rule.ready() && rule.candidates.len > 0) drafted_rules[rule] = rule.weight - + if(!drafted_rules.len) + message_admins("Not enough threat level for roundstart antags!") + log_game("DYNAMIC: Not enough threat level for roundstart antags!") var/indice_pop = min(10,round(roundstart_pop_ready/pop_per_requirement)+1) var/extra_rulesets_amount = 0 if (GLOB.dynamic_classic_secret) From 57fbad5d4128ef6230ac4deb11d02000bcfacb2f Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 9 Nov 2019 21:29:09 -0800 Subject: [PATCH 086/121] forces antag if all antags are dead --- code/game/gamemodes/dynamic/dynamic.dm | 5 ++++- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 07ec3432fa..ab62a08cb1 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -632,8 +632,11 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if (prob(get_injection_chance())) var/list/drafted_rules = list() + var/antag_num = current_players[CURRENT_LIVING_ANTAGS].len for (var/datum/dynamic_ruleset/midround/rule in midround_rules) - if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost) + var/antag_acceptable = (antag_num || !isnull(rule.antag_flag)) + // if there are antags OR the rule is an antag rule, antag_acceptable will be true. + if (antag_acceptable && rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost) // Classic secret : only autotraitor/minor roles if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET))) continue diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 512420f3b1..e823a364ae 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -724,9 +724,10 @@ return Ninja /datum/dynamic_ruleset/midround/event/pirates - name = "Pirates" + name = "Space Pirates" config_tag = "pirates" typepath = /datum/round_event/pirates + antag_flag = ROLE_TRAITOR enemy_roles = list("AI","Security Officer","Head of Security","Captain") required_enemies = list(2,2,1,1,0,0,0,0,0,0) weight = 5 From 3ddbee88786a3e84a6a94ae90a4d12e4fd514201 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sun, 10 Nov 2019 06:30:47 +0100 Subject: [PATCH 087/121] Initial stuff. --- code/game/gamemodes/dynamic/dynamic.dm | 64 ++++++----------- .../gamemodes/dynamic/dynamic_rulesets.dm | 57 ++++----------- .../dynamic/dynamic_rulesets_latejoin.dm | 11 ++- .../dynamic/dynamic_rulesets_midround.dm | 34 ++++----- .../dynamic/dynamic_rulesets_roundstart.dm | 70 ++++++++----------- 5 files changed, 87 insertions(+), 149 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index ca009f76ad..473e2ae4a5 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -118,7 +118,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) /datum/game_mode/dynamic/admin_panel() var/list/dat = list("Game Mode Panel

Game Mode Panel

") - dat += "Dynamic Mode \[VV\]
" + dat += "Dynamic Mode \[VV\]\[Refresh\]
" dat += "Threat Level: [threat_level]
" dat += "Threat to Spend: [threat] \[Adjust\] \[View Log\]
" @@ -273,15 +273,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) threat = threat_level /datum/game_mode/dynamic/can_start() - /* Disabled for now, had some changes that need to be tested and this might interfere with that. - if(GLOB.dynamic_curve_centre == 0) - // 10 is when the centre starts to decrease - // 6 is just 1 + 5 (from the maximum value and the one decreased) - // 1 just makes the curve look better, I don't know. - // Limited between 1 and 5 then inverted and rounded - // With this you get a centre curve that stays at -5 until 10 then first rapidly decreases but slows down at the end - GLOB.dynamic_curve_centre = round(-CLAMP((10*6/GLOB.player_list.len)-1, 0, 5), 0.5) - */ message_admins("Dynamic mode parameters for the round:") message_admins("Centre is [GLOB.dynamic_curve_centre], Width is [GLOB.dynamic_curve_width], Forced extended is [GLOB.dynamic_forced_extended ? "Enabled" : "Disabled"], No stacking is [GLOB.dynamic_no_stacking ? "Enabled" : "Disabled"].") message_admins("Stacking limit is [GLOB.dynamic_stacking_limit], Classic secret is [GLOB.dynamic_classic_secret ? "Enabled" : "Disabled"], High population limit is [GLOB.dynamic_high_pop_limit].") @@ -342,8 +333,11 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) for(var/datum/dynamic_ruleset/roundstart/rule in executed_rules) rule.candidates.Cut() // The rule should not use candidates at this point as they all are null. - if(!rule.execute()) - stack_trace("The starting rule \"[rule.name]\" failed to execute.") + if(rule.delay > 0) + addtimer(CALLBACK(rule, /datum/dynamic_ruleset/roundstart.proc/execute), rule.delay) + else + if(!rule.execute()) + stack_trace("The starting rule \"[rule.name]\" failed to execute.") ..() /// A simple roundstart proc used when dynamic_forced_roundstart_ruleset has rules in it. @@ -427,16 +421,18 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if(drafted_rules.len <= 0) return FALSE starting_rule = pickweight(drafted_rules) + // With low pop and high threat there might be rulesets that get executed with no valid candidates. + else if(starting_rule.ready()) + drafted_rules -= starting_rule + if(drafted_rules.len <= 0) + return FALSE + starting_rule = pickweight(drafted_rules) - log_game("DYNAMIC: Picking a [istype(starting_rule, /datum/dynamic_ruleset/roundstart/delayed/) ? " delayed " : ""] ruleset [starting_rule.name]") + log_game("DYNAMIC: Picking a ruleset [starting_rule.name]") roundstart_rules -= starting_rule drafted_rules -= starting_rule - if (istype(starting_rule, /datum/dynamic_ruleset/roundstart/delayed/)) - var/datum/dynamic_ruleset/roundstart/delayed/rule = starting_rule - addtimer(CALLBACK(src, .proc/execute_delayed, rule), rule.delay) - starting_rule.trim_candidates() if (starting_rule.pre_execute()) spend_threat(starting_rule.cost) @@ -448,29 +444,14 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) executed_rules += starting_rule if (starting_rule.persistent) current_rules += starting_rule - for(var/mob/M in starting_rule.assigned) - for (var/datum/dynamic_ruleset/roundstart/rule in roundstart_rules) - if (!rule.ready()) - drafted_rules -= rule // And removing rules that are no longer elligible + for (var/datum/dynamic_ruleset/roundstart/rule in drafted_rules) + if (!rule.ready()) + drafted_rules -= rule // And removing rules that are no longer elligible return TRUE else stack_trace("The starting rule \"[starting_rule.name]\" failed to pre_execute.") return FALSE -/// Executes delayed roundstart rules and has a hack in it. -/datum/game_mode/dynamic/proc/execute_delayed(datum/dynamic_ruleset/roundstart/delayed/rule) - update_playercounts() - rule.candidates = current_players[CURRENT_LIVING_PLAYERS].Copy() - rule.trim_candidates() - if(rule.execute()) - executed_rules += rule - if (rule.persistent) - current_rules += rule - return TRUE - else - stack_trace("The delayed roundstart rule \"[rule.name]\" failed to execute.") - return FALSE - /// Picks a random midround OR latejoin rule from the list given as an argument and executes it. /// Also this could be named better. /datum/game_mode/dynamic/proc/picking_midround_latejoin_rule(list/drafted_rules = list(), forced = FALSE) @@ -550,7 +531,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) update_playercounts() if ((forced || (new_rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && new_rule.cost <= threat))) - new_rule.candidates = current_players.Copy() new_rule.trim_candidates() if (new_rule.ready(forced)) spend_threat(new_rule.cost) @@ -582,7 +562,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if (GLOB.dynamic_forced_extended) return - // Somehow it manages to trigger midround multiple times so this was moved here. + // Somehow it managed to trigger midround multiple times so this was moved here. // There is no way this should be able to trigger an injection twice now. var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_midround_delay_max + GLOB.dynamic_midround_delay_min) midround_injection_cooldown = (round(CLAMP(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_midround_delay_min, GLOB.dynamic_midround_delay_max)) + world.time) @@ -591,21 +571,19 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if(EMERGENCY_ESCAPED_OR_ENDGAMED) // Unless the shuttle is gone return - log_game("DYNAMIC: Checking state of the round.") + message_admins("DYNAMIC: Checking for midround injection.") + log_game("DYNAMIC: Checking for midround injection.") update_playercounts() - - if (prob(get_injection_chance())) + if (get_injection_chance()) var/list/drafted_rules = list() for (var/datum/dynamic_ruleset/midround/rule in midround_rules) if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost) // Classic secret : only autotraitor/minor roles if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET))) continue - rule.candidates = list() - rule.candidates = current_players.Copy() rule.trim_candidates() - if (rule.ready() && rule.candidates.len > 0) + if (rule.ready()) drafted_rules[rule] = rule.get_weight() if (drafted_rules.len > 0) picking_midround_latejoin_rule(drafted_rules) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index 011b6ec251..b77bfcc4a0 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -86,10 +86,9 @@ /datum/dynamic_ruleset/roundstart // One or more of those drafted at roundstart ruletype = "Roundstart" - -/datum/dynamic_ruleset/roundstart/delayed/ // Executed with a 30 seconds delay - var/delay = 30 SECONDS - var/required_type = /mob/living/carbon/human // No ghosts, new players or silicons allowed. + /// Delay for when execute will get called from the time of post_setup. + /// Make sure your ruleset works with execute being called during the game when using this. + var/delay = 0 // Can be drafted when a player joins the server /datum/dynamic_ruleset/latejoin @@ -113,7 +112,7 @@ /datum/dynamic_ruleset/proc/rule_process() return -/// Called on game mode pre_setup, used for non-delayed roundstart rulesets only. +/// Called on game mode pre_setup for roundstart rulesets. /// Do everything you need to do before job is assigned here. /// IMPORTANT: ASSIGN special_role HERE /datum/dynamic_ruleset/proc/pre_execute() @@ -126,12 +125,6 @@ M.add_antag_datum(antag_datum) return TRUE -/// Called after delay set in ruleset. -/// Give your candidates or assignees equipment and antag datum here. -/datum/dynamic_ruleset/roundstart/delayed/execute() - if (SSticker && SSticker.current_state < GAME_STATE_PLAYING) - CRASH("The delayed ruleset [name] executed before the round started.") - /// Here you can perform any additional checks you want. (such as checking the map etc) /// Remember that on roundstart no one knows what their job is at this point. /// IMPORTANT: If ready() returns TRUE, that means pre_execute() or execute() should never fail! @@ -156,14 +149,6 @@ /datum/dynamic_ruleset/proc/trim_candidates() return -/// Counts how many players are ready at roundstart. -/// Used only by non-delayed roundstart rulesets. -/datum/dynamic_ruleset/proc/num_players() - . = 0 - for(var/mob/dead/new_player/P in GLOB.player_list) - if(P.client && P.ready == PLAYER_READY_TO_PLAY) - . ++ - /// Set mode result and news report here. /// Only called if ruleset is flagged as HIGHLANDER_RULESET /datum/dynamic_ruleset/proc/round_result() @@ -191,32 +176,14 @@ if(P.mind.special_role) // We really don't want to give antag to an antag. candidates.Remove(P) continue - if (!(antag_flag in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag, ROLE_SYNDICATE)) || (antag_flag_override && jobban_isbanned(P.ckey, list(antag_flag_override, ROLE_SYNDICATE))))//are they willing and not antag-banned? - candidates.Remove(P) - continue - -/// Checks if candidates are required mob type, connected, banned and if the job is exclusive to the role. -/datum/dynamic_ruleset/roundstart/delayed/trim_candidates() - . = ..() - for (var/mob/P in candidates) - if (!istype(P, required_type)) - candidates.Remove(P) // Can be a new_player, etc. - continue - if(!mode.check_age(P.client, minimum_required_age)) - candidates.Remove(P) - continue - if (!P.client || !P.mind || !P.mind.assigned_role) // Are they connected? - candidates.Remove(P) - continue - if(P.mind.special_role || P.mind.antag_datums?.len > 0) // Are they an antag already? - candidates.Remove(P) - continue - if (!(antag_flag in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag, ROLE_SYNDICATE)) || (antag_flag_override && jobban_isbanned(P.ckey, list(antag_flag_override, ROLE_SYNDICATE))))//are they willing and not antag-banned? - candidates.Remove(P) - continue - if ((exclusive_roles.len > 0) && !(P.mind.assigned_role in exclusive_roles)) // Is the rule exclusive to their job? - candidates.Remove(P) - continue + if(antag_flag_override) + if(!(antag_flag_override in P.client.prefs.be_special) || is_banned_from(P.ckey, list(antag_flag_override, ROLE_SYNDICATE))) + candidates.Remove(P) + continue + else + if(!(antag_flag in P.client.prefs.be_special) || is_banned_from(P.ckey, list(antag_flag, ROLE_SYNDICATE))) + candidates.Remove(P) + continue /// Do your checks if the ruleset is ready to be executed here. /// Should ignore certain checks if forced is TRUE diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index fde020a3ae..a560e03f6e 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -12,9 +12,14 @@ if(!mode.check_age(P.client, minimum_required_age)) candidates.Remove(P) continue - if (!(antag_flag in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag, ROLE_SYNDICATE)) || (antag_flag_override && jobban_isbanned(P.ckey, list(antag_flag_override))))//are they willing and not antag-banned? - candidates.Remove(P) - continue + if(antag_flag_override) + if(!(antag_flag_override in P.client.prefs.be_special) || is_banned_from(P.ckey, list(antag_flag_override, ROLE_SYNDICATE))) + candidates.Remove(P) + continue + else + if(!antag_flag in P.client.prefs.be_special || is_banned_from(P.ckey, list(antag_flag, ROLE_SYNDICATE))) + candidates.Remove(P) + continue if (P.mind.assigned_role in restricted_roles) // Does their job allow for it? candidates.Remove(P) continue diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index f24301d716..006a80cca6 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -8,7 +8,7 @@ ruletype = "Midround" /// If the ruleset should be restricted from ghost roles. var/restrict_ghost_roles = TRUE - /// What type the ruleset is restricted to. + /// What mob type the ruleset is restricted to. var/required_type = /mob/living/carbon/human var/list/living_players = list() var/list/living_antags = list() @@ -17,26 +17,18 @@ /datum/dynamic_ruleset/midround/from_ghosts weight = 0 + required_type = /mob/dead/observer /// Whether the ruleset should call generate_ruleset_body or not. var/makeBody = TRUE /datum/dynamic_ruleset/midround/trim_candidates() - // Unlike the previous two types, these rulesets are not meant for /mob/dead/new_player - // And since I want those rulesets to be as flexible as possible, I'm not gonna put much here, - // - // All you need to know is that here, the candidates list contains 4 lists itself, indexed with the following defines: - // Candidates = list(CURRENT_LIVING_PLAYERS, CURRENT_LIVING_ANTAGS, CURRENT_DEAD_PLAYERS, CURRENT_OBSERVERS) - // So for example you can get the list of all current dead players with var/list/dead_players = candidates[CURRENT_DEAD_PLAYERS] - // Make sure to properly typecheck the mobs in those lists, as the dead_players list could contain ghosts, or dead players still in their bodies. - // We're still gonna trim the obvious (mobs without clients, jobbanned players, etc) - living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS]) - living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS]) - dead_players = trim_list(mode.current_players[CURRENT_DEAD_PLAYERS]) - list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS]) + living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS]) + living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS]) + dead_players = trim_list(mode.current_players[CURRENT_DEAD_PLAYERS]) + list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS]) /datum/dynamic_ruleset/midround/proc/trim_list(list/L = list()) var/list/trimmed_list = L.Copy() - var/antag_name = initial(antag_flag) for(var/mob/M in trimmed_list) if (!istype(M, required_type)) trimmed_list.Remove(M) @@ -47,9 +39,14 @@ if(!mode.check_age(M.client, minimum_required_age)) trimmed_list.Remove(M) continue - if (!(antag_name in M.client.prefs.be_special) || jobban_isbanned(M.ckey, list(antag_name, ROLE_SYNDICATE)))//are they willing and not antag-banned? - trimmed_list.Remove(M) - continue + if(antag_flag_override) + if(!(antag_flag_override in M.client.prefs.be_special) || is_banned_from(M.ckey, list(antag_flag_override, ROLE_SYNDICATE))) + candidates.Remove(M) + continue + else + if(!antag_flag in M.client.prefs.be_special || is_banned_from(M.ckey, list(antag_flag, ROLE_SYNDICATE))) + candidates.Remove(M) + continue if (M.mind) if (restrict_ghost_roles && M.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL]) // Are they playing a ghost role? trimmed_list.Remove(M) @@ -256,8 +253,7 @@ /datum/dynamic_ruleset/midround/malf/execute() if(!candidates || !candidates.len) return FALSE - var/mob/living/silicon/ai/M = pick(candidates) - candidates -= M + var/mob/living/silicon/ai/M = pick_n_take(candidates) assigned += M.mind var/datum/antagonist/traitor/AI = new M.mind.special_role = antag_flag diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 6a9aefa996..f515ccc443 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -25,8 +25,7 @@ var/traitor_scaling_coeff = 10 - max(0,round(mode.threat_level/10)-5) // Above 50 threat level, coeff goes down by 1 for every 10 levels var/num_traitors = min(round(mode.candidates.len / traitor_scaling_coeff) + 1, candidates.len) for (var/i = 1 to num_traitors) - var/mob/M = pick(candidates) - candidates -= M + var/mob/M = pick_n_take(candidates) assigned += M.mind M.mind.special_role = ROLE_TRAITOR M.mind.restricted_roles = restricted_roles @@ -67,7 +66,7 @@ var/num_teams = team_amount var/bsc = CONFIG_GET(number/brother_scaling_coeff) if(bsc) - num_teams = max(1, round(num_players() / bsc)) + num_teams = max(1, round(mode.roundstart_pop_ready / bsc)) for(var/j = 1 to num_teams) if(candidates.len < min_team_size || candidates.len < required_candidates) @@ -75,8 +74,7 @@ var/datum/team/brother_team/team = new var/team_size = prob(10) ? min(3, candidates.len) : 2 for(var/k = 1 to team_size) - var/mob/bro = pick(candidates) - candidates -= bro + var/mob/bro = pick_n_take(candidates) assigned += bro.mind team.add_member(bro.mind) bro.mind.special_role = "brother" @@ -117,8 +115,7 @@ /datum/dynamic_ruleset/roundstart/changeling/pre_execute() var/num_changelings = min(round(mode.candidates.len / 10) + 1, candidates.len) for (var/i = 1 to num_changelings) - var/mob/M = pick(candidates) - candidates -= M + var/mob/M = pick_n_take(candidates) assigned += M.mind M.mind.restricted_roles = restricted_roles M.mind.special_role = ROLE_CHANGELING @@ -175,9 +172,8 @@ if(GLOB.wizardstart.len == 0) return FALSE - var/mob/M = pick(candidates) + var/mob/M = pick_n_take(candidates) if (M) - candidates -= M assigned += M.mind M.mind.assigned_role = ROLE_WIZARD M.mind.special_role = ROLE_WIZARD @@ -225,8 +221,7 @@ for(var/cultists_number = 1 to cultists) if(candidates.len <= 0) break - var/mob/M = pick(candidates) - candidates -= M + var/mob/M = pick_n_take(candidates) assigned += M.mind M.mind.special_role = ROLE_CULTIST M.mind.restricted_roles = restricted_roles @@ -288,8 +283,7 @@ for(var/operatives_number = 1 to operatives) if(candidates.len <= 0) break - var/mob/M = pick(candidates) - candidates -= M + var/mob/M = pick_n_take(candidates) assigned += M.mind M.mind.assigned_role = "Nuclear Operative" M.mind.special_role = "Nuclear Operative" @@ -347,7 +341,7 @@ // // ////////////////////////////////////////////// -/datum/dynamic_ruleset/roundstart/delayed/revs +/datum/dynamic_ruleset/roundstart/revs name = "Revolution" config_tag = "revolution" persistent = TRUE @@ -358,47 +352,48 @@ restricted_roles = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") required_candidates = 3 weight = 2 + delay = 7 MINUTES cost = 35 requirements = list(101,101,70,40,30,20,10,10,10,10) high_population_requirement = 10 - delay = 5 MINUTES flags = HIGHLANDER_RULESET // I give up, just there should be enough heads with 35 players... minimum_players = 35 var/datum/team/revolution/revolution var/finished = 0 -/datum/dynamic_ruleset/roundstart/delayed/revs/execute() - var/max_canditates = 4 - revolution = new() +/datum/dynamic_ruleset/roundstart/revs/pre_execute() + var/max_canditates = 3 for(var/i = 1 to max_canditates) if(candidates.len <= 0) break - var/mob/M = pick(candidates) - candidates -= M + var/mob/M = pick_n_take(candidates) assigned += M.mind M.mind.restricted_roles = restricted_roles M.mind.special_role = antag_flag + return TRUE + +/datum/dynamic_ruleset/roundstart/revs/execute() + revolution = new() + for(var/datum/mind/M in assigned) var/datum/antagonist/rev/head/new_head = new antag_datum() new_head.give_flash = TRUE new_head.give_hud = TRUE new_head.remove_clumsy = TRUE - M.mind.add_antag_datum(new_head,revolution) - + M.add_antag_datum(new_head,revolution) revolution.update_objectives() revolution.update_heads() SSshuttle.registerHostileEnvironment(src) - return TRUE -/datum/dynamic_ruleset/roundstart/delayed/revs/rule_process() +/datum/dynamic_ruleset/roundstart/revs/rule_process() if(check_rev_victory()) finished = 1 else if(check_heads_victory()) finished = 2 return -/datum/dynamic_ruleset/roundstart/delayed/revs/check_finished() +/datum/dynamic_ruleset/roundstart/revs/check_finished() if(CONFIG_GET(keyed_list/continuous)["revolution"]) if(finished) SSshuttle.clearHostileEnvironment(src) @@ -408,13 +403,13 @@ else return ..() -/datum/dynamic_ruleset/roundstart/delayed/revs/proc/check_rev_victory() +/datum/dynamic_ruleset/roundstart/revs/proc/check_rev_victory() for(var/datum/objective/mutiny/objective in revolution.objectives) if(!(objective.check_completion())) return FALSE return TRUE -/datum/dynamic_ruleset/roundstart/delayed/revs/proc/check_heads_victory() +/datum/dynamic_ruleset/roundstart/revs/proc/check_heads_victory() for(var/datum/mind/rev_mind in revolution.head_revolutionaries()) var/turf/T = get_turf(rev_mind.current) if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z)) @@ -422,7 +417,7 @@ return FALSE return TRUE -/datum/dynamic_ruleset/roundstart/delayed/revs/round_result() +/datum/dynamic_ruleset/roundstart/revs/round_result() if(finished == 1) SSticker.mode_result = "win - heads killed" SSticker.news_report = REVS_WIN @@ -487,14 +482,13 @@ PM.initTemplateBounds() var/starter_servants = 4 - var/number_players = num_players() + var/number_players = mode.roundstart_pop_ready if(number_players > 30) number_players -= 30 starter_servants += round(number_players / 10) starter_servants = min(starter_servants, 8) for (var/i in 1 to starter_servants) - var/mob/servant = pick(candidates) - candidates -= servant + var/mob/servant = pick_n_take(candidates) assigned += servant.mind servant.mind.assigned_role = ROLE_SERVANT_OF_RATVAR servant.mind.special_role = ROLE_SERVANT_OF_RATVAR @@ -610,16 +604,15 @@ var/num_devils = 1 if(tsc) - num_devils = max(required_candidates, min(round(num_players() / (tsc * 3)) + 2, round(num_players() / (tsc * 1.5)))) + num_devils = max(required_candidates, min(round(mode.roundstart_pop_ready / (tsc * 3)) + 2, round(mode.roundstart_pop_ready / (tsc * 1.5)))) else - num_devils = max(required_candidates, min(num_players(), devil_limit)) + num_devils = max(required_candidates, min(mode.roundstart_pop_ready, devil_limit)) for(var/j = 0, j < num_devils, j++) if (!candidates.len) break - var/mob/devil = pick(candidates) - assigned += devil - candidates -= devil + var/mob/devil = pick_n_take(candidates) + assigned += devil.mind devil.mind.special_role = ROLE_DEVIL devil.mind.restricted_roles = restricted_roles @@ -668,13 +661,12 @@ var/datum/team/monkey/monkey_team /datum/dynamic_ruleset/roundstart/monkey/pre_execute() - var/carriers_to_make = max(round(num_players()/players_per_carrier, 1), 1) + var/carriers_to_make = max(round(mode.roundstart_pop_ready / players_per_carrier, 1), 1) for(var/j = 0, j < carriers_to_make, j++) if (!candidates.len) break - var/mob/carrier = pick(candidates) - candidates -= carrier + var/mob/carrier = pick_n_take(candidates) assigned += carrier.mind carrier.mind.special_role = "Monkey Leader" carrier.mind.restricted_roles = restricted_roles From 03da6d6960e8c5e7e7015390021e14f5854ef0c9 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sun, 10 Nov 2019 06:41:42 +0100 Subject: [PATCH 088/121] fixeronis. --- .../gamemodes/dynamic/dynamic_rulesets.dm | 42 +++++++++---------- .../dynamic/dynamic_rulesets_latejoin.dm | 2 +- .../dynamic/dynamic_rulesets_midround.dm | 6 +-- .../dynamic/dynamic_rulesets_roundstart.dm | 26 ++++++------ 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index b77bfcc4a0..22a54d9b73 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -2,21 +2,21 @@ /// For admin logging and round end screen. var/name = "" /// For admin logging and round end screen, do not change this unless making a new rule type. - var/ruletype = "" + var/ruletype = "" /// For config purposes, similar to config_tag for secret game modes. var/config_tag = null /// If set to TRUE, the rule won't be discarded after being executed, and dynamic will call rule_process() every time it ticks. - var/persistent = FALSE + var/persistent = FALSE /// If set to TRUE, dynamic mode will be able to draft this ruleset again later on. (doesn't apply for roundstart rules) - var/repeatable = FALSE + var/repeatable = FALSE /// If set higher than 0 decreases weight by itself causing the ruleset to appear less often the more it is repeated. - var/repeatable_weight_decrease = 2 + var/repeatable_weight_decrease = 2 /// List of players that are being drafted for this rule - var/list/mob/candidates = list() + var/list/mob/candidates = list() /// List of players that were selected for this rule - var/list/datum/mind/assigned = list() + var/list/datum/mind/assigned = list() /// Preferences flag such as ROLE_WIZARD that need to be turned on for players to be antag - var/antag_flag = null + var/antag_flag = null /// The antagonist datum that is assigned to the mobs mind on ruleset execution. var/datum/antagonist/antag_datum = null /// The required minimum account age for this ruleset. @@ -24,19 +24,19 @@ /// If set, and config flag protect_roles_from_antagonist is false, then the rule will not pick players from these roles. var/list/protected_roles = list() /// If set, rule will deny candidates from those roles always. - var/list/restricted_roles = list() + var/list/restricted_roles = list() /// If set, rule will only accept candidates from those roles, IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS. - var/list/exclusive_roles = list() + var/list/exclusive_roles = list() /// If set, there needs to be a certain amount of players doing those roles (among the players who won't be drafted) for the rule to be drafted IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS. - var/list/enemy_roles = list() + var/list/enemy_roles = list() /// If enemy_roles was set, this is the amount of enemy job workers needed per threat_level range (0-10,10-20,etc) IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS. - var/required_enemies = list(1,1,0,0,0,0,0,0,0,0) + var/required_enemies = list(1,1,0,0,0,0,0,0,0,0) /// The rule needs this many candidates (post-trimming) to be executed (example: Cult needs 4 players at round start) - var/required_candidates = 0 + var/required_candidates = 0 /// 1 -> 9, probability for this rule to be picked against other rules - var/weight = 5 + var/weight = 5 /// Threat cost for this rule, this is decreased from the mode's threat when the rule is executed. - var/cost = 0 + var/cost = 0 /// A flag that determines how the ruleset is handled /// HIGHLANDER_RULESET are rulesets can end the round. /// TRAITOR_RULESET and MINOR_RULESET can't end the round and have no difference right now. @@ -46,18 +46,18 @@ /// Requirements are the threat level requirements per pop range. /// With the default values, The rule will never get drafted below 10 threat level (aka: "peaceful extended"), and it requires a higher threat level at lower pops. var/list/requirements = list(40,30,20,10,10,10,10,10,10,10) - /// An alternative, static requirement used instead when pop is over mode's high_pop_limit. + /// An alternative, static requirement used instead when pop is over mode's high_pop_limit. var/high_population_requirement = 10 /// Reference to the mode, use this instead of SSticker.mode. var/datum/game_mode/dynamic/mode = null /// If a role is to be considered another for the purpose of banning. - var/antag_flag_override = null + var/antag_flag_override = null /// If a ruleset type which is in this list has been executed, then the ruleset will not be executed. var/list/blocking_rules = list() - /// The minimum amount of players required for the rule to be considered. + /// The minimum amount of players required for the rule to be considered. var/minimum_players = 0 /// The maximum amount of players required for the rule to be considered. - /// Anything below zero or exactly zero is ignored. + /// Anything below zero or exactly zero is ignored. var/maximum_players = 0 @@ -105,7 +105,7 @@ return (threat_level >= high_population_requirement) else pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement - var/indice_pop = min(10,round(population/pop_per_requirement)+1) + var/indice_pop = min(requirements.len,round(population/pop_per_requirement)+1) return (threat_level >= requirements[indice_pop]) /// This is called if persistent variable is true everytime SSTicker ticks. @@ -128,8 +128,8 @@ /// Here you can perform any additional checks you want. (such as checking the map etc) /// Remember that on roundstart no one knows what their job is at this point. /// IMPORTANT: If ready() returns TRUE, that means pre_execute() or execute() should never fail! -/datum/dynamic_ruleset/proc/ready(forced = 0) - if (required_candidates > candidates.len) +/datum/dynamic_ruleset/proc/ready(forced = 0) + if (required_candidates > candidates.len) return FALSE return TRUE diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index a560e03f6e..5c4728bc89 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -17,7 +17,7 @@ candidates.Remove(P) continue else - if(!antag_flag in P.client.prefs.be_special || is_banned_from(P.ckey, list(antag_flag, ROLE_SYNDICATE))) + if(!(antag_flag in P.client.prefs.be_special) || is_banned_from(P.ckey, list(antag_flag, ROLE_SYNDICATE))) candidates.Remove(P) continue if (P.mind.assigned_role in restricted_roles) // Does their job allow for it? diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 006a80cca6..d26aa57856 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -44,7 +44,7 @@ candidates.Remove(M) continue else - if(!antag_flag in M.client.prefs.be_special || is_banned_from(M.ckey, list(antag_flag, ROLE_SYNDICATE))) + if(!(antag_flag in M.client.prefs.be_special) || is_banned_from(M.ckey, list(antag_flag, ROLE_SYNDICATE))) candidates.Remove(M) continue if (M.mind) @@ -317,14 +317,14 @@ cost = 35 requirements = list(90,90,90,80,60,40,30,20,10,10) high_population_requirement = 10 - var/operative_cap = list(2,2,3,3,4,5,5,5,5,5) + var/list/operative_cap = list(2,2,3,3,4,5,5,5,5,5) var/datum/team/nuclear/nuke_team flags = HIGHLANDER_RULESET /datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat=0) if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules) return FALSE // Unavailable if nuke ops were already sent at roundstart - var/indice_pop = min(10,round(living_players.len/5)+1) + var/indice_pop = min(operative_cap.len, round(living_players.len/5)+1) required_candidates = operative_cap[indice_pop] return ..() diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index f515ccc443..d48153b222 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -123,7 +123,7 @@ /datum/dynamic_ruleset/roundstart/changeling/execute() var/team_mode = FALSE - if(prob(team_mode_probability)) + if(prob(team_mode_probability)) team_mode = TRUE var/list/team_objectives = subtypesof(/datum/objective/changeling_team_objective) var/list/possible_team_objectives = list() @@ -171,13 +171,13 @@ /datum/dynamic_ruleset/roundstart/wizard/pre_execute() if(GLOB.wizardstart.len == 0) return FALSE - + var/mob/M = pick_n_take(candidates) if (M) assigned += M.mind M.mind.assigned_role = ROLE_WIZARD M.mind.special_role = ROLE_WIZARD - + return TRUE /datum/dynamic_ruleset/roundstart/wizard/execute() @@ -185,7 +185,7 @@ M.current.forceMove(pick(GLOB.wizardstart)) M.add_antag_datum(new antag_datum()) return TRUE - + ////////////////////////////////////////////// // // // BLOOD CULT // @@ -207,16 +207,16 @@ high_population_requirement = 10 pop_per_requirement = 5 flags = HIGHLANDER_RULESET - var/cultist_cap = list(2,2,2,3,3,4,4,4,4,4) + var/list/cultist_cap = list(2,2,2,3,3,4,4,4,4,4) var/datum/team/cult/main_cult /datum/dynamic_ruleset/roundstart/bloodcult/ready(forced = FALSE) - var/indice_pop = min(10,round(mode.roundstart_pop_ready/pop_per_requirement)+1) + var/indice_pop = min(cultist_cap.len, round(mode.roundstart_pop_ready/pop_per_requirement)+1) required_candidates = cultist_cap[indice_pop] . = ..() /datum/dynamic_ruleset/roundstart/bloodcult/pre_execute() - var/indice_pop = min(10,round(mode.roundstart_pop_ready/pop_per_requirement)+1) + var/indice_pop = min(cultist_cap.len, round(mode.roundstart_pop_ready/pop_per_requirement)+1) var/cultists = cultist_cap[indice_pop] for(var/cultists_number = 1 to cultists) if(candidates.len <= 0) @@ -233,7 +233,7 @@ var/datum/antagonist/cult/new_cultist = new antag_datum() new_cultist.cult_team = main_cult new_cultist.give_equipment = TRUE - M.add_antag_datum(new_cultist) + M.add_antag_datum(new_cultist) main_cult.setup_objectives() return TRUE @@ -267,18 +267,18 @@ high_population_requirement = 10 pop_per_requirement = 5 flags = HIGHLANDER_RULESET - var/operative_cap = list(2,2,2,3,3,3,4,4,5,5) + var/list/operative_cap = list(2,2,2,3,3,3,4,4,5,5) var/datum/team/nuclear/nuke_team /datum/dynamic_ruleset/roundstart/nuclear/ready(forced = FALSE) - var/indice_pop = min(10,round(mode.roundstart_pop_ready/pop_per_requirement)+1) + var/indice_pop = min(operative_cap.len,round(mode.roundstart_pop_ready/pop_per_requirement)+1) required_candidates = operative_cap[indice_pop] . = ..() /datum/dynamic_ruleset/roundstart/nuclear/pre_execute() // If ready() did its job, candidates should have 5 or more members in it - var/indice_pop = min(10,round(mode.roundstart_pop_ready/5)+1) + var/indice_pop = min(operative_cap.len, round(mode.roundstart_pop_ready/5)+1) var/operatives = operative_cap[indice_pop] for(var/operatives_number = 1 to operatives) if(candidates.len <= 0) @@ -385,7 +385,7 @@ revolution.update_heads() SSshuttle.registerHostileEnvironment(src) return TRUE - + /datum/dynamic_ruleset/roundstart/revs/rule_process() if(check_rev_victory()) finished = 1 @@ -599,7 +599,7 @@ high_population_requirement = 101 var/devil_limit = 4 // Hard limit on devils if scaling is turned off -/datum/dynamic_ruleset/roundstart/devil/pre_execute() +/datum/dynamic_ruleset/roundstart/devil/pre_execute() var/tsc = CONFIG_GET(number/traitor_scaling_coeff) var/num_devils = 1 From c6e44a7fed8d3687344c89a12144a6cf25405eca Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sun, 10 Nov 2019 17:59:40 +0100 Subject: [PATCH 089/121] That's it: #46027, (a little bit of) #46132, #47100, #47341, #47351, #47395, #47457, #47491. --- code/__DEFINES/traits.dm | 3 +- code/__HELPERS/roundend.dm | 2 +- code/game/gamemodes/dynamic/dynamic.dm | 192 +++++++++++------- .../gamemodes/dynamic/dynamic_rulesets.dm | 56 ++++- .../dynamic/dynamic_rulesets_latejoin.dm | 92 +++++++-- .../dynamic/dynamic_rulesets_midround.dm | 10 +- .../dynamic/dynamic_rulesets_roundstart.dm | 151 ++++++++------ .../antagonists/revolution/revolution.dm | 38 +++- code/modules/mob/living/carbon/human/death.dm | 9 +- 9 files changed, 381 insertions(+), 172 deletions(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 1f37556d1d..f96337f691 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -213,4 +213,5 @@ #define LOCKED_HELMET_TRAIT "locked-helmet" #define NINJA_SUIT_TRAIT "ninja-suit" #define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant" -#define ABDUCTOR_ANTAGONIST "abductor-antagonist" \ No newline at end of file +#define ABDUCTOR_ANTAGONIST "abductor-antagonist" +#define MADE_UNCLONEABLE "made-uncloneable" \ No newline at end of file diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 8e59106d98..85b839c9a1 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -314,7 +314,7 @@ parts += "[FOURSPACES]Threat left: [mode.threat]" parts += "[FOURSPACES]Executed rules:" for(var/datum/dynamic_ruleset/rule in mode.executed_rules) - parts += "[FOURSPACES][FOURSPACES][rule.ruletype] - [rule.name]: -[rule.cost] threat" + parts += "[FOURSPACES][FOURSPACES][rule.ruletype] - [rule.name]: -[rule.cost + rule.scaled_times * rule.scaling_cost] threat" return parts.Join("
") /client/proc/roundend_report_file() diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 473e2ae4a5..78febd0615 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -19,7 +19,7 @@ GLOBAL_VAR_INIT(dynamic_midround_delay_max, (35 MINUTES)) // Are HIGHLANDER_RULESETs allowed to stack? GLOBAL_VAR_INIT(dynamic_no_stacking, TRUE) -// A number between -5 and +5. +// A number between -5 and +5. // A negative value will give a more peaceful round and // a positive value will give a round with higher threat. GLOBAL_VAR_INIT(dynamic_curve_centre, 0) @@ -27,7 +27,7 @@ GLOBAL_VAR_INIT(dynamic_curve_centre, 0) // Higher value will favour extreme rounds and // lower value rounds closer to the average. GLOBAL_VAR_INIT(dynamic_curve_width, 1.8) -// If enabled only picks a single starting rule and executes only autotraitor midround ruleset. +// If enabled only picks a single starting rule and executes only autotraitor midround ruleset. GLOBAL_VAR_INIT(dynamic_classic_secret, FALSE) // How many roundstart players required for high population override to take effect. GLOBAL_VAR_INIT(dynamic_high_pop_limit, 55) @@ -38,7 +38,7 @@ GLOBAL_VAR_INIT(dynamic_forced_extended, FALSE) GLOBAL_VAR_INIT(dynamic_stacking_limit, 90) // List of forced roundstart rulesets. GLOBAL_LIST_EMPTY(dynamic_forced_roundstart_ruleset) -// Forced threat level, setting this to zero or higher forces the roundstart threat to the value. +// Forced threat level, setting this to zero or higher forces the roundstart threat to the value. GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) /datum/game_mode/dynamic @@ -49,14 +49,14 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) announce_text = "Dynamic mode!" // This needs to be changed maybe reroll_friendly = FALSE; - + // Threat logging vars /// The "threat cap", threat shouldn't normally go above this and is used in ruleset calculations - var/threat_level = 0 + var/threat_level = 0 /// Set at the beginning of the round. Spent by the mode to "purchase" rules. - var/threat = 0 + var/threat = 0 /// Running information about the threat. Can store text or datum entries. - var/list/threat_log = list() + var/list/threat_log = list() /// List of roundstart rules used for selecting the rules. var/list/roundstart_rules = list() /// List of latejoin rules used for selecting the rules. @@ -72,14 +72,20 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) * 0-6, 7-13, 14-20, 21-27, 28-34, 35-41, 42-48, 49-55, 56-62, 63+ */ var/pop_per_requirement = 6 - /// The requirement used for checking if a second rule should be selected. + /// The requirement used for checking if a second rule should be selected. Index based on pop_per_requirement. var/list/second_rule_req = list(100, 100, 80, 70, 60, 50, 30, 20, 10, 0) - /// The requirement used for checking if a third rule should be selected. + /// The probability for a second ruleset with index being every ten threat. + var/list/second_rule_prob = list(0,0,60,80,80,80,100,100,100,100) + /// The requirement used for checking if a third rule should be selected. Index based on pop_per_requirement. var/list/third_rule_req = list(100, 100, 100, 90, 80, 70, 60, 50, 40, 30) - /// Threat requirement for a second ruleset when high pop override is in effect. + /// The probability for a third ruleset with index being every ten threat. + var/list/third_rule_prob = list(0,0,0,0,60,60,80,90,100,100) + /// Threat requirement for a second ruleset when high pop override is in effect. var/high_pop_second_rule_req = 40 - /// Threat requirement for a third ruleset when high pop override is in effect. + /// Threat requirement for a third ruleset when high pop override is in effect. var/high_pop_third_rule_req = 60 + /// The amount of additional rulesets waiting to be picked. + var/extra_rulesets_amount = 0 /// Number of players who were ready on roundstart. var/roundstart_pop_ready = 0 /// List of candidates used on roundstart rulesets. @@ -106,6 +112,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/highlander_executed = FALSE /// If a only ruleset has been executed. var/only_ruleset_executed = FALSE + /// Antags rolled by rules so far, to keep track of and discourage scaling past a certain ratio of crew/antags especially on lowpop. + var/antags_rolled = 0 /datum/game_mode/dynamic/New() // i have NO IDEA if this is the proper way to do this. ..() @@ -175,7 +183,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) show_threatlog(usr) else if (href_list["stacking_limit"]) GLOB.dynamic_stacking_limit = input(usr,"Change the threat limit at which round-endings rulesets will start to stack.", "Change stacking limit", null) as num - + admin_panel() // Refreshes the window // Checks if there are HIGHLANDER_RULESETs and calls the rule's round_result() proc @@ -313,18 +321,21 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) candidates.Add(player) log_game("DYNAMIC: Listing [roundstart_rules.len] round start rulesets, and [candidates.len] players ready.") if (candidates.len <= 0) + log_game("DYNAMIC: [candidates.len] candidates.") return TRUE if (roundstart_rules.len <= 0) + log_game("DYNAMIC: [roundstart_rules.len] rules.") return TRUE - + if(GLOB.dynamic_forced_roundstart_ruleset.len > 0) rigged_roundstart() - else + else roundstart() var/starting_rulesets = "" for (var/datum/dynamic_ruleset/roundstart/DR in executed_rules) starting_rulesets += "[DR.name], " + log_game("DYNAMIC: Picked the following roundstart rules: [starting_rulesets]") candidates.Cut() return TRUE @@ -332,12 +343,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) update_playercounts() for(var/datum/dynamic_ruleset/roundstart/rule in executed_rules) - rule.candidates.Cut() // The rule should not use candidates at this point as they all are null. - if(rule.delay > 0) - addtimer(CALLBACK(rule, /datum/dynamic_ruleset/roundstart.proc/execute), rule.delay) - else - if(!rule.execute()) - stack_trace("The starting rule \"[rule.name]\" failed to execute.") + addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_roundstart_rule, rule), rule.delay) ..() /// A simple roundstart proc used when dynamic_forced_roundstart_ruleset has rules in it. @@ -348,6 +354,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) message_admins("Drafting players for forced ruleset [rule.name].") log_game("DYNAMIC: Drafting players for forced ruleset [rule.name].") rule.mode = src + rule.acceptable(roundstart_pop_ready, threat_level) // Assigns some vars in the modes, running it here for consistency rule.candidates = candidates.Copy() rule.trim_candidates() if (rule.ready(TRUE)) @@ -366,7 +373,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) drafted_rules[rule] = rule.weight var/indice_pop = min(10,round(roundstart_pop_ready/pop_per_requirement)+1) - var/extra_rulesets_amount = 0 + extra_rulesets_amount = 0 if (GLOB.dynamic_classic_secret) extra_rulesets_amount = 0 else @@ -378,23 +385,28 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if (threat_level > high_pop_third_rule_req) extra_rulesets_amount++ else - if (threat_level >= second_rule_req[indice_pop]) + var/threat_indice = min(10, max(round(threat_level ? threat_level/10 : 1), 1)) // 0-9 threat = 1, 10-19 threat = 2 ... + if (threat_level >= second_rule_req[indice_pop] && prob(second_rule_prob[threat_indice])) extra_rulesets_amount++ - if (threat_level >= third_rule_req[indice_pop]) + if (threat_level >= third_rule_req[indice_pop] && prob(third_rule_prob[threat_indice])) extra_rulesets_amount++ + log_game("DYNAMIC: Trying to roll [extra_rulesets_amount + 1] roundstart rulesets. Picking from [drafted_rules.len] eligible rulesets.") if (drafted_rules.len > 0 && picking_roundstart_rule(drafted_rules)) - if (extra_rulesets_amount > 0) // We've got enough population and threat for a second rulestart rule + log_game("DYNAMIC: First ruleset picked successfully. [extra_rulesets_amount] remaining.") + while(extra_rulesets_amount > 0 && drafted_rules.len > 0) // We had enough threat for one or two more rulesets for (var/datum/dynamic_ruleset/roundstart/rule in drafted_rules) if (rule.cost > threat) drafted_rules -= rule - if (drafted_rules.len > 0 && picking_roundstart_rule(drafted_rules)) - if (extra_rulesets_amount > 1) // We've got enough population and threat for a third rulestart rule - for (var/datum/dynamic_ruleset/roundstart/rule in drafted_rules) - if (rule.cost > threat) - drafted_rules -= rule - picking_roundstart_rule(drafted_rules) + if(drafted_rules.len) + picking_roundstart_rule(drafted_rules) + extra_rulesets_amount-- + log_game("DYNAMIC: Additional ruleset picked successfully, now [executed_rules.len] picked. [extra_rulesets_amount] remaining.") else + + if(threat >= 10) + message_admins("DYNAMIC: Picking first roundstart ruleset failed. You should report this.") + log_game("DYNAMIC: Picking first roundstart ruleset failed. drafted_rules.len = [drafted_rules.len] and threat = [threat]/[threat_level]") return FALSE return TRUE @@ -402,63 +414,83 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) /datum/game_mode/dynamic/proc/picking_roundstart_rule(list/drafted_rules = list(), forced = FALSE) var/datum/dynamic_ruleset/roundstart/starting_rule = pickweight(drafted_rules) if(!starting_rule) + log_game("DYNAMIC: Couldn't pick a starting ruleset. No rulesets available") return FALSE if(!forced) if(only_ruleset_executed) return FALSE // Check if a blocking ruleset has been executed. - else if(check_blocking(starting_rule.blocking_rules, executed_rules)) + else if(check_blocking(starting_rule.blocking_rules, executed_rules)) // Should already be filtered out, but making sure. Check filtering at end of proc if reported. drafted_rules -= starting_rule if(drafted_rules.len <= 0) + log_game("DYNAMIC: Picking [starting_rule.name] failed due to blocking_rules and no more rulesets available. Report this.") return FALSE starting_rule = pickweight(drafted_rules) // Check if the ruleset is highlander and if a highlander ruleset has been executed - else if(starting_rule.flags & HIGHLANDER_RULESET) - if(threat < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) + else if(starting_rule.flags & HIGHLANDER_RULESET) // Should already be filtered out, but making sure. Check filtering at end of proc if reported. + if(threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) if(highlander_executed) drafted_rules -= starting_rule if(drafted_rules.len <= 0) + log_game("DYNAMIC: Picking [starting_rule.name] failed due to no highlander stacking and no more rulesets available. Report this.") return FALSE starting_rule = pickweight(drafted_rules) // With low pop and high threat there might be rulesets that get executed with no valid candidates. - else if(starting_rule.ready()) + else if(starting_rule.ready()) // Should already be filtered out, but making sure. Check filtering at end of proc if reported. drafted_rules -= starting_rule if(drafted_rules.len <= 0) + log_game("DYNAMIC: Picking [starting_rule.name] failed because there were not enough candidates and no more rulesets available. Report this.") return FALSE starting_rule = pickweight(drafted_rules) - log_game("DYNAMIC: Picking a ruleset [starting_rule.name]") + log_game("DYNAMIC: Picked a ruleset: [starting_rule.name]") roundstart_rules -= starting_rule drafted_rules -= starting_rule starting_rule.trim_candidates() - if (starting_rule.pre_execute()) - spend_threat(starting_rule.cost) + + var/added_threat = starting_rule.scale_up(extra_rulesets_amount, threat) + if(starting_rule.pre_execute()) + spend_threat(starting_rule.cost + added_threat) threat_log += "[worldtime2text()]: Roundstart [starting_rule.name] spent [starting_rule.cost]" if(starting_rule.flags & HIGHLANDER_RULESET) highlander_executed = TRUE else if(starting_rule.flags & ONLY_RULESET) only_ruleset_executed = TRUE executed_rules += starting_rule - if (starting_rule.persistent) - current_rules += starting_rule - for (var/datum/dynamic_ruleset/roundstart/rule in drafted_rules) - if (!rule.ready()) - drafted_rules -= rule // And removing rules that are no longer elligible + for(var/datum/dynamic_ruleset/roundstart/rule in drafted_rules) + if(check_blocking(rule.blocking_rules, executed_rules)) + drafted_rules -= rule + if(highlander_executed && rule.flags & HIGHLANDER_RULESET) + drafted_rules -= rule + if(!rule.ready()) + drafted_rules -= rule // And removing rules that are no longer eligible return TRUE else stack_trace("The starting rule \"[starting_rule.name]\" failed to pre_execute.") return FALSE +/// Mainly here to facilitate delayed rulesets. All roundstart rulesets are executed with a timered callback to this proc. +/datum/game_mode/dynamic/proc/execute_roundstart_rule(sent_rule) + var/datum/dynamic_ruleset/rule = sent_rule + if(rule.execute()) + if(rule.persistent) + current_rules += rule + return TRUE + rule.clean_up() // Refund threat, delete teams and so on. + executed_rules -= rule + stack_trace("The starting rule \"[rule.name]\" failed to execute.") + return FALSE + /// Picks a random midround OR latejoin rule from the list given as an argument and executes it. /// Also this could be named better. /datum/game_mode/dynamic/proc/picking_midround_latejoin_rule(list/drafted_rules = list(), forced = FALSE) var/datum/dynamic_ruleset/rule = pickweight(drafted_rules) if(!rule) return FALSE - + if(!forced) if(only_ruleset_executed) return FALSE @@ -470,39 +502,21 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) rule = pickweight(drafted_rules) // Check if the ruleset is highlander and if a highlander ruleset has been executed else if(rule.flags & HIGHLANDER_RULESET) - if(threat < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) + if(threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) if(highlander_executed) drafted_rules -= rule if(drafted_rules.len <= 0) return FALSE rule = pickweight(drafted_rules) - + if(!rule.repeatable) if(rule.ruletype == "Latejoin") latejoin_rules = remove_from_list(latejoin_rules, rule.type) else if(rule.type == "Midround") midround_rules = remove_from_list(midround_rules, rule.type) - - if (rule.execute()) - log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") - spend_threat(rule.cost) - threat_log += "[worldtime2text()]: [rule.ruletype] [rule.name] spent [rule.cost]" - if(rule.flags & HIGHLANDER_RULESET) - highlander_executed = TRUE - else if(rule.flags & ONLY_RULESET) - only_ruleset_executed = TRUE - if(rule.ruletype == "Latejoin") - var/mob/M = pick(rule.candidates) - message_admins("[key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") - log_game("DYNAMIC: [key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") - executed_rules += rule - rule.candidates.Cut() - if (rule.persistent) - current_rules += rule - return TRUE - else - stack_trace("The [rule.ruletype] rule \"[rule.name]\" failed to execute.") - return FALSE + + addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_midround_latejoin_rule, rule), rule.delay) + return TRUE /// An experimental proc to allow admins to call rules on the fly or have rules call other rules. /datum/game_mode/dynamic/proc/picking_specific_rule(ruletype, forced = FALSE) @@ -513,10 +527,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) new_rule = ruletype else return FALSE - + if(!new_rule) return FALSE - + if(!forced) if(only_ruleset_executed) return FALSE @@ -525,10 +539,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) return FALSE // Check if the ruleset is highlander and if a highlander ruleset has been executed else if(new_rule.flags & HIGHLANDER_RULESET) - if(threat < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) + if(threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) if(highlander_executed) return FALSE - + update_playercounts() if ((forced || (new_rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && new_rule.cost <= threat))) new_rule.trim_candidates() @@ -549,6 +563,30 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) log_game("DYNAMIC: The ruleset [new_rule.name] couldn't be executed due to lack of elligible players.") return FALSE +/// Mainly here to facilitate delayed rulesets. All midround/latejoin rulesets are executed with a timered callback to this proc. +/datum/game_mode/dynamic/proc/execute_midround_latejoin_rule(sent_rule) + var/datum/dynamic_ruleset/rule = sent_rule + if (rule.execute()) + log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") + spend_threat(rule.cost) + threat_log += "[worldtime2text()]: [rule.ruletype] [rule.name] spent [rule.cost]" + if(rule.flags & HIGHLANDER_RULESET) + highlander_executed = TRUE + else if(rule.flags & ONLY_RULESET) + only_ruleset_executed = TRUE + if(rule.ruletype == "Latejoin") + var/mob/M = pick(rule.candidates) + message_admins("[key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") + log_game("DYNAMIC: [key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") + executed_rules += rule + rule.candidates.Cut() + if (rule.persistent) + current_rules += rule + return TRUE + rule.clean_up() + stack_trace("The [rule.ruletype] rule \"[rule.name]\" failed to execute.") + return FALSE + /datum/game_mode/dynamic/process() if (pop_last_updated < world.time - (60 SECONDS)) pop_last_updated = world.time @@ -561,19 +599,19 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if (midround_injection_cooldown < world.time) if (GLOB.dynamic_forced_extended) return - + // Somehow it managed to trigger midround multiple times so this was moved here. // There is no way this should be able to trigger an injection twice now. var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_midround_delay_max + GLOB.dynamic_midround_delay_min) midround_injection_cooldown = (round(CLAMP(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_midround_delay_min, GLOB.dynamic_midround_delay_max)) + world.time) - + // Time to inject some threat into the round if(EMERGENCY_ESCAPED_OR_ENDGAMED) // Unless the shuttle is gone return message_admins("DYNAMIC: Checking for midround injection.") log_game("DYNAMIC: Checking for midround injection.") - + update_playercounts() if (get_injection_chance()) var/list/drafted_rules = list() @@ -587,7 +625,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) drafted_rules[rule] = rule.get_weight() if (drafted_rules.len > 0) picking_midround_latejoin_rule(drafted_rules) - + /// Updates current_players. /datum/game_mode/dynamic/proc/update_playercounts() current_players[CURRENT_LIVING_PLAYERS] = list() @@ -682,11 +720,11 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) // Classic secret : only autotraitor/minor roles if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET))) continue - // No stacking : only one round-enter, unless > stacking_limit threat. - if (threat < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) + // No stacking : only one round-ender, unless threat level > stacking_limit. + if (threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) if(rule.flags & HIGHLANDER_RULESET && highlander_executed) continue - + rule.candidates = list(newPlayer) rule.trim_candidates() if (rule.ready()) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index 22a54d9b73..266d313a06 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -1,3 +1,9 @@ +#define EXTRA_RULESET_PENALTY 20 // Changes how likely a gamemode is to scale based on how many other roundstart rulesets are waiting to be rolled. +#define POP_SCALING_PENALTY 50 // Discourages scaling up rulesets if ratio of antags to crew is high. + +#define REVOLUTION_VICTORY 1 +#define STATION_VICTORY 2 + /datum/dynamic_ruleset /// For admin logging and round end screen. var/name = "" @@ -37,6 +43,12 @@ var/weight = 5 /// Threat cost for this rule, this is decreased from the mode's threat when the rule is executed. var/cost = 0 + /// Cost per level the rule scales up. + var/scaling_cost = 0 + /// How many times a rule has scaled up upon getting picked. + var/scaled_times = 0 + /// Used for the roundend report + var/total_cost = 0 /// A flag that determines how the ruleset is handled /// HIGHLANDER_RULESET are rulesets can end the round. /// TRAITOR_RULESET and MINOR_RULESET can't end the round and have no difference right now. @@ -59,7 +71,15 @@ /// The maximum amount of players required for the rule to be considered. /// Anything below zero or exactly zero is ignored. var/maximum_players = 0 - + /// Calculated during acceptable(), used in scaling and team sizes. + var/indice_pop = 0 + /// Population scaling. Used by team antags and scaling for solo antags. + var/list/antag_cap = list() + /// Base probability used in scaling. The higher it is, the more likely to scale. Kept as a var to allow for config editing._SendSignal(sigtype, list/arguments) + var/base_prob = 60 + /// Delay for when execute will get called from the time of post_setup (roundstart) or process (midround/latejoin). + /// Make sure your ruleset works with execute being called during the game when using this, and that the clean_up proc reverts it properly in case of faliure. + var/delay = 0 /datum/dynamic_ruleset/New() ..() @@ -86,9 +106,6 @@ /datum/dynamic_ruleset/roundstart // One or more of those drafted at roundstart ruletype = "Roundstart" - /// Delay for when execute will get called from the time of post_setup. - /// Make sure your ruleset works with execute being called during the game when using this. - var/delay = 0 // Can be drafted when a player joins the server /datum/dynamic_ruleset/latejoin @@ -102,12 +119,35 @@ if(maximum_players > 0 && population > maximum_players) return FALSE if (population >= GLOB.dynamic_high_pop_limit) + indice_pop = 10 return (threat_level >= high_population_requirement) else pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement - var/indice_pop = min(requirements.len,round(population/pop_per_requirement)+1) + if(antag_cap.len && requirements.len != antag_cap.len) + message_admins("DYNAMIC: requirements and antag_cap lists have different lengths in ruleset [name]. Likely config issue, report this.") + log_game("DYNAMIC: requirements and antag_cap lists have different lengths in ruleset [name]. Likely config issue, report this.") + indice_pop = min(requirements.len,round(population/pop_per_requirement)+1) return (threat_level >= requirements[indice_pop]) +/// Called when a suitable rule is picked during roundstart(). Will some times attempt to scale a rule up when there is threat remaining. Returns the amount of scaled steps. +/datum/dynamic_ruleset/proc/scale_up(extra_rulesets = 0, remaining_threat_level = 0) + remaining_threat_level -= cost + if(scaling_cost && scaling_cost <= remaining_threat_level) // Only attempts to scale the modes with a scaling cost explicitly set. + var/new_prob + var/pop_to_antags = (mode.antags_rolled + (antag_cap[indice_pop] * (scaled_times + 1))) / mode.roundstart_pop_ready + log_game("DYNAMIC: [name] roundstart ruleset attempting to scale up with [extra_rulesets] rulesets waiting and [remaining_threat_level] threat remaining.") + for(var/i in 1 to 3) //Can scale a max of 3 times + if(remaining_threat_level >= scaling_cost && pop_to_antags < 0.25) + new_prob = base_prob + (remaining_threat_level) - (scaled_times * scaling_cost) - (extra_rulesets * EXTRA_RULESET_PENALTY) - (pop_to_antags * POP_SCALING_PENALTY) + if (!prob(new_prob)) + break + remaining_threat_level -= scaling_cost + scaled_times++ + pop_to_antags = (mode.antags_rolled + (antag_cap[indice_pop] * (scaled_times + 1))) / mode.roundstart_pop_ready + log_game("DYNAMIC: [name] roundstart ruleset failed scaling up at [new_prob ? new_prob : 0]% chance after [scaled_times]/3 successful scaleups. [remaining_threat_level] threat remaining, antag to crew ratio: [pop_to_antags*100]%.") + mode.antags_rolled += (1 + scaled_times) * antag_cap[indice_pop] + return scaled_times * scaling_cost + /// This is called if persistent variable is true everytime SSTicker ticks. /datum/dynamic_ruleset/proc/rule_process() return @@ -133,6 +173,12 @@ return FALSE return TRUE +/// Runs from gamemode process() if ruleset fails to start, like delayed rulesets not getting valid candidates. +/// This one only handles refunding the threat, override in ruleset to clean up the rest. +/datum/dynamic_ruleset/proc/clean_up() + mode.refund_threat(cost + (scaled_times * scaling_cost)) + mode.threat_log += "[worldtime2text()]: [ruletype] [name] refunded [cost + (scaled_times * scaling_cost)]" + /// Gets weight of the ruleset /// Note that this decreases weight if repeatable is TRUE and repeatable_weight_decrease is higher than 0 /// Note: If you don't want repeatable rulesets to decrease their weight use the weight variable directly diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 5c4728bc89..6eb7fb37eb 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -78,6 +78,7 @@ /datum/dynamic_ruleset/latejoin/provocateur name = "Provocateur" + persistent = TRUE config_tag = "latejoin_revolution" antag_datum = /datum/antagonist/rev/head antag_flag = ROLE_REV_HEAD @@ -87,31 +88,98 @@ required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 weight = 2 + delay = 1 MINUTES // Prevents rule start while head is offstation. cost = 20 requirements = list(101,101,70,40,30,20,20,20,20,20) high_population_requirement = 50 flags = HIGHLANDER_RULESET - var/required_heads = 3 + var/required_heads_of_staff = 3 + var/finished = FALSE + var/datum/team/revolution/revolution /datum/dynamic_ruleset/latejoin/provocateur/ready(forced=FALSE) if (forced) - required_heads = 1 + required_heads_of_staff = 1 if(!..()) return FALSE var/head_check = 0 for(var/mob/player in mode.current_players[CURRENT_LIVING_PLAYERS]) if (player.mind.assigned_role in GLOB.command_positions) head_check++ - return (head_check >= required_heads) + return (head_check >= required_heads_of_staff) /datum/dynamic_ruleset/latejoin/provocateur/execute() - var/mob/M = pick(candidates) - assigned += M.mind - M.mind.special_role = antag_flag - var/datum/antagonist/rev/head/new_head = new() - new_head.give_flash = TRUE - new_head.give_hud = TRUE - new_head.remove_clumsy = TRUE - new_head = M.mind.add_antag_datum(new_head) - new_head.rev_team.max_headrevs = 1 // Only one revhead if it is latejoin. + var/mob/M = pick(candidates) // This should contain a single player, but in case. + if(check_eligible(M.mind)) // Didnt die/run off z-level/get implanted since leaving shuttle. + assigned += M.mind + M.mind.special_role = antag_flag + revolution = new() + var/datum/antagonist/rev/head/new_head = new() + new_head.give_flash = TRUE + new_head.give_hud = TRUE + new_head.remove_clumsy = TRUE + new_head = M.mind.add_antag_datum(new_head, revolution) + revolution.update_objectives() + revolution.update_heads() + SSshuttle.registerHostileEnvironment(src) + return TRUE + else + log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.") + log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.") + return FALSE + +/datum/dynamic_ruleset/latejoin/provocateur/rule_process() + if(check_rev_victory()) + finished = REVOLUTION_VICTORY + return RULESET_STOP_PROCESSING + else if (check_heads_victory()) + finished = STATION_VICTORY + SSshuttle.clearHostileEnvironment(src) + priority_announce("It appears the mutiny has been quelled. Please return yourself and your colleagues to work. \ + We have remotely blacklisted the head revolutionaries from your cloning software to prevent accidental cloning.", null, "attention", null, "Central Command Loyalty Monitoring Division") + for(var/datum/mind/M in revolution.members) // Remove antag datums and prevent headrev cloning then restarting rebellions. + if(M.has_antag_datum(/datum/antagonist/rev/head)) + var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head) + R.remove_revolutionary(FALSE, "gamemode") + var/mob/living/carbon/C = M.current + if(C.stat == DEAD) + C.makeUncloneable() + if(M.has_antag_datum(/datum/antagonist/rev)) + var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev) + R.remove_revolutionary(FALSE, "gamemode") + return RULESET_STOP_PROCESSING + +/// Checks for revhead loss conditions and other antag datums. +/datum/dynamic_ruleset/latejoin/provocateur/proc/check_eligible(var/datum/mind/M) + var/turf/T = get_turf(M.current) + if(!considered_afk(M) && considered_alive(M) && is_station_level(T.z) && !M.antag_datums?.len && !HAS_TRAIT(M, TRAIT_MINDSHIELD)) + return TRUE + return FALSE + +/datum/dynamic_ruleset/latejoin/provocateur/check_finished() + if(finished == REVOLUTION_VICTORY) + return TRUE + else + return ..() + +/datum/dynamic_ruleset/latejoin/provocateur/proc/check_rev_victory() + for(var/datum/objective/mutiny/objective in revolution.objectives) + if(!(objective.check_completion())) + return FALSE return TRUE + +/datum/dynamic_ruleset/latejoin/provocateur/proc/check_heads_victory() + for(var/datum/mind/rev_mind in revolution.head_revolutionaries()) + var/turf/T = get_turf(rev_mind.current) + if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z)) + if(ishuman(rev_mind.current) || ismonkey(rev_mind.current)) + return FALSE + return TRUE + +/datum/dynamic_ruleset/latejoin/provocateur/round_result() + if(finished == REVOLUTION_VICTORY) + SSticker.mode_result = "win - heads killed" + SSticker.news_report = REVS_WIN + else if(finished == STATION_VICTORY) + SSticker.mode_result = "loss - rev heads killed" + SSticker.news_report = REVS_LOSE \ No newline at end of file diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index d26aa57856..ef08b11739 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -41,17 +41,17 @@ continue if(antag_flag_override) if(!(antag_flag_override in M.client.prefs.be_special) || is_banned_from(M.ckey, list(antag_flag_override, ROLE_SYNDICATE))) - candidates.Remove(M) + trimmed_list.Remove(M) continue else if(!(antag_flag in M.client.prefs.be_special) || is_banned_from(M.ckey, list(antag_flag, ROLE_SYNDICATE))) - candidates.Remove(M) + trimmed_list.Remove(M) continue if (M.mind) if (restrict_ghost_roles && M.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL]) // Are they playing a ghost role? trimmed_list.Remove(M) continue - if (M.mind.assigned_role in restricted_roles || HAS_TRAIT(M, TRAIT_MINDSHIELD)) // Does their job allow it or are they mindshielded? + if (M.mind.assigned_role in restricted_roles) // Does their job allow it? trimmed_list.Remove(M) continue if ((exclusive_roles.len > 0) && !(M.mind.assigned_role in exclusive_roles)) // Is the rule exclusive to their job? @@ -239,7 +239,7 @@ /datum/dynamic_ruleset/midround/malf/trim_candidates() ..() - candidates = candidates[CURRENT_LIVING_PLAYERS] + living_players = candidates[CURRENT_LIVING_PLAYERS] for(var/mob/living/player in candidates) if(!isAI(player)) candidates -= player @@ -324,7 +324,7 @@ /datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat=0) if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules) return FALSE // Unavailable if nuke ops were already sent at roundstart - var/indice_pop = min(operative_cap.len, round(living_players.len/5)+1) + indice_pop = min(operative_cap.len, round(living_players.len/5)+1) required_candidates = operative_cap[indice_pop] return ..() diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index d48153b222..346cbe1e00 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -16,14 +16,15 @@ restricted_roles = list("Cyborg") required_candidates = 1 weight = 5 - cost = 10 + cost = 10 // Avoid raising traitor threat above 10, as it is the default low cost ruleset. + scaling_cost = 10 requirements = list(10,10,10,10,10,10,10,10,10,10) high_population_requirement = 10 + antag_cap = list(1,1,1,1,2,2,2,2,3,3) var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) /datum/dynamic_ruleset/roundstart/traitor/pre_execute() - var/traitor_scaling_coeff = 10 - max(0,round(mode.threat_level/10)-5) // Above 50 threat level, coeff goes down by 1 for every 10 levels - var/num_traitors = min(round(mode.candidates.len / traitor_scaling_coeff) + 1, candidates.len) + var/num_traitors = antag_cap[indice_pop] * (scaled_times + 1) for (var/i = 1 to num_traitors) var/mob/M = pick_n_take(candidates) assigned += M.mind @@ -55,19 +56,16 @@ protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") required_candidates = 2 weight = 4 - cost = 10 + cost = 15 + scaling_cost = 15 requirements = list(40,30,30,20,20,15,15,15,10,10) high_population_requirement = 15 + antag_cap = list(2,2,2,2,2,2,2,2,2,2) // Can pick 3 per team, but rare enough it doesn't matter. var/list/datum/team/brother_team/pre_brother_teams = list() - var/const/team_amount = 2 // Hard limit on brother teams if scaling is turned off var/const/min_team_size = 2 /datum/dynamic_ruleset/roundstart/traitorbro/pre_execute() - var/num_teams = team_amount - var/bsc = CONFIG_GET(number/brother_scaling_coeff) - if(bsc) - num_teams = max(1, round(mode.roundstart_pop_ready / bsc)) - + var/num_teams = (antag_cap[indice_pop]/min_team_size) * (scaled_times + 1) // 1 team per scaling for(var/j = 1 to num_teams) if(candidates.len < min_team_size || candidates.len < required_candidates) break @@ -107,13 +105,15 @@ protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") required_candidates = 1 weight = 3 - cost = 30 - requirements = list(80,70,60,50,40,20,20,10,10,10) + cost = 15 + scaling_cost = 15 + requirements = list(70,70,60,50,40,20,20,10,10,10) high_population_requirement = 10 + antag_cap = list(1,1,1,1,1,2,2,2,2,3) var/team_mode_probability = 30 /datum/dynamic_ruleset/roundstart/changeling/pre_execute() - var/num_changelings = min(round(mode.candidates.len / 10) + 1, candidates.len) + var/num_changelings = antag_cap[indice_pop] * (scaled_times + 1) for (var/i = 1 to num_changelings) var/mob/M = pick_n_take(candidates) assigned += M.mind @@ -171,7 +171,7 @@ /datum/dynamic_ruleset/roundstart/wizard/pre_execute() if(GLOB.wizardstart.len == 0) return FALSE - + mode.antags_rolled += 1 var/mob/M = pick_n_take(candidates) if (M) assigned += M.mind @@ -202,22 +202,20 @@ protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") required_candidates = 2 weight = 3 - cost = 30 + cost = 35 requirements = list(100,90,80,60,40,30,10,10,10,10) high_population_requirement = 10 - pop_per_requirement = 5 flags = HIGHLANDER_RULESET - var/list/cultist_cap = list(2,2,2,3,3,4,4,4,4,4) + antag_cap = list(2,2,2,3,3,4,4,4,4,4) var/datum/team/cult/main_cult /datum/dynamic_ruleset/roundstart/bloodcult/ready(forced = FALSE) - var/indice_pop = min(cultist_cap.len, round(mode.roundstart_pop_ready/pop_per_requirement)+1) - required_candidates = cultist_cap[indice_pop] + required_candidates = antag_cap[indice_pop] . = ..() /datum/dynamic_ruleset/roundstart/bloodcult/pre_execute() - var/indice_pop = min(cultist_cap.len, round(mode.roundstart_pop_ready/pop_per_requirement)+1) - var/cultists = cultist_cap[indice_pop] + var/cultists = antag_cap[indice_pop] + mode.antags_rolled += cultists for(var/cultists_number = 1 to cultists) if(candidates.len <= 0) break @@ -263,23 +261,22 @@ required_candidates = 5 weight = 3 cost = 40 + pop_per_requirement = 5 requirements = list(90,90,90,80,60,40,30,20,10,10) high_population_requirement = 10 pop_per_requirement = 5 flags = HIGHLANDER_RULESET - var/list/operative_cap = list(2,2,2,3,3,3,4,4,5,5) + antag_cap = list(2,2,2,3,3,3,4,4,5,5) var/datum/team/nuclear/nuke_team /datum/dynamic_ruleset/roundstart/nuclear/ready(forced = FALSE) - var/indice_pop = min(operative_cap.len,round(mode.roundstart_pop_ready/pop_per_requirement)+1) - required_candidates = operative_cap[indice_pop] + required_candidates = antag_cap[indice_pop] . = ..() /datum/dynamic_ruleset/roundstart/nuclear/pre_execute() // If ready() did its job, candidates should have 5 or more members in it - - var/indice_pop = min(operative_cap.len, round(mode.roundstart_pop_ready/5)+1) - var/operatives = operative_cap[indice_pop] + var/operatives = antag_cap[indice_pop] + mode.antags_rolled += operatives for(var/operatives_number = 1 to operatives) if(candidates.len <= 0) break @@ -356,15 +353,17 @@ cost = 35 requirements = list(101,101,70,40,30,20,10,10,10,10) high_population_requirement = 10 + antag_cap = list(3,3,3,3,3,3,3,3,3,3) flags = HIGHLANDER_RULESET // I give up, just there should be enough heads with 35 players... minimum_players = 35 var/datum/team/revolution/revolution - var/finished = 0 + var/finished = FALSE /datum/dynamic_ruleset/roundstart/revs/pre_execute() - var/max_canditates = 3 - for(var/i = 1 to max_canditates) + var/max_candidates = antag_cap[indice_pop] + mode.antags_rolled += max_candidates + for(var/i = 1 to max_candidates) if(candidates.len <= 0) break var/mob/M = pick_n_take(candidates) @@ -374,31 +373,63 @@ return TRUE /datum/dynamic_ruleset/roundstart/revs/execute() + var/success = TRUE revolution = new() for(var/datum/mind/M in assigned) - var/datum/antagonist/rev/head/new_head = new antag_datum() - new_head.give_flash = TRUE - new_head.give_hud = TRUE - new_head.remove_clumsy = TRUE - M.add_antag_datum(new_head,revolution) - revolution.update_objectives() - revolution.update_heads() - SSshuttle.registerHostileEnvironment(src) - return TRUE + if(check_eligible(M)) + var/datum/antagonist/rev/head/new_head = new antag_datum() + new_head.give_flash = TRUE + new_head.give_hud = TRUE + new_head.remove_clumsy = TRUE + M.add_antag_datum(new_head,revolution) + else + assigned -= M + log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.") + if(!revolution.members.len) + success = FALSE + log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.") + if(success) + revolution.update_objectives() + revolution.update_heads() + SSshuttle.registerHostileEnvironment(src) + return TRUE + return FALSE + +/datum/dynamic_ruleset/roundstart/revs/clean_up() + qdel(revolution) + ..() /datum/dynamic_ruleset/roundstart/revs/rule_process() if(check_rev_victory()) - finished = 1 - else if(check_heads_victory()) - finished = 2 - return + finished = REVOLUTION_VICTORY + return RULESET_STOP_PROCESSING + else if (check_heads_victory()) + finished = STATION_VICTORY + SSshuttle.clearHostileEnvironment(src) + priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \ + We have remotely blacklisted the head revolutionaries from your cloning software to prevent accidental cloning.", null, "attention", null, "Central Command Loyalty Monitoring Division") + + for(var/datum/mind/M in revolution.members) // Remove antag datums and prevents podcloned or exiled headrevs restarting rebellions. + if(M.has_antag_datum(/datum/antagonist/rev/head)) + var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head) + R.remove_revolutionary(FALSE, "gamemode") + var/mob/living/carbon/C = M.current + if(C.stat == DEAD) + C.makeUncloneable() + if(M.has_antag_datum(/datum/antagonist/rev)) + var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev) + R.remove_revolutionary(FALSE, "gamemode") + return RULESET_STOP_PROCESSING + +/// Checks for revhead loss conditions and other antag datums. +/datum/dynamic_ruleset/roundstart/revs/proc/check_eligible(var/datum/mind/M) + var/turf/T = get_turf(M.current) + if(!considered_afk(M) && considered_alive(M) && is_station_level(T.z) && !M.antag_datums?.len && !HAS_TRAIT(M, TRAIT_MINDSHIELD)) + return TRUE + return FALSE /datum/dynamic_ruleset/roundstart/revs/check_finished() - if(CONFIG_GET(keyed_list/continuous)["revolution"]) - if(finished) - SSshuttle.clearHostileEnvironment(src) - return ..() - if(finished != 0) + if(finished == REVOLUTION_VICTORY) return TRUE else return ..() @@ -418,10 +449,10 @@ return TRUE /datum/dynamic_ruleset/roundstart/revs/round_result() - if(finished == 1) + if(finished == REVOLUTION_VICTORY) SSticker.mode_result = "win - heads killed" SSticker.news_report = REVS_WIN - else if(finished == 2) + else if(finished == STATION_VICTORY) SSticker.mode_result = "loss - rev heads killed" SSticker.news_report = REVS_LOSE @@ -469,6 +500,7 @@ requirements = list(101,101,101,101,101,101,101,101,101,101) high_population_requirement = 101 flags = HIGHLANDER_RULESET + antag_cap = list(2,3,3,4,4,4,4,4,4,4) var/ark_time /datum/dynamic_ruleset/roundstart/clockcult/pre_execute() @@ -481,12 +513,12 @@ for(var/datum/parsed_map/PM in reebes) PM.initTemplateBounds() - var/starter_servants = 4 + var/starter_servants = antag_cap[indice_pop] var/number_players = mode.roundstart_pop_ready if(number_players > 30) number_players -= 30 - starter_servants += round(number_players / 10) - starter_servants = min(starter_servants, 8) + starter_servants += min(round(number_players / 10), 5) + mode.antags_rolled += starter_servants for (var/i in 1 to starter_servants) var/mob/servant = pick_n_take(candidates) assigned += servant.mind @@ -597,17 +629,11 @@ cost = 0 requirements = list(101,101,101,101,101,101,101,101,101,101) high_population_requirement = 101 - var/devil_limit = 4 // Hard limit on devils if scaling is turned off + antag_cap = list(1,1,1,2,2,2,3,3,3,4) /datum/dynamic_ruleset/roundstart/devil/pre_execute() - var/tsc = CONFIG_GET(number/traitor_scaling_coeff) - var/num_devils = 1 - - if(tsc) - num_devils = max(required_candidates, min(round(mode.roundstart_pop_ready / (tsc * 3)) + 2, round(mode.roundstart_pop_ready / (tsc * 1.5)))) - else - num_devils = max(required_candidates, min(mode.roundstart_pop_ready, devil_limit)) - + var/num_devils = antag_cap[indice_pop] + mode.antags_rolled += num_devils for(var/j = 0, j < num_devils, j++) if (!candidates.len) break @@ -662,6 +688,7 @@ /datum/dynamic_ruleset/roundstart/monkey/pre_execute() var/carriers_to_make = max(round(mode.roundstart_pop_ready / players_per_carrier, 1), 1) + mode.antags_rolled += carriers_to_make for(var/j = 0, j < carriers_to_make, j++) if (!candidates.len) diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm index e10d83ffb7..b41731369b 100644 --- a/code/modules/antagonists/revolution/revolution.dm +++ b/code/modules/antagonists/revolution/revolution.dm @@ -207,9 +207,20 @@ owner.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.", null, null, null, owner.current) to_chat(owner, "The frame's firmware detects and deletes your neural reprogramming! You remember nothing of your time spent reprogrammed, you can't even remember the names or identities of anyone involved...") +/datum/antagonist/rev/head/farewell() + if((ishuman(owner.current) || ismonkey(owner.current))) + if(owner.current.stat != DEAD) + owner.current.visible_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!", null, null, null, owner.current) + to_chat(owner, "You have given up your cause of overthrowing the command staff. You are no longer a Head Revolutionary.") + else + to_chat(owner, "The sweet release of death. You are no longer a Head Revolutionary.") + else if(issilicon(owner.current)) + owner.current.visible_message("The frame beeps contentedly, suppressing the disloyal personality traits from the MMI before initalizing it.", null, null, null, owner.current) + to_chat(owner, "The frame's firmware detects and suppresses your unwanted personality traits! You feel more content with the leadership around these parts.") + //blunt trauma deconversions call this through species.dm spec_attacked_by() /datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter) - log_attack("[key_name(owner.current)] has been deconverted from the revolution by [key_name(deconverter)]!") + log_attack("[key_name(owner.current)] has been deconverted from the revolution by [ismob(deconverter) ? key_name(deconverter) : deconverter]!") if(borged) message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]") owner.special_role = null @@ -219,9 +230,8 @@ owner.remove_antag_datum(type) /datum/antagonist/rev/head/remove_revolutionary(borged,deconverter) - if(!borged) - return - . = ..() + if(borged || deconverter == "gamemode") + . = ..() /datum/antagonist/rev/head/equip_rev() var/mob/living/carbon/human/H = owner.current @@ -253,6 +263,8 @@ /datum/team/revolution name = "Revolution" var/max_headrevs = 3 + var/list/ex_headrevs = list() // Dynamic removes revs on loss, used to keep a list for the roundend report. + var/list/ex_revs = list() /datum/team/revolution/proc/update_objectives(initial = FALSE) var/untracked_heads = SSjob.get_all_heads() @@ -295,9 +307,12 @@ addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE) +/datum/team/revolution/proc/save_members() + ex_headrevs = get_antag_minds(/datum/antagonist/rev/head, TRUE) + ex_revs = get_antag_minds(/datum/antagonist/rev, TRUE) /datum/team/revolution/roundend_report() - if(!members.len) + if(!members.len && !ex_headrevs.len) return var/list/result = list() @@ -317,8 +332,17 @@ var/list/targets = list() - var/list/datum/mind/headrevs = get_antag_minds(/datum/antagonist/rev/head) - var/list/datum/mind/revs = get_antag_minds(/datum/antagonist/rev,TRUE) + var/list/datum/mind/headrevs + var/list/datum/mind/revs + if(ex_headrevs.len) + headrevs = ex_headrevs + else + headrevs = get_antag_minds(/datum/antagonist/rev/head, TRUE) + + if(ex_revs.len) + revs = ex_revs + else + revs = get_antag_minds(/datum/antagonist/rev, TRUE) if(headrevs.len) var/list/headrev_part = list() headrev_part += "The head revolutionaries were:" diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index b0c3f61eec..2f13af95db 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -69,11 +69,16 @@ /mob/living/carbon/human/proc/makeSkeleton() ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC) set_species(/datum/species/skeleton) - return 1 + return TRUE /mob/living/carbon/proc/Drain() become_husk(CHANGELING_DRAIN) ADD_TRAIT(src, TRAIT_NOCLONE, CHANGELING_DRAIN) blood_volume = 0 - return 1 + return TRUE + +/mob/living/carbon/proc/makeUncloneable() + ADD_TRAIT(src, TRAIT_NOCLONE, MADE_UNCLONEABLE) + blood_volume = 0 + return TRUE \ No newline at end of file From 40dd37a85800df60421bb0e3e463a740d6276044 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 10 Nov 2019 19:00:24 -0800 Subject: [PATCH 090/121] all roundstarts are delayed now --- .../gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index aed9995f0a..bd7619d9cb 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -47,7 +47,7 @@ // // ////////////////////////////////////////////// -/datum/dynamic_ruleset/roundstart/delayed/malf_ai +/datum/dynamic_ruleset/roundstart/malf_ai name = "Malfunctioning AI" config_tag = "malf_ai" antag_datum = /datum/antagonist/traitor @@ -61,9 +61,10 @@ requirements = list(101,101,101,100,90,80,70,60,50,50) high_population_requirement = 50 required_type = /mob/living/silicon/ai + delay = 30 SECONDS var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) -/datum/dynamic_ruleset/roundstart/delayed/malf_ai/trim_candidates() +/datum/dynamic_ruleset/roundstart/malf_ai/trim_candidates() ..() candidates = candidates[CURRENT_LIVING_PLAYERS] for(var/mob/living/player in candidates) @@ -76,7 +77,7 @@ if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0)) candidates -= player -/datum/dynamic_ruleset/roundstart/delayed/malf_ai/execute() +/datum/dynamic_ruleset/roundstart/malf_ai/execute() if(!candidates || !candidates.len) return FALSE var/mob/living/silicon/ai/M = pick(candidates) @@ -87,7 +88,7 @@ M.mind.add_antag_datum(AI) return TRUE -/datum/dynamic_ruleset/roundstart/delayed/malf_ai/rule_process() +/datum/dynamic_ruleset/roundstart/malf_ai/rule_process() if (autotraitor_cooldown > 0) autotraitor_cooldown-- else From 18dc177a65ef63eafade90a209b8c02edffd05eb Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 10 Nov 2019 19:00:55 -0800 Subject: [PATCH 091/121] um. --- code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index bd7619d9cb..554adc2342 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -107,7 +107,7 @@ name = "Blood Brothers" config_tag = "traitorbro" antag_flag = ROLE_BROTHER - antag_datum = /datum/antagonist/brother/ + antag_datum = /datum/antagonist/brother restricted_roles = list("AI", "Cyborg") protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") required_candidates = 2 From 6307d44198baf12d42ad1ba93cfffd0763274405 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 10 Nov 2019 21:30:34 -0800 Subject: [PATCH 092/121] Fixing some logging --- code/game/gamemodes/dynamic/dynamic.dm | 4 ++-- code/game/gamemodes/dynamic/dynamic_rulesets.dm | 2 +- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 77995038b3..5785ea9f91 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -488,7 +488,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/added_threat = starting_rule.scale_up(extra_rulesets_amount, threat) if (starting_rule.pre_execute()) spend_threat(starting_rule.cost + added_threat) - log_threat("Roundstart [starting_rule.name] spent [starting_rule.cost]") + log_threat("[rule.ruletype] - [rule.name] -[rule.cost + rule.scaled_times * rule.scaling_cost] threat") if(starting_rule.flags & HIGHLANDER_RULESET) highlander_executed = TRUE else if(starting_rule.flags & ONLY_RULESET) @@ -625,7 +625,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if (rule.execute()) log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") spend_threat(rule.cost) - threat_log += "[worldtime2text()]: [rule.ruletype] [rule.name] spent [rule.cost]" + log_threat("[rule.ruletype] [rule.name] spent [rule.cost]") if(rule.flags & HIGHLANDER_RULESET) highlander_executed = TRUE else if(rule.flags & ONLY_RULESET) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index 266d313a06..19ebb79a7f 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -177,7 +177,7 @@ /// This one only handles refunding the threat, override in ruleset to clean up the rest. /datum/dynamic_ruleset/proc/clean_up() mode.refund_threat(cost + (scaled_times * scaling_cost)) - mode.threat_log += "[worldtime2text()]: [ruletype] [name] refunded [cost + (scaled_times * scaling_cost)]" + mode.log_threat("[ruletype] [name] refunded [cost + (scaled_times * scaling_cost)]",verbose=TRUE) /// Gets weight of the ruleset /// Note that this decreases weight if repeatable is TRUE and repeatable_weight_decrease is higher than 0 diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 6ed5399987..37cd91a9c9 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -111,7 +111,7 @@ message_admins("The ruleset [name] received no applications.") log_game("DYNAMIC: The ruleset [name] received no applications.") mode.refund_threat(cost) - mode.log_threat("[worldtime2text()]: Rule [name] refunded [cost] (no applications)",verbose=TRUE) + mode.log_threat("Rule [name] refunded [cost] (no applications)",verbose=TRUE) mode.executed_rules -= src return @@ -127,7 +127,7 @@ if(i == 1) // We have found no candidates so far and we are out of applicants. mode.refund_threat(cost) - mode.log_threat("[worldtime2text()]: Rule [name] refunded [cost] (all applications invalid)",verbose=TRUE) + mode.log_threat("Rule [name] refunded [cost] (all applications invalid)",verbose=TRUE) mode.executed_rules -= src break var/mob/applicant = pick(candidates) From b5d8b30ae3c0b3a97a1a57f6c714dac6318725e7 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 10 Nov 2019 21:34:10 -0800 Subject: [PATCH 093/121] Further logging fixes --- code/game/gamemodes/dynamic/dynamic.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 5785ea9f91..dbbba3ebc3 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -488,7 +488,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/added_threat = starting_rule.scale_up(extra_rulesets_amount, threat) if (starting_rule.pre_execute()) spend_threat(starting_rule.cost + added_threat) - log_threat("[rule.ruletype] - [rule.name] -[rule.cost + rule.scaled_times * rule.scaling_cost] threat") + log_threat("[starting_rule.ruletype] - [starting_rule.name] -[starting_rule.cost + starting_rule.scaled_times * starting_rule.scaling_cost] threat") if(starting_rule.flags & HIGHLANDER_RULESET) highlander_executed = TRUE else if(starting_rule.flags & ONLY_RULESET) @@ -604,7 +604,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) new_rule.trim_candidates() if (new_rule.ready(forced)) spend_threat(new_rule.cost) - log_threat("Rule [new_rule.name] spent [new_rule.cost]") + log_threat("[new_rule.ruletype] - [new_rule.name] -[new_rule.cost] threat") if (new_rule.execute()) // This should never fail since ready() returned 1 if(new_rule.flags & HIGHLANDER_RULESET) highlander_executed = TRUE From 9618050b17e42e26fe545c81d236552013f75c8e Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 10 Nov 2019 22:58:16 -0800 Subject: [PATCH 094/121] Editing stuff to let it compile (see description) Malf AI is no longer available as a roundstart ruleset because antag assignment happens before job assignment. On secret, this is not a problem, but on dynamic, there is no way to make malfunctioning AI limited to certain threat levels except by making it a delayed ruleset. Unfortunately, with the upstream changes, delayed rulesets were removed--all roundstart rulesets are delayed, and if it were to roll malf AI, it would simply error, make a runtime stack trace and, in general, shit the bed. There would be no roundstart antag that round, which is *kind of* a problem I'm desperate to fix. So, no more roundstart malf--it's either that or some rounds having no roundstart antags at all. --- .../gamemodes/dynamic/dynamic_rulesets.dm | 4 +- .../dynamic/dynamic_rulesets_latejoin.dm | 4 +- .../dynamic/dynamic_rulesets_midround.dm | 12 +++- .../dynamic/dynamic_rulesets_roundstart.dm | 56 ------------------- 4 files changed, 13 insertions(+), 63 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index 19ebb79a7f..5d6c262c5e 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -223,11 +223,11 @@ candidates.Remove(P) continue if(antag_flag_override) - if(!(antag_flag_override in P.client.prefs.be_special) || is_banned_from(P.ckey, list(antag_flag_override, ROLE_SYNDICATE))) + if(!(antag_flag_override in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag_override, ROLE_SYNDICATE))) candidates.Remove(P) continue else - if(!(antag_flag in P.client.prefs.be_special) || is_banned_from(P.ckey, list(antag_flag, ROLE_SYNDICATE))) + if(!(antag_flag in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag, ROLE_SYNDICATE))) candidates.Remove(P) continue diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 2718ab62de..3b01136ebd 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -13,11 +13,11 @@ candidates.Remove(P) continue if(antag_flag_override) - if(!(antag_flag_override in P.client.prefs.be_special) || is_banned_from(P.ckey, list(antag_flag_override, ROLE_SYNDICATE))) + if(!(antag_flag_override in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag_override))) candidates.Remove(P) continue else - if(!(antag_flag in P.client.prefs.be_special) || is_banned_from(P.ckey, list(antag_flag, ROLE_SYNDICATE))) + if(!(antag_flag in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag, ROLE_SYNDICATE))) candidates.Remove(P) continue if (P.mind.assigned_role in restricted_roles) // Does their job allow for it? diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 37cd91a9c9..a2dddb7508 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -48,11 +48,11 @@ trimmed_list.Remove(M) continue if(antag_flag_override) - if(!(antag_flag_override in M.client.prefs.be_special) || is_banned_from(M.ckey, list(antag_flag_override, ROLE_SYNDICATE))) + if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, list(antag_flag_override, ROLE_SYNDICATE))) trimmed_list.Remove(M) continue else - if(!(antag_flag in M.client.prefs.be_special) || is_banned_from(M.ckey, list(antag_flag, ROLE_SYNDICATE))) + if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, list(antag_flag, ROLE_SYNDICATE))) trimmed_list.Remove(M) continue if (M.mind) @@ -349,7 +349,13 @@ /datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat=0) if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules) return FALSE // Unavailable if nuke ops were already sent at roundstart - indice_pop = min(operative_cap.len, round(living_players.len/5)+1) + indice_pop = min(10, round(living_players.len/5)+1) + /* NOTE: The above line's magic value of "10" is a hack due to the fact that byond was + not recognizing operative_cap as a defined variable. It should be operative_cap.len-- + and yes, this means that if the len is changed, this variable must be changed along with it. + One day, once the mystery of why this issue was occuring is figured out, + we may change it back, but until this day comes, we must make it simply 10. + */ required_candidates = operative_cap[indice_pop] return ..() diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 554adc2342..fd9e1ae7a4 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -41,62 +41,6 @@ log_game("DYNAMIC: Checking if we can turn someone into a traitor.") mode.picking_specific_rule(/datum/dynamic_ruleset/midround/autotraitor) -////////////////////////////////////////////// -// // -// MALF AI // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/roundstart/malf_ai - name = "Malfunctioning AI" - config_tag = "malf_ai" - antag_datum = /datum/antagonist/traitor - antag_flag = ROLE_MALF - enemy_roles = list("Security Officer", "Warden","Detective","Head of Security", "Captain", "Scientist", "Chemist", "Research Director", "Chief Engineer") - exclusive_roles = list("AI") - required_enemies = list(4,4,4,4,4,4,2,2,2,0) - required_candidates = 1 - weight = 1 - cost = 35 - requirements = list(101,101,101,100,90,80,70,60,50,50) - high_population_requirement = 50 - required_type = /mob/living/silicon/ai - delay = 30 SECONDS - var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) - -/datum/dynamic_ruleset/roundstart/malf_ai/trim_candidates() - ..() - candidates = candidates[CURRENT_LIVING_PLAYERS] - for(var/mob/living/player in candidates) - if(!isAI(player)) - candidates -= player - continue - if(is_centcom_level(player.z)) - candidates -= player - continue - if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0)) - candidates -= player - -/datum/dynamic_ruleset/roundstart/malf_ai/execute() - if(!candidates || !candidates.len) - return FALSE - var/mob/living/silicon/ai/M = pick(candidates) - candidates -= M - assigned += M.mind - var/datum/antagonist/traitor/AI = new - M.mind.special_role = antag_flag - M.mind.add_antag_datum(AI) - return TRUE - -/datum/dynamic_ruleset/roundstart/malf_ai/rule_process() - if (autotraitor_cooldown > 0) - autotraitor_cooldown-- - else - autotraitor_cooldown = 450 // 15 minutes - message_admins("Checking if we can turn someone into a traitor.") - log_game("DYNAMIC: Checking if we can turn someone into a traitor.") - mode.picking_specific_rule(/datum/dynamic_ruleset/midround/autotraitor) - ////////////////////////////////////////// // // // BLOOD BROTHERS // From baf22899d0b4433149b984fbd9cff34a1dc6b746 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 10 Nov 2019 22:59:49 -0800 Subject: [PATCH 095/121] Removed a comment I only kept around for copy+pasting. --- code/game/gamemodes/dynamic/dynamic.dm | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index dbbba3ebc3..e963fe15d3 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -548,29 +548,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) latejoin_rules = remove_from_list(latejoin_rules, rule.type) else if(rule.type == "Midround") midround_rules = remove_from_list(midround_rules, rule.type) - /* - if (rule.execute()) - log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") - spend_threat(rule.cost) - log_threat("[rule.ruletype] [rule.name] spent [rule.cost]") - if(rule.flags & HIGHLANDER_RULESET) - highlander_executed = TRUE - else if(rule.flags & ONLY_RULESET) - only_ruleset_executed = TRUE - if(rule.ruletype == "Latejoin") - var/mob/M = pick(rule.candidates) - message_admins("[key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") - log_game("DYNAMIC: [key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") - executed_rules += rule - rule.candidates.Cut() - if (rule.persistent) - current_rules += rule - return TRUE - else - stack_trace("The [rule.ruletype] rule \"[rule.name]\" failed to execute.") - return FALSE - */ - addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_midround_latejoin_rule, rule), rule.delay) return TRUE From 7535ef8505d4ef837bfb299e0eb4339b36062d20 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 10 Nov 2019 23:09:37 -0800 Subject: [PATCH 096/121] balancing (hopefully more roundstart antags) --- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 4 ++-- .../gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 8 ++++---- config/dynamic_config.txt | 9 ++++----- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index a2dddb7508..2402758776 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -959,7 +959,7 @@ name = "Minor Space Dust" config_tag = "space_dust" typepath = /datum/round_event/space_dust - cost = 3 + cost = 2 enemy_roles = list("Chief Engineer","Station Engineer") required_enemies = list(1,1,1,0,0,0,0,0,0,0) requirements = list(5,5,5,5,5,5,5,5,5,5) @@ -970,7 +970,7 @@ name = "Major Space Dust" config_tag = "major_dust" typepath = /datum/round_event/meteor_wave/major_dust - cost = 10 + cost = 4 enemy_roles = list("Chief Engineer","Station Engineer") required_enemies = list(2,2,2,2,2,2,2,2,2,2) requirements = list(10,10,10,10,10,10,10,10,10,10) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index fd9e1ae7a4..f3d95e873f 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -18,8 +18,8 @@ weight = 5 cost = 10 // Avoid raising traitor threat above 10, as it is the default low cost ruleset. scaling_cost = 10 - requirements = list(60,60,50,50,50,50,50,50,50,50) - high_population_requirement = 50 + requirements = list(50,50,50,50,50,50,50,50,50,50) + high_population_requirement = 40 antag_cap = list(1,1,1,1,2,2,2,2,3,3) var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) @@ -202,7 +202,7 @@ required_candidates = 2 weight = 3 cost = 30 - requirements = list(101,101,101,100,90,80,70,60,50,50) + requirements = list(101,101,101,80,70,60,50,50,50,50) high_population_requirement = 50 flags = HIGHLANDER_RULESET antag_cap = list(2,2,2,3,3,4,4,4,4,4) @@ -494,7 +494,7 @@ required_candidates = 4 weight = 3 cost = 35 - requirements = list(101,101,101,100,90,80,70,60,50,50) + requirements = list(101,101,101,80,70,60,50,50,50,50) high_population_requirement = 50 flags = HIGHLANDER_RULESET antag_cap = list(2,3,3,4,4,4,4,4,4,4) diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index df9acef64b..57998bf9b3 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -137,8 +137,8 @@ DYNAMIC_COST BRAND_INTELLIGENCE 5 DYNAMIC_COST CARP_MIGRATION 3 DYNAMIC_COST COMMUNICATIONS_BLACKOUT 5 DYNAMIC_COST PROCESSOR_OVERLOAD 5 -DYNAMIC_COST SPACE_DUST 5 -DYNAMIC_COST MAJOR_DUST 10 +DYNAMIC_COST SPACE_DUST 2 +DYNAMIC_COST MAJOR_DUST 4 DYNAMIC_COST ELECTRICAL_STORM 1 DYNAMIC_COST HEART_ATTACK 1 DYNAMIC_COST RADIATION_STORM 3 @@ -152,15 +152,14 @@ DYNAMIC_COST LATEJOIN_REVOLUTION 20 ## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-8, 30 at 9-17 etc. DYNAMIC_REQUIREMENTS TRAITOR 50 50 50 50 50 50 50 50 50 50 DYNAMIC_REQUIREMENTS TRAITORBRO 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS MALF_AI 101 101 101 100 90 80 70 60 50 50 DYNAMIC_REQUIREMENTS CHANGELING 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS WIZARD 101 101 101 60 50 50 50 50 50 50 -DYNAMIC_REQUIREMENTS CULT 101 101 101 100 90 80 70 60 50 50 +DYNAMIC_REQUIREMENTS CULT 101 101 101 80 70 60 50 50 50 50 DYNAMIC_REQUIREMENTS NUCLEAR 101 101 101 70 60 50 50 50 50 50 DYNAMIC_REQUIREMENTS REVOLUTION 101 101 101 80 70 60 50 50 50 50 # All below are impossible-by-default DYNAMIC_REQUIREMENTS EXTENDED 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 101 101 101 100 90 80 70 60 50 50 +DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 101 101 101 80 70 60 50 50 50 50 DYNAMIC_REQUIREMENTS CLOWNOPS 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS DEVIL 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS MONKEY 101 101 101 101 101 101 101 101 101 101 From 23a2c24badaa54a44ea5af0aee1a6e8cef9e8af3 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 10 Nov 2019 23:25:25 -0800 Subject: [PATCH 097/121] ok from_ghosts the worst part is that putting this boilerplate as a base part of the proc probably isn't even advisable. I hate it. --- .../dynamic/dynamic_rulesets_midround.dm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 2402758776..61f04a3b41 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -394,6 +394,11 @@ high_population_requirement = 50 repeatable = TRUE +/datum/dynamic_ruleset/midround/from_ghosts/blob/ready(forced = FALSE) + if (required_candidates > (dead_players.len + list_observers.len)) + return FALSE + return ..() + /datum/dynamic_ruleset/midround/from_ghosts/blob/generate_ruleset_body(mob/applicant) var/body = applicant.become_overmind() return body @@ -419,6 +424,11 @@ repeatable = TRUE var/list/vents = list() +/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/ready(forced = FALSE) + if (required_candidates > (dead_players.len + list_observers.len)) + return FALSE + return ..() + /datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute() // 50% chance of being incremented by one required_candidates += prob(50) @@ -512,6 +522,11 @@ requirements = list(30,30,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"! high_population_requirement = 5 +/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/ready(forced = FALSE) + if (required_candidates > (dead_players.len + list_observers.len)) + return FALSE + return ..() + /datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/generate_ruleset_body(mob/applicant) var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center()) applicant.transfer_ckey(virus, FALSE) From 5466ebc1ceb5e8ed2a4a44bd4884fbf99f2b1a2a Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 10 Nov 2019 23:26:04 -0800 Subject: [PATCH 098/121] elligible more like illegible --- code/game/gamemodes/dynamic/dynamic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index e963fe15d3..e4e7746eeb 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -593,7 +593,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) current_rules += new_rule return TRUE else if (forced) - log_game("DYNAMIC: The ruleset [new_rule.name] couldn't be executed due to lack of elligible players.") + log_game("DYNAMIC: The ruleset [new_rule.name] couldn't be executed due to lack of eligible players.") return FALSE /// Mainly here to facilitate delayed rulesets. All midround/latejoin rulesets are executed with a timered callback to this proc. From c7ac41f8802beb1ae0c5f4ae87e08c5d6d25500c Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 10 Nov 2019 23:35:20 -0800 Subject: [PATCH 099/121] added weights, repeatable weight decreases --- .../dynamic/dynamic_rulesets_midround.dm | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 61f04a3b41..826bc6b593 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -421,6 +421,7 @@ cost = 10 requirements = list(101,101,101,70,50,50,50,50,50,50) high_population_requirement = 50 + repeatable_weight_decrease = 2 repeatable = TRUE var/list/vents = list() @@ -474,6 +475,7 @@ cost = 10 requirements = list(101,101,101,70,50,40,20,15,15,15) high_population_requirement = 50 + repeatable_weight_decrease = 2 repeatable = TRUE var/list/spawn_locs = list() @@ -654,6 +656,7 @@ requirements = list(80,80,70,50,40,30,30,20,15,15) high_population_requirement = 15 var/datum/team/abductor_team/team + repeatable_weight_decrease = 4 repeatable = TRUE /datum/dynamic_ruleset/midround/from_ghosts/abductors/acceptable(population=0, threat=0) @@ -787,6 +790,8 @@ enemy_roles = list("Chemist","Medical Doctor","Chief Medical Officer") required_enemies = list(1,1,1,0,0,0,0,0,0,0) cost = 2 + weight = 4 + repeatable_weight_decrease = 2 requirements = list(5,5,5,5,5,5,5,5,5,5) // yes, can happen on fake-extended high_population_requirement = 5 repeatable = TRUE @@ -797,6 +802,8 @@ typepath = /datum/round_event/vent_clog/threatening required_enemies = list(2,2,1,1,1,1,0,0,0,0) cost = 5 + weight = 4 + repeatable_weight_decrease = 2 requirements = list(15,15,15,15,15,15,15,15,15,15) // doesn't really scale with pop, so high_population_requirement = 15 repeatable = TRUE @@ -807,6 +814,8 @@ typepath = /datum/round_event/vent_clog/catastrophic required_enemies = list(3,3,3,2,2,2,1,1,1,1) cost = 15 + weight = 4 + repeatable_weight_decrease = 2 requirements = list(30,30,30,30,30,30,30,30,30,30) high_population_requirement = 30 repeatable = TRUE @@ -823,6 +832,8 @@ typepath = /datum/round_event/ion_storm enemy_roles = list("Research Director","Captain","Chief Engineer") required_enemies = list(1,1,0,0,0,0,0,0,0,0) + weight = 4 + // no repeatable weight decrease. too variable to be unfun multiple times in one round cost = 3 requirements = list(5,5,5,5,5,5,5,5,5,5) high_population_requirement = 5 @@ -841,6 +852,8 @@ enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Captain","Cyborg") required_enemies = list(2,2,2,2,2,2,2,2,2,2) cost = 15 + weight = 3 + repeatable_weight_decrease = 2 requirements = list(60,50,40,30,30,30,30,30,30,30) high_population_requirement = 30 repeatable = TRUE @@ -850,6 +863,8 @@ config_tag = "meteor_wave_threatening" typepath = /datum/round_event/meteor_wave/threatening cost = 25 + weight = 3 + repeatable_weight_decrease = 2 requirements = list(80,70,60,50,40,40,40,40,40,40) high_population_requirement = 40 repeatable = TRUE @@ -859,6 +874,8 @@ config_tag = "meteor_wave_catastrophic" typepath = /datum/round_event/meteor_wave/catastrophic cost = 40 + weight = 3 + repeatable_weight_decrease = 2 requirements = list(101,100,90,80,70,60,50,50,50,50) high_population_requirement = 50 repeatable = TRUE @@ -875,6 +892,8 @@ typepath = /datum/round_event/anomaly/anomaly_bluespace enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain") required_enemies = list(1,1,1,0,0,0,0,0,0,0) + weight = 2 + repeatable_weight_decrease = 1 cost = 3 requirements = list(5,5,5,5,5,5,5,5,5,5) high_population_requirement = 5 @@ -886,6 +905,8 @@ typepath = /datum/round_event/anomaly/anomaly_flux enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain") required_enemies = list(1,1,1,0,0,0,0,0,0,0) + weight = 2 + repeatable_weight_decrease = 1 cost = 5 requirements = list(5,5,5,5,5,5,5,5,5,5) high_population_requirement = 10 @@ -895,6 +916,8 @@ name = "Anomaly: Gravitational" config_tag = "anomaly_gravitational" typepath = /datum/round_event/anomaly/anomaly_grav + weight = 2 + repeatable_weight_decrease = 1 cost = 3 requirements = list(5,5,5,5,5,5,5,5,5,5) high_population_requirement = 5 @@ -904,6 +927,8 @@ name = "Anomaly: Pyroclastic" config_tag = "anomaly_pyroclastic" typepath = /datum/round_event/anomaly/anomaly_pyro + weight = 2 + repeatable_weight_decrease = 1 cost = 5 enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") required_enemies = list(1,1,1,1,1,1,1,1,1,1) @@ -915,6 +940,8 @@ name = "Anomaly: Vortex" config_tag = "anomaly_vortex" typepath = /datum/round_event/anomaly/anomaly_vortex + weight = 2 + repeatable_weight_decrease = 1 cost = 5 enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") required_enemies = list(1,1,1,1,1,1,1,1,1,1) @@ -932,6 +959,8 @@ name = "Brand Intelligence" config_tag = "brand_intelligence" typepath = /datum/round_event/brand_intelligence + weight = 1 + repeatable_weight_decrease = 1 cost = 2 enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") required_enemies = list(1,1,1,1,0,0,0,0,0,0) @@ -943,6 +972,8 @@ name = "Carp Migration" config_tag = "carp_migration" typepath = /datum/round_event/carp_migration + weight = 7 + repeatable_weight_decrease = 3 cost = 4 requirements = list(10,10,10,10,10,10,10,10,10,10) high_population_requirement = 10 @@ -953,6 +984,8 @@ config_tag = "communications_blackout" typepath = /datum/round_event/communications_blackout cost = 4 + weight = 2 + repeatable_weight_decrease = 3 enemy_roles = list("Chief Engineer","Station Engineer") required_enemies = list(1,1,1,0,0,0,0,0,0,0) requirements = list(5,5,5,5,5,5,5,5,5,5) @@ -964,6 +997,8 @@ config_tag = "processor_overload" typepath = /datum/round_event/processor_overload cost = 4 + weight = 2 + repeatable_weight_decrease = 3 enemy_roles = list("Chief Engineer","Station Engineer") required_enemies = list(1,1,1,0,0,0,0,0,0,0) requirements = list(5,5,5,5,5,5,5,5,5,5) @@ -975,6 +1010,8 @@ config_tag = "space_dust" typepath = /datum/round_event/space_dust cost = 2 + weight = 2 + repeatable_weight_decrease = 1 enemy_roles = list("Chief Engineer","Station Engineer") required_enemies = list(1,1,1,0,0,0,0,0,0,0) requirements = list(5,5,5,5,5,5,5,5,5,5) @@ -986,6 +1023,8 @@ config_tag = "major_dust" typepath = /datum/round_event/meteor_wave/major_dust cost = 4 + weight = 2 + repeatable_weight_decrease = 1 enemy_roles = list("Chief Engineer","Station Engineer") required_enemies = list(2,2,2,2,2,2,2,2,2,2) requirements = list(10,10,10,10,10,10,10,10,10,10) @@ -997,6 +1036,8 @@ config_tag = "electrical_storm" typepath = /datum/round_event/electrical_storm cost = 1 + weight = 2 + repeatable_weight_decrease = 1 enemy_roles = list("Chief Engineer","Station Engineer") required_enemies = list(1,1,1,0,0,0,0,0,0,0) requirements = list(5,5,5,5,5,5,5,5,5,5) @@ -1008,6 +1049,8 @@ config_tag = "heart_attack" typepath = /datum/round_event/heart_attack cost = 3 + weight = 2 + repeatable_weight_decrease = 1 enemy_roles = list("Medical Doctor","Chief Medical Officer") required_enemies = list(2,2,2,2,2,2,2,2,2,2) requirements = list(101,101,101,5,5,5,5,5,5,5) @@ -1019,6 +1062,7 @@ config_tag = "radiation_storm" typepath = /datum/round_event/radiation_storm cost = 3 + weight = 1 enemy_roles = list("Chemist","Chief Medical Officer","Geneticist","Medical Doctor","AI","Captain") required_enemies = list(1,1,1,1,1,1,1,1,1,1) requirements = list(5,5,5,5,5,5,5,5,5,5) From d13301312de5dca6681e9a7d804b02325d124df0 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 11 Nov 2019 00:04:51 -0800 Subject: [PATCH 100/121] made forced midround antags increase weight by their cost This is to make sure that threat is really, really used throughout a round, or at least to encourage it to be--people are rightfully annoyed at 70 threat level rounds just not using the vast majority of it. --- code/game/gamemodes/dynamic/dynamic.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index e4e7746eeb..f741cbb62b 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -647,6 +647,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) update_playercounts() if (get_injection_chance()) + var/cur_threat_frac = threat/threat_level var/list/drafted_rules = list() var/antag_num = current_players[CURRENT_LIVING_ANTAGS].len for (var/datum/dynamic_ruleset/midround/rule in midround_rules) @@ -658,7 +659,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) continue rule.trim_candidates() if (rule.ready()) - drafted_rules[rule] = rule.get_weight() + if(!antag_num) + drafted_rules[rule] = round(rule.get_weight() + (rule.cost * cur_threat_frac)) + else + drafted_rules[rule] = rule.get_weight() if (drafted_rules.len > 0) picking_midround_latejoin_rule(drafted_rules) else From 5f683b0effdebfb7d7b8810fd9ee9d25a4adaf66 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 11 Nov 2019 00:05:35 -0800 Subject: [PATCH 101/121] Let's make those roundstarts more likely. --- code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 2 +- config/dynamic_config.txt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index f3d95e873f..44183f7246 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -348,7 +348,7 @@ weight = 2 delay = 7 MINUTES cost = 35 - requirements = list(101,101,101,80,70,60,50,50,50,50) + requirements = list(101,101,101,60,50,50,50,50,50,50) high_population_requirement = 50 antag_cap = list(3,3,3,3,3,3,3,3,3,3) flags = HIGHLANDER_RULESET diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 57998bf9b3..0d43e67636 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -154,9 +154,9 @@ DYNAMIC_REQUIREMENTS TRAITOR 50 50 50 50 50 50 50 50 50 50 DYNAMIC_REQUIREMENTS TRAITORBRO 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS CHANGELING 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS WIZARD 101 101 101 60 50 50 50 50 50 50 -DYNAMIC_REQUIREMENTS CULT 101 101 101 80 70 60 50 50 50 50 -DYNAMIC_REQUIREMENTS NUCLEAR 101 101 101 70 60 50 50 50 50 50 -DYNAMIC_REQUIREMENTS REVOLUTION 101 101 101 80 70 60 50 50 50 50 +DYNAMIC_REQUIREMENTS CULT 101 101 101 60 50 50 50 50 50 50 +DYNAMIC_REQUIREMENTS NUCLEAR 101 101 101 60 50 50 50 50 50 50 +DYNAMIC_REQUIREMENTS REVOLUTION 101 101 101 60 50 50 50 50 50 50 # All below are impossible-by-default DYNAMIC_REQUIREMENTS EXTENDED 101 101 101 101 101 101 101 101 101 101 DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 101 101 101 80 70 60 50 50 50 50 From 0c50d39ddcf28e3417baaeb8c0fb9c5e8525536f Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 11 Nov 2019 05:12:36 -0800 Subject: [PATCH 102/121] the "latejoiners count too" commit --- code/game/gamemodes/dynamic/dynamic.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index f741cbb62b..7e35e74a5c 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -387,7 +387,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) message_admins("Drafting players for forced ruleset [rule.name].") log_game("DYNAMIC: Drafting players for forced ruleset [rule.name].") rule.mode = src - rule.acceptable(roundstart_pop_ready, threat_level) // Assigns some vars in the modes, running it here for consistency + rule.acceptable(GLOB.player_list.len, threat_level) // Assigns some vars in the modes, running it here for consistency rule.candidates = candidates.Copy() rule.trim_candidates() if (rule.ready(TRUE)) @@ -399,7 +399,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) return TRUE var/list/drafted_rules = list() for (var/datum/dynamic_ruleset/roundstart/rule in roundstart_rules) - if (rule.acceptable(roundstart_pop_ready, threat_level) && threat >= rule.cost) // If we got the population and threat required + if (rule.acceptable(GLOB.player_list.len, threat_level) && threat >= rule.cost) // If we got the population and threat required rule.candidates = candidates.Copy() rule.trim_candidates() if (rule.ready() && rule.candidates.len > 0) @@ -407,12 +407,12 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if(!drafted_rules.len) message_admins("Not enough threat level for roundstart antags!") log_game("DYNAMIC: Not enough threat level for roundstart antags!") - var/indice_pop = min(10,round(roundstart_pop_ready/pop_per_requirement)+1) + var/indice_pop = min(10,round(GLOB.player_list.len/pop_per_requirement)+1) extra_rulesets_amount = 0 if (GLOB.dynamic_classic_secret) extra_rulesets_amount = 0 else - if (roundstart_pop_ready > GLOB.dynamic_high_pop_limit) + if (GLOB.player_list.len > GLOB.dynamic_high_pop_limit) message_admins("High Population Override is in effect! Threat Level will have more impact on which roles will appear, and player population less.") log_game("DYNAMIC: High Population Override is in effect! Threat Level will have more impact on which roles will appear, and player population less.") if (threat_level > high_pop_second_rule_req) From 42d94e6cae5ec723409a88d801f827b0ee7d53e9 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 12 Nov 2019 02:57:31 -0800 Subject: [PATCH 103/121] Rethink events (see desc) Made events their own ruletype, made the duplicated-with-different-threats events are now one event with shared values that can scale theirselves up. Also fixed **MIDROUND ANTAGS NOT WORKING AT ALL BECAUSE THEY WERE LOOKING FOR ENEMIES ONLY AMONG PLAYERS ELIGIBLE FOR THE ANTAG WTF** --- code/game/gamemodes/dynamic/dynamic.dm | 42 ++- .../dynamic/dynamic_rulesets_events.dm | 345 +++++++++++++++++ .../dynamic/dynamic_rulesets_midround.dm | 349 +----------------- tgstation.dme | 1 + 4 files changed, 383 insertions(+), 354 deletions(-) create mode 100644 code/game/gamemodes/dynamic/dynamic_rulesets_events.dm diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 7e35e74a5c..a2fb71ee04 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -14,8 +14,12 @@ GLOBAL_VAR_INIT(dynamic_latejoin_delay_min, (10 MINUTES)) GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (30 MINUTES)) -GLOBAL_VAR_INIT(dynamic_midround_delay_min, (5 MINUTES)) -GLOBAL_VAR_INIT(dynamic_midround_delay_max, (15 MINUTES)) +GLOBAL_VAR_INIT(dynamic_midround_delay_min, (10 MINUTES)) +GLOBAL_VAR_INIT(dynamic_midround_delay_max, (30 MINUTES)) + +GLOBAL_VAR_INIT(dynamic_event_delay_min, (5 MINUTES)) +GLOBAL_VAR_INIT(dynamic_event_delay_max, (20 MINUTES)) // this is on top of regular events, so can't be quite as often + // -- Roundstart injection delays GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_min, (2 MINUTES)) @@ -76,6 +80,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/list/latejoin_rules = list() /// List of midround rules used for selecting the rules. var/list/midround_rules = list() + /// List of events used for reducing threat without causing antag injection (necessarily). + var/list/events = list() /** # Pop range per requirement. * If the value is five the range is: * 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-54, 45+ @@ -113,6 +119,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/latejoin_injection_cooldown = 0 /// When world.time is over this number the mode tries to inject a midround ruleset. var/midround_injection_cooldown = 0 + /// When wor.dtime is over this number the mode tries to do an event. + var/event_injection_cooldown = 0 /// When TRUE GetInjectionChance returns 100. var/forced_injection = FALSE /// Forced ruleset to be executed for the next latejoin. @@ -173,6 +181,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) dat += "
Injection Timers: ([get_injection_chance(TRUE)]% chance)
" dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)] seconds"] \[Now!\]
" dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)] seconds"] \[Now!\]
" + dat += "Event: [(event_injection_cooldown-world.time)>60*10 ? "[round((event_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(event_injection_cooldown-world.time)] seconds"] \[Now!\]
" usr << browse(dat.Join(), "window=gamemode_panel;size=500x500") /datum/game_mode/dynamic/Topic(href, href_list) @@ -204,6 +213,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) midround_injection_cooldown = 0 forced_injection = TRUE message_admins("[key_name(usr)] forced a midround injection.", 1) + else if (href_list["forceevent"]) + event_injection_cooldown = 0 + // events always happen anyway + message_admins("[key_name(usr)] forced an event.", 1) else if (href_list["threatlog"]) show_threatlog(usr) else if (href_list["stacking_limit"]) @@ -348,6 +361,9 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if ("Midround") if (ruleset.weight) midround_rules += ruleset + if("Event") + if(ruleset.weight) + events += ruleset for(var/mob/dead/new_player/player in GLOB.player_list) if(player.ready == PLAYER_READY_TO_PLAY && player.mind) roundstart_pop_ready++ @@ -548,6 +564,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) latejoin_rules = remove_from_list(latejoin_rules, rule.type) else if(rule.type == "Midround") midround_rules = remove_from_list(midround_rules, rule.type) + else if(rule.type == "Event") + events = remove_from_list(events,rule.type) addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_midround_latejoin_rule, rule), rule.delay) return TRUE @@ -641,7 +659,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) // Time to inject some threat into the round if(EMERGENCY_ESCAPED_OR_ENDGAMED) // Unless the shuttle is gone return - message_admins("DYNAMIC: Checking for midround injection.") log_game("DYNAMIC: Checking for midround injection.") @@ -651,9 +668,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/list/drafted_rules = list() var/antag_num = current_players[CURRENT_LIVING_ANTAGS].len for (var/datum/dynamic_ruleset/midround/rule in midround_rules) - var/antag_acceptable = (antag_num || !isnull(rule.antag_flag)) // if there are antags OR the rule is an antag rule, antag_acceptable will be true. - if (antag_acceptable && rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost) + if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost) // Classic secret : only autotraitor/minor roles if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET))) continue @@ -667,7 +683,21 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) picking_midround_latejoin_rule(drafted_rules) else midround_injection_cooldown = (midround_injection_cooldown + world.time)/2 - + + if(event_injection_cooldown < world.time) + var/event_injection_cooldown_middle = 0.5*(GLOB.dynamic_event_delay_max + GLOB.dynamic_event_delay_min) + event_injection_cooldown = (round(CLAMP(EXP_DISTRIBUTION(event_injection_cooldown_middle), GLOB.dynamic_event_delay_min, GLOB.dynamic_event_delay_max)) + world.time) + message_admins("DYNAMIC: Doing event injection.") + log_game("DYNAMIC: Doing event injection.") + update_playercounts() + var/list/drafted_rules = list() + for(var/datum/dynamic_ruleset/event/rule in events) + if(rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && threat >= rule.cost) + if(rule.ready()) + drafted_rules[rule] = rule.get_weight() + if(drafted_rules.len > 0) + picking_midround_latejoin_rule(drafted_rules) + /// Updates current_players. /datum/game_mode/dynamic/proc/update_playercounts() current_players[CURRENT_LIVING_PLAYERS] = list() diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm new file mode 100644 index 0000000000..707b0b6b5b --- /dev/null +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm @@ -0,0 +1,345 @@ +/datum/dynamic_ruleset/event + ruletype = "Event" + var/typepath // typepath of the event + var/triggering + +/datum/dynamic_ruleset/event/execute() + var/datum/round_event/E = new typepath() + E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1) + // E.control = src // can't be done! we just don't use events that require these, those can be from_ghost almost always + + testing("[time2text(world.time, "hh:mm:ss")] [E.type]") + deadchat_broadcast("[name] has just been triggered by dynamic!") + log_game("Random Event triggering: [name] ([typepath])") + + return E + +/datum/dynamic_ruleset/event/ready(forced = FALSE) // same as midround cause we're still using enemy system + if (!forced) + var/job_check = 0 + if (enemy_roles.len > 0) + for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS]) + if (M.stat == DEAD) + continue // Dead players cannot count as opponents + if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles)) + job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it + + var/threat = round(mode.threat_level/10) + if (job_check < required_enemies[threat]) + return FALSE + return TRUE + +////////////////////////////////////////////// +// // +// PIRATES // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/event/pirates + name = "Space Pirates" + config_tag = "pirates" + typepath = /datum/round_event/pirates + antag_flag = ROLE_TRAITOR + enemy_roles = list("AI","Security Officer","Head of Security","Captain") + required_enemies = list(2,2,1,1,0,0,0,0,0,0) + weight = 5 + cost = 10 + requirements = list(70,60,50,50,40,40,40,30,20,15) + high_population_requirement = 15 + +/datum/dynamic_ruleset/event/pirates/ready(forced = FALSE) + if (!SSmapping.empty_space) + return FALSE + return ..() + +////////////////////////////////////////////// +// // +// SPIDERS // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/event/spiders + name = "Spider Infestation" + config_tag = "spiders" + typepath = /datum/round_event/spider_infestation + enemy_roles = list("AI","Security Officer","Head of Security","Captain") + required_enemies = list(2,2,1,1,0,0,0,0,0,0) + weight = 5 + cost = 10 + requirements = list(70,60,50,50,40,40,40,30,20,15) + high_population_requirement = 15 + +////////////////////////////////////////////// +// // +// CLOGGED VENTS // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/event/ventclog + name = "Clogged Vents" + config_tag = "ventclog" + typepath = /datum/round_event/vent_clog + enemy_roles = list("Chemist","Medical Doctor","Chief Medical Officer") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + cost = 2 + weight = 4 + repeatable_weight_decrease = 3 + requirements = list(5,5,5,5,5,5,5,5,5,5) // yes, can happen on fake-extended + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/event/ventclog/ready() + if(mode.threat_level > 30 && mode.threat >= 5 && prob(20)) + name = "Clogged Vents: Threatening" + cost = 5 + required_enemies = list(3,3,3,2,2,2,1,1,1,1) + typepath = /datum/round_event/vent_clog/threatening + else if(mode.threat_level > 15 && mode.threat > 15 && prob(30)) + name = "Clogged Vents: Catastrophic" + cost = 15 + required_enemies = list(2,2,1,1,1,1,0,0,0,0) + typepath = /datum/round_event/vent_clog/catastrophic + else + cost = 2 + name = "Clogged Vents: Normal" + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + typepath = /datum/round_event/vent_clog + return ..() + +////////////////////////////////////////////// +// // +// ION STORM // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/event/ion_storm + name = "Ion Storm" + config_tag = "ion_storm" + typepath = /datum/round_event/ion_storm + enemy_roles = list("Research Director","Captain","Chief Engineer") + required_enemies = list(1,1,0,0,0,0,0,0,0,0) + weight = 4 + // no repeatable weight decrease. too variable to be unfun multiple times in one round + cost = 3 + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +////////////////////////////////////////////// +// // +// METEORS // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/event/meteor_wave + name = "Meteor Wave" + config_tag = "meteor_wave" + typepath = /datum/round_event/meteor_wave + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Captain","Cyborg") + required_enemies = list(3,3,3,3,3,3,3,3,3,3) + cost = 15 + weight = 3 + repeatable_weight_decrease = 2 + requirements = list(60,50,40,30,30,30,30,30,30,30) + high_population_requirement = 30 + repeatable = TRUE + +/datum/dynamic_ruleset/event/meteor_wave/ready() + if(mode.threat_level > 40 && mode.threat >= 25 && prob(20)) + cost = 25 + typepath = /datum/round_event/meteor_wave/threatening + else if(mode.threat_level > 50 && mode.threat >= 40 && prob(30)) + cost = 40 + typepath = /datum/round_event/meteor_wave/catastrophic + else + cost = 15 + typepath = /datum/round_event/meteor_wave + return ..() + +////////////////////////////////////////////// +// // +// ANOMALIES // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/event/anomaly_bluespace + name = "Anomaly: Bluespace" + config_tag = "anomaly_bluespace" + typepath = /datum/round_event/anomaly/anomaly_bluespace + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + weight = 2 + repeatable_weight_decrease = 1 + cost = 3 + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/event/anomaly_flux + name = "Anomaly: Hyper-Energetic Flux" + config_tag = "anomaly_flux" + typepath = /datum/round_event/anomaly/anomaly_flux + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + weight = 2 + repeatable_weight_decrease = 1 + cost = 5 + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/event/anomaly_gravitational + name = "Anomaly: Gravitational" + config_tag = "anomaly_gravitational" + typepath = /datum/round_event/anomaly/anomaly_grav + weight = 2 + repeatable_weight_decrease = 1 + cost = 3 + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/event/anomaly_pyroclastic + name = "Anomaly: Pyroclastic" + config_tag = "anomaly_pyroclastic" + typepath = /datum/round_event/anomaly/anomaly_pyro + weight = 2 + repeatable_weight_decrease = 1 + cost = 5 + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") + required_enemies = list(1,1,1,1,1,1,1,1,1,1) + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/event/anomaly_vortex + name = "Anomaly: Vortex" + config_tag = "anomaly_vortex" + typepath = /datum/round_event/anomaly/anomaly_vortex + weight = 2 + repeatable_weight_decrease = 1 + cost = 5 + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") + required_enemies = list(1,1,1,1,1,1,1,1,1,1) + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +////////////////////////////////////////////// +// // +// WOW THAT'S A LOT OF EVENTS // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/event/brand_intelligence + name = "Brand Intelligence" + config_tag = "brand_intelligence" + typepath = /datum/round_event/brand_intelligence + weight = 1 + repeatable_weight_decrease = 1 + cost = 2 + enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") + required_enemies = list(1,1,1,1,0,0,0,0,0,0) + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/event/carp_migration + name = "Carp Migration" + config_tag = "carp_migration" + typepath = /datum/round_event/carp_migration + weight = 7 + repeatable_weight_decrease = 3 + cost = 4 + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/event/communications_blackout + name = "Communications Blackout" + config_tag = "communications_blackout" + typepath = /datum/round_event/communications_blackout + cost = 4 + weight = 2 + repeatable_weight_decrease = 3 + enemy_roles = list("Chief Engineer","Station Engineer") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/event/processor_overload + name = "Processer Overload" + config_tag = "processor_overload" + typepath = /datum/round_event/processor_overload + cost = 4 + weight = 2 + repeatable_weight_decrease = 3 + enemy_roles = list("Chief Engineer","Station Engineer") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/event/space_dust + name = "Minor Space Dust" + config_tag = "space_dust" + typepath = /datum/round_event/space_dust + cost = 2 + weight = 2 + repeatable_weight_decrease = 1 + enemy_roles = list("Chief Engineer","Station Engineer") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/event/major_dust + name = "Major Space Dust" + config_tag = "major_dust" + typepath = /datum/round_event/meteor_wave/major_dust + cost = 4 + weight = 2 + repeatable_weight_decrease = 1 + enemy_roles = list("Chief Engineer","Station Engineer") + required_enemies = list(2,2,2,2,2,2,2,2,2,2) + requirements = list(10,10,10,10,10,10,10,10,10,10) + high_population_requirement = 10 + repeatable = TRUE + +/datum/dynamic_ruleset/event/electrical_storm + name = "Electrical Storm" + config_tag = "electrical_storm" + typepath = /datum/round_event/electrical_storm + cost = 1 + weight = 2 + repeatable_weight_decrease = 1 + enemy_roles = list("Chief Engineer","Station Engineer") + required_enemies = list(1,1,1,0,0,0,0,0,0,0) + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/event/heart_attack + name = "Random Heart Attack" + config_tag = "heart_attack" + typepath = /datum/round_event/heart_attack + cost = 3 + weight = 2 + repeatable_weight_decrease = 1 + enemy_roles = list("Medical Doctor","Chief Medical Officer") + required_enemies = list(2,2,2,2,2,2,2,2,2,2) + requirements = list(101,101,101,5,5,5,5,5,5,5) + high_population_requirement = 5 + repeatable = TRUE + +/datum/dynamic_ruleset/event/radiation_storm + name = "Radiation Storm" + config_tag = "radiation_storm" + typepath = /datum/round_event/radiation_storm + cost = 3 + weight = 1 + enemy_roles = list("Chemist","Chief Medical Officer","Geneticist","Medical Doctor","AI","Captain") + required_enemies = list(1,1,1,1,1,1,1,1,1,1) + requirements = list(5,5,5,5,5,5,5,5,5,5) + high_population_requirement = 5 diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 826bc6b593..c6f85a40b3 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -24,11 +24,6 @@ /// Whether the ruleset should call generate_ruleset_body or not. var/makeBody = TRUE -/datum/dynamic_ruleset/midround/event // Doesn't assume an antag - required_type = /mob - var/typepath // typepath of the event - var/triggering - /datum/dynamic_ruleset/midround/trim_candidates() living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS]) living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS]) @@ -76,7 +71,7 @@ if (!forced) var/job_check = 0 if (enemy_roles.len > 0) - for (var/mob/M in living_players) + for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS]) if (M.stat == DEAD) continue // Dead players cannot count as opponents if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles))) @@ -166,23 +161,6 @@ /datum/dynamic_ruleset/midround/from_ghosts/proc/setup_role(datum/antagonist/new_role) return -/datum/dynamic_ruleset/midround/event/trim_list(list/L = list()) - return L.Copy() // we're not drafting ghosts here - -/datum/dynamic_ruleset/midround/event/ready(forced = FALSE) - return TRUE - -/datum/dynamic_ruleset/midround/event/execute() - var/datum/round_event/E = new typepath() - E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1) - // E.control = src // can't be done! we just don't use events that require these, those can be from_ghost almost always - - testing("[time2text(world.time, "hh:mm:ss")] [E.type]") - deadchat_broadcast("[name] has just been triggered by dynamic!") - log_game("Random Event triggering: [name] ([typepath])") - - return E - ////////////////////////////////////////////// // // // SYNDICATE TRAITORS // @@ -743,330 +721,5 @@ log_game("[key_name(Ninja)] was spawned as a ninja by dynamic.") return Ninja -/datum/dynamic_ruleset/midround/event/pirates - name = "Space Pirates" - config_tag = "pirates" - typepath = /datum/round_event/pirates - antag_flag = ROLE_TRAITOR - enemy_roles = list("AI","Security Officer","Head of Security","Captain") - required_enemies = list(2,2,1,1,0,0,0,0,0,0) - weight = 5 - cost = 10 - requirements = list(70,60,50,50,40,40,40,30,20,15) - high_population_requirement = 15 - -/datum/dynamic_ruleset/midround/event/pirates/ready(forced = FALSE) - if (!SSmapping.empty_space) - return FALSE - return ..() - -////////////////////////////////////////////// -// // -// SPIDERS // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/midround/event/spiders - name = "Spider Infestation" - config_tag = "spiders" - typepath = /datum/round_event/spider_infestation - enemy_roles = list("AI","Security Officer","Head of Security","Captain") - required_enemies = list(2,2,1,1,0,0,0,0,0,0) - weight = 5 - cost = 10 - requirements = list(70,60,50,50,40,40,40,30,20,15) - high_population_requirement = 15 - -////////////////////////////////////////////// -// // -// CLOGGED VENTS // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/midround/event/ventclog - name = "Clogged Vents: Normal" - config_tag = "ventclog_normal" - typepath = /datum/round_event/vent_clog - enemy_roles = list("Chemist","Medical Doctor","Chief Medical Officer") - required_enemies = list(1,1,1,0,0,0,0,0,0,0) - cost = 2 - weight = 4 - repeatable_weight_decrease = 2 - requirements = list(5,5,5,5,5,5,5,5,5,5) // yes, can happen on fake-extended - high_population_requirement = 5 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/ventclog/threatening - name = "Clogged Vents: Threatening" - config_tag = "ventclog_threatening" - typepath = /datum/round_event/vent_clog/threatening - required_enemies = list(2,2,1,1,1,1,0,0,0,0) - cost = 5 - weight = 4 - repeatable_weight_decrease = 2 - requirements = list(15,15,15,15,15,15,15,15,15,15) // doesn't really scale with pop, so - high_population_requirement = 15 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/ventclog/catastrophic - name = "Clogged Vents: Catastrophic" - config_tag = "ventclog_catostrophic" - typepath = /datum/round_event/vent_clog/catastrophic - required_enemies = list(3,3,3,2,2,2,1,1,1,1) - cost = 15 - weight = 4 - repeatable_weight_decrease = 2 - requirements = list(30,30,30,30,30,30,30,30,30,30) - high_population_requirement = 30 - repeatable = TRUE - -////////////////////////////////////////////// -// // -// ION STORM // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/midround/event/ion_storm - name = "Ion Storm" - config_tag = "ion_storm" - typepath = /datum/round_event/ion_storm - enemy_roles = list("Research Director","Captain","Chief Engineer") - required_enemies = list(1,1,0,0,0,0,0,0,0,0) - weight = 4 - // no repeatable weight decrease. too variable to be unfun multiple times in one round - cost = 3 - requirements = list(5,5,5,5,5,5,5,5,5,5) - high_population_requirement = 5 - repeatable = TRUE - -////////////////////////////////////////////// -// // -// METEORS // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/midround/event/meteor_wave - name = "Meteor Wave: Normal" - config_tag = "meteor_wave_normal" - typepath = /datum/round_event/meteor_wave - enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Captain","Cyborg") - required_enemies = list(2,2,2,2,2,2,2,2,2,2) - cost = 15 - weight = 3 - repeatable_weight_decrease = 2 - requirements = list(60,50,40,30,30,30,30,30,30,30) - high_population_requirement = 30 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/meteor_wave/threatening - name = "Meteor Wave: Threatening" - config_tag = "meteor_wave_threatening" - typepath = /datum/round_event/meteor_wave/threatening - cost = 25 - weight = 3 - repeatable_weight_decrease = 2 - requirements = list(80,70,60,50,40,40,40,40,40,40) - high_population_requirement = 40 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/meteor_wave/catastrophic - name = "Meteor Wave: Catastrophic" - config_tag = "meteor_wave_catastrophic" - typepath = /datum/round_event/meteor_wave/catastrophic - cost = 40 - weight = 3 - repeatable_weight_decrease = 2 - requirements = list(101,100,90,80,70,60,50,50,50,50) - high_population_requirement = 50 - repeatable = TRUE - -////////////////////////////////////////////// -// // -// ANOMALIES // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/midround/event/anomaly_bluespace - name = "Anomaly: Bluespace" - config_tag = "anomaly_bluespace" - typepath = /datum/round_event/anomaly/anomaly_bluespace - enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain") - required_enemies = list(1,1,1,0,0,0,0,0,0,0) - weight = 2 - repeatable_weight_decrease = 1 - cost = 3 - requirements = list(5,5,5,5,5,5,5,5,5,5) - high_population_requirement = 5 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/anomaly_flux - name = "Anomaly: Hyper-Energetic Flux" - config_tag = "anomaly_flux" - typepath = /datum/round_event/anomaly/anomaly_flux - enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain") - required_enemies = list(1,1,1,0,0,0,0,0,0,0) - weight = 2 - repeatable_weight_decrease = 1 - cost = 5 - requirements = list(5,5,5,5,5,5,5,5,5,5) - high_population_requirement = 10 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/anomaly_gravitational - name = "Anomaly: Gravitational" - config_tag = "anomaly_gravitational" - typepath = /datum/round_event/anomaly/anomaly_grav - weight = 2 - repeatable_weight_decrease = 1 - cost = 3 - requirements = list(5,5,5,5,5,5,5,5,5,5) - high_population_requirement = 5 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/anomaly_pyroclastic - name = "Anomaly: Pyroclastic" - config_tag = "anomaly_pyroclastic" - typepath = /datum/round_event/anomaly/anomaly_pyro - weight = 2 - repeatable_weight_decrease = 1 - cost = 5 - enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") - required_enemies = list(1,1,1,1,1,1,1,1,1,1) - requirements = list(10,10,10,10,10,10,10,10,10,10) - high_population_requirement = 10 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/anomaly_vortex - name = "Anomaly: Vortex" - config_tag = "anomaly_vortex" - typepath = /datum/round_event/anomaly/anomaly_vortex - weight = 2 - repeatable_weight_decrease = 1 - cost = 5 - enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") - required_enemies = list(1,1,1,1,1,1,1,1,1,1) - requirements = list(10,10,10,10,10,10,10,10,10,10) - high_population_requirement = 10 - repeatable = TRUE - -////////////////////////////////////////////// -// // -// WOW THAT'S A LOT OF EVENTS // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/midround/event/brand_intelligence - name = "Brand Intelligence" - config_tag = "brand_intelligence" - typepath = /datum/round_event/brand_intelligence - weight = 1 - repeatable_weight_decrease = 1 - cost = 2 - enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") - required_enemies = list(1,1,1,1,0,0,0,0,0,0) - requirements = list(10,10,10,10,10,10,10,10,10,10) - high_population_requirement = 10 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/carp_migration - name = "Carp Migration" - config_tag = "carp_migration" - typepath = /datum/round_event/carp_migration - weight = 7 - repeatable_weight_decrease = 3 - cost = 4 - requirements = list(10,10,10,10,10,10,10,10,10,10) - high_population_requirement = 10 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/communications_blackout - name = "Communications Blackout" - config_tag = "communications_blackout" - typepath = /datum/round_event/communications_blackout - cost = 4 - weight = 2 - repeatable_weight_decrease = 3 - enemy_roles = list("Chief Engineer","Station Engineer") - required_enemies = list(1,1,1,0,0,0,0,0,0,0) - requirements = list(5,5,5,5,5,5,5,5,5,5) - high_population_requirement = 5 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/processor_overload - name = "Processer Overload" - config_tag = "processor_overload" - typepath = /datum/round_event/processor_overload - cost = 4 - weight = 2 - repeatable_weight_decrease = 3 - enemy_roles = list("Chief Engineer","Station Engineer") - required_enemies = list(1,1,1,0,0,0,0,0,0,0) - requirements = list(5,5,5,5,5,5,5,5,5,5) - high_population_requirement = 5 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/space_dust - name = "Minor Space Dust" - config_tag = "space_dust" - typepath = /datum/round_event/space_dust - cost = 2 - weight = 2 - repeatable_weight_decrease = 1 - enemy_roles = list("Chief Engineer","Station Engineer") - required_enemies = list(1,1,1,0,0,0,0,0,0,0) - requirements = list(5,5,5,5,5,5,5,5,5,5) - high_population_requirement = 5 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/major_dust - name = "Major Space Dust" - config_tag = "major_dust" - typepath = /datum/round_event/meteor_wave/major_dust - cost = 4 - weight = 2 - repeatable_weight_decrease = 1 - enemy_roles = list("Chief Engineer","Station Engineer") - required_enemies = list(2,2,2,2,2,2,2,2,2,2) - requirements = list(10,10,10,10,10,10,10,10,10,10) - high_population_requirement = 10 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/electrical_storm - name = "Electrical Storm" - config_tag = "electrical_storm" - typepath = /datum/round_event/electrical_storm - cost = 1 - weight = 2 - repeatable_weight_decrease = 1 - enemy_roles = list("Chief Engineer","Station Engineer") - required_enemies = list(1,1,1,0,0,0,0,0,0,0) - requirements = list(5,5,5,5,5,5,5,5,5,5) - high_population_requirement = 5 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/heart_attack - name = "Random Heart Attack" - config_tag = "heart_attack" - typepath = /datum/round_event/heart_attack - cost = 3 - weight = 2 - repeatable_weight_decrease = 1 - enemy_roles = list("Medical Doctor","Chief Medical Officer") - required_enemies = list(2,2,2,2,2,2,2,2,2,2) - requirements = list(101,101,101,5,5,5,5,5,5,5) - high_population_requirement = 5 - repeatable = TRUE - -/datum/dynamic_ruleset/midround/event/radiation_storm - name = "Radiation Storm" - config_tag = "radiation_storm" - typepath = /datum/round_event/radiation_storm - cost = 3 - weight = 1 - enemy_roles = list("Chemist","Chief Medical Officer","Geneticist","Medical Doctor","AI","Captain") - required_enemies = list(1,1,1,1,1,1,1,1,1,1) - requirements = list(5,5,5,5,5,5,5,5,5,5) - high_population_requirement = 5 - #undef ABDUCTOR_MAX_TEAMS #undef REVENANT_SPAWN_THRESHOLD diff --git a/tgstation.dme b/tgstation.dme index 4fd1b6c4f3..f9d5eb8823 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -565,6 +565,7 @@ #include "code\game\gamemodes\devil\devil agent\devil_agent.dm" #include "code\game\gamemodes\dynamic\dynamic.dm" #include "code\game\gamemodes\dynamic\dynamic_rulesets.dm" +#include "code\game\gamemodes\dynamic\dynamic_rulesets_events.dm" #include "code\game\gamemodes\dynamic\dynamic_rulesets_latejoin.dm" #include "code\game\gamemodes\dynamic\dynamic_rulesets_midround.dm" #include "code\game\gamemodes\dynamic\dynamic_rulesets_roundstart.dm" From 82a17d8144778d87cc7a78a56799a160e3688a01 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 12 Nov 2019 03:02:32 -0800 Subject: [PATCH 104/121] updated an error to actually be right --- code/game/gamemodes/dynamic/dynamic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index a2fb71ee04..260d6ec10a 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -455,7 +455,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) log_game("DYNAMIC: Additional ruleset picked successfully, now [executed_rules.len] picked. [extra_rulesets_amount] remaining.") else - if(threat >= 10) + if(threat >= 15) message_admins("DYNAMIC: Picking first roundstart ruleset failed. You should report this.") log_game("DYNAMIC: Picking first roundstart ruleset failed. drafted_rules.len = [drafted_rules.len] and threat = [threat]/[threat_level]") return FALSE From d381be7f07c809912276358f1d2012ccdb0dc02e Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 12 Nov 2019 05:30:08 -0800 Subject: [PATCH 105/121] more logging. --- code/game/gamemodes/dynamic/dynamic_rulesets.dm | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index 5d6c262c5e..33939fb642 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -120,14 +120,24 @@ return FALSE if (population >= GLOB.dynamic_high_pop_limit) indice_pop = 10 - return (threat_level >= high_population_requirement) + if(threat_level < high_population_requirement) + message_admins("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[high_population_requirement]") + log_game("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[high_population_requirement]") + return FALSE + else + return TRUE else pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement if(antag_cap.len && requirements.len != antag_cap.len) message_admins("DYNAMIC: requirements and antag_cap lists have different lengths in ruleset [name]. Likely config issue, report this.") log_game("DYNAMIC: requirements and antag_cap lists have different lengths in ruleset [name]. Likely config issue, report this.") indice_pop = min(requirements.len,round(population/pop_per_requirement)+1) - return (threat_level >= requirements[indice_pop]) + if(threat_level < requirements[indice_pop]) + message_admins("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[requirements[indice_pop]]") + log_game("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[requirements[indice_pop]]") + return FALSE + else + return TRUE /// Called when a suitable rule is picked during roundstart(). Will some times attempt to scale a rule up when there is threat remaining. Returns the amount of scaled steps. /datum/dynamic_ruleset/proc/scale_up(extra_rulesets = 0, remaining_threat_level = 0) From 7a7c410265b47d2ab1cb7e78c87e0bd8f1b284f3 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 12 Nov 2019 16:48:37 -0800 Subject: [PATCH 106/121] lowered admin spam --- code/game/gamemodes/dynamic/dynamic_rulesets.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index 33939fb642..14f8b5370f 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -121,7 +121,6 @@ if (population >= GLOB.dynamic_high_pop_limit) indice_pop = 10 if(threat_level < high_population_requirement) - message_admins("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[high_population_requirement]") log_game("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[high_population_requirement]") return FALSE else @@ -133,7 +132,6 @@ log_game("DYNAMIC: requirements and antag_cap lists have different lengths in ruleset [name]. Likely config issue, report this.") indice_pop = min(requirements.len,round(population/pop_per_requirement)+1) if(threat_level < requirements[indice_pop]) - message_admins("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[requirements[indice_pop]]") log_game("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[requirements[indice_pop]]") return FALSE else From 6a7453dedecaa61453bac14d5d94b564f1ef6271 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 12 Nov 2019 16:48:46 -0800 Subject: [PATCH 107/121] whoops forgot initialize cooldown --- code/game/gamemodes/dynamic/dynamic.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 260d6ec10a..72c1101b42 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -343,6 +343,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_midround_delay_min + GLOB.dynamic_first_midround_delay_max) midround_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_first_midround_delay_min, GLOB.dynamic_first_midround_delay_max)) + world.time + + var/event_injection_cooldown_middle = 0.5*(GLOB.dynamic_event_delay_max + GLOB.dynamic_event_delay_min) + event_injection_cooldown = (round(CLAMP(EXP_DISTRIBUTION(event_injection_cooldown_middle), GLOB.dynamic_event_delay_min, GLOB.dynamic_event_delay_max)) + world.time) + log_game("DYNAMIC: Dynamic Mode initialized with a Threat Level of... [threat_level]!") initial_threat_level = threat_level return TRUE @@ -455,7 +459,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) log_game("DYNAMIC: Additional ruleset picked successfully, now [executed_rules.len] picked. [extra_rulesets_amount] remaining.") else - if(threat >= 15) + if(threat >= 50) message_admins("DYNAMIC: Picking first roundstart ruleset failed. You should report this.") log_game("DYNAMIC: Picking first roundstart ruleset failed. drafted_rules.len = [drafted_rules.len] and threat = [threat]/[threat_level]") return FALSE From 7ea3b5e22125346adb1c1f4a291a7cd5d0cba775 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 12 Nov 2019 17:01:25 -0800 Subject: [PATCH 108/121] Increased event cooldown --- code/game/gamemodes/dynamic/dynamic.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 72c1101b42..9067e09f0e 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -17,8 +17,8 @@ GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (30 MINUTES)) GLOBAL_VAR_INIT(dynamic_midround_delay_min, (10 MINUTES)) GLOBAL_VAR_INIT(dynamic_midround_delay_max, (30 MINUTES)) -GLOBAL_VAR_INIT(dynamic_event_delay_min, (5 MINUTES)) -GLOBAL_VAR_INIT(dynamic_event_delay_max, (20 MINUTES)) // this is on top of regular events, so can't be quite as often +GLOBAL_VAR_INIT(dynamic_event_delay_min, (10 MINUTES)) +GLOBAL_VAR_INIT(dynamic_event_delay_max, (30 MINUTES)) // this is on top of regular events, so can't be quite as often // -- Roundstart injection delays From 89c560c891cdeed450ce3b3328a7240ae80e2dde Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 12 Nov 2019 17:36:12 -0800 Subject: [PATCH 109/121] this is why static typing is good and should be used more --- code/game/gamemodes/dynamic/dynamic_rulesets.dm | 4 ++-- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index 14f8b5370f..0c8ec0a2b8 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -231,11 +231,11 @@ candidates.Remove(P) continue if(antag_flag_override) - if(!(antag_flag_override in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag_override, ROLE_SYNDICATE))) + if(!(antag_flag_override in P.client.prefs.be_special) || jobban_isbanned(P.ckey, antag_flag_override)) candidates.Remove(P) continue else - if(!(antag_flag in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag, ROLE_SYNDICATE))) + if(!(antag_flag in P.client.prefs.be_special) || jobban_isbanned(P.ckey, antag_flag)) candidates.Remove(P) continue diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index c6f85a40b3..4e5406e2db 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -43,11 +43,11 @@ trimmed_list.Remove(M) continue if(antag_flag_override) - if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, list(antag_flag_override, ROLE_SYNDICATE))) + if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag_override)) trimmed_list.Remove(M) continue else - if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, list(antag_flag, ROLE_SYNDICATE))) + if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag)) trimmed_list.Remove(M) continue if (M.mind) From bbcf91f88c2b3e6ec8d601f849009ab661b638ca Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 12 Nov 2019 23:02:59 -0800 Subject: [PATCH 110/121] blacklisted blob from clock cult, latejoin revs now higher req threat --- code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm | 4 ++-- code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 1 + config/dynamic_config.txt | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 3b01136ebd..5810fd0ae0 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -90,8 +90,8 @@ weight = 2 delay = 1 MINUTES // Prevents rule start while head is offstation. cost = 20 - requirements = list(101,101,70,40,30,20,20,20,20,20) - high_population_requirement = 50 + requirements = list(101,101,70,40,40,40,40,40,40,40) + high_population_requirement = 40 flags = HIGHLANDER_RULESET var/required_heads_of_staff = 3 var/finished = FALSE diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 4e5406e2db..cc94408c80 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -366,6 +366,7 @@ enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") required_enemies = list(3,3,2,2,2,1,1,1,1,0) required_candidates = 1 + blocking_rules = list(/datum/dynamic_ruleset/roundstart/clockcult) weight = 4 cost = 10 requirements = list(101,101,101,80,60,50,50,50,50,50) diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 0d43e67636..921a630564 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -204,7 +204,7 @@ DYNAMIC_REQUIREMENTS RADIATION_STORM 5 5 5 5 5 5 5 5 5 5 ## Latejoin antags DYNAMIC_REQUIREMENTS LATEJOIN_TRAITOR 40 30 20 15 15 15 15 15 15 15 -DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 30 20 20 20 20 20 +DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 40 40 40 40 40 40 ## An alternative, static requirement used instead when pop is over mode's high_pop_limit. DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 50 From 0c3a7d4015e4240b332150268f46d9af020f3add Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 13 Nov 2019 03:49:22 -0800 Subject: [PATCH 111/121] holy shit --- code/game/gamemodes/dynamic/dynamic.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 9067e09f0e..83cfb6718b 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -566,9 +566,9 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) if(!rule.repeatable) if(rule.ruletype == "Latejoin") latejoin_rules = remove_from_list(latejoin_rules, rule.type) - else if(rule.type == "Midround") + else if(rule.ruletype == "Midround") midround_rules = remove_from_list(midround_rules, rule.type) - else if(rule.type == "Event") + else if(rule.ruletype == "Event") events = remove_from_list(events,rule.type) addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_midround_latejoin_rule, rule), rule.delay) return TRUE From 8a02c1a0a1c30b8810afd5d2229879e420e37e81 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 13 Nov 2019 04:30:45 -0800 Subject: [PATCH 112/121] Made results of vote semi-public --- code/controllers/subsystem/vote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index a4634622c9..a4544c6572 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -173,7 +173,7 @@ SUBSYSTEM_DEF(vote) mean += (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 GLOB.dynamic_curve_width = CLAMP(3-abs(mean*10),0.5,4) - message_admins("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") + to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") var/datum/map_config/VM = config.maplist[.] From e88a6f2571682772004c3ccf29111b565b38cf85 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 13 Nov 2019 19:12:06 -0800 Subject: [PATCH 113/121] why is this HERE --- .../gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 0afa26961c..9eb06884c1 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -628,16 +628,6 @@ requirements = list(101,101,101,101,101,101,101,101,101,101) high_population_requirement = 101 antag_cap = list(1,1,1,2,2,2,3,3,3,4) - var/devil_limit = 4 // Hard limit on devils if scaling is turned off - -/datum/dynamic_ruleset/roundstart/devil/pre_execute() - var/tsc = CONFIG_GET(number/traitor_scaling_coeff) - var/num_devils = 1 - - if(tsc) - num_devils = max(required_candidates, min(round(num_players() / (tsc * 3)) + 2, round(num_players() / (tsc * 1.5)))) - else - num_devils = max(required_candidates, min(num_players(), devil_limit)) /datum/dynamic_ruleset/roundstart/devil/pre_execute() var/num_devils = antag_cap[indice_pop] From c08c6f5bb7a12799fa22c4366b9dd518a4957ead Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 13 Nov 2019 19:13:16 -0800 Subject: [PATCH 114/121] Made roundstart --- code/game/gamemodes/dynamic/dynamic.dm | 28 ++++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 83cfb6718b..ced8fb3719 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -239,22 +239,24 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) /datum/game_mode/dynamic/send_intercept() . = "Central Command Status Summary
" switch(round(threat_level)) - if(0 to 30) + if(0 to 20) . += "Peaceful Waypoint
" . += "Your station orbits deep within controlled, core-sector systems and serves as a waypoint for routine traffic through Nanotrasen's trade empire. Due to the combination of high security, interstellar traffic, and low strategic value, it makes any direct threat of violence unlikely. Your primary enemies will be incompetence and bored crewmen: try to organize team-building events to keep staffers interested and productive. However, even deep in our territory there may be subversive elements, especially for such a high-value target as your station. Keep an eye out, but don't expect much trouble." set_security_level(SEC_LEVEL_GREEN) - if(31 to 49) - . += "Core Territory
" - . += "Your station orbits within reliably mundane, secure space. Although Nanotrasen has a firm grip on security in your region, the valuable resources and strategic position aboard your station make it a potential target for infiltrations. Monitor crew for non-loyal behavior, but expect a relatively tame shift free of large-scale destruction. We expect great things from your station." - set_security_level(SEC_LEVEL_GREEN) - if(50 to 65) - . += "Contested System
" - . += "Your station's orbit passes along the edge of Nanotrasen's sphere of influence. While subversive elements remain the most likely threat against your station, hostile organizations are bolder here, where our grip is weaker. Exercise increased caution against elite Syndicate strike forces, or Executives forbid, some kind of ill-conceived unionizing attempt." - set_security_level(SEC_LEVEL_BLUE) - if(65 to 79) - . += "Uncharted Space
" - . += "Congratulations and thank you for participating in the NT 'Frontier' space program! Your station is actively orbiting a high value system far from the nearest support stations. Little is known about your region of space, and the opportunity to encounter the unknown invites greater glory. You are encouraged to elevate security as necessary to protect Nanotrasen assets." - set_security_level(SEC_LEVEL_BLUE) + if(21 to 79) + var/perc_green = 100-round(100*((threat_level-21)/(79-21))) + if(prob(perc_green)) + . += "Core Territory
" + . += "Your station orbits within reliably mundane, secure space. Although Nanotrasen has a firm grip on security in your region, the valuable resources and strategic position aboard your station make it a potential target for infiltrations. Monitor crew for non-loyal behavior, but expect a relatively tame shift free of large-scale destruction. We expect great things from your station." + set_security_level(SEC_LEVEL_GREEN) + else if(prob(perc_green)) + . += "Contested System
" + . += "Your station's orbit passes along the edge of Nanotrasen's sphere of influence. While subversive elements remain the most likely threat against your station, hostile organizations are bolder here, where our grip is weaker. Exercise increased caution against elite Syndicate strike forces, or Executives forbid, some kind of ill-conceived unionizing attempt." + set_security_level(SEC_LEVEL_BLUE) + else + . += "Uncharted Space
" + . += "Congratulations and thank you for participating in the NT 'Frontier' space program! Your station is actively orbiting a high value system far from the nearest support stations. Little is known about your region of space, and the opportunity to encounter the unknown invites greater glory. You are encouraged to elevate security as necessary to protect Nanotrasen assets." + set_security_level(SEC_LEVEL_BLUE) if(80 to 99) . += "Black Orbit
" . += "As part of a mandatory security protocol, we are required to inform you that as a result of your orbital pattern directly behind an astrological body (oriented from our nearest observatory), your station will be under decreased monitoring and support. It is anticipated that your extreme location and decreased surveillance could pose security risks. Avoid unnecessary risks and attempt to keep your station in one piece." From ad84b2977ae471b359fc5cc809792733eb729d28 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 13 Nov 2019 19:14:42 -0800 Subject: [PATCH 115/121] this might help with the disk weirdness --- code/modules/antagonists/nukeop/equipment/nuclearbomb.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index aec8392230..aa3beaff08 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -617,7 +617,7 @@ This is here to make the tiles around the station mininuke change when it's arme mode.threat_tallies[STATIONARY_DISK_STRING] -= 0.1 mode.spend_threat(0.1) mode.threat_level = max(mode.threat_level-0.1,mode.initial_threat_level) - if(mode.threat_tallies[STATIONARY_DISK_STRING] == 0) + if(mode.threat_tallies[STATIONARY_DISK_STRING] <= 0) mode.threat_tallies -= STATIONARY_DISK_STRING else var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control From 3a6dce54acadd7b7874cb5a7f97386f9141e6ccf Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 14 Nov 2019 05:53:58 -0800 Subject: [PATCH 116/121] i'm like 90% sure this is what it's supposed to be. --- code/game/gamemodes/dynamic/dynamic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index ced8fb3719..83a3debfdc 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -494,7 +494,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) return FALSE starting_rule = pickweight(drafted_rules) // With low pop and high threat there might be rulesets that get executed with no valid candidates. - else if(starting_rule.ready()) // Should already be filtered out, but making sure. Check filtering at end of proc if reported. + else if(!starting_rule.ready()) // Should already be filtered out, but making sure. Check filtering at end of proc if reported. drafted_rules -= starting_rule if(drafted_rules.len <= 0) log_game("DYNAMIC: Picking [starting_rule.name] failed because there were not enough candidates and no more rulesets available. Report this.") From 28a14fd01e54ad4e2a3753d7797ba9dfeb6d7161 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 14 Nov 2019 05:57:56 -0800 Subject: [PATCH 117/121] Removed janky nuke disk threat increase --- .../nukeop/equipment/nuclearbomb.dm | 47 +++++-------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index aa3beaff08..d0e6dafbc1 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -583,8 +583,6 @@ This is here to make the tiles around the station mininuke change when it's arme . = ..() AddComponent(/datum/component/stationloving, !fake) -#define STATIONARY_DISK_STRING "Stationary Nuke Disk" - /obj/item/disk/nuclear/process() if(fake) STOP_PROCESSING(SSobj, src) @@ -592,42 +590,21 @@ This is here to make the tiles around the station mininuke change when it's arme var/turf/newturf = get_turf(src) if(newturf && lastlocation == newturf) if(last_disk_move < world.time - 5000 && prob((world.time - 5000 - last_disk_move)*0.0001)) - if(istype(SSticker.mode, /datum/game_mode/dynamic)) - var/datum/game_mode/dynamic/mode = SSticker.mode - mode.create_threat(0.1) - if(round(mode.threat) == mode.threat) - message_admins("[src] is stationary in [ADMIN_VERBOSEJMP(newturf)]. The dynamic threat rating has increased to [mode.threat].") - log_game("[src] is stationary for too long in [loc_name(newturf)], and has increased dynamic threat to [mode.threat].") - if(!(STATIONARY_DISK_STRING in mode.threat_tallies)) - mode.threat_tallies[STATIONARY_DISK_STRING] = 0 - mode.threat_tallies[STATIONARY_DISK_STRING] += 0.1 - else - var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control - if(istype(loneop)) - loneop.weight += 1 - if(loneop.weight % 5 == 0) - message_admins("[src] is stationary in [ADMIN_VERBOSEJMP(newturf)]. The weight of Lone Operative is now [loneop.weight].") - log_game("[src] is stationary for too long in [loc_name(newturf)], and has increased the weight of the Lone Operative event to [loneop.weight].") + var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control + if(istype(loneop)) + loneop.weight += 1 + if(loneop.weight % 5 == 0) + message_admins("[src] is stationary in [ADMIN_VERBOSEJMP(newturf)]. The weight of Lone Operative is now [loneop.weight].") + log_game("[src] is stationary for too long in [loc_name(newturf)], and has increased the weight of the Lone Operative event to [loneop.weight].") else lastlocation = newturf last_disk_move = world.time - if(istype(SSticker.mode, /datum/game_mode/dynamic)) - var/datum/game_mode/dynamic/mode = SSticker.mode - if(STATIONARY_DISK_STRING in mode.threat_tallies) - mode.threat_tallies[STATIONARY_DISK_STRING] -= 0.1 - mode.spend_threat(0.1) - mode.threat_level = max(mode.threat_level-0.1,mode.initial_threat_level) - if(mode.threat_tallies[STATIONARY_DISK_STRING] <= 0) - mode.threat_tallies -= STATIONARY_DISK_STRING - else - var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control - if(istype(loneop) && prob(loneop.weight)) - loneop.weight = max(loneop.weight - 1, 0) - if(loneop.weight % 5 == 0) - message_admins("[src] is on the move (currently in [ADMIN_VERBOSEJMP(newturf)]). The weight of Lone Operative is now [loneop.weight].") - log_game("[src] being on the move has reduced the weight of the Lone Operative event to [loneop.weight].") - -#undef STATIONARY_DISK_STRING + var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control + if(istype(loneop) && prob(loneop.weight)) + loneop.weight = max(loneop.weight - 1, 0) + if(loneop.weight % 5 == 0) + message_admins("[src] is on the move (currently in [ADMIN_VERBOSEJMP(newturf)]). The weight of Lone Operative is now [loneop.weight].") + log_game("[src] being on the move has reduced the weight of the Lone Operative event to [loneop.weight].") /obj/item/disk/nuclear/examine(mob/user) . = ..() From 6d8f2b89149475bbb705c79257cd2ffcb2053e39 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 14 Nov 2019 06:42:13 -0800 Subject: [PATCH 118/121] Made s?laughter demon and apprentice cost threat, too. --- .../configuration/entries/dynamic.dm | 4 ++ .../antagonists/wizard/equipment/spellbook.dm | 42 +++++++++++++++++++ config/dynamic_config.txt | 7 +++- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index a59f3a6954..8a45894728 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -105,6 +105,10 @@ config_entry_value = 10 min_val = 0 +/datum/config_entry/number/dynamic_apprentice_cost + config_entry_value = 10 + min_val = 0 + /datum/config_entry/number/dynamic_warops_requirement config_entry_value = 60 min_val = 0 diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index ef0974f73c..25b1cbb7af 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -370,6 +370,20 @@ item_path = /obj/item/antag_spawner/contract category = "Assistance" +/datum/spellbook_entry/item/contract/IsAvailible() + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + if(mode.threat < CONFIG_GET(number/dynamic_apprentice_cost)) + return 0 + +/datum/spellbook_entry/item/contract/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + var/threat_spent = CONFIG_GET(number/dynamic_apprentice_cost) + mode.spend_threat(threat_spent) + mode.log_threat("Wizard spent [threat_spent] on apprentice contract.") + return ..() + /datum/spellbook_entry/item/guardian name = "Guardian Deck" desc = "A deck of guardian tarot cards, capable of binding a personal guardian to your body. There are multiple types of guardian available, but all of them will transfer some amount of damage to you. \ @@ -389,6 +403,20 @@ limit = 3 category = "Assistance" +/datum/spellbook_entry/item/bloodbottle/IsAvailible() + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + if(mode.threat < CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]) + return 0 + +/datum/spellbook_entry/item/bloodbottle/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + var/threat_spent = CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"] + mode.spend_threat(threat_spent) + mode.log_threat("Wizard spent [threat_spent] on slaughter demon.") + return ..() + /datum/spellbook_entry/item/hugbottle name = "Bottle of Tickles" desc = "A bottle of magically infused fun, the smell of which will \ @@ -403,6 +431,20 @@ limit = 3 category = "Assistance" +/datum/spellbook_entry/item/hugbottle/IsAvailible() + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + if(mode.threat < round(CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]/3)) + return 0 + +/datum/spellbook_entry/item/hugbottle/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + var/threat_spent = CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]/3 + mode.spend_threat(threat_spent) + mode.log_threat("Wizard spent [threat_spent] on laughter demon.") + return ..() + /datum/spellbook_entry/item/mjolnir name = "Mjolnir" desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power." diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index 921a630564..e27844d336 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -283,16 +283,19 @@ DYNAMIC_ASSASSINATE_COST 2 DYNAMIC_SUMMON_GUNS_REQUIREMENT 10 ## How much summon guns reduces the round's remaining threat. Setting to 0 makes it cost none. -DYNAMIC_SUMMON_GUNS_COST 5 +DYNAMIC_SUMMON_GUNS_COST 10 ## As above, but for summon magic DYNAMIC_SUMMON_MAGIC_REQUIREMENT 10 -DYNAMIC_SUMMON_MAGIC_COST 5 +DYNAMIC_SUMMON_MAGIC_COST 10 ## As above, but for summon events DYNAMIC_SUMMON_EVENTS_REQUIREMENT 20 DYNAMIC_SUMMON_EVENTS_COST 10 +## As above, but for apprentice. Note that this is just a cost, since apprentices aren't as universally disruptive as above. +DYNAMIC_APPRENTICE_COST 10 + ## This requirement uses threat level, rather than current threat, which is why it's higher. DYNAMIC_WAROPS_REQUIREMENT 60 From e68ad1398395fa64765113505ae6c9de5e200a97 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 14 Nov 2019 22:24:43 -0800 Subject: [PATCH 119/121] Reduced RNG a bit more --- code/controllers/subsystem/vote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index a4544c6572..50be61f91d 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -172,7 +172,7 @@ SUBSYSTEM_DEF(vote) if(voted.len != 0) mean += (choices[PEACE]*-1+choices[CHAOS])/voted.len GLOB.dynamic_curve_centre = mean*20 - GLOB.dynamic_curve_width = CLAMP(3-abs(mean*10),0.5,4) + GLOB.dynamic_curve_width = CLAMP(2-abs(mean*5),0.5,4) to_chat(world,"Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].") log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]") if("map") From 009c0b46d5e0c430b87453177ac3291043022e7b Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 14 Nov 2019 22:28:42 -0800 Subject: [PATCH 120/121] Added some more blocking rules (whoops) --- code/game/gamemodes/dynamic/dynamic_rulesets_events.dm | 1 + code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 8 ++------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm index 707b0b6b5b..a20022cb71 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm @@ -44,6 +44,7 @@ required_enemies = list(2,2,1,1,0,0,0,0,0,0) weight = 5 cost = 10 + blocking_rules = list(/datum/dynamic_ruleset/roundstart/nuclear,/datum/dynamic_ruleset/midround/from_ghosts/nuclear) requirements = list(70,60,50,50,40,40,40,30,20,15) high_population_requirement = 15 diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index cc94408c80..0e3160d741 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -632,17 +632,13 @@ required_candidates = 2 weight = 8 cost = 10 - requirements = list(80,80,70,50,40,30,30,20,15,15) + requirements = list(101,101,70,50,40,30,30,20,15,15) + blocking_rules = list(/datum/dynamic_ruleset/roundstart/nuclear,/datum/dynamic_ruleset/midround/from_ghosts/nuclear) high_population_requirement = 15 var/datum/team/abductor_team/team repeatable_weight_decrease = 4 repeatable = TRUE -/datum/dynamic_ruleset/midround/from_ghosts/abductors/acceptable(population=0, threat=0) - if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules) - return FALSE // Unavailable if nuke ops were already sent at roundstart. yes, this is intentional for abductors too. - return ..() - /datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE) if(required_candidates > (dead_players.len + list_observers.len)) return FALSE From 4f06a259511b570100450d90089be6c7f0ab7dc5 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 14 Nov 2019 23:26:59 -0800 Subject: [PATCH 121/121] Made staff of change require/cost threat --- code/controllers/configuration/entries/dynamic.dm | 8 ++++++++ .../antagonists/wizard/equipment/spellbook.dm | 14 ++++++++++++++ config/dynamic_config.txt | 3 +++ 3 files changed, 25 insertions(+) diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 8a45894728..df57bd5aa8 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -105,6 +105,14 @@ config_entry_value = 10 min_val = 0 +/datum/config_entry/number/dynamic_staff_of_change_requirement + config_entry_value = 20 + min_val = 0 + +/datum/config_entry/number/dynamic_staff_of_change_cost + config_entry_value = 10 + min_val = 0 + /datum/config_entry/number/dynamic_apprentice_cost config_entry_value = 10 min_val = 0 diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index 2ca6d86e11..52d18a37d9 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -286,6 +286,20 @@ desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself." item_path = /obj/item/gun/magic/staff/change +/datum/spellbook_entry/item/staffchange/IsAvailible() + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + if(mode.threat < CONFIG_GET(number/dynamic_staff_of_change_requirement)) + return 0 + +/datum/spellbook_entry/item/staffchange/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + var/threat_spent = CONFIG_GET(number/dynamic_staff_of_change_cost) + mode.spend_threat(threat_spent) + mode.log_threat("Wizard spent [threat_spent] on staff of change.") + return ..() + /datum/spellbook_entry/item/staffanimation name = "Staff of Animation" desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines." diff --git a/config/dynamic_config.txt b/config/dynamic_config.txt index e27844d336..f9b78f046f 100644 --- a/config/dynamic_config.txt +++ b/config/dynamic_config.txt @@ -293,6 +293,9 @@ DYNAMIC_SUMMON_MAGIC_COST 10 DYNAMIC_SUMMON_EVENTS_REQUIREMENT 20 DYNAMIC_SUMMON_EVENTS_COST 10 +DYNAMIC_STAFF_OF_CHANGE_REQUIREMENT 20 +DYNAMIC_STAFF_OF_CHANGE_COST 10 + ## As above, but for apprentice. Note that this is just a cost, since apprentices aren't as universally disruptive as above. DYNAMIC_APPRENTICE_COST 10