From 0be81785dd870e35e2ed5abef1ff023c29dabc8d Mon Sep 17 00:00:00 2001 From: san7890 Date: Tue, 13 Sep 2022 21:40:01 -0600 Subject: [PATCH] Verbose Vote Initiation Feedback Tooltippery (#69763) * Verbose Vote Initiation Feedback Tooltippery Hey there, So basically, the old implementation had it such that when a vote was disabled and you tried to trigger it, you could get a very nice message in your chat explaining why you could not trigger that vote in that moment. HOWEVER, there's a current fatal flaw in this logic: You can't ever get that to_chat reason as to _why_ this vote is disabled since you can't click the button. I don't know if this ever worked, which is sad, because we had a lot of these nice messages that one would never see. So, let's leverage the power of TGUI and add messages. The messages are applied per-datum singleton, and are a generic explanation of what the vote does when there is no specific reason assigned to it when the can_be_initiated() proc runs. If it can not be initiated, we change the message to reflect exactly why the player can not initiate the vote. It ends up looking something like this: In order for this to work well for the restart vote and to lessen the amount of copy-pasting I might have to do, I created a new proc that checks to see if a valid admin is online, and uses that for both updating the message and restarting the server if the vote clears. * fixes messages not resetting * removes misleading section the admin can always restart the server if they wish --- code/controllers/subsystem/vote.dm | 1 + code/datums/votes/_vote_datum.dm | 6 +++-- code/datums/votes/custom_vote.dm | 1 + code/datums/votes/map_vote.dm | 8 +++--- code/datums/votes/restart_vote.dm | 27 ++++++++++++++++----- code/datums/votes/rock_the_vote.dm | 20 ++++++--------- tgui/packages/tgui/interfaces/VotePanel.tsx | 2 ++ 7 files changed, 41 insertions(+), 24 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 0c98a0e4f5d..853473aac83 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -238,6 +238,7 @@ SUBSYSTEM_DEF(vote) "name" = vote_name, "canBeInitiated" = vote.can_be_initiated(forced = is_lower_admin), "config" = vote.is_config_enabled(), + "message" = vote.message, ) if(vote == current_vote) diff --git a/code/datums/votes/_vote_datum.dm b/code/datums/votes/_vote_datum.dm index 13cae111ef5..9d9fe09b133 100644 --- a/code/datums/votes/_vote_datum.dm +++ b/code/datums/votes/_vote_datum.dm @@ -15,6 +15,8 @@ var/list/default_choices /// Does the name of this vote contain the word "vote"? var/contains_vote_in_name = FALSE + /// What message do we want to pass to the player-side vote panel as a tooltip? + var/message = "Click to initiate a vote." // Internal values used when tracking ongoing votes. // Don't mess with these, change the above values / override procs for subtypes. @@ -75,10 +77,10 @@ if(started_time) var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay)) if(next_allowed_time > world.time && !forced) - if(by_who) - to_chat(by_who, span_warning("A vote was initiated recently. You must wait [DisplayTimeText(next_allowed_time - world.time)] before a new vote can be started!")) + message = "A vote was initiated recently. You must wait [DisplayTimeText(next_allowed_time - world.time)] before a new vote can be started!" return FALSE + message = initial(message) return TRUE /** diff --git a/code/datums/votes/custom_vote.dm b/code/datums/votes/custom_vote.dm index 753e2fef13a..5f1a1a5996d 100644 --- a/code/datums/votes/custom_vote.dm +++ b/code/datums/votes/custom_vote.dm @@ -3,6 +3,7 @@ /datum/vote/custom_vote name = "Custom" + message = "Click here to start a custom vote." // Custom votes ares always accessible. /datum/vote/custom_vote/is_accessible_vote() diff --git a/code/datums/votes/map_vote.dm b/code/datums/votes/map_vote.dm index 849f7c20d12..fc0fe8ade4f 100644 --- a/code/datums/votes/map_vote.dm +++ b/code/datums/votes/map_vote.dm @@ -1,5 +1,6 @@ /datum/vote/map_vote name = "Map" + message = "Vote for next round's map!" /datum/vote/map_vote/New() . = ..() @@ -52,15 +53,14 @@ return TRUE if(!CONFIG_GET(flag/allow_vote_map)) - if(by_who) - to_chat(by_who, span_warning("Map voting is disabled.")) + message = "Map voting is disabled by server configuration settings." return FALSE if(SSmapping.map_voted) - if(by_who) - to_chat(by_who, span_warning("The next map has already been selected.")) + message = "The next map has already been selected." return FALSE + message = initial(message) return TRUE /datum/vote/map_vote/get_vote_result(list/non_voters) diff --git a/code/datums/votes/restart_vote.dm b/code/datums/votes/restart_vote.dm index c71bdb8170e..24d38f35396 100644 --- a/code/datums/votes/restart_vote.dm +++ b/code/datums/votes/restart_vote.dm @@ -7,10 +7,22 @@ CHOICE_RESTART, CHOICE_CONTINUE, ) + message = "Vote to restart the ongoing round." + +/// This proc checks to see if any admins are online for the purposes of this vote to see if it can pass. Returns TRUE if there are valid admins online (Has +SERVER and is not AFK), FALSE otherwise. +/datum/vote/restart_vote/proc/admins_present() + for(var/client/online_admin as anything in GLOB.admins) + if(online_admin.is_afk() || !check_rights_for(online_admin, R_SERVER)) + continue + + return TRUE + + return FALSE /datum/vote/restart_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 @@ -26,10 +38,16 @@ return FALSE if(!forced && !CONFIG_GET(flag/allow_vote_restart)) - if(by_who) - to_chat(by_who, span_warning("Restart voting is disabled.")) + message = "Restart voting is disabled by server configuration settings." return FALSE + // We still want players to be able to vote to restart even if valid admins are online. Let's update the message just so that the player is aware of this fact. + // We don't want to lock-out the vote though, so we'll return TRUE. + if(admins_present()) + message = "Regardless of the results of this vote, the round will not automatically restart because an admin is online." + return TRUE + + message = initial(message) return TRUE /datum/vote/restart_vote/get_vote_result(list/non_voters) @@ -44,10 +62,7 @@ return if(winning_option == CHOICE_RESTART) - for(var/client/online_admin as anything in GLOB.admins) - if(online_admin.is_afk() || !check_rights_for(online_admin, R_SERVER)) - continue - + if(admins_present()) to_chat(world, span_boldannounce("Notice: A restart vote will not restart the server automatically because there are active admins on.")) message_admins("A restart vote has passed, but there are active admins on with +SERVER, so it has been canceled. If you wish, you may restart the server.") return diff --git a/code/datums/votes/rock_the_vote.dm b/code/datums/votes/rock_the_vote.dm index 62181fef64f..6a2a592dea5 100644 --- a/code/datums/votes/rock_the_vote.dm +++ b/code/datums/votes/rock_the_vote.dm @@ -10,6 +10,7 @@ CHOICE_TO_ROCK, CHOICE_NOT_TO_ROCK, ) + message = "Override the current map vote." /// The number of times we have rocked the vote thus far. var/rocking_votes = 0 @@ -32,35 +33,30 @@ 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.")) + message = "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.")) + message = "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.")) + message = "The maximum number of times to rock the vote has been reached." 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!")) + message = "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!")) + message = "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!")) + message = "Rocking the vote is disabled because an admin has forcibly set the map!" return FALSE + message = initial(message) return TRUE /datum/vote/rock_the_vote/finalize_vote(winning_option) diff --git a/tgui/packages/tgui/interfaces/VotePanel.tsx b/tgui/packages/tgui/interfaces/VotePanel.tsx index 4d9f39068f0..4a98fdf4616 100644 --- a/tgui/packages/tgui/interfaces/VotePanel.tsx +++ b/tgui/packages/tgui/interfaces/VotePanel.tsx @@ -13,6 +13,7 @@ type Vote = { name: string; canBeInitiated: BooleanLike; config: VoteConfig; + message: string; }; type Option = { @@ -106,6 +107,7 @@ const VoteOptions = (props, context) => { )}