From 0fe77e9dd3f85dc229b44be2dab9ef1c68b4daef Mon Sep 17 00:00:00 2001 From: Lucy Date: Fri, 3 Apr 2026 10:26:31 -0400 Subject: [PATCH] read-only alist support for VV (#95501) ## About The Pull Request This adds experimental read-only support for `/alist`s in VV. I'm not quite sure how to add support for properly changing alists, but this is better than nothing at least. ### Before image ### After 2026-03-23 (1774313721) ~
dreamseeker ## Why It's Good For The Game Should be able to at least view alists with VV. ## Changelog :cl: admin: View Variables can now properly view alists, altho it cannot edit them. /:cl: --- code/__DEFINES/is_helpers.dm | 2 ++ .../admin/view_variables/debug_variables.dm | 16 ++++++++- .../admin/view_variables/modify_variables.dm | 3 ++ .../view_variables/reference_tracking.dm | 2 +- .../admin/view_variables/view_variables.dm | 33 ++++++++++++------- 5 files changed, 43 insertions(+), 13 deletions(-) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index c4cffab911e..b8c485eb776 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -22,6 +22,8 @@ GLOBAL_VAR_INIT(refid_filter, TYPEID(filter(type="angular_blur"))) #define isgenerator(A) (istype(A, /generator)) +#define isalist(A) (istype(A, /alist)) + //Turfs //#define isturf(A) (istype(A, /turf)) This is actually a byond built-in. Added here for completeness sake. diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm index d11bcb9316a..ded5890cba8 100644 --- a/code/modules/admin/view_variables/debug_variables.dm +++ b/code/modules/admin/view_variables/debug_variables.dm @@ -2,7 +2,9 @@ /// Get displayed variable in VV variable list /proc/debug_variable(name, value, level, datum/owner, sanitize = TRUE, display_flags = NONE) //if D is a list, name will be index, and value will be assoc value. if(owner) - if(islist(owner)) + if(isalist(owner)) + . = "
  • (READ ONLY) " + else if(islist(owner)) var/list/list_owner = owner var/index = name if (isnull(value)) @@ -64,6 +66,18 @@ var/datum/datum_value = value return datum_value.debug_variable_value(name, level, owner, sanitize, display_flags) + if(isalist(value)) + var/alist/alist_value = value + var/list/items = list() + + var/link_vars = "Vars=[REF(value)]" + + if (!(display_flags & VV_ALWAYS_CONTRACT_LIST) && alist_value.len > 0 && alist_value.len <= VV_NORMAL_LIST_NO_EXPAND_THRESHOLD) + for(var/key, val in alist_value) + items += debug_variable(key, val, level + 1, sanitize = sanitize) + return "/alist ([alist_value.len])" + return "/alist ([alist_value.len])" + if(islist(value) || (name in GLOB.vv_special_lists)) // Some special lists aren't detectable as a list through istype var/list/list_value = value var/list/items = list() diff --git a/code/modules/admin/view_variables/modify_variables.dm b/code/modules/admin/view_variables/modify_variables.dm index 13b3a2aa398..408cb30df5d 100644 --- a/code/modules/admin/view_variables/modify_variables.dm +++ b/code/modules/admin/view_variables/modify_variables.dm @@ -113,6 +113,9 @@ GLOBAL_PROTECT(VVpixelmovement) if(!istype(L, /list)) to_chat(src, "Not a List.", confidential = TRUE) return + if(isalist(L)) + to_chat(src, "alists are currently unsupported", confidential = TRUE) + return if(L.len > 1000) var/confirm = tgui_alert(usr, "The list you're trying to edit is very long, continuing may crash the server.", "Warning", list("Continue", "Abort")) diff --git a/code/modules/admin/view_variables/reference_tracking.dm b/code/modules/admin/view_variables/reference_tracking.dm index ee79bd8b5c1..5f3afd380f7 100644 --- a/code/modules/admin/view_variables/reference_tracking.dm +++ b/code/modules/admin/view_variables/reference_tracking.dm @@ -197,7 +197,7 @@ GLOBAL_ALIST_EMPTY(reftracker_skip_typecache_b) else if(islist(potential_container)) var/list/potential_cache = potential_container - var/is_alist = istype(potential_cache, /alist) + var/is_alist = isalist(potential_cache) for(var/element_in_list in potential_cache) //Check normal sublists if(islist(element_in_list)) diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm index 2bdee2254f0..18237e09e19 100644 --- a/code/modules/admin/view_variables/view_variables.dm +++ b/code/modules/admin/view_variables/view_variables.dm @@ -23,13 +23,14 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", datum/th var/islist = islist(thing) || (!isdatum(thing) && hascall(thing, "Cut")) // Some special lists don't count as lists, but can be detected by if they have list procs if(!islist && !isdatum(thing)) return + var/isalist = isalist(thing) // islist will always be true for alists too var/title = "" var/refid = REF(thing) var/icon/sprite var/hash - var/type = islist ? /list : thing.type + var/type = islist ? (isalist ? /alist : /list) : thing.type var/no_icon = FALSE if(isatom(thing)) @@ -67,7 +68,7 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", datum/th title = "[thing] ([REF(thing)]) = [type]" var/formatted_type = replacetext("[type]", "/", "/") - var/list/header = islist ? list("/list") : thing.vv_get_header() + var/list/header = islist ? (isalist ? list("/alist") : list("/list")) : thing.vv_get_header() var/ref_line = "@[copytext(refid, 2, -1)]" // get rid of the brackets, add a @ prefix for copy pasting in asay @@ -87,14 +88,20 @@ 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), - "Set len" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_SET_LENGTH), - "Shuffle" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_SHUFFLE), - "Show VV To Player" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_EXPOSE), - "---" + if(!isalist) + 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), + "Set len" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_SET_LENGTH), + "Shuffle" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_SHUFFLE), + "Show VV To Player" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_EXPOSE), + "---" + ) + else + dropdownoptions = list( + "Show VV To Player" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_EXPOSE), + "---" ) for(var/i in 1 to length(dropdownoptions)) var/name = dropdownoptions[i] @@ -113,7 +120,11 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", datum/th var/ui_scale = prefs?.read_preference(/datum/preference/toggle/ui_scale) var/list/variable_html = list() - if(islist) + if(isalist) + var/alist/alist_value = thing + for(var/key, value in alist_value) + variable_html += debug_variable(key, value, 0, alist_value) + else if(islist) var/list/list_value = thing for(var/i in 1 to list_value.len) var/key = list_value[i]