Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VV editor can now see /appearance types #10885

Merged
merged 22 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -1821,6 +1821,7 @@
#include "code\modules\admin\verbs\SDQL2\SDQL_2_wrappers.dm"
#include "code\modules\admin\view_variables\admin_delete.dm"
#include "code\modules\admin\view_variables\color_matrix_editor.dm"
#include "code\modules\admin\view_variables\debug_variable_appearance.dm"
#include "code\modules\admin\view_variables\debug_variables.dm"
#include "code\modules\admin\view_variables\filterrific.dm"
#include "code\modules\admin\view_variables\get_variables.dm"
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/vv.dm
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@

//Helpers for vv_get_dropdown()
#define VV_DROPDOWN_OPTION(href_key, name) . += "<option value='?_src_=vars;[HrefToken()];[href_key]=TRUE;target=[REF(src)]'>[name]</option>"
#define VV_DROPDOWN_OPTION_APPEARANCE(thing, href_key, name) . += "<option value='?_src_=vars;[HrefToken()];[href_key]=TRUE;target=[REF(thing)]'>[name]</option>"

// VV HREF KEYS
#define VV_HK_TARGET "target"
Expand Down
223 changes: 223 additions & 0 deletions code/modules/admin/view_variables/debug_variable_appearance.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
/* < OH MY GOD. Can't you just make "/image/proc/foo()" instead of making these? >
* /appearance is a hardcoded byond type, and it is very internal type.
* Its type is actually /image, but it isn't truly /image. We defined it as "/appearance"
* new procs to /image will only work to actual /image references, but...
* /appearance references are not capable of executing procs, because these are not real /image
PowerfulBacon marked this conversation as resolved.
Show resolved Hide resolved
* This is why these global procs exist. Welcome to the curse.
*/
/// Makes a var list of /appearance type actually uses. This will be only called once.
/proc/build_appearance_var_list()
. = list("vis_flags") // manual listing
var/list/unused_var_names = list(
"vars", // /appearnace doesn't have internal "vars" variable. Even if it has, we have no reason to see it
"appearance", // it only does self-reference
"x","y","z", // these are always 0

// we have no reason to show those, right?
"active_timers",
"comp_lookup",
"signal_procs",
"status_traits",
"stat_tabs",
"cooldowns",
"datum_flags",
"visibility",
"verbs",
)
var/image/dummy_image = image(null, null)
for(var/each in dummy_image.vars)
if(each in unused_var_names)
continue
. += each
del(dummy_image)
dummy_image = null

/// appearance type needs a manual var referencing because it doesn't have "vars" variable internally.
/// There's no way doing this in a fancier way.
/proc/debug_variable_appearance(var_name, image/appearance)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the thing coming in isn't an image, then it shouldn't be typed as an image

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Welcome to Byond

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least it's a single case. I converted it to movable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thats even worse, its definitely not an atom/movable. Its a variable type and should be untyped, with the type being resolved later on.

Copy link
Member

@PowerfulBacon PowerfulBacon Apr 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why even bother typing it with the wrong type, just use the unsafe access operator, :, and keep it untyped

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aight changed

try // somehow /appearance has "vars" variable.
return debug_variable(var_name, appearance.vars[var_name], 0, appearance, sanitize = TRUE, display_flags = NONE)
catch
pass()

var/atom/movable/atom_appearance = appearance
var/value
try
switch(var_name) // Welcome to this curse
// appearance doesn't have "vars" variable.
// This means you need to target a variable manually through this way.

// appearance vars in DM document
if("alpha")
value = appearance.alpha
if("appearance_flags")
value = appearance.appearance_flags
if("blend_mode")
value = appearance.blend_mode
if("color")
value = appearance.color
if("desc")
value = appearance.desc
if("gender")
value = appearance.gender
if("icon")
value = appearance.icon
if("icon_state")
value = appearance.icon_state
if("invisibility")
value = appearance.invisibility
if("infra_luminosity")
value = atom_appearance.infra_luminosity
if("filters")
value = appearance.filters
if("layer")
value = appearance.layer
if("luminosity")
value = appearance.luminosity
if("maptext")
value = appearance.maptext
if("maptext_width")
value = appearance.maptext_width
if("maptext_height")
value = appearance.maptext_height
if("maptext_x")
value = appearance.maptext_x
if("maptext_y")
value = appearance.maptext_y
if("mouse_over_pointer")
value = appearance.mouse_over_pointer
if("mouse_drag_pointer")
value = appearance.mouse_drag_pointer
if("mouse_drop_pointer")
value = appearance.mouse_drop_pointer
if("mouse_drop_zone")
value = appearance.mouse_drop_zone
if("mouse_opacity")
value = appearance.mouse_opacity
if("name")
value = appearance.name
if("opacity")
value = appearance.opacity
if("overlays")
value = appearance.overlays
if("override")
value = appearance.override
if("pixel_x")
value = appearance.pixel_x
if("pixel_y")
value = appearance.pixel_y
if("pixel_w")
value = appearance.pixel_w
if("pixel_z")
value = appearance.pixel_z
if("plane")
value = appearance.plane
if("render_source")
value = appearance.render_source
if("render_target")
value = appearance.render_target
if("suffix")
value = appearance.suffix
if("text")
value = appearance.text
if("transform")
value = appearance.transform
if("underlays")
value = appearance.underlays

if("parent_type")
value = appearance.parent_type
if("type")
value = appearance.type

// These are not documented ones but trackable values. Maybe we'd want these.
if("animate_movement")
value = atom_appearance.animate_movement
if("dir")
value = atom_appearance.dir
if("glide_size")
value = atom_appearance.glide_size
if("pixel_step_size")
value = "" //atom_appearance.pixel_step_size
// DM compiler complains this

// These variables are only available in some conditions.
if("contents")
value = atom_appearance.contents
if("vis_contents")
value = atom_appearance.vis_contents
if("vis_flags")
value = atom_appearance.vis_flags
if("loc")
value = atom_appearance.loc
if("locs")
value = atom_appearance.locs
if("x")
value = atom_appearance.x
if("y")
value = atom_appearance.y
if("z")
value = atom_appearance.z

// we wouldn't need these, but let's these trackable anyway...
if("cooldowns")
value = atom_appearance.cooldowns
if("gc_destroyed")
value = atom_appearance.gc_destroyed
if("datum_components")
value = atom_appearance.datum_components
if("datum_flags")
value = atom_appearance.datum_flags
if("density")
value = atom_appearance.density
if("screen_loc")
value = atom_appearance.screen_loc
if("sorted_verbs")
value = atom_appearance.sorted_verbs
if("tag")
value = atom_appearance.tag
if("tgui_shared_states")
value = atom_appearance.tgui_shared_states
if("verbs")
value = atom_appearance.verbs
if("weak_reference")
value = atom_appearance.weak_reference
if("cached_ref")
value = appearance.cached_ref

else
return "<li style='backgroundColor:white'>(STATIC) [var_name] <font color='blue'>(Undefined var name in switch)</font></li>"
catch
return "<li style='backgroundColor:white'>(STATIC) <font color='blue'>[var_name] = (untrackable)</font></li>"
return "<li style='backgroundColor:white'>(STATIC) [var_name] = [_debug_variable_value(var_name, value, 0, appearance, sanitize = TRUE, display_flags = NONE)]</li>"
EvilDragonfiend marked this conversation as resolved.
Show resolved Hide resolved

/// Shows a header name on top when you investigate an appearance
/proc/vv_get_header_appearance(image/thing)
. = list()
var/icon_name = "<b>[length(thing.icon) ? thing.icon || "null" : "(icon exists, but name is null)"]</b><br/>"
. += replacetext(icon_name, "icons/obj", "") // shortens the name. We know the path already.
if(thing.icon)
. += thing.icon_state ? "\"[thing.icon_state]\"" : "(icon_state = null)"

/// Makes a format name for shortened vv name.
/proc/get_appearance_vv_summary_name(image/thing)
var/icon_file_name = thing.icon ? splittext("[thing.icon]", "/") : "null"
if(islist(icon_file_name))
icon_file_name = length(icon_file_name) ? icon_file_name[length(icon_file_name)] : "(null??)" // thing.icon exists but it's null????
if(thing.icon_state)
return "[icon_file_name]:[thing.icon_state]"
else
return "[icon_file_name]"

/proc/vv_get_dropdown_appearance(image/thing)
. = list()
try
if(thing.vars)
VV_DROPDOWN_OPTION_APPEARANCE(thing, "", "---")
VV_DROPDOWN_OPTION_APPEARANCE(thing, VV_HK_MARK, "Mark Object")
VV_DROPDOWN_OPTION_APPEARANCE(thing, VV_HK_TAG, "Tag Datum")
VV_DROPDOWN_OPTION_APPEARANCE(thing, VV_HK_DELETE, "Delete")
VV_DROPDOWN_OPTION_APPEARANCE(thing, VV_HK_EXPOSE, "Show VV To Player")
catch
VV_DROPDOWN_OPTION_APPEARANCE(thing, "", "---")
VV_DROPDOWN_OPTION_APPEARANCE(thing, "", "VV option not allowed")
5 changes: 2 additions & 3 deletions code/modules/admin/view_variables/debug_variables.dm
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@
return "/icon (<span class='value'>[value]</span>)"
#endif

if(isappearance(value))
var/image/actually_an_appearance = value
return "/appearance (<span class='value'>[actually_an_appearance.icon]</span>)"
if(isappearance(value)) // Reminder: Do not replace this into /image/debug_variable_value() proc. /appearance can't do that.
return "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>/appearance (<span class='value'>[get_appearance_vv_summary_name(value)]</span>) [REF(value)]</a>"

if(isfilter(value))
var/datum/filter_value = value
Expand Down
25 changes: 19 additions & 6 deletions code/modules/admin/view_variables/view_variables.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,28 @@
var/datum/asset/asset_cache_datum = get_asset_datum(/datum/asset/simple/vv)
asset_cache_datum.send(usr)

var/isappearance = isappearance(thing)
var/islist = islist(thing) || (!isdatum(thing) && hascall(thing, "Cut")) // Some special lists dont count as lists, but can be detected by if they have list procs
if(!islist && !isdatum(thing))
if(!islist && !isdatum(thing) && !isappearance)
return

var/title = ""
var/refid = REF(thing)
var/icon/sprite
var/hash

var/type = islist? /list : thing.type
var/type = islist? /list : (isappearance ? "/appearance" : thing.type)
var/no_icon = FALSE

if(isatom(thing))
sprite = getFlatIcon(thing)
if(!sprite)
no_icon = TRUE

else if(isimage(thing))
else if(isimage(thing) || isappearance(thing))
var/image/image_object = thing
sprite = icon(image_object.icon, image_object.icon_state)
if(image_object.icon_state) // icon_state=null shows first image. Let's skip null name for general cases, because it's confusing.
sprite = icon(image_object.icon, image_object.icon_state)

var/sprite_text
if(sprite)
Expand All @@ -44,7 +46,7 @@
title = "[thing] ([REF(thing)]) = [type]"
var/formatted_type = replacetext("[type]", "/", "<wbr>/")

var/list/header = islist ? list("<b>/list</b>") : thing.vv_get_header()
var/list/header = islist ? list("<b>/list</b>") : (isappearance ? vv_get_header_appearance(thing) : thing.vv_get_header())

var/ref_line = "@[copytext(refid, 2, -1)]" // get rid of the brackets, add a @ prefix for copy pasting in asay

Expand Down Expand Up @@ -78,11 +80,18 @@
var/name = dropdownoptions[i]
var/link = dropdownoptions[name]
dropdownoptions[i] = "<option value[link? "='[link]'":""]>[name]</option>"
else if(isappearance)
dropdownoptions = vv_get_dropdown_appearance(thing)
else
dropdownoptions = thing.vv_get_dropdown()

var/list/names = list()
if(!islist)
if(isappearance)
var/static/list/appearnace_vars
EvilDragonfiend marked this conversation as resolved.
Show resolved Hide resolved
if(!appearnace_vars)
appearnace_vars = build_appearance_var_list()
names = appearnace_vars.Copy()
else if(!islist)
for(var/varname in thing.vars)
names += varname

Expand All @@ -97,6 +106,10 @@
if(IS_NORMAL_LIST(list_value) && IS_VALID_ASSOC_KEY(key))
value = list_value[key]
variable_html += debug_variable(i, value, 0, list_value)
else if(isappearance)
names = sort_list(names)
for(var/varname in names)
variable_html += debug_variable_appearance(varname, thing)
else
names = sort_list(names)
for(var/varname in names)
Expand Down
Loading