From c5cc9ea00a6e81aafbdd6b4841c13d6bd3b37773 Mon Sep 17 00:00:00 2001 From: _0Steven <42909981+00-Steven@users.noreply.github.com> Date: Fri, 4 Oct 2024 02:45:00 +0200 Subject: [PATCH] Fixes prosopagnosia not working with screentips (bitflag&signal edition) (#86980) ## About The Pull Request So previously I made a pr for fixing the prosopagnosia quirk, but the code I wrote was far too ass for what was already incredibly hot code. In the comments, Mothblocks requested using the same bitflag&signal logic the other screentip modifiers use. ![image](https://github.com/user-attachments/assets/cd26ab56-f1e8-4be3-a847-5a4509d312c1) I, of course, said I'd look into it in a few days. Anyhow, 199 days later, I've made this pr. Here we introduce a new `mob_flags` var on `/mob`, where we set `MOB_HAS_SCREENTIPS_NAME_OVERRIDE`. Then, based on whether this is set, the screentips system sends a signal to the user mob to request possible name overrides. We then make the prosopagnosia quirk set this flag and register the signal, upon which it just sets the name to "Unknown" if it's a human. This fixes our issues (in a saner way). ## Why It's Good For The Game Better is prosopagnosia can't be easily obviated by just having screentips on. ## Changelog :cl: fix: Prosopagnosia actually accounts for hover screentips, showing humans as Unknown in those too. /:cl: --- code/__DEFINES/dcs/signals/signals_screentips.dm | 12 ++++++++++++ code/__DEFINES/mobs.dm | 4 ++++ code/_globalvars/bitfields.dm | 4 ++++ .../quirks/negative_quirks/prosopagnosia.dm | 16 ++++++++++++++++ code/game/atom/_atom.dm | 12 ++++++++++-- code/modules/mob/mob_defines.dm | 3 +++ 6 files changed, 49 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_screentips.dm b/code/__DEFINES/dcs/signals/signals_screentips.dm index 8f7326ee2ee..31a851c0483 100644 --- a/code/__DEFINES/dcs/signals/signals_screentips.dm +++ b/code/__DEFINES/dcs/signals/signals_screentips.dm @@ -21,3 +21,15 @@ /// Tells the contextual screentips system that the list context was mutated. #define CONTEXTUAL_SCREENTIP_SET (1 << 0) + + +/// A user screentip name override. +/// These are used for mobs that may override the names of atoms they hover over. +/// Examples include prosopagnosia (sees human names as Unknown regardless of what they are). +/// Called on /mob with a mutable screentip name list, the item being used, and the atom hovered over. +/// A screentip name override list is a list used for returning a string value from the signal. Only the first value matters. +/// If you mutate the list in this signal, you must return SCREENTIP_NAME_SET. +#define COMSIG_MOB_REQUESTING_SCREENTIP_NAME_FROM_USER "mob_requesting_screentip_name_from_user" + +/// Tells the screentips system that the list names was mutated. +#define SCREENTIP_NAME_SET (1 << 0) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index a9e9f5f1aab..82301ffb484 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -44,6 +44,10 @@ #define VENTCRAWLER_NUDE 1 #define VENTCRAWLER_ALWAYS 2 +// Flags for the mob_flags var on /mob +/// May override the names used in screentips of OTHER OBJECTS hovered over. +#define MOB_HAS_SCREENTIPS_NAME_OVERRIDE (1 << 0) + //Mob bio-types flags ///The mob is organic, can heal from medical sutures. #define MOB_ORGANIC (1 << 0) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 7f6735cb5d7..0865867196c 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -259,6 +259,10 @@ DEFINE_BITFIELD(mob_biotypes, list( "MOB_UNDEAD" = MOB_UNDEAD, )) +DEFINE_BITFIELD(mob_flags, list( + "MOB_HAS_SCREENTIPS_NAME_OVERRIDE" = MOB_HAS_SCREENTIPS_NAME_OVERRIDE, +)) + DEFINE_BITFIELD(mob_respiration_type, list( "RESPIRATION_OXYGEN" = RESPIRATION_OXYGEN, "RESPIRATION_N2" = RESPIRATION_N2, diff --git a/code/datums/quirks/negative_quirks/prosopagnosia.dm b/code/datums/quirks/negative_quirks/prosopagnosia.dm index 8634e13bf63..9b41713e6ce 100644 --- a/code/datums/quirks/negative_quirks/prosopagnosia.dm +++ b/code/datums/quirks/negative_quirks/prosopagnosia.dm @@ -7,3 +7,19 @@ medical_record_text = "Patient suffers from prosopagnosia and cannot recognize faces." hardcore_value = 5 mail_goodies = list(/obj/item/skillchip/appraiser) // bad at recognizing faces but good at recognizing IDs + +/datum/quirk/prosopagnosia/add(client/client_source) + RegisterSignal(quirk_holder, COMSIG_MOB_REQUESTING_SCREENTIP_NAME_FROM_USER, PROC_REF(screentip_name_override)) + quirk_holder.mob_flags |= MOB_HAS_SCREENTIPS_NAME_OVERRIDE + +/datum/quirk/prosopagnosia/remove() + UnregisterSignal(quirk_holder, COMSIG_MOB_REQUESTING_SCREENTIP_NAME_FROM_USER) + +/datum/quirk/prosopagnosia/proc/screentip_name_override(datum/source, list/returned_name, obj/item/held_item, atom/hovered) + SIGNAL_HANDLER + + if(!ishuman(hovered)) + return NONE + + returned_name[1] = "Unknown" + return SCREENTIP_NAME_SET diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index b45912c6053..8b6e630c34d 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -881,10 +881,18 @@ var/shift_lmb_ctrl_shift_lmb_line = "" var/extra_lines = 0 var/extra_context = "" + var/used_name = name if(isliving(user) || isovermind(user) || isaicamera(user) || (ghost_screentips && isobserver(user))) var/obj/item/held_item = user.get_active_held_item() + if (user.mob_flags & MOB_HAS_SCREENTIPS_NAME_OVERRIDE) + var/list/returned_name = list(used_name) + + var/name_override_returns = SEND_SIGNAL(user, COMSIG_MOB_REQUESTING_SCREENTIP_NAME_FROM_USER, returned_name, held_item, src) + if (name_override_returns & SCREENTIP_NAME_SET) + used_name = returned_name[1] + if (flags_1 & HAS_CONTEXTUAL_SCREENTIPS_1 || held_item?.item_flags & ITEM_HAS_CONTEXTUAL_SCREENTIPS) var/list/context = list() @@ -950,9 +958,9 @@ new_maptext = "" else //We inline a MAPTEXT() here, because there's no good way to statically add to a string like this - new_maptext = "[name][extra_context]" + new_maptext = "[used_name][extra_context]" - if (length(name) * 10 > active_hud.screentip_text.maptext_width) + if (length(used_name) * 10 > active_hud.screentip_text.maptext_width) INVOKE_ASYNC(src, PROC_REF(set_hover_maptext), client, active_hud, new_maptext) return diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 7f439db6bc9..c5192e681a1 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -63,6 +63,9 @@ ///Cursor icon used when holding shift over things var/examine_cursor_icon = 'icons/effects/mouse_pointers/examine_pointer.dmi' + /// Mob bitflags + var/mob_flags = NONE + /// Whether a mob is alive or dead. TODO: Move this to living - Nodrak (2019, still here) var/stat = CONSCIOUS