From 3b2cf65d59aa5ae22876b0ebabecb564ccb912d0 Mon Sep 17 00:00:00 2001 From: san7890 Date: Mon, 5 Sep 2022 17:06:01 -0600 Subject: [PATCH] Rocking The Boat, er, Map Vote (#69561) * Rocking The Boat, er, Map Vote Hey there, A while ago, I spooke (typo intentional) to some other people. One frustration I heard was the fact that people would sometimes sneak through map votes during the very start of a shift, during a high-paced portion, or just as a meme. People in OOC would then flood the vote, putting in any given station. However, if a vote happens 10 minutes in- and the round goes for 70 minutes and not many of the original players are around, then it's not particularly fair to those who have to play next shift on a map they bemoan. So, we can rock the vote! If a player isn't particularly chuffed with the hand they are given, they can poll the players to see if they want to change the map as well. If rocking the vote goes through, huzzah, you get the ability to vote for the map again. If it doesn't go through: tough luck. You can rock the vote one time per shift by default, and server operators can change the amount of times you can call to rock the map vote at their discretion. Calling to rock the vote either successfully or non-successfully counts as a "call", and when that limit is exceeded: no more calls. Does this mean that we will only rotate between two maps because pissants will keep rocking the vote until they get what they like? Maybe? I still see people bemoan getting Tram or shit the bed over IceBox, but I think enough people get sick of bread-on-butter to take the server where it need to go. If operators don't really like seeing only two maps play, they can always adjust the config to ensure it doesn't happen. * makes the grammar grammar it would be "Rock the Vote vote" otherwise --- .../configuration/entries/general.dm | 12 ++- code/controllers/subsystem/mapping.dm | 5 ++ code/datums/votes/_vote_datum.dm | 4 +- code/datums/votes/map_vote.dm | 5 ++ code/datums/votes/rock_the_vote.dm | 80 +++++++++++++++++++ code/modules/admin/verbs/maprotation.dm | 2 + config/config.txt | 6 ++ tgstation.dme | 1 + 8 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 code/datums/votes/rock_the_vote.dm diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index 4f5ad8f3d74..b21ce90ef41 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -164,6 +164,14 @@ /// allow votes to change map /datum/config_entry/flag/allow_vote_map +/// allow players to vote to re-do the map vote +/datum/config_entry/flag/allow_rock_the_vote + +/// the number of times we allow players to rock the vote +/datum/config_entry/number/max_rocking_votes + default = 1 + min_val = 1 + /// minimum time between voting sessions (deciseconds, 10 minute default) /datum/config_entry/number/vote_delay default = 6000 @@ -176,8 +184,8 @@ integer = FALSE min_val = 0 -/// If disabled, no-voters will automatically have their votes added to certain vote options -/// (For eample: restart votes will default to "no restart", map votes will default to their preferred map / default map) +/// If disabled, non-voters will automatically have their votes added to certain vote options +/// (For example: restart votes will default to "no restart", map votes will default to their preferred map / default map, rocking the vote will default to "no") /datum/config_entry/flag/default_no_vote /// Prevents dead people from voting. diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index db20431886a..c35a6244252 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -9,7 +9,12 @@ SUBSYSTEM_DEF(mapping) var/datum/map_config/config var/datum/map_config/next_map_config + /// Has the map for the next round been voted for already? var/map_voted = FALSE + /// Has the map for the next round been deliberately chosen by an admin? + var/map_force_chosen = FALSE + /// Has the map vote been rocked? + var/map_vote_rocked = FALSE var/list/map_templates = list() diff --git a/code/datums/votes/_vote_datum.dm b/code/datums/votes/_vote_datum.dm index 63bcd9cf22e..13cae111ef5 100644 --- a/code/datums/votes/_vote_datum.dm +++ b/code/datums/votes/_vote_datum.dm @@ -13,6 +13,8 @@ var/vote_sound = 'sound/misc/bloop.ogg' /// A list of default choices we have for this vote. var/list/default_choices + /// Does the name of this vote contain the word "vote"? + var/contains_vote_in_name = FALSE // Internal values used when tracking ongoing votes. // Don't mess with these, change the above values / override procs for subtypes. @@ -103,7 +105,7 @@ started_time = world.time time_remaining = round(duration / 10) - return "[capitalize(name)] vote started by [initiator || "Central Command"]." + return "[contains_vote_in_name ? "[capitalize(name)]" : "[capitalize(name)] vote"] started by [initiator || "Central Command"]." /** * Gets the result of the vote. diff --git a/code/datums/votes/map_vote.dm b/code/datums/votes/map_vote.dm index b55ee8419ee..849f7c20d12 100644 --- a/code/datums/votes/map_vote.dm +++ b/code/datums/votes/map_vote.dm @@ -48,6 +48,9 @@ if(forced) return TRUE + if(SSmapping.map_vote_rocked) + return TRUE + if(!CONFIG_GET(flag/allow_vote_map)) if(by_who) to_chat(by_who, span_warning("Map voting is disabled.")) @@ -85,3 +88,5 @@ SSmapping.changemap(winning_map) SSmapping.map_voted = TRUE + if(SSmapping.map_vote_rocked) + SSmapping.map_vote_rocked = FALSE diff --git a/code/datums/votes/rock_the_vote.dm b/code/datums/votes/rock_the_vote.dm new file mode 100644 index 00000000000..62181fef64f --- /dev/null +++ b/code/datums/votes/rock_the_vote.dm @@ -0,0 +1,80 @@ +#define CHOICE_TO_ROCK "Yes, re-do the map vote." +#define CHOICE_NOT_TO_ROCK "No, keep the currently selected map." + +/// If a map vote is called before the emergency shuttle leaves the station, the players can call another vote to re-run the vote on the shuttle leaving. +/datum/vote/rock_the_vote + name = "Rock the Vote" + override_question = "Rock the Vote?" + contains_vote_in_name = TRUE //lol + default_choices = list( + CHOICE_TO_ROCK, + CHOICE_NOT_TO_ROCK, + ) + /// The number of times we have rocked the vote thus far. + var/rocking_votes = 0 + +/datum/vote/rock_the_vote/toggle_votable(mob/toggler) + if(!toggler) + CRASH("[type] wasn't passed a \"toggler\" mob to toggle_votable.") + if(!check_rights_for(toggler.client, R_ADMIN)) + return FALSE + + CONFIG_SET(flag/allow_rock_the_vote, !CONFIG_GET(flag/allow_rock_the_vote)) + return TRUE + +/datum/vote/rock_the_vote/is_config_enabled() + return CONFIG_GET(flag/allow_rock_the_vote) + +/datum/vote/rock_the_vote/can_be_initiated(mob/by_who, forced) + . = ..() + + if(!.) + return FALSE + + if(!forced && !CONFIG_GET(flag/allow_rock_the_vote)) + if(by_who) + to_chat(by_who, span_warning("Rocking the vote is disabled by this server's configuration settings.")) + return FALSE + + if(SSticker.current_state == GAME_STATE_FINISHED) + if(by_who) + to_chat(by_who, span_warning("The game is finished, no map votes can be initiated.")) + return FALSE + + if(rocking_votes >= CONFIG_GET(number/max_rocking_votes)) + if(by_who) + to_chat(by_who, span_warning("You have rocked the vote the maximum number of times.")) + return FALSE + + if(SSmapping.map_vote_rocked) + if(by_who) + to_chat(by_who, span_warning("The vote has already been rocked! Initiate a map vote!")) + return FALSE + + if(!SSmapping.map_voted) + if(by_who) + to_chat(by_who, span_warning("Rocking the vote is disabled because no map has been voted on yet!")) + return FALSE + + if(SSmapping.map_force_chosen) + if(by_who) + to_chat(by_who, span_warning("Rocking the vote is disabled because an admin has forcibly set the map!")) + return FALSE + + return TRUE + +/datum/vote/rock_the_vote/finalize_vote(winning_option) + rocking_votes++ + if(winning_option == CHOICE_NOT_TO_ROCK) + return + + if(winning_option == CHOICE_TO_ROCK) + to_chat(world, span_boldannounce("The vote has been rocked! Players are now able to re-run the map vote once more.")) + message_admins("The players have successfully rocked the vote.") + SSmapping.map_vote_rocked = TRUE + return + + CRASH("[type] wasn't passed a valid winning choice. (Got: [winning_option || "null"])") + +#undef CHOICE_TO_ROCK +#undef CHOICE_NOT_TO_ROCK diff --git a/code/modules/admin/verbs/maprotation.dm b/code/modules/admin/verbs/maprotation.dm index cc7e72f1ea5..c985a835a11 100644 --- a/code/modules/admin/verbs/maprotation.dm +++ b/code/modules/admin/verbs/maprotation.dm @@ -98,9 +98,11 @@ if(SSmapping.changemap(VM)) message_admins("[key_name_admin(usr)] has changed the map to [VM.map_name]") + SSmapping.map_force_chosen = TRUE else var/datum/map_config/VM = maprotatechoices[chosenmap] message_admins("[key_name_admin(usr)] is changing the map to [VM.map_name]") log_admin("[key_name(usr)] is changing the map to [VM.map_name]") if (SSmapping.changemap(VM)) message_admins("[key_name_admin(usr)] has changed the map to [VM.map_name]") + SSmapping.map_force_chosen = TRUE diff --git a/config/config.txt b/config/config.txt index 569b62c7160..c80b60cae87 100644 --- a/config/config.txt +++ b/config/config.txt @@ -200,6 +200,12 @@ ID_CONSOLE_JOBSLOT_DELAY 30 ## allow players to initiate a map-change vote #ALLOW_VOTE_MAP +## allow players to rock the vote, or to vote on the map again if they didn't like the last results +#ALLOW_ROCK_THE_VOTE + +## the number of times you wish to allow players to rock the vote in a given shift +MAX_ROCKING_VOTES 1 + ## min delay (deciseconds) between voting sessions (default 10 minutes) VOTE_DELAY 6000 diff --git a/tgstation.dme b/tgstation.dme index 7cd419dbc20..4b606016959 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1226,6 +1226,7 @@ #include "code\datums\votes\custom_vote.dm" #include "code\datums\votes\map_vote.dm" #include "code\datums\votes\restart_vote.dm" +#include "code\datums\votes\rock_the_vote.dm" #include "code\datums\weather\weather.dm" #include "code\datums\weather\weather_types\ash_storm.dm" #include "code\datums\weather\weather_types\floor_is_lava.dm"