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