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-31 11:07:28 +13:00
committed by GitHub
parent 6162daf1cb
commit 9c6fdb567d
153 changed files with 1196 additions and 986 deletions
+1 -1
View File
@@ -124,7 +124,7 @@
/obj/structure/sign/barsign/proc/pick_sign(mob/user)
var/picked_name = tgui_input_list(user, "Available Signage", "Bar Sign", sort_list(get_bar_names()))
if(!picked_name)
if(isnull(picked_name))
return
chosen_sign = set_sign_by_name(picked_name)
SSblackbox.record_feedback("tally", "barsign_picked", 1, chosen_sign.type)
+2 -2
View File
@@ -41,8 +41,8 @@
/obj/structure/bonfire/attackby(obj/item/used_item, mob/living/user, params)
if(istype(used_item, /obj/item/stack/rods) && !can_buckle && !grill)
var/obj/item/stack/rods/rods = used_item
var/choice = input(user, "What would you like to construct?", "Bonfire") as null|anything in list("Stake","Grill")
if(!choice)
var/choice = tgui_alert(user, "What would you like to construct?", "Bonfire", list("Stake","Grill"))
if(isnull(choice))
return
rods.use(1)
switch(choice)
@@ -67,7 +67,11 @@
if(..())
return
var/list/buildlist = list("Walls and Floors" = RCD_FLOORWALL, "Airlocks" = RCD_AIRLOCK, "Deconstruction" = RCD_DECONSTRUCT, "Windows and Grilles" = RCD_WINDOWGRILLE)
var/buildmode = input(owner, "Set construction mode.", "Base Console", null) in buildlist
var/buildmode = tgui_input_list(owner, "Set construction mode", "Base Console", buildlist)
if(isnull(buildmode))
return
if(isnull(buildlist[buildmode]))
return
check_rcd()
base_console.internal_rcd.construction_mode = buildlist[buildmode]
to_chat(owner, "Build mode is now [buildmode].")
+2 -2
View File
@@ -508,14 +508,14 @@
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE)
return
var/new_price_input = input(usr,"Set the sale price for this vend-a-tray.","new price",0) as num|null
var/new_price_input = tgui_input_number(usr, "Sale price for this vend-a-tray", "New Price", 10, 1000, 1)
if(isnull(new_price_input) || (payments_acc != potential_acc.registered_account))
to_chat(usr, span_warning("[src] rejects your new price."))
return
if(!usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) )
to_chat(usr, span_warning("You need to get closer!"))
return
new_price_input = clamp(round(new_price_input, 1), 10, 1000)
new_price_input = round(new_price_input)
sale_price = new_price_input
to_chat(usr, span_notice("The cost is now set to [sale_price]."))
SStgui.update_uis(src)
@@ -51,7 +51,7 @@
/obj/structure/door_assembly/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pen))
var/t = tgui_input_text(user, "Enter the name for the door.", name, created_name, MAX_NAME_LEN)
var/t = tgui_input_text(user, "Enter the name for the door", "Airlock Renaming", created_name, MAX_NAME_LEN)
if(!t)
return
if(!in_range(src, usr) && loc != usr)
+30 -27
View File
@@ -26,34 +26,37 @@
return
if(!Adjacent(user))//no tele-grooming
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(!ishuman(user))
return
var/mob/living/carbon/human/dressing_human = user
if(H.dna && H.dna.species && (NO_UNDERWEAR in H.dna.species.species_traits))
to_chat(user, span_warning("You are not capable of wearing underwear."))
return
if(dressing_human.dna && dressing_human.dna.species && (NO_UNDERWEAR in dressing_human.dna.species.species_traits))
to_chat(user, span_warning("You are not capable of wearing underwear."))
return
var/choice = input(user, "Underwear, Undershirt, or Socks?", "Changing") as null|anything in list("Underwear","Underwear Color","Undershirt","Socks")
var/choice = tgui_input_list(user, "Underwear, Undershirt, or Socks?", "Changing", list("Underwear","Underwear Color","Undershirt","Socks"))
if(isnull(choice))
return
if(!Adjacent(user))
return
switch(choice)
if("Underwear")
var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in GLOB.underwear_list
if(new_undies)
H.underwear = new_undies
if("Underwear Color")
var/new_underwear_color = input(H, "Choose your underwear color", "Underwear Color",H.underwear_color) as color|null
if(new_underwear_color)
H.underwear_color = sanitize_hexcolor(new_underwear_color)
if("Undershirt")
var/new_undershirt = input(user, "Select your undershirt", "Changing") as null|anything in GLOB.undershirt_list
if(new_undershirt)
H.undershirt = new_undershirt
if("Socks")
var/new_socks = input(user, "Select your socks", "Changing") as null|anything in GLOB.socks_list
if(new_socks)
H.socks= new_socks
if(!Adjacent(user))
return
switch(choice)
if("Underwear")
var/new_undies = tgui_input_list(user, "Select your underwear", "Changing", GLOB.underwear_list)
if(new_undies)
dressing_human.underwear = new_undies
if("Underwear Color")
var/new_underwear_color = input(dressing_human, "Choose your underwear color", "Underwear Color", dressing_human.underwear_color) as color|null
if(new_underwear_color)
dressing_human.underwear_color = sanitize_hexcolor(new_underwear_color)
if("Undershirt")
var/new_undershirt = tgui_input_list(user, "Select your undershirt", "Changing", GLOB.undershirt_list)
if(new_undershirt)
dressing_human.undershirt = new_undershirt
if("Socks")
var/new_socks = tgui_input_list(user, "Select your socks", "Changing", GLOB.socks_list)
if(new_socks)
dressing_human.socks= new_socks
add_fingerprint(H)
H.update_body()
add_fingerprint(dressing_human)
dressing_human.update_body()
@@ -178,9 +178,10 @@
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
var/new_layer = input("Select a layer", "Layer") as null|anything in layers
if(new_layer)
target_layer = layers[new_layer]
var/new_layer = tgui_input_list(user, "Select a layer", "Layer", layers)
if(isnull(new_layer))
return
target_layer = layers[new_layer]
///A faster reinforced plunger
/obj/item/plunger/reinforced
+20 -13
View File
@@ -29,22 +29,25 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
//handle facial hair (if necessary)
if(hairdresser.gender != FEMALE)
var/new_style = input(user, "Select a facial hairstyle", "Grooming") as null|anything in GLOB.facial_hairstyles_list
var/new_style = tgui_input_list(user, "Select a facial hairstyle", "Grooming", GLOB.facial_hairstyles_list)
if(isnull(new_style))
return TRUE
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return TRUE //no tele-grooming
if(new_style)
hairdresser.facial_hairstyle = new_style
hairdresser.facial_hairstyle = new_style
else
hairdresser.facial_hairstyle = "Shaved"
//handle normal hair
var/new_style = input(user, "Select a hairstyle", "Grooming") as null|anything in GLOB.hairstyles_list
var/new_style = tgui_input_list(user, "Select a hairstyle", "Grooming", GLOB.hairstyles_list)
if(isnull(new_style))
return TRUE
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return TRUE //no tele-grooming
if(HAS_TRAIT(hairdresser, TRAIT_BALD))
to_chat(hairdresser, span_notice("If only growing back hair were that easy for you..."))
if(new_style)
hairdresser.hairstyle = new_style
hairdresser.hairstyle = new_style
hairdresser.update_hair()
@@ -130,7 +133,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
/obj/structure/mirror/magic/Initialize(mapload)
. = ..()
if(selectable_races.len)
if(length(selectable_races))
return
for(var/datum/species/species_type as anything in subtypesof(/datum/species))
if(initial(species_type.changesource_flags) & race_flags)
@@ -146,14 +149,16 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
var/mob/living/carbon/human/amazed_human = user
var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes")
var/choice = tgui_input_list(user, "Something to change?", "Magical Grooming", list("name", "race", "gender", "hair", "eyes"))
if(isnull(choice))
return TRUE
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return TRUE
switch(choice)
if("name")
var/newname = sanitize_name(stripped_input(amazed_human, "Who are we again?", "Name change", amazed_human.name, MAX_NAME_LEN), allow_numbers = TRUE) //It's magic so whatever.
var/newname = sanitize_name(tgui_input_text(amazed_human, "Who are we again?", "Name change", amazed_human.name, MAX_NAME_LEN), allow_numbers = TRUE) //It's magic so whatever.
if(!newname)
return TRUE
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
@@ -166,8 +171,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
amazed_human.mind.name = newname
if("race")
var/racechoice = input(amazed_human, "What are we again?", "Race change") as null|anything in selectable_races
if(!racechoice || !selectable_races[racechoice])
var/racechoice = tgui_input_list(amazed_human, "What are we again?", "Race change", selectable_races)
if(isnull(racechoice))
return TRUE
if(selectable_races[racechoice])
return TRUE
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return TRUE
@@ -176,7 +183,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
amazed_human.set_species(newrace, icon_update = FALSE)
if(amazed_human.dna.species.use_skintones)
var/new_s_tone = input(user, "Choose your skin tone:", "Race change") as null|anything in GLOB.skin_tones
var/new_s_tone = tgui_input_list(user, "Choose your skin tone", "Race change", GLOB.skin_tones)
if(new_s_tone)
amazed_human.skin_tone = new_s_tone
amazed_human.dna.update_ui_block(DNA_SKIN_TONE_BLOCK)
@@ -280,7 +287,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
var/turf/user_turf = get_turf(user)
var/list/levels = SSmapping.levels_by_trait(ZTRAIT_SPACE_RUINS)
var/turf/dest
if(levels.len)
if(length(levels))
dest = locate(user_turf.x, user_turf.y, pick(levels))
user_turf.ChangeTurf(/turf/open/chasm, flags = CHANGETURF_INHERIT_AIR)
@@ -98,10 +98,10 @@
if(engraved)
to_chat(user, span_warning("This plaque has already been engraved."))
return
var/namechoice = input(user, "Title this plaque. (e.g. 'Best HoP Award', 'Great Ashwalker War Memorial')", "Plaque Customization")
var/namechoice = tgui_input_text(user, "Title this plaque. (e.g. 'Best HoP Award', 'Great Ashwalker War Memorial')", "Plaque Customization", max_length = MAX_NAME_LEN)
if(!namechoice)
return
var/descriptionchoice = input(user, "Engrave this plaque's text.", "Plaque Customization")
var/descriptionchoice = tgui_input_text(user, "Engrave this plaque's text", "Plaque Customization")
if(!descriptionchoice)
return
if(!Adjacent(user)) //Make sure user is adjacent still
@@ -130,10 +130,10 @@
if(engraved)
to_chat(user, span_warning("This plaque has already been engraved."))
return
var/namechoice = input(user, "Title this plaque. (e.g. 'Best HoP Award', 'Great Ashwalker War Memorial')", "Plaque Customization")
var/namechoice = tgui_input_text(user, "Title this plaque. (e.g. 'Best HoP Award', 'Great Ashwalker War Memorial')", "Plaque Customization", max_length = MAX_NAME_LEN)
if(!namechoice)
return
var/descriptionchoice = input(user, "Engrave this plaque's text.", "Plaque Customization")
var/descriptionchoice = tgui_input_text(user, "Engrave this plaque's text", "Plaque Customization")
if(!descriptionchoice)
return
if(!Adjacent(user)) //Make sure user is adjacent still
+4 -6
View File
@@ -132,8 +132,8 @@
if(is_editable && istype(I, /obj/item/pen))
if(!length(GLOB.editable_sign_types))
CRASH("GLOB.editable_sign_types failed to populate")
var/choice = input(user, "Select a sign type.", "Sign Customization") as null|anything in GLOB.editable_sign_types
if(!choice)
var/choice = tgui_input_list(user, "Select a sign type", "Sign Customization", GLOB.editable_sign_types)
if(isnull(choice))
return
if(!Adjacent(user)) //Make sure user is adjacent still.
to_chat(user, span_warning("You need to stand next to the sign to change it!"))
@@ -160,14 +160,12 @@
if(is_editable && istype(I, /obj/item/pen))
if(!length(GLOB.editable_sign_types))
CRASH("GLOB.editable_sign_types failed to populate")
var/choice = input(user, "Select a sign type.", "Sign Customization") as null|anything in GLOB.editable_sign_types
if(!choice)
var/choice = tgui_input_list(user, "Select a sign type", "Sign Customization", GLOB.editable_sign_types)
if(isnull(choice))
return
if(!Adjacent(user)) //Make sure user is adjacent still.
to_chat(user, span_warning("You need to stand next to the sign to change it!"))
return
if(!choice)
return
user.visible_message(span_notice("You begin changing [src]."))
if(!do_after(user, 4 SECONDS, target = src))
return
+4 -2
View File
@@ -34,8 +34,10 @@
virgin = FALSE
notify_ghosts("Someone has begun playing with a [src.name] in [get_area(src)]!", source = src, header = "Spirit board")
planchette = input("Choose the letter.", "Seance!") as null|anything in list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
if(!planchette || !Adjacent(M) || next_use > world.time)
planchette = tgui_input_list(M, "Choose the letter.", "Seance!", list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"))
if(isnull(planchette))
return
if(!Adjacent(M) || next_use > world.time)
return
M.log_message("picked a letter on [src], which was \"[planchette]\".", LOG_GAME)
next_use = world.time + rand(30,50)
@@ -245,7 +245,7 @@
ae.forceMove(drop_location())
else if(istype(W, /obj/item/pen))
var/t = tgui_input_text(user, "Enter the name for the door.", "Windoor", created_name, MAX_NAME_LEN)
var/t = tgui_input_text(user, "Enter the name for the door", "Windoor Renaming", created_name, MAX_NAME_LEN)
if(!t)
return
if(!in_range(src, usr) && loc != usr)