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