diff --git a/code/controllers/configuration/entries/vote.dm b/code/controllers/configuration/entries/vote.dm
index 6dfbb44508..545fd01e3c 100644
--- a/code/controllers/configuration/entries/vote.dm
+++ b/code/controllers/configuration/entries/vote.dm
@@ -1,5 +1,7 @@
/datum/config_entry/flag/allow_vote_restart // allow votes to restart
+/datum/config_entry/flag/allow_vote_mode // allow votes to change mode
+
/datum/config_entry/number/vote_delay // minimum time between voting sessions (deciseconds, 10 minute default)
config_entry_value = 6000
min_val = 0
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index a1628e49da..d2a4882f82 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -620,7 +620,7 @@ SUBSYSTEM_DEF(ticker)
if(mode)
GLOB.master_mode = "dynamic"
else
- GLOB.master_mode = "dynamic"
+ GLOB.master_mode = GLOB.dynamic_forced_extended
log_game("Saved mode is '[GLOB.master_mode]'")
/datum/controller/subsystem/ticker/proc/save_mode(the_mode)
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index 66e90ced31..3cd1bc54e6 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -68,11 +68,15 @@ SUBSYSTEM_DEF(vote)
//get the highest number of votes
var/greatest_votes = 0
var/total_votes = 0
- for(var/option in choices)
- var/votes = choices[option]
- total_votes += votes
- if(votes > greatest_votes)
- greatest_votes = votes
+ if((mode == "gamemode" || mode == "roundtype") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
+ for(var/mob/dead/new_player/P in GLOB.player_list)
+ if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
+ choices[choices[voted[P.ckey]]]--
+ for(var/option in choices)
+ var/votes = choices[option]
+ total_votes += votes
+ if(votes > greatest_votes)
+ greatest_votes = votes
//default-vote for everyone who didn't vote
if(!CONFIG_GET(flag/default_no_vote) && choices.len)
var/list/non_voters = GLOB.directory.Copy()
@@ -86,6 +90,11 @@ SUBSYSTEM_DEF(vote)
choices["Continue Playing"] += non_voters.len
if(choices["Continue Playing"] >= greatest_votes)
greatest_votes = choices["Continue Playing"]
+ else if(mode == "gamemode")
+ if(GLOB.master_mode in choices)
+ choices[GLOB.master_mode] += non_voters.len
+ if(choices[GLOB.master_mode] >= greatest_votes)
+ greatest_votes = choices[GLOB.master_mode]
//get all options with that many votes and return them in a list
. = list()
if(greatest_votes)
@@ -95,6 +104,10 @@ SUBSYSTEM_DEF(vote)
return .
/datum/controller/subsystem/vote/proc/calculate_condorcet_votes(var/blackbox_text)
+ if((mode == "gamemode" || mode == "dynamic" || mode == "roundtype") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
+ for(var/mob/dead/new_player/P in GLOB.player_list)
+ if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
+ voted -= P.ckey
var/list/d[][] = new/list(choices.len,choices.len) // the basic vote matrix, how many times a beats b
for(var/ckey in voted)
var/list/this_vote = voted[ckey]
@@ -141,6 +154,10 @@ SUBSYSTEM_DEF(vote)
for(var/choice in choices)
scores_by_choice += "[choice]"
scores_by_choice["[choice]"] = list()
+ if((mode == "gamemode" || mode == "dynamic" || mode == "roundtype") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
+ for(var/mob/dead/new_player/P in GLOB.player_list)
+ if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
+ voted -= P.ckey
for(var/ckey in voted)
var/list/this_vote = voted[ckey]
var/list/pretty_vote = list()
@@ -233,7 +250,7 @@ SUBSYSTEM_DEF(vote)
if(vote_system == HIGHEST_MEDIAN_VOTING)
calculate_highest_median(vote_title_text) // nothing uses this at the moment
var/list/winners = vote_system == INSTANT_RUNOFF_VOTING ? get_runoff_results() : get_result()
- var/was_roundtype_vote = mode == "dynamic"
+ var/was_roundtype_vote = mode == "roundtype" || mode == "dynamic"
if(winners.len > 0)
if(was_roundtype_vote)
stored_gamemode_votes = list()
@@ -304,6 +321,14 @@ SUBSYSTEM_DEF(vote)
var/restart = 0
if(.)
switch(mode)
+ if("roundtype") //CIT CHANGE - adds the roundstart extended/dynamic 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(. == "extended")
+ GLOB.dynamic_forced_extended = TRUE
+ message_admins("The gamemode has been voted for, and has been changed to: [GLOB.master_mode]")
+ log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].")
if("restart")
if(. == "Restart Round")
restart = 1
@@ -404,6 +429,8 @@ SUBSYSTEM_DEF(vote)
switch(vote_type)
if("restart")
choices.Add("Restart Round","Continue Playing")
+ if("gamemode")
+ choices.Add(config.votable_modes)
if("map")
var/players = GLOB.clients.len
var/list/lastmaps = SSpersistence.saved_maps?.len ? list("[SSmapping.config.map_name]") | SSpersistence.saved_maps : list("[SSmapping.config.map_name]")
@@ -420,6 +447,8 @@ SUBSYSTEM_DEF(vote)
choices |= M
if("transfer") // austation begin -- Crew autotranfer vote
choices.Add("Initiate Crew Transfer","Continue Playing") // austation end
+ if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote
+ choices.Add("dynamic", "extended")
if("custom")
question = stripped_input(usr,"What is the vote for?")
if(!question)
@@ -577,6 +606,16 @@ SUBSYSTEM_DEF(vote)
if(trialmin)
. += "\t([avr ? "Allowed" : "Disallowed"])"
. += "
"
+ //gamemode
+ var/avm = CONFIG_GET(flag/allow_vote_mode)
+ if(trialmin || avm)
+ . += "GameMode"
+ else
+ . += "GameMode (Disallowed)"
+ if(trialmin)
+ . += "\t([avm ? "Allowed" : "Disallowed"])"
+
+ . += ""
//custom
if(trialmin)
. += "Custom"
@@ -599,9 +638,15 @@ SUBSYSTEM_DEF(vote)
if("toggle_restart")
if(usr.client.holder)
CONFIG_SET(flag/allow_vote_restart, !CONFIG_GET(flag/allow_vote_restart))
+ if("toggle_gamemode")
+ if(usr.client.holder)
+ CONFIG_SET(flag/allow_vote_mode, !CONFIG_GET(flag/allow_vote_mode))
if("restart")
if(CONFIG_GET(flag/allow_vote_restart) || usr.client.holder)
initiate_vote("restart",usr.key)
+ if("gamemode")
+ if(CONFIG_GET(flag/allow_vote_mode) || usr.client.holder)
+ initiate_vote("gamemode",usr.key)
if("custom")
if(usr.client.holder)
initiate_vote("custom",usr.key)
diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm
index 3b163ddd65..679d2faf11 100644
--- a/code/datums/world_topic.dm
+++ b/code/datums/world_topic.dm
@@ -166,6 +166,7 @@
.["mode"] = "hidden" //CIT CHANGE - hides the gamemode in topic() calls to prevent meta'ing the gamemode
.["respawn"] = config ? CONFIG_GET(flag/respawns_enabled) : FALSE
.["enter"] = GLOB.enter_allowed
+ .["vote"] = CONFIG_GET(flag/allow_vote_mode)
.["ai"] = CONFIG_GET(flag/allow_ai)
.["host"] = world.host ? world.host : null
.["round_id"] = GLOB.round_id
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index 56337d859d..1329395df7 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -305,7 +305,7 @@
required_candidates = 1
weight = 1
cost = 20
- requirements = list(90,90,90,80,60,40,30,20,10,10)
+ requirements = list(101,101,100,80,60,40,30,20,10,10)
repeatable = TRUE
/datum/dynamic_ruleset/midround/from_ghosts/wizard/ready(forced = FALSE)
@@ -337,7 +337,7 @@
required_candidates = 5
weight = 5
cost = 35
- requirements = list(90,90,90,80,60,40,30,20,10,10)
+ requirements = list(101,101,101,80,60,40,30,20,10,10)
var/list/operative_cap = list(2,2,3,3,4,5,5,5,5,5)
var/datum/team/nuclear/nuke_team
flags = HIGH_IMPACT_RULESET
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index 11afacee4e..eae312bfa3 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -17,7 +17,7 @@
weight = 5
cost = 8 // Avoid raising traitor threat above 10, as it is the default low cost ruleset.
scaling_cost = 9
- requirements = list(10,10,10,10,10,10,10,10,10,10)
+ requirements = list(101,10,10,10,10,10,10,10,10,10)
antag_cap = list("denominator" = 24)
var/autotraitor_cooldown = (15 MINUTES)
COOLDOWN_DECLARE(autotraitor_cooldown_check)
@@ -103,7 +103,7 @@
weight = 3
cost = 16
scaling_cost = 10
- requirements = list(70,70,60,50,40,20,20,10,10,10)
+ requirements = list(101,70,60,50,40,20,20,10,10,10)
antag_cap = list("denominator" = 29)
/datum/dynamic_ruleset/roundstart/changeling/pre_execute(population)
@@ -179,7 +179,7 @@
required_candidates = 1
weight = 2
cost = 20
- requirements = list(90,90,90,80,60,40,30,20,10,10)
+ requirements = list(101,101,100,80,60,40,30,20,10,10)
var/list/roundstart_wizards = list()
/datum/dynamic_ruleset/roundstart/wizard/acceptable(population=0, threat=0)
@@ -222,7 +222,8 @@
required_candidates = 2
weight = 3
cost = 20
- requirements = list(100,90,80,60,40,30,10,10,10,10)
+ //requirements = list(100,90,80,60,40,30,10,10,10,10)
+ requirements = list(101,101,101,101,40,30,10,10,10,10)
flags = HIGH_IMPACT_RULESET
antag_cap = list("denominator" = 20, "offset" = 1)
var/datum/team/cult/main_cult
@@ -278,7 +279,7 @@
required_candidates = 5
weight = 3
cost = 20
- requirements = list(90,90,90,80,60,40,30,20,10,10)
+ requirements = list(101,101,101,80,60,40,30,20,10,10)
flags = HIGH_IMPACT_RULESET
antag_cap = list("denominator" = 18, "offset" = 1)
var/datum/team/nuclear/nuke_team
@@ -364,7 +365,8 @@
weight = 3
delay = 7 MINUTES
cost = 20
- requirements = list(101,101,70,40,30,20,10,10,10,10)
+ //requirements = list(101,101,70,40,30,20,10,10,10,10)
+ requirements = list(101,101,101,101,30,20,10,10,10,10)
antag_cap = 3
flags = HIGH_IMPACT_RULESET
blocking_rules = list(/datum/dynamic_ruleset/latejoin/provocateur)
@@ -444,7 +446,8 @@
required_candidates = 2
weight = 3
cost = 20
- requirements = list(100,90,80,60,40,30,10,10,10,10)
+ //requirements = list(100,90,80,60,40,30,10,10,10,10)
+ requirements = list(101,101,101,101,40,30,10,10,10,10)
flags = HIGH_IMPACT_RULESET
antag_cap = list("denominator" = 20, "offset" = 1)
var/datum/team/clockcult/main_clockcult
diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm
index af5884bf04..a3b472158e 100644
--- a/code/modules/events/pirates.dm
+++ b/code/modules/events/pirates.dm
@@ -22,7 +22,7 @@
/proc/send_pirate_threat()
var/pirate_type = PIRATES_ROGUES //pick(PIRATES_ROGUES, PIRATES_SILVERSCALES, PIRATES_DUTCHMAN)
- var/datum/comm_message/threat_msg
+ var/datum/comm_message/threat_msg = new
var/payoff = 0
var/payoff_min = 10000
var/ship_template
@@ -38,7 +38,6 @@
// ship_name = "Flying Dutchman"
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", "commandreport")
- var/datum/comm_message/threat = new
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
if(D)
payoff = max(payoff_min, FLOOR(D.account_balance * 0.80, 1000))
@@ -58,15 +57,15 @@
// threat_msg.title = "Business proposition"
// threat_msg.content = "Ahoy! This be the [ship_name]. Cough up [payoff] credits or you'll walk the plank."
// threat_msg.possible_answers = list("We'll pay.","We will not be extorted.")
- threat.answer_callback = CALLBACK(GLOBAL_PROC, .proc/pirates_answered, threat, payoff, ship_name, initial_send_time, response_max_time, ship_template)
- addtimer(CALLBACK(GLOBAL_PROC, .proc/spawn_pirates, threat, ship_template, FALSE), response_max_time)
+ threat_msg.answer_callback = CALLBACK(GLOBAL_PROC, .proc/pirates_answered, threat_msg, payoff, ship_name, initial_send_time, response_max_time, ship_template)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/spawn_pirates, threat_msg, ship_template, FALSE), response_max_time)
SScommunications.send_message(threat_msg,unique = TRUE)
-/proc/pirates_answered(datum/comm_message/threat, payoff, ship_name, initial_send_time, response_max_time, ship_template)
+/proc/pirates_answered(datum/comm_message/threat_msg, payoff, ship_name, initial_send_time, response_max_time, ship_template)
if(world.time > initial_send_time + response_max_time)
priority_announce("Too late to beg for mercy!",sender_override = ship_name)
return
- if(threat && threat.answered == 1)
+ if(threat_msg && threat_msg.answered == 1)
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
if(D)
if(D.adjust_money(-payoff))
@@ -74,10 +73,10 @@
return
else
priority_announce("Trying to cheat us? You'll regret this!",sender_override = ship_name)
- spawn_pirates(threat, ship_template, TRUE)
+ spawn_pirates(threat_msg, ship_template, TRUE)
-/proc/spawn_pirates(datum/comm_message/threat, ship_template, skip_answer_check)
- if(!skip_answer_check && threat?.answered == 1)
+/proc/spawn_pirates(datum/comm_message/threat_msg, ship_template, skip_answer_check)
+ if(!skip_answer_check && threat_msg?.answered == 1)
return
var/list/candidates = pollGhostCandidates("Do you wish to be considered for pirate crew?", ROLE_TRAITOR)