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)