From 6d19866c2a2453a1bf46706fcedfaa3bf9e9cad9 Mon Sep 17 00:00:00 2001 From: Kashargul <144968721+Kashargul@users.noreply.github.com> Date: Wed, 27 Mar 2024 08:52:26 +0100 Subject: [PATCH] TGPanel Patch 1 (#8059) Co-authored-by: Cadyn Bombaci --- code/__defines/statpanel_ch.dm | 2 + code/_helpers/icons.dm | 52 +++++++++++----- code/controllers/subsystems/statpanel_ch.dm | 62 ++++++++++++------- code/modules/asset_cache/assets/tgfont.dm | 6 +- .../simple_mob/subtypes/vore/bigdragon.dm | 2 +- .../subtypes/vore/shadekin/shadekin.dm | 2 +- .../station/protean/protean_species.dm | 2 +- vorestation.dme | 1 + 8 files changed, 86 insertions(+), 43 deletions(-) create mode 100644 code/__defines/statpanel_ch.dm diff --git a/code/__defines/statpanel_ch.dm b/code/__defines/statpanel_ch.dm new file mode 100644 index 0000000000..1c304d7fb3 --- /dev/null +++ b/code/__defines/statpanel_ch.dm @@ -0,0 +1,2 @@ +#define TURFLIST_UPDATED (1 << 0) +#define TURFLIST_UPDATE_QUEUED (1 << 1) diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index 5e3a348311..720fd1ddce 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -98,7 +98,8 @@ //CHOMPEdit Begin // Ported from /tg/station // Creates a single icon from a given /atom or /image. Only the first argument is required. -/proc/getFlatIcon(image/appearance, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE, force_south = FALSE) +// appearance_flags indicates whether appearance_flags should be respected (at the cost of about 10-20% perf) +/proc/getFlatIcon(image/appearance, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE, force_south = FALSE, appearance_flags = FALSE) // Loop through the underlays, then overlays, sorting them into the layers list #define PROCESS_OVERLAYS_OR_UNDERLAYS(flat, process, base_layer) \ for (var/i in 1 to process.len) { \ @@ -130,7 +131,6 @@ if(!appearance || appearance.alpha <= 0) return icon(flat_template) - if(start) if(!defdir) defdir = appearance.dir @@ -144,7 +144,9 @@ var/curicon = appearance.icon || deficon var/curstate = appearance.icon_state || defstate var/curdir = (!appearance.dir || appearance.dir == SOUTH) ? defdir : appearance.dir - if(force_south) curdir = SOUTH + + if(force_south) + curdir = SOUTH var/render_icon = curicon @@ -205,11 +207,21 @@ if(layer_image.alpha == 0) continue + // variables only relevant when accounting for appearance_flags: + var/apply_color = TRUE + var/apply_alpha = TRUE + if(layer_image == copy) // 'layer_image' is an /image based on the object being flattened. curblend = BLEND_OVERLAY add = icon(layer_image.icon, layer_image.icon_state, base_icon_dir) else // 'I' is an appearance object. - add = getFlatIcon(image(layer_image), curdir, curicon, curstate, curblend, FALSE, no_anim) + var/image/layer_as_image = image(layer_image) + if(appearance_flags) + if(layer_as_image.appearance_flags & RESET_COLOR) + apply_color = FALSE + if(layer_as_image.appearance_flags & RESET_ALPHA) + apply_alpha = FALSE + add = getFlatIcon(layer_as_image, curdir, curicon, curstate, curblend, FALSE, no_anim, force_south, appearance_flags) if(!add) continue @@ -224,7 +236,6 @@ || addX2 != flatX2 \ || addY1 != flatY1 \ || addY2 != flatY2 \ - ) // Resize the flattened icon so the new icon fits flat.Crop( @@ -239,17 +250,30 @@ flatY1 = addY1 flatY2 = addY2 + if(appearance_flags) + // apply parent's color/alpha to the added layers if the layer didn't opt + if(apply_color && appearance.color) + if(islist(appearance.color)) + add.MapColors(arglist(appearance.color)) + else + add.Blend(appearance.color, ICON_MULTIPLY) + + if(apply_alpha && appearance.alpha < 255) + add.Blend(rgb(255, 255, 255, appearance.alpha), ICON_MULTIPLY) + // Blend the overlay into the flattened icon flat.Blend(add, blendMode2iconMode(curblend), layer_image.pixel_x + 2 - flatX1, layer_image.pixel_y + 2 - flatY1) - if(appearance.color) - if(islist(appearance.color)) - flat.MapColors(arglist(appearance.color)) - else - flat.Blend(appearance.color, ICON_MULTIPLY) + if(!appearance_flags) + // If we didn't apply parent colors individually per layer respecting appearance_flags, then do it just the one time now + if(appearance.color) + if(islist(appearance.color)) + flat.MapColors(arglist(appearance.color)) + else + flat.Blend(appearance.color, ICON_MULTIPLY) - if(appearance.alpha < 255) - flat.Blend(rgb(255, 255, 255, appearance.alpha), ICON_MULTIPLY) + if(appearance.alpha < 255) + flat.Blend(rgb(255, 255, 255, appearance.alpha), ICON_MULTIPLY) if(no_anim) //Clean up repeated frames @@ -609,7 +633,7 @@ GLOBAL_LIST_EMPTY(cached_examine_icons) * * sourceonly - if TRUE, only generate the asset and send back the asset url, instead of tags that display the icon to players * * extra_clases - string of extra css classes to use when returning the icon string */ -/proc/icon2html(atom/thing, client/target, icon_state, dir = SOUTH, frame = 1, moving = FALSE, sourceonly = FALSE, extra_classes = null) +/proc/icon2html(atom/thing, client/target, icon_state, dir = SOUTH, frame = 1, moving = FALSE, sourceonly = FALSE, extra_classes = null) //CHOMPEdit if (!thing) return //if(SSlag_switch.measures[DISABLE_USR_ICON2HTML] && usr && !HAS_TRAIT(usr, TRAIT_BYPASS_MEASURES)) @@ -654,7 +678,7 @@ GLOBAL_LIST_EMPTY(cached_examine_icons) icon_state = thing.icon_state //Despite casting to atom, this code path supports mutable appearances, so let's be nice to them //if(isnull(icon_state) || (isatom(thing) && thing.flags_1 & HTML_USE_INITAL_ICON_1)) - if(isnull(icon_state) || isatom(thing)) + if(isnull(icon_state) && isatom(thing)) icon_state = initial(thing.icon_state) if (isnull(dir)) dir = initial(thing.dir) diff --git a/code/controllers/subsystems/statpanel_ch.dm b/code/controllers/subsystems/statpanel_ch.dm index fb36a22085..c17635dc60 100644 --- a/code/controllers/subsystems/statpanel_ch.dm +++ b/code/controllers/subsystems/statpanel_ch.dm @@ -14,7 +14,7 @@ SUBSYSTEM_DEF(statpanels) ///how many subsystem fires between most tab updates var/default_wait = 10 ///how many subsystem fires between updates of misc tabs - var/misc_wait = 7 + var/misc_wait = 3 ///how many subsystem fires between updates of the status tab var/status_wait = 2 ///how many subsystem fires between updates of the MC tab @@ -53,9 +53,6 @@ SUBSYSTEM_DEF(statpanels) if(!target.stat_panel.is_ready()) continue - if(target.stat_tab == "Examine") - set_examine_tab(target) - if(target.stat_tab == "Status" && num_fires % status_wait == 0) set_status_tab(target) @@ -98,19 +95,15 @@ SUBSYSTEM_DEF(statpanels) if(update_actions && num_fires % default_wait == 0) set_action_tabs(target, target_mob) - //Update every fire if tab is open, otherwise update every 7 fires - if((target.stat_tab in target.misc_tabs) || (num_fires % misc_wait == 0)) + if((num_fires % misc_wait == 0)) update_misc_tabs(target,target_mob) - // Handle the examined turf of the stat panel - if(target_mob?.listed_turf && num_fires % default_wait == 0) - if(!target_mob.TurfAdjacent(target_mob.listed_turf) || isnull(target_mob.listed_turf)) - target.stat_panel.send_message("remove_listedturf") - target_mob.listed_turf = null - - //else if(target.stat_tab == target_mob?.listed_turf.name || !(target_mob?.listed_turf.name in target.panel_tabs)) - //set_turf_examine_tab(target, target_mob) + var/datum/object_window_info/obj_window = target.obj_window + if(obj_window) + if(obj_window.flags & TURFLIST_UPDATE_QUEUED) + immediate_send_stat_data(target) + obj_window.flags = 0 if(MC_TICK_CHECK) return @@ -168,7 +161,7 @@ SUBSYSTEM_DEF(statpanels) examine_update += "[target.examine_icon] [description_holders["name"]]" //The name, written in big letters. examine_update += "[description_holders["desc"]]" //the default examine text. if(description_holders["info"]) - examine_update += "[description_holders["info"]]
" //Blue, informative text. + examine_update += "[replacetext(description_holders["info"], "\n", "
")]

" //Blue, informative text. if(description_holders["interactions"]) for(var/line in description_holders["interactions"]) examine_update += "[line]
" @@ -205,6 +198,8 @@ SUBSYSTEM_DEF(statpanels) //target.stat_panel.send_message("update_spells", list(spell_tabs = target.spell_tabs, actions = actions)) /datum/controller/subsystem/statpanels/proc/set_turf_examine_tab(client/target, mob/target_mob) + if(!target)//statbrowser hasnt fired yet and we were called from immediate_send_stat_data() + return var/list/overrides = list() for(var/image/target_image as anything in target.images) if(!target_image.loc || target_image.loc.loc != target_mob.listed_turf || !target_image.override) @@ -225,6 +220,8 @@ SUBSYSTEM_DEF(statpanels) /// Set the atoms we're meant to display var/datum/object_window_info/obj_window = target.obj_window + if(!obj_window) + return // previous one no longer exists obj_window.atoms_to_show = atoms_to_display START_PROCESSING(SSobj_tab_items, obj_window) refresh_client_obj_view(target) @@ -296,9 +293,9 @@ SUBSYSTEM_DEF(statpanels) if(!target.stat_panel.is_ready()) return FALSE - //if(target.stat_tab == "Examine") - //set_examine_tab(target) - //return TRUE + if(target.stat_tab == "Examine") + set_examine_tab(target) + return TRUE if(target.stat_tab == "Status") set_status_tab(target) @@ -371,6 +368,7 @@ SUBSYSTEM_DEF(statpanels) var/actively_tracking = FALSE ///For reusing this logic for examines var/atom/examine_target + var/flags = 0 /datum/object_window_info/New(client/parent) . = ..() @@ -396,9 +394,10 @@ SUBSYSTEM_DEF(statpanels) var/atom/thing = to_make[index] var/generated_string - if(ismob(thing) || length(thing.overlays) > 2) - var/force_south = TRUE - if(isturf(thing)) force_south = FALSE + if(ismob(thing) || length(thing.overlays) > 0) + var/force_south = FALSE + if(isliving(thing)) + force_south = TRUE generated_string = costly_icon2html(thing, parent, sourceonly=TRUE, force_south = force_south) else generated_string = icon2html(thing, parent, sourceonly=TRUE) @@ -423,10 +422,14 @@ SUBSYSTEM_DEF(statpanels) COMSIG_MOB_LOGOUT = PROC_REF(on_mob_logout), ) AddComponent(/datum/component/connect_mob_behalf, parent, connections) + RegisterSignal(parent.mob.listed_turf, COMSIG_ATOM_ENTERED, PROC_REF(turflist_changed)) + RegisterSignal(parent.mob.listed_turf, COMSIG_ATOM_EXITED, PROC_REF(turflist_changed)) actively_tracking = TRUE /datum/object_window_info/proc/stop_turf_tracking() qdel(GetComponent(/datum/component/connect_mob_behalf)) + UnregisterSignal(parent.mob.listed_turf, COMSIG_ATOM_ENTERED) + UnregisterSignal(parent.mob.listed_turf, COMSIG_ATOM_EXITED) actively_tracking = FALSE /datum/object_window_info/proc/on_mob_move(mob/source) @@ -439,6 +442,16 @@ SUBSYSTEM_DEF(statpanels) SIGNAL_HANDLER on_mob_move(parent.mob) +/datum/object_window_info/proc/turflist_changed(mob/source) + if(!parent)//statbrowser hasnt fired yet and we still have a pending action + return + SIGNAL_HANDLER + if(!(flags & TURFLIST_UPDATED)) //Limit updates to 1 per tick + SSstatpanels.immediate_send_stat_data(parent) + flags |= TURFLIST_UPDATED + else if(!(flags & TURFLIST_UPDATE_QUEUED)) + flags |= TURFLIST_UPDATE_QUEUED + /// Clears any cached object window stuff /// We use hard refs cause we'd need a signal for this anyway. Cleaner this way /datum/object_window_info/proc/viewing_atom_deleted(atom/deleted) @@ -448,14 +461,17 @@ SUBSYSTEM_DEF(statpanels) atoms_to_images -= deleted /mob/proc/set_listed_turf(turf/new_turf) - listed_turf = new_turf if(!client) + listed_turf = new_turf return if(!client.obj_window) client.obj_window = new(client) + if(!new_turf) + client.obj_window.stop_turf_tracking() //Needs to go before listed_turf is set to null so signals can be removed + listed_turf = new_turf + if(listed_turf) client.stat_panel.send_message("create_listedturf", listed_turf.name) client.obj_window.start_turf_tracking() else client.stat_panel.send_message("remove_listedturf") - client.obj_window.stop_turf_tracking() diff --git a/code/modules/asset_cache/assets/tgfont.dm b/code/modules/asset_cache/assets/tgfont.dm index 1d9df4282c..efa98e22e2 100644 --- a/code/modules/asset_cache/assets/tgfont.dm +++ b/code/modules/asset_cache/assets/tgfont.dm @@ -1,8 +1,8 @@ /datum/asset/simple/namespaced/tgfont assets = list( - "tgfont.eot" = file("tgui/packages/tgfont/dist/tgfont.eot"), - "tgfont.woff2" = file("tgui/packages/tgfont/dist/tgfont.woff2"), + "tgfont.eot" = file("tgui/packages/tgfont/static/tgfont.eot"), + "tgfont.woff2" = file("tgui/packages/tgfont/static/tgfont.woff2"), ) parents = list( - "tgfont.css" = file("tgui/packages/tgfont/dist/tgfont.css"), + "tgfont.css" = file("tgui/packages/tgfont/static/tgfont.css"), ) diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/bigdragon.dm b/code/modules/mob/living/simple_mob/subtypes/vore/bigdragon.dm index 6be0cc1c74..70984d8987 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/bigdragon.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/bigdragon.dm @@ -106,7 +106,7 @@ I think I covered everything. special_attack_max_range = 10 special_attack_cooldown = 80 - plane = ABOVE_MOB_PLANE + plane = MOB_PLANE //CHOMPEdit //Dragon vars var/notame diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm index 7ca559e81f..89158d1923 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm @@ -245,7 +245,7 @@ img = icon2html(A,C,sourceonly=TRUE) C.misc_cache[A.ability_name] = img - L[++L.len] = list("[A.ability_name]", A.ability_name, img, "Activate", REF(A)) + L[++L.len] = list("[A.ability_name]", A.ability_name, img, A.atom_button_text(), REF(A)) misc_tabs["Shadekin"] = L //ChompEDIT END diff --git a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_species.dm b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_species.dm index 7a037f1a93..35a78211a7 100644 --- a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_species.dm +++ b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_species.dm @@ -309,7 +309,7 @@ CHOMP Station removal end*/ img = icon2html(A,C,sourceonly=TRUE) C.misc_cache[A.ability_name] = img - L[++L.len] = list("[A.ability_name]", A.ability_name, img, A.name, REF(A)) + L[++L.len] = list("[A.ability_name]", A.ability_name, img, A.atom_button_text(), REF(A)) H.misc_tabs["Protean"] = L // Various modifiers diff --git a/vorestation.dme b/vorestation.dme index f0493f8b97..55dc6fcd73 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -105,6 +105,7 @@ #include "code\__defines\sprite_sheets_ch.dm" #include "code\__defines\sqlite_defines.dm" #include "code\__defines\stat_tracking.dm" +#include "code\__defines\statpanel_ch.dm" #include "code\__defines\subsystems.dm" #include "code\__defines\supply.dm" #include "code\__defines\targeting.dm"