[READY] TGUI Input Collection (#23891)

* List Input refresh

* Modal Alerts

* Text Input

* Number Input

* Split Button

* Renaming

* Alert converts

* Text Input Conversion (Part 1)

And TextArea Autofocus + maxLength

* Text Input Conversion (Part 2)

* AAAAAAAAAAAAAAAAAAAA

* I'm FUCKED

* @GDNgit review changes

* "'" fixes

* Revert TGUI Alert from admin delete

* NumberInput Window size

* CRASH if empty list

* Update code/modules/tgui/tgui_input/list_input.dm

* TGUI Rebuild

* TGUI Rebuild

* Update code/modules/paperwork/faxmachine.dm

* _char

* compile

* Rebuild

---------

Co-authored-by: Aylong <69762909+Aylong220@users.noreply.github.com>
Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com>
This commit is contained in:
Aylong
2024-02-19 13:55:01 +02:00
committed by GitHub
parent 0d5986fc5c
commit ac5add482f
168 changed files with 2310 additions and 1066 deletions
+4 -4
View File
@@ -545,16 +545,16 @@ GLOBAL_LIST_INIT(view_runtimes_verbs, list(
if("Big Bomb")
explosion(epicenter, 3, 5, 7, 5)
if("Custom Bomb")
var/devastation_range = input("Devastation range (in tiles):") as null|num
var/devastation_range = tgui_input_number(src, "Devastation range (in tiles):", "Custom Bomb", max_value = 255)
if(devastation_range == null)
return
var/heavy_impact_range = input("Heavy impact range (in tiles):") as null|num
var/heavy_impact_range = tgui_input_number(src, "Heavy impact range (in tiles):", "Custom Bomb", max_value = 255)
if(heavy_impact_range == null)
return
var/light_impact_range = input("Light impact range (in tiles):") as null|num
var/light_impact_range = tgui_input_number(src, "Light impact range (in tiles):", "Custom Bomb", max_value = 255)
if(light_impact_range == null)
return
var/flash_range = input("Flash range (in tiles):") as null|num
var/flash_range = tgui_input_number(src, "Flash range (in tiles):", "Custom Bomb", max_value = 255)
if(flash_range == null)
return
explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, 1, 1)
@@ -12,7 +12,7 @@
category = /datum/changeling_power_category/defence
/datum/action/changeling/headslug/try_to_sting(mob/user, mob/target)
if(alert("Are you sure you wish to do this? This action cannot be undone.",,"Yes","No") == "No")
if(tgui_alert(user, "Are you sure you wish to do this? This action cannot be undone.", "Sting", list("Yes", "No")) == "No")
return
..()
@@ -32,7 +32,7 @@
to_chat(user, "<span class='warning'>We are already regenerating.</span>")
return FALSE
if(!user.stat)//Confirmation for living changelings if they want to fake their death
switch(alert("Are we sure we wish to fake our death?",,"Yes","No"))
switch(tgui_alert(user, "Are we sure we wish to fake our death?", "Fake Death", list("Yes", "No")))
if("No")
return FALSE
// Do the checks again since we had user input
@@ -18,7 +18,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
to_chat(user, "<span class='notice'>We feel our consciousness become capable of communion with the hivemind.</span>")
/datum/action/changeling/hivemind_pick/sting_action(mob/user)
var/channel_pick = alert("Upload or Absorb DNA?", "Channel Select", "Upload", "Absorb")
var/channel_pick = tgui_alert(user, "Upload or Absorb DNA?", "Channel Select", list("Upload", "Absorb"))
if(channel_pick == "Upload")
dna_upload(user)
@@ -17,7 +17,7 @@
to_chat(user, "<span class='notice'>We return our vocal glands to their original position.</span>")
return FALSE
var/mimic_voice = stripped_input(user, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN)
var/mimic_voice = tgui_input_text(user, "Enter a name to mimic.", "Mimic Voice", max_length = MAX_NAME_LEN)
if(!mimic_voice)
return FALSE
@@ -111,7 +111,7 @@
return T
/obj/effect/proc_holder/spell/vampire/thrall_commune/cast(list/targets, mob/user)
var/input = stripped_input(user, "Enter a message to relay to the other thralls", "Thrall Commune", "")
var/input = tgui_input_text(user, "Enter a message to relay to the other thralls", "Thrall Commune")
if(!input)
revert_cast(user)
return
+2 -2
View File
@@ -189,8 +189,8 @@ th.cost.toomuch {background:maroon;}
if(href_list["buy"])
var/itemID = text2num(href_list["buy"])
var/datum/prize_item/item = GLOB.global_prizes.prizes[itemID]
var/sure = alert(usr,"Are you sure you wish to purchase [item.name] for [item.cost] tickets?","You sure?","Yes","No") in list("Yes","No")
if(sure=="No")
var/sure = tgui_alert(usr,"Are you sure you wish to purchase [item.name] for [item.cost] tickets?", "You sure?", list("Yes","No"))
if(sure == "No")
updateUsrDialog()
return
if(!GLOB.global_prizes.PlaceOrder(src, itemID))
+2 -2
View File
@@ -165,8 +165,8 @@
if(!a_left || !a_right)
to_chat(user, "<span class='warning'>Assembly part missing!</span>")
return
if(istype(a_left, a_right.type))//If they are the same type it causes issues due to window code
switch(alert("Which side would you like to use?",,"Left","Right"))
if(istype(a_left, a_right.type)) // If they are the same type it causes issues due to window code
switch(tgui_alert(user, "Which side would you like to use?", "Choose", list("Left", "Right")))
if("Left")
a_left.attack_self(user)
if("Right")
@@ -864,14 +864,9 @@
"direction")
var/val = isnum(params["val"]) ? params["val"] : text2num(params["val"])
if(isnull(val))
var/newval = input("Enter new value") as num|null
var/newval = tgui_input_number(usr, "Enter new value", "New Value", ONE_ATMOSPHERE, 1000 + ONE_ATMOSPHERE, 0, round_value = FALSE)
if(isnull(newval))
return
if(params["cmd"] == "set_external_pressure")
if(newval > 1000 + ONE_ATMOSPHERE)
newval = 1000 + ONE_ATMOSPHERE
if(newval < 0)
newval = 0
val = newval
// Figure out what it is
@@ -939,7 +934,7 @@
return
var/datum/tlv/tlv = TLV[env]
var/newval = input("Enter [varname] for [env]", "Alarm triggers", tlv.vars[varname]) as num|null
var/newval = tgui_input_number(usr, "Enter [varname] for [env]", "Alarm triggers", tlv.vars[varname], round_value = FALSE)
if(isnull(newval) || ..()) // No setting if you walked away
return
@@ -987,7 +982,7 @@
var/min_temperature = max(selected.min1, MIN_TEMPERATURE)
var/max_temperature_c = max_temperature - T0C
var/min_temperature_c = min_temperature - T0C
var/input_temperature = input("What temperature would you like the system to maintain? (Capped between [min_temperature_c]C and [max_temperature_c]C)", "Thermostat Controls") as num|null
var/input_temperature = tgui_input_number(usr, "What temperature would you like the system to maintain? (Capped between [min_temperature_c]C and [max_temperature_c]C)", "Thermostat Controls", target_temperature - T0C, max_temperature_c, min_temperature_c)
if(isnull(input_temperature) || ..()) // No temp setting if you walked away
return
input_temperature = input_temperature + T0C
@@ -345,7 +345,7 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
switch(action)
if("relabel")
if(can_label)
var/T = sanitize(copytext(input("Choose canister label", "Name", name) as text|null, 1, MAX_NAME_LEN))
var/T = tgui_input_text(usr, "Choose canister label", "Name", name, max_length = MAX_NAME_LEN)
if(can_label) //Exploit prevention
if(T)
name = T
@@ -156,7 +156,7 @@
else
has_owner = FALSE
owner = null
var/transfer_choice = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No")
var/transfer_choice = tgui_alert(user, "Transfer your soul to [src]? (Warning, your old body will die!)", "Respawn", list("Yes","No"))
if(transfer_choice != "Yes")
return
if(QDELETED(src) || uses <= 0)
@@ -171,7 +171,7 @@
if(!istype(I, /obj/item/slimepotion/transference))
return ..()
if(iscarbon(user) && can_transfer)
var/human_transfer_choice = alert("Transfer your soul to [src]? (Warning, your old body will die!)", null, "Yes", "No")
var/human_transfer_choice = tgui_alert(user, "Transfer your soul to [src]? (Warning, your old body will die!)", "Respawn", list("Yes", "No"))
if(human_transfer_choice != "Yes")
return
if(QDELETED(src) || uses <= 0 || user.stat >= 1 || QDELETED(I))
+2 -2
View File
@@ -43,7 +43,7 @@
/obj/effect/mob_spawn/attack_ghost(mob/user)
if(!valid_to_spawn(user))
return
var/ghost_role = alert("Become [mob_name]? (Warning, You can no longer be cloned!)",,"Yes","No")
var/ghost_role = tgui_alert(user, "Become [mob_name]? (Warning, You can no longer be cloned!)", "Respawn", list("Yes","No"))
if(ghost_role == "No")
return
if(!species_prompt(user))
@@ -331,7 +331,7 @@
assignedrole = "Space Bar Patron"
/obj/effect/mob_spawn/human/alive/space_bar_patron/attack_hand(mob/user)
var/despawn = alert("Return to cryosleep? (Warning, Your mob will be deleted!)",,"Yes","No")
var/despawn = tgui_alert(user, "Return to cryosleep? (Warning, Your mob will be deleted!)", "Leave Bar", list("Yes", "No"))
if(despawn == "No" || !loc || !Adjacent(user))
return
user.visible_message("<span class='notice'>[user.name] climbs back into cryosleep...</span>")
+2 -2
View File
@@ -65,7 +65,7 @@
// If we are here, they just want to change the mode
var/option = alert(usr, "Would you like to change 2FA mode or disable it entirely?", "2FA Mode", "Enable (Always)", "Enable (On IP Change)", "Deactivate")
var/option = tgui_alert(usr, "Would you like to change 2FA mode or disable it entirely?", "2FA Mode", list("Enable (Always)", "Enable (On IP Change)", "Deactivate"))
switch(option)
if("Enable (Always)")
prefs._2fa_status = _2FA_ENABLED_ALWAYS
@@ -76,7 +76,7 @@
prefs.save_preferences(src)
prefs.ShowChoices(usr)
if("Deactivate")
var/confirm = alert(usr, "Are you SURE you want to deactivate 2FA?", "WARNING", "Yes", "No")
var/confirm = tgui_alert(usr, "Are you SURE you want to deactivate 2FA?", "WARNING", list("Yes", "No"))
if(confirm != "Yes")
return
+1 -1
View File
@@ -138,7 +138,7 @@
return // prevents a recursive loop where the ..() 5 lines after this makes the proc endlessly re-call itself
if(href_list["withdraw_consent"])
var/choice = alert(usr, "Are you SURE you want to withdraw your consent to the Terms of Service?\nYou will be instantaneously removed from the server and will have to re-accept the Terms of Service.", "Warning", "Yes", "No")
var/choice = tgui_alert(usr, "Are you SURE you want to withdraw your consent to the Terms of Service?\nYou will be instantaneously removed from the server and will have to re-accept the Terms of Service.", "Warning", list("Yes", "No"))
if(choice == "Yes")
// Update the DB
var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO privacy (ckey, datetime, consent) VALUES (:ckey, Now(), 0)", list(
@@ -13,7 +13,7 @@
active_character.SetChoices(user)
if("learnaboutselection")
if(GLOB.configuration.url.wiki_url)
if(alert("Would you like to open the Job selection info in your browser?", "Open Job Selection", "Yes", "No") == "Yes")
if(tgui_alert(user, "Would you like to open the Job selection info in your browser?", "Open Job Selection", list("Yes", "No")) == "Yes")
user << link("[GLOB.configuration.url.wiki_url]/index.php/Job_Selection_and_Assignment")
else
to_chat(user, "<span class='danger'>The Wiki URL is not set in the server configuration.</span>")
@@ -65,7 +65,7 @@
user << browse(null, "window=records")
if(href_list["task"] == "med_record")
var/medmsg = input(usr,"Set your medical notes here.","Medical Records",html_decode(active_character.med_record)) as message
var/medmsg = tgui_input_text(usr, "Set your medical notes here.", "Medical Records", active_character.med_record, multiline = TRUE, encode = FALSE)
if(medmsg != null)
medmsg = copytext(medmsg, 1, MAX_PAPER_MESSAGE_LEN)
@@ -75,7 +75,7 @@
active_character.SetRecords(user)
if(href_list["task"] == "sec_record")
var/secmsg = input(usr,"Set your security notes here.","Security Records",html_decode(active_character.sec_record)) as message
var/secmsg = tgui_input_text(usr, "Set your security notes here.", "Security Records", active_character.sec_record, multiline = TRUE, encode = FALSE)
if(secmsg != null)
secmsg = copytext(secmsg, 1, MAX_PAPER_MESSAGE_LEN)
@@ -85,7 +85,7 @@
active_character.SetRecords(user)
if(href_list["task"] == "gen_record")
var/genmsg = input(usr,"Set your employment notes here.","Employment Records",html_decode(active_character.gen_record)) as message
var/genmsg = tgui_input_text(usr, "Set your employment notes here.", "Employment Records", active_character.gen_record, multiline = TRUE, encode = FALSE)
if(genmsg != null)
genmsg = copytext(genmsg, 1, MAX_PAPER_MESSAGE_LEN)
@@ -212,9 +212,10 @@
to_chat(user, "<font color='red'>Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .</font>")
if("age")
var/new_age = input(user, "Choose your character's age:\n([S.min_age]-[S.max_age])", "Character Preference") as num|null
if(new_age)
active_character.age = max(min(round(text2num(new_age)), S.max_age), S.min_age)
var/new_age = tgui_input_number(user, "Choose your character's age:\n([S.min_age]-[S.max_age])", "Character Preference", active_character.age, S.max_age, S.min_age)
if(!new_age)
return
active_character.age = max(min(round(text2num(new_age)), S.max_age), S.min_age)
if("species")
var/list/new_species = list()
var/prev_species = active_character.species
@@ -326,9 +327,10 @@
active_character.autohiss_mode = autohiss_choice[new_autohiss_pref]
if("metadata")
var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , active_character.metadata) as message|null
if(new_metadata)
active_character.metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN))
var/new_metadata = tgui_input_text(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference", active_character.metadata, multiline = TRUE, encode = FALSE)
if(!new_metadata)
return
active_character.metadata = new_metadata
if("b_type")
var/new_b_type = tgui_input_list(user, "Choose your character's blood-type", "Character Preference", list( "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"))
@@ -388,11 +390,12 @@
if("h_grad_offset")
var/result = input(user, "Enter your character's hair gradient offset as a comma-separated value (x,y). Example:\n0,0 (no offset)\n5,0 (5 pixels to the right)", "Character Preference") as null|text
if(result)
var/list/expl = splittext(result, ",")
if(length(expl) == 2)
active_character.h_grad_offset_x = clamp(text2num(expl[1]) || 0, -16, 16)
active_character.h_grad_offset_y = clamp(text2num(expl[2]) || 0, -16, 16)
if(!result)
return
var/list/expl = splittext(result, ",")
if(length(expl) == 2)
active_character.h_grad_offset_x = clamp(text2num(expl[1]) || 0, -16, 16)
active_character.h_grad_offset_y = clamp(text2num(expl[2]) || 0, -16, 16)
if("h_grad_colour")
var/result = input(user, "Choose your character's hair gradient colour:", "Character Preference", active_character.h_grad_colour) as color|null
@@ -400,9 +403,10 @@
active_character.h_grad_colour = result
if("h_grad_alpha")
var/result = input(user, "Choose your character's hair gradient alpha (0-255):", "Character Preference", active_character.h_grad_alpha) as num|null
if(!isnull(result))
active_character.h_grad_alpha = clamp(result, 0, 255)
var/result = tgui_input_number(user, "Choose your character's hair gradient alpha (0-255):", "Character Preference", active_character.h_grad_alpha, 255)
if(isnull(result))
return
active_character.h_grad_alpha = clamp(result, 0, 255)
if("headaccessory")
if(S.bodyflags & HAS_HEAD_ACCESSORY) //Species with head accessories.
@@ -667,14 +671,16 @@
if("s_tone")
if(S.bodyflags & HAS_SKIN_TONE)
var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Character Preference") as num|null
if(new_s_tone)
active_character.s_tone = 35 - max(min(round(new_s_tone), 220), 1)
if(!new_s_tone)
return
active_character.s_tone = 35 - max(min(round(new_s_tone), 220), 1)
else if(S.bodyflags & HAS_ICON_SKIN_TONE)
var/const/MAX_LINE_ENTRIES = 4
var/prompt = "Choose your character's skin tone: 1-[length(S.icon_skin_tones)]\n(Light to Dark)"
var/skin_c = input(user, prompt, "Character Preference") as num|null
if(isnum(skin_c))
active_character.s_tone = max(min(round(skin_c), S.icon_skin_tones.len), 1)
var/skin_c = tgui_input_number(user, prompt, "Character Preference", active_character.s_tone, length(S.icon_skin_tones), 1)
if(!skin_c)
return
active_character.s_tone = skin_c
if("skin")
if((S.bodyflags & HAS_SKIN_COLOR) || GLOB.body_accessory_by_species[active_character.species] || check_rights(R_ADMIN, 0, user))
@@ -708,7 +714,7 @@
active_character.height = new_height
if("flavor_text")
var/msg = input(usr,"Set the flavor text in your 'examine' verb. The flavor text should be a physical descriptor of your character at a glance. SFW Drawn Art of your character is acceptable.","Flavor Text",html_decode(active_character.flavor_text)) as message
var/msg = tgui_input_text(usr, "Set the flavor text in your 'examine' verb. The flavor text should be a physical descriptor of your character at a glance. SFW Drawn Art of your character is acceptable.", "Flavor Text", active_character.flavor_text, multiline = TRUE, encode = FALSE)
if(msg != null)
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
@@ -875,7 +881,7 @@
version_message = "\nYou need to be using byond version 511 or later to take advantage of this feature, your version of [user.client.byond_version] is too low"
if(world.byond_version < 511)
version_message += "\nThis server does not currently support client side fps. You can set now for when it does."
var/desiredfps = input(user, "Choose your desired fps.[version_message]\n(0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num
var/desiredfps = tgui_input_number(user, "Choose your desired fps.[version_message]\n(Min = synced with server tick rate)", "Character Preference", clientfps, 120, world.fps)
if(!isnull(desiredfps))
clientfps = desiredfps
if(world.byond_version >= 511 && user.client && user.client.byond_version >= 511)
@@ -943,8 +949,14 @@
if("tgui")
toggles2 ^= PREFTOGGLE_2_FANCYUI
if("input_lists")
toggles2 ^= PREFTOGGLE_2_DISABLE_TGUI_LISTS
if("tgui_input")
toggles2 ^= PREFTOGGLE_2_DISABLE_TGUI_INPUT
if("tgui_input_large")
toggles2 ^= PREFTOGGLE_2_LARGE_INPUT_BUTTONS
if("tgui_input_swap")
toggles2 ^= PREFTOGGLE_2_SWAP_INPUT_BUTTONS
if("tgui_say_light_mode")
toggles2 ^= PREFTOGGLE_2_ENABLE_TGUI_SAY_LIGHT_MODE
@@ -1000,8 +1012,8 @@
H.remake_hud()
if("UIalpha")
var/UI_style_alpha_new = input(user, "Select a new alpha(transparence) parameter for UI, between 50 and 255", UI_style_alpha) as num
if(!UI_style_alpha_new || !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50))
var/UI_style_alpha_new = tgui_input_number(user, "Select a new alpha(transparence) parameter for UI, between 50 and 255", "UI Alpha", UI_style_alpha, 255, 50)
if(!UI_style_alpha_new)
return
UI_style_alpha = UI_style_alpha_new
@@ -1115,9 +1127,10 @@
parent.mob?.hud_used?.update_parallax_pref()
if("screentip_mode")
var/desired_screentip_mode = clamp(input(user, "Pick a screentip size, pick 0 to disable screentips. (We suggest a number between 8 and 15):", "Screentip Size") as null|num, 0, 20)
if(!isnull(desired_screentip_mode))
screentip_mode = desired_screentip_mode
var/desired_screentip_mode = tgui_input_number(user, "Pick a screentip size, pick 0 to disable screentips. (We suggest a number between 8 and 15):", "Screentip Size", screentip_mode, 20, 0)
if(!desired_screentip_mode)
return
screentip_mode = desired_screentip_mode
if("screentip_color")
var/screentip_color_new = input(user, "Choose your screentip color", screentip_color) as color|null
@@ -1235,7 +1248,7 @@
keybindings_overrides -= KB.name
else if(href_list["all"])
var/yes = alert(user, "Really [href_list["all"]] all key bindings?", "Confirm", "Yes", "No") == "Yes"
var/yes = tgui_alert(user, "Really [href_list["all"]] all key bindings?", "Confirm", list("Yes", "No")) == "Yes"
if(yes)
switch(href_list["all"])
if("reset")
@@ -1249,7 +1262,7 @@
var/datum/keybinding/custom/custom_emote_keybind = locateUID(href_list["custom_emote_set"])
if(custom_emote_keybind)
var/emote_text = active_character.custom_emotes[custom_emote_keybind.name]
var/desired_emote = stripped_input(user, "Enter your custom emote text, 128 character limit.", "Custom Emote Setter", emote_text, max_length = 128)
var/desired_emote = tgui_input_text(user, "Enter your custom emote text, 128 character limit.", "Custom Emote Setter", emote_text, max_length = 128)
if(desired_emote && (desired_emote != custom_emote_keybind.default_emote_text)) //don't let them save the default custom emote text
active_character.custom_emotes[custom_emote_keybind.name] = desired_emote
active_character.save(user)
@@ -446,7 +446,9 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
dat += " - <b>UI Style:</b> <a href='?_src_=prefs;preference=ui'><b>[UI_style]</b></a><br>"
dat += "<b>TGUI settings:</b><br>"
dat += "<b> - Fancy TGUI:</b> <a href='?_src_=prefs;preference=tgui'>[(toggles2 & PREFTOGGLE_2_FANCYUI) ? "Yes" : "No"]</a><br>"
dat += "<b> - Input Lists:</b> <a href='?_src_=prefs;preference=input_lists'>[(toggles2 & PREFTOGGLE_2_DISABLE_TGUI_LISTS) ? "Default" : "TGUI"]</a><br>"
dat += "<b> - TGUI Input:</b> <a href='?_src_=prefs;preference=tgui_input'>[(toggles2 & PREFTOGGLE_2_DISABLE_TGUI_INPUT) ? "No" : "Yes"]</a><br>"
dat += "<b> - TGUI Input - Large Buttons:</b> <a href='?_src_=prefs;preference=tgui_input_large'>[(toggles2 & PREFTOGGLE_2_LARGE_INPUT_BUTTONS) ? "Yes" : "No"]</a><br>"
dat += "<b> - TGUI Input - Swap Buttons:</b> <a href='?_src_=prefs;preference=tgui_input_swap'>[(toggles2 & PREFTOGGLE_2_SWAP_INPUT_BUTTONS) ? "Yes" : "No"]</a><br>"
dat += "<b> - TGUI Say Theme:</b> <a href='?_src_=prefs;preference=tgui_say_light_mode'>[(toggles2 & PREFTOGGLE_2_ENABLE_TGUI_SAY_LIGHT_MODE) ? "Light" : "Dark"]</a><br>"
dat += "</td></tr></table>"
@@ -227,12 +227,12 @@
SSblackbox.record_feedback("tally", "toggle_verbs", 1, "Toggle Instruments") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_input()
set name = "Toggle TGUI Input Lists"
set name = "Toggle TGUI Input"
set category = "Preferences"
set desc = "Switches input lists between the TGUI and the standard one"
prefs.toggles2 ^= PREFTOGGLE_2_DISABLE_TGUI_LISTS
set desc = "Switches inputs between the TGUI and the standard one"
prefs.toggles2 ^= PREFTOGGLE_2_DISABLE_TGUI_INPUT
prefs.save_preferences(src)
to_chat(src, "You will [(prefs.toggles2 & PREFTOGGLE_2_DISABLE_TGUI_LISTS) ? "no longer" : "now"] use TGUI Input Lists.")
to_chat(src, "You will [(prefs.toggles2 & PREFTOGGLE_2_DISABLE_TGUI_INPUT) ? "no longer" : "now"] use TGUI Inputs.")
/client/verb/Toggle_disco() //to toggle off the disco machine locally, in case it gets too annoying
set name = "Hear/Silence Dance Machine"
@@ -68,7 +68,7 @@
/obj/item/clothing/gloves/color/black/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/wirecutters))
if(can_be_cut && icon_state == initial(icon_state))//only if not dyed
var/confirm = alert("Do you want to cut off the gloves fingertips? Warning: It might destroy their functionality.","Cut tips?","Yes","No")
var/confirm = tgui_alert(user, "Do you want to cut off the gloves fingertips? Warning: It might destroy their functionality.", "Cut tips?", list("Yes","No"))
if(get_dist(user, src) > 1)
to_chat(user, "You have moved too far away.")
return
+1 -1
View File
@@ -17,7 +17,7 @@
actions_types = list(/datum/action/item_action/print_forensic_report, /datum/action/item_action/clear_records)
/obj/item/detective_scanner/attack_self(mob/user)
var/search = input(user, "Enter name, fingerprint or blood DNA.", "Find record", "")
var/search = tgui_input_text(user, "Enter name, fingerprint or blood DNA.", "Find record")
if(!search || user.stat || user.incapacitated())
return
@@ -93,14 +93,12 @@
switch(action)
if("change_code")
var/attempt_code = input("Re-enter the current EFTPOS access code", "Confirm old EFTPOS code") as num
var/attempt_code = tgui_input_number(user, "Re-enter the current EFTPOS access code:", "Confirm old EFTPOS code", max_value = 9999, min_value = 1000)
if(attempt_code == access_code)
var/trycode = input("Enter a new access code for this device (4 digits, numbers only)", "Enter new EFTPOS code") as num
if(trycode < 1000 || trycode > 9999)
alert("That is not a valid code!")
var/trycode = tgui_input_number(user, "Enter a new access code for this device:", "Enter new EFTPOS code", max_value = 9999, min_value = 1000)
if(!trycode)
return
access_code = trycode
print_reference()
else
to_chat(user, "[bicon(src)]<span class='warning'>Incorrect code entered.</span>")
@@ -108,9 +106,11 @@
if(!account_database)
reconnect_database()
if(account_database)
var/attempt_account_num = input("Enter account number to pay EFTPOS charges into", "New account number") as num
var/attempt_pin = input("Enter pin code", "Account pin") as num
if(!check_user_position(user) || !account_database)
var/attempt_account_num = tgui_input_number(user, "Enter account number to pay EFTPOS charges into:", "New account number", max_value = 9999999, min_value = 1000000)
if(!attempt_account_num)
return
var/attempt_pin = tgui_input_number(user, "Enter pin code", "Account pin", max_value = 99999, min_value = 10000)
if(!check_user_position(user) || !account_database || !attempt_pin)
return
var/datum/money_account/target_account = GLOB.station_money_database.find_user_account(attempt_account_num, include_departments = TRUE)
if(!target_account)
@@ -122,6 +122,7 @@
linked_account = target_account
else
to_chat(user, "[bicon(src)]<span class='warning'>Unable to connect to inputed account.</span>")
return
else
to_chat(user, "[bicon(src)]<span class='warning'>Unable to connect to accounts database.</span>")
return
@@ -133,25 +134,18 @@
linked_account = target_account
to_chat(user, "[bicon(src)]<span class='warning'>Linked account successfully set to [target_account.account_name]</span>")
if("trans_purpose")
var/purpose = clean_input("Enter reason for EFTPOS transaction", "Transaction purpose", transaction_purpose)
if(!check_user_position(user))
var/purpose = tgui_input_text(user, "Enter reason for EFTPOS transaction", "Transaction purpose", transaction_purpose, encode = FALSE)
if(!check_user_position(user) || !purpose)
return
if(purpose)
transaction_purpose = purpose
transaction_purpose = purpose
if("trans_value")
var/try_num = input("Enter amount for EFTPOS transaction", "Transaction amount", transaction_amount) as num
if(!check_user_position(user))
return
if(try_num < 0)
alert("That is not a valid amount!")
return
if(try_num > MAX_EFTPOS_CHARGE)
alert("You cannot charge more than [MAX_EFTPOS_CHARGE] per transaction!")
var/try_num = tgui_input_number(user, "Enter amount for EFTPOS transaction", "Transaction amount", transaction_amount, MAX_EFTPOS_CHARGE)
if(!check_user_position(user) || !try_num)
return
transaction_amount = try_num
if("toggle_lock")
if(transaction_locked)
var/attempt_code = input("Enter EFTPOS access code", "Reset Transaction") as num
var/attempt_code = tgui_input_number(user, "Enter EFTPOS access code", "Reset Transaction", max_value = 9999, min_value = 1000)
if(!check_user_position(user))
return
if(attempt_code == access_code)
@@ -191,14 +185,14 @@
//if security level high enough, prompt for pin
var/attempt_pin
if(D.security_level != ACCOUNT_SECURITY_ID)
attempt_pin = input("Enter pin code", "EFTPOS transaction") as num
attempt_pin = tgui_input_number(user, "Enter pin code", "EFTPOS transaction", max_value = 9999, min_value = 1000)
if(!attempt_pin || !Adjacent(user))
return
//given the credentials, can the associated account be accessed right now?
if(!GLOB.station_money_database.try_authenticate_login(D, attempt_pin, restricted_bypass = FALSE))
to_chat(user, "[bicon(src)]<span class='warning'>Unable to access account, insufficient access.</span>")
return
if(alert("Are you sure you want to pay $[transaction_amount] to: [linked_account.account_name] ", "Confirm transaction", "Yes", "No") != "Yes")
if(tgui_alert(user, "Are you sure you want to pay $[transaction_amount] to: [linked_account.account_name]", "Confirm transaction", list("Yes", "No")) != "Yes")
return
if(!Adjacent(user))
return
+1 -1
View File
@@ -231,7 +231,7 @@
flick("blobbernaut_death", src)
/mob/living/simple_animal/hostile/blob/blobbernaut/proc/blob_talk()
var/message = input(src, "Announce to the overmind", "Blob Telepathy")
var/message = tgui_input_text(usr, "Announce to the overmind", "Blob Telepathy")
var/rendered
var/follow_text
if(message)
@@ -372,7 +372,9 @@
if(is_pen(I))
if(open)
return
var/t = clean_input("Enter what you want to set the tag to:", "Write", null)
var/t = tgui_input_text(usr, "Enter what you want to set the tag to:", "Write")
if(!t)
return
var/obj/item/pizzabox/boxtotagto = src
if(boxes.len > 0)
boxtotagto = boxes[boxes.len]
@@ -458,14 +460,16 @@
desc = "It seems inactive."
icon_state = "pizzabox_bomb"
timer_set = TRUE
timer = (input(user, "Set a timer, from one second to ten seconds.", "Timer", "[timer]") as num) SECONDS
var/new_timer = tgui_input_number(user, "Set a timer, from one second to ten seconds.", "Timer", timer / 10, 10, 1)
if(!new_timer)
return
if(!in_range(src, user) || issilicon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || user.restrained())
timer_set = FALSE
name = "pizza box"
desc = "A box suited for pizzas."
icon_state = "pizzabox1"
return
timer = clamp(timer, 1 SECONDS, 10 SECONDS)
timer = new_timer SECONDS
icon_state = "pizzabox1"
to_chat(user, "<span class='notice'>You set the timer to [timer / 10] before activating the payload and closing [src].")
message_admins("[key_name_admin(usr)] has set a timer on a pizza bomb to [timer/10] seconds at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[loc.x];Y=[loc.y];Z=[loc.z]'>(JMP)</a>.")
+4 -5
View File
@@ -66,7 +66,7 @@
return
if(length(H.cards) > 1)
var/confirm = alert("Are you sure you want to put your [length(H.cards)] cards back into the deck?", "Return Hand", "Yes", "No")
var/confirm = tgui_alert(user, "Are you sure you want to put your [length(H.cards)] cards back into the deck?", "Return Hand", list("Yes", "No"))
if(confirm == "No" || !Adjacent(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
for(var/datum/playingcard/P in H.cards)
@@ -191,9 +191,8 @@
for(var/mob/living/player in viewers(3))
if(!player.incapacitated())
players += player
var/maxcards = clamp(length(cards), 1, 10)
var/dcard = input("How many card(s) do you wish to deal? You may deal up to [maxcards] cards.") as num
if(dcard > maxcards)
var/dcard = tgui_input_number(usr, "How many card(s) do you wish to deal? You may deal up to [length(cards)] cards.", "Deal Cards", max_value = length(cards))
if(!dcard)
return
var/mob/living/M = tgui_input_list(usr, "Who do you wish to deal [dcard] card(s)?", "Deal Card", players)
if(!usr || !src || !M || !Adjacent(usr))
@@ -453,7 +452,7 @@
var/mob/living/carbon/user = usr
var/maxcards = min(length(cards), 5)
var/discards = input("How many cards do you want to discard? You may discard up to [maxcards] card(s)") as num
var/discards = tgui_input_number(usr, "How many cards do you want to discard? You may discard up to [maxcards] card(s)", "Discard Cards", max_value = maxcards)
if(discards > maxcards)
return
for(var/i in 1 to discards)
+1 -1
View File
@@ -327,7 +327,7 @@
/obj/item/seeds/proc/variant_prompt(mob/user, obj/item/container = null)
var/prev = variant
var/V = input(user, "Choose variant name:", "Plant Variant Naming", variant) as text|null
var/V = tgui_input_text(user, "Choose variant name:", "Plant Variant Naming", variant, encode = FALSE)
if(isnull(V)) // Did the user cancel?
return
if(container && (loc != container)) // Was the seed removed from the container, if there is a container?
+5 -14
View File
@@ -63,16 +63,9 @@
name = ""
if("import")
var/t = ""
do
t = html_encode(input(usr, "Please paste the entire song, formatted:", "[name]", t) as message)
if(!in_range(parent, usr))
return
if(length_char(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
if(cont == "no")
break
while(length_char(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
t = tgui_input_text(usr, "Please paste the entire song, formatted:", parent.name, max_length = (MUSIC_MAXLINECHARS * MUSIC_MAXLINES), multiline = TRUE)
if(!in_range(parent, usr))
return
parse_song(t)
return FALSE
if("help")
@@ -88,11 +81,9 @@
if("play")
INVOKE_ASYNC(src, PROC_REF(start_playing), usr)
if("newline")
var/newline = html_encode(input("Enter your line: ", parent.name) as text|null)
var/newline = tgui_input_text(usr, "Enter your line:", parent.name, max_length = MUSIC_MAXLINECHARS)
if(!newline || !in_range(parent, usr))
return
if(length(lines) > MUSIC_MAXLINES)
return
if(length(newline) > MUSIC_MAXLINECHARS)
newline = copytext(newline, 1, MUSIC_MAXLINECHARS)
lines.Add(newline)
@@ -103,7 +94,7 @@
lines.Cut(num, num + 1)
if("modifyline")
var/num = round(text2num(params["line"]))
var/content = stripped_input(usr, "Enter your line: ", parent.name, lines[num], MUSIC_MAXLINECHARS)
var/content = tgui_input_text(usr, "Enter your line:", parent.name, lines[num], max_length = MUSIC_MAXLINECHARS)
if(!content || !in_range(parent, usr))
return
if(num > length(lines) || num < 1)
+5 -5
View File
@@ -213,7 +213,7 @@
var/choice = tgui_input_list(user, "What would you like to edit?", "Book Edit", list("Title", "Edit Current Page", "Author", "Summary", "Add Page", "Remove Page"))
switch(choice)
if("Title")
var/newtitle = reject_bad_text(stripped_input(user, "Write a new title:"))
var/newtitle = reject_bad_text(tgui_input_text(user, "Write a new title:", "Title", title))
if(!newtitle)
to_chat(user, "<span class='notice'>You change your mind.</span>")
return
@@ -222,13 +222,13 @@
name = "Book: " + newtitle
title = newtitle
if("Author")
var/newauthor = stripped_input(user, "Write the author's name:")
var/newauthor = tgui_input_text(user, "Write the author's name:", "Author", author, MAX_NAME_LEN)
if(!newauthor)
to_chat(user, "<span class='notice'>You change your mind.</span>")
return
author = newauthor
if("Summary")
var/newsummary = strip_html(input(user, "Write the new summary:") as message|null, MAX_SUMMARY_LEN)
var/newsummary = tgui_input_text(user, "Write the new summary:", "Summary", summary, MAX_SUMMARY_LEN, multiline = TRUE)
if(!newsummary)
to_chat(user, "<span class='notice'>You change your mind.</span>")
return
@@ -244,7 +244,7 @@
if(character_space_remaining <= 0)
to_chat(user, "<span class='notice'>There's not enough space left on this page to write anything!</span>")
return
var/content = strip_html(input(user, "Add Text to this page, you have [character_space_remaining] characters of space left:") as message|null, MAX_CHARACTERS_PER_BOOKPAGE)
var/content = tgui_input_text(user, "Add Text to this page, you have [character_space_remaining] characters of space left:", "Edit Current Page", max_length = MAX_CHARACTERS_PER_BOOKPAGE, multiline = TRUE)
if(!content)
to_chat(user, "<span class='notice'>You change your mind.</span>")
return
@@ -267,7 +267,7 @@
if(!length(pages))
to_chat(user, "<span class='notice'>There aren't any pages in this book!</span>")
return
var/page_choice = input(user, "There are [length(pages)] pages, which page number would you like to remove?", "Input Page Number", null) as num|null
var/page_choice = tgui_input_number(user, "There are [length(pages)] pages, which page number would you like to remove?", "Input Page Number", max_value = length(pages))
if(!page_choice)
to_chat(user, "<span class='notice'>You change your mind.</span>")
return
+2 -2
View File
@@ -111,7 +111,7 @@
if("specify_ssid_delete")
if(!answer || !text2num(answer))
return
var/confirm = alert("You are about to delete book [text2num(answer)]", "Confirm Deletion", "Yes", "No")
var/confirm = tgui_alert(usr, "You are about to delete book [text2num(answer)]", "Confirm Deletion", list("Yes", "No"))
if(confirm != "Yes")
return //we don't need to sanitize b/c removeBookyByID uses id=:id instead of like statemetns
if(GLOB.library_catalog.remove_book_by_id(text2num(answer)))
@@ -140,7 +140,7 @@
return
var/sanitized_answer = paranoid_sanitize(answer) //the last thing we want happening is someone deleting every book with "%%"
var/confirm //We want to be absolutely certain an admin wants to do this
confirm = alert("You are about to mass delete potentially up to 10 books", "Confirm Deletion", "Yes", "No")
confirm = tgui_alert(usr, "You are about to mass delete potentially up to 10 books", "Confirm Deletion", list("Yes", "No"))
if(confirm != "Yes")
return
if(GLOB.library_catalog.remove_books_by_ckey(sanitized_answer))
+2 -2
View File
@@ -411,9 +411,9 @@
if(BARCODE_MODE_CHECKOUT)
var/confirm
if(!computer.user_data.patron_account)
confirm = alert("Warning: patron does not have an associated account number! Are you sure you want to checkout [B] to [computer.user_data.patron_name]?", "Confirm Checkout", "Yes", "No")
confirm = tgui_alert(user, "Warning: patron does not have an associated account number! Are you sure you want to checkout [B] to [computer.user_data.patron_name]?", "Confirm Checkout", list("Yes", "No"))
else
confirm = alert("Are you sure you want to checkout [B] to [computer.user_data.patron_name]?", "Confirm Checkout", "Yes", "No")
confirm = tgui_alert(user, "Are you sure you want to checkout [B] to [computer.user_data.patron_name]?", "Confirm Checkout", list("Yes", "No"))
if(confirm == "No")
return
@@ -224,7 +224,7 @@
if(!user.check_ahud_rejoin_eligibility())
to_chat(user, "<span class='warning'>Upon using the antagHUD you forfeited the ability to join the round.</span>")
return
var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No")
var/be_helper = tgui_alert(user, "Become a Lightgeist? (Warning, You can no longer be cloned!)", "Respawn", list("Yes","No"))
if(be_helper == "No")
return
if(!loc || QDELETED(src) || QDELETED(user))
@@ -229,7 +229,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(warningmsg)
var/response
var/alertmsg = "Are you -sure- you want to ghost?\n([warningmsg]. If you ghost now, you probably won't be able to rejoin the round! You can't change your mind, so choose wisely!)"
response = alert(src, alertmsg,"Are you sure you want to ghost?","Stay in body","Ghost")
response = tgui_alert(src, alertmsg, "Ghost", list("Stay in body", "Ghost"))
if(response != "Ghost")
return
@@ -398,7 +398,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "<span class='warning'>Your body is still alive!</span>")
return
var/choice = alert(src, "If you enable this, your body will be unrevivable for the remainder of the round.", "Are you sure?", "Yes", "No")
var/choice = tgui_alert(src, "If you enable this, your body will be unrevivable for the remainder of the round.", "Do Not Revive!", list("Yes", "No"))
if(choice == "Yes")
to_chat(src, "<span class='boldnotice'>Do Not Revive state enabled.</span>")
create_log(MISC_LOG, "DNR Enabled")
@@ -764,7 +764,7 @@
if(href_list["secrecordadd"])
if(usr.incapacitated() || !hasHUD(usr, EXAMINE_HUD_SECURITY_WRITE))
return
var/raw_input = input("Add Comment:", "Security records", null, null) as message
var/raw_input = tgui_input_text(usr, "Add Comment:", "Security records", multiline = TRUE, encode = FALSE)
var/sanitized = copytext(trim(sanitize(raw_input)), 1, MAX_MESSAGE_LEN)
if(!sanitized || usr.stat || usr.restrained() || !hasHUD(usr, EXAMINE_HUD_SECURITY_WRITE))
return
@@ -865,7 +865,7 @@
if(href_list["medrecordadd"])
if(usr.incapacitated() || !hasHUD(usr, EXAMINE_HUD_MEDICAL_WRITE))
return
var/raw_input = input("Add Comment:", "Medical records", null, null) as message
var/raw_input = tgui_input_text(usr, "Add Comment:", "Medical records", multiline = TRUE, encode = FALSE)
var/sanitized = copytext(trim(sanitize(raw_input)), 1, MAX_MESSAGE_LEN)
if(!sanitized || usr.stat || usr.restrained() || !hasHUD(usr, EXAMINE_HUD_MEDICAL_WRITE))
return
@@ -1505,7 +1505,7 @@
var/max_length = bloody_hands * 30 //tweeter style
var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "")
var/message = tgui_input_text(src, "Write a message. It cannot be longer than [max_length] characters.", "Blood writing", max_length = max_length)
if(origin != loc)
to_chat(src, "<span class='notice'>Stay still while writing!</span>")
return
@@ -2145,7 +2145,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
if(stat)
return
pose = sanitize(copytext(input(usr, "This is [src]. [p_they(TRUE)]...", "Pose", null) as text, 1, MAX_MESSAGE_LEN))
pose = tgui_input_text(usr, "This is [src]. [p_they(TRUE)]...", "Pose")
/mob/living/carbon/human/verb/set_flavor()
set name = "Set Flavour Text"
+1 -1
View File
@@ -295,7 +295,7 @@
to_chat(src, "<span class='warning'>You are unable to succumb to death! This life continues!</span>")
return
var/last_words = input(src, "Do you have any last words?", "Goodnight, Sweet Prince") as text|null
var/last_words = tgui_input_text(src, "Do you have any last words?", "Goodnight, Sweet Prince", encode = FALSE)
if(stat == DEAD)
// cancel em out if they died while they had the message box up
+2 -2
View File
@@ -416,9 +416,9 @@
to_chat(user, "<span class='boldwarning'>You cannot send IC messages (muted).</span>")
return FALSE
else if(!params)
custom_emote = copytext(sanitize(input("Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN)
custom_emote = tgui_input_text(user, "Choose an emote to display.", "Custom Emote")
if(custom_emote && !check_invalid(user, custom_emote))
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
var/type = tgui_alert(user, "Is this a visible or hearable emote?", "Custom Emote", list("Visible", "Hearable"))
switch(type)
if("Visible")
custom_emote_type = EMOTE_VISIBLE
+10 -11
View File
@@ -571,7 +571,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
to_chat(src, "<span class='warning'>Please allow one minute to pass between announcements.</span>")
return
var/input = input(usr, "Please write a message to announce to the station crew.", "A.I. Announcement") as message|null
var/input = tgui_input_text(usr, "Please write a message to announce to the station crew.", "A.I. Announcement", multiline = TRUE, encode = FALSE)
if(!input)
return
@@ -588,7 +588,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(check_unable(AI_CHECK_WIRELESS))
return
var/input = input("Please enter the reason for calling the shuttle.", "Shuttle Call Reason.") as null|message
var/input = tgui_input_text(src, "Please enter the reason for calling the shuttle.", "Shuttle Call Reason", multiline = TRUE, encode = FALSE)
if(!input || stat)
return
@@ -606,7 +606,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(check_unable(AI_CHECK_WIRELESS))
return
var/confirm = alert("Are you sure you want to recall the shuttle?", "Confirm Shuttle Recall", "Yes", "No")
var/confirm = tgui_alert(src, "Are you sure you want to recall the shuttle?", "Confirm Shuttle Recall", list("Yes", "No"))
if(check_unable(AI_CHECK_WIRELESS))
return
@@ -1007,7 +1007,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
custom_hologram = TRUE
var/input
switch(alert("Would you like to select a hologram based on a crew member, an animal, or switch to a unique avatar?",,"Crew Member","Unique","Animal"))
switch(tgui_alert(usr, "Would you like to select a hologram based on a crew member, an animal, or switch to a unique avatar?", "Change Hologram", list("Crew Member", "Unique", "Animal")))
if("Crew Member")
var/personnel_list[] = list()
@@ -1234,13 +1234,12 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
set desc = "Change the message that's transmitted when a new crew member arrives on station."
set category = "AI Commands"
var/newmsg = clean_input("What would you like the arrival message to be? List of options: $name, $rank, $species, $gender, $age", "Change Arrival Message", arrivalmsg)
if(!newmsg)
var/newmsg = tgui_input_text(usr, "What would you like the arrival message to be? List of options: $name, $rank, $species, $gender, $age", "Change Arrival Message", arrivalmsg, encode = FALSE)
if(!newmsg || newmsg == arrivalmsg)
return
newmsg = html_decode(newmsg) // This feels a bit redundant, but sanitisation is (probably) important.
if(newmsg != arrivalmsg)
arrivalmsg = newmsg
to_chat(usr, "The arrival message has been successfully changed.")
arrivalmsg = newmsg
to_chat(usr, "The arrival message has been successfully changed.")
// Handled camera lighting, when toggled.
// It will get the nearest camera from the eyeobj, lighting it.
@@ -1444,7 +1443,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
A = D
if(istype(A))
switch(alert(src, "Do you want to open \the [A] for [target]?", "Doorknob_v2a.exe", "Yes", "No"))
switch(tgui_alert(src, "Do you want to open \the [A] for [target]?", "Doorknob_v2a.exe", list("Yes", "No")))
if("Yes")
if(!A.density)
to_chat(src, "<span class='notice'>[A] was already opened.</span>")
+1 -1
View File
@@ -109,7 +109,7 @@ GLOBAL_VAR_INIT(announcing_vox, 0) // Stores the time of the last announcement
to_chat(src, "<span class='warning'>Please wait [round((GLOB.announcing_vox - world.time) / 10)] seconds.</span>")
return
var/message = clean_input("WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", last_announcement, src)
var/message = tgui_input_text(src, "WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", last_announcement)
last_announcement = message
@@ -6,8 +6,7 @@ GLOBAL_LIST_EMPTY(empty_playable_ai_cores)
set desc = "Wipe your core. This is functionally equivalent to cryo or robotic storage, freeing up your job slot."
// Guard against misclicks, this isn't the sort of thing we want happening accidentally
if(alert("WARNING: This will immediately wipe your core and ghost you, removing your character from the round permanently (similar to cryo and robotic storage). Are you entirely sure you want to do this?",
"Wipe Core", "No", "No", "Yes") != "Yes")
if(tgui_alert(usr, "WARNING: This will immediately wipe your core and ghost you, removing your character from the round permanently (similar to cryo and robotic storage). Are you entirely sure you want to do this?", "Wipe Core", list("No", "Yes")) != "Yes")
return
cryo_AI()
+1 -1
View File
@@ -437,7 +437,7 @@
var/mob/living/carbon/human/H = over_object //changed to human to avoid stupid issues like xenos holding pAIs.
if(!istype(H) || !Adjacent(H)) return ..()
if(usr == src)
switch(alert(H, "[src] wants you to pick [p_them()] up. Do it?",,"Yes","No"))
switch(tgui_alert(H, "[src] wants you to pick [p_them()] up. Do it?", "Pick up", list("Yes", "No")))
if("Yes")
if(Adjacent(H))
get_scooped(H)
+23 -14
View File
@@ -69,23 +69,32 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
switch(option)
if("name")
t = input("Enter a name for your pAI", "pAI Name", candidate.pai_name) as text
if(t)
candidate.pai_name = sanitize(copytext(t,1,MAX_NAME_LEN))
t = tgui_input_text(usr, "Enter a name for your pAI", "pAI Name", candidate.pai_name, MAX_NAME_LEN)
if(!t)
return
candidate.pai_name = t
if("desc")
t = input("Enter a description for your pAI", "pAI Description", candidate.description) as message
if(t)
candidate.description = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
t = tgui_input_text(usr, "Enter a description for your pAI", "pAI Description", candidate.description, multiline = TRUE)
if(!t)
return
candidate.description = t
if("role")
t = input("Enter a role for your pAI", "pAI Role", candidate.role) as text
if(t)
candidate.role = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
t = tgui_input_text(usr, "Enter a role for your pAI", "pAI Role", candidate.role)
if(!t)
return
candidate.role = t
if("ooc")
t = input("Enter any OOC comments", "pAI OOC Comments", candidate.ooc_comments) as message
if(t)
candidate.ooc_comments = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
t = tgui_input_text(usr, "Enter any OOC comments", "pAI OOC Comments", candidate.ooc_comments, multiline = TRUE)
if(!t)
return
candidate.ooc_comments = t
if("save")
candidate.save_to_db(usr)
if("reload")
candidate.reload_save(usr)
//In case people have saved unsanitized stuff.
@@ -368,12 +377,12 @@ GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler fo
if(!C) return
asked.Add(C.key)
asked[C.key] = world.time
var/response = alert(C, "Someone is requesting a pAI personality. Would you like to play as a personal AI?", "pAI Request", "Yes", "No", "Never for this round")
var/response = tgui_alert(C, "Someone is requesting a pAI personality. Would you like to play as a personal AI?", "pAI Request", list("Yes", "No", "Never for this round"))
if(!C) return //handle logouts that happen whilst the alert is waiting for a response.
if(response == "Yes")
recruitWindow(C.mob)
else if(response == "Never for this round")
var/warning = alert(C, "Are you sure? This action will be undoable and you will need to wait until next round.", "You sure?", "Yes", "No")
var/warning = tgui_alert(C, "Are you sure? This action will be undoable and you will need to wait until next round.", "You sure?", list("Yes", "No"))
if(warning == "Yes")
asked[C.key] = INFINITY
else
@@ -136,7 +136,7 @@
return
// Check the carrier
var/answer = alert(M, "[pai_holder] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[pai_holder] Check DNA", "Yes", "No")
var/answer = tgui_alert(M, "[pai_holder] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[pai_holder] Check DNA", list("Yes", "No"))
if(answer == "Yes")
M.visible_message("<span class='notice'>[M] presses [M.p_their()] thumb against [pai_holder].</span>", "<span class='notice'>You press your thumb against [pai_holder].</span>")
var/datum/dna/dna = M.dna
@@ -152,7 +152,7 @@
to_chat(usr, "<span class='warning'>You must wait 10 minutes to respawn as a drone!</span>")
return
if(alert("Are you sure you want to respawn as a drone?", "Are you sure?", "Yes", "No") != "Yes")
if(tgui_alert(usr, "Are you sure you want to respawn as a drone?", "Are you sure?", list("Yes", "No")) != "Yes")
return
for(var/obj/machinery/drone_fabricator/DF in GLOB.machines)
@@ -178,7 +178,7 @@
return
else
var/confirm = alert("Using your ID on a Maintenance Drone will shut it down, are you sure you want to do this?", "Disable Drone", "Yes", "No")
var/confirm = tgui_alert(user, "Using your ID on a Maintenance Drone will shut it down, are you sure you want to do this?", "Disable Drone", list("Yes", "No"))
if(confirm == ("Yes") && (user in range(3, src)))
user.visible_message("<span class='warning'>[user] swipes [user.p_their()] ID card through [src], attempting to shut it down.</span>",
"<span class='warning'>You swipe your ID card through [src], attempting to shut it down.</span>")
@@ -311,7 +311,7 @@
spawn(0)
if(!C || !M || jobban_isbanned(M, "nonhumandept") || jobban_isbanned(M, "Drone"))
return
var/response = alert(C, "Someone is attempting to reboot a maintenance drone. Would you like to play as one?", "Maintenance drone reboot", "Yes", "No")
var/response = tgui_alert(C, "Someone is attempting to reboot a maintenance drone. Would you like to play as one?", "Maintenance drone reboot", list("Yes", "No"))
if(!C || ckey)
return
if(response == "Yes")
@@ -7,15 +7,13 @@
var/mode = 1
/obj/item/pen/multi/robopen/attack_self(mob/user as mob)
var/choice = tgui_input_list(user, "Would you like to change colour or mode?", name, list("Colour","Mode"))
if(!choice) return
if(!choice)
return
switch(choice)
if("Colour")
select_colour(user)
if("Mode")
if(mode == 1)
mode = 2
@@ -23,7 +21,6 @@
mode = 1
to_chat(user, "Changed printing mode to '[mode == 2 ? "Rename Paper" : "Write Paper"]'")
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
return
// Copied over from paper's rename verb
@@ -32,14 +29,12 @@
/obj/item/pen/multi/robopen/proc/RenamePaper(mob/user, obj/paper)
if(!user || !paper)
return
var/n_name = input(user, "What would you like to label the paper?", "Paper Labelling") as text
if(!user || !paper)
var/n_name = tgui_input_text(user, "What would you like to label the paper?", "Paper Labelling", max_length = MAX_NAME_LEN)
if(!Adjacent(user) || !n_name)
return
n_name = copytext(n_name, 1, 32)
if(get_dist(user, paper) > 1 || user.stat)
return
paper.name = "paper[(n_name ? "- '[n_name]'" : null)]"
paper.name = "paper - [n_name]"
add_fingerprint(user)
//TODO: Add prewritten forms to dispense when you work out a good way to store the strings.
@@ -1054,7 +1054,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
set desc = "Toggles the lock on your cover."
if(can_lock_cover)
if(alert("Are you sure?", locked ? "Unlock Cover" : "Lock Cover", "Yes", "No") == "Yes")
if(tgui_alert(usr, "Are you sure?", locked ? "Unlock Cover" : "Lock Cover", list("Yes", "No")) == "Yes")
locked = !locked
update_icons()
to_chat(usr, "<span class='notice'>You [locked ? "lock" : "unlock"] your cover.</span>")
@@ -1062,7 +1062,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(!locked)
to_chat(usr, "<span class='warning'>You cannot lock your cover yourself. Find a roboticist.</span>")
return
if(alert("You cannnot lock your own cover again. Are you sure?\n You will need a roboticist to re-lock you.", "Unlock Own Cover", "Yes", "No") == "Yes")
if(tgui_alert(usr, "You cannnot lock your own cover again. Are you sure?\nYou will need a roboticist to re-lock you.", "Unlock Own Cover", list("Yes", "No")) == "Yes")
locked = !locked
update_icons()
to_chat(usr, "<span class='notice'>You unlock your cover.</span>")
@@ -337,7 +337,7 @@
set desc = "Sets a description which will be shown when someone examines you."
set category = "IC"
pose = sanitize(copytext(input(usr, "This is [src]. It...", "Pose", null) as text, 1, MAX_MESSAGE_LEN))
pose = tgui_input_text(usr, "This is [src]. It...", "Pose", pose)
/mob/living/silicon/verb/set_flavor()
set name = "Set Flavour Text"
@@ -242,7 +242,7 @@
if(new_dest)
set_destination(new_dest)
if("setid")
var/new_id = stripped_input(usr, "Enter ID:", name, suffix, MAX_NAME_LEN)
var/new_id = tgui_input_text(usr, "Enter ID:", name, suffix, MAX_NAME_LEN)
if(new_id)
set_suffix(new_id)
if("sethome")
@@ -269,7 +269,7 @@
to_chat(src, "<span class='big bold'>You are a cak!</span><b> You're a harmless cat/cake hybrid that everyone loves. People can take bites out of you if they're hungry, but you regenerate health \
so quickly that it generally doesn't matter. You're remarkably resilient to any damage besides this and it's hard for you to really die at all. You should go around and bring happiness and \
free cake to the station!</b>")
var/new_name = stripped_input(src, "Enter your name, or press \"Cancel\" to stick with Keeki.", "Name Change")
var/new_name = tgui_input_text(src, "Enter your name, or press \"Cancel\" to stick with Keeki.", "Name Change", name)
if(new_name)
to_chat(src, "<span class='notice'>Your name is now <b>\"[new_name]\"</b>!</span>")
name = new_name
@@ -49,7 +49,7 @@
if(istype(target, /obj/structure/elite_tumor))
var/obj/structure/elite_tumor/T = target
if(T.mychild == src && T.activity == TUMOR_PASSIVE)
var/response = alert(src, "Re-enter the tumor?","Despawn yourself?", "Yes", "No")
var/response = tgui_alert(src, "Re-enter the tumor?", "Despawn yourself?", list("Yes", "No"))
if(response == "No" || QDELETED(src) || !Adjacent(T))
return
T.clear_activator(src)
@@ -478,7 +478,7 @@ While using this makes the system rely on OnFire, it still gives options for tim
. = ..()
if(istype(mover, /obj/item/projectile))
return FALSE
/obj/item/gps/internal/tumor
icon_state = null
gpstag = "Cancerous Signal"
@@ -224,7 +224,7 @@
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/NestPrompt()
var/confirm = alert(src, "Are you sure you want to nest? You will be able to lay eggs, and smash walls, but not ventcrawl.","Nest?","Yes","No")
var/confirm = tgui_alert(src, "Are you sure you want to nest? You will be able to lay eggs, and smash walls, but not ventcrawl.", "Nest?", list("Yes","No"))
if(confirm == "Yes")
NestMode()
@@ -32,7 +32,7 @@
to_chat(user, "<span class='warning'>You are jobbanned from role of syndicate and/or terror spider.</span>")
return
if(error_on_humanize == "")
var/spider_ask = alert(humanize_prompt, "Join as Terror Spider?", "Yes", "No")
var/spider_ask = tgui_alert(user, humanize_prompt, "Join as Terror Spider?", list("Yes", "No"))
if(spider_ask == "No" || !src || QDELETED(src))
return
else
@@ -42,7 +42,7 @@
/mob/living/simple_animal/possessed_object/ghost() // Ghosting will return the object to normal, and will not disqualify the ghoster from various mid-round antag positions.
var/response = alert(src, "End your possession of this object? (It will not stop you from respawning later)","Are you sure you want to ghost?","Ghost","Stay in body")
var/response = tgui_alert(src, "End your possession of this object? (It will not stop you from respawning later)", "Are you sure you want to ghost?", list("Ghost", "Stay in body"))
if(response != "Ghost")
return
lay_down()
+1 -1
View File
@@ -764,7 +764,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
to_chat(usr, "<span class='notice'>You have to be conscious to change your flavor text</span>")
return
var/msg = input(usr,"Set the flavor text in your 'examine' verb. The flavor text should be a physical descriptor of your character at a glance.","Flavor Text",html_decode(flavor_text)) as message|null
var/msg = tgui_input_text(usr, "Set the flavor text in your 'examine' verb. The flavor text should be a physical descriptor of your character at a glance. SFW Drawn Art of your character is acceptable.", "Flavor Text", flavor_text, multiline = TRUE, encode = FALSE)
if(msg != null)
if(stat)
+1 -1
View File
@@ -53,7 +53,7 @@
if(!message && !client)
CRASH("An empty custom emote was called from a client-less mob.")
else if(!message)
input = sanitize(copytext(input(src,"Choose an emote to display.") as text|null, 1, MAX_MESSAGE_LEN))
input = tgui_input_text(src, "Choose an emote to display.", "Custom Emote")
else
input = message
+4 -4
View File
@@ -456,7 +456,7 @@
if(IsSleeping())
to_chat(src, "<span class='notice'>You are already sleeping.</span>")
return
if(alert(src, "You sure you want to sleep for a while?", "Sleep", "Yes", "No") == "Yes")
if(tgui_alert(src, "You sure you want to sleep for a while?", "Sleep", list("Yes", "No")) == "Yes")
SetSleeping(40 SECONDS, voluntary = TRUE) //Short nap
/mob/living/verb/rest()
@@ -660,11 +660,11 @@
for(var/i=1,i<=3,i++) //we get 3 attempts to pick a suitable name.
if(force)
newname = clean_input("Pick a new name.", "Name Change", oldname, src)
newname = tgui_input_text(src, "Pick a new name.", "Name Change", oldname)
else
newname = clean_input("You are a [role]. Would you like to change your name to something else? (You have 3 minutes to select a new name.)", "Name Change", oldname, src)
newname = tgui_input_text(src, "You are a [role]. Would you like to change your name to something else? (You have 3 minutes to select a new name.)", "Name Change", oldname, timeout = 3 MINUTES)
if(((world.time - time_passed) > 1800) && !force)
alert(src, "Unfortunately, more than 3 minutes have passed for selecting your name. If you are a robot, use the Namepick verb; otherwise, adminhelp.", "Name Change")
tgui_alert(src, "Unfortunately, more than 3 minutes have passed for selecting your name. If you are a robot, use the Namepick verb; otherwise, adminhelp.", "Name Change")
return //took too long
newname = reject_bad_name(newname,allow_numbers) //returns null if the name doesn't meet some basic requirements. Tidies up a few other things like bad-characters.
+2 -2
View File
@@ -178,9 +178,9 @@
to_chat(usr, "<span class='warning'>You must wait for the server to finish starting before you can join!</span>")
return FALSE
if(alert(src,"Are you sure you wish to observe? You cannot normally join the round after doing this!","Player Setup","Yes","No") == "Yes")
if(alert(usr, "Are you sure you wish to observe? You cannot normally join the round after doing this!", "Observe", "Yes", "No") == "Yes")
if(!client)
return 1
return TRUE
var/mob/dead/observer/observer = new(src)
src << browse(null, "window=playersetup")
spawning = TRUE
+1 -2
View File
@@ -163,8 +163,7 @@
if(scribble_page == curr_page)
to_chat(user, "<span class='notice'>There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?</span>")
else
var/s = strip_html(input(user, "Write something", "Newspaper", ""))
s = sanitize(copytext(s, 1, MAX_MESSAGE_LEN))
var/s = tgui_input_text(user, "Write something", "Newspaper")
if(!s || !Adjacent(user))
return
scribble_page = curr_page
@@ -13,7 +13,7 @@
suitBusy = 1
if(suitActive && (alert("Confirm suit systems shutdown? This cannot be halted once it has started.", "Confirm Shutdown", "Yes", "No") == "Yes"))
if(suitActive && (tgui_alert(usr, "Confirm suit systems shutdown? This cannot be halted once it has started.", "Confirm Shutdown", list("Yes", "No")) == "Yes"))
to_chat(usr, "<span class='darkmblue'>Now de-initializing...</span>")
sleep(15)
+3 -1
View File
@@ -201,7 +201,9 @@ GLOBAL_LIST_EMPTY(fax_blacklist)
. = FALSE
if("rename") // rename the item that is currently in the fax machine
if(copyitem)
var/n_name = sanitize(copytext(input(usr, "What would you like to label the fax?", "Fax Labelling", copyitem.name) as text, 1, MAX_MESSAGE_LEN))
var/n_name = tgui_input_text(usr, "What would you like to label the fax?", "Fax Labelling", copyitem.name)
if(!n_name)
return
if(copyitem && copyitem.loc == src && usr.stat == 0)
if(istype(copyitem, /obj/item/paper))
copyitem.name = "[(n_name ? "[n_name]" : initial(copyitem.name))]"
+1 -1
View File
@@ -40,7 +40,7 @@
if(mode)
to_chat(user, "<span class='notice'>You turn on \the [src].</span>")
//Now let them chose the text.
var/str = copytext(reject_bad_text(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN)
var/str = reject_bad_text(tgui_input_text(user,"Label text?", "Set label"))
if(!str || !length(str))
to_chat(user, "<span class='notice'>Invalid text.</span>")
return
+1 -1
View File
@@ -373,7 +373,7 @@
topic_href_write(id, input_element)
if(href_list["write"])
var/id = href_list["write"]
var/input_element = input("Enter what you want to write:", "Write", null, null) as message
var/input_element = tgui_input_text(usr, "Enter what you want to write:", "Write", multiline = TRUE, encode = FALSE)
topic_href_write(id, input_element)
/obj/item/paper/attackby(obj/item/P, mob/living/user, params)
+4 -4
View File
@@ -201,10 +201,10 @@
. = ..()
/obj/item/paper_bundle/proc/rename(mob/user)
var/n_name = sanitize(copytext(input(user, "What would you like to label the bundle?", "Bundle Labelling", name) as text, 1, MAX_MESSAGE_LEN))
if(loc == user && !user.stat)
name = "[(n_name ? "[n_name]" : "paper bundle")]"
var/n_name = tgui_input_text(user, "What would you like to label the bundle?", "Bundle Labelling", name)
if(!Adjacent(user) || !n_name || user.stat)
return
name = "[(n_name ? "[n_name]" : "paper bundle")]"
add_fingerprint(user)
/obj/item/paper_bundle/AltShiftClick(mob/user)
+1 -1
View File
@@ -435,7 +435,7 @@
return
if(stat & (BROKEN|NOPOWER))
return
var/text = input("Enter what you want to write:", "Write", null, null) as message
var/text = tgui_input_text(user, "Enter what you want to write:", "Write", multiline = TRUE, encode = FALSE)
if(!text)
return
if(toner < 1 || !user)
+8 -4
View File
@@ -41,7 +41,9 @@
/obj/item/photo/attackby(obj/item/P as obj, mob/user as mob, params)
if(is_pen(P) || istype(P, /obj/item/toy/crayon))
var/txt = sanitize(input(user, "What would you like to write on the back?", "Photo Writing", null) as text)
var/txt = tgui_input_text(user, "What would you like to write on the back?", "Photo Writing")
if(!txt)
return
txt = copytext(txt, 1, 128)
if(loc == user && user.stat == 0)
scribble = txt
@@ -106,9 +108,11 @@
onclose(usr, "Photo[UID()]")
/obj/item/photo/proc/rename(mob/user)
var/n_name = sanitize(copytext(input(user, "What would you like to label the photo?", "Photo Labelling", name) as text, 1, MAX_MESSAGE_LEN))
var/n_name = tgui_input_text(user, "What would you like to label the photo?", "Photo Labelling", name)
if(!n_name)
return
//loc.loc check is for making possible renaming photos in clipboards
if(( (loc == user || (loc.loc && loc.loc == user)) && !user.stat))
if(((loc == user || (loc.loc && loc.loc == user)) && !user.stat))
name = "[(n_name ? "[n_name]" : "photo")]"
add_fingerprint(user)
@@ -418,7 +422,7 @@ GLOBAL_LIST_INIT(SpookyGhosts, list("ghost","shade","shade2","ghost-narsie","hor
var/datum/picture/P = new()
if(istype(src,/obj/item/camera/digital))
P.fields["name"] = input(user,"Name photo:","photo")
P.fields["name"] = tgui_input_text(user, "Name photo:", "Photo", encode = FALSE)
if(!P.fields["name"])
P.fields["name"] = "Photo [current_photo_num]"
current_photo_num++
+4 -1
View File
@@ -381,11 +381,13 @@ GLOBAL_LIST_EMPTY(PDAs)
O.show_message(text("[bicon(src)] *[ttone]*"))
/obj/item/pda/proc/set_ringtone(mob/user)
var/new_tone = input("Please enter new ringtone", name, ttone) as text
var/new_tone = tgui_input_text(user, "Please enter new ringtone", name, ttone)
new_tone = trim(new_tone)
if(!in_range(src, user) || loc != user)
close(user)
return FALSE
if(!new_tone)
return FALSE
@@ -393,6 +395,7 @@ GLOBAL_LIST_EMPTY(PDAs)
to_chat(user, "The PDA softly beeps.")
close(user)
return TRUE
ttone = sanitize(copytext(new_tone, 1, 20))
return TRUE
+6 -2
View File
@@ -25,9 +25,13 @@
if(params["msgnum"])
switch(text2num(params["msgnum"]))
if(1)
message1 = clean_input("Line 1", "Enter Message Text", message1)
message1 = tgui_input_text(usr, "Line 1", "Enter Message Text", message1, encode = FALSE)
if(!message1)
return
if(2)
message2 = clean_input("Line 2", "Enter Message Text", message2)
message2 = tgui_input_text(usr, "Line 2", "Enter Message Text", message2, encode = FALSE)
if(!message2)
return
if("Status")
switch(text2num(params["statdisp"]))
+5 -5
View File
@@ -73,12 +73,12 @@
switch(action)
if("Edit")
var/n = input("Please enter message", name, note) as message
var/n = tgui_input_text(usr, "Please enter message", name, note, multiline = TRUE, encode = FALSE)
if(!n)
return
if(pda.loc == usr)
// TGUI will auto-reject supplied HTML
// However, the admin var-edit window will not
// SANITISATION IS IMPORTANT. DO NOT NEGLECT.
note = adminscrub(n)
note = n
else
pda.close(usr)
+1 -2
View File
@@ -121,10 +121,9 @@
/datum/data/pda/app/messenger/proc/create_message(mob/living/U, obj/item/pda/P)
var/t = input(U, "Please enter message", name, null) as text|null
var/t = tgui_input_text(U, "Please enter your message", name)
if(!t)
return
t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN))
if(!t || !istype(P))
return
if(!in_range(pda, U) && pda.loc != U)
+2 -2
View File
@@ -127,12 +127,12 @@
var/old_name = mob_info.mob_name
if(mob_info.nickname)
old_name = mob_info.nickname
mob_info.nickname = input("Give a nickname to [old_name]?", "Nickname", old_name)
mob_info.nickname = tgui_input_text(usr, "Give a nickname to [old_name]?", "Nickname", old_name)
/datum/data/pda/app/mob_hunter_game/proc/release()
if(!my_collection.len)
return
if(alert("Are you sure you want to release this mob back into the wild?", "Confirm Release", "Yes", "No") == "Yes")
if(tgui_alert(usr, "Are you sure you want to release this mob back into the wild?", "Confirm Release", list("Yes", "No")) == "Yes")
remove_mob()
/datum/data/pda/app/mob_hunter_game/proc/print_card()
+1 -1
View File
@@ -241,7 +241,7 @@
error_message(user, "Incorrect Credentials")
/datum/data/pda/app/nanobank/proc/input_account_pin(mob/user)
var/attempt_pin = input("Enter pin code", "NanoBank Account Auth") as num
var/attempt_pin = tgui_input_number(user, "Enter pin code", "NanoBank Account Auth")
if(!user_account || !attempt_pin)
return
return attempt_pin
+3 -1
View File
@@ -83,7 +83,9 @@
return
var/tmp_label = ""
var/label_text = sanitize(input(user, "Inscribe some text into \the [initial(BB.name)]", "Inscription", tmp_label))
var/label_text = tgui_input_text(user, "Inscribe some text into \the [initial(BB.name)]", "Inscription", tmp_label)
if(!label_text)
return
if(length(label_text) > 20)
to_chat(user, "<span class='warning'>The inscription can be at most 20 characters long.</span>")
@@ -749,11 +749,11 @@
return
var/tracking_target = locateUID(tracking_target_UID)
if(tracking_target)
if(alert("Do you want to clear the tracker?", "Tracker reset", "Yes", "No") == "Yes")
if(tgui_alert(user, "Do you want to clear the tracker?", "Tracker reset", list("Yes", "No")) == "Yes")
to_chat(user, "<span class='notice'>[src] stops tracking [tracking_target]</span>")
stop_pointing()
if(linked_pinpointer_UID)
if(alert("Do you want to clear the linked pinpointer?", "Pinpointer reset", "Yes", "No") == "Yes")
if(tgui_alert(user, "Do you want to clear the linked pinpointer?", "Pinpointer reset", list("Yes", "No")) == "Yes")
to_chat(user, "<span class='notice'>[src] is ready to be linked to a new pinpointer.</span>")
unlink()
@@ -114,7 +114,7 @@
D = new type(0, null)
if(!D)
return
var/name = stripped_input(usr,"Name:","Name the culture",D.name,MAX_NAME_LEN)
var/name = tgui_input_text(usr, "Name:", "Name the culture", D.name, MAX_NAME_LEN)
if(name == null || wait)
return
var/obj/item/reagent_containers/glass/bottle/B = new/obj/item/reagent_containers/glass/bottle(loc)
@@ -145,7 +145,7 @@
updateUsrDialog()
return
else if(href_list["name_disease"])
var/new_name = stripped_input(usr, "Name the Disease", "New Name", "", MAX_NAME_LEN)
var/new_name = tgui_input_text(usr, "Name the Disease", "New Name", max_length = MAX_NAME_LEN)
if(!new_name)
return
if(..())
@@ -179,7 +179,7 @@
/obj/machinery/computer/pandemic/proc/print_form(datum/disease/advance/D, mob/living/user)
D = GLOB.archive_diseases[D.GetDiseaseID()]
if(!(printing) && D)
var/reason = input(user,"Enter a reason for the release", "Write", null) as message
var/reason = tgui_input_text(user,"Enter a reason for the release", "Write", multiline = TRUE)
reason += "<span class=\"paper_field\"></span>"
var/english_symptoms = list()
for(var/I in D.symptoms)
@@ -189,7 +189,7 @@
var/signature
if(alert(user,"Would you like to add your signature?",,"Yes","No") == "Yes")
if(tgui_alert(user, "Would you like to add your signature?", "Signature", list("Yes","No")) == "Yes")
signature = "<font face=\"[SIGNFONT]\"><i>[user ? user.real_name : "Anonymous"]</i></font>"
else
signature = "<span class=\"paper_field\"></span>"
@@ -125,7 +125,7 @@
/obj/item/reagent_containers/applicator/AltClick(mob/user)
if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
if(alert(user, "Are you sure you want to empty [src]?", "Empty Applicator:", "Yes", "No") != "Yes")
if(tgui_alert(user, "Are you sure you want to empty [src]?", "Empty Applicator", list("Yes", "No")) != "Yes")
return
if(!user.incapacitated() && isturf(user.loc) && loc == user)
to_chat(user, "<span class='notice'>You empty [src] onto the floor.</span>")
@@ -106,7 +106,7 @@
/obj/item/reagent_containers/spray/AltClick(mob/user)
if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
if(alert(user, "Are you sure you want to empty that?", "Empty Bottle:", "Yes", "No") != "Yes")
if(tgui_alert(user, "Are you sure you want to empty that?", "Empty Bottle", list("Yes", "No")) != "Yes")
return
if(isturf(user.loc) && loc == user)
to_chat(user, "<span class='notice'>You empty [src] onto the floor.</span>")
+3 -3
View File
@@ -377,7 +377,7 @@
/obj/item/shippingPackage/attackby(obj/item/O, mob/user, params)
if(sealed)
if(is_pen(O))
var/str = copytext(sanitize(input(user, "Intended recipient?", "Address", "")), 1, MAX_NAME_LEN)
var/str = tgui_input_text(user, "Intended recipient?", "Address", max_length = MAX_NAME_LEN)
if(!str || !length(str))
to_chat(user, "<span class='notice'>Invalid text.</span>")
return
@@ -410,7 +410,7 @@
wrapped = null
qdel(src)
else if(wrapped)
switch(alert("Select an action:",, "Remove Object", "Seal Package", "Cancel"))
switch(tgui_alert(user, "Select an action:", "Shipping", list("Remove Object", "Seal Package", "Cancel")))
if("Remove Object")
to_chat(user, "<span class='notice'>You shake out [src]'s contents onto the floor.</span>")
wrapped.forceMove(get_turf(user))
@@ -421,7 +421,7 @@
sealed = 1
update_desc()
else
if(alert("Do you want to tear up the package?",, "Yes", "No") == "Yes")
if(tgui_alert(user, "Do you want to tear up the package?", "Shipping", list("Yes", "No")) == "Yes")
to_chat(user, "<span class='notice'>You shred [src].</span>")
playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1)
user.unEquip(src)
+2 -2
View File
@@ -579,7 +579,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
if("maxresearch")
if(!check_rights(R_ADMIN))
return
if(alert("Are you sure you want to maximize research levels?","Confirmation","Yes","No")=="No")
if(tgui_alert(usr, "Are you sure you want to maximize research levels?", "Confirmation", list("Yes", "No"))=="No")
return
log_admin("[key_name(usr)] has maximized the research levels.")
message_admins("[key_name_admin(usr)] has maximized the research levels.")
@@ -648,7 +648,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
if("reset") //Reset the R&D console's database.
griefProtection()
var/choice = alert("Are you sure you want to reset the R&D console's database? Data lost cannot be recovered.", "R&D Console Database Reset", "Continue", "Cancel")
var/choice = tgui_alert(usr, "Are you sure you want to reset the R&D console's database? Data lost cannot be recovered.", "R&D Console Database Reset", list("Continue", "Cancel"))
if(choice == "Continue")
add_wait_message("Resetting Database...", RESET_RESEARCH_DELAY)
addtimer(CALLBACK(src, PROC_REF(reset_research)), RESET_RESEARCH_DELAY)
+3 -3
View File
@@ -249,7 +249,7 @@
temp_server.id_with_download += num
else if(href_list["reset_tech"])
var/choice = alert("Technology Data Reset", "Are you sure you want to reset this technology to its default data? Data lost cannot be recovered.", "Continue", "Cancel")
var/choice = tgui_alert(usr, "Technology Data Reset", "Are you sure you want to reset this technology to its default data? Data lost cannot be recovered.", list("Continue", "Cancel"))
if(choice == "Continue")
for(var/I in temp_server.files.known_tech)
var/datum/tech/T = temp_server.files.known_tech[I]
@@ -259,7 +259,7 @@
temp_server.files.RefreshResearch()
else if(href_list["reset_design"])
var/choice = alert("Design Data Deletion", "Are you sure you want to blacklist this design? Ensure you sync servers after this decision.", "Continue", "Cancel")
var/choice = tgui_alert(usr, "Design Data Deletion", "Are you sure you want to blacklist this design? Ensure you sync servers after this decision.", list("Continue", "Cancel"))
if(choice == "Continue")
for(var/I in temp_server.files.known_designs)
var/datum/design/D = temp_server.files.known_designs[I]
@@ -272,7 +272,7 @@
temp_server.files.RefreshResearch()
else if(href_list["restore_design"])
var/choice = alert("Design Data Restoration", "Are you sure you want to restore this design? Ensure you sync servers after this decision.", "Continue", "Cancel")
var/choice = tgui_alert(usr, "Design Data Restoration", "Are you sure you want to restore this design? Ensure you sync servers after this decision.", list("Continue", "Cancel"))
if(choice == "Continue")
temp_server.files.blacklisted_designs -= href_list["restore_design"]
temp_server.files.unblacklisted_designs += href_list["restore_design"]
@@ -173,8 +173,7 @@
to_chat(M, "<span class='warning'>You absorb the potion and feel your intense desire to feed melt away.</span>")
to_chat(user, "<span class='notice'>You feed the slime the potion, removing its hunger and calming it.</span>")
being_used = TRUE
var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
var/newname = tgui_input_text(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime", MAX_NAME_LEN, 1)
if(!newname)
newname = "pet slime"
M.name = newname
@@ -228,7 +227,9 @@
explosion(T, -1, -1, 2, 3)
qdel(src)
return
var/reason_text = input(user, "Enter reason for giving sentience", "Reason for sentience potion", "") as null|text
var/reason_text = tgui_input_text(user, "Enter reason for giving sentience", "Reason for sentience potion")
if(!reason_text)
return
to_chat(user, "<span class='notice'>You offer [src] sentience potion to [SM]...</span>")
being_used = TRUE
@@ -304,7 +305,7 @@
return
prompted = TRUE
if(alert("This will permanently transfer your consciousness to [SM]. Are you sure you want to do this?",,"Yes","No")=="No")
if(tgui_alert(user, "This will permanently transfer your consciousness to [SM]. Are you sure you want to do this?", "Consciousness Transfer", list("Yes", "No")) == "No")
prompted = FALSE
return
+2 -2
View File
@@ -12,7 +12,7 @@
/obj/effect/mob_spawn/human/alive/ghost_bar/create(ckey, flavour = TRUE, name, mob/user = usr) // So divorced from the normal proc it's just being overriden
var/datum/character_save/save_to_load
if(alert(user, "Would you like to use one of your saved characters in your character creator?",, "Yes", "No") == "Yes")
if(tgui_alert(user, "Would you like to use one of your saved characters in your character creator?", "Ghost Bar", list("Yes", "No")) == "Yes")
var/list/our_characters_names = list()
var/list/our_character_saves = list()
for(var/index in 1 to length(user.client.prefs.character_saves))
@@ -99,7 +99,7 @@
if(!istype(mob_to_delete) || !istype(user) || !Adjacent(user))
return
if(mob_to_delete.client)
if(alert(mob_to_delete , "Would you like to return to the realm of spirits? (This will delete your current character, but you can rejoin later)",, "Yes", "No") == "No")
if(tgui_alert(mob_to_delete, "Would you like to return to the realm of spirits? (This will delete your current character, but you can rejoin later)", "Ghost Bar", list("Yes", "No")) == "No")
return
mob_to_delete.visible_message("<span class='notice'>[mob_to_delete.name] climbs into [src]...</span>")
playsound(src, 'sound/machines/wooden_closet_close.ogg', 50)
@@ -154,7 +154,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate)
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/structure/necropolis_gate/legion_gate/attack_hand(mob/user)
if(!open && !changing_openness)
var/safety = alert(user, "You think this might be a bad idea...", "Knock on the door?", "Proceed", "Abort")
var/safety = tgui_alert(user, "You think this might be a bad idea...", "Knock on the door?", list("Proceed", "Abort"))
if(safety == "Abort" || !in_range(src, user) || !src || open || changing_openness || user.incapacitated())
return
user.visible_message("<span class='warning'>[user] knocks on [src]...</span>", "<span class='boldannounceic'>You tentatively knock on [src]...</span>")
@@ -120,7 +120,7 @@
. = TRUE
switch(action)
if("ert")
ert_reason = input(usr, "Reason for ERT Call:", "", "") // we strip this later in ERT_Announce
ert_reason = tgui_input_text(usr, "Reason for ERT Call:", "Call ERT", encode = FALSE) // we strip this later in ERT_Announce
if("reset")
reset()
if("triggerevent")
+1 -1
View File
@@ -62,7 +62,7 @@
to_chat(user, "The access level of [W:registered_name]\'s card is not high enough. ")
return 0
var/choice = alert(user, "Would you like to (un)authorize a shortened launch time? [auth_need - length(authorized)] authorization\s are still needed. Use abort to cancel all authorizations.", "Shuttle Launch", "Authorize", "Repeal", "Abort")
var/choice = tgui_alert(user, "Would you like to (un)authorize a shortened launch time? [auth_need - length(authorized)] authorization\s are still needed. Use abort to cancel all authorizations.", "Shuttle Launch", list("Authorize", "Repeal", "Abort"))
if(SSshuttle.emergency.mode != SHUTTLE_DOCKED || user.get_active_hand() != W)
return 0
+4 -4
View File
@@ -256,7 +256,7 @@
return
var/amount = 1
if(params["multiple"])
var/num_input = input(user, "Amount", "How many crates? ([MULTIPLE_CRATE_MAX] Max)") as null|num
var/num_input = tgui_input_number(user, "Amount", "How many crates?", max_value = MULTIPLE_CRATE_MAX)
if(!num_input || (!is_public && !is_authorized(user)) || ..()) // Make sure they dont walk away
return
amount = clamp(round(num_input), 1, MULTIPLE_CRATE_MAX)
@@ -264,7 +264,7 @@
if(!istype(P))
return
var/timeout = world.time + (60 SECONDS) // If you dont type the reason within a minute, theres bigger problems here
var/reason = input(user, "Reason", "Why do you require this item?","") as null|text
var/reason = tgui_input_text(user, "Reason", "Why do you require this item?", encode = FALSE)
if(world.time > timeout || !reason || (!is_public && !is_authorized(user)) || ..())
// Cancel if they take too long, they dont give a reason, they aint authed, or if they walked away
return
@@ -431,8 +431,8 @@
var/attempt_pin = pin
if(customer_account.security_level != ACCOUNT_SECURITY_ID && !attempt_pin)
//if pin is not given, we'll prompt them here
attempt_pin = input("Enter pin code", "Vendor transaction") as num
if(!Adjacent(user))
attempt_pin = tgui_input_number(user, "Enter pin code", "Vendor transaction")
if(!Adjacent(user) || !attempt_pin)
return FALSE
var/is_admin = is_admin(user)
if(!account_database.try_authenticate_login(customer_account, attempt_pin, TRUE, FALSE, is_admin))
+2 -2
View File
@@ -67,7 +67,7 @@ GLOBAL_DATUM_INIT(multispin_words, /regex, regex("like a record baby"))
/datum/action/item_action/organ_action/use/adamantine_vocal_cords/Trigger(left_click)
if(!IsAvailable())
return
var/message = input(owner, "Resonate a message to all nearby golems.", "Resonate")
var/message = tgui_input_text(owner, "Resonate a message to all nearby golems.", "Resonate")
if(QDELETED(src) || QDELETED(owner) || !message)
return
owner.say(".~[message]")
@@ -123,7 +123,7 @@ GLOBAL_DATUM_INIT(multispin_words, /regex, regex("like a record baby"))
if(world.time < cords.next_command)
to_chat(owner, "<span class='notice'>You must wait [(cords.next_command - world.time)/10] seconds before Speaking again.</span>")
return
var/command = input(owner, "Speak with the Voice of God", "Command")
var/command = tgui_input_text(owner, "Speak with the Voice of God", "Command")
if(!command)
return
owner.say(".~[command]")
+1 -1
View File
@@ -693,7 +693,7 @@
/datum/surgery_step/robotics/edit_serial/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/new_name = copytext(reject_bad_text(input(user, "Choose a name for this machine.", "Set Name", "[target.real_name]") as null|text), 1, MAX_NAME_LEN)
var/new_name = reject_bad_text(tgui_input_text(user, "Choose a name for this machine.", "Set Name", "[target.real_name]", MAX_NAME_LEN, 1))
if(!new_name)
to_chat(user, "<span class='warning'>Invalid name! Please try again.</span>")
return SURGERY_STEP_INCOMPLETE
+1 -1
View File
@@ -66,7 +66,7 @@ GLOBAL_DATUM_INIT(ghost_hud_panel, /datum/ui_module/ghost_hud_panel, new)
return FALSE
// Check if this is the first time they're turning on Antag HUD.
if(!check_rights(R_ADMIN | R_MOD, FALSE) && !ghost.is_roundstart_observer() && GLOB.configuration.general.restrict_antag_hud_rejoin && !ghost.has_ahudded())
var/response = alert(ghost, "If you turn this on, you will not be able to take any part in the round.", "Are you sure you want to enable antag HUD?", "Yes", "No")
var/response = tgui_alert(ghost, "If you turn this on, you will not be able to take any part in the round.", "Are you sure you want to enable antag HUD?", list("Yes", "No"))
if(response == "No")
return FALSE
+7 -7
View File
@@ -69,29 +69,29 @@
owner.add_supplied_law(supplied_law_position, supplied_law)
if("change_zeroth_law")
var/new_law = sanitize(input("Enter new law Zero. Leaving the field blank will cancel the edit.", "Edit Law", zeroth_law))
var/new_law = tgui_input_text(src, "Enter new law Zero. Leaving the field blank will cancel the edit.", "Edit Law", zeroth_law)
if(new_law && new_law != zeroth_law && (!..()))
zeroth_law = new_law
if("change_ion_law")
var/new_law = sanitize(input("Enter new ion law. Leaving the field blank will cancel the edit.", "Edit Law", ion_law))
var/new_law = tgui_input_text(src, "Enter new ion law. Leaving the field blank will cancel the edit.", "Edit Law", ion_law)
if(new_law && new_law != ion_law && (!..()))
ion_law = new_law
if("change_inherent_law")
var/new_law = sanitize(input("Enter new inherent law. Leaving the field blank will cancel the edit.", "Edit Law", inherent_law))
var/new_law = tgui_input_text(src, "Enter new inherent law. Leaving the field blank will cancel the edit.", "Edit Law", inherent_law)
if(new_law && new_law != inherent_law && (!..()))
inherent_law = new_law
if("change_supplied_law")
var/new_law = sanitize(input("Enter new supplied law. Leaving the field blank will cancel the edit.", "Edit Law", supplied_law))
var/new_law = tgui_input_text(src, "Enter new supplied law. Leaving the field blank will cancel the edit.", "Edit Law", supplied_law)
if(new_law && new_law != supplied_law && (!..()))
supplied_law = new_law
if("change_supplied_law_position")
var/new_position = input(usr, "Enter new supplied law position between 1 and [MAX_SUPPLIED_LAW_NUMBER], inclusive. Inherent laws at the same index as a supplied law will not be stated.", "Law Position", supplied_law_position) as num|null
var/new_position = tgui_input_number(usr, "Enter new supplied law position between 1 and [MAX_SUPPLIED_LAW_NUMBER], inclusive. Inherent laws at the same index as a supplied law will not be stated.", "Law Position", supplied_law_position, MAX_SUPPLIED_LAW_NUMBER, 1)
if(isnum(new_position) && (!..()))
supplied_law_position = clamp(new_position, 1, MAX_SUPPLIED_LAW_NUMBER)
supplied_law_position = new_position
if("edit_law")
if(is_malf(usr))
@@ -101,7 +101,7 @@
to_chat(usr, "<span class='warning'>You can't edit that law.</span>")
return
if(AL)
var/new_law = sanitize(input(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", AL.law))
var/new_law = tgui_input_text(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", AL.law)
if(new_law && new_law != AL.law && is_malf(usr) && (!..()))
log_and_message_admins("has changed a law of [owner] from '[AL.law]' to '[new_law]'")
AL.law = new_law
@@ -1,188 +0,0 @@
/**
* Creates a TGUI input list window and returns the user's response.
*
* This proc should be used to create alerts that the caller will wait for a response from.
* Arguments:
* * user - The user to show the input box to.
* * message - The content of the input box, shown in the body of the TGUI window.
* * title - The title of the input box, shown on the top of the TGUI window.
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
* * timeout - The timeout of the input box, after which the input box will close and qdel itself. Set to zero for no timeout.
*/
/proc/tgui_input_list(mob/user, message, title, list/buttons, timeout = 0)
if(!user)
user = usr
if(!length(buttons))
return
if(!istype(user))
if(!isclient(user))
return
var/client/client = user
user = client.mob
/// Client does NOT have tgui_input on: Returns regular input
if(user.client?.prefs?.toggles2 & PREFTOGGLE_2_DISABLE_TGUI_LISTS)
return input(user, message, title) as null|anything in buttons
var/datum/tgui_list_input/input = new(user, message, title, buttons, timeout)
input.ui_interact(user)
input.wait()
if(input)
. = input.choice
qdel(input)
/**
* Creates an asynchronous TGUI input list window with an associated callback.
*
* This proc should be used to create inputs that invoke a callback with the user's chosen option.
* Arguments:
* * user - The user to show the input box to.
* * message - The content of the input box, shown in the body of the TGUI window.
* * title - The title of the input box, shown on the top of the TGUI window.
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
* * callback - The callback to be invoked when a choice is made.
* * timeout - The timeout of the input box, after which the menu will close and qdel itself. Set to zero for no timeout.
*/
/proc/tgui_input_list_async(mob/user, message, title, list/buttons, datum/callback/callback, timeout = 60 SECONDS)
if(!user)
user = usr
if(!length(buttons))
return
if(!istype(user))
if(!isclient(user))
return
var/client/client = user
user = client.mob
var/datum/tgui_list_input/async/input = new(user, message, title, buttons, timeout, callback)
input.ui_interact(user)
/**
* # tgui_list_input
*
* Datum used for instantiating and using a TGUI-controlled list input that prompts the user with
* a message and shows a list of selectable options
*/
/datum/tgui_list_input
/// The title of the TGUI window
var/title
/// The textual body of the TGUI window
var/message
/// The list of buttons (responses) provided on the TGUI window
var/list/buttons
/// Buttons (strings specifically) mapped to the actual value (e.g. a mob or a verb)
var/list/buttons_map
/// The button that the user has pressed, null if no selection has been made
var/choice
/// The time at which the tgui_list_input was created, for displaying timeout progress.
var/start_time
/// The lifespan of the tgui_list_input, after which the window will close and delete itself.
var/timeout
/// Boolean field describing if the tgui_list_input was closed by the user.
var/closed
/datum/tgui_list_input/New(mob/user, message, title, list/buttons, timeout)
src.title = title
src.message = message
src.buttons = list()
src.buttons_map = list()
// Gets rid of illegal characters
var/static/regex/whitelistedWords = regex(@{"([^\u0020-\u8000]+)"})
for(var/i in buttons)
var/string_key = whitelistedWords.Replace("[i]", "")
src.buttons += string_key
src.buttons_map[string_key] = i
if(timeout)
src.timeout = timeout
start_time = world.time
QDEL_IN(src, timeout)
/datum/tgui_list_input/Destroy(force, ...)
SStgui.close_uis(src)
QDEL_NULL(buttons)
. = ..()
/**
* Waits for a user's response to the tgui_list_input's prompt before returning. Returns early if
* the window was closed by the user.
*/
/datum/tgui_list_input/proc/wait()
while(!choice && !closed)
stoplag(1)
/datum/tgui_list_input/ui_state(mob/user)
return GLOB.always_state
/datum/tgui_list_input/ui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ListInput", title)
ui.set_autoupdate(FALSE)
ui.open()
/datum/tgui_list_input/ui_close(mob/user)
. = ..()
closed = TRUE
/datum/tgui_list_input/ui_static_data(mob/user)
var/list/data = list()
data["title"] = title
data["message"] = message
data["buttons"] = buttons
return data
/datum/tgui_list_input/ui_data(mob/user)
var/list/data = list()
if(timeout)
data["timeout"] = clamp((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS), 0, 1)
/datum/tgui_list_input/ui_act(action, list/params)
if(..())
return
. = TRUE
switch(action)
if("choose")
if(!(params["choice"] in buttons))
return
choice = buttons_map[params["choice"]]
SStgui.close_uis(src)
if("cancel")
SStgui.close_uis(src)
closed = TRUE
/**
* # async tgui_list_input
*
* An asynchronous version of tgui_list_input to be used with callbacks instead of waiting on user responses.
*/
/datum/tgui_list_input/async
/// The callback to be invoked by the tgui_list_input upon having a choice made.
var/datum/callback/callback
/datum/tgui_list_input/async/New(mob/user, message, title, list/buttons, timeout, callback)
..()
src.callback = callback
/datum/tgui_list_input/async/Destroy(force, ...)
QDEL_NULL(callback)
. = ..()
/datum/tgui_list_input/async/ui_close(mob/user)
. = ..()
qdel(src)
/datum/tgui_list_input/async/ui_act(action, list/params)
. = ..()
if(!. || choice == null)
return
callback.InvokeAsync(choice)
qdel(src)
/datum/tgui_list_input/async/wait()
return
+145
View File
@@ -0,0 +1,145 @@
/**
* Creates a TGUI alert window and returns the user's response.
*
* This proc should be used to create alerts that the caller will wait for a response from.
* Arguments:
* * user - The user to show the alert to.
* * message - The content of the alert, shown in the body of the TGUI window.
* * title - The of the alert modal, shown on the top of the TGUI window.
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
* * timeout - The timeout of the alert, after which the modal will close and qdel itself. Set to zero for no timeout.
* * autofocus - The bool that controls if this alert should grab window focus.
*/
/proc/tgui_alert(mob/user, message = "", title = "Alert", list/buttons = list("Ok"), timeout = 0, autofocus = TRUE, ui_state = GLOB.always_state)
if(!user)
user = usr
if(!istype(user))
if(!isclient(user))
CRASH("We passed something that wasn't a user/client in a TGUI Alert! The passed user was [user]!")
var/client/client = user
user = client.mob
if(isnull(user.client))
return
// A gentle nudge - you should not be using TGUI alert for anything other than a simple message.
if(length(buttons) > 3)
log_tgui(user, "Error: TGUI Alert initiated with too many buttons. Use a list.", "TguiAlert")
return tgui_input_list(user, message, title, buttons, timeout)
// Client does NOT have tgui_input on: Returns regular input
if(user.client?.prefs?.toggles2 & PREFTOGGLE_2_DISABLE_TGUI_INPUT)
if(length(buttons) == 2)
return alert(user, message, title, buttons[1], buttons[2])
if(length(buttons) == 3)
return alert(user, message, title, buttons[1], buttons[2], buttons[3])
var/datum/tgui_alert/alert = new(user, message, title, buttons, timeout, autofocus, ui_state)
alert.ui_interact(user)
alert.wait()
if(alert)
. = alert.choice
qdel(alert)
/**
* # tgui_alert
*
* Datum used for instantiating and using a TGUI-controlled modal that prompts the user with
* a message and has buttons for responses.
*/
/datum/tgui_alert
/// The title of the TGUI window
var/title
/// The textual body of the TGUI window
var/message
/// The list of buttons (responses) provided on the TGUI window
var/list/buttons
/// The button that the user has pressed, null if no selection has been made
var/choice
/// The time at which the tgui_alert was created, for displaying timeout progress.
var/start_time
/// The lifespan of the tgui_alert, after which the window will close and delete itself.
var/timeout
/// The bool that controls if this modal should grab window focus
var/autofocus
/// Boolean field describing if the tgui_alert was closed by the user.
var/closed
/// The TGUI UI state that will be returned in ui_state(). Default: always_state
var/datum/ui_state/state
/datum/tgui_alert/New(mob/user, message, title, list/buttons, timeout, autofocus, ui_state)
src.autofocus = autofocus
src.buttons = buttons.Copy()
src.message = message
src.title = title
src.state = ui_state
if(timeout)
src.timeout = timeout
start_time = world.time
QDEL_IN(src, timeout)
/datum/tgui_alert/Destroy(force)
SStgui.close_uis(src)
state = null
QDEL_NULL(buttons)
return ..()
/**
* Waits for a user's response to the tgui_alert's prompt before returning. Returns early if
* the window was closed by the user.
*/
/datum/tgui_alert/proc/wait()
while(!choice && !closed && !QDELETED(src))
stoplag(1)
/datum/tgui_alert/ui_state(mob/user)
return state
/datum/tgui_alert/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AlertModal")
ui.open()
/datum/tgui_alert/ui_close(mob/user)
closed = TRUE
/datum/tgui_alert/ui_static_data(mob/user)
var/list/data = list()
data["autofocus"] = autofocus
data["buttons"] = buttons
data["message"] = message
data["large_buttons"] = user.client?.prefs?.toggles2 & PREFTOGGLE_2_LARGE_INPUT_BUTTONS
data["swapped_buttons"] = user.client?.prefs?.toggles2 & PREFTOGGLE_2_SWAP_INPUT_BUTTONS
data["title"] = title
return data
/datum/tgui_alert/ui_data(mob/user)
var/list/data = list()
if(timeout)
data["timeout"] = CLAMP01((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS))
return data
/datum/tgui_alert/ui_act(action, list/params)
. = ..()
if(.)
return
switch(action)
if("choose")
if(!(params["choice"] in buttons))
CRASH("[usr] entered a non-existent button choice: [params["choice"]]")
set_choice(params["choice"])
closed = TRUE
SStgui.close_uis(src)
return TRUE
if("cancel")
closed = TRUE
SStgui.close_uis(src)
return TRUE
/datum/tgui_alert/proc/set_choice(choice)
src.choice = choice
+165
View File
@@ -0,0 +1,165 @@
/**
* Creates a TGUI input list window and returns the user's response.
*
* This proc should be used to create alerts that the caller will wait for a response from.
* Arguments:
* * user - The user to show the input box to.
* * message - The content of the input box, shown in the body of the TGUI window.
* * title - The title of the input box, shown on the top of the TGUI window.
* * items - The options that can be chosen by the user, each string is assigned a button on the UI.
* * default - If an option is already preselected on the UI. Current values, etc.
* * timeout - The timeout of the input box, after which the menu will close and qdel itself. Set to zero for no timeout.
*/
/proc/tgui_input_list(mob/user, message, title = "Select", list/items, default, timeout = 0, ui_state = GLOB.always_state)
if(!user)
user = usr
if(!length(items))
CRASH("[user] tried to open an empty TGUI Input List. Contents are: [items]")
if(!istype(user))
if(!isclient(user))
CRASH("We passed something that wasn't a user/client in a TGUI Input List! The passed user was [user]!")
var/client/client = user
user = client.mob
if(isnull(user.client))
return
/// Client does NOT have tgui_input on: Returns regular input
if(user.client?.prefs?.toggles2 & PREFTOGGLE_2_DISABLE_TGUI_INPUT)
return input(user, message, title, default) as null|anything in items
var/datum/tgui_list_input/input = new(user, message, title, items, default, timeout, ui_state)
if(input.invalid)
qdel(input)
return
input.ui_interact(user)
input.wait()
if(input)
. = input.choice
qdel(input)
/**
* # tgui_list_input
*
* Datum used for instantiating and using a TGUI-controlled list input that prompts the user with
* a message and shows a list of selectable options
*/
/datum/tgui_list_input
/// The title of the TGUI window
var/title
/// The textual body of the TGUI window
var/message
/// The list of items (responses) provided on the TGUI window
var/list/items
/// Buttons (strings specifically) mapped to the actual value (e.g. a mob or a verb)
var/list/items_map
/// The button that the user has pressed, null if no selection has been made
var/choice
/// The default button to be selected
var/default
/// The time at which the tgui_list_input was created, for displaying timeout progress.
var/start_time
/// The lifespan of the tgui_list_input, after which the window will close and delete itself.
var/timeout
/// Boolean field describing if the tgui_list_input was closed by the user.
var/closed
/// The TGUI UI state that will be returned in ui_state(). Default: always_state
var/datum/ui_state/state
/// Whether the tgui list input is invalid or not (i.e. due to all list entries being null)
var/invalid = FALSE
/datum/tgui_list_input/New(mob/user, message, title, list/items, default, timeout, ui_state)
src.title = title
src.message = message
src.items = list()
src.items_map = list()
src.default = default
src.state = ui_state
var/list/repeat_items = list()
// Gets rid of illegal characters
var/static/regex/whitelistedWords = regex(@{"([^\u0020-\u8000]+)"})
for(var/i in items)
var/string_key = whitelistedWords.Replace("[i]", "")
// Avoids duplicated keys E.g: when areas have the same name
string_key = avoid_assoc_duplicate_keys(string_key, repeat_items)
src.items += string_key
src.items_map[string_key] = i
if(length(src.items) == 0)
invalid = TRUE
if(timeout)
src.timeout = timeout
start_time = world.time
QDEL_IN(src, timeout)
/datum/tgui_list_input/Destroy(force)
SStgui.close_uis(src)
state = null
QDEL_NULL(items)
return ..()
/**
* Waits for a user's response to the tgui_list_input's prompt before returning. Returns early if
* the window was closed by the user.
*/
/datum/tgui_list_input/proc/wait()
while(!choice && !closed)
stoplag(1)
/datum/tgui_list_input/ui_state(mob/user)
return state
/datum/tgui_list_input/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ListInputModal")
ui.set_autoupdate(FALSE)
ui.open()
/datum/tgui_list_input/ui_close(mob/user)
closed = TRUE
/datum/tgui_list_input/ui_static_data(mob/user)
var/list/data = list()
data["init_value"] = default || items[1]
data["items"] = items
data["message"] = message
data["large_buttons"] = user.client?.prefs?.toggles2 & PREFTOGGLE_2_LARGE_INPUT_BUTTONS
data["swapped_buttons"] = user.client?.prefs?.toggles2 & PREFTOGGLE_2_SWAP_INPUT_BUTTONS
data["title"] = title
return data
/datum/tgui_list_input/ui_data(mob/user)
var/list/data = list()
if(timeout)
data["timeout"] = clamp((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS), 0, 1)
return data
/datum/tgui_list_input/ui_act(action, list/params)
. = ..()
if(.)
return
switch(action)
if("submit")
if(!(params["entry"] in items))
return
set_choice(items_map[params["entry"]])
closed = TRUE
SStgui.close_uis(src)
return TRUE
if("cancel")
closed = TRUE
SStgui.close_uis(src)
return TRUE
/datum/tgui_list_input/proc/set_choice(choice)
src.choice = choice
@@ -0,0 +1,168 @@
/**
* Creates a TGUI window with a number input. Returns the user's response as num | null.
*
* This proc should be used to create windows for number entry that the caller will wait for a response from.
* If tgui fancy chat is turned off: Will return a normal input. If a max or min value is specified, will
* validate the input inside the UI and ui_act.
*
* Arguments:
* * user - The user to show the number input to.
* * message - The content of the number input, shown in the body of the TGUI window.
* * title - The title of the number input modal, shown on the top of the TGUI window.
* * default - The default (or current) value, shown as a placeholder. Users can press refresh with this.
* * max_value - Specifies a maximum value. If none is set, any number can be entered. Pressing "max" defaults to 1000.
* * min_value - Specifies a minimum value. Often 0.
* * timeout - The timeout of the number input, after which the modal will close and qdel itself. Set to zero for no timeout.
* * round_value - whether the inputted number is rounded down into an integer.
*/
/proc/tgui_input_number(mob/user, message, title = "Number Input", default = 0, max_value = 10000, min_value = 0, timeout = 0, round_value = TRUE, ui_state = GLOB.always_state)
if(!user)
user = usr
if(!istype(user))
if(!isclient(user))
CRASH("We passed something that wasn't a user/client in a TGUI Input Number! The passed user was [user]!")
var/client/client = user
user = client.mob
if(isnull(user.client))
return
// Client does NOT have tgui_input on: Returns regular input
if(user.client?.prefs?.toggles2 & PREFTOGGLE_2_DISABLE_TGUI_INPUT)
var/input_number = input(user, message, title, default) as null|num
return clamp(round_value ? round(input_number) : input_number, min_value, max_value)
var/datum/tgui_input_number/number_input = new(user, message, title, default, max_value, min_value, timeout, round_value, ui_state)
number_input.ui_interact(user)
number_input.wait()
if(number_input)
. = number_input.entry
qdel(number_input)
/**
* # tgui_input_number
*
* Datum used for instantiating and using a TGUI-controlled number input that prompts the user with
* a message and has an input for number entry.
*/
/datum/tgui_input_number
/// Boolean field describing if the tgui_input_number was closed by the user.
var/closed
/// The default (or current) value, shown as a default. Users can press reset with this.
var/default
/// The entry that the user has return_typed in.
var/entry
/// The maximum value that can be entered.
var/max_value
/// The prompt's body, if any, of the TGUI window.
var/message
/// The minimum value that can be entered.
var/min_value
/// Whether the submitted number is rounded down into an integer.
var/round_value
/// The time at which the number input was created, for displaying timeout progress.
var/start_time
/// The lifespan of the number input, after which the window will close and delete itself.
var/timeout
/// The title of the TGUI window
var/title
/// The TGUI UI state that will be returned in ui_state(). Default: always_state
var/datum/ui_state/state
/datum/tgui_input_number/New(mob/user, message, title, default, max_value, min_value, timeout, round_value, ui_state)
src.default = default
src.max_value = max_value
src.message = message
src.min_value = min_value
src.title = title
src.round_value = round_value
src.state = ui_state
if(timeout)
src.timeout = timeout
start_time = world.time
QDEL_IN(src, timeout)
/// Checks for empty numbers - bank accounts, etc.
if(max_value == 0)
src.min_value = 0
if(default)
src.default = 0
/// Sanity check
if(default < min_value)
src.default = min_value
if(default > max_value)
CRASH("Default value is greater than max value.")
/datum/tgui_input_number/Destroy(force)
SStgui.close_uis(src)
state = null
return ..()
/**
* Waits for a user's response to the tgui_input_number's prompt before returning. Returns early if
* the window was closed by the user.
*/
/datum/tgui_input_number/proc/wait()
while(!entry && !closed && !QDELETED(src))
stoplag(1)
/datum/tgui_input_number/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "NumberInputModal")
ui.open()
/datum/tgui_input_number/ui_close(mob/user)
closed = TRUE
/datum/tgui_input_number/ui_state(mob/user)
return state
/datum/tgui_input_number/ui_static_data(mob/user)
var/list/data = list()
data["init_value"] = default // Default is a reserved keyword
data["min_value"] = min_value
data["max_value"] = max_value
data["round_value"] = round_value
data["message"] = message
data["large_buttons"] = user.client?.prefs?.toggles2 & PREFTOGGLE_2_LARGE_INPUT_BUTTONS
data["swapped_buttons"] = user.client?.prefs?.toggles2 & PREFTOGGLE_2_SWAP_INPUT_BUTTONS
data["title"] = title
return data
/datum/tgui_input_number/ui_data(mob/user)
var/list/data = list()
if(timeout)
data["timeout"] = CLAMP01((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS))
return data
/datum/tgui_input_number/ui_act(action, list/params)
. = ..()
if(.)
return
switch(action)
if("submit")
if(!isnum(params["entry"]))
CRASH("A non number was input into TGUI Input Number by [usr]")
var/choice = round_value ? round(params["entry"]) : params["entry"]
if(choice > max_value)
CRASH("A number greater than the max value was input into TGUI Input Number by [usr]")
if(choice < min_value)
CRASH("A number less than the min value was input into TGUI Input Number by [usr]")
set_entry(choice)
closed = TRUE
SStgui.close_uis(src)
return TRUE
if("cancel")
closed = TRUE
SStgui.close_uis(src)
return TRUE
/datum/tgui_input_number/proc/set_entry(entry)
src.entry = entry
+171
View File
@@ -0,0 +1,171 @@
/**
* Creates a TGUI window with a text input. Returns the user's response.
*
* This proc should be used to create windows for text entry that the caller will wait for a response from.
* If tgui fancy chat is turned off: Will return a normal input. If max_length is specified, will return
* stripped_multiline_input.
*
* Arguments:
* * user - The user to show the text input to.
* * message - The content of the text input, shown in the body of the TGUI window.
* * title - The title of the text input modal, shown on the top of the TGUI window.
* * default - The default (or current) value, shown as a placeholder.
* * max_length - Specifies a max length for input. MAX_MESSAGE_LEN is default (1024)
* * multiline - Bool that determines if the input box is much larger. Good for large messages, laws, etc.
* * encode - Toggling this determines if input is filtered via html_encode. Setting this to FALSE gives raw input.
* * timeout - The timeout of the textbox, after which the modal will close and qdel itself. Set to zero for no timeout.
*/
/proc/tgui_input_text(mob/user, message = "", title = "Text Input", default, max_length = MAX_MESSAGE_LEN, multiline = FALSE, encode = TRUE, timeout = 0, ui_state = GLOB.always_state)
if(!user)
user = usr
if(!istype(user))
if(!isclient(user))
CRASH("We passed something that wasn't a user/client in a TGUI Input Text! The passed user was [user]!")
var/client/client = user
user = client.mob
if(isnull(user.client))
return
// Client does NOT have tgui_input on: Returns regular input
if(user.client?.prefs?.toggles2 & PREFTOGGLE_2_DISABLE_TGUI_INPUT)
if(encode)
if(multiline)
return stripped_multiline_input(user, message, title, default, max_length)
else
return stripped_input(user, message, title, default, max_length)
else
if(multiline)
return input(user, message, title, default) as message|null
else
return input(user, message, title, default) as text|null
var/datum/tgui_input_text/text_input = new(user, message, title, default, max_length, multiline, encode, timeout, ui_state)
text_input.ui_interact(user)
text_input.wait()
if(text_input)
. = text_input.entry
qdel(text_input)
/**
* tgui_input_text
*
* Datum used for instantiating and using a TGUI-controlled text input that prompts the user with
* a message and has an input for text entry.
*/
/datum/tgui_input_text
/// Boolean field describing if the tgui_input_text was closed by the user.
var/closed
/// The default (or current) value, shown as a default.
var/default
/// Whether the input should be stripped using html_encode
var/encode
/// The entry that the user has return_typed in.
var/entry
/// The maximum length for text entry
var/max_length
/// The prompt's body, if any, of the TGUI window.
var/message
/// Multiline input for larger input boxes.
var/multiline
/// The time at which the text input was created, for displaying timeout progress.
var/start_time
/// The lifespan of the text input, after which the window will close and delete itself.
var/timeout
/// The title of the TGUI window
var/title
/// The TGUI UI state that will be returned in ui_state(). Default: always_state
var/datum/ui_state/state
/datum/tgui_input_text/New(mob/user, message, title, default, max_length, multiline, encode, timeout, ui_state)
src.default = default
src.encode = encode
src.max_length = max_length
src.message = message
src.multiline = multiline
src.title = title
src.state = ui_state
if(timeout)
src.timeout = timeout
start_time = world.time
QDEL_IN(src, timeout)
/datum/tgui_input_text/Destroy(force)
SStgui.close_uis(src)
state = null
return ..()
/**
* Waits for a user's response to the tgui_input_text's prompt before returning. Returns early if
* the window was closed by the user.
*/
/datum/tgui_input_text/proc/wait()
while(!entry && !closed && !QDELETED(src))
stoplag(1)
/datum/tgui_input_text/ui_state(mob/user)
return state
/datum/tgui_input_text/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TextInputModal")
ui.open()
/datum/tgui_input_text/ui_close(mob/user)
closed = TRUE
/datum/tgui_input_text/ui_static_data(mob/user)
var/list/data = list()
data["max_length"] = max_length
data["message"] = message
data["multiline"] = multiline
data["placeholder"] = default // Default is a reserved keyword
data["large_buttons"] = user.client?.prefs?.toggles2 & PREFTOGGLE_2_LARGE_INPUT_BUTTONS
data["swapped_buttons"] = user.client?.prefs?.toggles2 & PREFTOGGLE_2_SWAP_INPUT_BUTTONS
data["title"] = title
return data
/datum/tgui_input_text/ui_data(mob/user)
var/list/data = list()
if(timeout)
data["timeout"] = CLAMP01((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS))
return data
/datum/tgui_input_text/ui_act(action, list/params)
. = ..()
if(.)
return
switch(action)
if("submit")
if(!max_length)
return
if(length_char(params["entry"]) > max_length)
CRASH("[usr] typed a text string longer than the max length")
if(encode && (length_char(html_encode(params["entry"])) > max_length))
to_chat(usr, "<span class='notice'>Your message was clipped due to special character usage.</span>")
set_entry(params["entry"])
closed = TRUE
SStgui.close_uis(src)
return TRUE
if("cancel")
closed = TRUE
SStgui.close_uis(src)
return TRUE
/**
* Sets the return value for the tgui text proc.
* If html encoding is enabled, the text will be encoded.
* This can sometimes result in a string that is longer than the max length.
* If the string is longer than the max length, it will be clipped.
*/
/datum/tgui_input_text/proc/set_entry(entry)
if(isnull(entry))
return
var/converted_entry = encode ? html_encode(entry) : entry
src.entry = trim(converted_entry, max_length)
+4 -4
View File
@@ -28,7 +28,7 @@
for(var/vtype in vote_types)
votemap["[vtype]"] = vtype
var/choice = input(usr, "Select a vote type", "Vote") as null|anything in vote_types
var/choice = tgui_input_list(usr, "Select a vote type", "Vote", vote_types)
if(choice == null)
return
@@ -40,18 +40,18 @@
return
// Its custom, lets ask
var/question = input(usr, "What is the vote for?") as text|null
var/question = tgui_input_text(usr, "What is the vote for?", "Create Vote", encode = FALSE)
if(!question)
return
var/list/choices = list()
for(var/i in 1 to 10)
var/option = capitalize(input(usr, "Please enter an option or hit cancel to finish") as text|null)
var/option = tgui_input_text(usr, "Please enter an option or hit cancel to finish", "Create Vote", encode = FALSE)
if(!option || !usr.client)
break
choices |= option
var/c2 = alert(usr, "Show counts while vote is happening?", "Counts", "Yes", "No")
var/c2 = tgui_alert(usr, "Show counts while vote is happening?", "Counts", list("Yes", "No"))
var/c3 = input(usr, "Select a result calculation type", "Vote", VOTE_RESULT_TYPE_MAJORITY) as anything in list(VOTE_RESULT_TYPE_MAJORITY)
var/datum/vote/V = new /datum/vote(usr.ckey, question, choices, TRUE)