mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-18 21:53:22 +00:00
* Cult Vs. Heretic: 7 Months Later Edition * conflict fix --------- Co-authored-by: carlarctg <53100513+carlarctg@users.noreply.github.com> Co-authored-by: SpaceLoveSs13 <68121607+SpaceLoveSs13@users.noreply.github.com>
81 lines
3.0 KiB
Plaintext
81 lines
3.0 KiB
Plaintext
/// This component will intercept bare-handed attacks by the owner on sufficiently injured carbons and amputate random limbs instead
|
|
/datum/component/amputating_limbs
|
|
/// How long does it take?
|
|
var/surgery_time
|
|
/// What is the means by which we describe the act of amputation?
|
|
var/surgery_verb
|
|
/// How awake must our target be?
|
|
var/minimum_stat
|
|
/// How likely are we to perform this action?
|
|
var/snip_chance
|
|
/// The types of limb we can remove
|
|
var/list/target_zones
|
|
/// Callback for a proc right before confirming the attack. If it returns FALSE, cancel
|
|
var/datum/callback/pre_hit_callback
|
|
|
|
/datum/component/amputating_limbs/Initialize(
|
|
surgery_time = 5 SECONDS,
|
|
surgery_verb = "prying",
|
|
minimum_stat = SOFT_CRIT,
|
|
snip_chance = 100,
|
|
list/target_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_ARM, BODY_ZONE_R_LEG),
|
|
datum/callback/pre_hit_callback,
|
|
)
|
|
. = ..()
|
|
if (!isliving(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
if (!length(target_zones))
|
|
CRASH("[src] for [parent] was not provided a valid list of body zones to target.")
|
|
|
|
src.surgery_time = surgery_time
|
|
src.surgery_verb = surgery_verb
|
|
src.minimum_stat = minimum_stat
|
|
src.snip_chance = snip_chance
|
|
src.target_zones = target_zones
|
|
src.pre_hit_callback = pre_hit_callback
|
|
|
|
/datum/component/amputating_limbs/RegisterWithParent()
|
|
RegisterSignals(parent, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET), PROC_REF(try_amputate))
|
|
|
|
/datum/component/amputating_limbs/UnregisterFromParent()
|
|
UnregisterSignal(parent, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET))
|
|
|
|
/// Called when you click on literally anything with your hands, see if it is an injured carbon and then try to cut it up
|
|
/datum/component/amputating_limbs/proc/try_amputate(mob/living/surgeon, atom/victim, proximity, modifiers)
|
|
SIGNAL_HANDLER
|
|
if (!proximity || !iscarbon(victim) || HAS_TRAIT(victim, TRAIT_NODISMEMBER) || !prob(snip_chance))
|
|
return
|
|
|
|
var/mob/living/carbon/limbed_victim = victim
|
|
if (limbed_victim.stat < minimum_stat)
|
|
return
|
|
|
|
if (DOING_INTERACTION_WITH_TARGET(surgeon, victim))
|
|
surgeon.balloon_alert(surgeon, "already busy!")
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
if(pre_hit_callback && !pre_hit_callback.Invoke(victim))
|
|
return
|
|
|
|
var/list/valid_targets = list()
|
|
for (var/obj/item/bodypart/possible_target as anything in limbed_victim.bodyparts)
|
|
if (possible_target.bodypart_flags & BODYPART_UNREMOVABLE)
|
|
continue
|
|
if (!(possible_target.body_zone in target_zones))
|
|
continue
|
|
valid_targets += possible_target
|
|
|
|
if (!length(valid_targets))
|
|
return
|
|
|
|
INVOKE_ASYNC(src, PROC_REF(amputate), surgeon, victim, pick(valid_targets))
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
/// Chop one off
|
|
/datum/component/amputating_limbs/proc/amputate(mob/living/surgeon, mob/living/carbon/victim, obj/item/bodypart/to_remove)
|
|
if(surgery_time > 0 SECONDS)
|
|
surgeon.visible_message(span_warning("[surgeon] is [surgery_verb] the [to_remove] off of [victim]!"))
|
|
if (surgery_time > 0 && !do_after(surgeon, delay = surgery_time, target = victim))
|
|
return
|
|
to_remove.dismember()
|