From edf25895e5f7ec8e8d6bdd47c62fac3c998c1d93 Mon Sep 17 00:00:00 2001
From: Bloop <13398309+vinylspiders@users.noreply.github.com>
Date: Sat, 12 Oct 2024 10:14:53 -0400
Subject: [PATCH] Batch of TG PRs 10/12 (#4473)
## About The Pull Request
Doing another one early for map vote fix
## Changelog
Autochangelogs included
---
code/__DEFINES/sound.dm | 1 +
code/__DEFINES/traits/declarations.dm | 5 +-
code/_globalvars/traits/_traits.dm | 3 +-
code/_globalvars/traits/admin_tooling.dm | 1 +
code/datums/actions/mobs/lava_swoop.dm | 14 ++-
code/datums/components/self_ignition.dm | 57 ++++++++++
code/datums/elements/pet_bonus.dm | 9 +-
code/game/machinery/nebula_shielding.dm | 6 +-
code/game/sound.dm | 7 +-
code/modules/clothing/spacesuits/plasmamen.dm | 56 ++++++---
.../under/jobs/Plasmaman/civilian_service.dm | 107 +++++++++++-------
.../basic/farm_animals/chicken/chick.dm | 14 ++-
.../basic/farm_animals/chicken/chicken.dm | 14 ++-
.../mob/living/basic/farm_animals/cow/_cow.dm | 14 ++-
.../mob/living/basic/farm_animals/pig.dm | 13 ++-
.../mob/living/basic/farm_animals/pony.dm | 14 ++-
.../mob/living/basic/farm_animals/rabbit.dm | 12 +-
.../basic/lavaland/lobstrosity/lobstrosity.dm | 13 ++-
code/modules/mob/living/basic/pets/cat/cat.dm | 2 +-
.../modules/mob/living/basic/pets/dog/_dog.dm | 12 +-
code/modules/mob/living/basic/pets/fox.dm | 11 +-
.../mob/living/basic/pets/gondolas/gondola.dm | 2 +-
code/modules/mob/living/basic/pets/penguin.dm | 11 +-
code/modules/mob/living/basic/pets/sloth.dm | 12 +-
.../mob/living/basic/space_fauna/ant.dm | 12 +-
.../mob/living/basic/space_fauna/carp/carp.dm | 14 ++-
.../spider/giant_spider/giant_spiders.dm | 2 +-
.../living/basic/space_fauna/spider/spider.dm | 12 ++
.../modules/mob/living/basic/vermin/lizard.dm | 11 +-
.../basic/vermin/mothroach/mothroach.dm | 12 +-
code/modules/mob/living/basic/vermin/mouse.dm | 14 ++-
.../mob/living/carbon/human/_species.dm | 8 --
code/modules/mob/living/carbon/human/human.dm | 20 ++++
.../mob/living/carbon/human/human_defense.dm | 4 +-
.../carbon/human/species_types/plasmamen.dm | 56 ---------
code/modules/mod/modules/modules_general.dm | 4 +-
code/modules/shuttle/emergency.dm | 2 +-
.../spells/spell_types/pointed/tie_shoes.dm | 2 +-
.../species_parts/plasmaman_bodyparts.dm | 24 ++++
html/changelogs/AutoChangeLog-pr-87086.yml | 5 +
html/changelogs/AutoChangeLog-pr-87126.yml | 6 +
html/changelogs/AutoChangeLog-pr-87158.yml | 4 +
html/changelogs/AutoChangeLog-pr-87160.yml | 4 +
html/changelogs/AutoChangeLog-pr-87168.yml | 4 +
html/changelogs/AutoChangeLog-pr-87183.yml | 4 +
tgstation.dme | 1 +
46 files changed, 476 insertions(+), 159 deletions(-)
create mode 100644 code/datums/components/self_ignition.dm
create mode 100644 html/changelogs/AutoChangeLog-pr-87086.yml
create mode 100644 html/changelogs/AutoChangeLog-pr-87126.yml
create mode 100644 html/changelogs/AutoChangeLog-pr-87158.yml
create mode 100644 html/changelogs/AutoChangeLog-pr-87160.yml
create mode 100644 html/changelogs/AutoChangeLog-pr-87168.yml
create mode 100644 html/changelogs/AutoChangeLog-pr-87183.yml
diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm
index 4fb5a00adc1..1bd3a191f76 100644
--- a/code/__DEFINES/sound.dm
+++ b/code/__DEFINES/sound.dm
@@ -251,3 +251,4 @@ GLOBAL_LIST_INIT(announcer_keys, list(
#define SFX_PLASTIC_BOTTLE_LIQUID_SLOSH "plastic_bottle_liquid_slosh"
#define SFX_DEFAULT_LIQUID_SLOSH "default_liquid_slosh"
#define SFX_PLATE_ARMOR_RUSTLE "plate_armor_rustle"
+#define SFX_PIG_OINK "pig_oink"
diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm
index 8746e198d08..ae2dec14d16 100644
--- a/code/__DEFINES/traits/declarations.dm
+++ b/code/__DEFINES/traits/declarations.dm
@@ -139,7 +139,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_NOFIRE "nonflammable"
#define TRAIT_NOFIRE_SPREAD "no_fire_spreading"
/// Prevents plasmamen from self-igniting if only their helmet is missing
-#define TRAIT_NOSELFIGNITION_HEAD_ONLY "no_selfignition_head_only"
+#define TRAIT_HEAD_ATMOS_SEALED "no_selfignition_head_only"
#define TRAIT_NOGUNS "no_guns"
///Can toss a guns like a badass, causing additional damage/effect to their enemies
#define TRAIT_TOSS_GUN_HARD "toss_gun_hard"
@@ -288,6 +288,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Applied into wounds when they're scanned with the wound analyzer, halves time to treat them manually.
#define TRAIT_WOUND_SCANNED "wound_scanned"
+/// Owner will ignore any fire protection when calculating fire damage
+#define TRAIT_IGNORE_FIRE_PROTECTION "ignore_fire_protection"
+
#define TRAIT_NODEATH "nodeath"
#define TRAIT_NOHARDCRIT "nohardcrit"
#define TRAIT_NOSOFTCRIT "nosoftcrit"
diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm
index 3aa4b4f1926..8c2b86e2cbc 100644
--- a/code/_globalvars/traits/_traits.dm
+++ b/code/_globalvars/traits/_traits.dm
@@ -371,7 +371,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_NOHUNGER" = TRAIT_NOHUNGER,
"TRAIT_NOLIMBDISABLE" = TRAIT_NOLIMBDISABLE,
"TRAIT_NOMOBSWAP" = TRAIT_NOMOBSWAP,
- "TRAIT_NOSELFIGNITION_HEAD_ONLY" = TRAIT_NOSELFIGNITION_HEAD_ONLY,
+ "TRAIT_HEAD_ATMOS_SEALED" = TRAIT_HEAD_ATMOS_SEALED,
"TRAIT_NOSOFTCRIT" = TRAIT_NOSOFTCRIT,
"TRAIT_NO_AUGMENTS" = TRAIT_NO_AUGMENTS,
"TRAIT_NO_BLOOD_OVERLAY" = TRAIT_NO_BLOOD_OVERLAY,
@@ -567,6 +567,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_SPEECH_BOOSTER" = TRAIT_SPEECH_BOOSTER,
"TRAIT_MINING_PARRYING" = TRAIT_MINING_PARRYING,
"TRAIT_ILLUSORY_EFFECT" = TRAIT_ILLUSORY_EFFECT,
+ "TRAIT_IGNORE_FIRE_PROTECTION" = TRAIT_IGNORE_FIRE_PROTECTION,
),
/obj/item = list(
"TRAIT_APC_SHOCKING" = TRAIT_APC_SHOCKING,
diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm
index 691db719f54..fd33957efe9 100644
--- a/code/_globalvars/traits/admin_tooling.dm
+++ b/code/_globalvars/traits/admin_tooling.dm
@@ -325,6 +325,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
"TRAIT_XRAY_HEARING" = TRAIT_XRAY_HEARING,
"TRAIT_XRAY_VISION" = TRAIT_XRAY_VISION,
"TRAIT_MINING_PARRYING" = TRAIT_MINING_PARRYING,
+ "TRAIT_IGNORE_FIRE_PROTECTION" = TRAIT_IGNORE_FIRE_PROTECTION,
),
/obj/item = list(
"TRAIT_APC_SHOCKING" = TRAIT_APC_SHOCKING,
diff --git a/code/datums/actions/mobs/lava_swoop.dm b/code/datums/actions/mobs/lava_swoop.dm
index 2b07734b4a8..428c9756656 100644
--- a/code/datums/actions/mobs/lava_swoop.dm
+++ b/code/datums/actions/mobs/lava_swoop.dm
@@ -144,11 +144,17 @@
for(var/turf/T in walled)
drakewalls += new /obj/effect/temp_visual/drakewall(T) // no people with lava immunity can just run away from the attack for free
var/list/indestructible_turfs = list()
- for(var/turf/T in RANGE_TURFS(2, center))
- if(isindestructiblefloor(T))
+
+ for(var/turf/turf_target as anything in RANGE_TURFS(2, center))
+ if(isindestructiblefloor(turf_target))
+ continue
+ if(isindestructiblewall(turf_target))
+ indestructible_turfs += turf_target
continue
- if(isindestructiblewall(T))
- indestructible_turfs += T
+ if(ismineralturf(turf_target))
+ var/turf/closed/mineral/mineral_turf = turf_target
+ mineral_turf.gets_drilled(owner)
+
SLEEP_CHECK_DEATH(1 SECONDS, owner) // give them a bit of time to realize what attack is actually happening
var/list/turfs = RANGE_TURFS(2, center)
diff --git a/code/datums/components/self_ignition.dm b/code/datums/components/self_ignition.dm
new file mode 100644
index 00000000000..6736a746355
--- /dev/null
+++ b/code/datums/components/self_ignition.dm
@@ -0,0 +1,57 @@
+/// Component used by plasmeme limbs. Ignites the owner and prevents fire armor from working if they're exposed to oxygen
+/datum/component/self_ignition
+ /// How many fire stacks do we apply per second?
+ /// Default value is 0.25 / 6 (default amount of limbs)
+ var/fire_stacks_per_second = 0.0416
+ /// How many fire stacks are removed when we're exposed to hypernoblium
+ /// Default value is 10 / 6 (default amount of limbs)
+ var/fire_stacks_loss = 1.66
+
+/datum/component/self_ignition/Initialize(fire_stacks_per_second = 0.0416, fire_stacks_loss = 1.66)
+ . = ..()
+ if(!isbodypart(parent))
+ return COMPONENT_INCOMPATIBLE
+ src.fire_stacks_per_second = fire_stacks_per_second
+ src.fire_stacks_loss = fire_stacks_loss
+
+/datum/component/self_ignition/RegisterWithParent()
+ RegisterSignal(parent, COMSIG_BODYPART_ATTACHED, PROC_REF(on_attached))
+ RegisterSignal(parent, COMSIG_BODYPART_REMOVED, PROC_REF(on_detached))
+
+/datum/component/self_ignition/proc/on_attached(datum/source, mob/living/carbon/human/new_owner)
+ SIGNAL_HANDLER
+ RegisterSignal(new_owner, COMSIG_LIVING_LIFE, PROC_REF(on_life))
+
+/datum/component/self_ignition/proc/on_detached(datum/source, mob/living/carbon/human/old_owner)
+ SIGNAL_HANDLER
+ UnregisterSignal(old_owner, COMSIG_LIVING_LIFE)
+ REMOVE_TRAIT(old_owner, TRAIT_IGNORE_FIRE_PROTECTION, REF(parent))
+
+/datum/component/self_ignition/proc/on_life(mob/living/carbon/human/owner, seconds_per_tick, times_fired)
+ SIGNAL_HANDLER
+
+ if (owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE))
+ if (!owner.on_fire)
+ REMOVE_TRAIT(owner, TRAIT_IGNORE_FIRE_PROTECTION, REF(parent))
+ return
+
+ var/datum/gas_mixture/environment = owner.loc.return_air()
+ if (!environment?.total_moles())
+ return
+
+ if(environment.gases[/datum/gas/hypernoblium] && environment.gases[/datum/gas/hypernoblium][MOLES] >= 5)
+ if(owner.on_fire && owner.fire_stacks > 0)
+ owner.adjust_fire_stacks(-fire_stacks_loss * seconds_per_tick)
+ return
+
+ if (HAS_TRAIT(owner, TRAIT_NOFIRE))
+ return
+
+ ADD_TRAIT(owner, TRAIT_IGNORE_FIRE_PROTECTION, REF(parent))
+
+ if(!environment.gases[/datum/gas/oxygen] || environment.gases[/datum/gas/oxygen][MOLES] < 1) //Same threshhold that extinguishes fire
+ return
+
+ owner.adjust_fire_stacks(fire_stacks_per_second * seconds_per_tick)
+ if(owner.ignite_mob())
+ owner.visible_message(span_danger("[owner]'s body reacts with the atmosphere and bursts into flames!"), span_userdanger("Your body reacts with the atmosphere and bursts into flame!"))
diff --git a/code/datums/elements/pet_bonus.dm b/code/datums/elements/pet_bonus.dm
index a802c363f44..d809b9ef4bd 100644
--- a/code/datums/elements/pet_bonus.dm
+++ b/code/datums/elements/pet_bonus.dm
@@ -10,17 +10,14 @@
///string key of the emote to do when pet.
var/emote_name
- ///optional cute message to send when you pet your pet!
- var/emote_message
///actual moodlet given, defaults to the pet animal one
var/moodlet
-/datum/element/pet_bonus/Attach(datum/target, emote_message, moodlet = /datum/mood_event/pet_animal)
+/datum/element/pet_bonus/Attach(datum/target, emote_name, moodlet = /datum/mood_event/pet_animal)
. = ..()
if(!isliving(target))
return ELEMENT_INCOMPATIBLE
- src.emote_message = emote_message
src.emote_name = emote_name
src.moodlet = moodlet
RegisterSignal(target, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand))
@@ -37,8 +34,6 @@
new /obj/effect/temp_visual/heart(pet.loc)
SEND_SIGNAL(pet, COMSIG_ANIMAL_PET, petter, modifiers)
- if(emote_message && prob(33))
- pet.manual_emote(emote_message)
- if(emote_name)
+ if(emote_name && prob(33))
INVOKE_ASYNC(pet, TYPE_PROC_REF(/mob, emote), emote_name)
petter.add_mood_event("petting_bonus", moodlet, pet)
diff --git a/code/game/machinery/nebula_shielding.dm b/code/game/machinery/nebula_shielding.dm
index 10306177ebf..6473c1b1bfc 100644
--- a/code/game/machinery/nebula_shielding.dm
+++ b/code/game/machinery/nebula_shielding.dm
@@ -140,7 +140,7 @@
/obj/item/paper/fluff/radiation_nebula
name = "radioactive nebula shielding"
default_raw_text = {"EXTREME IMPORTANCE!!!!
- Set up these radioactive nebula shielding units before the gravity generators native shielding is overwhelmed!
+ Set up these radioactive nebula shielding units before the gravity generator's native shielding is overwhelmed!
Shielding units passively generate tritium, so make sure to properly ventilate/isolate the area before setting up a shielding unit!
More circuit boards can be ordered through cargo. Consider setting up auxillary shielding units in-case of destruction, power loss or sabotage.
"}
@@ -149,6 +149,6 @@
/obj/item/paper/fluff/radiation_nebula_virologist
name = "radioactive resonance"
default_raw_text = {"EXTREME IMPORTANCE!!!!
- During routine bloodscreening on employees working in the nebula, we found no traces of the sympton called 'Radioactive Resonance'.
- Something inside the nebula is interfering with it, be wary of a more shallow viral genepool.
+ During routine blood screening on employees working within the nebula, we have found no traces of the symptom called 'Radioactive Resonance'.
+ Something inside the nebula is interfering with it; be wary of a more shallow viral genepool.
"}
diff --git a/code/game/sound.dm b/code/game/sound.dm
index ab00fc4d6e0..f77a2aebf35 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -541,7 +541,7 @@
'sound/mobs/humanoids/human/snore/snore_male1.ogg' = 20,
'sound/mobs/humanoids/human/snore/snore_male2.ogg' = 20,
'sound/mobs/humanoids/human/snore/snore_male3.ogg' = 20,
- 'sound/mobs/humanoids/human/snore/snore_male3.ogg' = 20,
+ 'sound/mobs/humanoids/human/snore/snore_male4.ogg' = 20,
'sound/mobs/humanoids/human/snore/snore_male5.ogg' = 20,
'sound/mobs/humanoids/human/snore/snore_mimimi2.ogg' = 1,
))
@@ -580,4 +580,9 @@
'sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle4.ogg' = 23,
'sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle5.ogg' = 23,
))
+ if(SFX_PIG_OINK)
+ soundin = pick(
+ 'sound/mobs/non-humanoids/pig/pig1.ogg',
+ 'sound/mobs/non-humanoids/pig/pig2.ogg',
+ )
return soundin
diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm
index 88767b84b66..3de75657d33 100644
--- a/code/modules/clothing/spacesuits/plasmamen.dm
+++ b/code/modules/clothing/spacesuits/plasmamen.dm
@@ -9,11 +9,10 @@
icon_state = "plasmaman_suit"
inhand_icon_state = "plasmaman_suit"
fishing_modifier = 0
- var/next_extinguish = 0
+ COOLDOWN_DECLARE(extinguish_timer)
var/extinguish_cooldown = 100
var/extinguishes_left = 10
-
/datum/armor/eva_plasmaman
bio = 100
fire = 100
@@ -23,21 +22,52 @@
. = ..()
. += span_notice("There [extinguishes_left == 1 ? "is" : "are"] [extinguishes_left] extinguisher charge\s left in this suit.")
+/obj/item/clothing/suit/space/eva/plasmaman/equipped(mob/living/user, slot)
+ . = ..()
+ if (slot & ITEM_SLOT_OCLOTHING)
+ RegisterSignals(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED)), PROC_REF(check_fire_state))
+ check_fire_state()
+
+/obj/item/clothing/suit/space/eva/plasmaman/dropped(mob/living/user)
+ . = ..()
+ UnregisterSignal(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED)))
+
+/obj/item/clothing/suit/space/eva/plasmaman/proc/check_fire_state(datum/source)
+ SIGNAL_HANDLER
+
+ if (!ishuman(loc))
+ return
+
+ // This is weird but basically we're calling this proc once the cooldown ends in case our wearer gets set on fire again during said cooldown
+ // This is why we're ignoring source and instead checking by loc
+ var/mob/living/carbon/human/owner = loc
+ if (!owner.on_fire || !owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE))
+ return
-/obj/item/clothing/suit/space/eva/plasmaman/proc/Extinguish(mob/living/carbon/human/H)
- if(!istype(H))
+ if (!extinguishes_left || !COOLDOWN_FINISHED(src, extinguish_timer))
return
- if(H.fire_stacks > 0)
- if(extinguishes_left)
- if(next_extinguish > world.time)
- return
- next_extinguish = world.time + extinguish_cooldown
- extinguishes_left--
- H.visible_message(span_warning("[H]'s suit automatically extinguishes [H.p_them()]!"),span_warning("Your suit automatically extinguishes you."))
- H.extinguish_mob()
- new /obj/effect/particle_effect/water(get_turf(H))
+ extinguishes_left -= 1
+ COOLDOWN_START(src, extinguish_timer, extinguish_cooldown)
+ // Check if our (possibly other) wearer is on fire once the cooldown ends
+ addtimer(CALLBACK(src, PROC_REF(check_fire_state)), extinguish_cooldown)
+ owner.visible_message(span_warning("[owner]'s suit automatically extinguishes [owner.p_them()]!"), span_warning("Your suit automatically extinguishes you."))
+ owner.extinguish_mob()
+ new /obj/effect/particle_effect/water(get_turf(owner))
+
+/obj/item/clothing/suit/space/eva/plasmaman/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if (!istype(tool, /obj/item/extinguisher_refill))
+ return
+ if (extinguishes_left == 5)
+ to_chat(user, span_notice("The inbuilt extinguisher is full."))
+ return ITEM_INTERACT_BLOCKING
+
+ extinguishes_left = 5
+ to_chat(user, span_notice("You refill the suit's built-in extinguisher, using up the cartridge."))
+ check_fire_state()
+ qdel(tool)
+ return ITEM_INTERACT_SUCCESS
//I just want the light feature of helmets
/obj/item/clothing/head/helmet/space/plasmaman
diff --git a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
index ee70fbb3d6a..1d2166653ae 100644
--- a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
+++ b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
@@ -11,7 +11,7 @@
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
can_adjust = FALSE
strip_delay = 80
- var/next_extinguish = 0
+ COOLDOWN_DECLARE(extinguish_timer)
var/extinguish_cooldown = 100
var/extinguishes_left = 5
@@ -22,31 +22,54 @@
/obj/item/clothing/under/plasmaman/examine(mob/user)
. = ..()
- . += span_notice("There are [extinguishes_left] extinguisher charges left in this suit.")
+ . += span_notice("There [extinguishes_left == 1 ? "is" : "are"] [extinguishes_left] extinguisher charges left in this suit.")
-/obj/item/clothing/under/plasmaman/proc/Extinguish(mob/living/carbon/human/H)
- if(!istype(H))
+/obj/item/clothing/under/plasmaman/equipped(mob/living/user, slot)
+ . = ..()
+ if (slot & ITEM_SLOT_ICLOTHING)
+ RegisterSignals(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED)), PROC_REF(check_fire_state))
+ check_fire_state()
+
+/obj/item/clothing/under/plasmaman/dropped(mob/living/user)
+ . = ..()
+ UnregisterSignal(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED)))
+
+/obj/item/clothing/under/plasmaman/proc/check_fire_state(datum/source)
+ SIGNAL_HANDLER
+
+ if (!ishuman(loc))
+ return
+
+ // This is weird but basically we're calling this proc once the cooldown ends in case our wearer gets set on fire again during said cooldown
+ // This is why we're ignoring source and instead checking by loc
+ var/mob/living/carbon/human/owner = loc
+ if (!owner.on_fire || !owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE))
+ return
+
+ if (!extinguishes_left || !COOLDOWN_FINISHED(src, extinguish_timer))
return
- if(H.on_fire)
- if(extinguishes_left)
- if(next_extinguish > world.time)
- return
- next_extinguish = world.time + extinguish_cooldown
- extinguishes_left--
- H.visible_message(span_warning("[H]'s suit automatically extinguishes [H.p_them()]!"),span_warning("Your suit automatically extinguishes you."))
- H.extinguish_mob()
- new /obj/effect/particle_effect/water(get_turf(H))
-
-/obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params)
- ..()
- if (istype(E, /obj/item/extinguisher_refill))
- if (extinguishes_left == 5)
- to_chat(user, span_notice("The inbuilt extinguisher is full."))
- else
- extinguishes_left = 5
- to_chat(user, span_notice("You refill the suit's built-in extinguisher, using up the cartridge."))
- qdel(E)
+ extinguishes_left -= 1
+ COOLDOWN_START(src, extinguish_timer, extinguish_cooldown)
+ // Check if our (possibly other) wearer is on fire once the cooldown ends
+ addtimer(CALLBACK(src, PROC_REF(check_fire_state)), extinguish_cooldown)
+ owner.visible_message(span_warning("[owner]'s suit automatically extinguishes [owner.p_them()]!"), span_warning("Your suit automatically extinguishes you."))
+ owner.extinguish_mob()
+ new /obj/effect/particle_effect/water(get_turf(owner))
+
+/obj/item/clothing/under/plasmaman/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if (!istype(tool, /obj/item/extinguisher_refill))
+ return
+
+ if (extinguishes_left == 5)
+ to_chat(user, span_notice("The inbuilt extinguisher is full."))
+ return ITEM_INTERACT_BLOCKING
+
+ extinguishes_left = 5
+ to_chat(user, span_notice("You refill the suit's built-in extinguisher, using up the cartridge."))
+ check_fire_state()
+ qdel(tool)
+ return ITEM_INTERACT_SUCCESS
/obj/item/extinguisher_refill
name = "envirosuit extinguisher cartridge"
@@ -54,7 +77,6 @@
icon_state = "plasmarefill"
icon = 'icons/obj/canisters.dmi'
-
/obj/item/clothing/under/plasmaman/cargo
name = "cargo plasma envirosuit"
desc = "A joint envirosuit used by plasmamen quartermasters and cargo techs alike, due to the logistical problems of differenciating the two with the length of their pant legs."
@@ -134,20 +156,27 @@
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
-/obj/item/clothing/under/plasmaman/clown/Extinguish(mob/living/carbon/human/H)
- if(!istype(H))
+/obj/item/clothing/under/plasmaman/clown/check_fire_state(datum/source, datum/status_effect/fire_handler/status_effect)
+ if (!ishuman(loc))
+ return
+
+ // This is weird but basically we're calling this proc once the cooldown ends in case our wearer gets set on fire again during said cooldown
+ // This is why we're ignoring source and instead checking by loc
+ var/mob/living/carbon/human/owner = loc
+ if (!owner.on_fire || !owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE))
+ return
+
+ if (!extinguishes_left || !COOLDOWN_FINISHED(src, extinguish_timer))
return
- if(H.on_fire)
- if(extinguishes_left)
- if(next_extinguish > world.time)
- return
- next_extinguish = world.time + extinguish_cooldown
- extinguishes_left--
- H.visible_message(span_warning("[H]'s suit spews space lube everywhere!"),span_warning("Your suit spews space lube everywhere!"))
- H.extinguish_mob()
- var/datum/effect_system/fluid_spread/foam/foam = new
- var/datum/reagents/foamreagent = new /datum/reagents(15)
- foamreagent.add_reagent(/datum/reagent/lube, 15)
- foam.set_up(4, holder = src, location = H.loc, carry = foamreagent)
- foam.start() //Truly terrifying.
+ extinguishes_left -= 1
+ COOLDOWN_START(src, extinguish_timer, extinguish_cooldown)
+ // Check if our (possibly other) wearer is on fire once the cooldown ends
+ addtimer(CALLBACK(src, PROC_REF(check_fire_state)), extinguish_cooldown)
+ owner.visible_message(span_warning("[owner]'s suit spews space lube everywhere!"), span_warning("Your suit spews space lube everywhere!"))
+ owner.extinguish_mob()
+ var/datum/effect_system/fluid_spread/foam/foam = new
+ var/datum/reagents/foamreagent = new /datum/reagents(15)
+ foamreagent.add_reagent(/datum/reagent/lube, 15)
+ foam.set_up(4, holder = src, location = get_turf(owner), carry = foamreagent)
+ foam.start() //Truly terrifying.
diff --git a/code/modules/mob/living/basic/farm_animals/chicken/chick.dm b/code/modules/mob/living/basic/farm_animals/chicken/chick.dm
index 9e4af384aee..7ddf86b0cfb 100644
--- a/code/modules/mob/living/basic/farm_animals/chicken/chick.dm
+++ b/code/modules/mob/living/basic/farm_animals/chicken/chick.dm
@@ -33,6 +33,18 @@
/// What we grow into.
var/grow_as = /mob/living/basic/chicken
+/datum/emote/chick
+ mob_type_allowed_typecache = /mob/living/basic/chick
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/chick/chirp
+ key = "chirp"
+ key_third_person = "chirps"
+ message = "chirps!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+ vary = TRUE
+ sound = 'sound/mobs/non-humanoids/chicken/chick_peep.ogg'
+
/mob/living/basic/chick/Initialize(mapload)
. = ..()
pixel_x = base_pixel_x + rand(-6, 6)
@@ -40,7 +52,7 @@
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
- AddElement(/datum/element/pet_bonus, "chirps!")
+ AddElement(/datum/element/pet_bonus, "chirp")
AddElement(/datum/element/swabable, CELL_LINE_TABLE_CHICKEN, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW)
diff --git a/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm b/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm
index 9508f8fae3b..4f83608b9d6 100644
--- a/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm
+++ b/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm
@@ -38,12 +38,24 @@ GLOBAL_VAR_INIT(chicken_count, 0)
///boolean deciding whether eggs laid by this chicken can hatch into chicks
var/fertile = TRUE
+/datum/emote/chicken
+ mob_type_allowed_typecache = /mob/living/basic/chicken
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/chicken/cluck
+ key = "cluck"
+ key_third_person = "clucks"
+ message = "clucks happily!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+ vary = TRUE
+ sound = 'sound/mobs/non-humanoids/chicken/bagawk.ogg'
+
/mob/living/basic/chicken/Initialize(mapload)
. = ..()
GLOB.chicken_count++
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
AddElement(/datum/element/ai_retaliate)
- AddElement(/datum/element/pet_bonus, "clucks happily!")
+ AddElement(/datum/element/pet_bonus, "cluck")
AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW)
AddElement(/datum/element/swabable, CELL_LINE_TABLE_CHICKEN, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
AddElement(/datum/element/animal_variety, "chicken", pick("brown", "black", "white"), modify_pixels = TRUE)
diff --git a/code/modules/mob/living/basic/farm_animals/cow/_cow.dm b/code/modules/mob/living/basic/farm_animals/cow/_cow.dm
index fadac576ea5..5c771e72bad 100644
--- a/code/modules/mob/living/basic/farm_animals/cow/_cow.dm
+++ b/code/modules/mob/living/basic/farm_animals/cow/_cow.dm
@@ -36,13 +36,25 @@
/// What kind of juice do we produce?
var/milked_reagent = /datum/reagent/consumable/milk
+/datum/emote/cow
+ mob_type_allowed_typecache = /mob/living/basic/cow
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/cow/moo
+ key = "moo"
+ key_third_person = "moos"
+ message = "moos happily!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+ vary = TRUE
+ sound = 'sound/mobs/non-humanoids/cow/cow.ogg'
+
/mob/living/basic/cow/Initialize(mapload)
AddComponent(/datum/component/tippable, \
tip_time = 0.5 SECONDS, \
untip_time = 0.5 SECONDS, \
self_right_time = rand(25 SECONDS, 50 SECONDS), \
post_tipped_callback = CALLBACK(src, PROC_REF(after_cow_tipped)))
- AddElement(/datum/element/pet_bonus, "moos happily!")
+ AddElement(/datum/element/pet_bonus, "moo")
AddElement(/datum/element/swabable, CELL_LINE_TABLE_COW, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
setup_udder()
setup_eating()
diff --git a/code/modules/mob/living/basic/farm_animals/pig.dm b/code/modules/mob/living/basic/farm_animals/pig.dm
index d0fbb5a8247..c3cfc57ac05 100644
--- a/code/modules/mob/living/basic/farm_animals/pig.dm
+++ b/code/modules/mob/living/basic/farm_animals/pig.dm
@@ -28,9 +28,20 @@
blood_volume = BLOOD_VOLUME_NORMAL
ai_controller = /datum/ai_controller/basic_controller/pig
+/datum/emote/pig
+ mob_type_allowed_typecache = /mob/living/basic/pig
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/pig/oink
+ key = "oink"
+ key_third_person = "oinks"
+ message = "oinks!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+ vary = TRUE
+ sound = SFX_PIG_OINK
/mob/living/basic/pig/Initialize(mapload)
. = ..()
- AddElement(/datum/element/pet_bonus, "oinks!")
+ AddElement(/datum/element/pet_bonus, "oink")
AddElement(/datum/element/ai_retaliate)
AddElement(/datum/element/ai_flee_while_injured)
make_tameable()
diff --git a/code/modules/mob/living/basic/farm_animals/pony.dm b/code/modules/mob/living/basic/farm_animals/pony.dm
index 29672e032c8..a39fd328f11 100644
--- a/code/modules/mob/living/basic/farm_animals/pony.dm
+++ b/code/modules/mob/living/basic/farm_animals/pony.dm
@@ -33,11 +33,23 @@
/// Greyscale color config; 1st color is body, 2nd is mane
var/list/ponycolors = list("#cc8c5d", "#cc8c5d")
+/datum/emote/pony
+ mob_type_allowed_typecache = /mob/living/basic/pony
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/pony/whicker
+ key = "whicker"
+ key_third_person = "whickers"
+ message = "whickers."
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+ vary = TRUE
+ sound = 'sound/mobs/non-humanoids/pony/snort.ogg'
+
/mob/living/basic/pony/Initialize(mapload)
. = ..()
apply_colour()
- AddElement(/datum/element/pet_bonus, "whickers.")
+ AddElement(/datum/element/pet_bonus, "whicker")
AddElement(/datum/element/ai_retaliate)
AddElement(/datum/element/ai_flee_while_injured)
AddElementTrait(TRAIT_WADDLING, INNATE_TRAIT, /datum/element/waddling)
diff --git a/code/modules/mob/living/basic/farm_animals/rabbit.dm b/code/modules/mob/living/basic/farm_animals/rabbit.dm
index dec48ea8be4..c667ac311cd 100644
--- a/code/modules/mob/living/basic/farm_animals/rabbit.dm
+++ b/code/modules/mob/living/basic/farm_animals/rabbit.dm
@@ -39,10 +39,20 @@
/// passed to animal_varity as the prefix icon.
var/icon_prefix = "rabbit"
+/datum/emote/rabbit
+ mob_type_allowed_typecache = /mob/living/basic/rabbit
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/rabbit
+ key = "hop"
+ key_third_person = "hops"
+ message = "hops around happily!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+
/mob/living/basic/rabbit/Initialize(mapload)
. = ..()
AddElement(/datum/element/ai_retaliate)
- AddElement(/datum/element/pet_bonus, "hops around happily!")
+ AddElement(/datum/element/pet_bonus, "hop")
AddElement(/datum/element/animal_variety, icon_prefix, pick("brown", "black", "white"), TRUE)
if(prob(20)) // bunny
name = "bunny"
diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
index b4de3d2321f..625dc4af907 100644
--- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
+++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
@@ -157,6 +157,17 @@
/// Were we tamed? If yes, tame the mob we become when we grow up too.
var/was_tamed = FALSE
+/datum/emote/lobstrosity_juvenile
+ mob_type_allowed_typecache = /mob/living/basic/mining/lobstrosity/juvenile
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/lobstrosity_juvenile/chitter
+ key = "chitter"
+ key_third_person = "chitters"
+ message = "chitters pleasantly!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+ sound = 'sound/mobs/non-humanoids/insect/chitter.ogg'
+
/mob/living/basic/mining/lobstrosity/juvenile/Initialize(mapload)
. = ..()
var/growth_step = 1000/(7 MINUTES) //It should take 7-ish minutes if you keep the happiness above 40% and at most 12
@@ -203,7 +214,7 @@
. = ..()
was_tamed = TRUE
// They are more pettable I guess
- AddElement(/datum/element/pet_bonus, "chitters pleasantly!")
+ AddElement(/datum/element/pet_bonus, "chitter")
REMOVE_TRAIT(src, TRAIT_MOB_HIDE_HAPPINESS, INNATE_TRAIT)
/mob/living/basic/mining/lobstrosity/juvenile/proc/ready_to_grow()
diff --git a/code/modules/mob/living/basic/pets/cat/cat.dm b/code/modules/mob/living/basic/pets/cat/cat.dm
index fe652495965..68821731ee4 100644
--- a/code/modules/mob/living/basic/pets/cat/cat.dm
+++ b/code/modules/mob/living/basic/pets/cat/cat.dm
@@ -86,7 +86,7 @@
AddElement(/datum/element/cultist_pet, pet_cult_icon_state = cult_icon_state)
AddElement(/datum/element/wears_collar, collar_icon_state = collar_icon_state, collar_resting_icon_state = TRUE)
AddElement(/datum/element/ai_retaliate)
- AddElement(/datum/element/pet_bonus, null, /datum/mood_event/pet_animal, "purr")
+ AddElement(/datum/element/pet_bonus, "purr", /datum/mood_event/pet_animal)
AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW)
add_cell_sample()
add_verb(src, /mob/living/proc/toggle_resting)
diff --git a/code/modules/mob/living/basic/pets/dog/_dog.dm b/code/modules/mob/living/basic/pets/dog/_dog.dm
index 35996d4d77c..b5259d275b5 100644
--- a/code/modules/mob/living/basic/pets/dog/_dog.dm
+++ b/code/modules/mob/living/basic/pets/dog/_dog.dm
@@ -50,12 +50,22 @@
///icon state of our cult icon
var/cult_icon_state
+/datum/emote/dog
+ mob_type_allowed_typecache = /mob/living/basic/pet/dog
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/dog/woof
+ key = "woof"
+ key_third_person = "woof"
+ message = "woofs happily!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+
/mob/living/basic/pet/dog/Initialize(mapload)
. = ..()
AddElement(/datum/element/cultist_pet, pet_cult_icon_state = cult_icon_state)
AddElement(/datum/element/wears_collar, collar_icon_state = collar_icon_state)
ADD_TRAIT(src, TRAIT_WOUND_LICKER, INNATE_TRAIT)
- AddElement(/datum/element/pet_bonus, "woofs happily!")
+ AddElement(/datum/element/pet_bonus, "woof")
AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW)
AddElement(/datum/element/unfriend_attacker, untamed_reaction = "%SOURCE% fixes %TARGET% with a look of betrayal.")
AddComponent(/datum/component/tameable, food_types = list(/obj/item/food/meat/slab/human/mutant/skeleton, /obj/item/stack/sheet/bone), tame_chance = 30, bonus_tame_chance = 15, unique = FALSE)
diff --git a/code/modules/mob/living/basic/pets/fox.dm b/code/modules/mob/living/basic/pets/fox.dm
index c19e89e1fe8..737f7b21391 100644
--- a/code/modules/mob/living/basic/pets/fox.dm
+++ b/code/modules/mob/living/basic/pets/fox.dm
@@ -37,13 +37,22 @@
/datum/pet_command/perform_trick_sequence,
)
+/datum/emote/fox
+ mob_type_allowed_typecache = /mob/living/basic/pet/fox
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/fox/yap
+ key = "yap"
+ key_third_person = "yaps"
+ message = "yaps happily!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
/mob/living/basic/pet/fox/Initialize(mapload)
. = ..()
AddComponent(/datum/component/obeys_commands, pet_commands)
AddElement(/datum/element/cultist_pet)
AddElement(/datum/element/wears_collar)
- AddElement(/datum/element/pet_bonus, "pants and yaps happily!")
+ AddElement(/datum/element/pet_bonus, "yap")
AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW)
AddElement(/datum/element/tiny_mob_hunter, MOB_SIZE_SMALL)
AddElement(/datum/element/ai_retaliate)
diff --git a/code/modules/mob/living/basic/pets/gondolas/gondola.dm b/code/modules/mob/living/basic/pets/gondolas/gondola.dm
index 9e17d1e08a5..e607a13bf1e 100644
--- a/code/modules/mob/living/basic/pets/gondolas/gondola.dm
+++ b/code/modules/mob/living/basic/pets/gondolas/gondola.dm
@@ -39,7 +39,7 @@
/mob/living/basic/pet/gondola/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_MUTE, INNATE_TRAIT)
- AddElement(/datum/element/pet_bonus, "smiles!")
+ AddElement(/datum/element/pet_bonus, "smile")
if(LAZYLEN(loot))
loot = string_list(loot)
AddElement(/datum/element/death_drops, loot)
diff --git a/code/modules/mob/living/basic/pets/penguin.dm b/code/modules/mob/living/basic/pets/penguin.dm
index a597bd70cbb..c1afe10187c 100644
--- a/code/modules/mob/living/basic/pets/penguin.dm
+++ b/code/modules/mob/living/basic/pets/penguin.dm
@@ -17,6 +17,15 @@
///the egg it carries
var/obj/carried_egg
+/datum/emote/penguin
+ mob_type_allowed_typecache = /mob/living/basic/pet/penguin
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/penguin/honk
+ key = "honk"
+ key_third_person = "honks"
+ message = "honks happily!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
/mob/living/basic/pet/penguin/Initialize(mapload)
. = ..()
@@ -24,7 +33,7 @@
AddElement(/datum/element/wears_collar)
AddElement(/datum/element/ai_retaliate)
AddElement(/datum/element/ai_flee_while_injured)
- AddElement(/datum/element/pet_bonus, "honks happily!")
+ AddElement(/datum/element/pet_bonus, "honk")
AddElementTrait(TRAIT_WADDLING, INNATE_TRAIT, /datum/element/waddling)
if(!can_lay_eggs)
return
diff --git a/code/modules/mob/living/basic/pets/sloth.dm b/code/modules/mob/living/basic/pets/sloth.dm
index 9cd7711aa06..b1f5c61001a 100644
--- a/code/modules/mob/living/basic/pets/sloth.dm
+++ b/code/modules/mob/living/basic/pets/sloth.dm
@@ -37,9 +37,19 @@ GLOBAL_DATUM(cargo_sloth, /mob/living/basic/sloth)
ai_controller = /datum/ai_controller/basic_controller/sloth
+/datum/emote/sloth
+ mob_type_allowed_typecache = /mob/living/basic/sloth
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/sloth/smile_slow
+ key = "ssmile"
+ key_third_person = "slowlysmiles"
+ message = "slowly smiles!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+
/mob/living/basic/sloth/Initialize(mapload)
. = ..()
- AddElement(/datum/element/pet_bonus, "slowly smiles!")
+ AddElement(/datum/element/pet_bonus, "ssmile")
AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW)
AddElement(/datum/element/ai_retaliate)
AddComponent(/datum/component/tree_climber)
diff --git a/code/modules/mob/living/basic/space_fauna/ant.dm b/code/modules/mob/living/basic/space_fauna/ant.dm
index 7fbbe03e631..3ae46b7f539 100644
--- a/code/modules/mob/living/basic/space_fauna/ant.dm
+++ b/code/modules/mob/living/basic/space_fauna/ant.dm
@@ -36,10 +36,20 @@
ai_controller = /datum/ai_controller/basic_controller/ant
+/datum/emote/ant
+ mob_type_allowed_typecache = /mob/living/basic/ant
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/ant/clack
+ key = "clack"
+ key_third_person = "clacks"
+ message = "clacks happily!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+
/mob/living/basic/ant/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
- AddElement(/datum/element/pet_bonus, "clacks happily!")
+ AddElement(/datum/element/pet_bonus, "clack")
AddElement(/datum/element/ai_retaliate)
AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW)
diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp.dm b/code/modules/mob/living/basic/space_fauna/carp/carp.dm
index f1c12cc3ce9..a315e253ece 100644
--- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm
+++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm
@@ -81,6 +81,16 @@
/obj/structure/window,
))
+/datum/emote/carp
+ mob_type_allowed_typecache = /mob/living/basic/carp
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/carp/bloop
+ key = "bloop"
+ key_third_person = "bloops"
+ message = "bloops!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+
/mob/living/basic/carp/Initialize(mapload, mob/tamer)
ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT) //Need to set before init cause if we init in hyperspace we get dragged before the trait can be added
. = ..()
@@ -186,7 +196,7 @@
/mob/living/basic/carp/pet/Initialize(mapload)
. = ..()
AddElement(/datum/element/ai_retaliate)
- AddElement(/datum/element/pet_bonus, "bloops happily!")
+ AddElement(/datum/element/pet_bonus, "bloop")
/**
* Lia - Sometimes the pet of the Head of Security.
@@ -291,7 +301,7 @@
/mob/living/basic/carp/passive/Initialize(mapload)
. = ..()
AddComponent(/datum/component/ai_retaliate_advanced, CALLBACK(src, PROC_REF(on_attacked)))
- AddElement(/datum/element/pet_bonus, "bloops happily!")
+ AddElement(/datum/element/pet_bonus, "bloop")
ADD_TRAIT(src, TRAIT_PACIFISM, INNATE_TRAIT)
/// If someone slaps one of the school, scatter
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 f293f1dcbaa..1e78bd924a8 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
@@ -608,6 +608,6 @@
/mob/living/basic/spider/giant/sgt_araneus/Initialize(mapload)
. = ..()
- AddElement(/datum/element/pet_bonus, "chitters proudly!")
+ AddElement(/datum/element/pet_bonus, "chitter")
AddElement(/datum/element/ai_retaliate)
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider.dm b/code/modules/mob/living/basic/space_fauna/spider/spider.dm
index 9f94d839a76..195b8149833 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/spider.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/spider.dm
@@ -49,6 +49,18 @@
/// If true then you shouldn't be told that you're a spider antagonist as soon as you are placed into this mob
var/apply_spider_antag = TRUE
+/datum/emote/spider
+ mob_type_allowed_typecache = /mob/living/basic/spider
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/spider/chitter
+ key = "chitter"
+ key_third_person = "chitters"
+ message = "chitters."
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+ vary = TRUE
+ sound = 'sound/mobs/non-humanoids/insect/chitter.ogg'
+
/mob/living/basic/spider/Initialize(mapload)
. = ..()
add_traits(list(TRAIT_WEB_SURFER, TRAIT_FENCE_CLIMBER), INNATE_TRAIT)
diff --git a/code/modules/mob/living/basic/vermin/lizard.dm b/code/modules/mob/living/basic/vermin/lizard.dm
index da68087d70f..c1c21850ee6 100644
--- a/code/modules/mob/living/basic/vermin/lizard.dm
+++ b/code/modules/mob/living/basic/vermin/lizard.dm
@@ -46,10 +46,19 @@
/mob/living/basic/cockroach,
))
+/datum/emote/lizard
+ mob_type_allowed_typecache = /mob/living/basic/lizard
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/lizard/whicker
+ key = "tongue"
+ message = "sticks its tongue out contentedly!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+
/mob/living/basic/lizard/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
- AddElement(/datum/element/pet_bonus, "sticks its tongue out contentedly!")
+ AddElement(/datum/element/pet_bonus, "tongue")
AddElement(/datum/element/basic_eating, heal_amt = 5, food_types = edibles)
ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(edibles))
diff --git a/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm b/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm
index 4e5d4fbf7f0..6d4d201f59e 100644
--- a/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm
+++ b/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm
@@ -46,6 +46,16 @@
// NOVA EDIT ADDITION END
)
+/datum/emote/mothroach
+ mob_type_allowed_typecache = /mob/living/basic/mothroach
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/mothroach/squeaks
+ key = "squeaks"
+ key_third_person = "squeaks"
+ message = "squeaks!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+
/mob/living/basic/mothroach/Initialize(mapload)
. = ..()
var/static/list/food_types = list(/obj/item/clothing)
@@ -53,7 +63,7 @@
AddComponent(/datum/component/obeys_commands, pet_commands)
ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(food_types))
AddElement(/datum/element/ai_retaliate)
- AddElement(/datum/element/pet_bonus, "squeaks happily!")
+ AddElement(/datum/element/pet_bonus, "squeak")
add_verb(src, /mob/living/proc/toggle_resting)
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm
index aba7c00d4c7..a0c1faf971d 100644
--- a/code/modules/mob/living/basic/vermin/mouse.dm
+++ b/code/modules/mob/living/basic/vermin/mouse.dm
@@ -44,6 +44,18 @@
/datum/pet_command/perform_trick_sequence,
)
+/datum/emote/mouse
+ mob_type_allowed_typecache = /mob/living/basic/mouse
+ mob_type_blacklist_typecache = list()
+
+/datum/emote/mouse/squeak
+ key = "squeak"
+ key_third_person = "squeaks"
+ message = "squeak!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+ vary = TRUE
+ sound = 'sound/mobs/non-humanoids/mouse/mousesqueek.ogg'
+
/mob/living/basic/mouse/Initialize(mapload, tame = FALSE, new_body_color)
. = ..()
if(contributes_to_ratcap)
@@ -278,7 +290,7 @@
. = ..()
// Tom fears no cable.
ADD_TRAIT(src, TRAIT_SHOCKIMMUNE, INNATE_TRAIT)
- AddElement(/datum/element/pet_bonus, "squeaks happily!")
+ AddElement(/datum/element/pet_bonus, "squeak")
/mob/living/basic/mouse/brown/tom/create_a_new_rat()
new /mob/living/basic/mouse/brown(loc, /* tame = */ tame) // dominant gene
diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm
index 6a7f17fda8e..14b371c2bd3 100644
--- a/code/modules/mob/living/carbon/human/_species.dm
+++ b/code/modules/mob/living/carbon/human/_species.dm
@@ -1557,14 +1557,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
H.adjustBruteLoss(pressure_damage, required_bodytype = BODYTYPE_ORGANIC)
H.throw_alert(ALERT_PRESSURE, /atom/movable/screen/alert/lowpressure, 2)
-
-//////////
-// FIRE //
-//////////
-
-/datum/species/proc/handle_fire(mob/living/carbon/human/H, seconds_per_tick, no_protection = FALSE)
- return no_protection
-
////////////
// Stun //
////////////
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 31925573d77..260cc5af20f 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1140,6 +1140,26 @@
add_traits(list(TRAIT_NO_DNA_SCRAMBLE, TRAIT_BADDNA, TRAIT_BORN_MONKEY), SPECIES_TRAIT)
+/mob/living/carbon/human/proc/is_atmos_sealed(additional_flags = null, check_hands = FALSE, ignore_chest_pressureprot = FALSE)
+ var/chest_covered = FALSE
+ var/head_covered = FALSE
+ var/hands_covered = FALSE
+ for (var/obj/item/clothing/equipped in get_equipped_items())
+ // We don't really have space-proof gloves, so even if we're checking them we ignore the flags
+ if ((equipped.body_parts_covered & HANDS) && num_hands >= default_num_hands)
+ hands_covered = TRUE
+ if (!isnull(additional_flags) && !(equipped.clothing_flags & additional_flags))
+ continue
+ if ((ignore_chest_pressureprot || (equipped.clothing_flags & STOPSPRESSUREDAMAGE)) && (equipped.body_parts_covered & CHEST))
+ chest_covered = TRUE
+ if ((equipped.clothing_flags & STOPSPRESSUREDAMAGE) && (equipped.body_parts_covered & HEAD))
+ head_covered = TRUE
+ if (!chest_covered)
+ return FALSE
+ if (!hands_covered && check_hands)
+ return FALSE
+ return head_covered || HAS_TRAIT(src, TRAIT_HEAD_ATMOS_SEALED)
+
/mob/living/carbon/human/species/abductor
race = /datum/species/abductor
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index eeb3f9ea9b3..3c433842000 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -816,6 +816,6 @@
SEND_SIGNAL(src, COMSIG_HUMAN_BURNING)
burn_clothing(seconds_per_tick, fire_handler.stacks)
var/no_protection = FALSE
- if(dna && dna.species)
- no_protection = dna.species.handle_fire(src, seconds_per_tick, no_protection)
+ if (HAS_TRAIT(src, TRAIT_IGNORE_FIRE_PROTECTION))
+ no_protection = TRUE
fire_handler.harm_human(seconds_per_tick, no_protection)
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index 48a63300ee5..dcfbc70ca6d 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -69,62 +69,6 @@
/// If the bones themselves are burning clothes won't help you much
var/internal_fire = FALSE
-/datum/species/plasmaman/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired)
- . = ..()
- var/atmos_sealed = TRUE
- if(HAS_TRAIT(H, TRAIT_NOFIRE))
- atmos_sealed = FALSE
- else if(!isclothing(H.wear_suit) || !(H.wear_suit.clothing_flags & STOPSPRESSUREDAMAGE))
- atmos_sealed = FALSE
- else if(!HAS_TRAIT(H, TRAIT_NOSELFIGNITION_HEAD_ONLY) && (!isclothing(H.head) || !(H.head.clothing_flags & STOPSPRESSUREDAMAGE)))
- atmos_sealed = FALSE
-
- var/flammable_limb = FALSE
- for(var/obj/item/bodypart/found_bodypart as anything in H.bodyparts)//If any plasma based limb is found the plasmaman will attempt to autoignite
- if(IS_ORGANIC_LIMB(found_bodypart) && found_bodypart.limb_id == SPECIES_PLASMAMAN) //Allows for "donated" limbs and augmented limbs to prevent autoignition
- flammable_limb = TRUE
- break
-
- if(!flammable_limb && !H.on_fire) //Allows their suit to attempt to autoextinguish if augged and on fire
- return
-
- var/can_burn = FALSE
- if(!isclothing(H.w_uniform) || !(H.w_uniform.clothing_flags & PLASMAMAN_PREVENT_IGNITION))
- can_burn = TRUE
- else if(!isclothing(H.gloves) || H.num_hands < H.default_num_hands) //If you dont have the other glove then the suit isnt really sealed is it?
- can_burn = TRUE
- else if(!HAS_TRAIT(H, TRAIT_NOSELFIGNITION_HEAD_ONLY) && (!isclothing(H.head) || !(H.head.clothing_flags & PLASMAMAN_PREVENT_IGNITION)))
- can_burn = TRUE
-
- if(!atmos_sealed && can_burn)
- var/datum/gas_mixture/environment = H.loc.return_air()
- if(environment?.total_moles())
- if(environment.gases[/datum/gas/hypernoblium] && (environment.gases[/datum/gas/hypernoblium][MOLES]) >= 5)
- if(H.on_fire && H.fire_stacks > 0)
- H.adjust_fire_stacks(-10 * seconds_per_tick)
- else if(!HAS_TRAIT(H, TRAIT_NOFIRE))
- if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen][MOLES]) >= 1) //Same threshhold that extinguishes fire
- H.adjust_fire_stacks(0.25 * seconds_per_tick)
- if(!H.on_fire && H.fire_stacks > 0)
- H.visible_message(span_danger("[H]'s body reacts with the atmosphere and bursts into flames!"),span_userdanger("Your body reacts with the atmosphere and bursts into flame!"))
- H.ignite_mob()
- internal_fire = TRUE
-
- else if(H.fire_stacks)
- var/obj/item/clothing/under/plasmaman/P = H.w_uniform
- if(istype(P))
- P.Extinguish(H)
- internal_fire = FALSE
- else
- internal_fire = FALSE
-
- H.update_appearance(UPDATE_OVERLAYS)
-
-/datum/species/plasmaman/handle_fire(mob/living/carbon/human/H, seconds_per_tick, no_protection = FALSE)
- if(internal_fire)
- no_protection = TRUE
- . = ..()
-
/datum/species/plasmaman/pre_equip_species_outfit(datum/job/job, mob/living/carbon/human/equipping, visuals_only = FALSE)
if(job?.plasmaman_outfit)
equipping.equipOutfit(job.plasmaman_outfit, visuals_only)
diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm
index 3faf44fe2f0..485b66941d4 100644
--- a/code/modules/mod/modules/modules_general.dm
+++ b/code/modules/mod/modules/modules_general.dm
@@ -675,10 +675,10 @@
return ..()
/obj/item/mod/module/plasma_stabilizer/on_equip()
- ADD_TRAIT(mod.wearer, TRAIT_NOSELFIGNITION_HEAD_ONLY, MOD_TRAIT)
+ ADD_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, MOD_TRAIT)
/obj/item/mod/module/plasma_stabilizer/on_unequip()
- REMOVE_TRAIT(mod.wearer, TRAIT_NOSELFIGNITION_HEAD_ONLY, MOD_TRAIT)
+ REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, MOD_TRAIT)
//Finally, https://pipe.miroware.io/5b52ba1d94357d5d623f74aa/mspfa/Nuke%20Ops/Panels/0648.gif can be real:
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index 72bf5337dba..18e8de72101 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -560,7 +560,7 @@
color_override = "orange",
)
INVOKE_ASYNC(SSticker, TYPE_PROC_REF(/datum/controller/subsystem/ticker, poll_hearts))
- INVOKE_ASYNC(SSvote, TYPE_PROC_REF(/datum/controller/subsystem/vote, initiate_vote), /datum/vote/map_vote, vote_initiator_name = "Map Rotation")
+ INVOKE_ASYNC(SSvote, TYPE_PROC_REF(/datum/controller/subsystem/vote, initiate_vote), /datum/vote/map_vote, vote_initiator_name = "Map Rotation", forced = TRUE)
if(!is_reserved_level(z))
CRASH("Emergency shuttle did not move to transit z-level!")
diff --git a/code/modules/spells/spell_types/pointed/tie_shoes.dm b/code/modules/spells/spell_types/pointed/tie_shoes.dm
index b8efafaf3ba..42c47779aea 100644
--- a/code/modules/spells/spell_types/pointed/tie_shoes.dm
+++ b/code/modules/spells/spell_types/pointed/tie_shoes.dm
@@ -46,7 +46,7 @@
return isliving(cast_on)
// We need to override this, as trying to change next_use_time in cast() will just result in it being overridden.
-/datum/action/cooldown/spell/touch/before_cast(atom/cast_on)
+/datum/action/cooldown/spell/pointed/untie_shoes/before_cast(atom/cast_on)
return ..() | SPELL_NO_IMMEDIATE_COOLDOWN
/datum/action/cooldown/spell/pointed/untie_shoes/cast(mob/living/carbon/cast_on)
diff --git a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm
index b0acf914079..0125601bda5 100644
--- a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm
@@ -12,6 +12,10 @@
head_flags = HEAD_EYESPRITES
bodypart_flags = BODYPART_UNHUSKABLE
+/obj/item/bodypart/head/plasmaman/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/self_ignition)
+
/obj/item/bodypart/chest/plasmaman
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_chest"
@@ -29,6 +33,10 @@
/obj/item/bodypart/chest/plasmaman/get_butt_sprite()
return icon('icons/mob/butts.dmi', BUTT_SPRITE_PLASMA)
+/obj/item/bodypart/chest/plasmaman/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/self_ignition)
+
/obj/item/bodypart/arm/left/plasmaman
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_l_arm"
@@ -41,6 +49,10 @@
burn_modifier = 1.5 //Plasmemes are weak
bodypart_flags = BODYPART_UNHUSKABLE
+/obj/item/bodypart/arm/left/plasmaman/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/self_ignition)
+
/obj/item/bodypart/arm/right/plasmaman
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_r_arm"
@@ -53,6 +65,10 @@
burn_modifier = 1.5 //Plasmemes are weak
bodypart_flags = BODYPART_UNHUSKABLE
+/obj/item/bodypart/arm/right/plasmaman/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/self_ignition)
+
/obj/item/bodypart/leg/left/plasmaman
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_l_leg"
@@ -65,6 +81,10 @@
burn_modifier = 1.5 //Plasmemes are weak
bodypart_flags = BODYPART_UNHUSKABLE
+/obj/item/bodypart/leg/left/plasmaman/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/self_ignition)
+
/obj/item/bodypart/leg/right/plasmaman
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_r_leg"
@@ -76,3 +96,7 @@
brute_modifier = 1.5 //Plasmemes are weak
burn_modifier = 1.5 //Plasmemes are weak
bodypart_flags = BODYPART_UNHUSKABLE
+
+/obj/item/bodypart/leg/right/plasmaman/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/self_ignition)
diff --git a/html/changelogs/AutoChangeLog-pr-87086.yml b/html/changelogs/AutoChangeLog-pr-87086.yml
new file mode 100644
index 00000000000..6197c676d67
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87086.yml
@@ -0,0 +1,5 @@
+author: "SmArtKar"
+delete-after: True
+changes:
+ - bugfix: "Plasmaman space suit internal extinguisher works and can be refilled now"
+ - refactor: "Refactored plasmamen self-ignition to be limb-side instead of being handled by their species"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-87126.yml b/html/changelogs/AutoChangeLog-pr-87126.yml
new file mode 100644
index 00000000000..d8282e1ebb2
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87126.yml
@@ -0,0 +1,6 @@
+author: "grungussuss"
+delete-after: True
+changes:
+ - rscadd: "a lot of basic mobs and pets got new emotes"
+ - refactor: "emotes triggered by petting pets work differently now, please report any oddities with these behaviors."
+ - sound: "new emotes for basic mobs got sounds"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-87158.yml b/html/changelogs/AutoChangeLog-pr-87158.yml
new file mode 100644
index 00000000000..7d1810b7fd5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87158.yml
@@ -0,0 +1,4 @@
+author: "YakumoChen"
+delete-after: True
+changes:
+ - spellcheck: "Proofreads some faxes sent during radioactive nebulae"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-87160.yml b/html/changelogs/AutoChangeLog-pr-87160.yml
new file mode 100644
index 00000000000..f580e640640
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87160.yml
@@ -0,0 +1,4 @@
+author: "Ben10Omintrix"
+delete-after: True
+changes:
+ - bugfix: "fixes ashdrake arena attack not clearing out lavaland walls"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-87168.yml b/html/changelogs/AutoChangeLog-pr-87168.yml
new file mode 100644
index 00000000000..cf39b3a5484
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87168.yml
@@ -0,0 +1,4 @@
+author: "grungussuss"
+delete-after: True
+changes:
+ - bugfix: "snore emote works properly now"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-87183.yml b/html/changelogs/AutoChangeLog-pr-87183.yml
new file mode 100644
index 00000000000..53ac31882e6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-87183.yml
@@ -0,0 +1,4 @@
+author: "SmArtKar"
+delete-after: True
+changes:
+ - bugfix: "Untie shoes should have its cooldown increased correctly when casting it from a long distance"
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index fe0a7bfc9f3..6e853160451 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1321,6 +1321,7 @@
#include "code\datums\components\security_vision.dm"
#include "code\datums\components\seethrough.dm"
#include "code\datums\components\seethrough_mob.dm"
+#include "code\datums\components\self_ignition.dm"
#include "code\datums\components\shell.dm"
#include "code\datums\components\shielded.dm"
#include "code\datums\components\shovel_hands.dm"