From 1f0f65540f49b2db91cb1d165a9dd3b61fc0de97 Mon Sep 17 00:00:00 2001 From: Birdtalon Date: Sat, 25 Nov 2023 16:31:33 +0000 Subject: [PATCH] Moves Warrior Limb rip procs and adds check for host (#4979) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …HOST # About the pull request Fixes #4977 Refactors Warrior ripping procs to warrior class and adds a further check for XENO_HOST after do_after to account for delay between hugger jumping on and emplanting embryo. # Explain why it's good for the game Consistency with other anti host killing mechanics. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: fix: Warriors can no longer behead caps if they start limb ripping before embryo is inserted. code: Refactors warrior limb proc to the warrior class. /:cl: --- .../mob/living/carbon/xenomorph/XenoProcs.dm | 78 +----------------- .../living/carbon/xenomorph/castes/Warrior.dm | 79 +++++++++++++++++++ 2 files changed, 82 insertions(+), 75 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm index 0645d5fcba90..7b13e0010057 100644 --- a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm +++ b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm @@ -536,81 +536,9 @@ if(client) client.mouse_pointer_icon = initial(client.mouse_pointer_icon) // Reset our mouse pointer when we no longer have an action queued. -// Called when pulling something and attacking yourself with the pull -/mob/living/carbon/xenomorph/proc/pull_power(mob/M) - if(iswarrior(src) && !ripping_limb && M.stat != DEAD) - if(M.status_flags & XENO_HOST) - to_chat(src, SPAN_XENOWARNING("This would harm the embryo!")) - return - ripping_limb = TRUE - if(rip_limb(M)) - stop_pulling() - ripping_limb = FALSE - - -// Warrior Rip Limb - called by pull_power() -/mob/living/carbon/xenomorph/proc/rip_limb(mob/M) - if(!istype(M, /mob/living/carbon/human)) - return FALSE - - if(action_busy) //can't stack the attempts - return FALSE - - var/mob/living/carbon/human/H = M - var/obj/limb/L = H.get_limb(check_zone(zone_selected)) - - if(can_not_harm(H)) - to_chat(src, SPAN_XENOWARNING("You can't harm this host!")) - return - - if(!L || L.body_part == BODY_FLAG_CHEST || L.body_part == BODY_FLAG_GROIN || (L.status & LIMB_DESTROYED)) //Only limbs and head. - to_chat(src, SPAN_XENOWARNING("You can't rip off that limb.")) - return FALSE - var/limb_time = rand(40,60) - - if(L.body_part == BODY_FLAG_HEAD) - limb_time = rand(90,110) - - visible_message(SPAN_XENOWARNING("[src] begins pulling on [M]'s [L.display_name] with incredible strength!"), \ - SPAN_XENOWARNING("You begin to pull on [M]'s [L.display_name] with incredible strength!")) - - if(!do_after(src, limb_time, INTERRUPT_ALL|INTERRUPT_DIFF_SELECT_ZONE, BUSY_ICON_HOSTILE) || M.stat == DEAD) - to_chat(src, SPAN_NOTICE("You stop ripping off the limb.")) - return FALSE - - if(L.status & LIMB_DESTROYED) - return FALSE - - if(L.status & (LIMB_ROBOT|LIMB_SYNTHSKIN)) - L.take_damage(rand(30,40), 0, 0) // just do more damage - visible_message(SPAN_XENOWARNING("You hear [M]'s [L.display_name] being pulled beyond its load limits!"), \ - SPAN_XENOWARNING("[M]'s [L.display_name] begins to tear apart!")) - else - visible_message(SPAN_XENOWARNING("You hear the bones in [M]'s [L.display_name] snap with a sickening crunch!"), \ - SPAN_XENOWARNING("[M]'s [L.display_name] bones snap with a satisfying crunch!")) - L.take_damage(rand(15,25), 0, 0) - L.fracture(100) - M.last_damage_data = create_cause_data(initial(caste_type), src) - src.attack_log += text("\[[time_stamp()]\] ripped the [L.display_name] off of [M.name] ([M.ckey]) 1/2 progress") - M.attack_log += text("\[[time_stamp()]\] had their [L.display_name] ripped off by [src.name] ([src.ckey]) 1/2 progress") - log_attack("[src.name] ([src.ckey]) ripped the [L.display_name] off of [M.name] ([M.ckey]) 1/2 progress") - - if(!do_after(src, limb_time, INTERRUPT_ALL|INTERRUPT_DIFF_SELECT_ZONE, BUSY_ICON_HOSTILE) || M.stat == DEAD || iszombie(M)) - to_chat(src, SPAN_NOTICE("You stop ripping off the limb.")) - return FALSE - - if(L.status & LIMB_DESTROYED) - return FALSE - - visible_message(SPAN_XENOWARNING("[src] rips [M]'s [L.display_name] away from \his body!"), \ - SPAN_XENOWARNING("[M]'s [L.display_name] rips away from \his body!")) - src.attack_log += text("\[[time_stamp()]\] ripped the [L.display_name] off of [M.name] ([M.ckey]) 2/2 progress") - M.attack_log += text("\[[time_stamp()]\] had their [L.display_name] ripped off by [src.name] ([src.ckey]) 2/2 progress") - log_attack("[src.name] ([src.ckey]) ripped the [L.display_name] off of [M.name] ([M.ckey]) 2/2 progress") - - L.droplimb(0, 0, initial(name)) - - return TRUE +/// Called when pulling something and attacking yourself wth the pull (Z hotkey) override for caste specific behaviour +/mob/living/carbon/xenomorph/proc/pull_power(mob/mob) + return // Vent Crawl /mob/living/carbon/xenomorph/proc/vent_crawl() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm b/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm index 06eafcf074ed..d3d34af98908 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm @@ -156,3 +156,82 @@ /datum/behavior_delegate/warrior_base/proc/lifesteal_lock() bound_xeno.remove_filter("empower_rage") + + +/// Warrior specific behaviour for increasing pull power, limb rip. +/mob/living/carbon/xenomorph/warrior/pull_power(mob/mob) + if(!ripping_limb && mob.stat != DEAD) + if(mob.status_flags & XENO_HOST) + to_chat(src, SPAN_XENOWARNING("This would harm the embryo!")) + return + ripping_limb = TRUE + if(rip_limb(mob)) + stop_pulling() + ripping_limb = FALSE + + +/// Warrior Rip Limb - called by pull_power() +/mob/living/carbon/xenomorph/warrior/proc/rip_limb(mob/mob) + if(!istype(mob, /mob/living/carbon/human)) + return FALSE + + if(action_busy) //can't stack the attempts + return FALSE + + var/mob/living/carbon/human/human = mob + var/obj/limb/limb = human.get_limb(check_zone(zone_selected)) + + if(can_not_harm(human)) + to_chat(src, SPAN_XENOWARNING("You can't harm this host!")) + return + + if(!limb || limb.body_part == BODY_FLAG_CHEST || limb.body_part == BODY_FLAG_GROIN || (limb.status & LIMB_DESTROYED)) //Only limbs and head. + to_chat(src, SPAN_XENOWARNING("You can't rip off that limb.")) + return FALSE + var/limb_time = rand(40,60) + + if(limb.body_part == BODY_FLAG_HEAD) + limb_time = rand(90,110) + + visible_message(SPAN_XENOWARNING("[src] begins pulling on [mob]'s [limb.display_name] with incredible strength!"), \ + SPAN_XENOWARNING("You begin to pull on [mob]'s [limb.display_name] with incredible strength!")) + + if(!do_after(src, limb_time, INTERRUPT_ALL|INTERRUPT_DIFF_SELECT_ZONE, BUSY_ICON_HOSTILE) || mob.stat == DEAD || mob.status_flags & XENO_HOST) + to_chat(src, SPAN_NOTICE("You stop ripping off the limb.")) + if(mob.status_flags & XENO_HOST) + to_chat(src, SPAN_NOTICE("You detect an embryo inside [mob] which overwhelms your instinct to rip.")) + return FALSE + + if(limb.status & LIMB_DESTROYED) + return FALSE + + if(limb.status & (LIMB_ROBOT|LIMB_SYNTHSKIN)) + limb.take_damage(rand(30,40), 0, 0) // just do more damage + visible_message(SPAN_XENOWARNING("You hear [mob]'s [limb.display_name] being pulled beyond its load limits!"), \ + SPAN_XENOWARNING("[mob]'s [limb.display_name] begins to tear apart!")) + else + visible_message(SPAN_XENOWARNING("You hear the bones in [mob]'s [limb.display_name] snap with a sickening crunch!"), \ + SPAN_XENOWARNING("[mob]'s [limb.display_name] bones snap with a satisfying crunch!")) + limb.take_damage(rand(15,25), 0, 0) + limb.fracture(100) + mob.last_damage_data = create_cause_data(initial(caste_type), src) + src.attack_log += text("\[[time_stamp()]\] ripped the [limb.display_name] off of [mob.name] ([mob.ckey]) 1/2 progress") + mob.attack_log += text("\[[time_stamp()]\] had their [limb.display_name] ripped off by [src.name] ([src.ckey]) 1/2 progress") + log_attack("[src.name] ([src.ckey]) ripped the [limb.display_name] off of [mob.name] ([mob.ckey]) 1/2 progress") + + if(!do_after(src, limb_time, INTERRUPT_ALL|INTERRUPT_DIFF_SELECT_ZONE, BUSY_ICON_HOSTILE) || mob.stat == DEAD || iszombie(mob)) + to_chat(src, SPAN_NOTICE("You stop ripping off the limb.")) + return FALSE + + if(limb.status & LIMB_DESTROYED) + return FALSE + + visible_message(SPAN_XENOWARNING("[src] rips [mob]'s [limb.display_name] away from their body!"), \ + SPAN_XENOWARNING("[mob]'s [limb.display_name] rips away from their body!")) + src.attack_log += text("\[[time_stamp()]\] ripped the [limb.display_name] off of [mob.name] ([mob.ckey]) 2/2 progress") + mob.attack_log += text("\[[time_stamp()]\] had their [limb.display_name] ripped off by [src.name] ([src.ckey]) 2/2 progress") + log_attack("[src.name] ([src.ckey]) ripped the [limb.display_name] off of [mob.name] ([mob.ckey]) 2/2 progress") + + limb.droplimb(0, 0, initial(name)) + + return TRUE