From 83e4de8f9dc9b63f4b26ba6151445396dff28db6 Mon Sep 17 00:00:00 2001 From: simb11 <84613249+simb11@users.noreply.github.com> Date: Sun, 8 Sep 2024 10:11:51 +0200 Subject: [PATCH 1/4] pain & painkillers rework (#13310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 999 * pumpumpum * Update colors.dm * 999 * defines & anesthetic fix * обезбол не усыпляет если персонаж испытывает боль * Update life.dm * Update human_movement.dm * убирает усыпление от обезбола, слишком сильный дебафф... * Update carbon.dm * be * 4 * Update pain.dm * Update life.dm * Update living.dm * Update mood.dm * небольшая задержка перед падением * Update carbon.dm * Update carbon.dm * Update carbon.dm --- code/__DEFINES/colors.dm | 6 ++ code/__DEFINES/combat.dm | 6 ++ code/__DEFINES/mob.dm | 8 ++ code/_globalvars/lists/mob.dm | 2 +- code/datums/components/mood.dm | 20 ++-- .../changeling/powers/epinephrine.dm | 1 - .../modes_gameplays/cult/eminence.dm | 1 - code/game/objects/fitness.dm | 4 +- code/game/objects/items/stacks/medical.dm | 2 +- .../objects/items/weapons/implants/implant.dm | 1 - code/game/turfs/simulated/walls.dm | 6 +- code/game/turfs/simulated/walls_reinforced.dm | 2 +- .../clothing/spacesuits/rig/modules/ai.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 4 + code/modules/mob/living/carbon/human/human.dm | 1 - .../mob/living/carbon/human/human_damage.dm | 12 --- .../mob/living/carbon/human/human_movement.dm | 8 +- code/modules/mob/living/carbon/human/life.dm | 85 +++++++-------- code/modules/mob/living/carbon/shock.dm | 98 +++++++++--------- .../special/facehugger/facehugger_playable.dm | 2 +- code/modules/mob/living/living.dm | 21 ++-- code/modules/mob/mob.dm | 9 +- code/modules/organs/external/flesh.dm | 2 +- code/modules/organs/pain.dm | 20 +--- .../reagent_types/Chemistry-Medicine.dm | 8 +- code/modules/surgery/surgery.dm | 2 +- icons/hud/screen_gen.dmi | Bin 102855 -> 103316 bytes 27 files changed, 158 insertions(+), 175 deletions(-) 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 802a3c4de53f5372f4bf6e6347edbb3ceafa4729..8385d0da9f8c121be7d0c3704f79d14e593a9677 100644 GIT binary patch delta 16680 zcmch;cT`hf*De~00s^9<0wP2NK|y+z78DhbCW_KQK%@zwNSACx1rY%S=^{!mLQr}Q z9RZQvODIx92rZ$cogIJg`+nc~#<=5-aql=Mf3Wsmd)2w;eC9Lf+H_0sCpc$Xj+|yhx3oej@g!T%);**;go^P=c4}j9Y8TK9BjEToVd>9<$?H_c+f+X zN#(QTb!+&w?4wY+qRg8M6}Zv*JQ+awXx`)x>8c$6=5v1A!P=ozTr*~HPxi;XIDGfx zv>tOI|E|P?4Ab+8Zpt8_cc7PcErx;VebY&I=coNRb_tj z`{Fa#7k=K?DlPbHB~I2HE(BOx?>?5r*pCsDBzFoV)(&@_j?cUvN|pcyH^n5#KhO-g z_6tYzUb3qQ#m2Q?#NKj(2^%g&0QzB3Pmfn|eQmdUb1Z0veS1s#Tx3?p*a_cb;_R;t zFH@uHp_%9XBl|=PqTs%He{QZtHHc!#bmL_b>nwj<_TDA1UVr1h!geIUhI4!~&Lo4J zR8!Y`_xU@vs88QH`FO%g@Nb`|?z2~4uSM1SHFbyE!R{5j9ro)Geb``gnz{fio87)& z79qC#R#ne3&E$`50ji##gVSy8OhA&8Me)y;w&5WEAUr?fqZ$dj;r3%F@M5VsVD9Yh z`*wuQ9=Y-@dcvlmhy?b+Xgdu*>$3 zLxOnh`EG}m4CduaMfP=h1NPE40UkkyscvqJl+3HN+xoA~UOnU&;f)mN;^vvPZZ{48 zAh0gyBKqrMS^oBCf1P1dwykFQ$00=4(M`ZqGpwX`?DwLpf}r2e2SxtuvLCV&>IOqA z%{Oneiu&%f)E)x^cvPcIp!u6m4r{CYX@{*sB(x5&qQC8O4|smdXA zoTpP;qgmUJACF9ymq^t(qzKdx6h72-(U~US8SK5E?c!6Iz3k?E8#r7UCL(J07OK6j zope9Uq7@sY!5?681co5(53W%+@RNVME>2nbJx(K98NBkw0)h4qB}AIB)A8}$5l+SA zbZ&24jNQfaYK;)^_g?e{)2x(Qktd#x6r!YBY?EBsia?=(6yw=QocW_e^PxBvF5t<<^WTIzvDgCa+W3+GPRj!u&n!>^?Q z<`qlo;7~Cm@U`E{J6wnj-z5~r={p~~-b;TTvE#i503Kf(g2)xEf1{%BZx>#vu)y@P8W5zy$Vu54h&otxkn7;nL9lFp z-ko4vv4P`xTcc<6i2}Zl1OT5Uw1K|6(zar8znstWQ1P9%RekV5{7m)>?3+n=-bi#7 z$-%8;VryD#v~>yPqmNicin+kJ(Dew5b%f?!m3KC*f7}9n%jOT>4B+5eCh+uzAYFJr z{Dy}yC7V?&jp94yqg6568(2Bzi^_U>mEwZ+56r~I5bzw^#7SFIqCT^DklNWiXB5@+ zrS(f8^7TsW^n<|qOOrPKYTs;*HY1FVFDQ;7I715$F0G^lj@8U_<7I#^? z;q;^8m5aO6m>nV)DsN<8&vgWTd0=nj-d3btThPI~u5Z#;oRnUs>&Mh3 zNq3(qTncJ13tQ0h$4)U^gpL5f0wy{KRC$%kx%6~t6IbpN` zm}F7vYeSKf*vorbL=w|A@?fK)2g9pB`?5B5GHB^|p=9`Ta{6lh9Y> zQps*8N(|KVZN!e)^~{*-JaV7~J0<-{ui~5AZoT~JR847w5Ttg6T<+OVbX}OAq+!C= zg5NsMVu7@8wTq~TL*K%=svKDDHdMr+#%Iu~)~<LQKF?cE6NV|A1%KU$@1pfO3DaRWt#eW7GDKLU-Nn1cGpm_h;4bBv}Pq$xj z#0(e1aLp0gyuXz@O(nYfQQUTF>+x`Yu^`Sn+w3Q4jjaxuP^jS|YO`zFq2%-`;UK1~ z_XIPa1+oLikhE+#U?tDm3FRHi^1P2O+syBnH zoj&NP45sxm%mg-@UCZb5iD`#cwqek!UB6o^xlG)UlpH?w_nV;jVB!?cy~Jj}b1`Tf ze34aWkZzyT-mLl)^D8KjLQYpr0Fl^3@$;y7BK$c`-sumiE1$I%fgd9Ndv)&1l*@q` zt8_<05~QKb#lkmc|9Kx#QCpDCUfat+@(Fzh7NbGBy_Og#fI-|}>P$x6^&3g1_H5Xx+=iQfszMK?@zrgbM{NYic>*R)!0K=N z2{lP732CaFRE6r^=E}eKLO_DbfE*RZlzelg`7^l``%)uK;Ky@5ra2!*0_skmD2 zHffYC!L1c&gQ5#+V-EUQ&+RwB}((j{qybqroJkGpHg8RDe*4e+X zH;4nVHvpV+;B_Zae+BH5k_F2DZ#GtGq@y7(BbVlCZR8SD_$f2;NNHpG=!1%cXd4=!^ zn{HQs7Yh=_9IHJ59g3cM@rSHHRj>xq4f(|m^qDJ0dj@vd6z>VUk#+HV)mwG$;!~bi z?R)p}NRwa^v+RrKzV)AZ+$res}K+-uhnV;Tsthi4ZzG?2Om{s&NdF6c+v@1V^$ ziNN4@AU(2QEv9`#k+Iy~xSg6;xtebjbyO8C&qZcApC&6 z8a3-nx;J?Wl$Uh(g^XR z6UkO|T)^{z@4#XJJ}881Ln%SJ8?-pJ(hYR(c=}tbLoK+ur60VXw#QW6Bp@0!n9r) z1kgbs7uY}`oRsJdEK)y8gT6tyO+^oekU;31R6tJZr2ZWhCPeAm^X|VZVOgd3E3!}# zMni*+7}N){>^36}I^Lg4Vq{8u;X&sBWUNB!+z^#q4x0aTr5J2NKTXg$)bTyVGa;2d zI6{r@zpyHwkHmCu12{{AEWQJ%_X; z=NoXNXf}PO+3B4chtTB+A`V_d*W+bpU1@o=muIJDQO3WTAejsz8uU3R6hi<>T??4@ z;(3m{HY1n_r3nf?4K?GN1r@w&@um{zPpbp{3mv$2c*BXRZAoVaRCk2-{#Na7s>XU3 zT>ZV3J|k^K3zR;(F`wx+bIK<{AeNJEa_hj5NRv5?j}mcj?=-l>OE-=@s{Lg=`rBSv z8mZ#nA@3@>G3o*^kSPo*G0wN;fktx1HjK9!$MMQ@Ki%g!sdqy)=MwG3rGG*1Zm3u6 zBo!Ns!4u66L4nsS`x~whL7$BBp(ewKW>-P#HY23BqEfPBdh2KHvt?wPvl@a;|Q4V1>8CQ1cK_hYINP|D6lj6G!>0yM*xKtJvQf)VNSoS$~D}D zMch-Vd9r}9<~^5#!r%*9W~o*8$wus*E5?8^taHH+qxeqNsWCXGv;b;})N^x{Oj}lUg z4}tx39f{jzDi{2<`8|)U0NCbyw{kmx?$G8b^dnjXvHas9byXz!TpZ!%{1ja`NT zNNNqE9+IDGx1!3n)voDK!&>f{*v!Q|S{-Nv7oceDs&$X@L%|eVwft7hjs}w^&u^Re zwyE$cwl9IWzx?gBO0>f-uSt@7?>FM!_aLiLRKT|}UduROXAO61hU)ZvbTA4vgt_KF zSAK4K$BC@ax}GRBZJfz>lBkb#+)AVy40FN0>4XO^`Aw=EQG=c&z6?8tCE%Wx3$9U7 zU%o1fJSU!=EEQ1)?)E;qtCBEOuC>hJ63&X6KAwosNtqjihTSGb9gk-oWFW2Xb;v#m z@NkK793cZlIpY2Ax>OYt%dbJkK_D#hDlQ?PPMOkJdq+?fsD6=d%r06}lzF@;R=dk) z3o7auA&Jrl)Gw(wQF*G~?Edc!*P1!8M zzc^n;gN?}^+%3Ox5UMODMBvWpb%5JWP5ou4$~S83X32f3QKyQu>iQ61yb%qQv6C{7 zlX->UFEyz}ZnLN}FoYHbt}|14{(yt9dm2VPPS^!02dansVVLeH4L4R8?N}N?y25v0 zX!zBvv^^i?>TjAE#P8!r>PkP|8V|#aNiG_8%?-d>wsvp>lJUa&z+49|w2+V3lXVGP zZe=ZO-rb1{ruLWZ()fo2;;;?0Z*R&wRSZ0Q1Y~Efs8)m zGjD*G_k-$CDKf>h(hvpvEIs)PU**h1LzU#?2KCKpz~UXgPc{9?D90)64sHUL;6?Sm zvPV7fj}yS@HKQa#b>6yK>}SMbuD_7e`LwV2)B{u5Xmjvd$P`adaCzs#)Zl+gzWj|E)LET4*>A^E~ zsis}z-Z{TDssK$OD%@BDZ`T5p zvXfw~F|cd|=bKDI>deUP@bfp%m@W{)k2e-uk6obVh#wnzhg*w%3 zzW3U;$hDIteCgD(ziK3s2e=7mp41V%_rwa}Y_lg>XbrDmGrvK(>(I9@V+hDQSc34z z;=^VXzo-OyZ$QPn>ongdQQWV1G5qf{CPEvE^{$S^mic}P?s`-3z{J4z4*8ilfMRl$ zZ%D0xV%|Cj<%K2&KL0IxhI@XSW1lR)!4*%fmZHeJ3Sr=a$En^63x}~U7pS((z{7zm z9KwhQD5)32l~w;Lrr`uU&<}SWI$ET2V39w^3mjqD7kPc~#P$X{S5`z^+}Xx|YB$~hhrb?wdnx-;N^`m?9u zOXe~4+w+kYZq{0|olsE{bkiz0IM8w7cJLv2>sM1gZ@oT@cNhdrBU7Xe-Ip0`CI9gm z_lf@D(Okc1sN|tOb95JKXq$hZ{ zob;53e?K6%2>}Lx0^}bJ>Tw4Bfn`9fdb{b}3w;O(t|J-sw5i_x{!-{J7 z^KXylkFVRg=xkqlwSnxLwp_v2CVW573-YcJManOZ<)06+j)u5DnQlRPfOFI?k3B1G3iQ#=h2MBW$e?b$wew zX%{_llwtvSTxh=Q{)$ja2 ze?<9PANWvf>Zcp@w^gJ3tsiI=u~LkQ^(O;9n^gVun?||AE8#nT0t9JXHZ$=<7uC~S zjU5N05#3q})i4sZae}!wP9~W&Fl(a-Os+c^&l*>AXXAF>AJg>aTwkd18bwr@b7^#h_dofr9}tr&02hJCL1dla;$zaCzgJ2_xy>Ew$ho=IUGTRB<_%61lMs2nU;yadU5`&wkV8gQrAaA6@H zFm1iRCasjj(I_aG^8JbaJbTs7rmfDv+ol_hI#qn_aP1mC#j~W~2CPo`!fo`HiEGC@ z1}3{LNww#uvh)=uWeekuJJ>h-)ut|dK%VbSQq5Jo8daxKFlheO53QJ^Gfyg8a4`jZ zO z5c7ji*Q+{*Y*c2i35R!69!{LhMkV{I^1eiU@NHe?7>pJIdtB#`QhE(gP^f^Q{I9#V4pXI8~&V_k&4~5hfH}Wb?V~`GE|M zu2WX^!UHR$@8tGk_dgLZhyjybHURU@oRZSCOfu$4YW=%oBzN)={$G!u)i1{v0lEYD z&s_eg_0j*C%Yd?JAA;@ZzFhI;HA|9IQtBe?7tFa z`-5{F&=4yo36k6E1D0lhk4C9zlo>Tm#xsS9tcCwH>xYqi)IKqWvE2iyDA)!7 z8^J|@oQEY|R$;6t3)IIjnah7Wg4R`b;Cl2C_`)C|5x18zB{^RV{*qU-@tLN@{UJ9y zudZYDRUwWs{NmQVc!F?|tXvY$mY_U5AB4m$tNL_QjxsS_ z($P)0>Nxz={vM7(jP5FQJU-rGi|MI6Vi0(siNirF>tpreeXqMv?5-C|dmMZW1(7EN( zb}U;{dJkfxb}7a6Ehe=zRgE(=QQT%JcsoMmZKb$H!>>qX#&neV%r61g7MB2>uvv$~ zMe*$emZtY-ABra`mi?S4vE&y3s; zwf|Sb`naIZL|s6sMAa-kZT#Jka_Z%Q!i=_ilBd z_6T*yVud9vB8Cr#~U&G=$Yx z$q6XwNYrgM&wKTLR;!r}WffX%+3?E0$gDNZsp=5u?0mx`_LFpd+4IpC(8f!Hy_d!H znZw%ic|sCx>VMVFZ;3psPo%O1O2q+GHglwJYO(c_JW=2kP0@=VCjIeT0Xh$xHI zk@+UQoc%ew5g>aYJcg-eu?djR)cxb*=f_par{a6{`<)Z0F0yFpwc2rBZtlzOyu7@F zNH0`Z(i#WKrb5pKn2-1|gU$v}V7*g~W>iu#4 z081Y6#Jzmj6*uBEN}5t>b}^s+q#qn~HJ~3Qqz*VboVmc3_$QaMgXfk0s%$O&D_d{h z(!CmM$y8>?8y+7yXNB^=(ZBlYVR7pEn8R36o`%sEKH)j>$m(;qr(!tfJa~M?MDLz< z0>X9t3sdsK`kz56f^1^?`?!JrxMpY_7D;92Wi}##33s)dp300)S z9IE6=QjMU!3kedw8Cf4Z^3BWv5b1mqDm6Fy6b0(>?jZ(=xo()8MSHq*_drKR_}ulm z$`L}AnVc~q_Wk9&5e)mP;APUt#Ai9p$S%WE_hM>%LaY)6K&}Bpm{8uvSzlISB#N}$ zdcZXX46t7Ld*e1!S3S?>*>l%(fb~fDBkJR-tTlR(o_bgU*J;2Pt#*-|h^$td2?8t+ z;szMLA`K5~eEj=Y{0#N82VSR}yh2ZOUw)Dle@CD55^Kz#S7E8*!`&pF`bkf%8N zjlnz26)m`>p43Z=LH>nD9tANn_86(LzI`F!!+k?%;#l?--`g)+=r&8SP$IaL>1o@EW;sq1C%h%!A zd`5?<&K+|t;evaL17P;rcH+Y;)I$}6Pf8z>V0nBJB!yx!nEN#l4&Lxi_r6G3H3UR; zycQL+reSUqa-{d>$5%9_gP-)IJh8zbQ{Vd87g(*4reO^xC@>94Y^3})8C0$7Y<4nhwEr@)U-|EL<@$aqnIhL%btZqHp1J|+chV~ z_|nM&${!y@-odNz2YgOReJ}Aa&6P~1rl0_Au0n%y3WfTfgr>fE0CQ5Dk=mziI9Aa%4#^V&A9*a9*e zEeNe~rwdVuR^s=p?JeTJaEiNn@WnTCA>4hnY&<&ZJ`4RoOM&-du#1;7*-r$>XQW%T z9nRlYcPOG7bUqB_?)+)tR0QXYzwkxY`7#7)E`j^daiD1^d*;mLV^0IdgPCp4c+0=5 zfObripc$EAtSKTRCjtYuegiDW+9W28_O{qDqi3pcCYHZ4BQ@3p!75!tMv;~xYZ;B1))7yrl#e2CF5MmAOkh124#GUT1 z*Io^J0#Zf}hh>YaX?pd_N?b&(C^gb?jB zU+FjdGDse8s(2atL_Ob)NBxDUR%zgg;_tOnkQ02KG08<*|4iKw zwyrX`&W&8i|hUcX%LUzSImtZu(PO_1sr|F zs-)g6mApd;wyT9{-tR7+?$Lbz77ee#pVKQA#iM^efB16tKTEM=lL8}xT+fL=gNTg* z>RcxWYJGrX_7pu>9isVL2|VVr)*aZ}sHOTE#j1z+z5+MZchtY~c}GytsFPb41G z9$ed9yc2fQAv9Lb{A|YWnx}W+xGuOXCiV}9TlOT$*1c?HJ6wtcxRVvepDHBG%vwrt znax_M{1~yQ^Z#DqK3(7=h`Cr;eLi8wByr7zygj$#qOMtU0n+j+6ZnGMU-EZa_n3!A z?+;@3WW4KNP%67eTEZUbw7qw*4@Z9SAtES~dKXG7iBKpi2(=m&b&*8bh1%4A#XVh( z)s>*Us8>tvX?OzM@DS6K@Livp>wzYxo8|fp)HNU09Ym1R)BY1~yn5txbPb$01NhQQ zoJ7^vS5Xv!owS>pcc~ibic((MlKi6IV14OTz|-}+p23eGz&!*ff=v0Y={SsKLAcJ$ z*Wg-xaT$CiLJxMeQ-ZU%?>ZKz*L%B~1#JSgTj>f1W$CGN%%DfuS}n!Mi@Z;ts$C3g zdF@_=1nl#;LpaVqFRU_@NUZ&-#GA%g>HD~dYiPm3Eof+L&adm)>i!23o=l5R+P|`$ zgJ|$RqW`Eycn06dQmEU#?wLweXbDSHzf6$W=t&zYUVxs#?GcKN(tO4rO-mQ;1Jj4> zJ+IKY>Em84uqjd(d+gAjQNX?%LHea>oxi8%!>Vvh)=dwATjei`lAcI?bP2kX5b?=1vl1z0e za(qChD*0CeZ!xK>k3)j`ZnqZ|4;FI4O_Md-Vu?4m_pe{I2I@>PWfHrDDk)7U#QX(> zjj!nwrK^8U5^DF$N0 zkzz?|o4Ssub!BC8N8+|xsxNopYWgP*544JduO})MHp5%x9;n;n6J#++Y2MPhF4mF$ z3dK{LF18BvCGdWhc!dTiMb8#Z!t5~Q_^gASB}bY@x=q(S$T`+J-xe7U<^pZhzrB0d ztwO$^?FOaARek5#$s*B@|3vwdzFzlAn%!D-rCKaTk*O_lu`D+@)k4Y((f&AV^M+t4 zvEc6>7N5XFN_f}f4*2^pGb$Ota)QK2;^&D1=h8r*-=Vs@*|`;K)!C8q z*m^-_$EHgu1nUOfUzUp9djvl5qZ0R1#GJ0Wyr*`??5KV5bJYW2-Z>550o2ipHgLC{n)JP#6Hd3A&=2yEX*muOpV^JoeVPx8T;W_$9({tG zyXyrykF|j^iWFnaz7$fP2>=GDx(hfb2|&6sxYp)-9Yu$TJs})*hibh>NA4k*bQQzo z+yXr<`rN!5_DqL6Du8+9Do{VfP^0K~&mNjs3|KIaT z++SdS_a%wpevQ0Twnb@aTz4^AE#O;~_)0~(rH9e@{`eCzYMk_0dXV}b6q!x3fv~){STAH6}1O8m+#mkB&m8|_Y~VV zYkeQPNe_(_(n|v~q+b&s$~h~lT*?bLvG=0vXuSViWTTLxaR5v7=_J7oJV9UYhGC2td)Mz z4$&U?sT^=F0pUfBi)}EULTpqopMHtt3*@NV%ql*YU>%*WMu9v=&?^e@H44|D>nI#( zN#fHVHP1@^l&5h(A7&weQp)A_@MPs5M+YN=rh~LZizjtUk<^Mk05oeAmX~s(i^gYA z=-v65B5C$KQce9w_AN*c`e+)0IQQHxdQHsiZZguGA_6P^7P>hcw>-29z^+wqk0w1K@7-~TznXw?njH{c zsdyNTGVPqNdR9t!D8c?ZcN%4A3aEi_t+sEcPP(%da}a+gyXRNc4By1uu&B?IX5=_* zb->Bfo8m%aQkHG74Q? z4EWd9lXHqHF~mqzCgzz{lop#|?$MGw($Pc;zM7|ID|v616nt;gWM(wNF~_C9az@fS z1uM&+n$uDnQy?Z2OZ7JfZSMOE(f zWx*~pU!?PfNd%=C>gG%`Ue})wrbPvmv1#)KY7xae)H1XBKzC=v^Zfkhwo;hu-Irsi zAeMj3vRh<*X~to$5J(#SYpF?_t_dcHOEz1!i{*vx+)yY7*;K`My-y5TcS>0I%p8b@NN}w@E)Qpf$&4vnk)B4Mn`c0Hj1LS-_iWTH;BJE5LU{& zk8HE6m4Ei^+c<5Tvgd^N4P}%UYLKS$@4ub%!*#=537<+u6Jq6pew)=SE>?C2hWhbQ z^SC$lB9M0xg~wV=41v%0>(T>MsrN(~JNJHH#jvH?3VSD0%;#JdTu^-qM;u_a#fV~_SN+7aZ$sgEB5$fFztQI!-U z_Y#u?Yjj!5E!?Wpxc5;0lIDSbttjEWz< zqt-YwRrI3-5Ib^I*&D|BC3TxCno7gB#T!_AAZ@`#SMziSENJO5`6kyY=+{k#t`%3v zy;7rG0G%@O@X?JD7F1XR*P+jTWcc=IIxf*5ewS%=GedK2azau^xo-dcVFg|{SLg6< zEakovYWk(CL7)+mY3z7CXE{?97*$?(9s10;3|z_7LnsK;qu$Grz0a;rdH44J?x1|F z!qV&^{5Jfa?{402YtnnKYQ-U#qtSTM>}72Wh^rz>sAxs4K$j`oB3+!FL8(p!T2Y#* z<%8L+=hr{qoA(JSm5BufvBbOKrlr_+u-kP8G1Ad=6_DH0>ka??(WGuhI0hIl9>UVO@6Fcc7aDKacXtd30@@YzL9&;CskkF1 zX`=9zj{}EqIXn3aQ9?88+%fn?&8|GEj^Sa!l9koD$@ks$MwY#cGkr*a%**FL*J*0d z{=Nb-Vn88bBn>kM(sb{0H9eg;9QyP ziRu(7(?T|r_h^0w67v4chZz;w%?4ko3fw~a&Cxut_GzHMjkSkP9$r$dTt0R|aRH&v zfirw&l!u3}qtSg^sKd2FMa$<~ZLpFS9E|#K0G^tym(^-S++MWBB(yb(tHUI&oOiHn(+TU=_H&@iIss#;}oXCS8?bL%rh<@rsA zluOPw)AbpG;vKFxHeWQ)-to3$%db0j^ZZ<;Aj25r_N1Htem?2Y#Z?K(SGAzbX*EdE zyWQ45K%VQkkSd)=SoI>)Z6FJ$_Hf6V#?VBu2cPG@nKQF)14M?YxVV@jQ}+k9ypL5T z?ole%6xAA!Qh7GkiYou>QgJ>ptDCa9#=d7USNV0;HJGeiS0%@GQIupKh$%9BMu7Lf z5@Q{S&`X{nm3)lmXtYpIco?pnZl(J4qq!(Bbk#!L_d>aLfy6VjsueJqKgFM03t}B3 zuw|lJ;qxO($eJodPSj7%s;`by#{3}FL>e-D78`$M*h;$dw}ha!oz zdYjz3Od5=zA;$2*M(V&%E>Y)n_yGB4e$+=;_3LY$ZDZB=a5e30&qm?(6l-)|3({CU zr_%IXk1~GiCf|-llrN4?pMeNeYIA*ar%?EyAp&YbX95e9MLZy`Cctoo(gk;F2Fmm< ziKW4uZ`PbtZro24i{~&b>GgWp3pHk{I(y*R96y`_5@ME_0Kp(Aw@&eI8QO~8k zc%g0>sNw~1Z&PyB?o+NhQ^&rR%JtbaeBQEV8$K$l;{sB&z8%;^G4+S!RDQ$y_T%fI zo>)D3=UOE5r~);kBRNmV#qLW|-<4s8A_0#@li$UwtfDU}f`iC$uB1U2IWC{!dSOJF=;3)t`_JXT@FQKR`yFR>(w;Ht~Fe$yWho|K%xs85RYcf*)vHlwnN6gNa z{c>}(Qn*ZZ3L0NHXfa7<1uVe-ky;sw^0 z@&oIE_zO>O+bP@rEVyrxYC9t;DE`}nNt@MH6V45E(I*Hwmq~q=i(xTcs=2l>_B6g? z@=}$Heq%G5p8^gx@XnBFk3Mw(-2ID>Zy=;i==5RS ze!qzL11MzR?ZNmI<0ay{t*=yE7jUl1D%UzL%m|LLZD zjGJoIqd;G>NWGL=<8_gaM^~kU+Ath|B4C3U1CN6l+|#$)Zq7uZyh*PcXHJqjiH51q zCwj4W55erz$PijKWTwAp$*mZv;+&sj##= zQ)(#4T^6-QzIP(Maar$VdJL5w70`o^ve?2!PKG@M&*%U?TGq@3(1dJggwjh2&{Ag? z&U1P(w=&pNHTWCbP|+O16hT1NG4vR|NJ?%r7{FYSHM5ZNc9DZ-_j3mde z`Wf8;oU?l}dT=U%^f@MPj|ps~4Rt$Vo_QRlpcD3pmJ51v!$VV`BEAEB1kvVsN9V4& zzIMFG*dHjt^>W*Sl_9E(vkHQ-15ebMn`n(LF*mw_=r*dsO#6uB=b*G>XzHNNH9HXh zJBOv-OhO&^AIF9|dIOXwBrCask3lupW@fE{gl~H4Omr&t znw-{s8GiX$C~Ei)N6&m0E7)u{rGmXtLHOC7>{(~{q?+<~@bnA<=8)a4G1@&&Q)Sl$ z~!N)ICi8;InNFC|wBl4D)#@`Rv?h z6ujVxs)9Z>#-2LyhV*wxs2fknCFfxGF!$$6YHC3G5I%m-XFfUKe79&XvJwWMhvo@9 zG5UjZ(^~k=Rd@0LPrp2^BgF2j8-oYP9TMIxEjy_d=9{CIgTYly``c0uX_WHzVv8gA z_$+Ye5GKgh2r|ew1{}1G()|^5`+p)bQ>KQ+bj-c(-@XTSXtH+DlI>zA+)@70QY&k2 zItG4zMN@?f{1Y|DTHnrO)_Cg#l>Fk5|GC#UQD zJN25eIkf}X=6AFrk>g4xBH-Kuz>JwM{#mY1@SYRm#zc4c$9}Gi!Xr~3VVrK_cC@~4 zKIepK=p{?=!A|+y7nK&+oy*p2~N|!+9W+&!E3G@0sA@GfdBIW9LPc-TA(@@ zTzbZ_NfGx{`1^&+1s)|I%?aBQn%ZZ*t5829171KhhW>rlMWP0O5DV0fY*nPy>)bN9 KS$yMB=>Gx-{yNbB delta 16070 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 From 4d0ed298343cdf485ef62359a6e21e03f34dafd1 Mon Sep 17 00:00:00 2001 From: "Alexander V." Date: Wed, 11 Sep 2024 09:49:56 +0300 Subject: [PATCH 2/4] Default game confings (#13526) * Default game configs * Update game_options.txt --- code/controllers/configuration.dm | 6 +++--- config/example/game_options.txt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index bd40c0a082c6..d91db387f411 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -114,11 +114,11 @@ var/global/bridge_secret = null //game_options.txt configs var/health_threshold_softcrit = 0 - var/health_threshold_crit = 0 + var/health_threshold_crit = -50 var/health_threshold_dead = -100 var/organ_health_multiplier = 1 - var/organ_regeneration_multiplier = 1 + var/organ_regeneration_multiplier = 0.75 var/revival_pod_plants = 1 var/revival_cloning = 1 @@ -195,7 +195,7 @@ var/global/bridge_secret = null // The object used for the clickable stat() button. var/obj/effect/statclick/statclick - var/craft_recipes_visibility = FALSE // If false, then users won't see crafting recipes in personal crafting menu until they have all required components and then it will show up. + var/craft_recipes_visibility = TRUE // Show all recipes (TRUE) or only these that have all required components around (FALSE) in craft menu. var/nightshift = FALSE var/list/maplist = list() diff --git a/config/example/game_options.txt b/config/example/game_options.txt index 941e8b3f5548..43534530db24 100644 --- a/config/example/game_options.txt +++ b/config/example/game_options.txt @@ -53,9 +53,9 @@ ANIMAL_DELAY 0 ### CRAFTING ### ## Controls if players can see recipes in menu, even if they don't have required components (this does not affect crafting itself, just visibility). -#CRAFT_RECIPES_VISIBILITY +CRAFT_RECIPES_VISIBILITY ### ETC ### ## If server time is beetween 11 pm and 8 am, lights will become more dim and easy on the eyes, comment to disable -NIGHTSHIFT +#NIGHTSHIFT From 7aa2a22704ae850028d69805596b8c56f55f1a10 Mon Sep 17 00:00:00 2001 From: "Alexander V." Date: Wed, 11 Sep 2024 09:50:43 +0300 Subject: [PATCH 3/4] icon cache path (#13527) --- code/modules/goonchat/browserOutput.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 4c9ed8ed3c8e..6614113a047b 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -1,4 +1,4 @@ -var/global/savefile/iconCache = new /savefile("data/iconCache.sav") +var/global/savefile/iconCache = new /savefile("cache/iconCache.sav") var/global/list/bicon_cache = list() From b182b057e77846e8ef76e05a531dac6eba2ff9ab Mon Sep 17 00:00:00 2001 From: Yashark Date: Wed, 11 Sep 2024 10:20:12 +0300 Subject: [PATCH 4/4] Map fix for detective room: add switch for windows (#13534) --- maps/boxstation/boxstation.dmm | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/maps/boxstation/boxstation.dmm b/maps/boxstation/boxstation.dmm index 0e77a4b5422c..7d2a39a1bd19 100644 --- a/maps/boxstation/boxstation.dmm +++ b/maps/boxstation/boxstation.dmm @@ -7948,6 +7948,11 @@ pixel_y = 10 }, /obj/item/weapon/reagent_containers/food/drinks/flask/detflask, +/obj/machinery/windowtint{ + id = "Detective"; + pixel_x = -28; + pixel_y = -15 + }, /turf/simulated/floor/carpet/red, /area/station/security/detectives_office) "anb" = ( @@ -59174,8 +59179,7 @@ "ciY" = ( /obj/machinery/door/airlock/external{ dir = 4; - dock_tag = "pod4"; - name = "Escape Pod 4" + dock_tag = "pod4" }, /turf/simulated/floor/grid_floor, /area/station/maintenance/engineering) @@ -70168,8 +70172,7 @@ /area/shuttle/escape_pod4/station) "dAo" = ( /obj/machinery/door/airlock/external{ - dir = 4; - name = "Escape Pod 5" + dir = 4 }, /obj/machinery/door/firedoor{ dir = 4