Files
Bubberstation/code/datums/wounds/loss.dm
nikothedude 009af8c2ce [TEST-MERGE FIRST] Wound refactor number two: Full synthetic support (#78124)
## About The Pull Request

Heavily refactors wounds AGAIN.

The primary thing this PR does is completely change how wounds are
generated and added - while the normal "hit a guy til they bleed" stuff
works about the same, asking for a specific type of wound, say, like how
vending machines try to apply a compound fracture sometimes, isnt going
to work if we ever get any non-organic wounds, which the previous
refactor allowed.

With this PR, however...
* You can now ask for a specific type of wound via
get_corresponding_wound_type(), which takes wound types, a limb, wound
series, etc. and will try to give you a wound fitting those
specifications - but also, a wound that can be applied to a limb.
* This will allow for a vending machine to apply a compound fracture to
a human, but a collapsed superstructure (assuming my synth wounds go in)
to a robot

There are now new "series types" and "wound specific types" that allow
us to designate what series are "mainline" and randomly generatable, and
what are "alternate types" and must be generated manually - you can see
the documentation in wounds.dm.

The behavior of limping and interaction delays has been abstracted to
datum/wound from bone wounds to allow just, general ease of development

Pregen data now allows for series-specific wound penalties. Example: You
could set a burn wound's series wound penalty to 40, which would make
wound progression in the burn category easier - but it would not make it
any easier to get a slashing wound. As it stands wound penalties are for
wounds globally

Scar files are now picked in a "priority" list, where the wound checks
to see if the limb has a biostate before moving down in said list.
Example: Wounds will check for flesh first, if it finds it - it will use
the flesh scar list. Failing that, they then check bone - if it uses
that, it will use the bone scar list. This allows for significantly more
modular scars that dont even need much proc editing when a new wound
type is added

Misc changes: most initial() usage has been replaced by singleton
datums, wound_type is now wound_types and thus wounds can accept
multiple wound types, wounds can now accept multiple tool behaviors for
treatment, wounds now have a picking weight so we can make certain
wounds rarer flatly,

This PR also allows for wounds to override lower severity wounds on
generation, allowing eswords to jump to avulsions - but in spirit of
refactoring, this has been disabled by default (see pregen data's
competition_mode var).
## Why It's Good For The Game

Code quality is good!

Also, all the changes above allow wounds to be a MUCH more modular
system, which is one of its biggest problems right now - everything is
kinda hardcoded and static, making creative work within wounds harder to
do.

## Changelog
🆑
refactor: Refactored wounds yet again
fix: Wounds are now picked from the most severe down again, meaning
eswords can jump to avulsions
fix: Scar descs are now properly applied
/🆑
2023-09-09 19:20:21 -04:00

86 lines
3.3 KiB
Plaintext

/datum/wound_pregen_data/loss
abstract = FALSE
wound_path_to_generate = /datum/wound/loss
required_limb_biostate = NONE
require_any_biostate = TRUE
required_wounding_types = list(WOUND_ALL)
wound_series = WOUND_SERIES_LOSS_BASIC
threshold_minimum = WOUND_DISMEMBER_OUTRIGHT_THRESH // not actually used since dismembering is handled differently, but may as well assign it since we got it
/datum/wound/loss
name = "Dismemberment Wound"
desc = "oof ouch!!"
sound_effect = 'sound/effects/dismember.ogg'
severity = WOUND_SEVERITY_LOSS
status_effect_type = null
scar_keyword = "dismember"
wound_flags = null
already_scarred = TRUE // We manually assign scars for dismembers through endround missing limbs and aheals
/// The wounding_type of the attack that caused us. Used to generate the description of our scar. Currently unused, but primarily exists in case non-biological wounds are added.
var/loss_wounding_type
/// Our special proc for our special dismembering, the wounding type only matters for what text we have
/datum/wound/loss/proc/apply_dismember(obj/item/bodypart/dismembered_part, wounding_type = WOUND_SLASH, outright = FALSE, attack_direction)
if(!istype(dismembered_part) || !dismembered_part.owner || !(dismembered_part.body_zone in get_viable_zones()) || isalien(dismembered_part.owner) || !dismembered_part.can_dismember())
qdel(src)
return
set_victim(dismembered_part.owner)
var/self_msg
if(dismembered_part.body_zone == BODY_ZONE_CHEST)
occur_text = "is split open, causing [victim.p_their()] internal organs to spill out!"
self_msg = "is split open, causing your internal organs to spill out!"
else
occur_text = dismembered_part.get_dismember_message(wounding_type, outright)
var/msg = span_bolddanger("[victim]'s [dismembered_part.plaintext_zone] [occur_text]")
victim.visible_message(msg, span_userdanger("Your [dismembered_part.plaintext_zone] [self_msg ? self_msg : occur_text]"))
loss_wounding_type = wounding_type
set_limb(dismembered_part)
second_wind()
log_wound(victim, src)
if(dismembered_part.can_bleed() && wounding_type != WOUND_BURN && victim.blood_volume)
victim.spray_blood(attack_direction, severity)
dismembered_part.dismember(wounding_type == WOUND_BURN ? BURN : BRUTE, wounding_type = wounding_type)
qdel(src)
return TRUE
/obj/item/bodypart/proc/get_dismember_message(wounding_type, outright)
var/occur_text
if(outright)
switch(wounding_type)
if(WOUND_BLUNT)
occur_text = "is outright smashed to a gross pulp, severing it completely!"
if(WOUND_SLASH)
occur_text = "is outright slashed off, severing it completely!"
if(WOUND_PIERCE)
occur_text = "is outright blasted apart, severing it completely!"
if(WOUND_BURN)
occur_text = "is outright incinerated, falling to dust!"
else
var/bone_text = get_internal_description()
var/tissue_text = get_external_description()
switch(wounding_type)
if(WOUND_BLUNT)
occur_text = "is shattered through the last [bone_text] holding it together, severing it completely!"
if(WOUND_SLASH)
occur_text = "is slashed through the last [tissue_text] holding it together, severing it completely!"
if(WOUND_PIERCE)
occur_text = "is pierced through the last [tissue_text] holding it together, severing it completely!"
if(WOUND_BURN)
occur_text = "is completely incinerated, falling to dust!"
return occur_text