From 00d7e1f375b7f6f55f71d77be8c7612a6a5d6030 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Mon, 12 Sep 2022 05:18:14 +0200 Subject: [PATCH] [MIRROR] Rocking The Boat, er, Map Vote [MDB IGNORE] (#16083) * 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 * Rocking The Boat, er, Map Vote Co-authored-by: san7890 --- .../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 2783ab4e9e7..ed85e7ee3d2 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -170,6 +170,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 @@ -182,8 +190,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 31ed0c5ebb9..db063de8e08 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 3cdf26b1235..e146c4e7623 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 342f6e712eb..aa14e0664c7 100644 --- a/config/config.txt +++ b/config/config.txt @@ -213,6 +213,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 e2e14db479b..1738a6d2d9a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1294,6 +1294,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"