TGUI list conversions + bug fixes (#63354)

About The Pull Request

    Converts more inputs to TGUI. Possibly all user-facing input lists in the game.
    Did any surrounding text/number inputs as well
    Added null choice support so users can press cancel.
    Added some misc TGUI input fixes
    Fixed custom vendors while I was there

I refactored a lot of code while just poking around.
Primarily, usage of .len in files where I was already working on lists.
Some code was just awful - look at guardian.dm and its non use of early returns
If there are any disputes, I can revert it just fine, those changes are not integral to the PR.
Why It's Good For The Game

Fixes #63629
Fixes #63307
Fixes custom vendors /again/
Text input is more performant.
Part of a long series of TGUI conversion to make the game more visually appealing
Changelog

cl
refactor: The majority of user facing input lists have been converted to TGUI.
refactor: Tgui text inputs now scale with entered input.
fix: Many inputs now properly accept cancelling out of the menu.
fix: Fixes an edge case where users could not press enter on number inputs.
fix: Custom vendor bluescreen.
fix: You can now press ENTER on text inputs without an entry to cancel.
/cl
This commit is contained in:
Jeremiah
2021-12-30 14:07:28 -08:00
committed by GitHub
parent 6162daf1cb
commit 9c6fdb567d
153 changed files with 1196 additions and 986 deletions
+3 -2
View File
@@ -44,8 +44,9 @@
var/list/combined = sort_list(logs_present) + sort_list(logs_missing)
var/selected = input("Investigate what?", "Investigate") as null|anything in combined
var/selected = tgui_input_list(src, "Investigate what?", "Investigation", combined)
if(isnull(selected))
return
if(!(selected in combined) || selected == "---")
return
+4 -4
View File
@@ -490,12 +490,12 @@ GLOBAL_PROTECT(admin_verbs_hideable)
set desc = "Cause an explosion of varying strength at your location."
var/list/choices = list("Small Bomb (1, 2, 3, 3)", "Medium Bomb (2, 3, 4, 4)", "Big Bomb (3, 5, 7, 5)", "Maxcap", "Custom Bomb")
var/choice = tgui_input_list(usr, "What size explosion would you like to produce? NOTE: You can do all this rapidly and in an IC manner (using cruise missiles!) with the Config/Launch Supplypod verb. WARNING: These ignore the maxcap", "Drop Bomb", choices)
var/choice = tgui_input_list(src, "What size explosion would you like to produce? NOTE: You can do all this rapidly and in an IC manner (using cruise missiles!) with the Config/Launch Supplypod verb. WARNING: These ignore the maxcap", "Drop Bomb", choices)
if(isnull(choice))
return
var/turf/epicenter = mob.loc
switch(choice)
if(null)
return
if("Small Bomb (1, 2, 3, 3)")
explosion(epicenter, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 3, flash_range = 3, adminlog = TRUE, ignorecap = TRUE, explosion_cause = mob)
if("Medium Bomb (2, 3, 4, 4)")
@@ -779,7 +779,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
candidates = get_area_turfs(area)
if (candidates.len)
if (length(candidates))
k = 100
do
+7 -3
View File
@@ -167,7 +167,7 @@
if(suit)
suit = new suit //initial() doesn't like lists
options = suit.allowed
if(!options.len) //nothing will happen, but don't let the user think it's broken
if(!length(options)) //nothing will happen, but don't let the user think it's broken
to_chat(owner, span_warning("No options available for the current suit."))
if("belt")
@@ -189,8 +189,12 @@
if("r_pocket")
choose_any_item(slot)
if(length(options))
set_item(slot, tgui_input_list(owner, "Choose an item", OUTFIT_EDITOR_NAME, options))
if(!length(options))
return
var/option = tgui_input_list(owner, "Choose an item", OUTFIT_EDITOR_NAME, options)
if(isnull(option))
return
set_item(slot, option)
#undef OUTFIT_EDITOR_NAME
+5 -2
View File
@@ -58,8 +58,11 @@
owner.holder.load_outfit(owner.mob)
if("copy")
var/datum/outfit/outfit = tgui_input_list(owner, "Pick an outfit to copy from", "Outfit Manager", subtypesof(/datum/outfit))
if(ispath(outfit))
owner.open_outfit_editor(new outfit)
if(isnull(outfit))
return
if(!ispath(outfit))
return
owner.open_outfit_editor(new outfit)
var/datum/outfit/target_outfit = locate(params["outfit"])
if(!istype(target_outfit))
@@ -14,7 +14,9 @@
var/random_appearance
/datum/smite/custom_imaginary_friend/configure(client/user)
friend_candidate_client = tgui_input_list(user, "Pick the player to put in control.", "New Imaginary Friend", sort_list(GLOB.clients))
friend_candidate_client = tgui_input_list(user, "Pick the player to put in control", "New Imaginary Friend", sort_list(GLOB.clients))
if(isnull(friend_candidate_client))
return
if(QDELETED(friend_candidate_client))
to_chat(user, span_notice("Selected player no longer has a client, aborting."))
+1 -1
View File
@@ -1542,7 +1542,7 @@
if(!check_rights(R_ADMIN))
return
var/list/type_choices = typesof(/datum/station_goal)
var/picked = tgui_input_list(usr, "Choose goal type",, type_choices)
var/picked = tgui_input_list(usr, "Choose goal type", "Station Goal", type_choices)
if(!picked)
return
var/datum/station_goal/G = new picked()
@@ -322,13 +322,14 @@ GLOBAL_LIST_INIT_TYPED(sdql_spells, /obj/effect/proc_holder/spell, list())
saved_vars[params["name"]] = !saved_vars[params["name"]]
if("path_variable")
var/new_path = tgui_input_list(user, "Select type.", "Add SDQL Spell", typesof(text2path(params["root_path"])))
if(new_path)
saved_vars[params["name"]] = new_path
var/datum/sample = new new_path
var/list/overrides = list_vars[special_var_lists[params["name"]]]
overrides = overrides&sample.vars
qdel(sample)
icon_needs_updating(params["name"])
if(isnull(new_path))
return
saved_vars[params["name"]] = new_path
var/datum/sample = new new_path
var/list/overrides = list_vars[special_var_lists[params["name"]]]
overrides = overrides&sample.vars
qdel(sample)
icon_needs_updating(params["name"])
if("list_variable_add")
if(!list_vars[params["list"]])
list_vars[params["list"]] = list()
+18 -13
View File
@@ -153,21 +153,26 @@
usr.forceMove(M.loc)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/sendmob(mob/M in sort_mobs())
/client/proc/sendmob(mob/jumper in sort_mobs())
set category = "Admin.Game"
set name = "Send Mob"
if(!src.holder)
to_chat(src, "Only administrators may use this command.", confidential = TRUE)
return
var/area/A = input(usr, "Pick an area.", "Pick an area") in GLOB.sortedAreas|null
if(A && istype(A))
var/list/turfs = get_area_turfs(A)
if(length(turfs) && M.forceMove(pick(turfs)))
log_admin("[key_name(usr)] teleported [key_name(M)] to [AREACOORD(M)]")
var/msg = "[key_name_admin(usr)] teleported [ADMIN_LOOKUPFLW(M)] to [AREACOORD(M)]"
message_admins(msg)
admin_ticket_log(M, msg)
else
to_chat(src, "Failed to move mob to a valid location.", confidential = TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Send Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(!length(GLOB.sortedAreas))
to_chat(src, "No areas found.", confidential = TRUE)
return
var/area/target_area = tgui_input_list(src, "Pick an area", "Send Mob", GLOB.sortedAreas)
if(isnull(target_area))
return
if(!istype(target_area))
return
var/list/turfs = get_area_turfs(target_area)
if(length(turfs) && jumper.forceMove(pick(turfs)))
log_admin("[key_name(usr)] teleported [key_name(jumper)] to [AREACOORD(jumper)]")
var/msg = "[key_name_admin(usr)] teleported [ADMIN_LOOKUPFLW(jumper)] to [AREACOORD(jumper)]"
message_admins(msg)
admin_ticket_log(jumper, msg)
else
to_chat(src, "Failed to move mob to a valid location.", confidential = TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Send Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+6 -5
View File
@@ -84,11 +84,12 @@
return
switch (action)
if ("set_charge")
var/newcharge = input("New charge (0-[borg.cell.maxcharge]):", borg.name, borg.cell.charge) as num|null
if (newcharge)
borg.cell.charge = clamp(newcharge, 0, borg.cell.maxcharge)
message_admins("[key_name_admin(user)] set the charge of [ADMIN_LOOKUPFLW(borg)] to [borg.cell.charge].")
log_silicon("[key_name(user)] set the charge of [key_name(borg)] to [borg.cell.charge].")
var/newcharge = tgui_input_number(usr, "Set new charge", borg.name, borg.cell.charge, borg.cell.maxcharge)
if (isnull(newcharge))
return
borg.cell.charge = clamp(newcharge, 0, borg.cell.maxcharge)
message_admins("[key_name_admin(user)] set the charge of [ADMIN_LOOKUPFLW(borg)] to [borg.cell.charge].")
log_silicon("[key_name(user)] set the charge of [key_name(borg)] to [borg.cell.charge].")
if ("remove_cell")
QDEL_NULL(borg.cell)
message_admins("[key_name_admin(user)] deleted the cell of [ADMIN_LOOKUPFLW(borg)].")
+5 -3
View File
@@ -57,7 +57,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(C.key)
available.Add(C)
var/mob/choice = tgui_input_list(usr, "Choose a player to play the pAI", "Spawn pAI", sort_names(available))
if(!choice)
if(isnull(choice))
return
if(!isobserver(choice))
var/confirm = tgui_alert(usr, "[choice.key] isn't ghosting right now. Are you sure you want to yank them out of their body and place them in this pAI?", "Spawn pAI Confirmation", list("Yes", "No"))
@@ -534,8 +534,10 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
set category = "Debug"
set name = "Debug Mob Lists"
set desc = "For when you just gotta know"
switch(tgui_input_list(usr, "Which list?",, list("Players","Admins","Mobs","Living Mobs","Dead Mobs","Clients","Joined Clients")))
var/chosen_list = tgui_input_list(usr, "Which list?", "Select List", list("Players","Admins","Mobs","Living Mobs","Dead Mobs","Clients","Joined Clients"))
if(isnull(chosen_list))
return
switch(chosen_list)
if("Players")
to_chat(usr, jointext(GLOB.player_list,","), confidential = TRUE)
if("Admins")
+14 -10
View File
@@ -1,8 +1,8 @@
/client/proc/manipulate_organs(mob/living/carbon/C in world)
set name = "Manipulate Organs"
set category = "Debug"
var/operation = input("Select organ operation.", "Organ Manipulation", "cancel") as null|anything in list("add organ", "add implant", "drop organ/implant", "remove organ/implant", "cancel")
if (!operation)
var/operation = tgui_input_list(usr, "Select organ operation", "Organ Manipulation", list("add organ", "add implant", "drop organ/implant", "remove organ/implant"))
if (isnull(operation))
return
var/list/organs = list()
@@ -12,8 +12,10 @@
var/dat = replacetext("[path]", "/obj/item/organ/", ":")
organs[dat] = path
var/obj/item/organ/organ = input("Select organ type:", "Organ Manipulation", null) as null|anything in organs
if(!organ)
var/obj/item/organ/organ = tgui_input_list(usr, "Select organ type", "Organ Manipulation", organs)
if(isnull(organ))
return
if(isnull(organs[organ]))
return
organ = organs[organ]
organ = new organ
@@ -26,8 +28,10 @@
var/dat = replacetext("[path]", "/obj/item/implant/", ":")
organs[dat] = path
var/obj/item/implant/organ = input("Select implant type:", "Organ Manipulation", null) as null|anything in organs
if(!organ)
var/obj/item/implant/organ = tgui_input_list(usr, "Select implant type", "Organ Manipulation", organs)
if(isnull(organ))
return
if(isnull(organs[organ]))
return
organ = organs[organ]
organ = new organ
@@ -44,12 +48,12 @@
var/obj/item/implant/I = X
organs["[I.name] ([I.type])"] = I
var/obj/item/organ = input("Select organ/implant:", "Organ Manipulation", null) as null|anything in organs
if(!organ)
var/obj/item/organ = tgui_input_list(usr, "Select organ/implant", "Organ Manipulation", organs)
if(isnull(organ))
return
if(isnull(organs[organ]))
return
organ = organs[organ]
if(!organ)
return
var/obj/item/organ/O
var/obj/item/implant/I
+1 -1
View File
@@ -33,7 +33,7 @@
maprotatechoices[mapname] = VM
var/chosenmap = tgui_input_list(usr, "Choose a map to change to", "Change Map", sort_list(maprotatechoices)|"Custom")
if (!chosenmap)
if (isnull(chosenmap))
return
if(chosenmap == "Custom")
+4 -4
View File
@@ -24,8 +24,8 @@
options += "Delete Shuttle"
options += "Into The Sunset (delete & greentext 'escape')"
var/selection = input(user, "Select where to fly [name || id]:", "Fly Shuttle") as null|anything in options
if(!selection)
var/selection = tgui_input_list(user, "Select where to fly [name || id]:", "Fly Shuttle", options)
if(isnull(selection))
return
switch(selection)
@@ -67,8 +67,8 @@
if (canDock(S) == SHUTTLE_CAN_DOCK)
options[S.name || S.id] = S
var/selection = input(user, "Select the new arrivals destination:", "Fly Shuttle") as null|anything in options
if(!selection)
var/selection = tgui_input_list(user, "New arrivals destination", "Fly Shuttle", options)
if(isnull(selection))
return
target_dock = options[selection]
if(!QDELETED(target_dock))
@@ -62,7 +62,9 @@
names += "---Elements---"
names += sort_list(subtypesof(/datum/element), /proc/cmp_typepaths_asc)
var/result = tgui_input_list(usr, "Choose a component/element to add", "Add Component", names)
if(!usr || !result || result == "---Components---" || result == "---Elements---")
if(isnull(result))
return
if(!usr || result == "---Components---" || result == "---Elements---")
return
if(QDELETED(src))
to_chat(usr, "That thing doesn't exist anymore!", confidential = TRUE)
@@ -100,7 +102,9 @@
// We have to list every element here because there is no way to know what element is on this object without doing some sort of hack.
names += sort_list(subtypesof(/datum/element), /proc/cmp_typepaths_asc)
var/path = tgui_input_list(usr, "Choose a component/element to remove. All elements listed here may not be on the datum.", "Remove element", names)
if(!usr || !path || path == "---Components---" || path == "---Elements---")
if(isnull(path))
return
if(!usr || path == "---Components---" || path == "---Elements---")
return
if(QDELETED(src))
to_chat(usr, "That thing doesn't exist anymore!")