mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-01-30 10:53:24 +00:00
* Various medical fixes. Kiosk Rework. qol: Reworks the medical kiosk to have use. It now dispenses small amounts of painpills and medications to help stabilize you to get you to medical before you croak. qol: Lungs no longer IMMEDIATELY risk popping if you forget internals for one second. You now have gradually accumulate damage over time. Get those internals on quick! qol: Infections now give you a better alert that it's an INFECTION you have instead of just a random 'you feel itchy' so players are less blindsided by infections. qol: Adjusts the text that you get when you suffer internal bleeding. Now it sticks out more during fights so you can know you have IB and get to medical quicker. add: Makes the medical kiosk actually DETECT more issues than before. Now it actually does a full body scan on you to see what's wrong with you! qol: Crayons and markers are no longer the strongest poison in the game. One crayon won't OD you anymore, but two will. One marker can still OD you with disaster effects if you eat it entirely. OORAH fix: Crayons and markers get properly added to your stomach fix: inaprovaline PROPERLY affects internal bleeding now. qol: Putting pressure on an external wound will put some pressure on arterial bleeds as well, helping decrease (but not entirely stop) bloodloss. code: Changes a few sections in the code to use REAGENTS_OVERDOSE instead of just a plain number. code: Gets rid of a few //EDIT comments for better code quality. code: Moved internal wound handling to handle_blood() * Flavor adjustments * words hard * Fixes CPR as well Fixes CPR bug * Vox can be defibbed Still can't be resleeved, but you can shock them back to life. * cpr bug fix electric boogaloo
412 lines
13 KiB
Plaintext
412 lines
13 KiB
Plaintext
|
|
/****************************************************
|
|
WOUNDS
|
|
****************************************************/
|
|
/datum/wound
|
|
// number representing the current stage
|
|
var/current_stage = 0
|
|
|
|
// description of the wound
|
|
var/desc = "wound" //default in case something borks
|
|
|
|
// amount of damage this wound causes
|
|
var/damage = 0
|
|
// ticks of bleeding left.
|
|
var/bleed_timer = 0
|
|
// Above this amount wounds you will need to treat the wound to stop bleeding, regardless of bleed_timer
|
|
var/bleed_threshold = 30
|
|
// amount of damage the current wound type requires(less means we need to apply the next healing stage)
|
|
var/min_damage = 0
|
|
|
|
// is the wound bandaged?
|
|
var/bandaged = 0
|
|
// Similar to bandaged, but works differently
|
|
var/clamped = 0
|
|
// is the wound salved?
|
|
var/salved = 0
|
|
// is the wound disinfected?
|
|
var/disinfected = 0
|
|
var/created = 0
|
|
// number of wounds of this type
|
|
var/amount = 1
|
|
// amount of germs in the wound
|
|
var/germ_level = 0
|
|
|
|
/* These are defined by the wound type and should not be changed */
|
|
|
|
// stages such as "cut", "deep cut", etc.
|
|
var/list/stages
|
|
// internal wounds can only be fixed through surgery
|
|
var/internal = 0
|
|
// maximum stage at which bleeding should still happen. Beyond this stage bleeding is prevented.
|
|
var/max_bleeding_stage = 0
|
|
// one of CUT, PIERCE, BRUISE, BURN
|
|
var/damage_type = CUT
|
|
// whether this wound needs a bandage/salve to heal at all
|
|
// the maximum amount of damage that this wound can have and still autoheal
|
|
var/autoheal_cutoff = 10
|
|
|
|
|
|
|
|
|
|
// helper lists
|
|
var/tmp/list/desc_list = list()
|
|
var/tmp/list/damage_list = list()
|
|
|
|
/datum/wound/New(var/damage)
|
|
|
|
created = world.time
|
|
|
|
// reading from a list("stage" = damage) is pretty difficult, so build two separate
|
|
// lists from them instead
|
|
for(var/V in stages)
|
|
desc_list += V
|
|
damage_list += stages[V]
|
|
|
|
src.damage = damage
|
|
|
|
// initialize with the appropriate stage
|
|
src.init_stage(damage)
|
|
|
|
bleed_timer += damage
|
|
|
|
// returns 1 if there's a next stage, 0 otherwise
|
|
/datum/wound/proc/init_stage(var/initial_damage)
|
|
current_stage = stages.len
|
|
|
|
while(src.current_stage > 1 && src.damage_list[current_stage-1] <= initial_damage / src.amount)
|
|
src.current_stage--
|
|
|
|
src.min_damage = damage_list[current_stage]
|
|
src.desc = desc_list[current_stage]
|
|
|
|
// the amount of damage per wound
|
|
/datum/wound/proc/wound_damage()
|
|
return src.damage / src.amount
|
|
|
|
/datum/wound/proc/can_autoheal()
|
|
if(is_treated())
|
|
return TRUE
|
|
if(src.wound_damage() <= autoheal_cutoff)
|
|
if(created + 10 MINUTES > world.time) // Wounds don't autoheal for ten minutes if not bandaged.
|
|
return FALSE
|
|
return TRUE
|
|
|
|
// checks whether the wound has been appropriately treated
|
|
/datum/wound/proc/is_treated()
|
|
if(damage_type == BRUISE || damage_type == CUT || damage_type == PIERCE)
|
|
return bandaged
|
|
else if(damage_type == BURN)
|
|
return salved
|
|
|
|
// Checks whether other other can be merged into src.
|
|
/datum/wound/proc/can_merge(var/datum/wound/other)
|
|
if (other.type != src.type) return 0
|
|
if (other.current_stage != src.current_stage) return 0
|
|
if (other.damage_type != src.damage_type) return 0
|
|
if (!(other.can_autoheal()) != !(src.can_autoheal())) return 0
|
|
if (!(other.bandaged) != !(src.bandaged)) return 0
|
|
if (!(other.clamped) != !(src.clamped)) return 0
|
|
if (!(other.salved) != !(src.salved)) return 0
|
|
if (!(other.disinfected) != !(src.disinfected)) return 0
|
|
//if (other.germ_level != src.germ_level) return 0
|
|
return 1
|
|
|
|
/datum/wound/proc/merge_wound(var/datum/wound/other)
|
|
src.damage += other.damage
|
|
src.amount += other.amount
|
|
src.bleed_timer += other.bleed_timer
|
|
src.germ_level = max(src.germ_level, other.germ_level)
|
|
src.created = max(src.created, other.created) //take the newer created time
|
|
|
|
// checks if wound is considered open for external infections
|
|
// untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger
|
|
/datum/wound/proc/infection_check()
|
|
if (damage < 10) //small cuts, tiny bruises, and moderate burns shouldn't be infectable.
|
|
return 0
|
|
if (is_treated() && damage < 25) //anything less than a flesh wound (or equivalent) isn't infectable if treated properly
|
|
return 0
|
|
if (disinfected)
|
|
germ_level = 0 //reset this, just in case
|
|
return 0
|
|
|
|
if (damage_type == BRUISE && !bleeding()) //bruises only infectable if bleeding
|
|
return 0
|
|
|
|
var/dam_coef = round(damage/10)
|
|
switch (damage_type)
|
|
if (BRUISE)
|
|
return prob(dam_coef*5)
|
|
if (BURN)
|
|
return prob(dam_coef*10)
|
|
if (CUT)
|
|
return prob(dam_coef*20)
|
|
|
|
return 0
|
|
|
|
/datum/wound/proc/bandage()
|
|
bandaged = 1
|
|
|
|
/datum/wound/proc/salve()
|
|
salved = 1
|
|
|
|
/datum/wound/proc/disinfect()
|
|
disinfected = 1
|
|
|
|
// heal the given amount of damage, and if the given amount of damage was more
|
|
// than what needed to be healed, return how much heal was left
|
|
// set @heals_internal to also heal internal organ damage
|
|
/datum/wound/proc/heal_damage(amount, heals_internal = 0)
|
|
if(src.internal && !heals_internal)
|
|
// heal nothing
|
|
return amount
|
|
|
|
var/healed_damage = min(src.damage, amount)
|
|
amount -= healed_damage
|
|
src.damage -= healed_damage
|
|
|
|
while(src.wound_damage() < damage_list[current_stage] && current_stage < src.desc_list.len)
|
|
current_stage++
|
|
desc = desc_list[current_stage]
|
|
src.min_damage = damage_list[current_stage]
|
|
|
|
// return amount of healing still leftover, can be used for other wounds
|
|
return amount
|
|
|
|
// opens the wound again
|
|
/datum/wound/proc/open_wound(damage)
|
|
src.damage += damage
|
|
bleed_timer += damage
|
|
|
|
while(src.current_stage > 1 && src.damage_list[current_stage-1] <= src.damage / src.amount)
|
|
src.current_stage--
|
|
|
|
src.desc = desc_list[current_stage]
|
|
src.min_damage = damage_list[current_stage]
|
|
|
|
// returns whether this wound can absorb the given amount of damage.
|
|
// this will prevent large amounts of damage being trapped in less severe wound types
|
|
/datum/wound/proc/can_worsen(damage_type, damage)
|
|
if (src.damage_type != damage_type)
|
|
return 0 //incompatible damage types
|
|
|
|
if (src.amount > 1)
|
|
return 0//merged wounds cannot be worsened.
|
|
|
|
//with 1.5*, a shallow cut will be able to carry at most 30 damage,
|
|
//37.5 for a deep cut
|
|
//52.5 for a flesh wound, etc.
|
|
var/max_wound_damage = 1.5*src.damage_list[1]
|
|
if (src.damage + damage > max_wound_damage)
|
|
return 0
|
|
|
|
return 1
|
|
|
|
/datum/wound/proc/bleeding()
|
|
if (src.internal)
|
|
return FALSE // internal wounds don't bleed in the sense of this function
|
|
|
|
if (current_stage > max_bleeding_stage)
|
|
return FALSE
|
|
|
|
if (bandaged||clamped)
|
|
return FALSE
|
|
|
|
if (bleed_timer <= 0 && wound_damage() <= bleed_threshold)
|
|
return FALSE //Bleed timer has run out. Once a wound is big enough though, you'll need a bandage to stop it
|
|
|
|
return TRUE
|
|
|
|
/** WOUND DEFINITIONS **/
|
|
|
|
//Note that the MINIMUM damage before a wound can be applied should correspond to
|
|
//the damage amount for the stage with the same name as the wound.
|
|
//e.g. /datum/wound/cut/deep should only be applied for 15 damage and up,
|
|
//because in it's stages list, "deep cut" = 15.
|
|
/proc/get_wound_type(var/type = CUT, var/damage)
|
|
switch(type)
|
|
if(CUT)
|
|
switch(damage)
|
|
if(70 to INFINITY)
|
|
return /datum/wound/cut/massive
|
|
if(60 to 70)
|
|
return /datum/wound/cut/gaping_big
|
|
if(50 to 60)
|
|
return /datum/wound/cut/gaping
|
|
if(25 to 50)
|
|
return /datum/wound/cut/flesh
|
|
if(15 to 25)
|
|
return /datum/wound/cut/deep
|
|
if(0 to 15)
|
|
return /datum/wound/cut/small
|
|
if(PIERCE)
|
|
switch(damage)
|
|
if(60 to INFINITY)
|
|
return /datum/wound/puncture/massive
|
|
if(50 to 60)
|
|
return /datum/wound/puncture/gaping_big
|
|
if(30 to 50)
|
|
return /datum/wound/puncture/gaping
|
|
if(15 to 30)
|
|
return /datum/wound/puncture/flesh
|
|
if(0 to 15)
|
|
return /datum/wound/puncture/small
|
|
if(BRUISE)
|
|
return /datum/wound/bruise
|
|
if(BURN)
|
|
switch(damage)
|
|
if(50 to INFINITY)
|
|
return /datum/wound/burn/carbonised
|
|
if(40 to 50)
|
|
return /datum/wound/burn/deep
|
|
if(30 to 40)
|
|
return /datum/wound/burn/severe
|
|
if(15 to 30)
|
|
return /datum/wound/burn/large
|
|
if(0 to 15)
|
|
return /datum/wound/burn/moderate
|
|
return null //no wound
|
|
|
|
/** CUTS **/
|
|
/datum/wound/cut
|
|
bleed_threshold = 5
|
|
damage_type = CUT
|
|
|
|
/datum/wound/cut/small
|
|
// link wound descriptions to amounts of damage
|
|
// Minor cuts have max_bleeding_stage set to the stage that bears the wound type's name.
|
|
// The major cut types have the max_bleeding_stage set to the clot stage (which is accordingly given the "blood soaked" descriptor).
|
|
max_bleeding_stage = 3
|
|
stages = list("ugly ripped cut" = 20, "ripped cut" = 10, "cut" = 5, "healing cut" = 2, "small scab" = 0)
|
|
|
|
/datum/wound/cut/deep
|
|
max_bleeding_stage = 3
|
|
stages = list("ugly deep ripped cut" = 25, "deep ripped cut" = 20, "deep cut" = 15, "clotted cut" = 8, "scab" = 2, "fresh skin" = 0)
|
|
|
|
/datum/wound/cut/flesh
|
|
max_bleeding_stage = 4
|
|
stages = list("ugly ripped flesh wound" = 35, "ugly flesh wound" = 30, "flesh wound" = 25, "blood soaked clot" = 15, "large scab" = 5, "fresh skin" = 0)
|
|
|
|
/datum/wound/cut/gaping
|
|
max_bleeding_stage = 3
|
|
stages = list("gaping wound" = 50, "large blood soaked clot" = 25, "blood soaked clot" = 15, "small angry scar" = 5, "small straight scar" = 0)
|
|
|
|
/datum/wound/cut/gaping_big
|
|
max_bleeding_stage = 3
|
|
stages = list("big gaping wound" = 60, "healing gaping wound" = 40, "large blood soaked clot" = 25, "large angry scar" = 10, "large straight scar" = 0)
|
|
|
|
/datum/wound/cut/massive
|
|
max_bleeding_stage = 3
|
|
stages = list("massive wound" = 70, "massive healing wound" = 50, "massive blood soaked clot" = 25, "massive angry scar" = 10, "massive jagged scar" = 0)
|
|
|
|
/** PUNCTURES **/
|
|
/datum/wound/puncture
|
|
bleed_threshold = 5
|
|
damage_type = PIERCE
|
|
|
|
/datum/wound/puncture/can_worsen(damage_type, damage)
|
|
return 0 //puncture wounds cannot be enlargened
|
|
|
|
/datum/wound/puncture/small
|
|
max_bleeding_stage = 2
|
|
stages = list("puncture" = 5, "healing puncture" = 2, "small scab" = 0)
|
|
damage_type = PIERCE
|
|
|
|
/datum/wound/puncture/flesh
|
|
max_bleeding_stage = 2
|
|
stages = list("puncture wound" = 15, "blood soaked clot" = 5, "large scab" = 2, "small round scar" = 0)
|
|
damage_type = PIERCE
|
|
|
|
/datum/wound/puncture/gaping
|
|
max_bleeding_stage = 3
|
|
stages = list("gaping hole" = 30, "large blood soaked clot" = 15, "blood soaked clot" = 10, "small angry scar" = 5, "small round scar" = 0)
|
|
damage_type = PIERCE
|
|
|
|
/datum/wound/puncture/gaping_big
|
|
max_bleeding_stage = 3
|
|
stages = list("big gaping hole" = 50, "healing gaping hole" = 20, "large blood soaked clot" = 15, "large angry scar" = 10, "large round scar" = 0)
|
|
damage_type = PIERCE
|
|
|
|
/datum/wound/puncture/massive
|
|
max_bleeding_stage = 3
|
|
stages = list("massive wound" = 60, "massive healing wound" = 30, "massive blood soaked clot" = 25, "massive angry scar" = 10, "massive jagged scar" = 0)
|
|
damage_type = PIERCE
|
|
|
|
/** BRUISES **/
|
|
/datum/wound/bruise
|
|
stages = list("monumental bruise" = 80, "huge bruise" = 50, "large bruise" = 30,
|
|
"moderate bruise" = 20, "small bruise" = 10, "tiny bruise" = 5)
|
|
bleed_threshold = 20
|
|
max_bleeding_stage = 2 //only huge bruise and above can bleed.
|
|
damage_type = BRUISE
|
|
|
|
/** BURNS **/
|
|
/datum/wound/burn
|
|
damage_type = BURN
|
|
max_bleeding_stage = 0
|
|
|
|
/datum/wound/burn/bleeding()
|
|
return 0
|
|
|
|
/datum/wound/burn/moderate
|
|
stages = list("ripped burn" = 10, "moderate burn" = 5, "healing moderate burn" = 2, "fresh skin" = 0)
|
|
|
|
/datum/wound/burn/large
|
|
stages = list("ripped large burn" = 20, "large burn" = 15, "healing large burn" = 5, "fresh skin" = 0)
|
|
|
|
/datum/wound/burn/severe
|
|
stages = list("ripped severe burn" = 35, "severe burn" = 30, "healing severe burn" = 10, "burn scar" = 0)
|
|
|
|
/datum/wound/burn/deep
|
|
stages = list("ripped deep burn" = 45, "deep burn" = 40, "healing deep burn" = 15, "large burn scar" = 0)
|
|
|
|
/datum/wound/burn/carbonised
|
|
stages = list("carbonised area" = 50, "healing carbonised area" = 20, "massive burn scar" = 0)
|
|
|
|
/** INTERNAL BLEEDING **/
|
|
/datum/wound/internal_bleeding
|
|
internal = 1
|
|
stages = list("severed artery" = 30, "cut artery" = 20, "damaged artery" = 10, "bruised artery" = 5)
|
|
autoheal_cutoff = 5
|
|
max_bleeding_stage = 4 //all stages bleed. It's called internal bleeding after all.
|
|
|
|
/** EXTERNAL ORGAN LOSS **/
|
|
/datum/wound/lost_limb
|
|
|
|
/datum/wound/lost_limb/New(var/obj/item/organ/external/lost_limb, var/losstype, var/clean)
|
|
var/damage_amt = lost_limb.max_damage
|
|
if(clean) damage_amt /= 2
|
|
|
|
switch(losstype)
|
|
if(DROPLIMB_EDGE, DROPLIMB_BLUNT)
|
|
damage_type = CUT
|
|
max_bleeding_stage = 3 //clotted stump and above can bleed.
|
|
stages = list(
|
|
"ripped stump" = damage_amt*1.3,
|
|
"bloody stump" = damage_amt,
|
|
"clotted stump" = damage_amt*0.5,
|
|
"scarred stump" = 0
|
|
)
|
|
if(DROPLIMB_BURN)
|
|
damage_type = BURN
|
|
stages = list(
|
|
"ripped charred stump" = damage_amt*1.3,
|
|
"charred stump" = damage_amt,
|
|
"scarred stump" = damage_amt*0.5,
|
|
"scarred stump" = 0
|
|
)
|
|
|
|
if(DROPLIMB_ACID)
|
|
damage_type = BURN
|
|
stages = list(
|
|
"disfigured mass" = damage_amt*1.3,
|
|
"melted stump" = damage_amt,
|
|
"deformed stump" = damage_amt*0.5,
|
|
"scarred stump" = 0
|
|
)
|
|
|
|
..(damage_amt)
|
|
|
|
/datum/wound/lost_limb/can_merge(var/datum/wound/other)
|
|
return 0 //cannot be merged
|