From 11fbb59049730f731396d2dfc1b7fbaa062cf793 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Mon, 30 Mar 2026 03:47:29 +0200 Subject: [PATCH] TGUIfies some VV actions, replaces the actions dropdown with a searchable one (#95480) --- code/__DEFINES/vv.dm | 2 +- code/datums/datumvars.dm | 1 - code/datums/outfit.dm | 4 +- code/datums/weakrefs.dm | 3 +- code/game/atom/atom_vv.dm | 98 +++++++--------- code/game/atoms_movable.dm | 8 +- code/game/objects/objs.dm | 2 +- code/modules/admin/admin_verbs.dm | 10 +- code/modules/admin/verbs/debug.dm | 16 +-- .../modules/admin/verbs/grant_dna_infusion.dm | 2 +- code/modules/admin/verbs/manipulate_organs.dm | 15 +-- .../debug_variable_appearance.dm | 2 +- .../admin/view_variables/view_variables.dm | 46 ++++++-- .../events/space_vines/vine_controller.dm | 3 +- code/modules/mob/living/carbon/carbon.dm | 107 ++++++++++-------- code/modules/mob/living/carbon/human/human.dm | 69 +++++------ code/modules/mob/living/living.dm | 14 +-- code/modules/mob/mob.dm | 10 +- code/modules/power/singularity/narsie.dm | 4 +- html/admin/view_variables.css | 85 ++++++++++---- 20 files changed, 274 insertions(+), 227 deletions(-) diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index 5ad65cbc4df..eae9769003f 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -53,7 +53,7 @@ #define VV_TOPIC_LINK(datum, href_key, text) "text" //Helpers for vv_get_dropdown() -#define VV_DROPDOWN_OPTION(href_key, name) . += "" +#define VV_DROPDOWN_OPTION(href_key, name) . += "[name]" // VV HREF KEYS #define VV_HK_TARGET "target" diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 536fb1e0529..55d8e28b197 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -38,7 +38,6 @@ GLOBAL_LIST_INIT(vv_var_blacklist, list( SHOULD_CALL_PARENT(TRUE) . = list() - VV_DROPDOWN_OPTION("", "---") VV_DROPDOWN_OPTION(VV_HK_CALLPROC, "Call Proc") VV_DROPDOWN_OPTION(VV_HK_MARK, "Mark Object") VV_DROPDOWN_OPTION(VV_HK_TAG, "Tag Datum") diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm index 44d47bb11cd..d1290292ddd 100644 --- a/code/datums/outfit.dm +++ b/code/datums/outfit.dm @@ -518,7 +518,7 @@ /datum/outfit/vv_get_dropdown() . = ..() - VV_DROPDOWN_OPTION("", "---") + VV_DROPDOWN_OPTION("", "--- /outfit ---") VV_DROPDOWN_OPTION(VV_HK_TO_OUTFIT_EDITOR, "Outfit Editor") /datum/outfit/vv_do_topic(list/href_list) @@ -528,6 +528,4 @@ return if(href_list[VV_HK_TO_OUTFIT_EDITOR]) - if(!check_rights(NONE)) - return usr.client.open_outfit_editor(src) diff --git a/code/datums/weakrefs.dm b/code/datums/weakrefs.dm index eaeea94b3c3..757e7adf596 100644 --- a/code/datums/weakrefs.dm +++ b/code/datums/weakrefs.dm @@ -96,6 +96,7 @@ /datum/weakref/vv_get_dropdown() . = ..() + VV_DROPDOWN_OPTION("", "--- /weakref ---") VV_DROPDOWN_OPTION(VV_HK_WEAKREF_RESOLVE, "Go to reference") /datum/weakref/vv_do_topic(list/href_list) @@ -105,8 +106,6 @@ return if(href_list[VV_HK_WEAKREF_RESOLVE]) - if(!check_rights(NONE)) - return var/datum/R = resolve() if(R) usr.client.debug_variables(R) diff --git a/code/game/atom/atom_vv.dm b/code/game/atom/atom_vv.dm index d9600d4bae9..85d7ed011c7 100644 --- a/code/game/atom/atom_vv.dm +++ b/code/game/atom/atom_vv.dm @@ -5,11 +5,11 @@ */ /atom/vv_get_dropdown() . = ..() - VV_DROPDOWN_OPTION("", "---------") + VV_DROPDOWN_OPTION("", "--- /atom ---") if(!ismovable(src)) var/turf/curturf = get_turf(src) if(curturf) - . += "" + . += "Jump To" VV_DROPDOWN_OPTION(VV_HK_MODIFY_TRANSFORM, "Modify Transform") VV_DROPDOWN_OPTION(VV_HK_SPIN_ANIMATION, "SpinAnimation") VV_DROPDOWN_OPTION(VV_HK_STOP_ALL_ANIMATIONS, "Stop All Animations") @@ -32,39 +32,44 @@ return if(href_list[VV_HK_ADD_REAGENT]) - if(!check_rights(R_VAREDIT)) - return if(!reagents) - var/amount = input(usr, "Specify the reagent size of [src]", "Set Reagent Size", 50) as num|null - if(amount) - create_reagents(amount) - if(reagents) - var/chosen_id - switch(tgui_alert(usr, "Choose a method.", "Add Reagents", list("Search", "Choose from a list", "I'm feeling lucky"))) - if("Search") - var/valid_id - while(!valid_id) - chosen_id = input(usr, "Enter the ID of the reagent you want to add.", "Search reagents") as null|text - if(isnull(chosen_id)) //Get me out of here! - break - if (!ispath(text2path(chosen_id))) - chosen_id = pick_closest_path(chosen_id, make_types_fancy(subtypesof(/datum/reagent))) - if (ispath(chosen_id)) - valid_id = TRUE - else + var/amount = tgui_input_number(usr, "Specify the reagent size of [src]", "Set Reagent Size", 50) + if(!amount) + return + create_reagents(amount) + + if(!reagents) + return + + var/chosen_id + switch(tgui_alert(usr, "Choose a method.", "Add Reagents", list("Search", "Choose from a list", "I'm feeling lucky"))) + if("Search") + var/valid_id + while(!valid_id) + chosen_id = tgui_input_text(usr, "Enter the ID of the reagent you want to add.", "Search reagents") + if(isnull(chosen_id)) //Get me out of here! + break + if (!ispath(text2path(chosen_id))) + chosen_id = pick_closest_path(chosen_id, make_types_fancy(subtypesof(/datum/reagent))) + if (ispath(chosen_id)) valid_id = TRUE - if(!valid_id) - to_chat(usr, span_warning("A reagent with that ID doesn't exist!")) - if("Choose from a list") - chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in sort_list(subtypesof(/datum/reagent), GLOBAL_PROC_REF(cmp_typepaths_asc)) - if("I'm feeling lucky") - chosen_id = pick(subtypesof(/datum/reagent)) - if(chosen_id) - var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", reagents.maximum_volume) as num|null - if(amount) - reagents.add_reagent(chosen_id, amount) - log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to [src]") - message_admins(span_notice("[key_name(usr)] has added [amount] units of [chosen_id] to [src]")) + else + valid_id = TRUE + if(!valid_id) + to_chat(usr, span_warning("A reagent with that ID doesn't exist!")) + if("Choose from a list") + chosen_id = tgui_input_list(usr, "Choose a reagent to add.", "Choose a reagent.", sort_list(subtypesof(/datum/reagent), GLOBAL_PROC_REF(cmp_typepaths_asc))) + if("I'm feeling lucky") + chosen_id = pick(subtypesof(/datum/reagent)) + + if(!chosen_id) + return + var/amount = tgui_input_number(usr, "Choose the amount to add.", "Choose the amount.", reagents.maximum_volume - reagents.total_volume, reagents.maximum_volume) + if(!amount) + return + reagents.add_reagent(chosen_id, amount) + log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to [src]") + message_admins(span_notice("[key_name(usr)] has added [amount] units of [chosen_id] to [src]")) if(href_list[VV_HK_TRIGGER_EXPLOSION]) return SSadmin_verbs.dynamic_invoke_verb(usr, /datum/admin_verb/admin_explosion, src) @@ -78,8 +83,6 @@ usr.client.cmd_show_hiddenprints(src) if(href_list[VV_HK_ARMOR_MOD]) - if(!check_rights(NONE)) - return var/list/picker_list = list() var/list/armor_list = get_armor().get_rating_list() for (var/rating in armor_list) @@ -106,16 +109,11 @@ message_admins(span_notice(message)) if(href_list[VV_HK_ADD_AI]) - if(!check_rights(R_VAREDIT)) - return - var/result = input(usr, "Choose the AI controller to apply to this atom WARNING: Not all AI works on all atoms.", "AI controller") as null|anything in subtypesof(/datum/ai_controller) - if(!result) - return - ai_controller = new result(src) + var/result = tgui_input_list(usr, "Choose the AI controller to apply to this atom WARNING: Not all AI works on all atoms.", "AI controller", sort_list(subtypesof(/datum/ai_controller), GLOBAL_PROC_REF(cmp_typepaths_asc))) + if(result) + ai_controller = new result(src) if(href_list[VV_HK_MODIFY_TRANSFORM]) - if(!check_rights(R_VAREDIT)) - return var/result = input(usr, "Choose the transformation to apply","Transform Mod") as null|anything in list("Scale","Translate","Rotate","Shear") var/matrix/M = transform if(!result) @@ -147,8 +145,6 @@ SEND_SIGNAL(src, COMSIG_ATOM_VV_MODIFY_TRANSFORM) if(href_list[VV_HK_SPIN_ANIMATION]) - if(!check_rights(R_VAREDIT)) - return var/num_spins = input(usr, "Do you want infinite spins?", "Spin Animation") in list("Yes", "No") if(num_spins == "No") num_spins = input(usr, "How many spins?", "Spin Animation") as null|num @@ -170,34 +166,26 @@ SpinAnimation(1 SECONDS / spins_per_sec, num_spins, direction) if(href_list[VV_HK_STOP_ALL_ANIMATIONS]) - if(!check_rights(R_VAREDIT)) - return + // Critical: Needs to be accessible in case of animation spam breaking shit + // Do not TGUIfy var/result = input(usr, "Are you sure?", "Stop Animating") in list("Yes", "No") if(result == "Yes") animate(src, transform = null, flags = ANIMATION_END_NOW) // Literally just fucking stop animating entirely because admin said so return if(href_list[VV_HK_AUTO_RENAME]) - if(!check_rights(R_VAREDIT)) - return var/newname = input(usr, "What do you want to rename this to?", "Automatic Rename") as null|text // Check the new name against the chat filter. If it triggers the IC chat filter, give an option to confirm. if(newname && !(is_ic_filtered(newname) || is_soft_ic_filtered(newname) && tgui_alert(usr, "Your selected name contains words restricted by IC chat filters. Confirm this new name?", "IC Chat Filter Conflict", list("Confirm", "Cancel")) != "Confirm")) vv_auto_rename(newname) if(href_list[VV_HK_EDIT_FILTERS]) - if(!check_rights(R_VAREDIT)) - return usr.client?.open_filter_editor(src) if(href_list[VV_HK_EDIT_COLOR_MATRIX]) - if(!check_rights(R_VAREDIT)) - return usr.client?.open_color_matrix_editor(src) if(href_list[VV_HK_TEST_MATRIXES]) - if(!check_rights(R_VAREDIT)) - return usr.client?.open_matrix_tester(src) /atom/vv_get_header() diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 14b4fa73ba8..509cbfa2d31 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1729,7 +1729,7 @@ /atom/movable/vv_get_dropdown() . = ..() - VV_DROPDOWN_OPTION("", "---------") + VV_DROPDOWN_OPTION("", "--- /movable ---") VV_DROPDOWN_OPTION(VV_HK_OBSERVE_FOLLOW, "Observe Follow") VV_DROPDOWN_OPTION(VV_HK_GET_MOVABLE, "Get Movable") VV_DROPDOWN_OPTION(VV_HK_GET_FACTIONS, "Get Factions") @@ -1773,11 +1773,13 @@ var/list/factions_printout = faction_to_text() to_chat(usr, span_notice(span_notice("Factions for [src]:[factions_printout]"))) - if(href_list[VV_HK_EDIT_PARTICLES] && check_rights(R_VAREDIT)) + if(href_list[VV_HK_EDIT_PARTICLES]) var/client/C = usr.client C?.open_particle_editor(src) - if(href_list[VV_HK_DEADCHAT_PLAYS] && check_rights(R_FUN)) + if(href_list[VV_HK_DEADCHAT_PLAYS]) + if(!check_rights(R_FUN)) + return if(tgui_alert(usr, "Allow deadchat to control [src] via chat commands?", "Deadchat Plays [src]", list("Allow", "Cancel")) != "Allow") return // Alert is async, so quick sanity check to make sure we should still be doing this. diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index dec12fee636..3e572f7fb2e 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -168,7 +168,7 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) /obj/vv_get_dropdown() . = ..() - VV_DROPDOWN_OPTION("", "---") + VV_DROPDOWN_OPTION("", "--- /obj ---") VV_DROPDOWN_OPTION(VV_HK_MASS_DEL_TYPE, "Delete all of type") VV_DROPDOWN_OPTION(VV_HK_OSAY, "Object Say") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 5704a111195..ab95cad4f11 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -421,13 +421,13 @@ ADMIN_VERB(remove_spell, R_FUN, "Remove Spell", ADMIN_VERB_NO_DESCRIPTION, ADMIN BLACKBOX_LOG_ADMIN_VERB("Remove Spell") ADMIN_VERB(give_disease, R_FUN, "Give Disease", ADMIN_VERB_NO_DESCRIPTION, ADMIN_CATEGORY_HIDDEN, mob/living/victim) - var/datum/disease/D = input(user, "Choose the disease to give to that guy", "ACHOO") as null|anything in sort_list(SSdisease.diseases, GLOBAL_PROC_REF(cmp_typepaths_asc)) - if(!D) + var/datum/disease/disease = tgui_input_list(user, "Choose the disease to give to that guy", "ACHOO", sort_list(SSdisease.diseases, GLOBAL_PROC_REF(cmp_typepaths_asc))) + if(!disease) return - victim.ForceContractDisease(new D, FALSE, TRUE) + victim.ForceContractDisease(new disease, FALSE, TRUE) BLACKBOX_LOG_ADMIN_VERB("Give Disease") - log_admin("[key_name(user)] gave [key_name(victim)] the disease [D].") - message_admins(span_adminnotice("[key_name_admin(user)] gave [key_name_admin(victim)] the disease [D].")) + log_admin("[key_name(user)] gave [key_name(victim)] the disease [disease].") + message_admins(span_adminnotice("[key_name_admin(user)] gave [key_name_admin(victim)] the disease [disease].")) ADMIN_VERB_AND_CONTEXT_MENU(object_say, R_FUN, "OSay", ADMIN_VERB_NO_DESCRIPTION, ADMIN_CATEGORY_HIDDEN, obj/speaker in world) var/message = tgui_input_text(user, "What do you want the message to be?", "Make Sound", encode = FALSE) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index c0782a5bf4c..ce68cf4be71 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -181,7 +181,7 @@ ADMIN_VERB(cmd_give_direct_control, R_ADMIN, "Give Direct Control", "Give direct if(M.ckey) if(tgui_alert(user,"This mob is being controlled by [M.key]. Are you sure you wish to give someone else control of it? [M.key] will be made a ghost.",,list("Yes","No")) != "Yes") return - var/client/newkey = input(user, "Pick the player to put in control.", "New player") as null|anything in sort_list(GLOB.clients) + var/client/newkey = tgui_input_list(user, "Pick the player to put in control.", "New player", sort_list(GLOB.clients)) if(isnull(newkey)) return var/mob/oldmob = newkey.mob @@ -413,7 +413,7 @@ ADMIN_VERB(cmd_admin_areatest_all, R_DEBUG, "Test Areas (ALL)", "Tests the areas var/datum/outfit/O = path //not much to initalize here but whatever outfits[initial(O.name)] = path - var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in baseoutfits + sort_list(outfits) + var/dresscode = tgui_input_list(usr, "Select outfit", "Robust quick dress shop", baseoutfits + sort_list(outfits, GLOBAL_PROC_REF(cmp_typepaths_asc))) if (isnull(dresscode)) return @@ -427,7 +427,7 @@ ADMIN_VERB(cmd_admin_areatest_all, R_DEBUG, "Test Areas (ALL)", "Tests the areas var/datum/outfit/O = path job_outfits[initial(O.name)] = path - dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in sort_list(job_outfits) + dresscode = tgui_input_list(usr, "Select job equipment", "Robust quick dress shop", sort_list(job_outfits, GLOBAL_PROC_REF(cmp_typepaths_asc))) dresscode = job_outfits[dresscode] if(isnull(dresscode)) return @@ -439,7 +439,7 @@ ADMIN_VERB(cmd_admin_areatest_all, R_DEBUG, "Test Areas (ALL)", "Tests the areas var/datum/outfit/O = path plasmaman_outfits[initial(O.name)] = path - dresscode = input("Select plasmeme equipment", "Robust quick dress shop") as null|anything in sort_list(plasmaman_outfits) + dresscode = tgui_input_list(usr, "Select plasmeme equipment", "Robust quick dress shop", sort_list(plasmaman_outfits, GLOBAL_PROC_REF(cmp_typepaths_asc))) dresscode = plasmaman_outfits[dresscode] if(isnull(dresscode)) return @@ -448,7 +448,7 @@ ADMIN_VERB(cmd_admin_areatest_all, R_DEBUG, "Test Areas (ALL)", "Tests the areas var/list/custom_names = list() for(var/datum/outfit/D in GLOB.custom_outfits) custom_names[D.name] = D - var/selected_name = input("Select outfit", "Robust quick dress shop") as null|anything in sort_list(custom_names) + var/selected_name = tgui_input_list(usr, "Select outfit", "Robust quick dress shop", sort_list(custom_names, GLOBAL_PROC_REF(cmp_typepaths_asc))) dresscode = custom_names[selected_name] if(isnull(dresscode)) return @@ -621,12 +621,12 @@ ADMIN_VERB(place_ruin, R_DEBUG, "Spawn Ruin", "Attempt to randomly place a speci return var/datum/map_template/ruin/template = data[1] if (exists[template]) - var/response = tgui_alert(user,"There is already a [template] in existence.", "Spawn Ruin", list("Jump", "Place Another", "Cancel")) + var/response = tgui_alert(user,"There is already a [template] in existence.", "Spawn Ruin", list("Jump", "Place Another")) + if (!response) + return if (response == "Jump") user.mob.forceMove(get_turf(exists[template])) return - else if (response == "Cancel") - return var/len = GLOB.ruin_landmarks.len seedRuins(SSmapping.levels_by_trait(data[2]), max(1, template.cost), data[3], list(ruinname = template)) diff --git a/code/modules/admin/verbs/grant_dna_infusion.dm b/code/modules/admin/verbs/grant_dna_infusion.dm index 2e087a16057..d761e47ad94 100644 --- a/code/modules/admin/verbs/grant_dna_infusion.dm +++ b/code/modules/admin/verbs/grant_dna_infusion.dm @@ -8,7 +8,7 @@ set category = "Debug" var/list/infusions = list() - for(var/datum/infuser_entry/path as anything in subtypesof(/datum/infuser_entry)) + for(var/datum/infuser_entry/path as anything in sort_list(subtypesof(/datum/infuser_entry), GLOBAL_PROC_REF(cmp_typepaths_asc))) var/str = "[initial(path.name)] ([path])" infusions[str] = path diff --git a/code/modules/admin/verbs/manipulate_organs.dm b/code/modules/admin/verbs/manipulate_organs.dm index 6c0a86126b6..59c6e4983d7 100644 --- a/code/modules/admin/verbs/manipulate_organs.dm +++ b/code/modules/admin/verbs/manipulate_organs.dm @@ -1,13 +1,14 @@ ADMIN_VERB_VISIBILITY(manipulate_organs, ADMIN_VERB_VISIBLITY_FLAG_MAPPING_DEBUG) ADMIN_VERB(manipulate_organs, R_DEBUG, "Manipulate Organs", "Manipulate the organs of a living carbon.", ADMIN_CATEGORY_DEBUG, mob/living/carbon/carbon_victim in world) - var/operation = tgui_input_list(user, "Select organ operation", "Organ Manipulation", list("add organ", "add implant", "drop organ/implant", "remove organ/implant")) + var/operation = tgui_input_list(user, "Select organ operation", "Organ Manipulation", list("Add organ", "Add implant", "Drop organ/implant", "Remove organ/implant")) if (isnull(operation)) return var/list/organs = list() switch(operation) - if("add organ") - for(var/path in subtypesof(/obj/item/organ)) + if("Add organ") + // BYOND actually cares about order of addition in assoc lists, as long as its not an alist + for(var/path in sort_list(subtypesof(/obj/item/organ), GLOBAL_PROC_REF(cmp_typepaths_asc))) var/dat = replacetext("[path]", "/obj/item/organ/", ":") organs[dat] = path @@ -22,8 +23,8 @@ ADMIN_VERB(manipulate_organs, R_DEBUG, "Manipulate Organs", "Manipulate the orga log_admin("[key_name(user)] has added organ [organ_to_grant.type] to [key_name(carbon_victim)]") message_admins("[key_name_admin(user)] has added organ [organ_to_grant.type] to [ADMIN_LOOKUPFLW(carbon_victim)]") - if("add implant") - for(var/path in subtypesof(/obj/item/implant)) + if("Add implant") + for(var/path in sort_list(subtypesof(/obj/item/implant), GLOBAL_PROC_REF(cmp_typepaths_asc))) var/dat = replacetext("[path]", "/obj/item/implant/", ":") organs[dat] = path @@ -41,7 +42,7 @@ ADMIN_VERB(manipulate_organs, R_DEBUG, "Manipulate Organs", "Manipulate the orga log_admin("[key_name(user)] has added implant [implant_to_grant.type] to [key_name(carbon_victim)]") message_admins("[key_name_admin(user)] has added implant [implant_to_grant.type] to [ADMIN_LOOKUPFLW(carbon_victim)]") - if("drop organ/implant", "remove organ/implant") + if("Drop organ/implant", "Remove organ/implant") for(var/obj/item/organ/user_organs as anything in carbon_victim.organs) organs["[user_organs.name] ([user_organs.type])"] = user_organs @@ -70,7 +71,7 @@ ADMIN_VERB(manipulate_organs, R_DEBUG, "Manipulate Organs", "Manipulate the orga organ_to_modify.forceMove(get_turf(carbon_victim)) - if(operation == "remove organ/implant") + if(operation == "Remove organ/implant") qdel(organ_to_modify) else if(implant_holder) // Put the implant in case. var/obj/item/implantcase/case = new(get_turf(carbon_victim)) diff --git a/code/modules/admin/view_variables/debug_variable_appearance.dm b/code/modules/admin/view_variables/debug_variable_appearance.dm index dfa590fd437..d92efcb7b2a 100644 --- a/code/modules/admin/view_variables/debug_variable_appearance.dm +++ b/code/modules/admin/view_variables/debug_variable_appearance.dm @@ -68,7 +68,7 @@ SHOULD_CALL_PARENT(FALSE) . = list() - VV_DROPDOWN_OPTION("", "---") + VV_DROPDOWN_OPTION("", "--- /appearance_mirror ---") VV_DROPDOWN_OPTION(VV_HK_CALLPROC, "Call Proc") VV_DROPDOWN_OPTION(VV_HK_MARK, "Mark Object") VV_DROPDOWN_OPTION(VV_HK_TAG, "Tag Datum") diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm index 72185b93f35..2bdee2254f0 100644 --- a/code/modules/admin/view_variables/view_variables.dm +++ b/code/modules/admin/view_variables/view_variables.dm @@ -88,7 +88,6 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", datum/th var/list/dropdownoptions if (islist) dropdownoptions = list( - "---", "Add Item" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_ADD), "Remove Nulls" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_ERASE_NULLS), "Remove Dupes" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_ERASE_DUPES), @@ -100,7 +99,7 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", datum/th for(var/i in 1 to length(dropdownoptions)) var/name = dropdownoptions[i] var/link = dropdownoptions[name] - dropdownoptions[i] = "" + dropdownoptions[i] = "[name]" else dropdownoptions = thing.vv_get_dropdown() @@ -231,6 +230,37 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", datum/th var idx = what.indexOf(':'); document.getElementById(what.substr(0, idx)).innerHTML = what.substr(idx + 1); } + + function hideDropdown() { + var div = document.getElementById("vvDropdownDiv"); + var a = div.getElementsByTagName("a"); + for (i = 0; i < a.length; i++) { + a\[i\].style.display = "none"; + } + var input = document.getElementById("vvDropdownInput"); + input.value = ""; + } + + function filterDropdown() { + var input = document.getElementById("vvDropdownInput"); + var filter = input.value.toUpperCase(); + var div = document.getElementById("vvDropdownDiv"); + var a = div.getElementsByTagName("a"); + for (i = 0; i < a.length; i++) { + txtValue = a\[i\].textContent || a\[i\].innerText; + if (txtValue.toUpperCase().indexOf(filter) > -1) { + a\[i\].style.display = ""; + } else { + a\[i\].style.display = "none"; + } + } + } + + function delayHide() { + // Unfortunately required for links to work consistently when the input loses focus from a click + setTimeout(() => {hideDropdown();}, 150) + } +
@@ -259,14 +289,12 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", datum/th
Refresh -
- + +
diff --git a/code/modules/events/space_vines/vine_controller.dm b/code/modules/events/space_vines/vine_controller.dm index 119e9f86235..e33ed0c2b0f 100644 --- a/code/modules/events/space_vines/vine_controller.dm +++ b/code/modules/events/space_vines/vine_controller.dm @@ -48,6 +48,7 @@ GLOBAL_LIST_INIT(vine_mutations_list, init_vine_mutation_list()) /datum/spacevine_controller/vv_get_dropdown() . = ..() + VV_DROPDOWN_OPTION("", "--- /spacevine_controller ---") VV_DROPDOWN_OPTION(VV_HK_SPACEVINE_PURGE, "Delete Vines") /datum/spacevine_controller/vv_do_topic(href_list) @@ -57,8 +58,6 @@ GLOBAL_LIST_INIT(vine_mutations_list, init_vine_mutation_list()) return if(href_list[VV_HK_SPACEVINE_PURGE]) - if(!check_rights(NONE)) - return if(tgui_alert(usr, "Are you sure you want to delete this spacevine cluster?", "Delete Vines", list("Yes", "No")) == "Yes") DeleteVines() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index db83e9222a9..514e7035cba 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -976,7 +976,7 @@ /mob/living/carbon/vv_get_dropdown() . = ..() - VV_DROPDOWN_OPTION("", "---------") + VV_DROPDOWN_OPTION("", "--- /carbon ---") VV_DROPDOWN_OPTION(VV_HK_MODIFY_BODYPART, "Modify bodypart") VV_DROPDOWN_OPTION(VV_HK_MODIFY_ORGANS, "Modify organs") VV_DROPDOWN_OPTION(VV_HK_MARTIAL_ART, "Give Martial Arts") @@ -992,63 +992,78 @@ if(href_list[VV_HK_MODIFY_BODYPART]) if(!check_rights(R_SPAWN)) return - var/edit_action = input(usr, "What would you like to do?","Modify Body Part") as null|anything in list("replace","remove") + + var/edit_action = tgui_alert(usr, "What would you like to do?", "Modify Body Part", list("Replace", "Remove")) if(!edit_action) return + var/list/limb_list = list() - if(edit_action == "remove") + if(edit_action == "Remove") for(var/obj/item/bodypart/iter_part as anything in get_bodyparts()) - limb_list += iter_part.body_zone - limb_list -= BODY_ZONE_CHEST + var/zone = iter_part.body_zone + if (zone != BODY_ZONE_CHEST) + limb_list[parse_zone_with_bodypart(zone)] = zone else - limb_list = list(BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_CHEST) - var/result = input(usr, "Please choose which bodypart to [edit_action]","[capitalize(edit_action)] Bodypart") as null|anything in sort_list(limb_list) - if(result) - var/obj/item/bodypart/part = get_bodypart(result) - var/list/limbtypes = list() - switch(result) - if(BODY_ZONE_CHEST) - limbtypes = typesof(/obj/item/bodypart/chest) - if(BODY_ZONE_R_ARM) - limbtypes = typesof(/obj/item/bodypart/arm/right) - if(BODY_ZONE_L_ARM) - limbtypes = typesof(/obj/item/bodypart/arm/left) - if(BODY_ZONE_HEAD) - limbtypes = typesof(/obj/item/bodypart/head) - if(BODY_ZONE_L_LEG) - limbtypes = typesof(/obj/item/bodypart/leg/left) - if(BODY_ZONE_R_LEG) - limbtypes = typesof(/obj/item/bodypart/leg/right) - switch(edit_action) - if("remove") - if(part) - part.drop_limb() - admin_ticket_log("[key_name_admin(usr)] has removed [src]'s [part.plaintext_zone]") - else - to_chat(usr, span_boldwarning("[src] doesn't have such bodypart.")) - admin_ticket_log("[key_name_admin(usr)] has attempted to modify the bodyparts of [src]") - if("replace") - var/limb2add = input(usr, "Select a bodypart type to add", "Add/Replace Bodypart") as null|anything in sort_list(limbtypes) - var/obj/item/bodypart/new_bp = new limb2add() - if(new_bp.replace_limb(src)) - admin_ticket_log("key_name_admin(usr)] has replaced [src]'s [part?.type || "missing limb"] with [new_bp.type]") - qdel(part) - else - to_chat(usr, "Failed to replace bodypart! They might be incompatible.") - admin_ticket_log("[key_name_admin(usr)] has attempted to modify the bodyparts of [src]") + for(var/zone in GLOB.all_body_zones) + limb_list[parse_zone(zone)] = zone + + var/result = tgui_input_list(usr, "Please choose which bodypart to [LOWER_TEXT(edit_action)]","[edit_action] Bodypart", sort_list(limb_list)) + if (!result) + return + + result = limb_list[result] + var/obj/item/bodypart/part = get_bodypart(result) + var/list/limbtypes = list() + switch(result) + if(BODY_ZONE_CHEST) + limbtypes = typesof(/obj/item/bodypart/chest) + if(BODY_ZONE_R_ARM) + limbtypes = typesof(/obj/item/bodypart/arm/right) + if(BODY_ZONE_L_ARM) + limbtypes = typesof(/obj/item/bodypart/arm/left) + if(BODY_ZONE_HEAD) + limbtypes = typesof(/obj/item/bodypart/head) + if(BODY_ZONE_L_LEG) + limbtypes = typesof(/obj/item/bodypart/leg/left) + if(BODY_ZONE_R_LEG) + limbtypes = typesof(/obj/item/bodypart/leg/right) + + if(edit_action == "Remove") + if(part) + part.drop_limb() + admin_ticket_log("[key_name_admin(usr)] has removed [src]'s [part.plaintext_zone]") + else + to_chat(usr, span_boldwarning("[src] doesn't have such bodypart.")) + admin_ticket_log("[key_name_admin(usr)] has attempted to modify the bodyparts of [src]") + return + + var/list/limb_picks = list() + for (var/obj/item/bodypart/part_type as anything in sort_list(limbtypes, GLOBAL_PROC_REF(cmp_typepaths_asc))) + limb_picks[replacetext("[part_type]", "/obj/item/bodypart/", ":")] = part_type + + var/choice = tgui_input_list(usr, "Select a bodypart type to add", "Add/Replace Bodypart", limb_picks) + if (!choice) + return + + var/limb2add = limb_picks[choice] + var/obj/item/bodypart/new_bp = new limb2add() + if(new_bp.replace_limb(src)) + admin_ticket_log("key_name_admin(usr)] has replaced [src]'s [part?.type || "missing limb"] with [new_bp.type]") + qdel(part) + else + to_chat(usr, "Failed to replace bodypart! They might be incompatible.") + admin_ticket_log("[key_name_admin(usr)] has attempted to modify the bodyparts of [src]") if(href_list[VV_HK_MODIFY_ORGANS]) return SSadmin_verbs.dynamic_invoke_verb(usr, /datum/admin_verb/manipulate_organs, src) if(href_list[VV_HK_MARTIAL_ART]) - if(!check_rights(NONE)) - return var/list/artpaths = subtypesof(/datum/martial_art) var/list/artnames = list() for(var/i in artpaths) var/datum/martial_art/M = i artnames[initial(M.name)] = M - var/result = input(usr, "Choose the martial art to teach","JUDO CHOP") as null|anything in sort_list(artnames, GLOBAL_PROC_REF(cmp_typepaths_asc)) + var/result = tgui_input_list(usr, "Choose the martial art to teach", "JUDO CHOP", sort_list(artnames, GLOBAL_PROC_REF(cmp_typepaths_asc))) if(!usr) return if(QDELETED(src)) @@ -1062,10 +1077,8 @@ message_admins(span_notice("[key_name_admin(usr)] has taught [MA] to [key_name_admin(src)].")) if(href_list[VV_HK_GIVE_TRAUMA]) - if(!check_rights(NONE)) - return var/list/traumas = subtypesof(/datum/brain_trauma) - var/result = input(usr, "Choose the brain trauma to apply","Traumatize") as null|anything in sort_list(traumas, GLOBAL_PROC_REF(cmp_typepaths_asc)) + var/result = tgui_input_list(usr, "Choose the brain trauma to apply", "Traumatize", sort_list(traumas, GLOBAL_PROC_REF(cmp_typepaths_asc))) if(!usr) return if(QDELETED(src)) @@ -1079,8 +1092,6 @@ message_admins(span_notice("[key_name_admin(usr)] has traumatized [key_name_admin(src)] with [BT.name].")) if(href_list[VV_HK_CURE_TRAUMA]) - if(!check_rights(NONE)) - return cure_all_traumas(TRAUMA_RESILIENCE_ABSOLUTE) log_admin("[key_name(usr)] has cured all traumas from [key_name(src)].") message_admins(span_notice("[key_name_admin(usr)] has cured all traumas from [key_name_admin(src)].")) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 4078d7c6d30..bfac199095d 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -733,7 +733,7 @@ /mob/living/carbon/human/vv_get_dropdown() . = ..() - VV_DROPDOWN_OPTION("", "---------") + VV_DROPDOWN_OPTION("", "--- /human ---") VV_DROPDOWN_OPTION(VV_HK_COPY_OUTFIT, "Copy Outfit") VV_DROPDOWN_OPTION(VV_HK_MOD_MUTATIONS, "Add/Remove Mutation") VV_DROPDOWN_OPTION(VV_HK_MOD_QUIRKS, "Add/Remove Quirks") @@ -756,48 +756,56 @@ if(href_list[VV_HK_MOD_MUTATIONS]) if(!check_rights(R_SPAWN)) return - var/list/options = list("Clear"="Clear") - for(var/x in subtypesof(/datum/mutation)) + var/list/options = list("Clear" = "Clear") + for(var/x in sort_list(subtypesof(/datum/mutation), GLOBAL_PROC_REF(cmp_typepaths_asc))) var/datum/mutation/mut = x var/name = initial(mut.name) options[dna.check_mutation(mut) ? "[name] (Remove)" : "[name] (Add)"] = mut - var/result = input(usr, "Choose mutation to add/remove","Mutation Mod") as null|anything in sort_list(options) - if(result) - if(result == "Clear") - for(var/datum/mutation/mutation as anything in dna.mutations) - dna.remove_mutation(mutation, mutation.sources) - else - var/mut = options[result] - if(dna.check_mutation(mut)) - var/datum/mutation/mutation = dna.get_mutation(mut) - dna.remove_mutation(mut, mutation.sources) - else - dna.add_mutation(mut, MUTATION_SOURCE_VV) + + var/result = tgui_input_list(usr, "Choose mutation to add/remove", "Mutation Mod", options) + if(!result) + return + + if(result == "Clear") + for(var/datum/mutation/mutation as anything in dna.mutations) + dna.remove_mutation(mutation, mutation.sources) + return + + var/mut = options[result] + if(dna.check_mutation(mut)) + var/datum/mutation/mutation = dna.get_mutation(mut) + dna.remove_mutation(mut, mutation.sources) + else + dna.add_mutation(mut, MUTATION_SOURCE_VV) if(href_list[VV_HK_MOD_QUIRKS]) if(!check_rights(R_SPAWN)) return - var/list/options = list("Clear"="Clear") - for(var/type in valid_subtypesof(/datum/quirk)) + var/list/options = list("Clear" = "Clear") + for(var/type in sort_list(valid_subtypesof(/datum/quirk), GLOBAL_PROC_REF(cmp_typepaths_asc))) var/datum/quirk/quirk_type = type var/qname = initial(quirk_type.name) options[has_quirk(quirk_type) ? "[qname] (Remove)" : "[qname] (Add)"] = quirk_type - var/result = input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in sort_list(options) - if(result) - if(result == "Clear") - for(var/datum/quirk/q in quirks) - remove_quirk(q.type) - else - var/T = options[result] - if(has_quirk(T)) - remove_quirk(T) - else - add_quirk(T) + + var/result = tgui_input_list(usr, "Choose quirk to add/remove", "Quirk Mod", options) + if(!result) + return + + if(result == "Clear") + for(var/datum/quirk/quirk in quirks) + remove_quirk(quirk.type) + return + + var/selected = options[result] + if(has_quirk(selected)) + remove_quirk(selected) + else + add_quirk(selected) if(href_list[VV_HK_SET_SPECIES]) if(!check_rights(R_SPAWN)) return - var/result = input(usr, "Please choose a new species","Species") as null|anything in sortTim(GLOB.species_list, GLOBAL_PROC_REF(cmp_text_asc)) + var/result = tgui_input_list(usr, "Please choose a new species", "Species", sortTim(GLOB.species_list, GLOBAL_PROC_REF(cmp_text_asc))) if(result) var/newtype = GLOB.species_list[result] admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [src] to [result]") @@ -806,9 +814,6 @@ if(href_list[VV_HK_PURRBATION]) if(!check_rights(R_SPAWN)) return - if(!ishuman(src)) - to_chat(usr, "This can only be done to human species at the moment.") - return var/success = purrbation_toggle(src) if(success) to_chat(usr, "Put [src] on purrbation.") diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 75942a141e2..9d6ca3159d6 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -2135,7 +2135,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) /mob/living/vv_get_dropdown() . = ..() - VV_DROPDOWN_OPTION("", "---------") + VV_DROPDOWN_OPTION("", "--- /living ---") VV_DROPDOWN_OPTION(VV_HK_GIVE_SPEECH_IMPEDIMENT, "Impede Speech (Slurring, stuttering, etc)") VV_DROPDOWN_OPTION(VV_HK_ADD_MOOD, "Add Mood Event") VV_DROPDOWN_OPTION(VV_HK_REMOVE_MOOD, "Remove Mood Event") @@ -2151,33 +2151,21 @@ GLOBAL_LIST_EMPTY(fire_appearances) return if(href_list[VV_HK_GIVE_SPEECH_IMPEDIMENT]) - if(!check_rights(NONE)) - return admin_give_speech_impediment(usr) if(href_list[VV_HK_ADD_MOOD]) - if(!check_rights(NONE)) - return admin_add_mood_event(usr) if(href_list[VV_HK_REMOVE_MOOD]) - if(!check_rights(NONE)) - return admin_remove_mood_event(usr) if(href_list[VV_HK_GIVE_HALLUCINATION]) - if(!check_rights(NONE)) - return admin_give_hallucination(usr) if(href_list[VV_HK_GIVE_DELUSION_HALLUCINATION]) - if(!check_rights(NONE)) - return admin_give_delusion(usr) if(href_list[VV_HK_GIVE_GUARDIAN_SPIRIT]) - if(!check_rights(NONE)) - return admin_give_guardian(usr) if(href_list[VV_HK_ADMIN_RENAME]) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4a690abbf16..4a8c75c0b11 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1356,7 +1356,7 @@ */ /mob/vv_get_dropdown() . = ..() - VV_DROPDOWN_OPTION("", "---------") + VV_DROPDOWN_OPTION("", "--- /mob ---") VV_DROPDOWN_OPTION(VV_HK_GIB, "Gib") VV_DROPDOWN_OPTION(VV_HK_GIVE_AI, "Give AI Controller") VV_DROPDOWN_OPTION(VV_HK_GIVE_AI_SPEECH, "Give Random AI Speech") @@ -1384,13 +1384,9 @@ return if(href_list[VV_HK_REGEN_ICONS]) - if(!check_rights(NONE)) - return regenerate_icons() if(href_list[VV_HK_REGEN_ICONS_FULL]) - if(!check_rights(NONE)) - return cut_overlays() regenerate_icons() @@ -1441,8 +1437,6 @@ return SSadmin_verbs.dynamic_invoke_verb(usr, /datum/admin_verb/cmd_give_direct_control, src) if(href_list[VV_HK_OFFER_GHOSTS]) - if(!check_rights(NONE)) - return offer_control(src) if(href_list[VV_HK_VIEW_PLANES]) @@ -1451,8 +1445,6 @@ usr.client.edit_plane_masters(src) if(href_list[VV_HK_GIVE_ACCESS]) - if(!check_rights(NONE)) - return AddComponent(/datum/component/simple_access, SSid_access.get_region_access_list(list(REGION_ALL_GLOBAL))) to_chat(usr, span_notice("Access granted.")) /** diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 2e2d9058087..8e8e6c9e754 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -128,7 +128,7 @@ /obj/narsie/vv_get_dropdown() . = ..() - VV_DROPDOWN_OPTION("", "---------") + VV_DROPDOWN_OPTION("", "--- /narsie ---") VV_DROPDOWN_OPTION(VV_HK_BEGIN_NARSIE_ROUNDEND, "Begin Nar'Sie Roundender") /obj/narsie/vv_do_topic(list/href_list) @@ -137,7 +137,7 @@ if(!.) return - if(isnull(usr) || !href_list[VV_HK_BEGIN_NARSIE_ROUNDEND] || !check_rights(R_FUN, show_msg = TRUE)) + if(!href_list[VV_HK_BEGIN_NARSIE_ROUNDEND] || !check_rights(R_FUN, show_msg = TRUE)) return if(tgui_alert(usr, ADMIN_WARNING_MESSAGE, "Begin Nar'Sie Roundender", list("I'm Sure", "Abort")) != "I'm Sure") diff --git a/html/admin/view_variables.css b/html/admin/view_variables.css index b318b01e501..4155172acdf 100644 --- a/html/admin/view_variables.css +++ b/html/admin/view_variables.css @@ -1,39 +1,76 @@ body { - font-family: Verdana, sans-serif; - font-size: 9pt; + font-family: Verdana, sans-serif; + font-size: 9pt; } .value { - font-family: "Courier New", monospace; - font-size: 8pt; - display: inline-block; + font-family: "Courier New", monospace; + font-size: 8pt; + display: inline-block; } table.matrix { - border-collapse: collapse; - border-spacing: 0; - font-size: 7pt; + border-collapse: collapse; + border-spacing: 0; + font-size: 7pt; } .matrix td { - text-align: center; - padding: 0 1ex 0ex 1ex; + text-align: center; + padding: 0 1ex 0ex 1ex; } table.matrixbrak { - border-collapse: collapse; - border-spacing: 0; + border-collapse: collapse; + border-spacing: 0; } table.matrixbrak td.lbrak { - width: 0.8ex; - font-size: 50%; - border-top: solid 0.25ex black; - border-bottom: solid 0.25ex black; - border-left: solid 0.5ex black; - border-right: none; + width: 0.8ex; + font-size: 50%; + border-top: solid 0.25ex black; + border-bottom: solid 0.25ex black; + border-left: solid 0.5ex black; + border-right: none; } table.matrixbrak td.rbrak { - width: 0.8ex; - font-size: 50%; - border-top: solid 0.25ex black; - border-bottom: solid 0.25ex black; - border-right: solid 0.5ex black; - border-left: none; + width: 0.8ex; + font-size: 50%; + border-top: solid 0.25ex black; + border-bottom: solid 0.25ex black; + border-right: solid 0.5ex black; + border-left: none; +} + +#vvDropdownInput { + box-sizing: border-box; + padding: 4px; + border: none; + border-bottom: 1px solid #ddd; + width: 100%; +} + +#vvDropdownInput:focus { + outline: none; +} + +.dropdown-content { + margin-top: 4px; + position: absolute; + background-color: #f6f6f6; + border: 1px solid #ddd; + z-index: 1; +} + +.dropdown-options a { + color: black; + font-size: 12px; + padding: 6px 8px; + text-decoration: none; + display: block; +} + +.dropdown-options { + overflow-y: auto; + max-height: 500px; +} + +.dropdown-options a:hover { + background-color: #dbdbdb !important; }