diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index b7aabbd1c39..4e91b31da8c 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -733,6 +733,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai //quirk traits #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" +#define TRAIT_ANOSMIA "anosmia" #define TRAIT_HEAVY_DRINKER "heavy_drinker" #define TRAIT_AGEUSIA "ageusia" #define TRAIT_HEAVY_SLEEPER "heavy_sleeper" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index b2737fca837..2b00638e348 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -126,6 +126,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ALWAYS_WANTED" = TRAIT_ALWAYS_WANTED, "TRAIT_ANALGESIA" = TRAIT_ANALGESIA, "TRAIT_ANGELIC" = TRAIT_ANGELIC, + "TRAIT_ANOSMIA" = TRAIT_ANOSMIA, "TRAIT_ANTENNAE" = TRAIT_ANTENNAE, "TRAIT_ANTICONVULSANT" = TRAIT_ANTICONVULSANT, "TRAIT_ANTIMAGIC" = TRAIT_ANTIMAGIC, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index bacd7e3bc46..354449cfd55 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -29,6 +29,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_AGENDER" = TRAIT_AGENDER, "TRAIT_AGEUSIA" = TRAIT_AGEUSIA, "TRAIT_ALCOHOL_TOLERANCE" = TRAIT_ALCOHOL_TOLERANCE, + "TRAIT_ANOSMIA" = TRAIT_ANOSMIA, "TRAIT_ANTIMAGIC" = TRAIT_ANTIMAGIC, "TRAIT_ANXIOUS" = TRAIT_ANXIOUS, "TRAIT_BADDNA" = TRAIT_BADDNA, diff --git a/code/datums/components/bakeable.dm b/code/datums/components/bakeable.dm index a745be2b1a5..afc71936f1b 100644 --- a/code/datums/components/bakeable.dm +++ b/code/datums/components/bakeable.dm @@ -90,11 +90,24 @@ baked_result.pixel_y = original_object.pixel_y used_tray.AddToPlate(baked_result) + var/list/asomnia_hadders = list() + for(var/mob/smeller in get_hearers_in_view(DEFAULT_MESSAGE_RANGE, used_oven)) + if(HAS_TRAIT(smeller, TRAIT_ANOSMIA)) + asomnia_hadders += smeller + if(positive_result) - used_oven.visible_message(span_notice("You smell something great coming from [used_oven]."), blind_message = span_notice("You smell something great...")) + used_oven.visible_message( + span_notice("You smell something great coming from [used_oven]."), + blind_message = span_notice("You smell something great..."), + ignored_mobs = asomnia_hadders, + ) BLACKBOX_LOG_FOOD_MADE(baked_result.type) else - used_oven.visible_message(span_warning("You smell a burnt smell coming from [used_oven]."), blind_message = span_warning("You smell a burnt smell...")) + used_oven.visible_message( + span_warning("You smell a burnt smell coming from [used_oven]."), + blind_message = span_warning("You smell a burnt smell..."), + ignored_mobs = asomnia_hadders, + ) SEND_SIGNAL(parent, COMSIG_ITEM_BAKED, baked_result) qdel(parent) diff --git a/code/datums/diseases/advance/symptoms/fire.dm b/code/datums/diseases/advance/symptoms/fire.dm index f428abdb016..0708841fca0 100644 --- a/code/datums/diseases/advance/symptoms/fire.dm +++ b/code/datums/diseases/advance/symptoms/fire.dm @@ -71,7 +71,10 @@ if(prob(33.33)) living_mob.show_message(span_hear("You hear a crackling noise."), type = MSG_AUDIBLE) else - to_chat(living_mob, span_warning("[pick("You feel hot.", "You smell smoke.")]")) + if(HAS_TRAIT(living_mob, TRAIT_ANOSMIA)) //Anosmia quirk holder can't smell anything. + to_chat(living_mob, span_warning("You feel hot.")) + else + to_chat(living_mob, span_warning("[pick("You feel hot.", "You smell smoke.")]")) /* Alkali perspiration diff --git a/code/datums/mutations/olfaction.dm b/code/datums/mutations/olfaction.dm index e014806233a..305f6d16e83 100644 --- a/code/datums/mutations/olfaction.dm +++ b/code/datums/mutations/olfaction.dm @@ -40,6 +40,10 @@ to_chat(owner, span_warning("You have no nose!")) return FALSE + if(HAS_TRAIT(living_cast_on, TRAIT_ANOSMIA)) //Anosmia quirk holders can't smell anything + to_chat(owner, span_warning("You can't smell!")) + return FALSE + return TRUE /datum/action/cooldown/spell/olfaction/cast(mob/living/cast_on) diff --git a/code/datums/quirks/negative_quirks/anosmia.dm b/code/datums/quirks/negative_quirks/anosmia.dm new file mode 100644 index 00000000000..bbbf599aeaa --- /dev/null +++ b/code/datums/quirks/negative_quirks/anosmia.dm @@ -0,0 +1,9 @@ +/datum/quirk/item_quirk/anosmia + name = "Anosmia" + desc = "For some reason, you can't smell anything." + icon = FA_ICON_HEAD_SIDE_COUGH_SLASH + value = -2 + mob_trait = TRAIT_ANOSMIA + gain_text = span_notice("You find yourself unable to smell anything!") + lose_text = span_danger("Suddenly, you can smell again!") + medical_record_text = "Patient has lost their sensation of smell." diff --git a/code/modules/antagonists/changeling/powers/pheromone_receptors.dm b/code/modules/antagonists/changeling/powers/pheromone_receptors.dm index 18fda4bf4ff..0e468159a3c 100644 --- a/code/modules/antagonists/changeling/powers/pheromone_receptors.dm +++ b/code/modules/antagonists/changeling/powers/pheromone_receptors.dm @@ -23,6 +23,9 @@ /datum/action/changeling/pheromone_receptors/sting_action(mob/living/carbon/user) ..() var/datum/antagonist/changeling/changeling = IS_CHANGELING(user) + if(HAS_TRAIT(user, TRAIT_ANOSMIA)) //Anosmia quirk holders can't smell anything + to_chat(user, span_warning("We can't smell!")) + return if(!receptors_active) to_chat(user, span_warning("We search for the scent of any nearby changelings.")) changeling.chem_recharge_slowdown += 0.25 diff --git a/code/modules/food_and_drinks/machinery/deep_fryer.dm b/code/modules/food_and_drinks/machinery/deep_fryer.dm index 0ca70ccf840..d01e24a1e81 100644 --- a/code/modules/food_and_drinks/machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/machinery/deep_fryer.dm @@ -146,7 +146,11 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list( audible_message(span_notice("[src] dings!")) else if (cook_time >= DEEPFRYER_BURNTIME && !frying_burnt) frying_burnt = TRUE - visible_message(span_warning("[src] emits an acrid smell!")) + var/list/asomnia_hadders = list() + for(var/mob/smeller in get_hearers_in_view(DEFAULT_MESSAGE_RANGE, src)) + if(HAS_TRAIT(smeller, TRAIT_ANOSMIA)) + asomnia_hadders += smeller + visible_message(span_warning("[src] emits an acrid smell!"), ignored_mobs = asomnia_hadders) use_energy(active_power_usage) diff --git a/code/modules/food_and_drinks/machinery/oven.dm b/code/modules/food_and_drinks/machinery/oven.dm index 517e25c6dcb..8135dd8308f 100644 --- a/code/modules/food_and_drinks/machinery/oven.dm +++ b/code/modules/food_and_drinks/machinery/oven.dm @@ -90,7 +90,11 @@ baked_item.fire_act(1000) //Hot hot hot! if(SPT_PROB(10, seconds_per_tick)) - visible_message(span_danger("You smell a burnt smell coming from [src]!")) + var/list/asomnia_hadders = list() + for(var/mob/smeller in get_hearers_in_view(DEFAULT_MESSAGE_RANGE, src)) + if(HAS_TRAIT(smeller, TRAIT_ANOSMIA)) + asomnia_hadders += smeller + visible_message(span_danger("You smell a burnt smell coming from [src]!"), ignored_mobs = asomnia_hadders) set_smoke_state(worst_cooked_food_state) update_appearance() use_energy(active_power_usage) diff --git a/code/modules/mining/lavaland/megafauna_loot.dm b/code/modules/mining/lavaland/megafauna_loot.dm index d9074800e4c..e6caf573f00 100644 --- a/code/modules/mining/lavaland/megafauna_loot.dm +++ b/code/modules/mining/lavaland/megafauna_loot.dm @@ -291,7 +291,10 @@ if(prob(7.5)) wearer.cause_hallucination(/datum/hallucination/oh_yeah, "H.E.C.K suit", haunt_them = TRUE) else - to_chat(wearer, span_warning("[pick("You hear faint whispers.","You smell ash.","You feel hot.","You hear a roar in the distance.")]")) + if(HAS_TRAIT(wearer, TRAIT_ANOSMIA)) //Anosmia quirk holder cannot fell any smell + to_chat(wearer, span_warning("[pick("You hear faint whispers.","You feel hot.","You hear a roar in the distance.")]")) + else + to_chat(wearer, span_warning("[pick("You hear faint whispers.","You smell ash.","You feel hot.","You hear a roar in the distance.")]")) /obj/item/clothing/head/hooded/hostile_environment name = "H.E.C.K. helmet" diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index fea1de2ecc6..d80a91d0af8 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -280,7 +280,8 @@ if(!can_breathe_vacuum && (o2_pp < safe_oxygen_min)) // Breathe insufficient amount of O2. oxygen_used = handle_suffocation(o2_pp, safe_oxygen_min, breath_gases[/datum/gas/oxygen][MOLES]) - throw_alert(ALERT_NOT_ENOUGH_OXYGEN, /atom/movable/screen/alert/not_enough_oxy) + if(!HAS_TRAIT(src, TRAIT_ANOSMIA)) + throw_alert(ALERT_NOT_ENOUGH_OXYGEN, /atom/movable/screen/alert/not_enough_oxy) else // Enough oxygen to breathe. failed_last_breath = FALSE @@ -307,7 +308,8 @@ if(!co2overloadtime) co2overloadtime = world.time else if((world.time - co2overloadtime) > 12 SECONDS) - throw_alert(ALERT_TOO_MUCH_CO2, /atom/movable/screen/alert/too_much_co2) + if(!HAS_TRAIT(src, TRAIT_ANOSMIA)) + throw_alert(ALERT_TOO_MUCH_CO2, /atom/movable/screen/alert/too_much_co2) Unconscious(6 SECONDS) // Lets hurt em a little, let them know we mean business. adjustOxyLoss(3) @@ -325,7 +327,8 @@ // Plasma side-effects. var/ratio = (breath_gases[/datum/gas/plasma][MOLES] / safe_plas_max) * 10 adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE)) - throw_alert(ALERT_TOO_MUCH_PLASMA, /atom/movable/screen/alert/too_much_plas) + if(!HAS_TRAIT(src, TRAIT_ANOSMIA)) + throw_alert(ALERT_TOO_MUCH_PLASMA, /atom/movable/screen/alert/too_much_plas) else // Reset side-effects. clear_alert(ALERT_TOO_MUCH_PLASMA) @@ -356,6 +359,8 @@ miasma_disease.name = "Unknown" ForceContractDisease(miasma_disease, make_copy = TRUE, del_on_fail = TRUE) // Miasma side-effects. + if (HAS_TRAIT(src, TRAIT_ANOSMIA)) //We can't feel miasma without sense of smell + return switch(miasma_pp) if(0.25 to 5) // At lower pp, give out a little warning @@ -386,7 +391,8 @@ if(n2o_pp > n2o_para_min) // More N2O, more severe side-effects. Causes stun/sleep. n2o_euphoria = EUPHORIA_ACTIVE - throw_alert(ALERT_TOO_MUCH_N2O, /atom/movable/screen/alert/too_much_n2o) + if(!HAS_TRAIT(src, TRAIT_ANOSMIA)) + throw_alert(ALERT_TOO_MUCH_N2O, /atom/movable/screen/alert/too_much_n2o) // give them one second of grace to wake up and run away a bit! if(!HAS_TRAIT(src, TRAIT_SLEEPIMMUNE)) Unconscious(6 SECONDS) diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 98a5c823c06..a5b5cef2e8c 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -535,7 +535,10 @@ . = ..() if(isvampire(affected_mob)) //incapacitating but not lethal. Unfortunately, vampires cannot vomit. if(SPT_PROB(min((current_cycle-1)/2, 12.5), seconds_per_tick)) - to_chat(affected_mob, span_danger("You can't get the scent of garlic out of your nose! You can barely think...")) + if(HAS_TRAIT(affected_mob, TRAIT_ANOSMIA)) + to_chat(affected_mob, span_danger("You feel that something is wrong, your strength is leaving you! You can barely think...")) + else + to_chat(affected_mob, span_danger("You can't get the scent of garlic out of your nose! You can barely think...")) affected_mob.Paralyze(10) affected_mob.set_jitter_if_lower(20 SECONDS) else diff --git a/code/modules/reagents/reagent_containers/cups/glassbottle.dm b/code/modules/reagents/reagent_containers/cups/glassbottle.dm index 4f7abbe6f20..a293aac7aa1 100644 --- a/code/modules/reagents/reagent_containers/cups/glassbottle.dm +++ b/code/modules/reagents/reagent_containers/cups/glassbottle.dm @@ -894,7 +894,8 @@ desc = "Fermented prison wine made from fruit, sugar, and despair. You probably shouldn't drink this around Security." icon_state = "trashbag1" // pruno releases air as it ferments, we don't want to simulate this in atmos, but we can make it look like it did for (var/mob/living/M in view(2, get_turf(src))) // letting people and/or narcs know when the pruno is done - to_chat(M, span_info("A pungent smell emanates from [src], like fruit puking out its guts.")) + if(HAS_TRAIT(M, TRAIT_ANOSMIA)) + to_chat(M, span_info("A pungent smell emanates from [src], like fruit puking out its guts.")) playsound(get_turf(src), 'sound/effects/bubbles2.ogg', 25, TRUE) /** diff --git a/code/modules/surgery/organs/internal/lungs/_lungs.dm b/code/modules/surgery/organs/internal/lungs/_lungs.dm index 8bba59d7987..a60cc243756 100644 --- a/code/modules/surgery/organs/internal/lungs/_lungs.dm +++ b/code/modules/surgery/organs/internal/lungs/_lungs.dm @@ -266,7 +266,8 @@ var/ratio = (breath.gases[/datum/gas/oxygen][MOLES] / safe_oxygen_max) * 10 breather.apply_damage(clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type, spread_damage = TRUE) - breather.throw_alert(ALERT_TOO_MUCH_OXYGEN, /atom/movable/screen/alert/too_much_oxy) + if(!HAS_TRAIT(breather, TRAIT_ANOSMIA)) + breather.throw_alert(ALERT_TOO_MUCH_OXYGEN, /atom/movable/screen/alert/too_much_oxy) /// Handles NOT having too much o2. only relevant if safe_oxygen_max has a value /obj/item/organ/internal/lungs/proc/safe_oxygen(mob/living/carbon/breather, datum/gas_mixture/breath, old_o2_pp) @@ -285,7 +286,8 @@ if(nitro_pp < safe_nitro_min && !HAS_TRAIT(src, TRAIT_SPACEBREATHING)) // Suffocation side-effects. // Not safe to check the old pp because of can_breath_vacuum - breather.throw_alert(ALERT_NOT_ENOUGH_NITRO, /atom/movable/screen/alert/not_enough_nitro) + if(!HAS_TRAIT(breather, TRAIT_ANOSMIA)) + breather.throw_alert(ALERT_NOT_ENOUGH_NITRO, /atom/movable/screen/alert/not_enough_nitro) var/gas_breathed = handle_suffocation(breather, nitro_pp, safe_nitro_min, breath.gases[/datum/gas/nitrogen][MOLES]) if(nitro_pp) breathe_gas_volume(breath, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, volume = gas_breathed) @@ -318,7 +320,8 @@ breather.emote("cough") if((world.time - breather.co2overloadtime) > 12 SECONDS) - breather.throw_alert(ALERT_TOO_MUCH_CO2, /atom/movable/screen/alert/too_much_co2) + if(!HAS_TRAIT(breather, TRAIT_ANOSMIA)) + breather.throw_alert(ALERT_TOO_MUCH_CO2, /atom/movable/screen/alert/too_much_co2) breather.Unconscious(6 SECONDS) // Lets hurt em a little, let them know we mean business. breather.apply_damage(3, co2_damage_type, spread_damage = TRUE) @@ -337,7 +340,8 @@ // Suffocation side-effects. if(plasma_pp < safe_plasma_min && !HAS_TRAIT(src, TRAIT_SPACEBREATHING)) // Could check old_plasma_pp but vacuum breathing hates me - breather.throw_alert(ALERT_NOT_ENOUGH_PLASMA, /atom/movable/screen/alert/not_enough_plas) + if(!HAS_TRAIT(breather, TRAIT_ANOSMIA)) + breather.throw_alert(ALERT_NOT_ENOUGH_PLASMA, /atom/movable/screen/alert/not_enough_plas) // Breathe insufficient amount of Plasma, exhale CO2. var/gas_breathed = handle_suffocation(breather, plasma_pp, safe_plasma_min, breath.gases[/datum/gas/plasma][MOLES]) if(plasma_pp) @@ -362,7 +366,8 @@ // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so. if(old_plasma_pp < safe_plasma_max) - breather.throw_alert(ALERT_TOO_MUCH_PLASMA, /atom/movable/screen/alert/too_much_plas) + if(!HAS_TRAIT(breather, TRAIT_ANOSMIA)) + breather.throw_alert(ALERT_TOO_MUCH_PLASMA, /atom/movable/screen/alert/too_much_plas) var/ratio = (breath.gases[/datum/gas/plasma][MOLES] / safe_plasma_max) * 10 breather.apply_damage(clamp(ratio, plas_breath_dam_min, plas_breath_dam_max), plas_damage_type, spread_damage = TRUE) @@ -466,6 +471,8 @@ miasma_disease.name = "Unknown" breather.AirborneContractDisease(miasma_disease, TRUE) // Miasma side effects + if (HAS_TRAIT(breather, TRAIT_ANOSMIA)) //Anosmia quirk holder cannot smell miasma, but can get diseases from it. + return switch(miasma_pp) if(0.25 to 5) // At lower pp, give out a little warning @@ -522,7 +529,8 @@ // More N2O, more severe side-effects. Causes stun/sleep. if(old_n2o_pp < n2o_para_min) - breather.throw_alert(ALERT_TOO_MUCH_N2O, /atom/movable/screen/alert/too_much_n2o) + if(!HAS_TRAIT(breather, TRAIT_ANOSMIA)) + breather.throw_alert(ALERT_TOO_MUCH_N2O, /atom/movable/screen/alert/too_much_n2o) n2o_euphoria = EUPHORIA_ACTIVE // give them one second of grace to wake up and run away a bit! diff --git a/tgstation.dme b/tgstation.dme index 9a7b0be49a0..61058989978 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1752,6 +1752,7 @@ #include "code\datums\quirks\negative_quirks\addict.dm" #include "code\datums\quirks\negative_quirks\all_nighter.dm" #include "code\datums\quirks\negative_quirks\allergic.dm" +#include "code\datums\quirks\negative_quirks\anosmia.dm" #include "code\datums\quirks\negative_quirks\bad_back.dm" #include "code\datums\quirks\negative_quirks\bad_touch.dm" #include "code\datums\quirks\negative_quirks\big_hands.dm"