From 44acefa73fa3deee6699d3541d6c33e34291de9e Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Thu, 2 Oct 2025 14:36:40 -0500 Subject: [PATCH] More things use trait huds over raw hud management (#93084) --- code/__DEFINES/traits/declarations.dm | 9 +- code/_globalvars/traits/_traits.dm | 6 +- code/_globalvars/traits/admin_tooling.dm | 3 + code/datums/elements/digitalcamo.dm | 8 +- code/datums/hud.dm | 17 +++- .../quirks/positive_quirks/clown_enjoyer.dm | 4 - .../datums/quirks/positive_quirks/mime_fan.dm | 4 - code/datums/status_effects/buffs.dm | 8 +- code/game/data_huds.dm | 32 ++----- code/game/objects/items/storage/holsters.dm | 3 - code/modules/admin/verbs/admingame.dm | 15 ++-- code/modules/antagonists/abductor/abductor.dm | 4 +- code/modules/antagonists/cult/runes.dm | 15 +--- .../fugitive/hunters/hunter_outfits.dm | 4 +- .../paradox_clone/paradox_clone.dm | 5 +- .../antagonists/pirate/pirate_outfits.dm | 7 +- .../bitrunning/antagonists/cyber_police.dm | 7 +- code/modules/clothing/glasses/_glasses.dm | 34 +++----- code/modules/clothing/glasses/hud.dm | 14 ++- code/modules/clothing/under/_under.dm | 85 ++++++++++++------- code/modules/jobs/job_types/clown.dm | 3 +- code/modules/jobs/job_types/mime.dm | 3 +- .../mining_loot/megafauna/the_thing.dm | 4 +- code/modules/mob/living/basic/bots/_bots.dm | 5 +- .../mob/living/basic/bots/honkbots/honkbot.dm | 2 +- .../mob/living/basic/bots/medbot/medbot.dm | 2 +- .../mob/living/basic/bots/vibebot/vibebot.dm | 2 +- .../living/basic/cult/constructs/artificer.dm | 5 +- .../basic/guardian/guardian_types/support.dm | 3 +- .../living/basic/space_fauna/lightgeist.dm | 4 +- .../spider/giant_spider/giant_spiders.dm | 5 +- .../young_spider/young_spider_subtypes.dm | 5 +- .../living/carbon/human/human_stripping.dm | 6 +- .../mob/living/carbon/human/inventory.dm | 2 - .../carbon/human/species_types/abductors.dm | 11 +-- code/modules/mob/living/init_signals.dm | 16 ++++ .../mob/living/silicon/ai/ai_defines.dm | 2 +- code/modules/mob/living/silicon/silicon.dm | 15 ++-- .../mob/living/simple_animal/bot/bot.dm | 5 +- .../mob/living/simple_animal/bot/secbot.dm | 2 +- code/modules/mob/mob.dm | 35 +++++++- code/modules/mob_spawn/mob_spawn.dm | 3 +- code/modules/pai/pai.dm | 4 - code/modules/pai/software.dm | 25 +++--- code/modules/unit_tests/_unit_tests.dm | 1 + code/modules/unit_tests/huds.dm | 18 ++++ .../vehicles/mecha/medical/odysseus.dm | 13 +-- 47 files changed, 249 insertions(+), 236 deletions(-) create mode 100644 code/modules/unit_tests/huds.dm diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index bcf4f4287e8..67d38d4e7db 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -433,7 +433,12 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_UNSTABLE "unstable" #define TRAIT_OIL_FRIED "oil_fried" #define TRAIT_MEDICAL_HUD "med_hud" +#define TRAIT_MEDICAL_HUD_SENSOR_ONLY "med_hud_lesser" #define TRAIT_SECURITY_HUD "sec_hud" +#define TRAIT_SECURITY_HUD_ID_ONLY "sec_hud_lesser" +#define TRAIT_ABDUCTOR_HUD "abductor_hud" +/// Stop the user from seeing the sechud. Only works for trait handled sechuds. +#define TRAIT_BLOCK_SECHUD "block_sechud" /// for something granting you a diagnostic hud #define TRAIT_DIAGNOSTIC_HUD "diag_hud" #define TRAIT_BOT_PATH_HUD "bot_path_hud" @@ -1475,8 +1480,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///Trait given to atoms currently affected by projectile dampeners #define TRAIT_GOT_DAMPENED "got_dampened" -/// humans with this trait will have their health visible to AIs without suit -#define HUMAN_SENSORS_VISIBLE_WITHOUT_SUIT "hmsensorsvisiblewithoutsuit" +/// Having this trait allows the basic health hud to show up for this mob +#define TRAIT_BASIC_HEALTH_HUD_VISIBLE "basic_health_hud_visible" /// Apply to movables to say "hey, this movable is technically flat on the floor, so it'd be mopped up by a mop" #define TRAIT_MOPABLE "mopable" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 74c81f76b13..b445f25381a 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -150,6 +150,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_WALLMOUNTED" = TRAIT_WALLMOUNTED, ), /mob = list( + "TRAIT_ABDUCTOR_HUD" = TRAIT_ABDUCTOR_HUD, "TRAIT_ABDUCTOR_SCIENTIST_TRAINING" = TRAIT_ABDUCTOR_SCIENTIST_TRAINING, "TRAIT_ABDUCTOR_TRAINING" = TRAIT_ABDUCTOR_TRAINING, "TRAIT_ACT_AS_CULTIST" = TRAIT_ACT_AS_CULTIST, @@ -185,6 +186,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_BLOB_ALLY" = TRAIT_BLOB_ALLY, "TRAIT_BLOCKING_PROJECTILES" = TRAIT_BLOCKING_PROJECTILES, "TRAIT_BLOCK_FORMALDEHYDE_METABOLISM" = TRAIT_BLOCK_FORMALDEHYDE_METABOLISM, + "TRAIT_BLOCK_SECHUD" = TRAIT_BLOCK_SECHUD, "TRAIT_BLOCK_SHUTTLE_MOVEMENT" = TRAIT_BLOCK_SHUTTLE_MOVEMENT, "TRAIT_BLOODSHOT_EYES" = TRAIT_BLOODSHOT_EYES, "TRAIT_BLOODY_MESS" = TRAIT_BLOODY_MESS, @@ -373,6 +375,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_MARTIAL_ARTS_IMMUNE" = TRAIT_MARTIAL_ARTS_IMMUNE, "TRAIT_MANSUS_TOUCHED" = TRAIT_MANSUS_TOUCHED, "TRAIT_MEDICAL_HUD" = TRAIT_MEDICAL_HUD, + "TRAIT_MEDICAL_HUD_SENSOR_ONLY" = TRAIT_MEDICAL_HUD_SENSOR_ONLY, "TRAIT_MESON_VISION" = TRAIT_MESON_VISION, "TRAIT_MIME_FAN" = TRAIT_MIME_FAN, "TRAIT_MIMING" = TRAIT_MIMING, @@ -512,6 +515,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ROUGHRIDER" = TRAIT_ROUGHRIDER, "TRAIT_SABRAGE_PRO" = TRAIT_SABRAGE_PRO, "TRAIT_SECURITY_HUD" = TRAIT_SECURITY_HUD, + "TRAIT_SECURITY_HUD_ID_ONLY" = TRAIT_SECURITY_HUD_ID_ONLY, "TRAIT_SEE_WORN_COLOURS" = TRAIT_SEE_WORN_COLOURS, "TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE, "TRAIT_SELF_SURGERY" = TRAIT_SELF_SURGERY, @@ -630,7 +634,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_INVISIBLE_TO_CAMERA" = TRAIT_INVISIBLE_TO_CAMERA, "TRAIT_LEFT_EYE_SCAR" = TRAIT_LEFT_EYE_SCAR, "TRAIT_RIGHT_EYE_SCAR" = TRAIT_RIGHT_EYE_SCAR, - "HUMAN_SENSORS_VISIBLE_WITHOUT_SUIT" = HUMAN_SENSORS_VISIBLE_WITHOUT_SUIT, + "TRAIT_BASIC_HEALTH_HUD_VISIBLE" = TRAIT_BASIC_HEALTH_HUD_VISIBLE, "TRAIT_PREVENT_BLINKING" = TRAIT_PREVENT_BLINKING, "TRAIT_PREVENT_BLINK_LOOPS" = TRAIT_PREVENT_BLINK_LOOPS, "TRAIT_NO_EYELIDS" = TRAIT_NO_EYELIDS, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 0b46d8d9595..5599bbef7ce 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_SPEED_POTIONED" = TRAIT_SPEED_POTIONED, ), /mob = list( + "TRAIT_ABDUCTOR_HUD" = TRAIT_ABDUCTOR_HUD, "TRAIT_ABDUCTOR_SCIENTIST_TRAINING" = TRAIT_ABDUCTOR_SCIENTIST_TRAINING, "TRAIT_ABDUCTOR_TRAINING" = TRAIT_ABDUCTOR_TRAINING, "TRAIT_ACT_AS_CULTIST" = TRAIT_ACT_AS_CULTIST, @@ -172,6 +173,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_MAGICALLY_GIFTED" = TRAIT_MAGICALLY_GIFTED, "TRAIT_MARTIAL_ARTS_IMMUNE" = TRAIT_MARTIAL_ARTS_IMMUNE, "TRAIT_MEDICAL_HUD" = TRAIT_MEDICAL_HUD, + "TRAIT_MEDICAL_HUD_SENSOR_ONLY" = TRAIT_MEDICAL_HUD_SENSOR_ONLY, "TRAIT_MIME_FAN" = TRAIT_MIME_FAN, "TRAIT_MIMING" = TRAIT_MIMING, "TRAIT_MINDSHIELD" = TRAIT_MINDSHIELD, @@ -266,6 +268,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_ROUGHRIDER" = TRAIT_ROUGHRIDER, "TRAIT_SABRAGE_PRO" = TRAIT_SABRAGE_PRO, "TRAIT_SECURITY_HUD" = TRAIT_SECURITY_HUD, + "TRAIT_SECURITY_HUD_ID_ONLY" = TRAIT_SECURITY_HUD_ID_ONLY, "TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE, "TRAIT_SETTLER" = TRAIT_SETTLER, "TRAIT_SHIFTY_EYES" = TRAIT_SHIFTY_EYES, diff --git a/code/datums/elements/digitalcamo.dm b/code/datums/elements/digitalcamo.dm index 1061131f88b..30038f2a55d 100644 --- a/code/datums/elements/digitalcamo.dm +++ b/code/datums/elements/digitalcamo.dm @@ -27,14 +27,14 @@ /datum/element/digitalcamo/proc/HideFromAIHuds(mob/living/target) for(var/mob/living/silicon/ai/AI in GLOB.ai_list) - for (var/hud_type in AI.silicon_huds) - var/datum/atom_hud/silicon_hud = GLOB.huds[hud_type] + for (var/hud_trait in AI.silicon_huds) + var/datum/atom_hud/silicon_hud = GLOB.huds[GLOB.trait_to_hud[hud_trait]] silicon_hud.hide_single_atomhud_from(AI,target) /datum/element/digitalcamo/proc/UnhideFromAIHuds(mob/living/target) for(var/mob/living/silicon/ai/AI in GLOB.ai_list) - for (var/hud_type in AI.silicon_huds) - var/datum/atom_hud/silicon_hud = GLOB.huds[hud_type] + for (var/hud_trait in AI.silicon_huds) + var/datum/atom_hud/silicon_hud = GLOB.huds[GLOB.trait_to_hud[hud_trait]] silicon_hud.unhide_single_atomhud_from(AI,target) /datum/element/digitalcamo/proc/on_examine(datum/source, mob/M, list/examine_list) diff --git a/code/datums/hud.dm b/code/datums/hud.dm index e81ded951fe..8c7678347ee 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -20,11 +20,22 @@ GLOBAL_LIST_INIT(huds, list( DATA_HUD_MALF_APC = new /datum/atom_hud/data/malf_apc(), )) +/// Assoc list of traits to the huds they give. GLOBAL_LIST_INIT(trait_to_hud, list( - TRAIT_SECURITY_HUD = DATA_HUD_SECURITY_ADVANCED, - TRAIT_MEDICAL_HUD = DATA_HUD_MEDICAL_ADVANCED, - TRAIT_DIAGNOSTIC_HUD = DATA_HUD_DIAGNOSTIC, + TRAIT_ABDUCTOR_HUD = DATA_HUD_ABDUCTOR, TRAIT_BOT_PATH_HUD = DATA_HUD_BOT_PATH, + TRAIT_CLOWN_ENJOYER = DATA_HUD_FAN, + TRAIT_DIAGNOSTIC_HUD = DATA_HUD_DIAGNOSTIC, + TRAIT_MEDICAL_HUD = DATA_HUD_MEDICAL_ADVANCED, + TRAIT_MEDICAL_HUD_SENSOR_ONLY = DATA_HUD_MEDICAL_BASIC, + TRAIT_MIME_FAN = DATA_HUD_FAN, + TRAIT_SECURITY_HUD = DATA_HUD_SECURITY_ADVANCED, + TRAIT_SECURITY_HUD_ID_ONLY = DATA_HUD_SECURITY_BASIC, +)) + +/// Assoc list of traits that block other traits' huds to list of hud (traits) that they block +GLOBAL_LIST_INIT(trait_blockers_to_hud, list( + TRAIT_BLOCK_SECHUD = list(TRAIT_SECURITY_HUD, TRAIT_SECURITY_HUD_ID_ONLY), )) /datum/atom_hud diff --git a/code/datums/quirks/positive_quirks/clown_enjoyer.dm b/code/datums/quirks/positive_quirks/clown_enjoyer.dm index 79dd6e0c6bf..cccea9d074e 100644 --- a/code/datums/quirks/positive_quirks/clown_enjoyer.dm +++ b/code/datums/quirks/positive_quirks/clown_enjoyer.dm @@ -25,7 +25,3 @@ /datum/quirk/item_quirk/clown_enjoyer/add_unique(client/client_source) give_item_to_holder(/obj/item/clothing/accessory/clown_enjoyer_pin, list(LOCATION_BACKPACK, LOCATION_HANDS)) - -/datum/quirk/item_quirk/clown_enjoyer/add(client/client_source) - var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN] - fan.show_to(quirk_holder) diff --git a/code/datums/quirks/positive_quirks/mime_fan.dm b/code/datums/quirks/positive_quirks/mime_fan.dm index fea99220259..fb971d10579 100644 --- a/code/datums/quirks/positive_quirks/mime_fan.dm +++ b/code/datums/quirks/positive_quirks/mime_fan.dm @@ -23,7 +23,3 @@ /datum/quirk/item_quirk/mime_fan/add_unique(client/client_source) give_item_to_holder(/obj/item/clothing/accessory/mime_fan_pin, list(LOCATION_BACKPACK, LOCATION_HANDS)) - -/datum/quirk/item_quirk/mime_fan/add(client/client_source) - var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN] - fan.show_to(quirk_holder) diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 6b15ee87de9..c10fed425ca 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -299,16 +299,12 @@ ) //Makes the user passive, it's in their oath not to harm! - owner.add_traits(list(TRAIT_PACIFISM, TRAIT_HIPPOCRATIC_OATH), HIPPOCRATIC_OATH_TRAIT) - var/datum/atom_hud/med_hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] - med_hud.show_to(owner) + owner.add_traits(list(TRAIT_PACIFISM, TRAIT_HIPPOCRATIC_OATH, TRAIT_MEDICAL_HUD), HIPPOCRATIC_OATH_TRAIT) return ..() /datum/status_effect/hippocratic_oath/on_remove() QDEL_NULL(aura_healing) - owner.remove_traits(list(TRAIT_PACIFISM, TRAIT_HIPPOCRATIC_OATH), HIPPOCRATIC_OATH_TRAIT) - var/datum/atom_hud/med_hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] - med_hud.hide_from(owner) + owner.remove_traits(list(TRAIT_PACIFISM, TRAIT_HIPPOCRATIC_OATH, TRAIT_MEDICAL_HUD), HIPPOCRATIC_OATH_TRAIT) /datum/status_effect/hippocratic_oath/get_examine_text() return span_notice("[owner.p_They()] seem[owner.p_s()] to have an aura of healing and helpfulness about [owner.p_them()].") diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 959716d230d..dbda746a728 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -20,36 +20,23 @@ /datum/atom_hud/data/human/medical hud_icons = list(STATUS_HUD, HEALTH_HUD) +/// Sees health (0-100) status (alive, dead), but relies on suit sensors being on /datum/atom_hud/data/human/medical/basic -/datum/atom_hud/data/human/medical/basic/proc/check_sensors(mob/living/carbon/human/human) - if(!istype(human)) - return FALSE - if(HAS_TRAIT(human, HUMAN_SENSORS_VISIBLE_WITHOUT_SUIT)) - return TRUE - var/obj/item/clothing/under/undersuit = human.w_uniform - if(!istype(undersuit)) - return FALSE - if(undersuit.has_sensor < HAS_SENSORS) - return FALSE - if(undersuit.sensor_mode <= SENSOR_VITALS) - return FALSE - return TRUE - -/datum/atom_hud/data/human/medical/basic/add_atom_to_single_mob_hud(mob/M, mob/living/carbon/H) - if(check_sensors(H)) - ..() - -/datum/atom_hud/data/human/medical/basic/proc/update_suit_sensors(mob/living/carbon/H) - check_sensors(H) ? add_atom_to_hud(H) : remove_atom_from_hud(H) +/datum/atom_hud/data/human/medical/basic/add_atom_to_single_mob_hud(mob/requesting_mob, atom/hud_atom) + if(HAS_TRAIT(hud_atom, TRAIT_BASIC_HEALTH_HUD_VISIBLE)) + return ..() +/// Sees health (0-100) status (alive, dead), always /datum/atom_hud/data/human/medical/advanced /datum/atom_hud/data/human/security +/// Only sees ID card job /datum/atom_hud/data/human/security/basic hud_icons = list(ID_HUD) +/// Sees ID card job, implants, and wanted status /datum/atom_hud/data/human/security/advanced hud_icons = list(ID_HUD, IMPSEC_FIRST_HUD, IMPLOYAL_HUD, IMPSEC_SECOND_HUD, WANTED_HUD) @@ -165,11 +152,6 @@ Medical HUD! Basic mode needs suit sensors on. //HOOKS -//called when a human changes suit sensors -/mob/living/carbon/proc/update_suit_sensors() - var/datum/atom_hud/data/human/medical/basic/B = GLOB.huds[DATA_HUD_MEDICAL_BASIC] - B.update_suit_sensors(src) - //called when a living mob changes health /mob/living/proc/med_hud_set_health() set_hud_image_state(HEALTH_HUD, "hud[RoundHealth(src)]") diff --git a/code/game/objects/items/storage/holsters.dm b/code/game/objects/items/storage/holsters.dm index 379d8b1c3bf..5f191ae60f0 100644 --- a/code/game/objects/items/storage/holsters.dm +++ b/code/game/objects/items/storage/holsters.dm @@ -102,6 +102,3 @@ /obj/item/ammo_box/speedloader/c357 = 2, /obj/item/gun/ballistic/revolver/cowboy/nuclear = 1, ), src) - - - diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm index 3787ed3a2ec..342813f4f6f 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -340,15 +340,17 @@ ADMIN_VERB(combo_hud, R_ADMIN, "Toggle Combo HUD", "Toggles the Admin Combo HUD. log_admin("[key_name(user)] toggled their admin combo HUD [user.combo_hud_enabled ? "ON" : "OFF"].") SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Combo HUD", "[user.combo_hud_enabled ? "Enabled" : "Disabled"]")) // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! +/// List of hud traits in the admin combo hud +#define ADMIN_HUDS list(TRAIT_SECURITY_HUD, TRAIT_MEDICAL_HUD, TRAIT_DIAGNOSTIC_HUD, TRAIT_BOT_PATH_HUD) + /client/proc/enable_combo_hud() if (combo_hud_enabled) return combo_hud_enabled = TRUE - for (var/hudtype in list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC, DATA_HUD_BOT_PATH)) - var/datum/atom_hud/atom_hud = GLOB.huds[hudtype] - atom_hud.show_to(mob) + for (var/hudtrait in ADMIN_HUDS) + ADD_TRAIT(mob, hudtrait, ADMIN_TRAIT) for (var/datum/atom_hud/alternate_appearance/basic/antagonist_hud/antag_hud in GLOB.active_alternate_appearances) antag_hud.show_to(mob) @@ -362,9 +364,8 @@ ADMIN_VERB(combo_hud, R_ADMIN, "Toggle Combo HUD", "Toggles the Admin Combo HUD. combo_hud_enabled = FALSE - for (var/hudtype in list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC, DATA_HUD_BOT_PATH)) - var/datum/atom_hud/atom_hud = GLOB.huds[hudtype] - atom_hud.hide_from(mob) + for (var/hudtrait in ADMIN_HUDS) + REMOVE_TRAIT(mob, hudtrait, ADMIN_TRAIT) for (var/datum/atom_hud/alternate_appearance/basic/antagonist_hud/antag_hud in GLOB.active_alternate_appearances) antag_hud.hide_from(mob) @@ -372,6 +373,8 @@ ADMIN_VERB(combo_hud, R_ADMIN, "Toggle Combo HUD", "Toggles the Admin Combo HUD. mob.lighting_cutoff = mob.default_lighting_cutoff() mob.update_sight() +#undef ADMIN_HUDS + ADMIN_VERB(show_traitor_panel, R_ADMIN, "Show Traitor Panel", "Edit mobs's memory and role", ADMIN_CATEGORY_GAME, mob/target_mob) var/datum/mind/target_mind = target_mob.mind if(!target_mind) diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm index 2bc2346aae8..25ee36f6a81 100644 --- a/code/modules/antagonists/abductor/abductor.dm +++ b/code/modules/antagonists/abductor/abductor.dm @@ -74,11 +74,11 @@ objectives += team.objectives finalize_abductor() // We don't want abductors to be converted by other antagonists - owner.add_traits(list(TRAIT_ABDUCTOR_TRAINING, TRAIT_UNCONVERTABLE), ABDUCTOR_ANTAGONIST) + owner.add_traits(list(TRAIT_ABDUCTOR_TRAINING, TRAIT_ABDUCTOR_HUD, TRAIT_UNCONVERTABLE), ABDUCTOR_ANTAGONIST) return ..() /datum/antagonist/abductor/on_removal() - owner.remove_traits(list(TRAIT_ABDUCTOR_TRAINING, TRAIT_UNCONVERTABLE), ABDUCTOR_ANTAGONIST) + owner.remove_traits(list(TRAIT_ABDUCTOR_TRAINING, TRAIT_ABDUCTOR_HUD, TRAIT_UNCONVERTABLE), ABDUCTOR_ANTAGONIST) return ..() /datum/antagonist/abductor/greet() diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 799e54f2c48..2adffa36596 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -1151,14 +1151,13 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0) empulse(T, 0.42*(intensity), 1) var/list/images = list() - var/datum/atom_hud/sec_hud = GLOB.huds[DATA_HUD_SECURITY_ADVANCED] for(var/mob/living/M in GLOB.alive_mob_list) if(!is_valid_z_level(T, get_turf(M))) continue if(ishuman(M)) if(!IS_CULTIST(M)) - sec_hud.hide_from(M) - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(hudFix), M), duration) + ADD_TRAIT(M, TRAIT_BLOCK_SECHUD, CULT_TRAIT) + addtimer(TRAIT_CALLBACK_REMOVE(M, TRAIT_BLOCK_SECHUD, CULT_TRAIT), duration) var/image/A = image('icons/mob/nonhuman-player/cult.dmi',M,"cultist", ABOVE_MOB_LAYER) A.override = 1 add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/noncult, "human_apoc", A, NONE) @@ -1235,13 +1234,3 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0) if(I.icon_state != "bloodsparkles") I.override = TRUE sleep(19 SECONDS) - - - -/proc/hudFix(mob/living/carbon/human/target) - if(!target || !target.client) - return - var/obj/O = target.get_item_by_slot(ITEM_SLOT_EYES) - if(istype(O, /obj/item/clothing/glasses/hud/security)) - var/datum/atom_hud/sec_hud = GLOB.huds[DATA_HUD_SECURITY_ADVANCED] - sec_hud.show_to(target) diff --git a/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm b/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm index 65e22b1ed6c..854ac2d43a4 100644 --- a/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm +++ b/code/modules/antagonists/fugitive/hunters/hunter_outfits.dm @@ -85,8 +85,8 @@ if(istype(equip_to.w_uniform, /obj/item/clothing/under)) var/obj/item/clothing/under/uniform = equip_to.w_uniform - uniform.sensor_mode = NO_SENSORS - uniform.has_sensor = NO_SENSORS + uniform.set_sensor_mode(SENSOR_OFF) + uniform.set_has_sensor(NO_SENSORS) /datum/outfit/russian_hunter/leader name = "Russian Hunter Leader" diff --git a/code/modules/antagonists/paradox_clone/paradox_clone.dm b/code/modules/antagonists/paradox_clone/paradox_clone.dm index d009d9b5d48..18631c51237 100644 --- a/code/modules/antagonists/paradox_clone/paradox_clone.dm +++ b/code/modules/antagonists/paradox_clone/paradox_clone.dm @@ -50,9 +50,8 @@ //dont want anyone noticing there's two now var/mob/living/carbon/human/clone_human = owner.current var/obj/item/clothing/under/sensor_clothes = clone_human.w_uniform - if(sensor_clothes) - sensor_clothes.sensor_mode = SENSOR_OFF - clone_human.update_suit_sensors() + if(istype(sensor_clothes)) + sensor_clothes.set_sensor_mode(SENSOR_OFF) // Perform a quick copy of existing memories. // This may result in some minutely imperfect memories, but it'll do diff --git a/code/modules/antagonists/pirate/pirate_outfits.dm b/code/modules/antagonists/pirate/pirate_outfits.dm index 8976e212c54..e484a8cd097 100644 --- a/code/modules/antagonists/pirate/pirate_outfits.dm +++ b/code/modules/antagonists/pirate/pirate_outfits.dm @@ -25,10 +25,9 @@ outfit_id.update_icon() var/obj/item/clothing/under/pirate_uniform = equipped.w_uniform - if(pirate_uniform) - pirate_uniform.has_sensor = NO_SENSORS - pirate_uniform.sensor_mode = SENSOR_OFF - equipped.update_suit_sensors() + if(istype(pirate_uniform)) + pirate_uniform.set_has_sensor(NO_SENSORS) + pirate_uniform.set_sensor_mode(SENSOR_OFF) /datum/outfit/pirate/captain name = "Space Pirate Captain" diff --git a/code/modules/bitrunning/antagonists/cyber_police.dm b/code/modules/bitrunning/antagonists/cyber_police.dm index 3e335475ac6..bf2606bf815 100644 --- a/code/modules/bitrunning/antagonists/cyber_police.dm +++ b/code/modules/bitrunning/antagonists/cyber_police.dm @@ -33,7 +33,6 @@ /datum/outfit/cyber_police/post_equip(mob/living/carbon/human/user, visuals_only) var/obj/item/clothing/under/officer_uniform = user.w_uniform - if(officer_uniform) - officer_uniform.has_sensor = NO_SENSORS - officer_uniform.sensor_mode = SENSOR_OFF - user.update_suit_sensors() + if(istype(officer_uniform)) + officer_uniform.set_has_sensor(NO_SENSORS) + officer_uniform.set_sensor_mode(SENSOR_OFF) diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 69476431f6d..ce8c3eeebae 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -658,43 +658,29 @@ lighting_cutoff = LIGHTING_CUTOFF_HIGH glass_colour_type = FALSE vision_flags = SEE_TURFS - clothing_traits = list(TRAIT_REAGENT_SCANNER, TRAIT_MADNESS_IMMUNE) - var/list/hudlist = list(DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC, DATA_HUD_SECURITY_ADVANCED, DATA_HUD_BOT_PATH) + clothing_traits = list( + TRAIT_REAGENT_SCANNER, + TRAIT_MADNESS_IMMUNE, + TRAIT_MEDICAL_HUD, + TRAIT_SECURITY_HUD, + TRAIT_DIAGNOSTIC_HUD, + TRAIT_BOT_PATH_HUD, + ) var/xray = FALSE /obj/item/clothing/glasses/debug/Initialize(mapload) . = ..() AddComponent(/datum/component/adjust_fishing_difficulty, -15) -/obj/item/clothing/glasses/debug/equipped(mob/user, slot) - . = ..() - if(!(slot & ITEM_SLOT_EYES)) - return - if(ishuman(user)) - for(var/hud in hudlist) - var/datum/atom_hud/our_hud = GLOB.huds[hud] - our_hud.show_to(user) - user.add_traits(list(TRAIT_MEDICAL_HUD, TRAIT_SECURITY_HUD), GLASSES_TRAIT) - if(xray) - ADD_TRAIT(user, TRAIT_XRAY_VISION, GLASSES_TRAIT) - -/obj/item/clothing/glasses/debug/dropped(mob/user) - . = ..() - user.remove_traits(list(TRAIT_MEDICAL_HUD, TRAIT_SECURITY_HUD, TRAIT_XRAY_VISION), GLASSES_TRAIT) - if(ishuman(user)) - for(var/hud in hudlist) - var/datum/atom_hud/our_hud = GLOB.huds[hud] - our_hud.hide_from(user) - /obj/item/clothing/glasses/debug/click_alt(mob/user) if(!ishuman(user)) return CLICK_ACTION_BLOCKING if(xray) vision_flags &= ~SEE_MOBS|SEE_OBJS - REMOVE_TRAIT(user, TRAIT_XRAY_VISION, GLASSES_TRAIT) + detach_clothing_traits(TRAIT_XRAY_VISION) else vision_flags |= SEE_MOBS|SEE_OBJS - ADD_TRAIT(user, TRAIT_XRAY_VISION, GLASSES_TRAIT) + attach_clothing_traits(TRAIT_XRAY_VISION) xray = !xray var/mob/living/carbon/human/human_user = user human_user.update_sight() diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 4c0c9af89f2..170d624a32f 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -243,18 +243,14 @@ if (wearer.glasses != src) return - for(var/trait in clothing_traits) - REMOVE_CLOTHING_TRAIT(user, trait) - if (TRAIT_MEDICAL_HUD in clothing_traits) - clothing_traits = null + detach_clothing_traits(TRAIT_MEDICAL_HUD) else if (TRAIT_SECURITY_HUD in clothing_traits) - clothing_traits = list(TRAIT_MEDICAL_HUD) + detach_clothing_traits(TRAIT_MEDICAL_HUD) + attach_clothing_traits(TRAIT_SECURITY_HUD) else - clothing_traits = list(TRAIT_SECURITY_HUD) - - for(var/trait in clothing_traits) - ADD_CLOTHING_TRAIT(user, trait) + detach_clothing_traits(TRAIT_MEDICAL_HUD) + attach_clothing_traits(TRAIT_SECURITY_HUD) /datum/action/item_action/switch_hud name = "Switch HUD" diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index d3bcef958f4..8f4468e483a 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -54,7 +54,10 @@ . = ..() if(random_sensor) //make the sensor mode favor higher levels, except coords. - sensor_mode = pick(SENSOR_VITALS, SENSOR_VITALS, SENSOR_VITALS, SENSOR_LIVING, SENSOR_LIVING, SENSOR_COORDS, SENSOR_COORDS, SENSOR_OFF) + set_sensor_mode(pick(SENSOR_VITALS, SENSOR_VITALS, SENSOR_VITALS, SENSOR_LIVING, SENSOR_LIVING, SENSOR_COORDS, SENSOR_COORDS, SENSOR_OFF)) + //ensure we add or remove relevant clothing traits based on base sensor status and mode + update_wearer_status() + register_context() AddElement(/datum/element/update_icon_updates_onmob, flags = ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING|ITEM_SLOT_NECK, body = TRUE) @@ -165,6 +168,12 @@ if((slot & ITEM_SLOT_ICLOTHING) && freshly_laundered) freshly_laundered = FALSE user.add_mood_event("fresh_laundry", /datum/mood_event/fresh_laundry) + update_wearer_status() + +/obj/item/clothing/under/dropped(mob/living/user) + . = ..() + update_wearer_status() + GLOB.suit_sensors_list -= user // Start suit sensor handling @@ -174,9 +183,8 @@ return visible_message(span_warning("[src]'s medical sensors short out!"), blind_message = span_warning("The [src] makes an electronic sizzling sound!"), vision_distance = COMBAT_MESSAGE_RANGE) - has_sensor = BROKEN_SENSORS + set_has_sensor(BROKEN_SENSORS) sensor_malfunction() - update_wearer_status() /** * Repair the suit sensors and update the mob's status on the global sensor list. @@ -200,8 +208,7 @@ cabling.visible_message(span_notice("[user] repairs the suit sensors on [src] with [cabling].")) playsound(source = src, soundin = 'sound/effects/sparks/sparks4.ogg', vol = 100, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE, ignore_walls = FALSE) - has_sensor = HAS_SENSORS - update_wearer_status() + set_has_sensor(HAS_SENSORS) return TRUE @@ -211,29 +218,46 @@ do_sparks(number = 2, cardinal_only = FALSE, source = src) addtimer(CALLBACK(src, PROC_REF(sensor_malfunction)), rand(BROKEN_SPARKS_MIN, BROKEN_SPARKS_MAX * 0.5), TIMER_UNIQUE | TIMER_NO_HASH_WAIT) -/// If the item is being worn, update the mob's status on the global sensor list +/// Changes whether the suit sensor has a sensor, or if it's broken, etc. and handles updating mob status if applicable +/obj/item/clothing/under/proc/set_has_sensor(new_has_sensor) + if(new_has_sensor == has_sensor) + return FALSE + if(new_has_sensor < BROKEN_SENSORS || new_has_sensor > LOCKED_SENSORS) + stack_trace("Invalid has_sensor value [new_has_sensor] passed to set_has_sensor()") + return FALSE + has_sensor = new_has_sensor + update_wearer_status() + return TRUE + +/// Changes the active sensor mode of the suit and handles updating mob status if applicable +/obj/item/clothing/under/proc/set_sensor_mode(new_sensor_mode) + if(new_sensor_mode == sensor_mode) + return FALSE + if(new_sensor_mode < SENSOR_OFF || new_sensor_mode > SENSOR_COORDS) + stack_trace("Invalid sensor_mode value [new_sensor_mode] passed to set_sensor_mode()") + return FALSE + sensor_mode = new_sensor_mode + update_wearer_status() + return TRUE + +/// Updates the sensor status and any mobs status if applicable /obj/item/clothing/under/proc/update_wearer_status() - if(!ishuman(loc)) + if(has_sensor <= NO_SENSORS || sensor_mode <= SENSOR_VITALS) + detach_clothing_traits(TRAIT_BASIC_HEALTH_HUD_VISIBLE) + else + attach_clothing_traits(TRAIT_BASIC_HEALTH_HUD_VISIBLE) + + if(!ishuman(loc) || isdummy(loc)) return - var/mob/living/carbon/human/ooman = loc - ooman.update_suit_sensors() - ooman.med_hud_set_status() + var/mob/living/carbon/human/wearer = loc -/mob/living/carbon/human/update_suit_sensors() - . = ..() - update_sensor_list() - -/// Adds or removes a mob from the global suit sensors list based on sensor status and mode -/mob/living/carbon/human/proc/update_sensor_list() - var/obj/item/clothing/under/uniform = w_uniform - if(istype(uniform) && uniform.has_sensor > NO_SENSORS && uniform.sensor_mode) - GLOB.suit_sensors_list |= src + if(has_sensor >= HAS_SENSORS && sensor_mode >= SENSOR_LIVING) + GLOB.suit_sensors_list |= wearer else - GLOB.suit_sensors_list -= src + GLOB.suit_sensors_list -= wearer -/mob/living/carbon/human/dummy/update_sensor_list() - return + wearer.med_hud_set_status() /obj/item/clothing/under/emp_act(severity) . = ..() @@ -244,13 +268,11 @@ if(severity <= EMP_HEAVY) break_sensors() + return - else - sensor_mode = pick(SENSOR_OFF, SENSOR_OFF, SENSOR_OFF, SENSOR_LIVING, SENSOR_LIVING, SENSOR_VITALS, SENSOR_VITALS, SENSOR_COORDS) - playsound(source = src, soundin = 'sound/effects/sparks/sparks3.ogg', vol = 75, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE, ignore_walls = FALSE) - visible_message(span_warning("The [src]'s medical sensors flash and change rapidly!"), blind_message = span_warning("The [src] makes an electronic sizzling sound!"), vision_distance = COMBAT_MESSAGE_RANGE) - - update_wearer_status() + set_sensor_mode(pick(SENSOR_OFF, SENSOR_OFF, SENSOR_OFF, SENSOR_LIVING, SENSOR_LIVING, SENSOR_VITALS, SENSOR_VITALS, SENSOR_COORDS)) + playsound(source = src, soundin = 'sound/effects/sparks/sparks3.ogg', vol = 75, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE, ignore_walls = FALSE) + visible_message(span_warning("The [src]'s medical sensors flash and change rapidly!"), blind_message = span_warning("The [src] makes an electronic sizzling sound!"), vision_distance = COMBAT_MESSAGE_RANGE) /** * Called by medical scanners a simple summary of the status @@ -399,7 +421,7 @@ if(!can_toggle_sensors(user_mob)) return - sensor_mode = modes.Find(switchMode) - 1 + set_sensor_mode(modes.Find(switchMode) - 1) if (loc == user_mob) switch(sensor_mode) if(SENSOR_OFF) @@ -411,15 +433,12 @@ if(SENSOR_COORDS) to_chat(user_mob, span_notice("Your suit will now report your exact vital lifesigns as well as your coordinate position.")) - update_wearer_status() - /obj/item/clothing/under/item_ctrl_click(mob/user) if(!can_toggle_sensors(user)) return CLICK_ACTION_BLOCKING - sensor_mode = SENSOR_COORDS + set_sensor_mode(SENSOR_COORDS) balloon_alert(user, "set to tracking") - update_wearer_status() return CLICK_ACTION_SUCCESS /// Checks if the toggler is allowed to toggle suit sensors currently diff --git a/code/modules/jobs/job_types/clown.dm b/code/modules/jobs/job_types/clown.dm index 0d6c90b8d6a..a7a7fc77896 100644 --- a/code/modules/jobs/job_types/clown.dm +++ b/code/modules/jobs/job_types/clown.dm @@ -101,6 +101,5 @@ H.fully_replace_character_name(H.real_name, pick(GLOB.clown_names)) //rename the mob AFTER they're equipped so their ID gets updated properly. H.dna.add_mutation(/datum/mutation/clumsy, MUTATION_SOURCE_CLOWN_CLUMSINESS) - var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN] - fan.show_to(H) + ADD_TRAIT(H, TRAIT_CLOWN_ENJOYER, INNATE_TRAIT) H.faction |= FACTION_CLOWN diff --git a/code/modules/jobs/job_types/mime.dm b/code/modules/jobs/job_types/mime.dm index 50c48509dec..f4bc4955208 100644 --- a/code/modules/jobs/job_types/mime.dm +++ b/code/modules/jobs/job_types/mime.dm @@ -77,8 +77,7 @@ var/datum/action/cooldown/spell/vow_of_silence/vow = new(H.mind) vow.Grant(H) - var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN] - fan.show_to(H) + ADD_TRAIT(H, TRAIT_MIME_FAN, INNATE_TRAIT) /obj/item/book/granter/action/spell/mime/mimery name = "Guide to Dank Mimery" diff --git a/code/modules/mining/lavaland/mining_loot/megafauna/the_thing.dm b/code/modules/mining/lavaland/mining_loot/megafauna/the_thing.dm index cea00930325..19c04179d25 100644 --- a/code/modules/mining/lavaland/mining_loot/megafauna/the_thing.dm +++ b/code/modules/mining/lavaland/mining_loot/megafauna/the_thing.dm @@ -37,7 +37,7 @@ /obj/item/organ/brain/cybernetic/ai/on_mob_insert(mob/living/carbon/brain_owner, special, movement_flags) . = ..() - brain_owner.add_traits(list(HUMAN_SENSORS_VISIBLE_WITHOUT_SUIT, TRAIT_NO_MINDSWAP, TRAIT_CORPSELOCKED), REF(src)) + brain_owner.add_traits(list(TRAIT_BASIC_HEALTH_HUD_VISIBLE, TRAIT_NO_MINDSWAP, TRAIT_CORPSELOCKED), REF(src)) update_med_hud_status(brain_owner) RegisterSignal(brain_owner, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(update_med_hud_status)) RegisterSignal(brain_owner, COMSIG_CLICK, PROC_REF(owner_clicked)) @@ -53,7 +53,7 @@ /obj/item/organ/brain/cybernetic/ai/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) undeploy() . = ..() - organ_owner.remove_traits(list(HUMAN_SENSORS_VISIBLE_WITHOUT_SUIT, TRAIT_NO_MINDSWAP, TRAIT_CORPSELOCKED), REF(src)) + organ_owner.remove_traits(list(TRAIT_BASIC_HEALTH_HUD_VISIBLE, TRAIT_NO_MINDSWAP, TRAIT_CORPSELOCKED), REF(src)) UnregisterSignal(organ_owner, list(COMSIG_LIVING_HEALTH_UPDATE, COMSIG_CLICK, COMSIG_MOB_GET_STATUS_TAB_ITEMS, COMSIG_MOB_MIND_BEFORE_MIDROUND_ROLL, COMSIG_QDELETING, COMSIG_LIVING_PRE_WABBAJACKED)) var/obj/item/implant/radio/radio = radio_weakref.resolve() diff --git a/code/modules/mob/living/basic/bots/_bots.dm b/code/modules/mob/living/basic/bots/_bots.dm index 4cdf7f8ecf3..58ecef8863d 100644 --- a/code/modules/mob/living/basic/bots/_bots.dm +++ b/code/modules/mob/living/basic/bots/_bots.dm @@ -84,7 +84,7 @@ GLOBAL_LIST_INIT(command_strings, list( var/list/current_pathed_turfs = list() ///The type of data HUD the bot uses. Diagnostic by default. - var/data_hud_type = DATA_HUD_DIAGNOSTIC + var/data_hud_type = TRAIT_DIAGNOSTIC_HUD /// If true we will allow ghosts to control this mob var/can_be_possessed = FALSE /// Message to display upon possession @@ -139,8 +139,7 @@ GLOBAL_LIST_INIT(command_strings, list( //If a bot has its own HUD (for player bots), provide it. if(!isnull(data_hud_type)) - var/datum/atom_hud/datahud = GLOB.huds[data_hud_type] - datahud.show_to(src) + ADD_TRAIT(src, data_hud_type, INNATE_TRAIT) if(mapload && is_station_level(z) && (bot_mode_flags & BOT_MODE_CAN_BE_SAPIENT) && (bot_mode_flags & BOT_MODE_ROUNDSTART_POSSESSION)) enable_possession(mapload = mapload) diff --git a/code/modules/mob/living/basic/bots/honkbots/honkbot.dm b/code/modules/mob/living/basic/bots/honkbots/honkbot.dm index 13caade7c94..68fdb431a96 100644 --- a/code/modules/mob/living/basic/bots/honkbots/honkbot.dm +++ b/code/modules/mob/living/basic/bots/honkbots/honkbot.dm @@ -12,7 +12,7 @@ bot_mode_flags = BOT_MODE_ON | BOT_MODE_REMOTE_ENABLED | BOT_MODE_CAN_BE_SAPIENT | BOT_MODE_AUTOPATROL | BOT_MODE_ROUNDSTART_POSSESSION hackables = "sound control systems" path_image_color = "#FF69B4" - data_hud_type = DATA_HUD_SECURITY_BASIC + data_hud_type = TRAIT_SECURITY_HUD_ID_ONLY additional_access = /datum/id_trim/job/clown possessed_message = "You are a honkbot! Make sure the crew are having a great time!" ///our voicelines diff --git a/code/modules/mob/living/basic/bots/medbot/medbot.dm b/code/modules/mob/living/basic/bots/medbot/medbot.dm index 4a60ca178a7..7b5bf6c5869 100644 --- a/code/modules/mob/living/basic/bots/medbot/medbot.dm +++ b/code/modules/mob/living/basic/bots/medbot/medbot.dm @@ -19,7 +19,7 @@ radio_key = /obj/item/encryptionkey/headset_med radio_channel = RADIO_CHANNEL_MEDICAL bot_type = MED_BOT - data_hud_type = DATA_HUD_MEDICAL_ADVANCED + data_hud_type = TRAIT_MEDICAL_HUD hackables = "health processor circuits" possessed_message = "You are a medbot! Ensure good health among the crew to the best of your ability!" diff --git a/code/modules/mob/living/basic/bots/vibebot/vibebot.dm b/code/modules/mob/living/basic/bots/vibebot/vibebot.dm index c8e2d713623..b881e74fc92 100644 --- a/code/modules/mob/living/basic/bots/vibebot/vibebot.dm +++ b/code/modules/mob/living/basic/bots/vibebot/vibebot.dm @@ -14,7 +14,7 @@ radio_key = /obj/item/encryptionkey/headset_service radio_channel = RADIO_CHANNEL_SERVICE bot_type = VIBE_BOT - data_hud_type = DATA_HUD_DIAGNOSTIC + data_hud_type = TRAIT_DIAGNOSTIC_HUD path_image_color = "#2cac12" possessed_message = "You are a vibebot! Maintain the station's vibes to the best of your ability!" diff --git a/code/modules/mob/living/basic/cult/constructs/artificer.dm b/code/modules/mob/living/basic/cult/constructs/artificer.dm index 0e65e8ae5ef..f16ef6d35a1 100644 --- a/code/modules/mob/living/basic/cult/constructs/artificer.dm +++ b/code/modules/mob/living/basic/cult/constructs/artificer.dm @@ -30,14 +30,11 @@ can_repair = TRUE can_repair_self = TRUE smashes_walls = TRUE - ///The health HUD applied to this mob. - var/health_hud = DATA_HUD_MEDICAL_ADVANCED /mob/living/basic/construct/artificer/Initialize(mapload) . = ..() AddElement(/datum/element/ai_retaliate) - var/datum/atom_hud/datahud = GLOB.huds[health_hud] - datahud.show_to(src) + ADD_TRAIT(src, TRAIT_MEDICAL_HUD, INNATE_TRAIT) /// Hostile NPC version. Heals nearby constructs and cult structures, avoids targets that aren't extremely hurt. /mob/living/basic/construct/artificer/hostile diff --git a/code/modules/mob/living/basic/guardian/guardian_types/support.dm b/code/modules/mob/living/basic/guardian/guardian_types/support.dm index 46b69652cf5..3e05b403fbc 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/support.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/support.dm @@ -27,8 +27,7 @@ after_healed = CALLBACK(src, PROC_REF(after_healed)),\ ) - var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] - medsensor.show_to(src) + ADD_TRAIT(src, TRAIT_MEDICAL_HUD, INNATE_TRAIT) var/datum/action/cooldown/mob_cooldown/guardian_bluespace_beacon/teleport = new(src) teleport.Grant(src) diff --git a/code/modules/mob/living/basic/space_fauna/lightgeist.dm b/code/modules/mob/living/basic/space_fauna/lightgeist.dm index 8fe00b40484..1237df72584 100644 --- a/code/modules/mob/living/basic/space_fauna/lightgeist.dm +++ b/code/modules/mob/living/basic/space_fauna/lightgeist.dm @@ -48,13 +48,11 @@ /mob/living/basic/lightgeist/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) + ADD_TRAIT(src, TRAIT_MEDICAL_HUD, INNATE_TRAIT) remove_verb(src, /mob/living/verb/pulled) remove_verb(src, /mob/verb/me_verb) - var/datum/atom_hud/medical_sensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] - medical_sensor.show_to(src) - AddElement(/datum/element/simple_flying) AddComponent(\ /datum/component/healing_touch,\ diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm index 68629154ab6..6d0f3771a82 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm @@ -169,8 +169,6 @@ web_speed = 0.25 web_type = /datum/action/cooldown/mob_cooldown/lay_web/sealer menu_description = "Avarage speed spider able to heal other spiders and itself together with a fast web laying capability, has low damage and health." - ///The health HUD applied to the mob. - var/health_hud = DATA_HUD_MEDICAL_ADVANCED ///Used in the caves away mission. /mob/living/basic/spider/giant/nurse/away_caves @@ -179,8 +177,7 @@ /mob/living/basic/spider/giant/nurse/Initialize(mapload) . = ..() - var/datum/atom_hud/datahud = GLOB.huds[health_hud] - datahud.show_to(src) + ADD_TRAIT(src, TRAIT_MEDICAL_HUD, INNATE_TRAIT) AddComponent(/datum/component/healing_touch,\ heal_brute = 10,\ diff --git a/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider_subtypes.dm b/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider_subtypes.dm index e245f3adcc9..a3f0fc1c64f 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider_subtypes.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/young_spider/young_spider_subtypes.dm @@ -92,13 +92,10 @@ speed = 0.7 web_speed = 0.5 web_type = /datum/action/cooldown/mob_cooldown/lay_web/sealer - ///The health HUD applied to the mob. - var/health_hud = DATA_HUD_MEDICAL_ADVANCED /mob/living/basic/spider/growing/young/nurse/Initialize(mapload) . = ..() - var/datum/atom_hud/datahud = GLOB.huds[health_hud] - datahud.show_to(src) + ADD_TRAIT(src, TRAIT_MEDICAL_HUD, INNATE_TRAIT) AddComponent(/datum/component/healing_touch,\ heal_brute = 15,\ diff --git a/code/modules/mob/living/carbon/human/human_stripping.dm b/code/modules/mob/living/carbon/human/human_stripping.dm index d2c09ec258a..961d1592baa 100644 --- a/code/modules/mob/living/carbon/human/human_stripping.dm +++ b/code/modules/mob/living/carbon/human/human_stripping.dm @@ -118,15 +118,11 @@ GLOBAL_LIST_INIT(strippable_human_items, create_strippable_list(list( return to_chat(source, span_notice("[user] is trying to adjust your [jumpsuit.name]'s sensor.")) - if(!do_after(user, jumpsuit.strip_delay * 0.5, source)) // takes the same amount of time as adjusting it + if(!do_after(user, jumpsuit.strip_delay * 0.5, source) || !jumpsuit.set_sensor_mode(new_mode)) // takes the same amount of time as adjusting it source.balloon_alert(user, "failed!") return source.balloon_alert(user, "changed sensors") - jumpsuit.sensor_mode = new_mode to_chat(source, span_notice("[user] successfully adjusted your [jumpsuit.name]'s sensor.")) - if(ishuman(source)) - var/mob/living/carbon/human/humano = source - humano.update_suit_sensors() /datum/strippable_item/mob_item_slot/jumpsuit/proc/do_strip_accessory(atom/source, mob/user, obj/item/clothing/under/jumpsuit) var/list/accessory_choices = list() diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index a2dfad08eee..ff9abf55fd6 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -185,7 +185,6 @@ if(w_uniform) return w_uniform = equipping - update_suit_sensors() update_worn_undersuit() if(ITEM_SLOT_LPOCKET) l_store = equipping @@ -227,7 +226,6 @@ update_worn_oversuit() else if(item_dropping == w_uniform) w_uniform = null - update_suit_sensors() if(!QDELETED(src)) update_worn_undersuit() if(invdrop) diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm index 77ba4b89d6d..7178d569f01 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductors.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm @@ -3,6 +3,7 @@ id = SPECIES_ABDUCTOR sexes = FALSE inherent_traits = list( + TRAIT_ABDUCTOR_HUD, TRAIT_CHUNKYFINGERS_IGNORE_BATON, TRAIT_NEVER_WOUNDED, TRAIT_NOBLOOD, @@ -32,16 +33,6 @@ return "Abductors do not need to breathe, eat, do not have blood, a heart, stomach, or lungs and cannot be infected by human viruses. \ Their hardy physique prevents their skin from being wounded or dismembered, but their chunky tridactyl hands make it hard to operate human equipment." -/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load, regenerate_icons) - . = ..() - var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR] - abductor_hud.show_to(C) - -/datum/species/abductor/on_species_loss(mob/living/carbon/C) - . = ..() - var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR] - abductor_hud.hide_from(C) - /datum/species/abductor/get_species_description() return "Abductors, colloquially known as \"Greys\" (or \"Grays\"), \ are, three fingered, pale skinned inquisitive aliens who can't communicate well to the average crew-member." diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm index d60a99f3f41..eeaeb9d3b72 100644 --- a/code/modules/mob/living/init_signals.dm +++ b/code/modules/mob/living/init_signals.dm @@ -70,6 +70,10 @@ RegisterSignal(src, COMSIG_MOVABLE_EDIT_UNIQUE_IMMERSE_OVERLAY, PROC_REF(edit_immerse_overlay)) + RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_BASIC_HEALTH_HUD_VISIBLE), PROC_REF(add_to_basic_health_hud)) + RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_BASIC_HEALTH_HUD_VISIBLE), PROC_REF(remove_from_basic_health_hud)) + + /// Called when [TRAIT_KNOCKEDOUT] is added to the mob. /mob/living/proc/on_knockedout_trait_gain(datum/source) SIGNAL_HANDLER @@ -297,3 +301,15 @@ /mob/living/proc/on_hearing_regain() SIGNAL_HANDLER refresh_looping_ambience() + +/// When gaining [TRAIT_BASIC_HEALTH_HUD_VISIBLE], add to the basic health hud +/mob/living/proc/add_to_basic_health_hud(datum/source) + SIGNAL_HANDLER + var/datum/atom_hud/data/human/medical/basic/hud = GLOB.huds[DATA_HUD_MEDICAL_BASIC] + hud.add_atom_to_hud(src) + +/// When losing [TRAIT_BASIC_HEALTH_HUD_VISIBLE], remove from the basic health hud +/mob/living/proc/remove_from_basic_health_hud(datum/source) + SIGNAL_HANDLER + var/datum/atom_hud/data/human/medical/basic/hud = GLOB.huds[DATA_HUD_MEDICAL_BASIC] + hud.remove_atom_from_hud(src) diff --git a/code/modules/mob/living/silicon/ai/ai_defines.dm b/code/modules/mob/living/silicon/ai/ai_defines.dm index 2ce27d098a8..e1399a1ddb1 100644 --- a/code/modules/mob/living/silicon/ai/ai_defines.dm +++ b/code/modules/mob/living/silicon/ai/ai_defines.dm @@ -12,7 +12,7 @@ mob_size = MOB_SIZE_LARGE can_buckle_to = FALSE - silicon_huds = list(DATA_HUD_MEDICAL_BASIC, DATA_HUD_SECURITY_BASIC, DATA_HUD_DIAGNOSTIC, DATA_HUD_BOT_PATH) + silicon_huds = list(TRAIT_MEDICAL_HUD_SENSOR_ONLY, TRAIT_SECURITY_HUD_ID_ONLY, TRAIT_DIAGNOSTIC_HUD, TRAIT_BOT_PATH_HUD) radio = /obj/item/radio/headset/silicon/ai radiomod = ";" //AIs will, by default, state their laws on the internal radio. diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index a5a08116aff..ae8b3531e7d 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -38,7 +38,7 @@ ///Are our siliconHUDs on? TRUE for yes, FALSE for no. var/sensors_on = TRUE - var/list/silicon_huds = list(DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_SECURITY_ADVANCED, DATA_HUD_DIAGNOSTIC) + var/list/silicon_huds = list(TRAIT_MEDICAL_HUD, TRAIT_SECURITY_HUD, TRAIT_DIAGNOSTIC_HUD) var/law_change_counter = 0 var/obj/machinery/camera/silicon/builtInCamera @@ -417,15 +417,16 @@ /mob/living/silicon/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //Secbots won't hunt silicon units return -10 +/// Innate, toggleable silicon HUDs +#define SILICON_HUD_TRAIT "silicon_hud" + /mob/living/silicon/proc/remove_sensors() - for (var/hud_type in silicon_huds) - var/datum/atom_hud/silicon_hud = GLOB.huds[hud_type] - silicon_hud.hide_from(src) + remove_traits(silicon_huds, SILICON_HUD_TRAIT) /mob/living/silicon/proc/add_sensors() - for (var/hud_type in silicon_huds) - var/datum/atom_hud/silicon_hud = GLOB.huds[hud_type] - silicon_hud.show_to(src) + add_traits(silicon_huds, SILICON_HUD_TRAIT) + +#undef SILICON_HUD_TRAIT /mob/living/silicon/proc/toggle_sensors() if(incapacitated) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index cb740063e55..7fbe53a584e 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -94,7 +94,7 @@ var/turf/nearest_beacon_loc ///The type of data HUD the bot uses. Diagnostic by default. - var/data_hud_type = DATA_HUD_DIAGNOSTIC + var/data_hud_type = TRAIT_DIAGNOSTIC_HUD var/datum/atom_hud/data/bot_path/private/path_hud var/path_image_icon = 'icons/mob/silicon/aibots.dmi' var/path_image_icon_state = "path_indicator" @@ -191,8 +191,7 @@ //If a bot has its own HUD (for player bots), provide it. if(!isnull(data_hud_type)) - var/datum/atom_hud/datahud = GLOB.huds[data_hud_type] - datahud.show_to(src) + ADD_TRAIT(src, data_hud_type, INNATE_TRAIT) if(path_hud) path_hud.add_atom_to_hud(src) path_hud.show_to(src) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index d902fdf1eff..bf21d14b9f0 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -20,7 +20,7 @@ radio_channel = RADIO_CHANNEL_SECURITY //Security channel bot_type = SEC_BOT bot_mode_flags = ~BOT_MODE_CAN_BE_SAPIENT - data_hud_type = DATA_HUD_SECURITY_ADVANCED + data_hud_type = TRAIT_SECURITY_HUD hackables = "target identification systems" path_image_color = COLOR_RED possessed_message = "You are a securitron! Guard the station to the best of your ability!" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4f5432ee1f0..600358726a9 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1665,13 +1665,44 @@ for(var/hud_trait in GLOB.trait_to_hud) RegisterSignal(src, SIGNAL_ADDTRAIT(hud_trait), PROC_REF(hud_trait_enabled)) RegisterSignal(src, SIGNAL_REMOVETRAIT(hud_trait), PROC_REF(hud_trait_disabled)) + for(var/hud_trait in GLOB.trait_blockers_to_hud) + RegisterSignal(src, SIGNAL_ADDTRAIT(hud_trait), PROC_REF(hud_trait_blocker_gained)) + RegisterSignal(src, SIGNAL_REMOVETRAIT(hud_trait), PROC_REF(hud_trait_blocker_lost)) /mob/proc/hud_trait_enabled(datum/source, new_trait) SIGNAL_HANDLER + + for(var/blocker, blocked_traits in GLOB.trait_blockers_to_hud) + if(HAS_TRAIT(src, blocker) && (new_trait in blocked_traits)) + return + var/datum/atom_hud/datahud = GLOB.huds[GLOB.trait_to_hud[new_trait]] datahud.show_to(src) -/mob/proc/hud_trait_disabled(datum/source, new_trait) +/mob/proc/hud_trait_disabled(datum/source, lost_trait) SIGNAL_HANDLER - var/datum/atom_hud/datahud = GLOB.huds[GLOB.trait_to_hud[new_trait]] + + for(var/blocker, blocked_traits in GLOB.trait_blockers_to_hud) + if(HAS_TRAIT(src, blocker) && (lost_trait in blocked_traits)) + return // it may seem counterintuitive to check for blockers on trait removal, the blocker now has total reign over whether the hud should come back + + var/datum/atom_hud/datahud = GLOB.huds[GLOB.trait_to_hud[lost_trait]] datahud.hide_from(src) + +/mob/proc/hud_trait_blocker_gained(datum/source, new_trait) + SIGNAL_HANDLER + + for(var/trait in GLOB.trait_blockers_to_hud[new_trait]) + if(!HAS_TRAIT(src, trait)) + continue + var/datum/atom_hud/datahud = GLOB.huds[GLOB.trait_to_hud[trait]] + datahud.hide_from(src) + +/mob/proc/hud_trait_blocker_lost(datum/source, new_trait) + SIGNAL_HANDLER + + for(var/trait in GLOB.trait_blockers_to_hud[new_trait]) + if(!HAS_TRAIT(src, trait)) + continue + var/datum/atom_hud/datahud = GLOB.huds[GLOB.trait_to_hud[trait]] + datahud.show_to(src) diff --git a/code/modules/mob_spawn/mob_spawn.dm b/code/modules/mob_spawn/mob_spawn.dm index fe25ac2dcdb..d9fb401680e 100644 --- a/code/modules/mob_spawn/mob_spawn.dm +++ b/code/modules/mob_spawn/mob_spawn.dm @@ -344,8 +344,7 @@ // Or on crew monitors var/obj/item/clothing/under/sensor_clothes = spawned_human.w_uniform if(istype(sensor_clothes)) - sensor_clothes.sensor_mode = SENSOR_OFF - spawned_human.update_suit_sensors() + sensor_clothes.set_sensor_mode(SENSOR_OFF) //don't use this in subtypes, just add 1000 brute yourself. that being said, this is a type that has 1000 brute. it doesn't really have a home anywhere else, it just needs to exist /obj/effect/mob_spawn/corpse/human/damaged diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm index 02f83bc1865..7ccb16810b9 100644 --- a/code/modules/pai/pai.dm +++ b/code/modules/pai/pai.dm @@ -59,12 +59,8 @@ var/master_name /// DNA string for owner verification var/master_dna - /// Toggles whether the Medical HUD is active or not - var/medHUD = FALSE /// Used as currency to purchase different abilities var/ram = 100 - /// Toggles whether the Security HUD is active or not - var/secHUD = FALSE /// The current leash to the owner var/datum/component/leash/leash diff --git a/code/modules/pai/software.dm b/code/modules/pai/software.dm index f0b61e05929..08212301f35 100644 --- a/code/modules/pai/software.dm +++ b/code/modules/pai/software.dm @@ -219,6 +219,9 @@ stack_trace("Invalid mode passed to host scan: [mode || "null"]") return FALSE +/// Huds from PAI software +#define PAI_HUD_TRAIT "pai_hud" + /** * Proc that toggles any active huds based on the option. * @@ -227,18 +230,16 @@ /mob/living/silicon/pai/proc/toggle_hud(mode) if(isnull(mode)) return FALSE - var/datum/atom_hud/hud - var/hud_on if(mode == PAI_TOGGLE_MEDICAL_HUD) - hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] - medHUD = !medHUD - hud_on = medHUD + if(HAS_TRAIT_FROM(src, TRAIT_MEDICAL_HUD, PAI_HUD_TRAIT)) + REMOVE_TRAIT(src, TRAIT_MEDICAL_HUD, PAI_HUD_TRAIT) + else + ADD_TRAIT(src, TRAIT_MEDICAL_HUD, PAI_HUD_TRAIT) if(mode == PAI_TOGGLE_SECURITY_HUD) - hud = GLOB.huds[DATA_HUD_SECURITY_ADVANCED] - secHUD = !secHUD - hud_on = secHUD - if(hud_on) - hud.show_to(src) - else - hud.hide_from(src) + if(HAS_TRAIT_FROM(src, TRAIT_SECURITY_HUD, PAI_HUD_TRAIT)) + REMOVE_TRAIT(src, TRAIT_SECURITY_HUD, PAI_HUD_TRAIT) + else + ADD_TRAIT(src, TRAIT_SECURITY_HUD, PAI_HUD_TRAIT) return TRUE + +#undef PAI_HUD_TRAIT diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index a809b6b19dd..ad13a50d18e 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -178,6 +178,7 @@ #include "holder_loving.dm" #include "holidays.dm" #include "holofan_placement.dm" +#include "huds.dm" #include "hulk.dm" #include "human_through_recycler.dm" #include "hunger_curse.dm" diff --git a/code/modules/unit_tests/huds.dm b/code/modules/unit_tests/huds.dm new file mode 100644 index 00000000000..8aadb770260 --- /dev/null +++ b/code/modules/unit_tests/huds.dm @@ -0,0 +1,18 @@ +/// Tests huds are applied and removed correctly when relevant traits are added/removed +/datum/unit_test/huds + +/datum/unit_test/huds/Run() + var/datum/atom_hud/testhud = GLOB.huds[GLOB.trait_to_hud[TRAIT_SECURITY_HUD]] + var/mob/living/carbon/human/consistent/dummy = allocate(__IMPLIED_TYPE__) + + ADD_TRAIT(dummy, TRAIT_SECURITY_HUD, TRAIT_SOURCE_UNIT_TESTS) + TEST_ASSERT(!!testhud.hud_users_all_z_levels[dummy], "HUD not applied when trait of HUD was added") + + ADD_TRAIT(dummy, TRAIT_BLOCK_SECHUD, TRAIT_SOURCE_UNIT_TESTS) + TEST_ASSERT(!testhud.hud_users_all_z_levels[dummy], "HUD not removed when trait blocking HUD was added") + + REMOVE_TRAIT(dummy, TRAIT_BLOCK_SECHUD, TRAIT_SOURCE_UNIT_TESTS) + TEST_ASSERT(!!testhud.hud_users_all_z_levels[dummy], "HUD not reapplied when trait blocking HUD was removed") + + REMOVE_TRAIT(dummy, TRAIT_SECURITY_HUD, TRAIT_SOURCE_UNIT_TESTS) + TEST_ASSERT(!testhud.hud_users_all_z_levels[dummy], "HUD not removed when trait of HUD was removed") diff --git a/code/modules/vehicles/mecha/medical/odysseus.dm b/code/modules/vehicles/mecha/medical/odysseus.dm index e6f02e2710b..3199124edaa 100644 --- a/code/modules/vehicles/mecha/medical/odysseus.dm +++ b/code/modules/vehicles/mecha/medical/odysseus.dm @@ -14,15 +14,16 @@ /obj/vehicle/sealed/mecha/odysseus/moved_inside(mob/living/carbon/human/human) . = ..() - if(. && !HAS_TRAIT(human, TRAIT_MEDICAL_HUD)) - ADD_TRAIT(human, TRAIT_MEDICAL_HUD, VEHICLE_TRAIT) + if(!.) + return + ADD_TRAIT(human, TRAIT_MEDICAL_HUD, VEHICLE_TRAIT) /obj/vehicle/sealed/mecha/odysseus/remove_occupant(mob/living/carbon/human/human) - if(isliving(human) && HAS_TRAIT_FROM(human, TRAIT_MEDICAL_HUD, VEHICLE_TRAIT)) - REMOVE_TRAIT(human, TRAIT_MEDICAL_HUD, VEHICLE_TRAIT) + REMOVE_TRAIT(human, TRAIT_MEDICAL_HUD, VEHICLE_TRAIT) return ..() /obj/vehicle/sealed/mecha/odysseus/mmi_moved_inside(obj/item/mmi/MMI, mob/user) . = ..() - if(. && !isnull(MMI.brainmob) && !HAS_TRAIT(MMI.brainmob, TRAIT_MEDICAL_HUD)) - ADD_TRAIT(MMI.brainmob, TRAIT_MEDICAL_HUD, VEHICLE_TRAIT) + if(!. || isnull(MMI.brainmob)) + return + ADD_TRAIT(MMI.brainmob, TRAIT_MEDICAL_HUD, VEHICLE_TRAIT)