diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm
index c394318c28..bb7bf300d0 100644
--- a/code/controllers/verbs.dm
+++ b/code/controllers/verbs.dm
@@ -25,7 +25,7 @@
usr.client.debug_variables(antag)
message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.")
-/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry"))
+/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry","Vote"))
set category = "Debug"
set name = "Debug Controller"
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
@@ -92,5 +92,8 @@
if("Chemistry")
debug_variables(chemistryProcess)
feedback_add_details("admin_verb", "DChem")
+ 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 efab120483..e6f88731b6 100644
--- a/code/controllers/voting.dm
+++ b/code/controllers/voting.dm
@@ -1,9 +1,15 @@
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.
+var/global/list/round_voters = list() // Keeps track of the individuals voting for a given round, for use in forcedrafting.
-datum/controller/vote
- var/initiator = null
+#define VOTE_RESTART "restart"
+#define VOTE_GAMEMODE "gamemode"
+#define VOTE_CREW_TRANSFER "crew_transfer"
+#define VOTE_ADD_ANTAGONIST "add_antagonist"
+#define VOTE_CUSTOM "custom"
+
+/datum/controller/vote
+ var/initiator = null // Key of the one who started the vote or "the server"
var/started_time = null
var/time_remaining = 0
var/mode = null
@@ -11,385 +17,366 @@ datum/controller/vote
var/list/choices = list()
var/list/gamemode_names = list()
var/list/voted = list()
- var/list/voting = list()
var/list/current_votes = list()
var/list/additional_text = list()
- var/auto_muted = 0
- New()
- if(vote != src)
- if(istype(vote))
- del(vote)
- vote = src
+/datum/controller/vote/New()
+ if(vote != src)
+ if(istype(vote))
+ del(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)
- 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.
+ if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP)
+ 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)
-
- if(time_remaining < 0)
- result()
- for(var/client/C in voting)
- if(C)
- C << browse(null,"window=vote")
- reset()
- else
- for(var/client/C in voting)
- if(C)
- C << browse(vote.interface(C),"window=vote")
-
- voting.Cut()
-
- proc/autotransfer()
- initiate_vote("crew_transfer","the server", 1)
- log_debug("The server has called a crew transfer vote")
-
- proc/autogamemode()
- initiate_vote("gamemode","the server", 1)
- log_debug("The server has called a gamemode vote")
-
- proc/reset()
- initiator = null
- time_remaining = 0
- mode = null
- question = null
- choices.Cut()
- voted.Cut()
- voting.Cut()
- current_votes.Cut()
- additional_text.Cut()
-
- 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)
- 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)
- 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
- 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
-
- else
- text += "Vote Result: Inconclusive - No Votes!"
- if(mode == "add_antagonist")
- antag_add_failed = 1
- log_vote(text)
- 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("crew_transfer")
- if(. == "Initiate Crew Transfer")
- init_shift_change(null, 1)
- if("add_antagonist")
- if(isnull(.) || . == "None")
- antag_add_failed = 1
- else
- additional_antag_types |= antag_names_to_ids[.]
-
- if(mode == "gamemode") //fire this even if the vote fails.
- if(!round_progressing)
- round_progressing = 1
- world << "The round will start soon."
-
- if(restart)
- world << "World restarting due to vote..."
- feedback_set_details("end_error","restart vote")
- if(blackbox) blackbox.save_all_data_to_sql()
- sleep(50)
- log_game("Rebooting due to restart vote")
- world.Reboot()
-
- return .
-
- proc/submit_vote(var/ckey, var/vote)
- if(mode)
- if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
- return 0
- if(vote && vote >= 1 && vote <= choices.len)
- if(current_votes[ckey])
- choices[choices[current_votes[ckey]]]--
- 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, var/automatic = 0)
- if(!mode)
- if(started_time != null && !(check_rights(R_ADMIN) || automatic))
- var/next_allowed_time = (started_time + config.vote_delay)
- if(next_allowed_time > world.time)
- return 0
+ // 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()
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)
- for (var/F in choices)
- var/datum/game_mode/M = gamemode_cache[F]
- if(!M)
- continue
- gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works
- additional_text.Add("
[M.required_players] | ")
- gamemode_names["secret"] = "Secret"
- if("crew_transfer")
- if(check_rights(R_ADMIN|R_MOD, 0))
- question = "End the shift?"
- choices.Add("Initiate Crew Transfer", "Continue The Round")
+
+/datum/controller/vote/proc/autotransfer()
+ initiate_vote(VOTE_CREW_TRANSFER, "the server", 1)
+ log_debug("The server has called a crew transfer vote")
+
+/datum/controller/vote/proc/autogamemode()
+ initiate_vote(VOTE_GAMEMODE, "the server", 1)
+ log_debug("The server has called a gamemode vote")
+
+/datum/controller/vote/proc/reset()
+ initiator = null
+ time_remaining = 0
+ mode = null
+ question = null
+ choices.Cut()
+ voted.Cut()
+ current_votes.Cut()
+ additional_text.Cut()
+
+/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
+
+ if(!config.vote_no_default && choices.len) // Default-vote for everyone who didn't vote
+ var/non_voters = (clients.len - total_votes)
+ if(non_voters > 0)
+ if(mode == VOTE_RESTART)
+ choices["Continue Playing"] += non_voters
+ if(choices["Continue Playing"] >= greatest_votes)
+ greatest_votes = choices["Continue Playing"]
+ else if(mode == VOTE_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 == VOTE_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
- if (get_security_level() == "red" || get_security_level() == "delta")
- initiator_key << "The current alert status is too high to call for a crew transfer!"
- return 0
- if(ticker.current_state <= 2)
- return 0
- initiator_key << "The crew transfer button has been disabled!"
- question = "End the shift?"
- choices.Add("Initiate Crew Transfer", "Continue The Round")
- if("add_antagonist")
- if(!config.allow_extra_antags || ticker.current_state >= 2)
- return 0
- for(var/antag_type in all_antag_types)
- var/datum/antagonist/antag = all_antag_types[antag_type]
- if(!(antag.id in additional_antag_types) && antag.is_votable())
- choices.Add(antag.role_text)
- choices.Add("None")
- if("custom")
- question = sanitizeSafe(input(usr,"What is the vote for?") as text|null)
- if(!question) return 0
- for(var/i=1,i<=10,i++)
- var/option = capitalize(sanitize(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]"
+ factor = 1.4
+ choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor)
+ world << "Crew Transfer Factor: [factor]"
+ greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"])
- log_vote(text)
- world << "[text]\nType vote or click here 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', repeat = 0, wait = 0, volume = 50, channel = 3)
- if("gamemode")
- world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
- if("custom")
- world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
- if(mode == "gamemode" && round_progressing)
- round_progressing = 0
- world << "Round start has been delayed."
+ . = list() // Get all options with that many votes and return them in a list
+ if(greatest_votes)
+ for(var/option in choices)
+ if(choices[option] == greatest_votes)
+ . += option
- time_remaining = round(config.vote_period/10)
- return 1
- return 0
+/datum/controller/vote/proc/announce_result()
+ var/list/winners = get_result()
+ var/text
+ if(winners.len > 0)
+ if(winners.len > 1)
+ if(mode != VOTE_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)
- proc/interface(var/client/C)
- if(!C) return
- var/admin = 0
- var/trialmin = 0
- if(C.holder)
- if(C.holder.rights & R_ADMIN)
- admin = 1
- trialmin = 1 // don't know why we use both of these it's really weird, but I'm 2 lasy to refactor this all to use just admin.
- voting |= C
-
- . = "Voting Panel"
- if(mode)
- if(question) . += "Vote: '[question]'
"
- else . += "Vote: [capitalize(mode)]
"
- . += "Time Left: [time_remaining] s
"
- . += "| Choices | Votes | "
- if(capitalize(mode) == "Gamemode") .+= "Minimum Players |
"
-
- for(var/i = 1, i <= choices.len, i++)
- var/votes = choices[choices[i]]
- if(!votes) votes = 0
- . += ""
- if(mode == "gamemode")
- if(current_votes[C.ckey] == i)
- . += "| [gamemode_names[choices[i]]] | [votes] | "
- else
- . += "[gamemode_names[choices[i]]] | [votes] | "
- else
- if(current_votes[C.ckey] == i)
- . += "[choices[i]] | [votes] | "
- else
- . += "[choices[i]] | [votes] | "
- if (additional_text.len >= i)
- . += additional_text[i]
- . += "
"
-
- . += "
"
- if(admin)
- . += "(Cancel Vote) "
+ 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 != VOTE_GAMEMODE || . == "Extended" || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes
+ text += "Vote Result: [.]"
else
- . += "Start a vote:
"
- . += "Close"
- return .
+ text += "The vote has ended."
+ else
+ text += "Vote Result: Inconclusive - No Votes!"
+ if(mode == VOTE_ADD_ANTAGONIST)
+ antag_add_failed = 1
+ log_vote(text)
+ world << "[text]"
- Topic(href,href_list[],hsrc)
- if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid
- switch(href_list["vote"])
- if("close")
- voting -= usr.client
- usr << browse(null, "window=vote")
- return
- if("cancel")
- if(usr.client.holder)
- reset()
- if("toggle_restart")
- if(usr.client.holder)
- config.allow_vote_restart = !config.allow_vote_restart
- if("toggle_gamemode")
- if(usr.client.holder)
- config.allow_vote_mode = !config.allow_vote_mode
- if("restart")
- if(config.allow_vote_restart || usr.client.holder)
- initiate_vote("restart",usr.key)
- if("gamemode")
- if(config.allow_vote_mode || usr.client.holder)
- initiate_vote("gamemode",usr.key)
- if("crew_transfer")
- if(config.allow_vote_restart || usr.client.holder)
- initiate_vote("crew_transfer",usr.key)
- if("add_antagonist")
- if(config.allow_extra_antags)
- initiate_vote("add_antagonist",usr.key)
- if("custom")
- if(usr.client.holder)
- initiate_vote("custom",usr.key)
+/datum/controller/vote/proc/result()
+ . = announce_result()
+ var/restart = 0
+ if(.)
+ switch(mode)
+ if(VOTE_RESTART)
+ if(. == "Restart Round")
+ restart = 1
+ if(VOTE_GAMEMODE)
+ if(master_mode != .)
+ world.save_mode(.)
+ if(ticker && ticker.mode)
+ restart = 1
+ else
+ master_mode = .
+ if(VOTE_CREW_TRANSFER)
+ if(. == "Initiate Crew Transfer")
+ init_shift_change(null, 1)
+ if(VOTE_ADD_ANTAGONIST)
+ if(isnull(.) || . == "None")
+ antag_add_failed = 1
+ else
+ additional_antag_types |= antag_names_to_ids[.]
+
+ if(mode == VOTE_GAMEMODE) //fire this even if the vote fails.
+ if(!round_progressing)
+ round_progressing = 1
+ world << "The round will start soon."
+
+ if(restart)
+ world << "World restarting due to vote..."
+ feedback_set_details("end_error", "restart vote")
+ if(blackbox)
+ blackbox.save_all_data_to_sql()
+ sleep(50)
+ log_game("Rebooting due to restart vote")
+ world.Reboot()
+
+/datum/controller/vote/proc/submit_vote(var/ckey, var/newVote)
+ if(mode)
+ if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
+ return
+ if(current_votes[ckey])
+ choices[choices[current_votes[ckey]]]--
+ if(newVote && newVote >= 1 && newVote <= choices.len)
+ choices[choices[newVote]]++
+ current_votes[ckey] = newVote
+ else
+ current_votes[ckey] = null
+
+/datum/controller/vote/proc/initiate_vote(var/vote_type, var/initiator_key, var/automatic = 0)
+ if(!mode)
+ if(started_time != null && !(check_rights(R_ADMIN) || automatic))
+ var/next_allowed_time = (started_time + config.vote_delay)
+ if(next_allowed_time > world.time)
+ return 0
+
+ reset()
+
+ switch(vote_type)
+ if(VOTE_RESTART)
+ choices.Add("Restart Round", "Continue Playing")
+ if(VOTE_GAMEMODE)
+ if(ticker.current_state >= GAME_STATE_SETTING_UP)
+ return 0
+ choices.Add(config.votable_modes)
+ for(var/F in choices)
+ var/datum/game_mode/M = gamemode_cache[F]
+ if(!M)
+ continue
+ gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works
+ additional_text.Add("[M.required_players] | ")
+ gamemode_names["secret"] = "Secret"
+ if(VOTE_CREW_TRANSFER)
+ if(!check_rights(R_ADMIN|R_MOD, 0)) // The gods care not for the affairs of the mortals
+ if(get_security_level() == "red" || get_security_level() == "delta")
+ initiator_key << "The current alert status is too high to call for a crew transfer!"
+ return 0
+ if(ticker.current_state <= GAME_STATE_SETTING_UP)
+ initiator_key << "The crew transfer button has been disabled!"
+ return 0
+ question = "End the shift?"
+ choices.Add("Initiate Crew Transfer", "Continue The Round")
+ if(VOTE_ADD_ANTAGONIST)
+ if(!config.allow_extra_antags || ticker.current_state >= GAME_STATE_SETTING_UP)
+ return 0
+ for(var/antag_type in all_antag_types)
+ var/datum/antagonist/antag = all_antag_types[antag_type]
+ if(!(antag.id in additional_antag_types) && antag.is_votable())
+ choices.Add(antag.role_text)
+ choices.Add("None")
+ if(VOTE_CUSTOM)
+ question = sanitizeSafe(input(usr, "What is the vote for?") as text|null)
+ if(!question)
+ return 0
+ for(var/i = 1 to 10)
+ var/option = capitalize(sanitize(input(usr, "Please enter an option or hit cancel to finish") as text|null))
+ if(!option || mode || !usr.client)
+ break
+ choices.Add(option)
else
- var/t = round(text2num(href_list["vote"]))
- if(t) // It starts from 1, so there's no problem
- submit_vote(usr.ckey, t)
- usr.vote()
+ return 0
+ mode = vote_type
+ initiator = initiator_key
+ started_time = world.time
+ var/text = "[capitalize(mode)] vote started by [initiator]."
+ if(mode == VOTE_CUSTOM)
+ text += "\n[question]"
-/mob/verb/vote()
+ log_vote(text)
+
+ world << "[text]\nType vote or click here to place your votes.\nYou have [config.vote_period / 10] seconds to vote."
+ if(vote_type == VOTE_CREW_TRANSFER || vote_type == VOTE_GAMEMODE || vote_type == VOTE_CUSTOM)
+ world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
+
+ if(mode == VOTE_GAMEMODE && round_progressing)
+ round_progressing = 0
+ world << "Round start has been delayed."
+
+ time_remaining = round(config.vote_period / 10)
+ return 1
+ return 0
+
+/datum/controller/vote/proc/interface(var/client/C)
+ if(!istype(C))
+ return
+ var/admin = 0
+ if(C.holder)
+ if(C.holder.rights & R_ADMIN)
+ admin = 1
+
+ . = "Voting Panel"
+ if(mode)
+ if(question)
+ . += "Vote: '[question]'
"
+ else
+ . += "Vote: [capitalize(mode)]
"
+ . += "Time Left: [time_remaining] s
"
+ . += "| Choices | Votes | "
+ if(mode == VOTE_GAMEMODE)
+ .+= "Minimum Players |
"
+
+ for(var/i = 1 to choices.len)
+ var/votes = choices[choices[i]]
+ if(!votes)
+ votes = 0
+ . += ""
+ var/thisVote = (current_votes[C.ckey] == i)
+ if(mode == VOTE_GAMEMODE)
+ . += "| [thisVote ? "" : ""][gamemode_names[choices[i]]][thisVote ? "" : ""] | [votes] | "
+ else
+ . += "[thisVote ? "" : ""][choices[i]][thisVote ? "" : ""] | [votes] | "
+ if (additional_text.len >= i)
+ . += additional_text[i]
+ . += "
"
+
+ . += "| Unvote |
"
+
+ . += "
"
+ if(admin)
+ . += "(Cancel Vote) "
+ else
+ . += "Start a vote:
"
+
+ . += "Close"
+
+/datum/controller/vote/Topic(href, href_list[])
+ if(!usr || !usr.client)
+ return
+ switch(href_list["vote"])
+ if("close")
+ usr << browse(null, "window=vote")
+ return
+
+ if("cancel")
+ if(usr.client.holder)
+ reset()
+ if("toggle_restart")
+ if(usr.client.holder)
+ config.allow_vote_restart = !config.allow_vote_restart
+ if("toggle_gamemode")
+ if(usr.client.holder)
+ config.allow_vote_mode = !config.allow_vote_mode
+
+ if(VOTE_RESTART)
+ if(config.allow_vote_restart || usr.client.holder)
+ initiate_vote(VOTE_RESTART, usr.key)
+ if(VOTE_GAMEMODE)
+ if(config.allow_vote_mode || usr.client.holder)
+ initiate_vote(VOTE_GAMEMODE, usr.key)
+ if(VOTE_CREW_TRANSFER)
+ if(config.allow_vote_restart || usr.client.holder)
+ initiate_vote(VOTE_CREW_TRANSFER, usr.key)
+ if(VOTE_ADD_ANTAGONIST)
+ if(config.allow_extra_antags || usr.client.holder)
+ initiate_vote(VOTE_ADD_ANTAGONIST, usr.key)
+ if(VOTE_CUSTOM)
+ if(usr.client.holder)
+ initiate_vote(VOTE_CUSTOM, usr.key)
+
+ if("unvote")
+ submit_vote(usr.ckey, null)
+
+ else
+ var/t = round(text2num(href_list["vote"]))
+ if(t) // It starts from 1, so there's no problem
+ submit_vote(usr.ckey, t)
+ usr.client.vote()
+
+/client/verb/vote()
set category = "OOC"
set name = "Vote"
if(vote)
- src << browse(vote.interface(client),"window=vote")
+ src << browse(vote.interface(src), "window=vote;size=500x[300 + vote.choices.len * 25]")