From 334894ea3affd7de06f42d18e561eaf2e8006909 Mon Sep 17 00:00:00 2001 From: Krausus Date: Fri, 22 Jul 2016 22:00:58 -0400 Subject: [PATCH 1/3] Makes vote controller pathing non-relative This is a separate commit so other changes are actually visible in the diffs --- code/controllers/voting.dm | 628 ++++++++++++++++++------------------- 1 file changed, 314 insertions(+), 314 deletions(-) diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index 52c976ec470..842de2e2a03 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -2,7 +2,7 @@ var/datum/controller/vote/vote = new() var/global/list/round_voters = list() //Keeps track of the individuals voting for a given round, for use in forcedrafting. -datum/controller/vote +/datum/controller/vote var/initiator = null var/started_time = null var/time_remaining = 0 @@ -14,340 +14,340 @@ datum/controller/vote var/list/current_votes = list() var/auto_muted = 0 - New() - if(vote != src) - if(istype(vote)) - qdel(vote) - vote = src +/datum/controller/vote/New() + if(vote != src) + if(istype(vote)) + qdel(vote) + vote = src - proc/process() //called by master_controller - if(mode) - // No more change mode votes after the game has started. - // 3 is GAME_STATE_PLAYING, but that #define is undefined for some reason - if(mode == "gamemode" && ticker.current_state >= 2) - to_chat(world, "Voting aborted due to game start.") - src.reset() - return +/datum/controller/vote/proc/process() //called by master_controller + if(mode) + // No more change mode votes after the game has started. + // 3 is GAME_STATE_PLAYING, but that #define is undefined for some reason + if(mode == "gamemode" && ticker.current_state >= 2) + to_chat(world, "Voting aborted due to game start.") + src.reset() + return - // Calculate how much time is remaining by comparing current time, to time of vote start, - // plus vote duration - time_remaining = round((started_time + config.vote_period - world.time)/10) + // Calculate how much time is remaining by comparing current time, to time of vote start, + // plus vote duration + time_remaining = round((started_time + config.vote_period - world.time)/10) - if(time_remaining < 0) - result() - for(var/client/C in voting) - if(C) - C << browse(null,"window=vote;can_close=0") - reset() - else - for(var/client/C in voting) - if(C) - C << browse(vote.interface(C),"window=vote;can_close=0") + if(time_remaining < 0) + result() + for(var/client/C in voting) + if(C) + C << browse(null,"window=vote;can_close=0") + reset() + else + for(var/client/C in voting) + if(C) + C << browse(vote.interface(C),"window=vote;can_close=0") - voting.Cut() + voting.Cut() - proc/autotransfer() - initiate_vote("crew_transfer","the server") +/datum/controller/vote/proc/autotransfer() + initiate_vote("crew_transfer","the server") - proc/reset() - initiator = null - time_remaining = 0 - mode = null - question = null - choices.Cut() - voted.Cut() - voting.Cut() - current_votes.Cut() +/datum/controller/vote/proc/reset() + initiator = null + time_remaining = 0 + mode = null + question = null + choices.Cut() + voted.Cut() + voting.Cut() + current_votes.Cut() - if(auto_muted && !config.ooc_allowed) - auto_muted = 0 - config.ooc_allowed = !( config.ooc_allowed ) - to_chat(world, "The OOC channel has been automatically enabled due to vote end.") - log_admin("OOC was toggled automatically due to vote end.") - message_admins("OOC has been toggled on automatically.") + if(auto_muted && !config.ooc_allowed) + auto_muted = 0 + config.ooc_allowed = !( config.ooc_allowed ) + to_chat(world, "The OOC channel has been automatically enabled due to vote end.") + log_admin("OOC was toggled automatically due to vote end.") + message_admins("OOC has been toggled on automatically.") - proc/get_result() - //get the highest number of votes - var/greatest_votes = 0 - var/total_votes = 0 +/datum/controller/vote/proc/get_result() + //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 + //default-vote for everyone who didn't vote + if(!config.vote_no_default && choices.len) + var/non_voters = (clients.len - total_votes) + if(non_voters > 0) + if(mode == "restart") + choices["Continue Playing"] += non_voters + if(choices["Continue Playing"] >= greatest_votes) + greatest_votes = choices["Continue Playing"] + else if(mode == "gamemode") + if(master_mode in choices) + choices[master_mode] += non_voters + if(choices[master_mode] >= greatest_votes) + greatest_votes = choices[master_mode] + else if(mode == "crew_transfer") + var/factor = 0.5 + switch(world.time / (10 * 60)) // minutes + if(0 to 60) + factor = 0.5 + if(61 to 120) + factor = 0.8 + if(121 to 240) + factor = 1 + if(241 to 300) + factor = 1.2 + else + factor = 1.4 + choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor) + to_chat(world, "Crew Transfer Factor: [factor]") + greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"]) + + + //get all options with that many votes and return them in a list + . = list() + if(greatest_votes) 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.vote_no_default && choices.len) - var/non_voters = (clients.len - total_votes) - if(non_voters > 0) - if(mode == "restart") - choices["Continue Playing"] += non_voters - if(choices["Continue Playing"] >= greatest_votes) - greatest_votes = choices["Continue Playing"] - else if(mode == "gamemode") - if(master_mode in choices) - choices[master_mode] += non_voters - if(choices[master_mode] >= greatest_votes) - greatest_votes = choices[master_mode] - else if(mode == "crew_transfer") - var/factor = 0.5 - switch(world.time / (10 * 60)) // minutes - if(0 to 60) - factor = 0.5 - if(61 to 120) - factor = 0.8 - if(121 to 240) - factor = 1 - if(241 to 300) - factor = 1.2 - else - factor = 1.4 - choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor) - to_chat(world, "Crew Transfer Factor: [factor]") - greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"]) + if(choices[option] == greatest_votes) + . += option + return . +/datum/controller/vote/proc/announce_result() + var/list/winners = get_result() + var/text + if(winners.len > 0) + if(winners.len > 1) + if(mode != "gamemode" || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes + text = "Vote Tied Between:\n" + for(var/option in winners) + text += "\t[option]\n" + . = pick(winners) - //get all options with that many votes and return them in a list - . = list() - if(greatest_votes) - for(var/option in choices) - if(choices[option] == greatest_votes) - . += option - return . - - proc/announce_result() - var/list/winners = get_result() - var/text - if(winners.len > 0) - if(winners.len > 1) - if(mode != "gamemode" || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes - text = "Vote Tied Between:\n" - for(var/option in winners) - text += "\t[option]\n" - . = pick(winners) - - for(var/key in current_votes) - if(choices[current_votes[key]] == .) - round_voters += key // Keep track of who voted for the winning round. - if((mode == "gamemode" && . == "extended") || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes + for(var/key in current_votes) + if(choices[current_votes[key]] == .) + round_voters += key // Keep track of who voted for the winning round. + if((mode == "gamemode" && . == "extended") || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes + text += "Vote Result: [.]" + else + if(mode != "gamemode") text += "Vote Result: [.]" else - if(mode != "gamemode") - text += "Vote Result: [.]" - else - text += "The vote has ended." // What will be shown if it is a gamemode vote that isn't extended + text += "The vote has ended." // What will be shown if it is a gamemode vote that isn't extended - else - text += "Vote Result: Inconclusive - No Votes!" - log_vote(text) - to_chat(world, "[text]") - return . + else + text += "Vote Result: Inconclusive - No Votes!" + log_vote(text) + to_chat(world, "[text]") + return . - proc/result() - . = announce_result() - var/restart = 0 - if(.) - switch(mode) - if("restart") - if(. == "Restart Round") - restart = 1 - if("gamemode") - if(master_mode != .) - world.save_mode(.) - if(ticker && ticker.mode) - restart = 1 - else - master_mode = . - if(!going) - going = 1 - to_chat(world, "The round will start soon.") - if("crew_transfer") - if(. == "Initiate Crew Transfer") - init_shift_change(null, 1) - - - if(restart) - world.Reboot("Restart vote successful.", "end_error", "restart vote") - - return . - - proc/submit_vote(var/ckey, var/vote) - if(mode) - if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) - return 0 - if(current_votes[ckey]) - choices[choices[current_votes[ckey]]]-- - if(vote && 1<=vote && vote<=choices.len) - voted += usr.ckey - choices[choices[vote]]++ //check this - current_votes[ckey] = vote - return vote - return 0 - - proc/initiate_vote(var/vote_type, var/initiator_key) - if(!mode) - if(started_time != null && !check_rights(R_ADMIN)) - var/next_allowed_time = (started_time + config.vote_delay) - if(next_allowed_time > world.time) - return 0 - - reset() - switch(vote_type) - if("restart") - choices.Add("Restart Round","Continue Playing") - if("gamemode") - if(ticker.current_state >= 2) - return 0 - choices.Add(config.votable_modes) - if("crew_transfer") - if(check_rights(R_ADMIN|R_MOD)) - if(ticker.current_state <= 2) - return 0 - question = "End the shift?" - choices.Add("Initiate Crew Transfer", "Continue The Round") - else - if(ticker.current_state <= 2) - return 0 - question = "End the shift?" - choices.Add("Initiate Crew Transfer", "Continue The Round") - if("custom") - question = html_encode(input(usr,"What is the vote for?") as text|null) - if(!question) return 0 - for(var/i=1,i<=10,i++) - var/option = capitalize(html_encode(input(usr,"Please enter an option or hit cancel to finish") as text|null)) - if(!option || mode || !usr.client) break - choices.Add(option) - else return 0 - mode = vote_type - initiator = initiator_key - started_time = world.time - var/text = "[capitalize(mode)] vote started by [initiator]." - if(mode == "custom") - text += "\n[question]" - - log_vote(text) - to_chat(world, "[text]\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote.") - switch(vote_type) - if("crew_transfer") - world << sound('sound/ambience/alarm4.ogg') - if("gamemode") - world << sound('sound/ambience/alarm4.ogg') - if("custom") - world << sound('sound/ambience/alarm4.ogg') - if(mode == "gamemode" && going) - going = 0 - to_chat(world, "Round start has been delayed.") - if(mode == "crew_transfer" && config.ooc_allowed) - auto_muted = 1 - config.ooc_allowed = !( config.ooc_allowed ) - to_chat(world, "The OOC channel has been automatically disabled due to a crew transfer vote.") - log_admin("OOC was toggled automatically due to crew_transfer vote.") - message_admins("OOC has been toggled off automatically.") - if(mode == "gamemode" && config.ooc_allowed) - auto_muted = 1 - config.ooc_allowed = !( config.ooc_allowed ) - to_chat(world, "The OOC channel has been automatically disabled due to the gamemode vote.") - log_admin("OOC was toggled automatically due to gamemode vote.") - message_admins("OOC has been toggled off automatically.") - if(mode == "custom" && config.ooc_allowed) - auto_muted = 1 - config.ooc_allowed = !( config.ooc_allowed ) - to_chat(world, "The OOC channel has been automatically disabled due to a custom vote.") - log_admin("OOC was toggled automatically due to custom vote.") - message_admins("OOC has been toggled off automatically.") - - - - - time_remaining = round(config.vote_period/10) - return 1 - return 0 - - proc/interface(var/client/C) - if(!C) return - var/admin = check_rights(R_ADMIN,0) - voting |= C - - . = "Voting Panel" - if(mode) - if(question) . += "

Vote: '[question]'

" - else . += "

Vote: [capitalize(mode)]

" - . += "Time Left: [time_remaining] s

" - if(admin) - . += "(Cancel Vote) " - else - . += "

Start a vote:



" - . += "Close" - return . - - - Topic(href,href_list[],hsrc) - if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid - var/admin = check_rights(R_ADMIN,0) - switch(href_list["vote"]) - if("close") - voting -= usr.client - usr << browse(null, "window=vote") - return - if("cancel") - if(admin) - reset() - if("toggle_restart") - if(admin) - config.allow_vote_restart = !config.allow_vote_restart - if("toggle_gamemode") - if(admin) - config.allow_vote_mode = !config.allow_vote_mode +/datum/controller/vote/proc/result() + . = announce_result() + var/restart = 0 + if(.) + switch(mode) if("restart") - if(config.allow_vote_restart || admin) - initiate_vote("restart",usr.key) + if(. == "Restart Round") + restart = 1 if("gamemode") - if(config.allow_vote_mode || admin) - initiate_vote("gamemode",usr.key) + if(master_mode != .) + world.save_mode(.) + if(ticker && ticker.mode) + restart = 1 + else + master_mode = . + if(!going) + going = 1 + to_chat(world, "The round will start soon.") if("crew_transfer") - if(config.allow_vote_restart || admin) - initiate_vote("crew_transfer",usr.key) + if(. == "Initiate Crew Transfer") + init_shift_change(null, 1) + + + if(restart) + world.Reboot("Restart vote successful.", "end_error", "restart vote") + + return . + +/datum/controller/vote/proc/submit_vote(var/ckey, var/vote) + if(mode) + if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) + return 0 + if(current_votes[ckey]) + choices[choices[current_votes[ckey]]]-- + if(vote && 1<=vote && vote<=choices.len) + voted += usr.ckey + choices[choices[vote]]++ //check this + current_votes[ckey] = vote + return vote + return 0 + +/datum/controller/vote/proc/initiate_vote(var/vote_type, var/initiator_key) + if(!mode) + if(started_time != null && !check_rights(R_ADMIN)) + var/next_allowed_time = (started_time + config.vote_delay) + if(next_allowed_time > world.time) + return 0 + + reset() + switch(vote_type) + if("restart") + choices.Add("Restart Round","Continue Playing") + if("gamemode") + if(ticker.current_state >= 2) + return 0 + choices.Add(config.votable_modes) + if("crew_transfer") + if(check_rights(R_ADMIN|R_MOD)) + if(ticker.current_state <= 2) + return 0 + question = "End the shift?" + choices.Add("Initiate Crew Transfer", "Continue The Round") + else + if(ticker.current_state <= 2) + return 0 + question = "End the shift?" + choices.Add("Initiate Crew Transfer", "Continue The Round") if("custom") - if(admin) - initiate_vote("custom",usr.key) + question = html_encode(input(usr,"What is the vote for?") as text|null) + if(!question) return 0 + for(var/i=1,i<=10,i++) + var/option = capitalize(html_encode(input(usr,"Please enter an option or hit cancel to finish") as text|null)) + if(!option || mode || !usr.client) break + choices.Add(option) + else return 0 + mode = vote_type + initiator = initiator_key + started_time = world.time + var/text = "[capitalize(mode)] vote started by [initiator]." + if(mode == "custom") + text += "\n[question]" + + log_vote(text) + to_chat(world, "[text]\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote.") + switch(vote_type) + if("crew_transfer") + world << sound('sound/ambience/alarm4.ogg') + if("gamemode") + world << sound('sound/ambience/alarm4.ogg') + if("custom") + world << sound('sound/ambience/alarm4.ogg') + if(mode == "gamemode" && going) + going = 0 + to_chat(world, "Round start has been delayed.") + if(mode == "crew_transfer" && config.ooc_allowed) + auto_muted = 1 + config.ooc_allowed = !( config.ooc_allowed ) + to_chat(world, "The OOC channel has been automatically disabled due to a crew transfer vote.") + log_admin("OOC was toggled automatically due to crew_transfer vote.") + message_admins("OOC has been toggled off automatically.") + if(mode == "gamemode" && config.ooc_allowed) + auto_muted = 1 + config.ooc_allowed = !( config.ooc_allowed ) + to_chat(world, "The OOC channel has been automatically disabled due to the gamemode vote.") + log_admin("OOC was toggled automatically due to gamemode vote.") + message_admins("OOC has been toggled off automatically.") + if(mode == "custom" && config.ooc_allowed) + auto_muted = 1 + config.ooc_allowed = !( config.ooc_allowed ) + to_chat(world, "The OOC channel has been automatically disabled due to a custom vote.") + log_admin("OOC was toggled automatically due to custom vote.") + message_admins("OOC has been toggled off automatically.") + + + + + time_remaining = round(config.vote_period/10) + return 1 + return 0 + +/datum/controller/vote/proc/interface(var/client/C) + if(!C) return + var/admin = check_rights(R_ADMIN,0) + voting |= C + + . = "Voting Panel" + if(mode) + if(question) . += "

Vote: '[question]'

" + else . += "

Vote: [capitalize(mode)]

" + . += "Time Left: [time_remaining] s

" + if(admin) + . += "(Cancel Vote) " + else + . += "

Start a vote:



" + . += "Close" + return . + + +/datum/controller/vote/Topic(href,href_list[],hsrc) + if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid + var/admin = check_rights(R_ADMIN,0) + switch(href_list["vote"]) + if("close") + voting -= usr.client + usr << browse(null, "window=vote") + return + if("cancel") + if(admin) + reset() + if("toggle_restart") + if(admin) + config.allow_vote_restart = !config.allow_vote_restart + if("toggle_gamemode") + if(admin) + config.allow_vote_mode = !config.allow_vote_mode + if("restart") + if(config.allow_vote_restart || admin) + initiate_vote("restart",usr.key) + if("gamemode") + if(config.allow_vote_mode || admin) + initiate_vote("gamemode",usr.key) + if("crew_transfer") + if(config.allow_vote_restart || admin) + initiate_vote("crew_transfer",usr.key) + if("custom") + if(admin) + initiate_vote("custom",usr.key) + else + submit_vote(usr.ckey, round(text2num(href_list["vote"]))) + usr.vote() /mob/verb/vote() From 5b21a9a7853a20ec6992dc691f3826501d99b707 Mon Sep 17 00:00:00 2001 From: Krausus Date: Sat, 23 Jul 2016 02:03:19 -0400 Subject: [PATCH 2/3] Improves voting system - Makes votes show votes for winning option, or all options in a custom vote - Makes the voting panel automatically update - Makes the voting panel use the browser datum - Turns the voting notice into a clickable link - Fixes admin status not properly being checked when the voting page is refreshed - Replaces vote process with a spawned loop in the vote controller - Removes vote processing from the pre-game game ticker --- code/controllers/Processes/vote.dm | 7 -- code/controllers/voting.dm | 167 ++++++++++++++++++----------- code/game/gamemodes/gameticker.dm | 4 +- paradise.dme | 1 - 4 files changed, 105 insertions(+), 74 deletions(-) delete mode 100644 code/controllers/Processes/vote.dm diff --git a/code/controllers/Processes/vote.dm b/code/controllers/Processes/vote.dm deleted file mode 100644 index 47cf079eeba..00000000000 --- a/code/controllers/Processes/vote.dm +++ /dev/null @@ -1,7 +0,0 @@ -/datum/controller/process/vote/setup() - name = "vote" - schedule_interval = 10 // every second - log_startup_progress("Voting ticker starting up.") - -/datum/controller/process/vote/doWork() - vote.process() diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index 842de2e2a03..5b152b8a4db 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -19,14 +19,17 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo if(istype(vote)) qdel(vote) vote = src + spawn(0) + while(TRUE) + process() + sleep(10) -/datum/controller/vote/proc/process() //called by master_controller +/datum/controller/vote/proc/process() if(mode) // No more change mode votes after the game has started. - // 3 is GAME_STATE_PLAYING, but that #define is undefined for some reason - if(mode == "gamemode" && ticker.current_state >= 2) + if(mode == "gamemode" && ticker.current_state >= GAME_STATE_SETTING_UP) to_chat(world, "Voting aborted due to game start.") - src.reset() + reset() return // Calculate how much time is remaining by comparing current time, to time of vote start, @@ -37,14 +40,10 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo result() for(var/client/C in voting) if(C) - C << browse(null,"window=vote;can_close=0") + C << browse(null,"window=vote") reset() else - for(var/client/C in voting) - if(C) - C << browse(vote.interface(C),"window=vote;can_close=0") - - voting.Cut() + update_panel() /datum/controller/vote/proc/autotransfer() initiate_vote("crew_transfer","the server") @@ -68,14 +67,26 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo /datum/controller/vote/proc/get_result() - //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 + var/list/sorted_choices = list() + var/sorted_highest + var/sorted_votes = -1 + //get the highest number of votes, while also sorting the list + while(choices.len) + // This is a very inefficient sorting method, but that's okay + for(var/option in choices) + var/votes = choices[option] + if(sorted_votes < votes) + sorted_highest = option + sorted_votes = votes + if(votes > greatest_votes) + greatest_votes = votes + sorted_votes = -1 + total_votes += choices[sorted_highest] + sorted_choices[sorted_highest] = choices[sorted_highest] || 0 + choices -= sorted_highest + choices = sorted_choices //default-vote for everyone who didn't vote if(!config.vote_no_default && choices.len) var/non_voters = (clients.len - total_votes) @@ -129,11 +140,18 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo for(var/key in current_votes) if(choices[current_votes[key]] == .) round_voters += key // Keep track of who voted for the winning round. - if((mode == "gamemode" && . == "extended") || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes - text += "Vote Result: [.]" + if(mode == "gamemode" && (. == "extended" || ticker.hide_mode == 0)) // Announce Extended gamemode, but not other gamemodes + text += "Vote Result: [.] ([choices[.]] vote\s)" else - if(mode != "gamemode") - text += "Vote Result: [.]" + if(mode == "custom") + // Completely replace text to show all results in custom votes + text = "[question]\n" + for(var/option in winners) + text += "\t[option]: [choices[option]] vote\s\n" + for(var/option in (choices-winners)) + text += "\t[option]: [choices[option]] vote\s\n" + else if(mode != "gamemode") + text += "Vote Result: [.] ([choices[.]] vote\s)" else text += "The vote has ended." // What will be shown if it is a gamemode vote that isn't extended @@ -217,7 +235,8 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo var/option = capitalize(html_encode(input(usr,"Please enter an option or hit cancel to finish") as text|null)) if(!option || mode || !usr.client) break choices.Add(option) - else return 0 + else + return 0 mode = vote_type initiator = initiator_key started_time = world.time @@ -226,7 +245,9 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo text += "\n[question]" log_vote(text) - to_chat(world, "[text]\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote.") + to_chat(world, {"[text] + Click here or type vote to place your vote. + You have [config.vote_period/10] seconds to vote."}) switch(vote_type) if("crew_transfer") world << sound('sound/ambience/alarm4.ogg') @@ -256,74 +277,92 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo log_admin("OOC was toggled automatically due to custom vote.") message_admins("OOC has been toggled off automatically.") - - - time_remaining = round(config.vote_period/10) return 1 return 0 -/datum/controller/vote/proc/interface(var/client/C) - if(!C) return - var/admin = check_rights(R_ADMIN,0) +/datum/controller/vote/proc/browse_to(var/client/C) + if(!C) + return + var/admin = check_rights(R_ADMIN, 0, user = C.mob) voting |= C - . = "Voting Panel" + var/dat = {""} if(mode) - if(question) . += "

Vote: '[question]'

" - else . += "

Vote: [capitalize(mode)]

" - . += "Time Left: [time_remaining] s

" + dat += "
[vote_html(C)]

" if(admin) - . += "(Cancel Vote) " + dat += "(Cancel Vote) " else - . += "

Start a vote:



" + var/datum/browser/popup = new(C.mob, "vote", "Voting Panel", nref=src) + popup.set_content(dat) + popup.open() + +/datum/controller/vote/proc/update_panel(var/client/client) + for(var/client/C in (client ? list(client) : voting)) + C << output(url_encode(vote_html(C)), "vote.browser:update_vote_div") + +/datum/controller/vote/proc/vote_html(var/client/C) + . = "" + if(question) + . += "

Vote: '[question]'

" + else + . += "

Vote: [capitalize(mode)]

" + . += "Time Left: [time_remaining] s
" /datum/controller/vote/Topic(href,href_list[],hsrc) if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid var/admin = check_rights(R_ADMIN,0) + if(href_list["close"]) + voting -= usr.client + return switch(href_list["vote"]) - if("close") - voting -= usr.client - usr << browse(null, "window=vote") - return + if("open") + // vote proc will automatically get called after this switch ends if("cancel") if(admin) reset() @@ -347,6 +386,8 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo initiate_vote("custom",usr.key) else submit_vote(usr.ckey, round(text2num(href_list["vote"]))) + update_panel(usr.client) + return usr.vote() @@ -355,4 +396,4 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo set name = "Vote" if(vote) - src << browse(vote.interface(client),"window=vote;can_close=0") + vote.browse_to(client) diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 35d17607709..7d6ea9b4e7d 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -48,9 +48,7 @@ var/round_start_time = 0 to_chat(world, "Welcome to the pre-game lobby!") to_chat(world, "Please, setup your character and select ready. Game will start in [pregame_timeleft] seconds") while(current_state == GAME_STATE_PREGAME) - for(var/i=0, i<10, i++) - sleep(1) - vote.process() + sleep(10) if(going) pregame_timeleft-- diff --git a/paradise.dme b/paradise.dme index 4f7fa9adeb9..8792226ca0f 100644 --- a/paradise.dme +++ b/paradise.dme @@ -180,7 +180,6 @@ #include "code\controllers\Processes\sun.dm" #include "code\controllers\Processes\ticker.dm" #include "code\controllers\Processes\timer.dm" -#include "code\controllers\Processes\vote.dm" #include "code\controllers\Processes\weather.dm" #include "code\controllers\ProcessScheduler\core\process.dm" #include "code\controllers\ProcessScheduler\core\processScheduler.dm" From 6cff9b10d66bdc9cb0eb6b8db9675a11850ffa63 Mon Sep 17 00:00:00 2001 From: Krausus Date: Sun, 24 Jul 2016 19:46:34 -0400 Subject: [PATCH 3/3] Further voting controller tweaks - Adds admin logging to creating and canceling votes - Adds exception handling - Adds deletion handling (should, theoretically, never be necessary) - Adds tick-checking, just in case there's a lot of clients watching a vote - Adds the vote controller to the "debug controller" list - Fixes that one "if" Tiger whined about --- code/controllers/verbs.dm | 5 ++++- code/controllers/voting.dm | 32 +++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 25b038554cc..3aa638aa40f 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -18,7 +18,7 @@ return -/client/proc/debug_controller(controller in list("Master","failsafe","Ticker","Air","Lighting","Jobs","Sun","Radio","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event","Alarm","Scheduler","Nano")) +/client/proc/debug_controller(controller in list("Master","failsafe","Ticker","Air","Lighting","Jobs","Sun","Radio","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event","Alarm","Scheduler","Nano","Vote")) set category = "Debug" set name = "Debug Controller" set desc = "Debug the various periodic loop controllers for the game (be careful!)" @@ -73,6 +73,9 @@ if("Nano") debug_variables(nanomanager) feedback_add_details("admin_verb","DNano") + if("Vote") + debug_variables(vote) + feedback_add_details("admin_verb","DVote") message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") return diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index 5b152b8a4db..451fdbd99e3 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -20,9 +20,13 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo qdel(vote) vote = src spawn(0) - while(TRUE) - process() - sleep(10) + while(!gcDestroyed) + try + while(!gcDestroyed) + sleep(10) + process() + catch(var/exception/e) + log_runtime(e, src, "Caught in vote controller") /datum/controller/vote/proc/process() if(mode) @@ -43,7 +47,9 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo C << browse(null,"window=vote") reset() else - update_panel() + for(var/client/C in voting) + update_panel(C) + CHECK_TICK /datum/controller/vote/proc/autotransfer() initiate_vote("crew_transfer","the server") @@ -243,6 +249,10 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo var/text = "[capitalize(mode)] vote started by [initiator]." if(mode == "custom") text += "\n[question]" + if(usr) + log_admin("[capitalize(mode)] ([question]) vote started by [key_name(usr)].") + else if(usr) + log_admin("[capitalize(mode)] vote started by [key_name(usr)].") log_vote(text) to_chat(world, {"[text] @@ -331,9 +341,8 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo popup.set_content(dat) popup.open() -/datum/controller/vote/proc/update_panel(var/client/client) - for(var/client/C in (client ? list(client) : voting)) - C << output(url_encode(vote_html(C)), "vote.browser:update_vote_div") +/datum/controller/vote/proc/update_panel(var/client/C) + C << output(url_encode(vote_html(C)), "vote.browser:update_vote_div") /datum/controller/vote/proc/vote_html(var/client/C) . = "" @@ -355,7 +364,8 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo /datum/controller/vote/Topic(href,href_list[],hsrc) - if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid + if(!usr || !usr.client) + return //not necessary but meh...just in-case somebody does something stupid var/admin = check_rights(R_ADMIN,0) if(href_list["close"]) voting -= usr.client @@ -364,7 +374,11 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo if("open") // vote proc will automatically get called after this switch ends if("cancel") - if(admin) + if(admin && mode) + var/votedesc = capitalize(mode) + if(mode == "custom") + votedesc += " ([question])" + admin_log_and_message_admins("cancelled the running [votedesc] vote.") reset() if("toggle_restart") if(admin)