Merge pull request #2955 from Anewbe/heart_damage

Big Ol' Medical Tweaks
This commit is contained in:
MagmaRam
2017-03-28 20:02:24 -05:00
committed by GitHub
41 changed files with 467 additions and 193 deletions

View File

@@ -6,6 +6,7 @@ var/const/BLOOD_VOLUME_SAFE = 85
var/const/BLOOD_VOLUME_OKAY = 75
var/const/BLOOD_VOLUME_BAD = 60
var/const/BLOOD_VOLUME_SURVIVE = 40
var/const/CE_STABLE_THRESHOLD = 0.5
/mob/living/carbon/human/var/datum/reagents/vessel // Container for blood and BLOOD ONLY. Do not transfer other chems here.
/mob/living/carbon/human/var/var/pale = 0 // Should affect how mob sprite is drawn, but currently doesn't.
@@ -68,14 +69,24 @@ var/const/BLOOD_VOLUME_SURVIVE = 40
if(!heart)
blood_volume = 0
else if(heart.damage > 1 && heart.damage < heart.min_bruised_damage)
blood_volume *= 0.8
else if(heart.damage >= heart.min_bruised_damage && heart.damage < heart.min_broken_damage)
blood_volume *= 0.6
else if(heart.damage >= heart.min_broken_damage && heart.damage < INFINITY)
else if(heart.is_broken())
blood_volume *= 0.3
else if(heart.is_bruised())
blood_volume *= 0.7
else if(heart.damage)
blood_volume *= 0.8
//Effects of bloodloss
var/dmg_coef = 1 //Lower means less damage taken
var/threshold_coef = 1 //Lower means the damage caps off lower
if(CE_STABLE in chem_effects)
dmg_coef = 0.5
threshold_coef = 0.75
// These are Bay bits, do some sort of calculation.
// dmg_coef = min(1, 10/chem_effects[CE_STABLE]) //TODO: add effect for increased damage
// threshold_coef = min(dmg_coef / CE_STABLE_THRESHOLD, 1)
if(blood_volume >= BLOOD_VOLUME_SAFE)
if(pale)
pale = 0
@@ -89,23 +100,23 @@ var/const/BLOOD_VOLUME_SURVIVE = 40
if(prob(1))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel [word]"
if(oxyloss < 20)
oxyloss += 3
if(getOxyLoss() < 20 * threshold_coef)
adjustOxyLoss(3 * dmg_coef)
else if(blood_volume >= BLOOD_VOLUME_BAD)
if(!pale)
pale = 1
update_body()
eye_blurry = max(eye_blurry,6)
if(oxyloss < 50)
oxyloss += 10
oxyloss += 1
if(getOxyLoss() < 50 * threshold_coef)
adjustOxyLoss(10 * dmg_coef)
adjustOxyLoss(1 * dmg_coef)
if(prob(15))
Paralyse(rand(1,3))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel extremely [word]"
else if(blood_volume >= BLOOD_VOLUME_SURVIVE)
oxyloss += 5
toxloss += 3
adjustOxyLoss(5 * dmg_coef)
adjustToxLoss(3 * dmg_coef)
if(prob(15))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel extremely [word]"
@@ -115,8 +126,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 40
update_body()
eye_blurry = max(eye_blurry,6)
Paralyse(3)
toxloss += 3
oxyloss += 75 // 15 more than dexp fixes (also more than dex+dexp+tricord)
adjustToxLoss(3 * dmg_coef)
adjustOxyLoss(75 * dmg_coef) // 15 more than dexp fixes (also more than dex+dexp+tricord)
// Without enough blood you slowly go hungry.
if(blood_volume < BLOOD_VOLUME_SAFE)
@@ -144,6 +155,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 40
blood_loss_divisor += 5
else if((temp.organ_tag == BP_L_HAND) || (temp.organ_tag == BP_R_HAND) || (temp.organ_tag == BP_L_FOOT) || (temp.organ_tag == BP_R_FOOT))
blood_loss_divisor += 10
if(CE_STABLE in chem_effects) //Inaprov slows bloodloss
blood_loss_divisor += 10
if(temp.applied_pressure)
if(ishuman(temp.applied_pressure))
var/mob/living/carbon/human/H = temp.applied_pressure

View File

@@ -24,7 +24,7 @@
/obj/item/organ/internal/lungs/proc/rupture()
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
if(istype(parent))
owner.custom_pain("You feel a stabbing pain in your [parent.name]!", 1)
owner.custom_pain("You feel a stabbing pain in your [parent.name]!", 50)
bruise()
/obj/item/organ/internal/lungs/handle_germ_effects()

View File

@@ -256,7 +256,7 @@ var/list/organ_cache = list()
if(owner && parent_organ && amount > 0)
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
if(parent && !silent)
owner.custom_pain("Something inside your [parent.name] hurts a lot.", 1)
owner.custom_pain("Something inside your [parent.name] hurts a lot.", amount)
/obj/item/organ/proc/bruise()
damage = max(damage, min_bruised_damage)

View File

@@ -487,7 +487,7 @@ This function completely restores a damaged organ to perfect condition.
if((damage > 15) && (type != BURN) && (local_damage > 30) && prob(damage) && (robotic < ORGAN_ROBOT))
var/datum/wound/internal_bleeding/I = new (min(damage - 15, 15))
wounds += I
owner.custom_pain("You feel something rip in your [name]!", 1)
owner.custom_pain("You feel something rip in your [name]!", 50)
//Burn damage can cause fluid loss due to blistering and cook-off
if((damage > 5 || damage + burn_dam >= 15) && type == BURN && (robotic < ORGAN_ROBOT))
@@ -705,7 +705,7 @@ Note that amputating the affected organ does in fact remove the infection from t
owner.vessel.remove_reagent("blood", wound_update_accuracy * W.damage/40) //line should possibly be moved to handle_blood, so all the bleeding stuff is in one place.
if(prob(1 * wound_update_accuracy))
owner.custom_pain("You feel a stabbing pain in your [name]!",1)
owner.custom_pain("You feel a stabbing pain in your [name]!", 50)
// slow healing
var/heal_amt = 0

View File

@@ -248,20 +248,23 @@
if(inflamed == 1)
if(prob(5))
owner << "<span class='warning'>You feel a stinging pain in your abdomen!</span>"
owner.emote("me", 1, "winces slightly.")
if(owner.can_feel_pain())
owner.custom_pain("You feel a stinging pain in your abdomen!", 25)
if(inflamed > 1)
if(prob(3))
owner << "<span class='warning'>You feel a stabbing pain in your abdomen!</span>"
owner.emote("me", 1, "winces painfully.")
if(owner.can_feel_pain())
owner.custom_pain("You feel a stabbing pain in your abdomen!", 50)
owner.adjustToxLoss(1)
if(inflamed > 2)
if(prob(1))
owner.vomit()
if(owner.can_feel_pain())
owner.custom_pain("You feel a horrible pain in your abdomen!", 70)
if(inflamed > 3)
if(prob(1))
owner << "<span class='danger'>Your abdomen is a world of pain!</span>"
owner.Weaken(10)
if(owner.can_feel_pain())
owner.custom_pain("You feel a stinging pain in your abdomen!", 100)
owner.Weaken(10)
var/obj/item/organ/external/groin = owner.get_organ(BP_GROIN)
var/datum/wound/W = new /datum/wound/internal_bleeding(20)

View File

@@ -5,118 +5,73 @@ mob/var/list/pain_stored = list()
mob/var/last_pain_message = ""
mob/var/next_pain_time = 0
// partname is the name of a body part
// amount is a num from 1 to 100
mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0)
if(stat >= 1)
return
if(!can_feel_pain())
return
if(analgesic > 40)
return
if(world.time < next_pain_time && !force)
return
if(amount > 10 && istype(src,/mob/living/carbon/human))
if(src:paralysis)
src:paralysis = max(0, src:paralysis-round(amount/10))
if(amount > 50 && prob(amount / 5))
src:drop_item()
var/msg
if(burning)
switch(amount)
if(1 to 10)
msg = "<span class='danger'>Your [partname] burns.</span>"
if(11 to 90)
flash_weak_pain()
msg = "<span class='danger'><font size=2>Your [partname] burns badly!</font></span>"
if(91 to 10000)
flash_pain()
msg = "<span class='danger'><font size=3>OH GOD! Your [partname] is on fire!</font></span>"
else
switch(amount)
if(1 to 10)
msg = "<b>Your [partname] hurts.</b>"
if(11 to 90)
flash_weak_pain()
msg = "<b><font size=2>Your [partname] hurts badly.</font></b>"
if(91 to 10000)
flash_pain()
msg = "<b><font size=3>OH GOD! Your [partname] is hurting terribly!</font></b>"
if(msg && (msg != last_pain_message || prob(10)))
last_pain_message = msg
src << msg
next_pain_time = world.time + (100 - amount)
// message is the custom message to be displayed
// flash_strength is 0 for weak pain flash, 1 for strong pain flash
mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength)
if(stat >= 1)
return
if(!can_feel_pain())
return
if(reagents.has_reagent("tramadol"))
return
if(reagents.has_reagent("oxycodone"))
return
if(analgesic)
return
var/msg = "<span class='danger'>[message]</span>"
if(flash_strength >= 1)
msg = "<span class='danger'><font size=3>[message]</font></span>"
// power decides how much painkillers will stop the message
// force means it ignores anti-spam timer
mob/living/carbon/proc/custom_pain(message, power, force)
if(!message || stat || !can_feel_pain() || chem_effects[CE_PAINKILLER] > power)
return 0
message = "<span class='danger'>[message]</span>"
if(power >= 50)
message = "<font size=3>[message]</font>"
// Anti message spam checks
if(msg && ((msg != last_pain_message) || (world.time >= next_pain_time)))
last_pain_message = msg
src << msg
next_pain_time = world.time + 100
if(force || (message != last_pain_message) || (world.time >= next_pain_time))
last_pain_message = message
src << message
next_pain_time = world.time + (100-power)
mob/living/carbon/human/proc/handle_pain()
// not when sleeping
if(stat)
return
if(!can_feel_pain()) return
if(!can_feel_pain())
return
if(stat >= 2) return
if(analgesic > 70)
if(world.time < next_pain_time)
return
var/maxdam = 0
var/obj/item/organ/external/damaged_organ = null
for(var/obj/item/organ/external/E in organs)
if((E.status & ORGAN_DEAD) || E.robotic >= ORGAN_ROBOT) continue
if(!E.can_feel_pain()) continue
var/dam = E.get_damage()
// make the choice of the organ depend on damage,
// but also sometimes use one of the less damaged ones
if(dam > maxdam && (maxdam == 0 || prob(70)) )
damaged_organ = E
maxdam = dam
if(damaged_organ)
pain(damaged_organ.name, maxdam, 0)
if(damaged_organ && chem_effects[CE_PAINKILLER] < maxdam)
if(maxdam > 10 && paralysis)
paralysis = max(0, paralysis - round(maxdam/10))
if(maxdam > 50 && prob(maxdam / 5))
drop_item()
var/burning = damaged_organ.burn_dam > damaged_organ.brute_dam
var/msg
switch(maxdam)
if(1 to 10)
msg = "Your [damaged_organ.name] [burning ? "burns" : "hurts"]."
if(11 to 90)
flash_weak_pain()
msg = "<font size=2>Your [damaged_organ.name] [burning ? "burns" : "hurts"] badly!</font>"
if(91 to 10000)
flash_pain()
msg = "<font size=3>OH GOD! Your [damaged_organ.name] is [burning ? "on fire" : "hurting terribly"]!</font>"
custom_pain(msg, maxdam, prob(10))
// Damage to internal organs hurts a lot.
for(var/obj/item/organ/I in internal_organs)
if((I.status & ORGAN_DEAD) || I.robotic >= ORGAN_ROBOT) continue
if(I.damage > 2) if(prob(2))
var/obj/item/organ/external/parent = get_organ(I.parent_organ)
src.custom_pain("You feel a sharp pain in your [parent.name]", 1)
src.custom_pain("You feel a sharp pain in your [parent.name]", 50)
var/toxDamageMessage = null
var/toxMessageProb = 1
switch(getToxLoss())
if(1 to 5)
toxMessageProb = 1
toxDamageMessage = "Your body stings slightly."
if(6 to 10)
toxMessageProb = 2
toxDamageMessage = "Your whole body hurts a little."
if(11 to 15)
toxMessageProb = 2
toxDamageMessage = "Your whole body hurts."
if(15 to 25)
toxMessageProb = 3
toxDamageMessage = "Your whole body hurts badly."
if(26 to INFINITY)
toxMessageProb = 5
toxDamageMessage = "Your body aches all over, it's driving you mad."
if(toxDamageMessage && prob(toxMessageProb))
src.custom_pain(toxDamageMessage, getToxLoss() >= 15)
if(prob(2))
switch(getToxLoss())
if(1 to 10)
custom_pain("Your body stings slightly.", getToxLoss())
if(11 to 30)
custom_pain("Your body hurts a little.", getToxLoss())
if(31 to 60)
custom_pain("Your whole body hurts badly.", getToxLoss())
if(61 to INFINITY)
custom_pain("Your body aches all over, it's driving you mad.", getToxLoss())