From 79ffefa06d0bc25769a5f72f0223640240af4b11 Mon Sep 17 00:00:00 2001
From: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Date: Thu, 17 Nov 2022 12:09:00 -0600
Subject: [PATCH] Allows Fully Heal to be passed a series of flags, fixes
Adminordrazine being horrible (#71123)
## About The Pull Request
- Fully heal can be passed a series of flags detailing what all is
healed by the proc. This allows for things to provide
almost-but-not-quite fully heals.
- Uses this in Adminordrazine, so that it stops being a pain to update
every time fully heal is updated.
This includes some small balance changes which i'll go over, nothing
extremely noticable.
## Why It's Good For The Game
Allows for more precise control over full heals.
## Changelog
:cl: Melbert
refactor: Fully heal can be passed a series of flags. As a result, some
things which previously did a full heal might heal slightly less, or
some things which did partial full heals might do slightly more.
fix: Adminordrazine will no longer completely break every facet of a
person
admin: Ahealing a changeling will refill all of their chems.
/:cl:
---
.../signals/signals_mob/signals_mob_carbon.dm | 3 +
.../signals/signals_mob/signals_mob_living.dm | 4 +-
code/__DEFINES/mobs.dm | 54 ++++++++
code/datums/components/phylactery.dm | 2 +-
code/datums/status_effects/_status_effect.dm | 20 ++-
code/datums/status_effects/buffs.dm | 36 +++--
code/datums/status_effects/debuffs/choke.dm | 4 +-
.../status_effects/debuffs/confusion.dm | 10 +-
code/datums/status_effects/debuffs/debuffs.dm | 2 +
.../status_effects/debuffs/dizziness.dm | 5 +-
.../status_effects/debuffs/drugginess.dm | 5 +-
code/datums/status_effects/debuffs/drunk.dm | 14 +-
.../status_effects/debuffs/fire_stacks.dm | 1 +
.../status_effects/debuffs/hallucination.dm | 11 +-
.../status_effects/debuffs/jitteriness.dm | 5 +-
.../datums/status_effects/debuffs/silenced.dm | 5 +-
.../status_effects/debuffs/speech_debuffs.dm | 9 +-
code/datums/status_effects/wound_effects.dm | 1 +
code/game/machinery/computer/aifixer.dm | 2 +-
code/game/objects/effects/powerup.dm | 6 +-
code/game/objects/items/defib.dm | 2 +-
code/game/objects/items/dice.dm | 2 +-
.../objects/items/robot/robot_upgrades.dm | 2 +-
code/game/objects/items/weaponry.dm | 2 +-
code/game/objects/structures/life_candle.dm | 3 +-
code/modules/admin/topic.dm | 2 +-
code/modules/admin/verbs/debug.dm | 2 +-
code/modules/antagonists/blob/overmind.dm | 2 +-
.../antagonists/changeling/changeling.dm | 14 +-
.../changeling/powers/fakedeath.dm | 37 +++---
.../changeling/powers/mutations.dm | 5 +-
.../changeling/powers/regenerate.dm | 56 ++++----
code/modules/antagonists/cult/runes.dm | 4 +-
.../heretic/status_effects/ghoul.dm | 2 +-
.../antagonists/highlander/highlander.dm | 4 +-
.../antagonists/nightmare/nightmare_organs.dm | 2 +-
.../antagonists/wizard/equipment/artefact.dm | 2 +-
.../mining/equipment/lazarus_injector.dm | 2 +-
.../monster_organs/regenerative_core.dm | 2 +-
code/modules/mob/living/basic/vermin/mouse.dm | 5 +-
code/modules/mob/living/carbon/carbon.dm | 62 ++++++---
.../modules/mob/living/carbon/damage_procs.dm | 14 ++
code/modules/mob/living/carbon/human/human.dm | 22 ++--
.../mob/living/carbon/human/species.dm | 3 -
.../carbon/human/species_types/dullahan.dm | 16 ++-
.../carbon/human/species_types/golems.dm | 7 +-
code/modules/mob/living/damage_procs.dm | 18 ++-
code/modules/mob/living/living.dm | 124 ++++++++++--------
code/modules/mob/living/silicon/ai/ai.dm | 10 +-
.../modules/mob/living/silicon/robot/robot.dm | 20 +--
.../mob/living/simple_animal/bot/bot.dm | 10 +-
.../friendly/drone/interaction.dm | 2 +-
.../mob/living/simple_animal/friendly/pet.dm | 12 +-
.../mob/living/simple_animal/hostile/carp.dm | 23 ++--
.../living/simple_animal/hostile/hivebot.dm | 2 +-
.../hostile/megafauna/colossus.dm | 29 ++--
.../hostile/megafauna/demonic_frost_miner.dm | 2 +-
.../simple_animal/hostile/megafauna/drake.dm | 2 +-
.../hostile/mining_mobs/elites/elite.dm | 6 +-
.../hostile/mining_mobs/goliath.dm | 16 ++-
.../hostile/mining_mobs/polarbear.dm | 2 +-
.../living/simple_animal/hostile/mushroom.dm | 16 ++-
.../simple_animal/hostile/space_dragon.dm | 2 +-
.../mob/living/simple_animal/simple_animal.dm | 2 +-
.../mob/living/simple_animal/slime/death.dm | 2 +-
.../file_system/programs/airestorer.dm | 3 +-
code/modules/projectiles/guns/magic/wand.dm | 4 +-
code/modules/projectiles/projectile/magic.dm | 7 +-
.../reagents/cat2_medicine_reagents.dm | 2 +-
.../chemistry/reagents/medicine_reagents.dm | 45 +------
.../xenobiology/crossbreeding/_potions.dm | 2 +-
.../xenobiology/crossbreeding/regenerative.dm | 4 +-
.../spells/spell_types/jaunt/bloodcrawl.dm | 6 +-
.../spell_types/shapeshift/_shape_status.dm | 2 +-
.../surgery/bodyparts/dismemberment.dm | 13 +-
code/modules/surgery/bodyparts/helpers.dm | 5 +-
code/modules/surgery/organs/_organ.dm | 4 +-
.../organs/external/_external_organs.dm | 8 +-
code/modules/surgery/organs/external/wings.dm | 7 +-
code/modules/surgery/organs/heart.dm | 4 +-
code/modules/surgery/revival.dm | 2 +-
code/modules/unit_tests/medical_wounds.dm | 4 +-
code/modules/zombie/organs.dm | 13 +-
83 files changed, 513 insertions(+), 397 deletions(-)
diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm
index 96b949c5999..e646642c1ea 100644
--- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm
+++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm
@@ -132,3 +132,6 @@
///From mob/living/carbon/human/suicide()
#define COMSIG_HUMAN_SUICIDE_ACT "human_suicide_act"
+
+///from base of /mob/living/carbon/regenerate_limbs(): (excluded_limbs)
+#define COMSIG_CARBON_REGENERATE_LIMBS "living_regen_limbs"
diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
index d58ae4df45a..2a2ea576470 100644
--- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
+++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
@@ -32,8 +32,6 @@
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock"
///from base of mob/living/revive() (full_heal, admin_revive)
#define COMSIG_LIVING_REVIVE "living_revive"
-///from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
-#define COMSIG_LIVING_REGENERATE_LIMBS "living_regen_limbs"
///from base of mob/living/set_buckled(): (new_buckled)
#define COMSIG_LIVING_SET_BUCKLED "living_set_buckled"
///from base of mob/living/set_body_position()
@@ -75,7 +73,7 @@
///from base of /mob/living/can_track(): (mob/user)
#define COMSIG_LIVING_CAN_TRACK "mob_cantrack"
#define COMPONENT_CANT_TRACK (1<<0)
-///from end of fully_heal(): (admin_revive)
+///from end of fully_heal(): (heal_flags)
#define COMSIG_LIVING_POST_FULLY_HEAL "living_post_fully_heal"
/// from start of /mob/living/handle_breathing(): (delta_time, times_fired)
#define COMSIG_LIVING_HANDLE_BREATHING "living_handle_breathing"
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 8038bc4ea92..1171f7c9526 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -703,6 +703,60 @@
/// Possible value of [/atom/movable/buckle_lying]. If set to a different (positive-or-zero) value than this, the buckling thing will force a lying angle on the buckled.
#define NO_BUCKLE_LYING -1
+// Flags for fully_heal().
+
+/// Special flag that means this heal is an admin heal and goes above and beyond
+/// Note, this includes things like removing suicide status and handcuffs / legcuffs, use with slight caution.
+#define HEAL_ADMIN (1<<0)
+/// Heals all brute damage.
+#define HEAL_BRUTE (1<<1)
+/// Heals all burn damage.
+#define HEAL_BURN (1<<2)
+/// Heals all toxin damage, slime people included.
+#define HEAL_TOX (1<<3)
+/// Heals all oxyloss.
+#define HEAL_OXY (1<<4)
+/// Heals all cellular damage.
+#define HEAL_CLONE (1<<5)
+/// Heals all stamina damage.
+#define HEAL_STAM (1<<6)
+/// Restore all limbs to their initial state.
+#define HEAL_LIMBS (1<<7)
+/// Heals all organs from failing. If done as a part of an admin heal, will instead restore all organs to their initial state.
+#define HEAL_ORGANS (1<<8)
+/// Removes all wounds.
+#define HEAL_WOUNDS (1<<9)
+/// Removes all brain traumas, not including permanent ones.
+#define HEAL_TRAUMAS (1<<10)
+/// Removes all reagents present.
+#define HEAL_ALL_REAGENTS (1<<11)
+/// Removes all non-positive diseases.
+#define HEAL_NEGATIVE_DISEASES (1<<12)
+/// Restores body temperature back to nominal.
+#define HEAL_TEMP (1<<13)
+/// Restores blood levels to normal.
+#define HEAL_BLOOD (1<<14)
+/// Removes all non-positive mutations (neutral included).
+#define HEAL_NEGATIVE_MUTATIONS (1<<15)
+/// Removes status effects with this flag set that also have remove_on_fullheal = TRUE.
+#define HEAL_STATUS (1<<16)
+/// Same as above, removes all CC related status effects with this flag set that also have remove_on_fullheal = TRUE.
+#define HEAL_CC_STATUS (1<<17)
+/// Deletes any restraints on the mob (handcuffs / legcuffs)
+#define HEAL_RESTRAINTS (1<<18)
+
+/// Combination flag to only heal the main damage types.
+#define HEAL_DAMAGE (HEAL_BRUTE|HEAL_BURN|HEAL_TOX|HEAL_OXY|HEAL_CLONE|HEAL_STAM)
+/// Combination flag to only heal things messed up things about the mob's body itself.
+#define HEAL_BODY (HEAL_LIMBS|HEAL_ORGANS|HEAL_WOUNDS|HEAL_TRAUMAS|HEAL_BLOOD|HEAL_TEMP)
+/// Combination flag to heal negative things affecting the mob.
+#define HEAL_AFFLICTIONS (HEAL_NEGATIVE_DISEASES|HEAL_NEGATIVE_MUTATIONS|HEAL_ALL_REAGENTS|HEAL_STATUS|HEAL_CC_STATUS)
+
+/// Full heal that isn't admin forced
+#define HEAL_ALL ~(HEAL_ADMIN|HEAL_RESTRAINTS)
+/// Heals everything and is as strong as / is an admin heal
+#define ADMIN_HEAL_ALL ALL
+
/// Checking flags for [/mob/proc/can_read()]
#define READING_CHECK_LITERACY (1<<0)
#define READING_CHECK_LIGHT (1<<1)
diff --git a/code/datums/components/phylactery.dm b/code/datums/components/phylactery.dm
index 03bab2c2980..219780e7e94 100644
--- a/code/datums/components/phylactery.dm
+++ b/code/datums/components/phylactery.dm
@@ -141,7 +141,7 @@
*
* If our lich's mob is revived at some point before returning, stop the timer
*/
-/datum/component/phylactery/proc/stop_timer(mob/living/source, full_heal, admin_revive)
+/datum/component/phylactery/proc/stop_timer(mob/living/source, full_heal_flags)
SIGNAL_HANDLER
deltimer(revive_timer)
diff --git a/code/datums/status_effects/_status_effect.dm b/code/datums/status_effects/_status_effect.dm
index c9f20a10370..061130bb104 100644
--- a/code/datums/status_effects/_status_effect.dm
+++ b/code/datums/status_effects/_status_effect.dm
@@ -24,6 +24,10 @@
var/atom/movable/screen/alert/status_effect/linked_alert
/// Used to define if the status effect should be using SSfastprocess or SSprocessing
var/processing_speed = STATUS_EFFECT_FAST_PROCESS
+ /// Do we self-terminate when a fullheal is called?
+ var/remove_on_fullheal = FALSE
+ /// If remove_on_fullheal is TRUE, what flag do we need to be removed?
+ var/heal_flag_necessary = HEAL_STATUS
/datum/status_effect/New(list/arguments)
on_creation(arglist(arguments))
@@ -39,6 +43,7 @@
return
if(owner)
LAZYADD(owner.status_effects, src)
+ RegisterSignal(owner, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(remove_effect_on_heal))
if(duration != -1)
duration = world.time + duration
@@ -53,7 +58,7 @@
switch(processing_speed)
if(STATUS_EFFECT_FAST_PROCESS)
START_PROCESSING(SSfastprocess, src)
- if (STATUS_EFFECT_NORMAL_PROCESS)
+ if(STATUS_EFFECT_NORMAL_PROCESS)
START_PROCESSING(SSprocessing, src)
return TRUE
@@ -62,13 +67,14 @@
switch(processing_speed)
if(STATUS_EFFECT_FAST_PROCESS)
STOP_PROCESSING(SSfastprocess, src)
- if (STATUS_EFFECT_NORMAL_PROCESS)
+ if(STATUS_EFFECT_NORMAL_PROCESS)
STOP_PROCESSING(SSprocessing, src)
if(owner)
linked_alert = null
owner.clear_alert(id)
LAZYREMOVE(owner.status_effects, src)
on_remove()
+ UnregisterSignal(owner, COMSIG_LIVING_POST_FULLY_HEAL)
owner = null
return ..()
@@ -137,6 +143,16 @@
/datum/status_effect/proc/nextmove_adjust()
return 0
+/// Signal proc for [COMSIG_LIVING_POST_FULLY_HEAL] to remove us on fullheal
+/datum/status_effect/proc/remove_effect_on_heal(datum/source, heal_flags)
+ SIGNAL_HANDLER
+
+ if(!remove_on_fullheal)
+ return
+
+ if(!heal_flag_necessary || (heal_flags & heal_flag_necessary))
+ qdel(src)
+
/// Alert base type for status effect alerts
/atom/movable/screen/alert/status_effect
name = "Curse of Mundanity"
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index 80a75994e49..a143baa294f 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -62,7 +62,7 @@
/datum/status_effect/wish_granters_gift/on_remove()
- owner.revive(full_heal = TRUE, admin_revive = TRUE)
+ owner.revive(ADMIN_HEAL_ALL)
owner.visible_message(span_warning("[owner] appears to wake from the dead, having healed all wounds!"), span_notice("You have regenerated."))
@@ -146,22 +146,38 @@
//Being on fire will suppress this healing
/datum/status_effect/fleshmend
id = "fleshmend"
- duration = 100
+ duration = 10 SECONDS
alert_type = /atom/movable/screen/alert/status_effect/fleshmend
+/datum/status_effect/fleshmend/on_apply()
+ . = ..()
+ if(iscarbon(owner))
+ var/mob/living/carbon/carbon_owner = owner
+ QDEL_LAZYLIST(carbon_owner.all_scars)
+
+ RegisterSignal(owner, COMSIG_LIVING_IGNITED, PROC_REF(on_ignited))
+ RegisterSignal(owner, COMSIG_LIVING_EXTINGUISHED, PROC_REF(on_extinguished))
+
+/datum/status_effect/fleshmend/on_remove()
+ UnregisterSignal(owner, list(COMSIG_LIVING_IGNITED, COMSIG_LIVING_EXTINGUISHED))
+
/datum/status_effect/fleshmend/tick()
if(owner.on_fire)
- linked_alert.icon_state = "fleshmend_fire"
return
- else
- linked_alert.icon_state = "fleshmend"
+
owner.adjustBruteLoss(-10, FALSE)
owner.adjustFireLoss(-5, FALSE)
owner.adjustOxyLoss(-10)
- if(!iscarbon(owner))
- return
- var/mob/living/carbon/C = owner
- QDEL_LAZYLIST(C.all_scars)
+
+/datum/status_effect/fleshmend/proc/on_ignited(datum/source)
+ SIGNAL_HANDLER
+
+ linked_alert?.icon_state = "fleshmend_fire"
+
+/datum/status_effect/fleshmend/proc/on_extinguished(datum/source)
+ SIGNAL_HANDLER
+
+ linked_alert?.icon_state = "fleshmend"
/atom/movable/screen/alert/status_effect/fleshmend
name = "Fleshmend"
@@ -309,7 +325,7 @@
ADD_TRAIT(owner, TRAIT_IGNOREDAMAGESLOWDOWN, STATUS_EFFECT_TRAIT)
owner.adjustBruteLoss(-25)
owner.adjustFireLoss(-25)
- owner.remove_CC()
+ owner.fully_heal(HEAL_CC_STATUS)
owner.bodytemperature = owner.get_body_temp_normal()
if(ishuman(owner))
var/mob/living/carbon/human/humi = owner
diff --git a/code/datums/status_effects/debuffs/choke.dm b/code/datums/status_effects/debuffs/choke.dm
index 683c7e70a42..813d8864abc 100644
--- a/code/datums/status_effects/debuffs/choke.dm
+++ b/code/datums/status_effects/debuffs/choke.dm
@@ -3,6 +3,7 @@
id = "choke"
tick_interval = 0.2 SECONDS
alert_type = null
+ remove_on_fullheal = TRUE
/// Weakref to the thing we're choking on
var/datum/weakref/choking_on_ref
/// If the thing we're choking on is on fire
@@ -41,7 +42,6 @@
choking_on.forceMove(owner)
RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_NOBREATH), PROC_REF(no_breathing))
RegisterSignal(owner, COMSIG_MOB_LOGOUT, PROC_REF(on_logout))
- RegisterSignal(owner, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(remove_choke))
RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(on_death))
// Of note, this means plasma lovers lose some methods of vomiting up
RegisterSignal(owner, COMSIG_CARBON_VOMITED, PROC_REF(on_vomit))
@@ -182,7 +182,7 @@
victim.balloon_alert(aggressor, "already helping!")
return
if(DOING_INTERACTION(aggressor, "heimlich"))
- victim.balloon_alert(aggressor, "already helping someone!")
+ victim.balloon_alert(aggressor, "already helping someone!")
return
if(!thrusting_continues(victim, aggressor, before_work = TRUE))
diff --git a/code/datums/status_effects/debuffs/confusion.dm b/code/datums/status_effects/debuffs/confusion.dm
index 209e9bdebb2..0f8f0ef3187 100644
--- a/code/datums/status_effects/debuffs/confusion.dm
+++ b/code/datums/status_effects/debuffs/confusion.dm
@@ -9,24 +9,18 @@
/datum/status_effect/confusion
id = "confusion"
alert_type = null
+ remove_on_fullheal = TRUE
/datum/status_effect/confusion/on_creation(mob/living/new_owner, duration = 10 SECONDS)
src.duration = duration
return ..()
/datum/status_effect/confusion/on_apply()
- RegisterSignal(owner, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(remove_confusion))
RegisterSignal(owner, COMSIG_MOB_CLIENT_PRE_MOVE, PROC_REF(on_move))
return TRUE
/datum/status_effect/confusion/on_remove()
- UnregisterSignal(owner, list(COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_MOB_CLIENT_PRE_MOVE))
-
-/// Removes all of our confusion (self terminate) on signal
-/datum/status_effect/confusion/proc/remove_confusion(datum/source)
- SIGNAL_HANDLER
-
- qdel(src)
+ UnregisterSignal(owner, COMSIG_MOB_CLIENT_PRE_MOVE)
/// Signal proc for [COMSIG_MOB_CLIENT_PRE_MOVE]. We have a chance to mix up our movement pre-move with confusion.
/datum/status_effect/confusion/proc/on_move(datum/source, list/move_args)
diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm
index 933dc9b2735..28306c585a9 100644
--- a/code/datums/status_effects/debuffs/debuffs.dm
+++ b/code/datums/status_effects/debuffs/debuffs.dm
@@ -4,6 +4,8 @@
tick_interval = 0
status_type = STATUS_EFFECT_REPLACE
alert_type = null
+ remove_on_fullheal = TRUE
+ heal_flag_necessary = HEAL_CC_STATUS
var/needs_update_stat = FALSE
/datum/status_effect/incapacitating/on_creation(mob/living/new_owner, set_duration)
diff --git a/code/datums/status_effects/debuffs/dizziness.dm b/code/datums/status_effects/debuffs/dizziness.dm
index 82ced79e26a..2930f0b6856 100644
--- a/code/datums/status_effects/debuffs/dizziness.dm
+++ b/code/datums/status_effects/debuffs/dizziness.dm
@@ -2,17 +2,18 @@
id = "dizziness"
tick_interval = 2 SECONDS
alert_type = null
+ remove_on_fullheal = TRUE
/datum/status_effect/dizziness/on_creation(mob/living/new_owner, duration = 10 SECONDS)
src.duration = duration
return ..()
/datum/status_effect/dizziness/on_apply()
- RegisterSignal(owner, list(COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_LIVING_DEATH), PROC_REF(clear_dizziness))
+ RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(clear_dizziness))
return TRUE
/datum/status_effect/dizziness/on_remove()
- UnregisterSignal(owner, list(COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_LIVING_DEATH))
+ UnregisterSignal(owner, COMSIG_LIVING_DEATH)
// In case our client's offset is somewhere wacky from the dizziness effect
owner.client?.pixel_x = initial(owner.client?.pixel_x)
owner.client?.pixel_y = initial(owner.client?.pixel_y)
diff --git a/code/datums/status_effects/debuffs/drugginess.dm b/code/datums/status_effects/debuffs/drugginess.dm
index 651eb862148..c9a4b034634 100644
--- a/code/datums/status_effects/debuffs/drugginess.dm
+++ b/code/datums/status_effects/debuffs/drugginess.dm
@@ -2,13 +2,14 @@
/datum/status_effect/drugginess
id = "drugged"
alert_type = /atom/movable/screen/alert/status_effect/high
+ remove_on_fullheal = TRUE
/datum/status_effect/drugginess/on_creation(mob/living/new_owner, duration = 10 SECONDS)
src.duration = duration
return ..()
/datum/status_effect/drugginess/on_apply()
- RegisterSignal(owner, list(COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_LIVING_DEATH), PROC_REF(remove_drugginess))
+ RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(remove_drugginess))
owner.add_mood_event(id, /datum/mood_event/high)
owner.overlay_fullscreen(id, /atom/movable/screen/fullscreen/high)
@@ -17,7 +18,7 @@
return TRUE
/datum/status_effect/drugginess/on_remove()
- UnregisterSignal(owner, list(COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_LIVING_DEATH))
+ UnregisterSignal(owner, COMSIG_LIVING_DEATH)
owner.clear_mood_event(id)
owner.clear_fullscreen(id)
diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm
index 062658b504b..97d0fd48b98 100644
--- a/code/datums/status_effects/debuffs/drunk.dm
+++ b/code/datums/status_effects/debuffs/drunk.dm
@@ -14,6 +14,7 @@
id = "drunk"
tick_interval = 2 SECONDS
status_type = STATUS_EFFECT_REPLACE
+ remove_on_fullheal = TRUE
/// The level of drunkness we are currently at.
var/drunk_value = 0
@@ -21,13 +22,6 @@
. = ..()
set_drunk_value(drunk_value)
-/datum/status_effect/inebriated/on_apply()
- RegisterSignal(owner, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(clear_drunkenness))
- return TRUE
-
-/datum/status_effect/inebriated/on_remove()
- UnregisterSignal(owner, COMSIG_LIVING_POST_FULLY_HEAL)
-
/datum/status_effect/inebriated/get_examine_text()
// Dead people don't look drunk
if(owner.stat == DEAD || HAS_TRAIT(owner, TRAIT_FAKEDEATH))
@@ -58,12 +52,6 @@
return null
-/// Removes all of our drunkenness (self-deletes) on signal.
-/datum/status_effect/inebriated/proc/clear_drunkenness(mob/living/source)
- SIGNAL_HANDLER
-
- qdel(src)
-
/// Sets the drunk value to set_to, deleting if the value drops to 0 or lower
/datum/status_effect/inebriated/proc/set_drunk_value(set_to)
if(!isnum(set_to))
diff --git a/code/datums/status_effects/debuffs/fire_stacks.dm b/code/datums/status_effects/debuffs/fire_stacks.dm
index af4f2805a36..2ea67ba615f 100644
--- a/code/datums/status_effects/debuffs/fire_stacks.dm
+++ b/code/datums/status_effects/debuffs/fire_stacks.dm
@@ -126,6 +126,7 @@
/datum/status_effect/fire_handler/fire_stacks
id = "fire_stacks" //fire_stacks and wet_stacks should have different IDs or else has_status_effect won't work
+ remove_on_fullheal = TRUE
enemy_types = list(/datum/status_effect/fire_handler/wet_stacks)
stack_modifier = 1
diff --git a/code/datums/status_effects/debuffs/hallucination.dm b/code/datums/status_effects/debuffs/hallucination.dm
index 5179758356b..79567846000 100644
--- a/code/datums/status_effects/debuffs/hallucination.dm
+++ b/code/datums/status_effects/debuffs/hallucination.dm
@@ -4,6 +4,7 @@
id = "hallucination"
alert_type = null
tick_interval = 2 SECONDS
+ remove_on_fullheal = TRUE
/// Can this hallucination apply to silicons?
var/affects_silicons = FALSE
/// The lower range of when the next hallucination will trigger after one occurs.
@@ -28,8 +29,7 @@
if(!affects_silicons && issilicon(owner))
return FALSE
- RegisterSignal(owner, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(remove_hallucinations))
- RegisterSignal(owner, COMSIG_LIVING_HEALTHSCAN, PROC_REF(on_health_scan))
+ RegisterSignal(owner, COMSIG_LIVING_HEALTHSCAN, PROC_REF(on_health_scan))
if(iscarbon(owner))
RegisterSignal(owner, COMSIG_CARBON_CHECKING_BODYPART, PROC_REF(on_check_bodypart))
RegisterSignal(owner, COMSIG_CARBON_BUMPED_AIRLOCK_OPEN, PROC_REF(on_bump_airlock))
@@ -38,18 +38,11 @@
/datum/status_effect/hallucination/on_remove()
UnregisterSignal(owner, list(
- COMSIG_LIVING_POST_FULLY_HEAL,
COMSIG_LIVING_HEALTHSCAN,
COMSIG_CARBON_CHECKING_BODYPART,
COMSIG_CARBON_BUMPED_AIRLOCK_OPEN,
))
-/// Signal proc for [COMSIG_LIVING_POST_FULLY_HEAL], terminate on full heal
-/datum/status_effect/hallucination/proc/remove_hallucinations(datum/source)
- SIGNAL_HANDLER
-
- qdel(src)
-
/// Signal proc for [COMSIG_LIVING_HEALTHSCAN]. Show we're hallucinating to (advanced) scanners.
/datum/status_effect/hallucination/proc/on_health_scan(datum/source, list/render_list, advanced, mob/user, mode)
SIGNAL_HANDLER
diff --git a/code/datums/status_effects/debuffs/jitteriness.dm b/code/datums/status_effects/debuffs/jitteriness.dm
index 95a3060ca45..13bb9bc2e9f 100644
--- a/code/datums/status_effects/debuffs/jitteriness.dm
+++ b/code/datums/status_effects/debuffs/jitteriness.dm
@@ -2,6 +2,7 @@
id = "jitter"
tick_interval = 2 SECONDS
alert_type = null
+ remove_on_fullheal = TRUE
/datum/status_effect/jitter/on_creation(mob/living/new_owner, duration = 10 SECONDS)
src.duration = duration
@@ -14,12 +15,12 @@
owner.do_jitter_animation(duration / 10)
return FALSE
- RegisterSignal(owner, list(COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_LIVING_DEATH), PROC_REF(remove_jitter))
+ RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(remove_jitter))
owner.add_mood_event(id, /datum/mood_event/jittery)
return TRUE
/datum/status_effect/jitter/on_remove()
- UnregisterSignal(owner, list(COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_LIVING_DEATH))
+ UnregisterSignal(owner, COMSIG_LIVING_DEATH)
owner.clear_mood_event(id)
// juuust in case, reset our x and y's from our jittering
owner.pixel_x = 0
diff --git a/code/datums/status_effects/debuffs/silenced.dm b/code/datums/status_effects/debuffs/silenced.dm
index 84b6d537f70..50dab3b6da0 100644
--- a/code/datums/status_effects/debuffs/silenced.dm
+++ b/code/datums/status_effects/debuffs/silenced.dm
@@ -1,18 +1,19 @@
/datum/status_effect/silenced
id = "silent"
alert_type = null
+ remove_on_fullheal = TRUE
/datum/status_effect/silenced/on_creation(mob/living/new_owner, duration = 10 SECONDS)
src.duration = duration
return ..()
/datum/status_effect/silenced/on_apply()
- RegisterSignal(owner, list(COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_LIVING_DEATH), PROC_REF(clear_silence))
+ RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(clear_silence))
ADD_TRAIT(owner, TRAIT_MUTE, id)
return TRUE
/datum/status_effect/silenced/on_remove()
- UnregisterSignal(owner, list(COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_LIVING_DEATH))
+ UnregisterSignal(owner, COMSIG_LIVING_DEATH)
REMOVE_TRAIT(owner, TRAIT_MUTE, id)
/// Signal proc that clears any silence we have (self-deletes).
diff --git a/code/datums/status_effects/debuffs/speech_debuffs.dm b/code/datums/status_effects/debuffs/speech_debuffs.dm
index 4a5ff20b302..7298696bfc1 100644
--- a/code/datums/status_effects/debuffs/speech_debuffs.dm
+++ b/code/datums/status_effects/debuffs/speech_debuffs.dm
@@ -1,6 +1,7 @@
/datum/status_effect/speech
id = null
alert_type = null
+ remove_on_fullheal = TRUE
/datum/status_effect/speech/on_creation(mob/living/new_owner, duration = 10 SECONDS)
src.duration = duration
@@ -8,18 +9,10 @@
/datum/status_effect/speech/on_apply()
RegisterSignal(owner, COMSIG_LIVING_TREAT_MESSAGE, PROC_REF(handle_message))
- RegisterSignal(owner, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(on_heal))
return TRUE
/datum/status_effect/speech/on_remove()
UnregisterSignal(owner, COMSIG_LIVING_TREAT_MESSAGE)
- UnregisterSignal(owner, COMSIG_LIVING_POST_FULLY_HEAL)
-
-/// Signal proc for [COMSIG_LIVING_POST_FULLY_HEAL], removes all stutters and slurring on full heal
-/datum/status_effect/speech/proc/on_heal(datum/source, admin_revive)
- SIGNAL_HANDLER
-
- qdel(src)
/**
* Signal proc for [COMSIG_LIVING_TREAT_MESSAGE]
diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm
index 7e93c2318ab..c64e07f59c0 100644
--- a/code/datums/status_effects/wound_effects.dm
+++ b/code/datums/status_effects/wound_effects.dm
@@ -8,6 +8,7 @@
/datum/status_effect/determined
id = "determined"
alert_type = /atom/movable/screen/alert/status_effect/determined
+ remove_on_fullheal = TRUE
/datum/status_effect/determined/on_apply()
. = ..()
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index f8eb677c70e..87e53ebb368 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -70,7 +70,7 @@
occupier.adjustBruteLoss(-5, FALSE)
occupier.updatehealth()
if(occupier.health >= 0 && occupier.stat == DEAD)
- occupier.revive(full_heal = FALSE, admin_revive = FALSE)
+ occupier.revive()
if(!occupier.radio_enabled)
occupier.radio_enabled = TRUE
to_chat(occupier, span_warning("Your Subspace Transceiver has been enabled!"))
diff --git a/code/game/objects/effects/powerup.dm b/code/game/objects/effects/powerup.dm
index cd5091abccb..b0c47bde6f8 100644
--- a/code/game/objects/effects/powerup.dm
+++ b/code/game/objects/effects/powerup.dm
@@ -64,15 +64,15 @@
var/heal_amount = 50
/// Does this pickup fully heal when picked up
var/full_heal = FALSE
- /// If full heal, does this do an admin level heal?
- var/admin_heal = FALSE
+ /// If full heal, what flags do we pass?
+ var/heal_flags = HEAL_ALL
/obj/effect/powerup/health/trigger(mob/living/target)
. = ..()
if(!.)
return
if(full_heal)
- target.fully_heal(admin_heal)
+ target.fully_heal(heal_flags)
else if(heal_amount)
target.heal_ordered_damage(heal_amount, list(BRUTE, BURN))
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index d25ef08581a..fc0c8c10d27 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -651,7 +651,7 @@
H.set_heartattack(FALSE)
if(defib_result == DEFIB_POSSIBLE)
H.grab_ghost()
- H.revive(full_heal = FALSE, admin_revive = FALSE)
+ H.revive()
H.emote("gasp")
H.set_jitter_if_lower(200 SECONDS)
SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK)
diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm
index 37ac96a5af8..58b2dc38e9a 100644
--- a/code/game/objects/items/dice.dm
+++ b/code/game/objects/items/dice.dm
@@ -382,7 +382,7 @@
if(12)
//Healing
selected_turf.visible_message(span_userdanger("[user] looks very healthy!"))
- user.revive(full_heal = TRUE, admin_revive = TRUE)
+ user.revive(ADMIN_HEAL_ALL)
if(13)
//Mad Dosh
selected_turf.visible_message(span_userdanger("Mad dosh shoots out of [src]!"))
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index b153bf41160..90ddb0b4943 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -779,7 +779,7 @@
else
playsound(loc, 'sound/machines/ping.ogg', 75, TRUE)
- borgo.revive(full_heal = FALSE, admin_revive = FALSE)
+ borgo.revive()
borgo.logevent("WARN -- System recovered from unexpected shutdown.")
borgo.logevent("System brought online.")
return ..()
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index 55d7238b175..080667a509e 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -156,7 +156,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/claymore/highlander/attack(mob/living/target, mob/living/user)
. = ..()
if(!QDELETED(target) && target.stat == DEAD && target.mind && target.mind.special_role == "highlander")
- user.fully_heal(admin_revive = FALSE) //STEAL THE LIFE OF OUR FALLEN FOES
+ user.fully_heal() //STEAL THE LIFE OF OUR FALLEN FOES
add_notch(user)
target.visible_message(span_warning("[target] crumbles to dust beneath [user]'s blows!"), span_userdanger("As you fall, your body crumbles to dust!"))
target.investigate_log("has been dusted by a highlander claymore.", INVESTIGATE_DEATHS)
diff --git a/code/game/objects/structures/life_candle.dm b/code/game/objects/structures/life_candle.dm
index 3b2777a2b7f..7c9250ed9a2 100644
--- a/code/game/objects/structures/life_candle.dm
+++ b/code/game/objects/structures/life_candle.dm
@@ -89,8 +89,7 @@
mind.transfer_to(body)
else
body.forceMove(T)
- body.revive(full_heal = TRUE, admin_revive = TRUE)
- mind.grab_ghost(TRUE)
+ body.revive(ADMIN_HEAL_ALL, force_grab_ghost = TRUE)
body.flash_act()
if(ishuman(body) && istype(outfit))
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index dcc8fbdd368..d675b81df26 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -671,7 +671,7 @@
to_chat(usr, "This can only be used on instances of type /mob/living.", confidential = TRUE)
return
- L.revive(full_heal = TRUE, admin_revive = TRUE)
+ L.revive(ADMIN_HEAL_ALL)
message_admins(span_danger("Admin [key_name_admin(usr)] healed / revived [key_name_admin(L)]!"))
log_admin("[key_name(usr)] healed / Revived [key_name(L)].")
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index e40587a71af..34e7211b20c 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -509,7 +509,7 @@
if(!istype(M))
tgui_alert(usr,"Cannot revive a ghost")
return
- M.revive(full_heal = TRUE, admin_revive = TRUE)
+ M.revive(ADMIN_HEAL_ALL)
log_admin("[key_name(usr)] healed / revived [key_name(M)]")
var/msg = span_danger("Admin [key_name_admin(usr)] healed / revived [ADMIN_LOOKUPFLW(M)]!")
diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm
index cb1a6ab20e5..d9a26be372d 100644
--- a/code/modules/antagonists/blob/overmind.dm
+++ b/code/modules/antagonists/blob/overmind.dm
@@ -180,7 +180,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
L.death()
new/mob/living/simple_animal/hostile/blob/blobspore(T)
else
- L.fully_heal(admin_revive = FALSE)
+ L.fully_heal()
for(var/area/A in GLOB.areas)
if(!(A.type in GLOB.the_station_areas))
diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm
index f69de6d916e..dbb81b8010d 100644
--- a/code/modules/antagonists/changeling/changeling.dm
+++ b/code/modules/antagonists/changeling/changeling.dm
@@ -141,6 +141,7 @@
handle_clown_mutation(living_mob, "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself.")
RegisterSignal(living_mob, COMSIG_MOB_LOGIN, PROC_REF(on_login))
RegisterSignal(living_mob, COMSIG_LIVING_LIFE, PROC_REF(on_life))
+ RegisterSignal(living_mob, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(on_fullhealed))
RegisterSignal(living_mob, list(COMSIG_MOB_MIDDLECLICKON, COMSIG_MOB_ALTCLICKON), PROC_REF(on_click_sting))
if(living_mob.hud_used)
@@ -198,7 +199,7 @@
/datum/antagonist/changeling/remove_innate_effects(mob/living/mob_override)
var/mob/living/living_mob = mob_override || owner.current
handle_clown_mutation(living_mob, removing = FALSE)
- UnregisterSignal(living_mob, list(COMSIG_MOB_LOGIN, COMSIG_LIVING_LIFE, COMSIG_MOB_MIDDLECLICKON, COMSIG_MOB_ALTCLICKON))
+ UnregisterSignal(living_mob, list(COMSIG_MOB_LOGIN, COMSIG_LIVING_LIFE, COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_MOB_MIDDLECLICKON, COMSIG_MOB_ALTCLICKON))
if(living_mob.hud_used)
var/datum/hud/hud_used = living_mob.hud_used
@@ -258,7 +259,7 @@
regain_powers()
-/*
+/**
* Signal proc for [COMSIG_LIVING_LIFE].
* Handles regenerating chemicals on life ticks.
*/
@@ -273,6 +274,15 @@
else
adjust_chemicals((chem_recharge_rate - chem_recharge_slowdown) * delta_time)
+/**
+ * Signal proc for [COMSIG_LIVING_POST_FULLY_HEAL], getting admin-healed restores our chemicals.
+ */
+/datum/antagonist/changeling/proc/on_fullhealed(datum/source, heal_flags)
+ SIGNAL_HANDLER
+
+ if(heal_flags & HEAL_ADMIN)
+ adjust_chemicals(INFINITY)
+
/**
* Signal proc for [COMSIG_MOB_MIDDLECLICKON] and [COMSIG_MOB_ALTCLICKON].
* Allows the changeling to sting people with a click.
diff --git a/code/modules/antagonists/changeling/powers/fakedeath.dm b/code/modules/antagonists/changeling/powers/fakedeath.dm
index b1315945d6a..7a4ef35d9f9 100644
--- a/code/modules/antagonists/changeling/powers/fakedeath.dm
+++ b/code/modules/antagonists/changeling/powers/fakedeath.dm
@@ -27,24 +27,29 @@
addtimer(CALLBACK(src, PROC_REF(ready_to_regenerate), user), LING_FAKEDEATH_TIME, TIMER_UNIQUE)
return TRUE
-/datum/action/changeling/fakedeath/proc/revive(mob/living/user)
- if(!user || !istype(user))
+/datum/action/changeling/fakedeath/proc/revive(mob/living/carbon/user)
+ if(!istype(user))
return
+
user.cure_fakedeath("changeling")
- user.revive(full_heal = TRUE, admin_revive = FALSE)
- var/list/missing = user.get_missing_limbs()
- missing -= BODY_ZONE_HEAD // headless changelings are funny
- if(missing.len)
- playsound(user, 'sound/magic/demon_consume.ogg', 50, TRUE)
- user.visible_message("[user]'s missing limbs \
- reform, making a loud, grotesque sound!",
- "Your limbs regrow, making a \
- loud, crunchy sound and giving you great pain!",
- "You hear organic matter ripping \
- and tearing!")
- user.emote("scream")
- user.regenerate_limbs(list(BODY_ZONE_HEAD))
- user.regenerate_organs()
+ // Heal all damage and some minor afflictions,
+ var/flags_to_heal = (HEAL_DAMAGE|HEAL_BODY|HEAL_STATUS|HEAL_CC_STATUS)
+ // but leave out limbs so we can do it specially
+ user.revive(flags_to_heal & ~HEAL_LIMBS)
+
+ var/static/list/dont_regenerate = list(BODY_ZONE_HEAD) // headless changelings are funny
+ if(!length(user.get_missing_limbs() - dont_regenerate))
+ return
+
+ playsound(user, 'sound/magic/demon_consume.ogg', 50, TRUE)
+ user.visible_message(
+ span_warning("[user]'s missing limbs reform, making a loud, grotesque sound!"),
+ span_userdanger("Your limbs regrow, making a loud, crunchy sound and giving you great pain!"),
+ span_hear("You hear organic matter ripping and tearing!"),
+ )
+ user.emote("scream")
+ // Manually call this (outside of revive/fullheal) so we can pass our blacklist
+ user.regenerate_limbs(dont_regenerate)
/datum/action/changeling/fakedeath/proc/ready_to_regenerate(mob/user)
if(!user?.mind)
diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm
index 994e45383ea..6b95ea8c19e 100644
--- a/code/modules/antagonists/changeling/powers/mutations.dm
+++ b/code/modules/antagonists/changeling/powers/mutations.dm
@@ -36,11 +36,14 @@
user.update_held_items()
return 1
-/datum/action/changeling/weapon/sting_action(mob/living/user)
+/datum/action/changeling/weapon/sting_action(mob/living/carbon/user)
var/obj/item/held = user.get_active_held_item()
if(held && !user.dropItemToGround(held))
to_chat(user, span_warning("[held] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!"))
return
+ if(!istype(user))
+ to_chat(user, span_warning("You can't do that in this state!"))
+ return
..()
var/limb_regen = 0
if(user.active_hand_index % 2 == 0) //we regen the arm before changing it into the weapon
diff --git a/code/modules/antagonists/changeling/powers/regenerate.dm b/code/modules/antagonists/changeling/powers/regenerate.dm
index 94a90bb6725..87915534004 100644
--- a/code/modules/antagonists/changeling/powers/regenerate.dm
+++ b/code/modules/antagonists/changeling/powers/regenerate.dm
@@ -8,37 +8,29 @@
req_stat = HARD_CRIT
/datum/action/changeling/regenerate/sting_action(mob/living/user)
+ if(!iscarbon(user))
+ to_chat(user, span_notice("You have nothing to regenerate in this state!"))
+ return FALSE
+
..()
- to_chat(user, "You feel an itching, both inside and \
- outside as your tissues knit and reknit.")
- if(iscarbon(user))
- var/mob/living/carbon/C = user
- var/list/missing = C.get_missing_limbs()
- if(missing.len)
- playsound(user, 'sound/magic/demon_consume.ogg', 50, TRUE)
- C.visible_message("[user]'s missing limbs \
- reform, making a loud, grotesque sound!",
- "Your limbs regrow, making a \
- loud, crunchy sound and giving you great pain!",
- "You hear organic matter ripping \
- and tearing!")
- C.emote("scream")
- C.regenerate_limbs()
- if(!user.getorganslot(ORGAN_SLOT_BRAIN))
- var/obj/item/organ/internal/brain/B
- if(C.has_dna() && C.dna.species.mutantbrain)
- B = new C.dna.species.mutantbrain()
- else
- B = new()
- B.organ_flags &= ~ORGAN_VITAL
- B.decoy_override = TRUE
- B.Insert(C)
- C.regenerate_organs()
- for(var/i in C.all_wounds)
- var/datum/wound/iter_wound = i
- iter_wound.remove_wound()
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- H.restore_blood()
- H.remove_all_embedded_objects()
+ to_chat(user, span_notice("You feel an itching, both inside and outside as your tissues knit and reknit."))
+ var/mob/living/carbon/carbon_user = user
+ if(length(carbon_user.get_missing_limbs()))
+ playsound(user, 'sound/magic/demon_consume.ogg', 50, TRUE)
+ carbon_user.visible_message(
+ span_warning("[user]'s missing limbs reform, making a loud, grotesque sound!"),
+ span_userdanger("Your limbs regrow, making a loud, crunchy sound and giving you great pain!"),
+ span_hear("You hear organic matter ripping and tearing!"),
+ )
+
+ carbon_user.emote("scream")
+
+ carbon_user.fully_heal(HEAL_BODY)
+
+ // Make sure the brain's nonvital
+ // Shouldn't be necessary but you can never be certain with lingcode
+ var/obj/item/organ/internal/brain/replacement_brain = user.getorganslot(ORGAN_SLOT_BRAIN)
+ replacement_brain.organ_flags &= ~ORGAN_VITAL
+ replacement_brain.decoy_override = TRUE
+
return TRUE
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index ca0183a8589..c576b39ba06 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -608,8 +608,8 @@ structure_check() searches for nearby cultist structures required for the invoca
fail_invoke()
return
sacrifices_used += SOULS_TO_REVIVE
- mob_to_revive.revive(full_heal = TRUE, admin_revive = TRUE) //This does remove traits and such, but the rune might actually see some use because of it!
- mob_to_revive.grab_ghost()
+ mob_to_revive.revive(ADMIN_HEAL_ALL) //This does remove traits and such, but the rune might actually see some use because of it! //Why did you think this was a good idea
+
if(!mob_to_revive.client || mob_to_revive.client.is_afk())
set waitfor = FALSE
var/list/mob/dead/observer/candidates = poll_candidates_for_mob("Do you want to play as a [mob_to_revive.real_name], an inactive blood cultist?", ROLE_CULTIST, ROLE_CULTIST, 5 SECONDS, mob_to_revive)
diff --git a/code/modules/antagonists/heretic/status_effects/ghoul.dm b/code/modules/antagonists/heretic/status_effects/ghoul.dm
index 9fac065a352..5857dc28bd1 100644
--- a/code/modules/antagonists/heretic/status_effects/ghoul.dm
+++ b/code/modules/antagonists/heretic/status_effects/ghoul.dm
@@ -48,7 +48,7 @@
var/mob/living/carbon/human/human_target = owner
RegisterSignal(human_target, COMSIG_LIVING_DEATH, PROC_REF(remove_ghoul_status))
- human_target.revive(full_heal = TRUE, admin_revive = TRUE)
+ human_target.revive(ADMIN_HEAL_ALL) // Have to do an admin heal here, otherwise they'll likely just die due to missing organs or limbs
if(new_max_health)
human_target.setMaxHealth(new_max_health)
diff --git a/code/modules/antagonists/highlander/highlander.dm b/code/modules/antagonists/highlander/highlander.dm
index 92a81d0775f..79d33039512 100644
--- a/code/modules/antagonists/highlander/highlander.dm
+++ b/code/modules/antagonists/highlander/highlander.dm
@@ -56,7 +56,7 @@
if(!H.dropItemToGround(I))
qdel(I)
H.regenerate_icons()
- H.revive(full_heal = TRUE, admin_revive = TRUE)
+ H.revive(ADMIN_HEAL_ALL)
H.equip_to_slot_or_del(new /obj/item/clothing/under/costume/kilt/highlander(H), ITEM_SLOT_ICLOTHING)
H.equip_to_slot_or_del(new /obj/item/radio/headset/syndicate(H), ITEM_SLOT_EARS)
H.equip_to_slot_or_del(new /obj/item/clothing/head/beret/highlander(H), ITEM_SLOT_HEAD)
@@ -95,7 +95,7 @@
var/mob/living/silicon/robot/robotlander = owner.current
if(!istype(robotlander))
return ..()
- robotlander.revive(full_heal = TRUE, admin_revive = TRUE)
+ robotlander.revive(ADMIN_HEAL_ALL)
robotlander.set_connected_ai() //DISCONNECT FROM AI
robotlander.laws.clear_inherent_laws()
robotlander.laws.set_zeroth_law("THERE CAN BE ONLY ONE")
diff --git a/code/modules/antagonists/nightmare/nightmare_organs.dm b/code/modules/antagonists/nightmare/nightmare_organs.dm
index 3f88c386a3b..a2b6a9d5679 100644
--- a/code/modules/antagonists/nightmare/nightmare_organs.dm
+++ b/code/modules/antagonists/nightmare/nightmare_organs.dm
@@ -84,7 +84,7 @@
if(respawn_progress < HEART_RESPAWN_THRESHHOLD)
return
- owner.revive(full_heal = TRUE, admin_revive = FALSE)
+ owner.revive(HEAL_ALL)
if(!(owner.dna.species.id == SPECIES_SHADOW || owner.dna.species.id == SPECIES_NIGHTMARE))
var/mob/living/carbon/old_owner = owner
Remove(owner, HEART_SPECIAL_SHADOWIFY)
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index 1b8f6b896b9..861b3102126 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -250,7 +250,7 @@
return
M.set_species(/datum/species/skeleton, icon_update=0)
- M.revive(full_heal = TRUE, admin_revive = TRUE)
+ M.revive(ADMIN_HEAL_ALL)
spooky_scaries |= M
to_chat(M, "[span_userdanger("You have been revived by ")][user.real_name]!")
to_chat(M, span_userdanger("[user.p_theyre(TRUE)] your master now, assist [user.p_them()] even if it costs you your new life!"))
diff --git a/code/modules/mining/equipment/lazarus_injector.dm b/code/modules/mining/equipment/lazarus_injector.dm
index 02003f97f2b..bda5871c349 100644
--- a/code/modules/mining/equipment/lazarus_injector.dm
+++ b/code/modules/mining/equipment/lazarus_injector.dm
@@ -42,7 +42,7 @@
return
target_animal.faction = list("neutral")
- target_animal.revive(full_heal = TRUE, admin_revive = TRUE)
+ target_animal.revive(HEAL_ALL)
if(ishostile(target))
var/mob/living/simple_animal/hostile/target_hostile = target_animal
if(malfunctioning)
diff --git a/code/modules/mining/equipment/monster_organs/regenerative_core.dm b/code/modules/mining/equipment/monster_organs/regenerative_core.dm
index 1930337cd2c..94ceca1ce66 100644
--- a/code/modules/mining/equipment/monster_organs/regenerative_core.dm
+++ b/code/modules/mining/equipment/monster_organs/regenerative_core.dm
@@ -31,7 +31,7 @@
trigger_organ_action()
/obj/item/organ/internal/monster_core/regenerative_core/on_triggered_internal()
- owner.revive(full_heal = TRUE, admin_revive = FALSE)
+ owner.revive(HEAL_ALL)
qdel(src)
/// Log applications and apply moodlet.
diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm
index b2df748810e..22e808aa6f2 100644
--- a/code/modules/mob/living/basic/vermin/mouse.dm
+++ b/code/modules/mob/living/basic/vermin/mouse.dm
@@ -80,12 +80,13 @@
adjust_health(-maxHealth)
// On revival, re-add the mouse to the ratcap, or block it if we're at it
-/mob/living/basic/mouse/revive(full_heal = FALSE, admin_revive = FALSE)
+/mob/living/basic/mouse/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
if(!contributes_to_ratcap)
return ..()
+ var/aheal_included = full_heal_flags & HEAL_ADMIN
var/cap = CONFIG_GET(number/ratcap)
- if(!admin_revive && !ckey && length(SSmobs.cheeserats) >= cap)
+ if(!aheal_included && !ckey && length(SSmobs.cheeserats) >= cap)
visible_message(span_warning("[src] twitches, but does not continue moving \
due to the overwhelming rodent population on the station!"))
return
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 6e3cd77db25..7562e9beaf3 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -845,6 +845,18 @@
update_worn_handcuffs()
update_hud_handcuffed()
+/mob/living/carbon/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
+ if(excess_healing)
+ if(dna && !(NOBLOOD in dna.species.species_traits))
+ blood_volume += (excess_healing * 2) //1 excess = 10 blood
+
+ for(var/obj/item/organ/organ as anything in internal_organs)
+ if(organ.organ_flags & ORGAN_SYNTHETIC)
+ continue
+ organ.applyOrganDamage(excess_healing * -1) //1 excess = 5 organ damage healed
+
+ return ..()
+
/mob/living/carbon/heal_and_revive(heal_to = 75, revive_message)
// We can't heal them if they're missing a heart
if(needs_heart() && !getorganslot(ORGAN_SLOT_HEART))
@@ -860,36 +872,46 @@
return ..()
-/mob/living/carbon/fully_heal(admin_revive = FALSE)
- if(reagents)
- reagents.clear_reagents()
- if(mind)
- for(var/addiction_type in subtypesof(/datum/addiction))
- mind.remove_addiction_points(addiction_type, MAX_ADDICTION_POINTS) //Remove the addiction!
- for(var/obj/item/organ/organ as anything in internal_organs)
- organ.setOrganDamage(0)
- for(var/thing in diseases)
- var/datum/disease/D = thing
- if(D.severity != DISEASE_SEVERITY_POSITIVE)
- D.cure(FALSE)
- for(var/thing in all_wounds)
- var/datum/wound/W = thing
- W.remove_wound()
- if(admin_revive)
- suiciding = FALSE
+/mob/living/carbon/fully_heal(heal_flags = HEAL_ALL)
+
+ // Should be handled via signal on embedded, or via heal on bodypart
+ // Otherwise I don't care to give it a separate flag
+ remove_all_embedded_objects()
+
+ if(heal_flags & HEAL_NEGATIVE_DISEASES)
+ for(var/datum/disease/disease as anything in diseases)
+ if(disease.severity != DISEASE_SEVERITY_POSITIVE)
+ disease.cure(FALSE)
+
+ if(heal_flags & HEAL_WOUNDS)
+ for(var/datum/wound/wound as anything in all_wounds)
+ wound.remove_wound()
+
+ if(heal_flags & HEAL_LIMBS)
regenerate_limbs()
+
+ if(heal_flags & HEAL_ORGANS)
regenerate_organs()
+
+ if(heal_flags & HEAL_TRAUMAS)
+ cure_all_traumas(TRAUMA_RESILIENCE_MAGIC)
+ // Addictions are like traumas
+ if(mind)
+ for(var/addiction_type in subtypesof(/datum/addiction))
+ mind.remove_addiction_points(addiction_type, MAX_ADDICTION_POINTS) //Remove the addiction!
+
+ if(heal_flags & HEAL_RESTRAINTS)
QDEL_NULL(handcuffed)
QDEL_NULL(legcuffed)
set_handcuffed(null)
update_handcuffed()
- cure_all_traumas(TRAUMA_RESILIENCE_MAGIC)
- ..()
+
+ return ..()
/mob/living/carbon/can_be_revived()
- . = ..()
if(!getorgan(/obj/item/organ/internal/brain) && (!mind || !mind.has_antag_datum(/datum/antagonist/changeling)) || HAS_TRAIT(src, TRAIT_HUSK))
return FALSE
+ return ..()
/mob/living/carbon/proc/can_defib()
diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm
index 1dcb1252e70..4ff77a51956 100644
--- a/code/modules/mob/living/carbon/damage_procs.dm
+++ b/code/modules/mob/living/carbon/damage_procs.dm
@@ -70,6 +70,13 @@
heal_overall_damage(abs(amount), 0, 0, required_status ? required_status : BODYTYPE_ORGANIC, updating_health)
return amount
+/mob/living/carbon/setBruteLoss(amount, updating_health = TRUE, forced = FALSE)
+ var/current = getBruteLoss()
+ var/diff = amount - current
+ if(!diff)
+ return
+ adjustBruteLoss(diff, updating_health, forced)
+
/mob/living/carbon/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_status)
if(!forced && (status_flags & GODMODE))
return FALSE
@@ -79,6 +86,13 @@
heal_overall_damage(0, abs(amount), 0, required_status ? required_status : BODYTYPE_ORGANIC, updating_health)
return amount
+/mob/living/carbon/setFireLoss(amount, updating_health = TRUE, forced = FALSE)
+ var/current = getFireLoss()
+ var/diff = amount - current
+ if(!diff)
+ return
+ adjustFireLoss(diff, updating_health, forced)
+
/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE)
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
amount = -amount
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 6dd14b857b3..29b0a6e6f37 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -754,18 +754,16 @@
for(var/t in get_disabled_limbs()) //Disabled limbs
hud_used.healthdoll.add_overlay(mutable_appearance('icons/hud/screen_gen.dmi', "[t]7"))
-/mob/living/carbon/human/fully_heal(admin_revive = FALSE)
- dna?.species.spec_fully_heal(src)
- if(admin_revive)
- regenerate_limbs()
- regenerate_organs()
- remove_all_embedded_objects()
- set_heartattack(FALSE)
- for(var/datum/mutation/human/HM in dna.mutations)
- if(HM.quality != POSITIVE)
- dna.remove_mutation(HM.name)
- set_coretemperature(get_body_temp_normal(apply_change=FALSE))
- heat_exposure_stacks = 0
+/mob/living/carbon/human/fully_heal(heal_flags = HEAL_ALL)
+ if(heal_flags & HEAL_NEGATIVE_MUTATIONS)
+ for(var/datum/mutation/human/existing_mutation in dna.mutations)
+ if(existing_mutation.quality != POSITIVE)
+ dna.remove_mutation(existing_mutation.name)
+
+ if(heal_flags & HEAL_TEMP)
+ set_coretemperature(get_body_temp_normal(apply_change = FALSE))
+ heat_exposure_stacks = 0
+
return ..()
/mob/living/carbon/human/is_nearsighted()
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 3ba7ee7be75..b488fed1091 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1066,9 +1066,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
/datum/species/proc/spec_updatehealth(mob/living/carbon/human/H)
return
-/datum/species/proc/spec_fully_heal(mob/living/carbon/human/H)
- return
-
/datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(SEND_SIGNAL(target, COMSIG_CARBON_PRE_HELP, user, attacker_style) & COMPONENT_BLOCK_HELP_ACT)
return TRUE
diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
index 1f77defbc89..78a52729872 100644
--- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm
+++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
@@ -211,7 +211,7 @@
owner = new_owner
START_PROCESSING(SSobj, src)
RegisterSignal(owner, COMSIG_CLICK_SHIFT, PROC_REF(examinate_check))
- RegisterSignal(owner, COMSIG_LIVING_REGENERATE_LIMBS, PROC_REF(unlist_head))
+ RegisterSignal(owner, COMSIG_CARBON_REGENERATE_LIMBS, PROC_REF(unlist_head))
RegisterSignal(owner, COMSIG_LIVING_REVIVE, PROC_REF(retrieve_head))
become_hearing_sensitive(ROUNDSTART_TRAIT)
@@ -247,13 +247,15 @@
excluded_zones |= BODY_ZONE_HEAD
///Retrieving the owner's head for better ahealing.
-/obj/item/dullahan_relay/proc/retrieve_head(datum/source, full_heal, admin_revive)
+/obj/item/dullahan_relay/proc/retrieve_head(datum/source, full_heal_flags)
SIGNAL_HANDLER
- if(admin_revive)
- var/obj/item/bodypart/head/head = loc
- var/turf/body_turf = get_turf(owner)
- if(head && istype(head) && body_turf && !(head in owner.get_all_contents()))
- head.forceMove(body_turf)
+ if(!(full_heal_flags & HEAL_ADMIN))
+ return
+
+ var/obj/item/bodypart/head/head = loc
+ var/turf/body_turf = get_turf(owner)
+ if(head && istype(head) && body_turf && !(head in owner.get_all_contents()))
+ head.forceMove(body_turf)
/obj/item/dullahan_relay/Destroy()
if(!QDELETED(owner))
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 9e410ee9a93..9f62cdfd23b 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -880,7 +880,7 @@
icon_state = "pile_bandages"
resistance_flags = FLAMMABLE
- var/revive_time = 900
+ var/revive_time = 90 SECONDS
var/mob/living/carbon/human/cloth_golem
/obj/structure/cloth_pile/Initialize(mapload, mob/living/carbon/human/H)
@@ -904,7 +904,7 @@
new /obj/effect/decal/cleanable/ash(get_turf(src))
..()
-/obj/structure/cloth_pile/proc/revive(full_heal = FALSE, admin_revive = FALSE)
+/obj/structure/cloth_pile/proc/revive()
if(QDELETED(src) || QDELETED(cloth_golem)) //QDELETED also checks for null, so if no cloth golem is set this won't runtime
return
if(cloth_golem.suiciding)
@@ -913,8 +913,7 @@
invisibility = INVISIBILITY_MAXIMUM //disappear before the animation
new /obj/effect/temp_visual/mummy_animation(get_turf(src))
- if(cloth_golem.revive(full_heal = TRUE, admin_revive = TRUE))
- cloth_golem.grab_ghost() //won't pull if it's a suicide
+ cloth_golem.revive(ADMIN_HEAL_ALL)
sleep(2 SECONDS)
cloth_golem.forceMove(get_turf(src))
cloth_golem.visible_message(span_danger("[src] rises and reforms into [cloth_golem]!"),span_userdanger("You reform into yourself!"))
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index ac2b116cc89..9d0247fbd73 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -173,6 +173,14 @@
updatehealth()
return amount
+/mob/living/proc/setBruteLoss(amount, updating_health = TRUE, forced = FALSE)
+ if(!forced && (status_flags & GODMODE))
+ return
+ . = bruteloss
+ bruteloss = amount
+ if(updating_health)
+ updatehealth()
+
/mob/living/proc/getOxyLoss()
return oxyloss
@@ -186,7 +194,7 @@
/mob/living/proc/setOxyLoss(amount, updating_health = TRUE, forced = FALSE)
- if(!forced && status_flags & GODMODE)
+ if(!forced && (status_flags & GODMODE))
return
. = oxyloss
oxyloss = amount
@@ -224,6 +232,14 @@
updatehealth()
return amount
+/mob/living/proc/setFireLoss(amount, updating_health = TRUE, forced = FALSE)
+ if(!forced && (status_flags & GODMODE))
+ return
+ . = fireloss
+ fireloss = amount
+ if(updating_health)
+ updatehealth()
+
/mob/living/proc/getCloneLoss()
return cloneloss
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index fe9331ff8ca..753e4b8dfa9 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -727,30 +727,32 @@
else
clear_fullscreen("brute")
-//Proc used to resuscitate a mob, for full_heal see fully_heal()
-/mob/living/proc/revive(full_heal = FALSE, admin_revive = FALSE, excess_healing = 0)
+/**
+ * Proc used to resuscitate a mob, bringing them back to life.
+ *
+ * Note that, even if a mob cannot be revived, the healing from this proc will still be applied.
+ *
+ * Arguments
+ * * full_heal_flags - Optional. If supplied, [/mob/living/fully_heal] will be called with these flags before revival.
+ * * excess_healing - Optional. If supplied, this number will be used to apply a bit of healing to the mob. Currently, 1 "excess healing" translates to -1 oxyloss, -1 toxloss, +2 blood, -5 to all organ damage.
+ * * force_grab_ghost - We grab the ghost of the mob on revive. If TRUE, we force grab the ghost (includes suiciders). If FALSE, we do not. See [/mob/grab_ghost].
+ *
+ */
+/mob/living/proc/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
if(excess_healing)
- if(iscarbon(src) && excess_healing)
- var/mob/living/carbon/C = src
- if(!(C.dna?.species && (NOBLOOD in C.dna.species.species_traits)))
- C.blood_volume += (excess_healing*2)//1 excess = 10 blood
-
- for(var/obj/item/organ/organ as anything in C.internal_organs)
- if(organ.organ_flags & ORGAN_SYNTHETIC)
- continue
- organ.applyOrganDamage(excess_healing * -1)//1 excess = 5 organ damage healed
-
- adjustOxyLoss(-20, TRUE)
- adjustToxLoss(-20, TRUE, TRUE) //slime friendly
+ adjustOxyLoss(-excess_healing, FALSE)
+ adjustToxLoss(-excess_healing, FALSE, TRUE) //slime friendly
updatehealth()
- grab_ghost()
- if(full_heal)
- fully_heal(admin_revive = admin_revive)
+
+ grab_ghost(force_grab_ghost)
+ if(full_heal_flags)
+ fully_heal(full_heal_flags)
+
if(stat == DEAD && can_be_revived()) //in some cases you can't revive (e.g. no brain)
set_suicide(FALSE)
set_stat(UNCONSCIOUS) //the mob starts unconscious,
updatehealth() //then we check if the mob should wake up.
- if(admin_revive)
+ if(full_heal_flags & HEAL_ADMIN)
get_up(TRUE)
update_sight()
clear_alert(ALERT_NOT_ENOUGH_OXYGEN)
@@ -759,15 +761,16 @@
if(excess_healing)
INVOKE_ASYNC(src, PROC_REF(emote), "gasp")
log_combat(src, src, "revived")
- else if(admin_revive)
+
+ else if(full_heal_flags & HEAL_ADMIN)
updatehealth()
get_up(TRUE)
+
// The signal is called after everything else so components can properly check the updated values
- SEND_SIGNAL(src, COMSIG_LIVING_REVIVE, full_heal, admin_revive)
+ SEND_SIGNAL(src, COMSIG_LIVING_REVIVE, full_heal_flags)
-
-/*
- * Heals up the [target] to up to [heal_to] of the main damage types.
+/**
+ * Heals up the mob up to [heal_to] of the main damage types.
* EX: If heal_to is 50, and they have 150 brute damage, they will heal 100 brute (up to 50 brute damage)
*
* If the target is dead, also revives them and heals their organs / restores blood.
@@ -810,48 +813,65 @@
return stat != DEAD
-/mob/living/proc/remove_CC()
- SetStun(0)
- SetKnockdown(0)
- SetImmobilized(0)
- SetParalyzed(0)
- SetSleeping(0)
- setStaminaLoss(0)
- SetUnconscious(0)
+/**
+ * A grand proc used whenever this mob is, quote, "fully healed".
+ * Fully healed could mean a number of things, such as "healing all the main damage types", "healing all the organs", etc
+ * So, you can pass flags to specify
+ *
+ * See [mobs.dm] for more information on the flags
+ *
+ * If you ever think "hey I'm adding something and want it to be reverted on full heal",
+ * consider handling it via signal instead of implementing it in this proc
+ */
+/mob/living/proc/fully_heal(heal_flags = HEAL_ALL)
+ SHOULD_CALL_PARENT(TRUE)
+ if(heal_flags & HEAL_TOX)
+ setToxLoss(0, FALSE, TRUE)
+ if(heal_flags & HEAL_OXY)
+ setToxLoss(0, FALSE, TRUE)
+ if(heal_flags & HEAL_CLONE)
+ setCloneLoss(0, FALSE, TRUE)
+ if(heal_flags & HEAL_BRUTE)
+ setBruteLoss(0, FALSE, TRUE)
+ if(heal_flags & HEAL_BURN)
+ setFireLoss(0, FALSE, TRUE)
+ if(heal_flags & HEAL_STAM)
+ setStaminaLoss(0, FALSE, TRUE)
-
-
-
-//proc used to completely heal a mob.
-//admin_revive = TRUE is used in other procs, for example mob/living/carbon/fully_heal()
-/mob/living/proc/fully_heal(admin_revive = FALSE)
- restore_blood()
- setToxLoss(0, 0) //zero as second argument not automatically call updatehealth().
- setOxyLoss(0, 0)
- setCloneLoss(0, 0)
- remove_CC()
- set_disgust(0)
- losebreath = 0
+ // I don't really care to keep this under a flag
set_nutrition(NUTRITION_LEVEL_FED + 50)
- bodytemperature = get_body_temp_normal(apply_change=FALSE)
+
+ // These should be tracked by status effects
+ losebreath = 0
set_blindness(0)
set_blurriness(0)
+ set_drowsyness(0)
+ set_disgust(0)
cure_nearsighted()
cure_blind()
cure_husk()
- heal_overall_damage(INFINITY, INFINITY, INFINITY, null, TRUE) //heal brute and burn dmg on both organic and robotic limbs, and update health right away.
- extinguish_mob()
- set_drowsyness(0)
+
+ if(heal_flags & HEAL_TEMP)
+ bodytemperature = get_body_temp_normal(apply_change = FALSE)
+ if(heal_flags & HEAL_BLOOD)
+ restore_blood()
+ if(reagents && (heal_flags & HEAL_ALL_REAGENTS))
+ reagents.clear_reagents()
+
+ if(heal_flags & HEAL_ADMIN)
+ suiciding = FALSE
+
+ updatehealth()
stop_sound_channel(CHANNEL_HEARTBEAT)
- SEND_SIGNAL(src, COMSIG_LIVING_POST_FULLY_HEAL, admin_revive)
+ SEND_SIGNAL(src, COMSIG_LIVING_POST_FULLY_HEAL, heal_flags)
-
-//proc called by revive(), to check if we can actually ressuscitate the mob (we don't want to revive him and have him instantly die again)
+/// Checks if we are actually able to ressuscitate this mob.
+/// (We don't want to revive then to have them instantly die again)
/mob/living/proc/can_be_revived()
- . = TRUE
if(health <= HEALTH_THRESHOLD_DEAD)
return FALSE
+ return TRUE
/mob/living/proc/update_damage_overlays()
return
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 18c4b1f0964..46251fd5f30 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -959,11 +959,13 @@
// I am so sorry
SEND_SIGNAL(src, COMSIG_MOB_RESET_PERSPECTIVE)
-/mob/living/silicon/ai/revive(full_heal = FALSE, admin_revive = FALSE)
+/mob/living/silicon/ai/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
. = ..()
- if(.) //successfully ressuscitated from death
- set_core_display_icon(display_icon_override)
- set_eyeobj_visible(TRUE)
+ if(!.) //successfully ressuscitated from death
+ return
+
+ set_core_display_icon(display_icon_override)
+ set_eyeobj_visible(TRUE)
/mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc)
malfhack = null
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index f1908ad2575..d7c0639893f 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -685,16 +685,18 @@
update_health_hud()
update_icons() //Updates eye_light overlay
-/mob/living/silicon/robot/revive(full_heal = FALSE, admin_revive = FALSE)
- if(..()) //successfully ressuscitated from death
- if(!QDELETED(builtInCamera) && !wires.is_cut(WIRE_CAMERA))
- builtInCamera.toggle_cam(src,0)
- if(admin_revive)
- locked = TRUE
- notify_ai(AI_NOTIFICATION_NEW_BORG)
- . = TRUE
- toggle_headlamp(FALSE, TRUE) //This will reenable borg headlamps if doomsday is currently going on still.
+/mob/living/silicon/robot/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
+ . = ..()
+ if(!.)
+ return
+ if(!QDELETED(builtInCamera) && !wires.is_cut(WIRE_CAMERA))
+ builtInCamera.toggle_cam(src, 0)
+ if(full_heal_flags & HEAL_ADMIN)
+ locked = TRUE
+ notify_ai(AI_NOTIFICATION_NEW_BORG)
+ toggle_headlamp(FALSE, TRUE) //This will reenable borg headlamps if doomsday is currently going on still.
+ return TRUE
/mob/living/silicon/robot/fully_replace_character_name(oldname, newname)
. = ..()
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index ebaa2231e0f..2f2536078d9 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -995,10 +995,12 @@ Pass a positive integer as an argument to override a bot's default speed.
. = ..()
bot_reset()
-/mob/living/simple_animal/bot/revive(full_heal = FALSE, admin_revive = FALSE)
- if(..())
- update_appearance()
- . = TRUE
+/mob/living/simple_animal/bot/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
+ . = ..()
+ if(!.)
+ return
+
+ update_appearance()
/mob/living/simple_animal/bot/ghost()
if(stat != DEAD) // Only ghost if we're doing this while alive, the pAI probably isn't dead yet.
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
index effd7faa3b0..fc710a583e6 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
@@ -83,7 +83,7 @@
return
user.visible_message(span_notice("[user] begins to reactivate [src]."), span_notice("You begin to reactivate [src]..."))
if(do_after(user, 30, 1, target = src))
- revive(full_heal = TRUE, admin_revive = FALSE)
+ revive(HEAL_ALL)
user.visible_message(span_notice("[user] reactivates [src]!"), span_notice("You reactivate [src]."))
alert_drones(DRONE_NET_CONNECT)
if(G)
diff --git a/code/modules/mob/living/simple_animal/friendly/pet.dm b/code/modules/mob/living/simple_animal/friendly/pet.dm
index c7127679f74..592d411786a 100644
--- a/code/modules/mob/living/simple_animal/friendly/pet.dm
+++ b/code/modules/mob/living/simple_animal/friendly/pet.dm
@@ -55,12 +55,14 @@
access_card = null
return ..()
-/mob/living/simple_animal/pet/revive(full_heal = FALSE, admin_revive = FALSE)
+/mob/living/simple_animal/pet/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
. = ..()
- if(.)
- if(collar_type)
- collar_type = "[initial(collar_type)]"
- regenerate_icons()
+ if(!.)
+ return
+
+ if(collar_type)
+ collar_type = "[initial(collar_type)]"
+ regenerate_icons()
/mob/living/simple_animal/pet/death(gibbed)
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm
index 31629374a2e..1fffeef1145 100644
--- a/code/modules/mob/living/simple_animal/hostile/carp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/carp.dm
@@ -85,13 +85,17 @@
else
make_tameable()
-/mob/living/simple_animal/hostile/carp/revive(full_heal, admin_revive)
- if (tamed)
- var/datum/weakref/friendref = ai_controller.blackboard[BB_HOSTILE_FRIEND]
- var/mob/living/friend = friendref?.resolve()
- if(friend)
- tamed(friend)
- return ..()
+/mob/living/simple_animal/hostile/carp/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
+ . = ..()
+ if(!. || !tamed)
+ return
+
+ var/datum/weakref/friendref = ai_controller.blackboard[BB_HOSTILE_FRIEND]
+ var/mob/living/friend = friendref?.resolve()
+ if(friend)
+ tamed(friend)
+
+ update_icon()
/mob/living/simple_animal/hostile/carp/death(gibbed)
if (tamed)
@@ -130,11 +134,6 @@
our_color = pick(carp_colors)
set_greyscale(colors=list(carp_colors[our_color]))
-/mob/living/simple_animal/hostile/carp/revive(full_heal = FALSE, admin_revive = FALSE)
- . = ..()
- if(.)
- update_icon()
-
/mob/living/simple_animal/hostile/carp/proc/chomp_plastic()
var/obj/item/storage/cans/tasty_plastic = locate(/obj/item/storage/cans) in view(1, src)
if(tasty_plastic && Adjacent(tasty_plastic))
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
index c8c665351c3..a32669f34fc 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
@@ -132,7 +132,7 @@
return
to_chat(src, span_warning("You begin repairs..."))
if(do_after(src, 50, target = fixable))
- fixable.revive(full_heal = TRUE, admin_revive = TRUE)
+ fixable.revive(HEAL_ALL)
do_sparks(3, TRUE, fixable)
to_chat(src, span_warning("Repairs complete."))
return
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index 17b9f37366d..9041188a44b 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -430,20 +430,23 @@
use_time = 3 SECONDS
/obj/machinery/anomalous_crystal/dark_reprise/ActivationReaction(mob/user, method)
- if(..())
- for(var/i in range(1, src))
- if(isturf(i))
- new /obj/effect/temp_visual/cult/sparks(i)
+ . = ..()
+ if(!.)
+ return
+ for(var/atom/thing as anything in range(1, src))
+ if(isturf(thing))
+ new /obj/effect/temp_visual/cult/sparks(thing)
+ continue
+
+ if(ishuman(thing))
+ var/mob/living/carbon/human/to_revive = thing
+ if(to_revive.stat != DEAD)
continue
- if(ishuman(i))
- var/mob/living/carbon/human/H = i
- if(H.stat == DEAD)
- H.set_species(/datum/species/shadow, 1)
- H.regenerate_limbs()
- H.regenerate_organs()
- H.revive(full_heal = TRUE, admin_revive = FALSE)
- ADD_TRAIT(H, TRAIT_BADDNA, MAGIC_TRAIT) //Free revives, but significantly limits your options for reviving except via the crystal
- H.grab_ghost(force = TRUE)
+ to_revive.set_species(/datum/species/shadow, TRUE)
+ to_revive.revive(ADMIN_HEAL_ALL, force_grab_ghost = TRUE)
+ //Free revives, but significantly limits your options for reviving except via the crystal
+ //except JK who cares about BADDNA anymore. this even heals suicides.
+ ADD_TRAIT(to_revive, TRAIT_BADDNA, MAGIC_TRAIT)
/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
observer_desc = "This crystal allows ghosts to turn into a fragile creature that can heal people."
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
index 6468778564f..f155414b006 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
@@ -257,7 +257,7 @@ Difficulty: Extremely Hard
clone.updateappearance(mutcolor_update=1)
var/turf/T = find_safe_turf()
user.forceMove(T)
- user.revive(full_heal = TRUE, admin_revive = TRUE)
+ user.revive(ADMIN_HEAL_ALL)
INVOKE_ASYNC(user, TYPE_PROC_REF(/mob/living/carbon, set_species), /datum/species/shadow)
to_chat(user, span_notice("You blink and find yourself in [get_area_name(T)]... feeling a bit darker."))
clone.dust()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
index 1230231f456..6b4ce7d22a3 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
@@ -105,7 +105,7 @@
QDEL_NULL(lava_swoop)
return ..()
-/mob/living/simple_animal/hostile/megafauna/dragon/revive(full_heal = FALSE, admin_revive = FALSE)
+/mob/living/simple_animal/hostile/megafauna/dragon/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
. = ..()
if(!.)
return
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm
index 48653cceed7..c7bcfaef68e 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm
@@ -212,7 +212,7 @@ While using this makes the system rely on OnFire, it still gives options for tim
mychild.forceMove(loc)
visible_message(span_boldwarning("[mychild] emerges from [src]!"))
playsound(loc,'sound/effects/phasein.ogg', 200, 0, 50, TRUE, TRUE)
- mychild.revive(full_heal = TRUE, admin_revive = TRUE)
+ mychild.revive(HEAL_ALL)
if(boosted)
mychild.maxHealth = mychild.maxHealth * 2
mychild.health = mychild.maxHealth
@@ -324,7 +324,7 @@ While using this makes the system rely on OnFire, it still gives options for tim
/obj/structure/elite_tumor/proc/onEliteWon()
activity = TUMOR_PASSIVE
clear_activator(activator)
- mychild.revive(full_heal = TRUE, admin_revive = TRUE)
+ mychild.revive(HEAL_ALL)
if(boosted)
times_won++
mychild.maxHealth = mychild.maxHealth * 0.4
@@ -360,7 +360,7 @@ While using this makes the system rely on OnFire, it still gives options for tim
user.visible_message(span_notice("It appears [E] is unable to be revived right now. Perhaps try again later."))
return
E.faction = list("[REF(user)]")
- E.revive(full_heal = TRUE, admin_revive = TRUE)
+ E.revive(HEAL_ALL)
user.visible_message(span_notice("[user] stabs [E] with [src], reviving it."))
E.playsound_local(get_turf(E), 'sound/effects/magic.ogg', 40, 0)
to_chat(E, "You have been revived by [user]. While you can't speak to them, you owe [user] a great debt. Assist [user.p_them()] in achieving [user.p_their()] goals, regardless of risk.")
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
index 7855f395cd2..3487d52bfbf 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
@@ -50,18 +50,20 @@
return
icon_state = pre_attack_icon
-/mob/living/simple_animal/hostile/asteroid/goliath/revive(full_heal = FALSE, admin_revive = FALSE)//who the fuck anchors mobs
- if(..())
- move_force = MOVE_FORCE_VERY_STRONG
- move_resist = MOVE_FORCE_VERY_STRONG
- pull_force = MOVE_FORCE_VERY_STRONG
- . = 1
+/mob/living/simple_animal/hostile/asteroid/goliath/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)//who the fuck anchors mobs
+ . = ..()
+ if(!.)
+ return
+
+ move_force = initial(move_force)
+ move_resist = initial(move_resist)
+ pull_force = initial(pull_force)
/mob/living/simple_animal/hostile/asteroid/goliath/death(gibbed)
move_force = MOVE_FORCE_DEFAULT
move_resist = MOVE_RESIST_DEFAULT
pull_force = PULL_FORCE_DEFAULT
- ..(gibbed)
+ return ..()
/mob/living/simple_animal/hostile/asteroid/goliath/OpenFire()
var/tturf = get_turf(target)
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm
index 6596780e325..ffa74eb530b 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm
@@ -58,7 +58,7 @@
pull_force = PULL_FORCE_DEFAULT
return ..()
-/mob/living/simple_animal/hostile/asteroid/polarbear/revive(full_heal = FALSE, admin_revive = FALSE)
+/mob/living/simple_animal/hostile/asteroid/polarbear/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
. = ..()
if(!.)
return
diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm
index 834e9c5f016..845556cf2bb 100644
--- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm
@@ -116,14 +116,16 @@
return TRUE
return ..()
-/mob/living/simple_animal/hostile/mushroom/revive(full_heal = FALSE, admin_revive = FALSE)
- if(..())
- icon_state = "mushroom_color"
- UpdateMushroomCap()
- . = 1
+/mob/living/simple_animal/hostile/mushroom/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
+ . = ..()
+ if(!.)
+ return
+
+ icon_state = "mushroom_color"
+ UpdateMushroomCap()
/mob/living/simple_animal/hostile/mushroom/death(gibbed)
- ..(gibbed)
+ . = ..()
UpdateMushroomCap()
/mob/living/simple_animal/hostile/mushroom/proc/UpdateMushroomCap()
@@ -138,7 +140,7 @@
/mob/living/simple_animal/hostile/mushroom/proc/Recover()
visible_message(span_notice("[src] slowly begins to recover."))
faint_ticker = 0
- revive(full_heal = TRUE, admin_revive = FALSE)
+ revive(HEAL_ALL)
UpdateMushroomCap()
recovery_cooldown = 1
addtimer(CALLBACK(src, PROC_REF(recovery_recharge)), 300)
diff --git a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm
index 4e4c96900c5..8971a45a01e 100644
--- a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm
@@ -173,7 +173,7 @@
add_dragon_overlay()
UnregisterSignal(small_sprite, COMSIG_ACTION_TRIGGER)
-/mob/living/simple_animal/hostile/space_dragon/revive(full_heal, admin_revive)
+/mob/living/simple_animal/hostile/space_dragon/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
. = ..()
add_dragon_overlay()
RegisterSignal(small_sprite, COMSIG_ACTION_TRIGGER, PROC_REF(add_dragon_overlay))
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 44943b8ae8a..a66e2bf9163 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -518,7 +518,7 @@
return
return ..()
-/mob/living/simple_animal/revive(full_heal = FALSE, admin_revive = FALSE)
+/mob/living/simple_animal/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
. = ..()
if(!.)
return
diff --git a/code/modules/mob/living/simple_animal/slime/death.dm b/code/modules/mob/living/simple_animal/slime/death.dm
index 5d5845c41d3..f957b9264a5 100644
--- a/code/modules/mob/living/simple_animal/slime/death.dm
+++ b/code/modules/mob/living/simple_animal/slime/death.dm
@@ -13,7 +13,7 @@
R.Remove(src)
var/datum/action/innate/slime/evolve/E = new
E.Grant(src)
- revive(full_heal = TRUE, admin_revive = FALSE)
+ revive(HEAL_ALL)
regenerate_icons()
update_name()
return
diff --git a/code/modules/modular_computers/file_system/programs/airestorer.dm b/code/modules/modular_computers/file_system/programs/airestorer.dm
index 276470f8f6e..5994da37fd6 100644
--- a/code/modules/modular_computers/file_system/programs/airestorer.dm
+++ b/code/modules/modular_computers/file_system/programs/airestorer.dm
@@ -50,8 +50,9 @@
// Please don't forget to update health, otherwise the below if statements will probably always fail.
A.updatehealth()
if(A.health >= 0 && A.stat == DEAD)
- A.revive(full_heal = FALSE, admin_revive = FALSE)
+ A.revive()
stored_card.update_appearance()
+
// Finished restoring
if(A.health >= 100)
restoring = FALSE
diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm
index 18174cbe69c..4ff00029409 100644
--- a/code/modules/projectiles/guns/magic/wand.dm
+++ b/code/modules/projectiles/guns/magic/wand.dm
@@ -80,7 +80,7 @@
if(isliving(user))
var/mob/living/L = user
if(L.mob_biotypes & MOB_UNDEAD) //negative energy heals the undead
- user.revive(full_heal = TRUE, admin_revive = TRUE)
+ user.revive(ADMIN_HEAL_ALL, force_grab_ghost = TRUE) // This heals suicides
to_chat(user, span_notice("You feel great!"))
return
to_chat(user, "You irradiate yourself with pure negative energy! \
@@ -125,7 +125,7 @@
user.investigate_log("has been killed by a bolt of resurrection.", INVESTIGATE_DEATHS)
user.death(FALSE)
return
- user.revive(full_heal = TRUE, admin_revive = TRUE)
+ user.revive(ADMIN_HEAL_ALL, force_grab_ghost = TRUE) // This heals suicides
to_chat(user, span_notice("You feel great!"))
/obj/item/gun/magic/wand/resurrection/debug //for testing
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index d02a1b77231..a2a5cfa5910 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -38,8 +38,8 @@
if(isliving(target))
var/mob/living/victim = target
if(victim.mob_biotypes & MOB_UNDEAD) //negative energy heals the undead
- if(victim.revive(full_heal = TRUE, admin_revive = TRUE))
- victim.grab_ghost(force = TRUE) // even suicides
+ if(victim.revive(ADMIN_HEAL_ALL, force_grab_ghost = TRUE)) // This heals suicides
+ victim.grab_ghost(force = TRUE)
to_chat(victim, span_notice("You rise with a start, you're undead!!!"))
else if(victim.stat != DEAD)
to_chat(victim, span_notice("You feel great!"))
@@ -72,8 +72,7 @@
victim.death()
return
- if(victim.revive(full_heal = TRUE, admin_revive = TRUE))
- victim.grab_ghost(force = TRUE) // even suicides
+ if(victim.revive(ADMIN_HEAL_ALL, force_grab_ghost = TRUE)) // This heals suicides
to_chat(victim, span_notice("You rise with a start, you're alive!!!"))
else if(victim.stat != DEAD)
to_chat(victim, span_notice("You feel great!"))
diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
index 8f1efd59462..2c31c98284b 100644
--- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
@@ -70,7 +70,7 @@
else //VICTORY ROYALE
to_chat(M, span_hierophant("You win, and the malevolent spirits fade away as well as your wounds."))
M.client.give_award(/datum/award/achievement/misc/helbitaljanken, M)
- M.revive(full_heal = TRUE, admin_revive = FALSE)
+ M.revive(HEAL_ALL)
holder.del_reagent(type)
return
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index ce121f0d909..6892d39e24f 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -42,6 +42,8 @@
color = "#E0BB00" //golden for the gods
taste_description = "badmins"
chemical_flags = REAGENT_DEAD_PROCESS
+ /// Flags to fullheal every metabolism tick
+ var/full_heal_flags = ~(HEAL_BRUTE|HEAL_BURN|HEAL_TOX|HEAL_RESTRAINTS)
// The best stuff there is. For testing/debugging.
/datum/reagent/medicine/adminordrazine/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user)
@@ -64,50 +66,17 @@
mytray.visible_message(span_warning("Nothing happens..."))
/datum/reagent/medicine/adminordrazine/on_mob_life(mob/living/carbon/M, delta_time, times_fired)
- M.heal_bodypart_damage(5 * REM * delta_time, 5 * REM * delta_time)
+ M.heal_bodypart_damage(5 * REM * delta_time, 5 * REM * delta_time, updating_health = FALSE)
M.adjustToxLoss(-5 * REM * delta_time, FALSE, TRUE)
- M.setOxyLoss(0, 0)
- M.setCloneLoss(0, 0)
-
- M.set_blurriness(0)
- M.set_blindness(0)
- M.SetKnockdown(0)
- M.SetStun(0)
- M.SetUnconscious(0)
- M.SetParalyzed(0)
- M.SetImmobilized(0)
- M.remove_status_effect(/datum/status_effect/confusion)
- M.SetSleeping(0)
-
- M.remove_status_effect(/datum/status_effect/silenced)
- M.remove_status_effect(/datum/status_effect/dizziness)
- M.disgust = 0
- M.drowsyness = 0
- // Remove all speech related status effects
- for(var/effect in typesof(/datum/status_effect/speech))
- M.remove_status_effect(effect)
- M.remove_status_effect(/datum/status_effect/jitter)
- M.remove_status_effect(/datum/status_effect/hallucination)
- REMOVE_TRAITS_NOT_IN(M, list(SPECIES_TRAIT, ROUNDSTART_TRAIT, ORGAN_TRAIT))
- M.reagents.remove_all_type(/datum/reagent/toxin, 5 * REM * delta_time, FALSE, TRUE)
- if(M.blood_volume < BLOOD_VOLUME_NORMAL)
- M.blood_volume = BLOOD_VOLUME_NORMAL
-
- M.cure_all_traumas(TRAUMA_RESILIENCE_MAGIC)
- for(var/obj/item/organ/organ as anything in M.internal_organs)
- organ.setOrganDamage(0)
- for(var/thing in M.diseases)
- var/datum/disease/D = thing
- if(D.severity == DISEASE_SEVERITY_POSITIVE)
- continue
- D.cure()
- ..()
- . = TRUE
+ // Heal everything! That we want to. But really don't heal reagents. Otherwise we'll lose ... us.
+ M.fully_heal(full_heal_flags & ~HEAL_ALL_REAGENTS)
+ return ..()
/datum/reagent/medicine/adminordrazine/quantum_heal
name = "Quantum Medicine"
description = "Rare and experimental particles, that apparently swap the user's body with one from an alternate dimension where it's completely healthy."
taste_description = "science"
+ full_heal_flags = ~(HEAL_ADMIN|HEAL_BRUTE|HEAL_BURN|HEAL_TOX|HEAL_RESTRAINTS|HEAL_ALL_REAGENTS)
/datum/reagent/medicine/synaptizine
name = "Synaptizine"
diff --git a/code/modules/research/xenobiology/crossbreeding/_potions.dm b/code/modules/research/xenobiology/crossbreeding/_potions.dm
index d3da93fbbd3..7dd780cca3b 100644
--- a/code/modules/research/xenobiology/crossbreeding/_potions.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_potions.dm
@@ -187,7 +187,7 @@ Slimecrossing Potions
return
if(revive_target.maxHealth <= 0)
to_chat(user, span_warning("The slime is too unstable to return!"))
- revive_target.revive(full_heal = TRUE, admin_revive = FALSE)
+ revive_target.revive(HEAL_ALL)
revive_target.set_stat(CONSCIOUS)
revive_target.visible_message(span_notice("[revive_target] is filled with renewed vigor and blinks awake!"))
revive_target.maxHealth -= 10 //Revival isn't healthy.
diff --git a/code/modules/research/xenobiology/crossbreeding/regenerative.dm b/code/modules/research/xenobiology/crossbreeding/regenerative.dm
index 5e36207a44b..3873fabb708 100644
--- a/code/modules/research/xenobiology/crossbreeding/regenerative.dm
+++ b/code/modules/research/xenobiology/crossbreeding/regenerative.dm
@@ -29,7 +29,7 @@ Regenerative extracts:
user.visible_message(span_notice("[user] crushes [src] over [user.p_them()]self, the milky goo quickly regenerating all of [user.p_their()] injuries!"),
span_notice("You squeeze [src], and it bursts in your hand, splashing you with milky goo which quickly regenerates your injuries!"))
core_effect_before(H, user)
- H.revive(full_heal = TRUE, admin_revive = FALSE)
+ H.revive(HEAL_ALL)
core_effect(H, user)
playsound(target, 'sound/effects/splat.ogg', 40, TRUE)
qdel(src)
@@ -262,7 +262,7 @@ Regenerative extracts:
if(target == user)
return
var/mob/living/U = user
- U.revive(full_heal = TRUE, admin_revive = FALSE)
+ U.revive(HEAL_ALL)
to_chat(U, span_notice("Some of the milky goo sprays onto you, as well!"))
/obj/item/slimecross/regenerative/adamantine
diff --git a/code/modules/spells/spell_types/jaunt/bloodcrawl.dm b/code/modules/spells/spell_types/jaunt/bloodcrawl.dm
index 84b6c11e9c5..bf9b0f2876f 100644
--- a/code/modules/spells/spell_types/jaunt/bloodcrawl.dm
+++ b/code/modules/spells/spell_types/jaunt/bloodcrawl.dm
@@ -218,7 +218,7 @@
if(SEND_SIGNAL(victim, COMSIG_LIVING_BLOOD_CRAWL_CONSUMED, src, jaunter) & COMPONENT_STOP_CONSUMPTION)
return FALSE
- jaunter.revive(full_heal = TRUE, admin_revive = FALSE)
+ jaunter.revive(HEAL_ALL)
// No defib possible after laughter
victim.apply_damage(1000, BRUTE, wound_bonus = CANT_WOUND)
@@ -290,9 +290,9 @@
UnregisterSignal(friend, list(COMSIG_MOB_STATCHANGE, COMSIG_PARENT_QDELETING))
friend.forceMove(release_turf)
- if(!friend.revive(full_heal = TRUE, admin_revive = TRUE))
+ // Heals them back to state one
+ if(!friend.revive(ADMIN_HEAL_ALL, force_grab_ghost = TRUE))
continue
- friend.grab_ghost(force = TRUE)
playsound(release_turf, consumed_mobs, 50, TRUE, -1)
to_chat(friend, span_clown("You leave [source]'s warm embrace, and feel ready to take on the world."))
diff --git a/code/modules/spells/spell_types/shapeshift/_shape_status.dm b/code/modules/spells/spell_types/shapeshift/_shape_status.dm
index f361c87f384..620a91bf58d 100644
--- a/code/modules/spells/spell_types/shapeshift/_shape_status.dm
+++ b/code/modules/spells/spell_types/shapeshift/_shape_status.dm
@@ -187,7 +187,7 @@
return
if(caster_mob.stat != DEAD)
- caster_mob.revive(full_heal = TRUE, admin_revive = FALSE)
+ caster_mob.revive(HEAL_DAMAGE)
var/damage_to_apply = caster_mob.maxHealth * ((owner.maxHealth - owner.health) / owner.maxHealth)
caster_mob.apply_damage(damage_to_apply, source_spell.convert_damage_type, forced = TRUE, wound_bonus = CANT_WOUND)
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index 23f1668a4ef..984043cee5c 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -465,22 +465,15 @@
carbon_owner.dna.species.bodytype = all_limb_flags
-//Regenerates all limbs. Returns amount of limbs regenerated
-/mob/living/proc/regenerate_limbs(list/excluded_zones = list())
- SEND_SIGNAL(src, COMSIG_LIVING_REGENERATE_LIMBS, excluded_zones)
-
-/mob/living/carbon/regenerate_limbs(list/excluded_zones = list())
- SEND_SIGNAL(src, COMSIG_LIVING_REGENERATE_LIMBS, excluded_zones)
+/mob/living/carbon/proc/regenerate_limbs(list/excluded_zones = list())
+ SEND_SIGNAL(src, COMSIG_CARBON_REGENERATE_LIMBS, excluded_zones)
var/list/zone_list = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)
if(length(excluded_zones))
zone_list -= excluded_zones
for(var/limb_zone in zone_list)
regenerate_limb(limb_zone)
-/mob/living/proc/regenerate_limb(limb_zone)
- return
-
-/mob/living/carbon/regenerate_limb(limb_zone)
+/mob/living/carbon/proc/regenerate_limb(limb_zone)
var/obj/item/bodypart/limb
if(get_bodypart(limb_zone))
return FALSE
diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm
index 39c368cac95..1363bb0ae3d 100644
--- a/code/modules/surgery/bodyparts/helpers.dm
+++ b/code/modules/surgery/bodyparts/helpers.dm
@@ -70,10 +70,7 @@
return TRUE
-/mob/living/proc/get_missing_limbs()
- return list()
-
-/mob/living/carbon/get_missing_limbs()
+/mob/living/carbon/proc/get_missing_limbs()
RETURN_TYPE(/list)
var/list/full = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)
for(var/zone in full)
diff --git a/code/modules/surgery/organs/_organ.dm b/code/modules/surgery/organs/_organ.dm
index 3ab324fec3b..410475d14c1 100644
--- a/code/modules/surgery/organs/_organ.dm
+++ b/code/modules/surgery/organs/_organ.dm
@@ -237,7 +237,9 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
lungs.setOrganDamage(0)
var/obj/item/organ/internal/heart/heart = getorganslot(ORGAN_SLOT_HEART)
- if(!heart)
+ if(heart)
+ set_heartattack(FALSE)
+ else
heart = new()
heart.Insert(src)
heart.setOrganDamage(0)
diff --git a/code/modules/surgery/organs/external/_external_organs.dm b/code/modules/surgery/organs/external/_external_organs.dm
index 61e17195c0d..60e38435491 100644
--- a/code/modules/surgery/organs/external/_external_organs.dm
+++ b/code/modules/surgery/organs/external/_external_organs.dm
@@ -360,10 +360,13 @@
set_sprite("Burnt Off")
///heal our antennae back up!!
-/obj/item/organ/external/antennae/proc/heal_antennae()
+/obj/item/organ/external/antennae/proc/heal_antennae(datum/source, heal_flags)
SIGNAL_HANDLER
- if(burnt)
+ if(!burnt)
+ return
+
+ if(heal_flags & (HEAL_LIMBS|HEAL_ORGANS))
burnt = FALSE
set_sprite(original_sprite)
@@ -397,4 +400,3 @@
/obj/item/organ/external/pod_hair/override_color(rgb_value)
var/list/rgb_list = rgb2num(rgb_value)
return rgb(255 - rgb_list[1], 255 - rgb_list[2], 255 - rgb_list[3])
-
diff --git a/code/modules/surgery/organs/external/wings.dm b/code/modules/surgery/organs/external/wings.dm
index c04951191ca..7addf6e6ff5 100644
--- a/code/modules/surgery/organs/external/wings.dm
+++ b/code/modules/surgery/organs/external/wings.dm
@@ -234,9 +234,12 @@
set_sprite("Burnt Off")
///heal our wings back up!!
-/obj/item/organ/external/wings/moth/proc/heal_wings()
+/obj/item/organ/external/wings/moth/proc/heal_wings(datum/source, heal_flags)
SIGNAL_HANDLER
- if(burnt)
+ if(!burnt)
+ return
+
+ if(heal_flags & (HEAL_LIMBS|HEAL_ORGANS))
burnt = FALSE
set_sprite(original_sprite)
diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm
index 728f51493c5..6a745e5fe0f 100644
--- a/code/modules/surgery/organs/heart.dm
+++ b/code/modules/surgery/organs/heart.dm
@@ -300,7 +300,7 @@
. += shine
-/obj/item/organ/internal/heart/ethereal/proc/on_owner_fully_heal(mob/living/carbon/healed, admin_heal)
+/obj/item/organ/internal/heart/ethereal/proc/on_owner_fully_heal(mob/living/carbon/healed, heal_flags)
SIGNAL_HANDLER
QDEL_NULL(current_crystal) //Kicks out the ethereal
@@ -485,7 +485,7 @@
. += shine
/obj/structure/ethereal_crystal/proc/heal_ethereal()
- ethereal_heart.owner.revive(TRUE, FALSE)
+ ethereal_heart.owner.revive(HEAL_ALL)
to_chat(ethereal_heart.owner, span_notice("You burst out of the crystal with vigour... But at a cost."))
var/datum/brain_trauma/picked_trauma
if(prob(10)) //10% chance for a severe trauma
diff --git a/code/modules/surgery/revival.dm b/code/modules/surgery/revival.dm
index 4dc371d71ac..c2bfafb8965 100644
--- a/code/modules/surgery/revival.dm
+++ b/code/modules/surgery/revival.dm
@@ -79,7 +79,7 @@
target.grab_ghost()
target.adjustOxyLoss(-50, 0)
target.updatehealth()
- if(target.revive(full_heal = FALSE, admin_revive = FALSE))
+ if(target.revive())
target.visible_message(span_notice("...[target] wakes up, alive and aware!"))
target.emote("gasp")
target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 50, 199) //MAD SCIENCE
diff --git a/code/modules/unit_tests/medical_wounds.dm b/code/modules/unit_tests/medical_wounds.dm
index 8b3400c1ec9..b21deddee6f 100644
--- a/code/modules/unit_tests/medical_wounds.dm
+++ b/code/modules/unit_tests/medical_wounds.dm
@@ -34,7 +34,7 @@
TEST_ASSERT_EQUAL(actual_wound.type, iter_test_wound, "Patient has wound of incorrect severity. Expected: [initial(iter_test_wound.name)] Got: [actual_wound]")
threshold_penalty = actual_wound.threshold_penalty
i++
- victim.fully_heal(TRUE) // should clear all wounds between types
+ victim.fully_heal(ADMIN_HEAL_ALL) // should clear all wounds between types
/// This test is used for making sure species with bones but no flesh (skeletons, plasmamen) can only suffer BONE_WOUNDS, and nothing tagged with FLESH_WOUND (it's possible to require both)
@@ -84,4 +84,4 @@
TEST_ASSERT_EQUAL(actual_wound.type, iter_test_wound, "Patient has wound of incorrect severity. Expected: [initial(iter_test_wound.name)] Got: [actual_wound]")
threshold_penalty = actual_wound.threshold_penalty
i++
- victim.fully_heal(TRUE) // should clear all wounds between types
+ victim.fully_heal(ADMIN_HEAL_ALL) // should clear all wounds between types
diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm
index fe15a073024..3c9f5c59c9f 100644
--- a/code/modules/zombie/organs.dm
+++ b/code/modules/zombie/organs.dm
@@ -80,19 +80,14 @@
var/stand_up = (target.stat == DEAD) || (target.stat == UNCONSCIOUS)
//Fully heal the zombie's damage the first time they rise
- target.setToxLoss(0, 0)
- target.setOxyLoss(0, 0)
- target.heal_overall_damage(INFINITY, INFINITY, INFINITY, null, TRUE)
-
- if(!target.revive())
+ if(!target.heal_and_revive(0, span_danger("[target] suddenly convulses, as [target.p_they()][stand_up ? " stagger to [target.p_their()] feet and" : ""] gain a ravenous hunger in [target.p_their()] eyes!")))
return
- target.grab_ghost()
- target.visible_message(span_danger("[owner] suddenly convulses, as [owner.p_they()][stand_up ? " stagger to [owner.p_their()] feet and" : ""] gain a ravenous hunger in [owner.p_their()] eyes!"), span_alien("You HUNGER!"))
- playsound(target.loc, 'sound/hallucinations/far_noise.ogg', 50, 1)
+ to_chat(target, span_alien("You HUNGER!"))
+ to_chat(target, span_alertalien("You are now a zombie! Do not seek to be cured, do not help any non-zombies in any way, do not harm your zombie brethren and spread the disease by killing others. You are a creature of hunger and violence."))
+ playsound(target, 'sound/hallucinations/far_noise.ogg', 50, 1)
target.do_jitter_animation(living_transformation_time)
target.Stun(living_transformation_time)
- to_chat(target, span_alertalien("You are now a zombie! Do not seek to be cured, do not help any non-zombies in any way, do not harm your zombie brethren and spread the disease by killing others. You are a creature of hunger and violence."))
/obj/item/organ/internal/zombie_infection/nodamage
causes_damage = FALSE