diff --git a/code/datums/components/fantasy/prefixes.dm b/code/datums/components/fantasy/prefixes.dm index a2e9d91a6a0..301b208f100 100644 --- a/code/datums/components/fantasy/prefixes.dm +++ b/code/datums/components/fantasy/prefixes.dm @@ -71,9 +71,13 @@ /datum/fantasy_affix/vampiric/apply(datum/component/fantasy/comp, newName) var/obj/item/master = comp.parent - comp.appliedComponents += master.AddComponent(/datum/component/lifesteal, comp.quality) + master.AddElement(/datum/element/lifesteal, comp.quality) return "vampiric [newName]" +/datum/fantasy_affix/vampiric/remove(datum/component/fantasy/comp) + var/obj/item/master = comp.parent + master.RemoveElement(/datum/element/lifesteal, comp.quality) + /datum/fantasy_affix/beautiful name = "beautiful" placement = AFFIX_PREFIX diff --git a/code/datums/components/lifesteal.dm b/code/datums/components/lifesteal.dm deleted file mode 100644 index ef33e63960e..00000000000 --- a/code/datums/components/lifesteal.dm +++ /dev/null @@ -1,46 +0,0 @@ -/datum/component/lifesteal - var/flat_heal // heals a constant amount every time a hit occurs - var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) - -/datum/component/lifesteal/Initialize(flat_heal=0) - if(!isitem(parent) && !ishostile(parent) && !isgun(parent)) - return COMPONENT_INCOMPATIBLE - - src.flat_heal = flat_heal - -/datum/component/lifesteal/RegisterWithParent() - if(isgun(parent)) - RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) - else if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) - else if(ishostile(parent)) - RegisterSignal(parent, COMSIG_HOSTILE_POST_ATTACKINGTARGET, .proc/hostile_attackingtarget) - -/datum/component/lifesteal/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_POST_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT)) - -/datum/component/lifesteal/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) - SIGNAL_HANDLER - - if(!proximity_flag) - return - do_lifesteal(user, target) - -/datum/component/lifesteal/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target, success) - SIGNAL_HANDLER - - if(!success) - return - do_lifesteal(attacker, target) - -/datum/component/lifesteal/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) - SIGNAL_HANDLER - - do_lifesteal(firer, target) - -/datum/component/lifesteal/proc/do_lifesteal(atom/heal_target, atom/damage_target) - if(isliving(heal_target) && isliving(damage_target)) - var/mob/living/healing = heal_target - var/mob/living/damaging = damage_target - if(damaging.stat != DEAD) - healing.heal_ordered_damage(flat_heal, damage_heal_order) diff --git a/code/datums/elements/lifesteal.dm b/code/datums/elements/lifesteal.dm new file mode 100644 index 00000000000..db3d008cd07 --- /dev/null +++ b/code/datums/elements/lifesteal.dm @@ -0,0 +1,53 @@ +/** + * Heals the user (if attached to an item) or the mob itself (if attached to a hostile simple mob) + * by a flat amount whenever a successful attack is performed against another living mob. + */ +/datum/element/lifesteal + element_flags = ELEMENT_DETACH|ELEMENT_BESPOKE + id_arg_index = 2 + /// heals a constant amount every time a hit occurs + var/flat_heal + var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) + +/datum/element/lifesteal/Attach(datum/target, flat_heal) + . = ..() + if(isgun(target)) + RegisterSignal(target, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) + else if(isitem(target)) + RegisterSignal(target, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) + else if(ishostile(target)) + RegisterSignal(target, COMSIG_HOSTILE_POST_ATTACKINGTARGET, .proc/hostile_attackingtarget) + else + return ELEMENT_INCOMPATIBLE + + src.flat_heal = flat_heal + +/datum/element/lifesteal/Detach(datum/source) + UnregisterSignal(source, list(COMSIG_PROJECTILE_ON_HIT, COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_POST_ATTACKINGTARGET)) + return ..() + +/datum/element/lifesteal/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) + SIGNAL_HANDLER + + if(!proximity_flag) + return + do_lifesteal(user, target) + +/datum/element/lifesteal/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target, success) + SIGNAL_HANDLER + + if(!success) + return + do_lifesteal(attacker, target) + +/datum/element/lifesteal/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) + SIGNAL_HANDLER + + do_lifesteal(firer, target) + +/datum/element/lifesteal/proc/do_lifesteal(atom/heal_target, atom/damage_target) + if(isliving(heal_target) && isliving(damage_target)) + var/mob/living/healing = heal_target + var/mob/living/damaging = damage_target + if(damaging.stat != DEAD) + healing.heal_ordered_damage(flat_heal, damage_heal_order) 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 af26b42de55..cfab4b99c19 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 @@ -57,7 +57,7 @@ Difficulty: Extremely Hard for(var/obj/structure/frost_miner_prism/prism_to_set in GLOB.frost_miner_prisms) prism_to_set.set_prism_light(LIGHT_COLOR_BLUE, 5) AddComponent(/datum/component/knockback, 7, FALSE, TRUE) - AddComponent(/datum/component/lifesteal, 50) + AddElement(/datum/element/lifesteal, 50) /datum/action/innate/megafauna_attack/frost_orbs name = "Fire Frost Orbs" @@ -366,7 +366,7 @@ Difficulty: Extremely Hard /obj/item/pickaxe/drill/jackhammer/demonic/Initialize() . = ..() AddComponent(/datum/component/knockback, 4, TRUE, FALSE) - AddComponent(/datum/component/lifesteal, 5) + AddElement(/datum/element/lifesteal, 5) /obj/item/pickaxe/drill/jackhammer/demonic/use_tool(atom/target, mob/living/user, delay, amount=0, volume=0, datum/callback/extra_checks) var/turf/T = get_turf(target) diff --git a/tgstation.dme b/tgstation.dme index 794c7bc084a..a5fe22fd5ba 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -577,7 +577,6 @@ #include "code\datums\components\knockback.dm" #include "code\datums\components\knockoff.dm" #include "code\datums\components\label.dm" -#include "code\datums\components\lifesteal.dm" #include "code\datums\components\light_eater.dm" #include "code\datums\components\lockon_aiming.dm" #include "code\datums\components\manual_blinking.dm" @@ -762,6 +761,7 @@ #include "code\datums\elements\item_scaling.dm" #include "code\datums\elements\kneecapping.dm" #include "code\datums\elements\kneejerk.dm" +#include "code\datums\elements\lifesteal.dm" #include "code\datums\elements\light_blocking.dm" #include "code\datums\elements\light_eaten.dm" #include "code\datums\elements\light_eater.dm"