diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm
index 7ce18ed805a8..e6d9b03347e4 100644
--- a/code/__DEFINES/colors.dm
+++ b/code/__DEFINES/colors.dm
@@ -210,3 +210,9 @@
0, 0, 0, 1, \
0, 0, 0, 0)
+
+#define PAINKILLERS_FILTER list(1.25, 0, 0, 0, \
+ 0, 1.25, 0, 0, \
+ 0, 0, 1.25, 0, \
+ 0, 0, 0, 1, \
+ -0.05,-0.05,-0.05, 0)
diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index 6c593f9a140b..99add07ecc06 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -111,3 +111,9 @@
#define MOVESET_TYPE "moveset_type"
#define MOVESET_ROLES "moveset_role"
#define MOVESET_QUALITY "moveset_quality"
+
+//Painkiller effectiveness (for get_painkiller_effect() comparison)
+#define PAINKILLERS_EFFECT_SLIGHT 0.95 //all painkillers.
+#define PAINKILLERS_EFFECT_MEDIUM 0.75 //weak painkillers, allow you to ignore minor pain and not see pain() messages.
+#define PAINKILLERS_EFFECT_HEAVY 0.6 //powerful painkillers, allow you to not see custom_pain() messages.
+#define PAINKILLERS_EFFECT_VERY_HEAVY 0.5 //very powerful painkillers that does not allow the user to determine the location of the injury.
diff --git a/code/__DEFINES/mob.dm b/code/__DEFINES/mob.dm
index 56ca366f294f..8b502f6c90a5 100644
--- a/code/__DEFINES/mob.dm
+++ b/code/__DEFINES/mob.dm
@@ -262,3 +262,11 @@
#define LOGOUT_GHOST 2
#define LOGOUT_REENTER 3
#define LOGOUT_SWAP 4 // not so safe, check other things if available
+
+// traumatic shock levels
+#define TRAUMATIC_SHOCK_MINOR 10
+#define TRAUMATIC_SHOCK_SERIOUS 30
+#define TRAUMATIC_SHOCK_INTENSE 50
+#define TRAUMATIC_SHOCK_MIND_SHATTERING 80
+#define TRAUMATIC_SHOCK_CRITICAL 100
+
diff --git a/code/_globalvars/lists/mob.dm b/code/_globalvars/lists/mob.dm
index 787f75ba6295..d3a0291dd300 100644
--- a/code/_globalvars/lists/mob.dm
+++ b/code/_globalvars/lists/mob.dm
@@ -43,6 +43,6 @@ var/global/list/gods_list = list()
//feel free to add shit to lists below
var/global/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglycerin", "thirteenloko", "nicotine", "ambrosium", "jenkem") //increase heart rate
-var/global/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") //decrease heart rate
+var/global/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin", "tramadol", "oxycodone") //decrease heart rate
var/global/list/heartstopper = list("potassium_phorochloride", "zombie_powder") //this stops the heart
var/global/list/cheartstopper = list("potassium_chloride") //this stops the heart when overdose is met -- c = conditional
diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm
index c724405d2e75..c193ca1d3d5a 100644
--- a/code/datums/components/mood.dm
+++ b/code/datums/components/mood.dm
@@ -355,22 +355,20 @@
return
var/mob/living/carbon/C = parent
- if(C.shock_stage <= 0)
- if(C.traumatic_shock < 10)
- clear_event(null, "pain")
- else
- add_event(null, "pain", /datum/mood_event/mild_pain)
-
+ if(!C.traumatic_shock)
+ clear_event(null, "pain")
return
- switch(C.shock_stage)
- if(0 to 30)
+ switch(C.traumatic_shock)
+ if(0 to TRAUMATIC_SHOCK_MINOR)
+ add_event(null, "pain", /datum/mood_event/mild_pain)
+ if(TRAUMATIC_SHOCK_MINOR to TRAUMATIC_SHOCK_SERIOUS)
add_event(null, "pain", /datum/mood_event/moderate_pain)
- if(30 to 60)
+ if(TRAUMATIC_SHOCK_SERIOUS to TRAUMATIC_SHOCK_INTENSE)
add_event(null, "pain", /datum/mood_event/intense_pain)
- if(60 to 120)
+ if(TRAUMATIC_SHOCK_INTENSE to TRAUMATIC_SHOCK_MIND_SHATTERING)
add_event(null, "pain", /datum/mood_event/unspeakable_pain)
- if(120 to INFINITY)
+ if(TRAUMATIC_SHOCK_MIND_SHATTERING to INFINITY)
add_event(null, "pain", /datum/mood_event/agony)
/datum/component/mood/proc/check_area_mood(datum/source, area/A, atom/OldLoc)
diff --git a/code/game/gamemodes/modes_gameplays/changeling/powers/epinephrine.dm b/code/game/gamemodes/modes_gameplays/changeling/powers/epinephrine.dm
index 78a5f67d957f..2d9dccce4d7a 100644
--- a/code/game/gamemodes/modes_gameplays/changeling/powers/epinephrine.dm
+++ b/code/game/gamemodes/modes_gameplays/changeling/powers/epinephrine.dm
@@ -24,7 +24,6 @@
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.setHalLoss(0)
- H.shock_stage = 0
feedback_add_details("changeling_powers","UNS")
return TRUE
diff --git a/code/game/gamemodes/modes_gameplays/cult/eminence.dm b/code/game/gamemodes/modes_gameplays/cult/eminence.dm
index 79e11755c28a..479f00ba5a01 100644
--- a/code/game/gamemodes/modes_gameplays/cult/eminence.dm
+++ b/code/game/gamemodes/modes_gameplays/cult/eminence.dm
@@ -298,7 +298,6 @@
L.SetDrunkenness(0)
if(iscarbon(L))
var/mob/living/carbon/C = L
- C.shock_stage = 0
if(ishuman(C))
var/mob/living/carbon/human/H = C
H.restore_blood()
diff --git a/code/game/objects/fitness.dm b/code/game/objects/fitness.dm
index 91c343f22443..205967ed0489 100644
--- a/code/game/objects/fitness.dm
+++ b/code/game/objects/fitness.dm
@@ -67,7 +67,7 @@
to_chat(user, "You should get off the [user.buckled] first.")
return
- if(gymnast.halloss > 80 || gymnast.shock_stage > 80)
+ if(gymnast.halloss > 80 || gymnast.traumatic_shock > 80)
to_chat(user, "You are too exausted.")
return
@@ -171,7 +171,7 @@
if(user.buckled && user.buckled != src)
to_chat(user, "You should get off the [user.buckled] first.")
return
- if(user.halloss > 80 || user.shock_stage > 80)
+ if(user.halloss > 80 || user.traumatic_shock > 80)
to_chat(user, "You are too exausted.")
return
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index ca240dd09983..ef348376ea30 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -403,7 +403,7 @@
// Suturing yourself brings much more pain.
var/pain_factor = H == user ? 40 : 20
if(H.stat == CONSCIOUS)
- H.AdjustShockStage(pain_factor)
+ H.adjustHalLoss(pain_factor)
BP.status &= ~ORGAN_ARTERY_CUT
BP.strap()
user.visible_message(
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index c815860a7b5b..9e7ca1dd8f7d 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -321,7 +321,6 @@
if(ishuman(S.imp_in))
var/mob/living/carbon/human/H = S.imp_in
H.setHalLoss(0)
- H.shock_stage = 0
S.imp_in.stat = CONSCIOUS
S.imp_in.SetParalysis(0)
S.imp_in.SetStunned(0)
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 9a9f238d870b..b15b5ce5a10c 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -36,8 +36,8 @@
smooth = SMOOTH_TRUE
// todo:
-// probably we should make /obj/structure/falsewall
-// and /turf/simulated/wall as meta-types not used in the game, and move
+// probably we should make /obj/structure/falsewall
+// and /turf/simulated/wall as meta-types not used in the game, and move
// real walls and falsewalls to subtypes
/turf/simulated/wall/yellow
icon = 'icons/turf/walls/has_false_walls/wall_yellow.dmi'
@@ -447,7 +447,7 @@
//slowdown, user. No need destruct all walls without debuff
if(iscarbon(user))
var/mob/living/carbon/C = user
- C.shock_stage += 5
+ C.adjustHalLoss(15)
user.visible_message("[user] бьет стену!")
user.do_attack_animation(src)
playsound(user, pick(hammer.hitsound), VOL_EFFECTS_MASTER)
diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm
index ccce152c1f22..5acaac26f3f7 100644
--- a/code/game/turfs/simulated/walls_reinforced.dm
+++ b/code/game/turfs/simulated/walls_reinforced.dm
@@ -302,7 +302,7 @@
//slowdown, user. No need destruct all walls without debuff
if(iscarbon(user))
var/mob/living/carbon/C = user
- C.shock_stage += 5
+ C.adjustHalLoss(15)
user.do_attack_animation(src)
user.visible_message("[user] бьет укрепленную стену!",
"Вы пытаетесь снести укрепленную стену!",
diff --git a/code/modules/clothing/spacesuits/rig/modules/ai.dm b/code/modules/clothing/spacesuits/rig/modules/ai.dm
index a2a17e39a2dc..7625147604dd 100644
--- a/code/modules/clothing/spacesuits/rig/modules/ai.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/ai.dm
@@ -366,7 +366,7 @@
if(H.getBruteLoss() > 40)
if(try_inject(H, chem_disp, list("bicaridine", "tricordrazine")))
return
- if(H.traumatic_shock > 40 || H.shock_stage > 40)
+ if(H.traumatic_shock > 40)
if(try_inject(H, chem_disp, list("oxycodone", "tramadol", "paracetamol")))
return
if(H.getToxLoss() > 20)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index e85c61287d78..03a6c0b1b88a 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -231,6 +231,7 @@
// Enough to make us sleep as well
if(SA_pp > SA_sleep_min)
Sleeping(10 SECONDS)
+ analgesic = clamp(analgesic + 5, 0, 10)
// There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
else if(SA_pp > SA_giggle_min)
@@ -841,6 +842,9 @@
if(IsSleeping())
to_chat(src, "You are already sleeping")
return
+ if(traumatic_shock >= TRAUMATIC_SHOCK_SERIOUS)
+ to_chat(src, "The pain keeps you from sleeping.")
+ return
if(tgui_alert(src, "You sure you want to sleep for a while?","Sleep", list("Yes","No")) == "Yes")
SetSleeping(40 SECONDS) //Short nap
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 84a7c5ac593f..0e8eb2d68c2f 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1403,7 +1403,6 @@
maxHealth = species.total_health
if(species.flags[NO_PAIN])
- shock_stage = 0
traumatic_shock = 0
if(species.base_color && default_colour)
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 4eef91fd6e2e..c5a9fb7d0854 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -214,18 +214,6 @@
else
..()
-
-//========== Shock Stage =========
-/mob/living/carbon/human/SetShockStage(amount)
- if(species.flags[NO_PAIN])
- return
- shock_stage = max(amount, 0)
-
-/mob/living/carbon/human/AdjustShockStage(amount)
- if(species.flags[NO_PAIN])
- return
- shock_stage = max(shock_stage + amount, 0)
-
////////////////////////////////////////////
//Returns a list of damaged bodyparts
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index f6fe2ce7e3e1..a5d8a7bf3f34 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -35,17 +35,13 @@
if(embedded_flag)
handle_embedded_objects() // Moving with objects stuck in you can cause bad times.
- var/health_deficiency = (100 - health + halloss)
- if(health_deficiency >= 40)
- tally += health_deficiency / 25
+ if(traumatic_shock >= TRAUMATIC_SHOCK_INTENSE)
+ tally += traumatic_shock * 0.05
var/hungry = NUTRITION_LEVEL_FULL - get_satiation()
if(hungry >= NUTRITION_LEVEL_NORMAL) // Slow down if nutrition <= 40%
tally += hungry / 250 // 1,4 - 2
- if(shock_stage >= 10)
- tally += round(log(3.5, shock_stage), 0.1) // (40 = ~3.0) and (starts at ~1.83)
-
if(bodytemperature < species.cold_level_1)
tally += 1.75 * (species.cold_level_1 - bodytemperature) / 10
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 4d533c1c1c18..cc31588d6b68 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -911,7 +911,11 @@ var/global/list/tourette_bad_words= list(
else
icon_num = 5
- healthdoll.add_overlay(image('icons/hud/screen_gen.dmi',"[BP.body_zone][icon_num]"))
+ if(get_painkiller_effect() <= PAINKILLERS_EFFECT_VERY_HEAVY)
+ healthdoll.icon_state = "health_numb"
+ healthdoll.cut_overlays()
+ else
+ healthdoll.add_overlay(image('icons/hud/screen_gen.dmi',"[BP.body_zone][icon_num]"))
if(!healths)
return
@@ -977,7 +981,7 @@ var/global/list/tourette_bad_words= list(
clear_fullscreen("oxy")
//Fire and Brute damage overlay (BSSR)
- var/hurtdamage = getBruteLoss() + getFireLoss() + damageoverlaytemp
+ var/hurtdamage = ((getBruteLoss() + getFireLoss() + damageoverlaytemp) * get_painkiller_effect())
damageoverlaytemp = 0 // We do this so we can detect if someone hits us or not.
if(hurtdamage)
var/severity = 0
@@ -1097,6 +1101,11 @@ var/global/list/tourette_bad_words= list(
else
animate(client, color = null, time = 5)
+ if(painkiller_overlay_time)
+ animate(client, color = PAINKILLERS_FILTER, time = 5)
+ else
+ animate(client, color = null, time = 5)
+
return TRUE
/mob/living/carbon/human/proc/handle_random_events()
@@ -1155,68 +1164,52 @@ var/global/list/tourette_bad_words= list(
/mob/living/carbon/human/handle_shock()
..()
- if(status_flags & GODMODE) return 0 //godmode
+ if(status_flags & GODMODE) return FALSE //godmode
if(species && species.flags[NO_PAIN])
return
if(analgesic && !reagents.has_reagent("prismaline"))
return // analgesic avoids all traumatic shock temporarily
- if(health < config.health_threshold_softcrit)// health 0 makes you immediately collapse
- shock_stage = max(shock_stage, 61)
+ var/message
- if(traumatic_shock >= 80 && shock_stage <= 150)
- shock_stage += 1
- else if(health < config.health_threshold_softcrit)
- shock_stage = max(shock_stage, 61)
- else
- shock_stage = min(shock_stage, 160)
- shock_stage = max(shock_stage-1, 0)
- return
-
- if(shock_stage == 10)
- to_chat(src, "[pick("It hurts so much!", "You really need some painkillers..", "Dear god, the pain!")]")
+ if(traumatic_shock >= TRAUMATIC_SHOCK_MINOR)
+ message = "[pick("You feel slight pain.", "Ow... That hurts.")]"
- if(shock_stage >= 30)
- if(shock_stage == 30) me_emote("is having trouble keeping their eyes open.")
+ if(traumatic_shock >= TRAUMATIC_SHOCK_SERIOUS)
+ message = "[pick("Ughhh... When will it end?", "You're wincing in pain!", "You really need some painkillers!")]"
blurEyes(2)
stuttering = max(stuttering, 5)
- if(shock_stage == 40)
- to_chat(src, "[pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")]")
-
- if (shock_stage >= 60)
- if(shock_stage == 60)
- visible_message("[src]'s body becomes limp.")
- if (prob(2))
- to_chat(src, "[pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")]")
- Stun(10)
- Weaken(20)
-
- if(shock_stage >= 80)
- if (prob(5))
- to_chat(src, "[pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")]")
- Stun(10)
- Weaken(20)
-
- if(shock_stage >= 120)
- if (prob(2))
+ if(traumatic_shock >= TRAUMATIC_SHOCK_INTENSE)
+ message = "[pick("Stop this pain!", "This pain is unbearable!", "Your whole body is going numb!")]"
+
+ if(traumatic_shock >= TRAUMATIC_SHOCK_MIND_SHATTERING)
+ message = "[pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")]"
+ if(prob(10) && !crawling)
+ Weaken(1)
+
+ if(traumatic_shock >= TRAUMATIC_SHOCK_CRITICAL)
+ if(!crawling)
+ addtimer(CALLBACK(src, PROC_REF(knockdown_by_pain)), 7.5 SECOND)
+ if(prob(10))
to_chat(src, "[pick("You black out!", "You feel like you could die any moment now.", "You're about to lose consciousness.")]")
- Paralyse(5)
+ AdjustSleeping(10)
- if(shock_stage == 150)
- me_emote("can no longer stand, collapsing!")
- Stun(10)
- Weaken(20)
+ if(prob(15) && message)
+ to_chat(src, message)
- if(shock_stage >= 150)
- Stun(10)
- Weaken(20)
+/mob/living/carbon/human/proc/knockdown_by_pain()
+ if(crawling || traumatic_shock <= TRAUMATIC_SHOCK_CRITICAL)
+ return
+ SetCrawling(TRUE)
+ drop_from_inventory(l_hand)
+ drop_from_inventory(r_hand)
/mob/living/carbon/human/proc/handle_heart_beat()
if(pulse == PULSE_NONE) return
- if(pulse == PULSE_2FAST || shock_stage >= 10 || isspaceturf(get_turf(src)))
+ if(pulse == PULSE_2FAST || traumatic_shock >= TRAUMATIC_SHOCK_INTENSE || isspaceturf(get_turf(src)))
var/temp = (5 - pulse)/2
diff --git a/code/modules/mob/living/carbon/shock.dm b/code/modules/mob/living/carbon/shock.dm
index 90d546547665..6c056292ffd8 100644
--- a/code/modules/mob/living/carbon/shock.dm
+++ b/code/modules/mob/living/carbon/shock.dm
@@ -1,57 +1,15 @@
/mob/living/carbon
var/traumatic_shock = 0
- var/shock_stage = 0
+ var/painkiller_overlay_time = 0
// proc to find out in how much pain the mob is at the moment
/mob/living/carbon/proc/updateshock()
traumatic_shock = \
- 1 * getOxyLoss() + \
- 0.7 * getToxLoss() + \
+ 0.5 * getToxLoss() + \
1.5 * getFireLoss() + \
- 1.2 * getBruteLoss() + \
- 1.7 * getCloneLoss() + \
- 2 * halloss
-
- var/painkiller_effectiveness = 1.0
- if(reagents.has_reagent("prismaline"))
- painkiller_effectiveness = 0.3
-
- if(reagents.has_reagent("alkysine"))
- traumatic_shock -= 10 * painkiller_effectiveness
- shock_stage -= 1 * painkiller_effectiveness
- if(reagents.has_reagent("dextromethorphan"))
- traumatic_shock -= 10 * painkiller_effectiveness
- shock_stage -= 1 * painkiller_effectiveness
- if(reagents.has_reagent("jenkem"))
- traumatic_shock -= 15 * painkiller_effectiveness
- shock_stage -= 1.5 * painkiller_effectiveness
- if(reagents.has_reagent("inaprovaline"))
- traumatic_shock -= 25 * painkiller_effectiveness
- shock_stage -= 2.5 * painkiller_effectiveness
- if(reagents.has_reagent("ambrosium"))
- traumatic_shock -= 30 * painkiller_effectiveness
- shock_stage -= 3 * painkiller_effectiveness
- if(reagents.has_reagent("synaptizine"))
- traumatic_shock -= 40 * painkiller_effectiveness
- shock_stage -= 4 * painkiller_effectiveness
- if(reagents.has_reagent("paracetamol"))
- traumatic_shock -= 50 * painkiller_effectiveness
- shock_stage -= 5 * painkiller_effectiveness
- if(reagents.has_reagent("space_drugs"))
- traumatic_shock -= 60 * painkiller_effectiveness
- shock_stage -= 6 * painkiller_effectiveness
- if(reagents.has_reagent("tramadol") || reagents.has_reagent("endorphine"))
- traumatic_shock -= 80 * painkiller_effectiveness
- shock_stage -= 8 * painkiller_effectiveness
- if(reagents.has_reagent("oxycodone"))
- traumatic_shock -= 200 * painkiller_effectiveness
- shock_stage -= 20 * painkiller_effectiveness
- if(slurring && drunkenness > DRUNKENNESS_SLUR)
- traumatic_shock -= min(drunkenness - DRUNKENNESS_SLUR, 40)
- shock_stage -= min(drunkenness - DRUNKENNESS_SLUR, 40)
- if(analgesic && !reagents.has_reagent("prismaline"))
- traumatic_shock = 0
- shock_stage = 0
+ 1.0 * getBruteLoss() + \
+ 1.0 * getCloneLoss() + \
+ 1.0 * halloss
// broken or ripped off bodyparts will add quite a bit of pain
if(ishuman(src))
@@ -64,8 +22,12 @@
if(BP.status & ORGAN_SPLINTED)
traumatic_shock -= 25
+ traumatic_shock *= get_painkiller_effect()
+
if(traumatic_shock < 0)
traumatic_shock = 0
+ if(painkiller_overlay_time > 0)
+ painkiller_overlay_time--
play_pain_sound()
@@ -93,7 +55,7 @@
return
var/pain_sound_name
- var/current_health = round(100 - (traumatic_shock - (getOxyLoss() + 0.7 * getToxLoss()))) // don't consider suffocation and toxins
+ var/current_health = round(100 - traumatic_shock)
switch(current_health)
if(80 to 99)
if(HAS_TRAIT(src, TRAIT_LOW_PAIN_THRESHOLD) && prob(20))
@@ -116,3 +78,43 @@
last_pain_emote_sound = world.time + (HAS_TRAIT(src, TRAIT_LOW_PAIN_THRESHOLD) ? rand(15 SECONDS, 30 SECONDS) : rand(30 SECONDS, 60 SECONDS))
if(pain_sound_name == "scream") // don't cry out in pain too often
last_pain_emote_sound += (HAS_TRAIT(src, TRAIT_LOW_PAIN_THRESHOLD) ? rand(5 SECONDS, 10 SECONDS) : rand(10 SECONDS, 20 SECONDS))
+
+/mob/living/carbon/proc/painkiller_byeffect(chance, yawn_chance)
+ if(stat != CONSCIOUS)
+ return
+ if(traumatic_shock >= TRAUMATIC_SHOCK_MINOR)
+ return
+ if(!prob(chance))
+ return
+ adjustBlurriness(3)
+ painkiller_overlay_time += 3
+ to_chat(src, "[pick("Вы невольно закрываете глаза.", "Вы чувствуете себя подавленным.", "Вы чувствуете себя расслабленным.", "Вы чувствуете себя размякшим.", "Вы ощущаете сонливость.", "Вы чувствуете себя уставшим.", "Вы чувствуете, как силы покидают вас.", "Вам сложно держаться на ногах.")]")
+ if(dizziness <= 5)
+ make_dizzy(150)
+ if(prob(yawn_chance))
+ emote("yawn")
+
+/mob/living/carbon/proc/get_painkiller_effect()
+ var/painkiller_effect = 1.0
+ var/painkiller_multiplier = 1.0
+ if(reagents.has_reagent("prismaline"))
+ painkiller_multiplier = 3
+
+ if(reagents.has_reagent("stimulants"))
+ painkiller_effect *= min(0.1 * painkiller_multiplier, 1)
+ else if(reagents.has_reagent("oxycodone"))
+ painkiller_effect *= min(0.3 * painkiller_multiplier, 1)
+ else if(reagents.has_reagent("tramadol") || reagents.has_reagent("endorphine"))
+ painkiller_effect *= min(0.5 * painkiller_multiplier, 1)
+ else if(druggy)
+ painkiller_effect *= min(0.6 * painkiller_multiplier, 1)
+ else if(reagents.has_reagent("paracetamol") || reagents.has_reagent("synaptizine"))
+ painkiller_effect *= min(0.75 * painkiller_multiplier, 1)
+ else if(reagents.has_reagent("inaprovaline"))
+ painkiller_effect *= min(0.8 * painkiller_multiplier, 1)
+ if(slurring && drunkenness > DRUNKENNESS_SLUR)
+ painkiller_effect *= min((DRUNKENNESS_PASS_OUT - drunkenness) / 1000, 1)
+ if(analgesic && !reagents.has_reagent("prismaline"))
+ painkiller_effect = 0
+
+ return painkiller_effect
diff --git a/code/modules/mob/living/carbon/xenomorph/special/facehugger/facehugger_playable.dm b/code/modules/mob/living/carbon/xenomorph/special/facehugger/facehugger_playable.dm
index 5a1986a76e72..5664706afae1 100644
--- a/code/modules/mob/living/carbon/xenomorph/special/facehugger/facehugger_playable.dm
+++ b/code/modules/mob/living/carbon/xenomorph/special/facehugger/facehugger_playable.dm
@@ -245,7 +245,7 @@ This is chestburster mechanic for damaging
last_bite = world.time
playsound(src, 'sound/weapons/bite.ogg', VOL_EFFECTS_MASTER)
H.apply_damage(rand(7, 14), BRUTE, BP_CHEST)
- H.SetShockStage(20)
+ H.setHalLoss(20)
H.Stun(1)
H.Weaken(1)
H.emote("scream")
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 49eff1197eea..e90ff9d4bf9c 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -576,16 +576,12 @@
SetDrunkenness(0)
- if(iscarbon(src))
- var/mob/living/carbon/C = src
- C.shock_stage = 0
-
- if(ishuman(src))
- var/mob/living/carbon/human/H = src
- H.restore_blood()
- H.full_prosthetic = null
- var/obj/item/organ/internal/heart/Heart = H.organs_by_name[O_HEART]
- Heart?.heart_normalize()
+ if(ishuman(src))
+ var/mob/living/carbon/human/H = src
+ H.restore_blood()
+ H.full_prosthetic = null
+ var/obj/item/organ/internal/heart/Heart = H.organs_by_name[O_HEART]
+ Heart?.heart_normalize()
restore_all_bodyparts()
restore_all_organs()
@@ -1060,6 +1056,11 @@
return
if(crawling)
+ if(iscarbon(src))
+ var/mob/living/carbon/C = src
+ if(C.traumatic_shock >= TRAUMATIC_SHOCK_CRITICAL)
+ to_chat(C, "I'm in so much pain! I can not get up!")
+ return
crawl_getup = TRUE
if(do_after(src, 10, target = src))
crawl_getup = FALSE
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 084f7a88ba8f..3299899d139f 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -882,13 +882,6 @@ note dizziness decrements automatically in the mob's Life() proc.
return
stuttering = max(amount, 0)
-//========== Shock Stage =========
-/mob/proc/AdjustShockStage(amount)
- return
-
-/mob/proc/SetShockStage(amount)
- return
-
//======= Bodytemperature =======
/mob/proc/adjust_bodytemperature(amount, min_temp=0, max_temp=INFINITY)
if(amount > 0)
@@ -971,7 +964,7 @@ note dizziness decrements automatically in the mob's Life() proc.
for(var/datum/wound/wound in BP.wounds)
wound.embedded_objects -= selection
- H.AdjustShockStage(20)
+ H.adjustHalLoss(20)
BP.take_damage((selection.w_class * 3), null, DAM_EDGE, "Embedded object extraction")
if(prob(selection.w_class * 5) && BP.sever_artery()) // I'M SO ANEMIC I COULD JUST -DIE-.
diff --git a/code/modules/organs/external/flesh.dm b/code/modules/organs/external/flesh.dm
index 00fdf6d786d9..222af999b0a3 100644
--- a/code/modules/organs/external/flesh.dm
+++ b/code/modules/organs/external/flesh.dm
@@ -130,7 +130,7 @@
var/spillover = cur_damage + damage_amt + BP.burn_dam + burn - BP.max_damage // excess damage goes off into shock_stage, this var also can prevent dismemberment, if result is negative.
if(spillover > 0 && !BP.species.flags[IS_SYNTHETIC])
- BP.owner.shock_stage += spillover * ORGAN_DAMAGE_SPILLOVER_MULTIPLIER
+ BP.owner.halloss += spillover * ORGAN_DAMAGE_SPILLOVER_MULTIPLIER
// sync the organ's damage with its wounds
BP.update_damages()
diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm
index 36efb449d376..bac59de50bd0 100644
--- a/code/modules/organs/pain.dm
+++ b/code/modules/organs/pain.dm
@@ -6,14 +6,10 @@
// partname is the name of a body part
// amount is a num from 1 to 100
-/mob/living/carbon/proc/on_painkillers()
- return reagents.has_reagent("paracetamol") || reagents.has_reagent("tramadol") || reagents.has_reagent("oxycodone") || reagents.has_reagent("endorphine")
-
/mob/living/carbon/proc/pain(partname, amount, force, burning = 0)
- if(stat >= DEAD) return
- if(on_painkillers())
+ if(stat >= DEAD)
return
- if(analgesic)
+ if(get_painkiller_effect() <= PAINKILLERS_EFFECT_MEDIUM)
return
if(world.time < next_pain_time && !force)
return
@@ -50,13 +46,9 @@
/mob/living/carbon/human/proc/custom_pain(message, flash_strength)
if(stat != CONSCIOUS)
return
-
if(species && species.flags[NO_PAIN])
return
-
- if(on_painkillers())
- return
- if(analgesic)
+ if(get_painkiller_effect() <= PAINKILLERS_EFFECT_HEAVY)
return
var/msg = "[message]"
if(flash_strength >= 1)
@@ -70,15 +62,11 @@
/mob/living/carbon/human/proc/handle_pain()
// not when sleeping
-
if(species && species.flags[NO_PAIN])
return
-
if(stat >= DEAD)
return
- if(on_painkillers())
- return
- if(analgesic)
+ if(get_painkiller_effect() <= PAINKILLERS_EFFECT_HEAVY)
return
var/maxdam = 0
var/obj/item/organ/external/damaged_organ = null
diff --git a/code/modules/reagents/reagent_types/Chemistry-Medicine.dm b/code/modules/reagents/reagent_types/Chemistry-Medicine.dm
index 6988cbaf5c7b..e912208a51ad 100644
--- a/code/modules/reagents/reagent_types/Chemistry-Medicine.dm
+++ b/code/modules/reagents/reagent_types/Chemistry-Medicine.dm
@@ -111,6 +111,9 @@
M.adjustHalLoss(-4)
if(volume > overdose)
M.hallucination = max(M.hallucination, 2)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.painkiller_byeffect(5, 15)
/datum/reagent/oxycodone
name = "Oxycodone"
@@ -128,6 +131,9 @@
if(volume > overdose)
M.adjustDrugginess(1)
M.hallucination = max(M.hallucination, 3)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.painkiller_byeffect(10, 25)
/datum/reagent/endorphine
name = "Endorphine"
@@ -560,7 +566,6 @@
M.AdjustWeakened(-3)
var/mob/living/carbon/human/H = M
H.adjustHalLoss(-30)
- H.shock_stage -= 20
if(M.bodytemperature < 310) //standard body temperature
M.adjustHalLoss(15)
@@ -773,7 +778,6 @@
M.AdjustWeakened(-3)
var/mob/living/carbon/human/H = M
H.adjustHalLoss(-30)
- H.shock_stage -= 20
/datum/reagent/nanocalcium
name = "Nano-Calcium"
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index c36efca15577..c60f139aee9a 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -167,7 +167,7 @@
var/mob/living/carbon/human/H = M
if(!H.species.flags[NO_PAIN] && !HAS_TRAIT(H, TRAIT_IMMOBILIZED))
H.adjustHalLoss(25)
- if(prob(H.halloss) && !H.incapacitated(NONE))
+ if(prob(H.traumatic_shock) && !H.incapacitated(NONE))
to_chat(user, "The patient is writhing in pain, this interferes with the operation!")
S.fail_step(user, H, target_zone, tool) //patient movements due to pain interfere with surgery
if(prob(S.tool_quality(tool)) && tool.use_tool(M,user, step_duration, volume=100, required_skills_override = S.required_skills, skills_speed_bonus = S.skills_speed_bonus) && user.get_targetzone() && target_zone == user.get_targetzone())
diff --git a/icons/hud/screen_gen.dmi b/icons/hud/screen_gen.dmi
index 802a3c4de53f..8385d0da9f8c 100644
Binary files a/icons/hud/screen_gen.dmi and b/icons/hud/screen_gen.dmi differ