Files
Bubberstation/code/datums/elements/attack_zone_randomiser.dm
Jacquerel c9986346e4 Ian and Runtime can lick your wounds (#83746)
## About The Pull Request

As I turned this into a trait the other day I thought I might as well go
all the way.

This PR allows basic mobs to perform wound handling steps if not in
combat mode.
This chiefly means that:
- cats and dogs can lick your wounds clean (they have the "wound licker"
trait)
- gorillas can set a dislocated limb (they have hands)
- dextrous holoparasites can pluck the eyeballs out of someone's crushed
head (they also have hands)

Wolves have the wound licker trait but can't lick your wounds because
for some reason they can't drag humans and I couldn't be bothered to
figure out why that was set up that way. Also it would look stupid
because it would still do the attack forecast animation.

In order to facilitate being able to set bones, gorillas need to be able
to aggressively grab you.
While I was there I set it to allow them to strangle people to death
because... well they're gorillas. It's probably slower than they could
punch you to death, so I don't see the harm.

## Why It's Good For The Game

If felinids can lick your wounds to heal them why can't an ordinary cat?
An ordinary cat won't _often_ do this and I have not placed any such
behaviour into their AI tree, but a sapient Ian or Runtime might provide
extremely minor assistance in medbay.

Also Cargorilla setting your dislocated limbs seems very funny and like
something it should be allowed to do.

## Changelog

🆑
add: Cats and Dogs can lick slashing wounds clean.
add: Basic Mobs with hands can relocate dislocated bones, and pluck
eyeballs out of pulped skulls.
balance: Gorillas can strangle people.
/🆑
2024-06-14 18:27:15 -07:00

36 lines
1.5 KiB
Plaintext

/// Pick a random attack zone before you attack something
/datum/element/attack_zone_randomiser
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
/// List of attack zones you can select, should be a subset of GLOB.all_body_zones
var/list/valid_attack_zones
/datum/element/attack_zone_randomiser/Attach(datum/target, list/valid_attack_zones = GLOB.all_body_zones)
. = ..()
if (!isliving(target))
return ELEMENT_INCOMPATIBLE
RegisterSignals(target, list(COMSIG_HOSTILE_PRE_ATTACKINGTARGET, COMSIG_LIVING_UNARMED_ATTACK), PROC_REF(randomise))
src.valid_attack_zones = valid_attack_zones
/datum/element/attack_zone_randomiser/Detach(datum/source)
UnregisterSignal(source, list (COMSIG_HOSTILE_PRE_ATTACKINGTARGET, COMSIG_LIVING_UNARMED_ATTACK))
return ..()
/// If we're attacking a carbon, pick a random defence zone
/datum/element/attack_zone_randomiser/proc/randomise(mob/living/source, atom/target)
SIGNAL_HANDLER
if (!iscarbon(target))
return
if (!isnull(source.mind) && !isnull(source.hud_used?.zone_select))
return
var/mob/living/living_target = target
var/list/blacklist_zones = GLOB.all_body_zones - valid_attack_zones
var/new_zone = living_target.get_random_valid_zone(blacklisted_parts = blacklist_zones, bypass_warning = TRUE)
if (isnull(new_zone))
new_zone = BODY_ZONE_CHEST
var/atom/movable/screen/zone_sel/zone_selector = source.hud_used?.zone_select
if (isnull(zone_selector))
source.zone_selected = new_zone
else
zone_selector.set_selected_zone(new_zone, source, should_log = FALSE)