Files
Polaris/code/modules/organs/wound.dm
mwerezak cf5ff7e992 Body temperature fixes and updates
Body temperature regulation is now based on species, and environmental
temperature now respects the air density when affecting living/humans.
This also fixes some bugs with heat/cold protection handling and
improves the way synthetic species body temperatures are handled to be
much more logical.

IPCs always gain temperature but cool down because of their environment.
When the heat transfer to the environment is reduced because of the lack
of air, this will cause IPCs to heat up.

As well, having an infection will increase your body temperature, and
body scanners now detect infections.
2014-06-20 18:18:02 -04:00

257 lines
8.2 KiB
Plaintext

/****************************************************
WOUNDS
****************************************************/
/datum/wound
// number representing the current stage
var/current_stage = 0
// description of the wound
var/desc = ""
// amount of damage this wound causes
var/damage = 0
// ticks of bleeding left.
var/bleed_timer = 0
// 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, counted from the right rather than the left of the list
// 1 means all stages except the last should bleed
var/max_bleeding_stage = 1
// one of CUT, 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 = 15
// helper lists
var/tmp/list/desc_list = list()
var/tmp/list/damage_list = list()
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
max_bleeding_stage = src.desc_list.len - max_bleeding_stage
// initialize with the appropriate stage
src.init_stage(damage)
bleed_timer += damage
// returns 1 if there's a next stage, 0 otherwise
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
proc/wound_damage()
return src.damage / src.amount
// checks whether the wound has been appropriately treated
// always returns 1 for wounds that are too minor to need treatment
proc/is_treated()
if(src.wound_damage() <= autoheal_cutoff)
return 1
if(damage_type == BRUISE || damage_type == CUT)
return bandaged
else if(damage_type == BURN)
return salved
// Checks whether other other can be merged into src.
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.is_treated()) != !(src.is_treated())) 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
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
proc/infection_check()
if (is_treated() && damage < 10)
return 0
if (disinfected)
return 0
var/dam_coef = round(damage/10)
switch (damage_type)
if (BRUISE)
return prob(dam_coef*5) && bleeding() //bruises only infectable if bleeding
if (BURN)
return prob(dam_coef*10)
if (CUT)
return prob(dam_coef*20)
return 0
// 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
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
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
proc/can_worsen(damage_type, damage)
if (src.damage_type != damage_type)
return 0 //incompatible damage types
if (src.amount > 1)
return 0
//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
proc/bleeding()
// internal wounds don't bleed in the sense of this function
return ((wound_damage() > 30 || bleed_timer > 0) && !(bandaged||clamped) && (damage_type == BRUISE && wound_damage() >= 20 || damage_type == CUT && wound_damage() >= 5) && current_stage <= max_bleeding_stage && !src.internal)
/** CUTS **/
/datum/wound/cut/small
// link wound descriptions to amounts of damage
max_bleeding_stage = 2
stages = list("ugly ripped cut" = 20, "ripped cut" = 10, "cut" = 5, "healing cut" = 2, "small scab" = 0)
damage_type = CUT
/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)
damage_type = CUT
/datum/wound/cut/flesh
max_bleeding_stage = 3
stages = list("ugly ripped flesh wound" = 35, "ugly flesh wound" = 30, "flesh wound" = 25, "blood soaked clot" = 15, "large scab" = 5, "fresh skin" = 0)
damage_type = CUT
/datum/wound/cut/gaping
max_bleeding_stage = 2
stages = list("gaping wound" = 50, "large blood soaked clot" = 25, "large clot" = 15, "small angry scar" = 5, "small straight scar" = 0)
damage_type = CUT
/datum/wound/cut/gaping_big
max_bleeding_stage = 2
stages = list("big gaping wound" = 60, "healing gaping wound" = 40, "large angry scar" = 10, "large straight scar" = 0)
damage_type = CUT
datum/wound/cut/massive
max_bleeding_stage = 2
stages = list("massive wound" = 70, "massive healing wound" = 50, "massive angry scar" = 10, "massive jagged scar" = 0)
damage_type = CUT
/** BRUISES **/
/datum/wound/bruise
stages = list("monumental bruise" = 80, "huge bruise" = 50, "large bruise" = 30,\
"moderate bruise" = 20, "small bruise" = 10, "tiny bruise" = 5)
max_bleeding_stage = 3
autoheal_cutoff = 30
damage_type = BRUISE
/** BURNS **/
/datum/wound/burn/moderate
stages = list("ripped burn" = 10, "moderate burn" = 5, "moderate salved burn" = 2, "fresh skin" = 0)
damage_type = BURN
/datum/wound/burn/large
stages = list("ripped large burn" = 20, "large burn" = 15, "large salved burn" = 5, "fresh skin" = 0)
damage_type = BURN
/datum/wound/burn/severe
stages = list("ripped severe burn" = 35, "severe burn" = 30, "severe salved burn" = 10, "burn scar" = 0)
damage_type = BURN
/datum/wound/burn/deep
stages = list("ripped deep burn" = 45, "deep burn" = 40, "deep salved burn" = 15, "large burn scar" = 0)
damage_type = BURN
/datum/wound/burn/carbonised
stages = list("carbonised area" = 50, "treated carbonised area" = 20, "massive burn scar" = 0)
damage_type = BURN
/datum/wound/internal_bleeding
internal = 1
stages = list("severed vein" = 30, "cut vein" = 20, "damaged vein" = 10, "bruised vein" = 5)
autoheal_cutoff = 5
max_bleeding_stage = 0 //all stages bleed. It's called internal bleeding after all.