diff --git a/code/modules/mob/living/carbon/breathe.dm b/code/modules/mob/living/carbon/breathe.dm
index 98027fb6877..63ce8f01acc 100644
--- a/code/modules/mob/living/carbon/breathe.dm
+++ b/code/modules/mob/living/carbon/breathe.dm
@@ -29,7 +29,7 @@
//First, check if we can breathe at all
if(is_asystole() && !(CE_STABLE in chem_effects)) //crit aka circulatory shock
- losebreath++
+ losebreath = max(2, losebreath + 1)
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index b888f9e88da..db30f1ad7cf 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1950,11 +1950,10 @@
return
var/obj/item/organ/internal/heart/heart = internal_organs_by_name[BP_HEART]
if(istype(heart) && !(heart.status & ORGAN_DEAD))
- var/active_breaths = 0
- if(!nervous_system_failure() && active_breaths)
- visible_message("\The [src] jerks and gasps for breath!")
+ if(!nervous_system_failure())
+ visible_message("[src] jerks and gasps for breath!")
else
- visible_message("\The [src] twitches a bit as \his heart restarts!")
+ visible_message("[src] twitches a bit as \his heart restarts!")
shock_stage = min(shock_stage, 100) // 120 is the point at which the heart stops.
if(getOxyLoss() >= 75)
setOxyLoss(75)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 5801632680c..fc98aa19d32 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -830,35 +830,26 @@
if(stat != DEAD)
if(stat == UNCONSCIOUS && health < maxHealth/2)
var/ovr
+ var/severity
switch(health - maxHealth/2)
- if(-20 to -10)
- ovr = "passage1"
- if(-30 to -20)
- ovr = "passage2"
- if(-40 to -30)
- ovr = "passage3"
- if(-50 to -40)
- ovr = "passage4"
- if(-60 to -50)
- ovr = "passage5"
- if(-70 to -60)
- ovr = "passage6"
- if(-80 to -70)
- ovr = "passage7"
- if(-90 to -80)
- ovr = "passage8"
- if(-95 to -90)
- ovr = "passage9"
- if(-INFINITY to -95)
- ovr = "passage10"
+ if(-20 to -10) severity = 1
+ if(-30 to -20) severity = 2
+ if(-40 to -30) severity = 3
+ if(-50 to -40) severity = 4
+ if(-60 to -50) severity = 5
+ if(-70 to -60) severity = 6
+ if(-80 to -70) severity = 7
+ if(-90 to -80) severity = 8
+ if(-95 to -90) severity = 9
+ if(-INFINITY to -95) severity = 10
+ ovr = "passage[severity]"
if (ovr != last_brute_overlay)
damageoverlay.cut_overlay(last_brute_overlay)
damageoverlay.add_overlay(ovr)
last_brute_overlay = ovr
- else
- //Oxygen damage overlay
- update_oxy_overlay()
+ else
+ update_oxy_overlay()
//Fire and Brute damage overlay (BSSR)
var/hurtdamage = src.getBruteLoss() + src.getFireLoss() + damageoverlaytemp
@@ -1092,15 +1083,16 @@
if(shock_stage >= 30)
if(shock_stage == 30)
visible_message("[src] is having trouble keeping \his eyes open.")
- eye_blurry = max(2, eye_blurry)
- stuttering = max(stuttering, 5)
+ if(prob(30))
+ eye_blurry = max(2, eye_blurry)
+ stuttering = max(stuttering, 5)
if(shock_stage == 40)
custom_pain("[pick("The pain is excruciating", "Please, just end the pain", "Your whole body is going numb")]!", 40, nohalloss = TRUE)
if (shock_stage >= 60)
if(shock_stage == 60)
- visible_message("[src]'s body becomes limp.", "Your body becomes limp.")
+ visible_message("[src]'s body becomes limp.", SPAN_DANGER("Your body becomes limp."))
if (prob(2))
custom_pain("[pick("The pain is excruciating", "Please, just end the pain", "Your whole body is going numb")]!", shock_stage, nohalloss = TRUE)
Weaken(20)
@@ -1344,23 +1336,18 @@
/mob/living/carbon/human/proc/update_oxy_overlay()
var/new_oxy
if(getOxyLoss())
+ var/severity = 0
switch(getOxyLoss())
- if(10 to 20)
- new_oxy = "oxydamageoverlay1"
- if(20 to 25)
- new_oxy = "oxydamageoverlay2"
- if(25 to 30)
- new_oxy = "oxydamageoverlay3"
- if(30 to 35)
- new_oxy = "oxydamageoverlay4"
- if(35 to 40)
- new_oxy = "oxydamageoverlay5"
- if(40 to 45)
- new_oxy = "oxydamageoverlay6"
- if(45 to INFINITY)
- new_oxy = "oxydamageoverlay7"
+ if(10 to 20) severity = 1
+ if(20 to 25) severity = 2
+ if(25 to 30) severity = 3
+ if(30 to 35) severity = 4
+ if(35 to 40) severity = 5
+ if(40 to 45) severity = 6
+ if(45 to INFINITY) severity = 7
+ new_oxy = "oxydamageoverlay[severity]"
- if (new_oxy != last_oxy_overlay)
+ if(new_oxy != last_oxy_overlay)
damageoverlay.cut_overlay(last_oxy_overlay)
damageoverlay.add_overlay(new_oxy)
last_oxy_overlay = new_oxy
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index 7791a01d681..795ae9bf5e4 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -288,7 +288,7 @@
if(length(cword))
rearranged += cword
message ="[prefix][jointext(rearranged," ")]"
- if(losebreath>=5) //Gasping is a mutation, right?
+ if(losebreath >= 5) //Gasping is a mutation, right?
var/prefix=copytext(message,1,2)
if(prefix == ";")
message = copytext(message,2)
@@ -304,7 +304,10 @@
var/gasppoint = rand(2, words.len)
words.Cut(gasppoint)
words[words.len] = "[words[words.len]]..."
- emote("gasp")
+ if(prob(50))
+ emote("gasp")
+ else
+ emote("chokes!")
message = "[prefix][jointext(words," ")]"
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index d571f8b477a..d65ca21c0fb 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -994,6 +994,13 @@
if(can_feel_pain())
flick("weak_pain", pain)
+/mob/living/proc/flash_strong_pain()
+ return
+
+/mob/living/carbon/human/flash_strong_pain()
+ if(can_feel_pain())
+ flick("strong_pain", pain)
+
/mob/proc/Jitter(amount)
jitteriness = max(jitteriness,amount,0)
diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm
index 8eab947284f..e713aacad9c 100644
--- a/code/modules/organs/internal/brain.dm
+++ b/code/modules/organs/internal/brain.dm
@@ -114,8 +114,10 @@
oxygen_reserve = max(0, oxygen_reserve-1)
else
oxygen_reserve = min(initial(oxygen_reserve), oxygen_reserve+1)
+
if(!oxygen_reserve) //(hardcrit)
- owner.Paralyse(3)
+ owner.Paralyse(10)
+
var/can_heal = damage && damage < max_damage && (damage % damage_threshold_value || owner.chem_effects[CE_BRAIN_REGEN] || (!past_damage_threshold(3) && owner.chem_effects[CE_STABLE]))
var/damprob
//Effects of bloodloss
@@ -143,8 +145,8 @@
damprob = owner.chem_effects[CE_STABLE] ? 60 : 100
if(!past_damage_threshold(8) && prob(damprob))
take_internal_damage(1)
- if(!owner.paralysis)
- owner.Paralyse(3,5)
+ if(!owner.paralysis && prob(15))
+ owner.Paralyse(rand(3, 5))
to_chat(owner, "You feel extremely [pick("dizzy","woozy","faint")]...")
if(-(INFINITY) to BLOOD_VOLUME_SURVIVE) // Also see heart.dm, being below this point puts you into cardiac arrest.
owner.eye_blurry = max(owner.eye_blurry,6)
@@ -170,21 +172,22 @@
addtimer(CALLBACK(src, .proc/brain_damage_callback, damage), rand(6, 20) SECONDS, TIMER_UNIQUE)
/obj/item/organ/internal/brain/proc/brain_damage_callback(var/damage) //Confuse them as a somewhat uncommon aftershock. Side note: Only here so a spawn isn't used. Also, for the sake of a unique timer.
- to_chat(owner, "I can't remember which way is forward...")
+ to_chat(owner, "I can't remember which way is forward...")
owner?.confused += damage
/obj/item/organ/internal/brain/proc/handle_severe_brain_damage()
set waitfor = FALSE
healed_threshold = 0
- to_chat(owner, "Where am I...?")
+ to_chat(owner, "Where am I...?")
+ owner.Paralyse(20)
sleep(5 SECONDS)
if(!owner)
return
- to_chat(owner, "What's going on...?")
+ to_chat(owner, "What's going on...?")
sleep(10 SECONDS)
if(!owner)
return
- to_chat(owner, "What happened...?")
+ to_chat(owner, "What happened...?")
alert(owner.find_mob_consciousness(), "You have taken massive brain damage! You will not be able to remember the events leading up to your injury.", "Brain Damaged")
/obj/item/organ/internal/brain/proc/handle_damage_effects()
diff --git a/code/modules/organs/internal/lungs.dm b/code/modules/organs/internal/lungs.dm
index 68057de468a..e00585fdc94 100644
--- a/code/modules/organs/internal/lungs.dm
+++ b/code/modules/organs/internal/lungs.dm
@@ -63,7 +63,7 @@
"You can't breathe!",
"You hear someone gasp for air!",
)
- owner.losebreath = 1
+ owner.losebreath = round(damage/2)
if(is_bruised() && rescued)
if(prob(4))
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 26be27dde44..c6b14a2f49d 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -855,6 +855,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(!clean)
victim.shock_stage += min_broken_damage
+ victim.flash_strong_pain()
removed(null, ignore_children)
@@ -997,13 +998,14 @@ Note that amputating the affected organ does in fact remove the infection from t
return
if(owner)
- var/message = pick("snapped in half", "shattered", "was pulverized")
+ var/message = pick("broke in half", "shattered")
owner.visible_message(\
- "You hear a loud cracking sound coming from \the [owner]!",\
+ "You hear a loud cracking sound coming from \the [owner]!",\
"Something feels like it [message] in your [name]!",\
"You hear a sickening crack!")
if(owner.species && (owner.can_feel_pain()))
owner.emote("scream")
+ owner.flash_strong_pain()
playsound(src.loc, "fracture", 100, 1, -2)
status |= ORGAN_BROKEN
diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm
index dcc05861b5a..cbfee8e6f8b 100644
--- a/code/modules/organs/pain.dm
+++ b/code/modules/organs/pain.dm
@@ -9,50 +9,6 @@ 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 = species.organ_low_burn_message
- if(11 to 90)
- flash_weak_pain()
- msg = species.organ_med_burn_message
- if(91 to 10000)
- flash_pain()
- msg = species.organ_high_burn_message
- else
- switch(amount)
- if(5 to 14)
- msg = species.organ_low_pain_message
- if(15 to 90)
- flash_weak_pain()
- msg = species.organ_med_pain_message
- if(91 to 10000)
- flash_pain()
- msg = species.organ_high_pain_message
- if(msg && (msg != last_pain_message || prob(10)))
- msg = replacetext(msg, "%PARTNAME%", partname)
- last_pain_message = msg
- to_chat(src, msg)
- next_pain_time = world.time + 50
-
-
// message is the custom message to be displayed
// power decides how much painkillers will stop the message
// force means it ignores anti-spam timer
@@ -68,18 +24,21 @@ mob/var/next_pain_time = 0
adjustHalLoss(Ceiling(power/2))
else
affecting.add_pain(Ceiling(power/2))
-
-
- flash_pain(min(round(2*power)+55, 255))
// Anti message spam checks
if(force || (message != last_pain_message) || (world.time >= next_pain_time))
last_pain_message = message
- if(power >= 70)
+ if(power >= 110)
+ flash_strong_pain()
+ to_chat(src, "[message]")
+ else if(power >= 70)
+ flash_pain()
to_chat(src, "[message]")
else if(power >= 40)
+ flash_pain()
to_chat(src, "[message]")
else if(power >= 10)
+ flash_weak_pain()
to_chat(src, "[message]")
else
to_chat(src, "[message]")
@@ -87,64 +46,66 @@ mob/var/next_pain_time = 0
next_pain_time = world.time + (100-power)
/mob/living/carbon/human/proc/handle_pain()
- // not when sleeping
-
if(!can_feel_pain())
return
-
if(stat >= DEAD)
return
- if(analgesic > 70)
+ if(!can_feel_pain())
+ return
+ 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|ORGAN_ROBOT)) continue
+ if(E.status & (ORGAN_DEAD|ORGAN_ROBOT))
+ 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 = "[burning ? species.organ_low_burn_message : species.organ_low_pain_message]"
+ if(11 to 60)
+ msg = "[burning ? species.organ_med_burn_message : species.organ_med_pain_message]"
+ if(70 to 10000)
+ msg = "[burning ? species.organ_high_burn_message : species.organ_high_pain_message]"
+ msg = replacetext(msg, "%PARTNAME%", damaged_organ.name)
+ custom_pain(msg, maxdam, prob(10), damaged_organ, TRUE)
// Damage to internal organs hurts a lot.
for(var/obj/item/organ/internal/I in internal_organs)
- if(I.status & (ORGAN_DEAD|ORGAN_ROBOT))
- continue
- if(prob(2))
+ if(prob(1) && !((I.status & ORGAN_DEAD) || BP_IS_ROBOTIC(I)) && I.damage > 5)
var/obj/item/organ/external/parent = get_organ(I.parent_organ)
- var/painmessage
+ var/pain = 10
+ var/message = "You feel a dull pain in your [parent.name]..."
+ if(I.is_bruised())
+ pain = 25
+ message = "You feel a stinging pain in your [parent.name]."
if(I.is_broken())
- painmessage = "You feel an excrutiating pain in your [parent.name]!"
- else if (I.is_bruised())
- painmessage = "You feel a sharp pain in your [parent.name]..."
- else if (I.is_damaged())
- painmessage = "You feel discomfort in your [parent.name]."
- if(painmessage)
- custom_pain(painmessage, 5, 5)
- //The less hardcoded values, the better.
+ pain = 50
+ message = "You feel a sharp pain in your [parent.name]!"
+ src.custom_pain(message, pain, affecting = parent)
- 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))
- custom_pain(toxDamageMessage, 5, 5)
\ No newline at end of file
+ if(prob(1))
+ switch(getToxLoss())
+ if(5 to 17)
+ custom_pain("Your body stings slightly.", getToxLoss())
+ if(17 to 35)
+ custom_pain("Your body stings.", getToxLoss())
+ if(35 to 60)
+ custom_pain("Your body stings strongly.", getToxLoss())
+ if(60 to 100)
+ custom_pain("Your whole body hurts badly!", getToxLoss())
+ if(100 to INFINITY)
+ custom_pain("Your body aches all over, it's driving you mad!", getToxLoss())
\ No newline at end of file
diff --git a/html/changelogs/mattatlas-painpainpain.yml b/html/changelogs/mattatlas-painpainpain.yml
new file mode 100644
index 00000000000..23c719ce410
--- /dev/null
+++ b/html/changelogs/mattatlas-painpainpain.yml
@@ -0,0 +1,42 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+# balance
+# admin
+# backend
+# security
+# refactor
+#################################
+
+# Your name.
+author: MattAtlas
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - experiment: "The handling of pain and pain messages has been overhauled."
+ - rscadd: "Added a STRONG red pain overlay when you're in a real lot of pain."
diff --git a/icons/mob/screen/full.dmi b/icons/mob/screen/full.dmi
index 97d2a29d930..193c7c138d0 100644
Binary files a/icons/mob/screen/full.dmi and b/icons/mob/screen/full.dmi differ
diff --git a/icons/mob/screen/generic.dmi b/icons/mob/screen/generic.dmi
index 8f7b06badcb..1c8bb6604bb 100644
Binary files a/icons/mob/screen/generic.dmi and b/icons/mob/screen/generic.dmi differ