From 504913cfc834fd807cc6eea62eab5145bea66492 Mon Sep 17 00:00:00 2001 From: Casper3667 <8396443+Casper3667@users.noreply.github.com> Date: Wed, 3 Jun 2026 18:29:05 +0200 Subject: [PATCH] Anatomy Skill take 2 (#22481) A continuation of https://github.com/Aurorastation/Aurora.3/pull/22354 with permission from the original author. The primary changes between the two are more things being visible with no skill as well as some changes to how arterial bleedings are shown. Also a custom pain message if you touch yourself somewhere that hurts, like with broken bones. Original PR description: > This PR provides a relatively simple first implementation for the Anatomy skill, which I have intended to be more broadly useful for any character, beyond just medical characters. The first use of Anatomy skill is for when examining your own injuries, your ranks in the skill determine both the time it takes to self-examine, as well as the quality of the information provided. Previously the injury check was instantaneous, now it takes 5 seconds to perform at its baseline, and all the way down to 1.25 seconds at maximum rank in the skill. > > No ranks in Anatomy: > image > High ranks in Anatomy: > image --------- Signed-off-by: VMSolidus Signed-off-by: Casper3667 <8396443+Casper3667@users.noreply.github.com> Co-authored-by: VMSolidus Co-authored-by: Matt Atlas --- code/datums/skills/occupational/medical.dm | 30 ++++- code/modules/mob/living/carbon/carbon.dm | 108 ++++++++++++++---- html/changelogs/hellfirejag-anatomy-skill.yml | 4 + 3 files changed, 119 insertions(+), 23 deletions(-) create mode 100644 html/changelogs/hellfirejag-anatomy-skill.yml diff --git a/code/datums/skills/occupational/medical.dm b/code/datums/skills/occupational/medical.dm index c749937dd0c..2b2010142bb 100644 --- a/code/datums/skills/occupational/medical.dm +++ b/code/datums/skills/occupational/medical.dm @@ -69,12 +69,38 @@ /singleton/skill/anatomy name = "Anatomy" - description = "Not currently implemented." + description = "Governs the speed at which you can check yourself for injuries, as well as the quality of the information obtained when doing so." maximum_level = SKILL_LEVEL_PROFESSIONAL - uneducated_skill_cap = SKILL_LEVEL_TRAINED + uneducated_skill_cap = SKILL_LEVEL_PROFESSIONAL category = /singleton/skill_category/occupational subcategory = SKILL_SUBCATEGORY_MEDICAL component_type = ANATOMY_SKILL_COMPONENT + skill_level_descriptions = alist( + SKILL_LEVEL_UNFAMILIAR = "You have zero training or knowledge of anatomy.
" \ + + " - You can only distinguish visible damage like cuts and burns.", + SKILL_LEVEL_FAMILIAR = "You have minimal training on the basics of anatomy.
" \ + + "You can diagnose the following conditions:
" \ + + " - External injuries.
" \ + + " - Limb dislocation.
" \ + + " - Simple bleeds.", + SKILL_LEVEL_TRAINED = "You have years of formal training and experience with anatomy.
" \ + + "You can diagnose the following conditions:
" \ + + " - External injuries at a high level of detail.
" \ + + " - Limb dislocation.
" \ + + " - Broken bones.
" \ + + " - Distinguish between simple bleeds and severed arteries.
" \ + + " - Limb necrosis.
" \ + + " - Tag injuries by triage priority.", + SKILL_LEVEL_PROFESSIONAL = "You have extensive training and experience with anatomy.
" \ + + "You can diagnose the following conditions at the highest level of detail:
" \ + + " - External injuries at a high level of detail.
" \ + + " - Limb dislocation.
" \ + + " - Broken bones.
" \ + + " - Distinguish between simple bleeds and severed arteries.
" \ + + " - Limb necrosis.
" \ + + " - Tag injuries by triage priority." + ) + required = TRUE /singleton/skill/forensics name = "Forensics" diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 0354370bb2c..08d6660d9fd 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -220,52 +220,118 @@ var/mob/living/carbon/human/H = src src.visible_message( SPAN_NOTICE("[src] examines [src.get_pronoun("himself")]."), \ - SPAN_NOTICE("You check yourself for injuries.") \ + SPAN_NOTICE("You start checking yourself for injuries.") \ ) + var/anatomy = GET_SKILL_LEVEL(M, ANATOMY_SKILL_COMPONENT) + if (!do_after(M, 5 SECONDS * (1 / (anatomy ? anatomy : 1)))) + to_chat(M, SPAN_WARNING("You must stand still to examine yourself for injuries.")) + return + + // Set to vanilla-equivalent for people without the skill. + if(!anatomy) + anatomy = 2 + var/painful_check = FALSE for(var/obj/item/organ/external/org in H.organs) var/list/status = list() var/brutedamage = org.brute_dam var/burndamage = org.burn_dam + + // Basic Anatomy 1: All the obvious stuff + // Damaged and missing limbs switch(brutedamage) - if(1 to 20) - status += "bruised" - if(20 to 40) - status += "wounded" - if(40 to INFINITY) - status += "mangled" + if(1 to 10) + status += (anatomy < 3 ? "bruised" : "superficially cut") + if(10 to 25) + status += (anatomy < 3 ? "wounded" : "moderately injured") + if(25 to 50) + status += (anatomy < 3 ? "badly injured" : "significantly injured") + if(50 to 75) + status += (anatomy < 3 ? "severely injured" : "mangled and difficult to move") + if(75 to 100) + status += (anatomy < 3 ? "extremely injured" : SPAN_DANGER("horribly mangled, and it feels like it may give out at any moment")) + if(100 to INFINITY) + status += (anatomy < 3 ? "critically injured" : SPAN_DANGER("ruined beyond recognition, and you can barely feel it at all")) switch(burndamage) if(1 to 10) - status += "numb" - if(10 to 40) - status += "blistered" - if(40 to INFINITY) - status += "peeling away" + status += (anatomy < 3 ? "numb" : "lightly burned") + if(10 to 25) + status += (anatomy < 3 ? "blistered" : "moderately burned") + if(25 to 50) + status += (anatomy < 3 ? "peeling away" : "marked by notable partial-thickness burns") + if(50 to 75) + status += (anatomy < 3 ? "visibly charred" : "covered in extensive partial-thickness burns") + if(75 to 100) + status += (anatomy < 3 ? "like black leather" : SPAN_DANGER("burned down to deadened, leathery tissue and looks close to being unrecoverable")) + if(100 to INFINITY) + status += (anatomy < 3 ? "like charcoal" : SPAN_DANGER("charred beyond recognition and may be beyond saving")) if(org.is_stump()) status += SPAN_DANGER("MISSING") if(org.status & ORGAN_MUTATED) status += "weirdly shapen" - if(org.dislocated == 2) - status += "dislocated" - if(org.status & ORGAN_BROKEN) - status += "hurts when touched" - if(org.status & ORGAN_DEAD) - status += "is necrotic" if(!org.is_usable()) status += "dangling uselessly" - if(org.status & ORGAN_BLEEDING) - status += SPAN_DANGER("bleeding") + // End of basic Anatomy 1. + + // Advanced Anatomy 1: Slightly harder. + // Dislocation + // Broken limbs + // Regular and arterial bleeding are vague + // Necrotic is vague + if(org.dislocated == 2) + status += (anatomy >= 2 ? "dislocated" : "hanging oddly") + if(org.status & ORGAN_BROKEN) + status += (anatomy < 3 ? "hurts when touched" : "broken") + painful_check = TRUE + // Anatomy 2 can't distinguish between regular bleeding and arterial. + // Bleeding without arterial + if(anatomy < 3 && ((org.status & ORGAN_BLEEDING) && !(org.status & ORGAN_ARTERY_CUT))) + status += "bleeding" + // Bleeding and arterial + else if(anatomy < 3 && ((org.status & ORGAN_BLEEDING) && (org.status & ORGAN_ARTERY_CUT))) + status += SPAN_DANGER("gushing with blood") + // Arterial without bleeding + else if(anatomy < 3 && (!(org.status & ORGAN_BLEEDING) && (org.status & ORGAN_ARTERY_CUT))) + if(!(org.status & (ORGAN_DEAD | ORGAN_BROKEN))) + status += "hurts when touched" + painful_check = TRUE + status += "swelled and has darkly discolored spots" + + if(anatomy < 3 && (org.status & ORGAN_DEAD)) + status += "feels numb and pale" + // End of advanced Anatomy 1. + + // Anatomy 3: Descriptions start to get more medical. + // Necrotic and arterials are plainly visible + // Bleeding gets an extra description + if(anatomy >= 3) + if(org.status & ORGAN_DEAD) + status += (anatomy < 4 ? "possibly necrotic" : "visible discoloration of skin that indicates tissue necrosis") + // Bleeding & arterial + if((org.status & ORGAN_BLEEDING) && (org.status & ORGAN_ARTERY_CUT)) + status += SPAN_DANGER("spraying blood from a severed artery") + // bleeding and no arterial + else if((org.status & ORGAN_BLEEDING) && !(org.status & ORGAN_ARTERY_CUT)) + status += "bandage-ably cut" + // arterial and no bleeding + else if(!(org.status & ORGAN_BLEEDING) && (org.status & ORGAN_ARTERY_CUT)) + status += SPAN_DANGER("swollen from an internal arterial bleed") + // End of Anatomy 3 + var/output = "" if(length(status)) output = "My [org.name] is [SPAN_WARNING("[english_list(status)].")]" else - output = "My [org.name] feels [SPAN_NOTICE("OK.")]" + output = (anatomy < 3 ? "My [org.name] feels [SPAN_NOTICE("OK.")]" : "My [org.name] has [SPAN_NOTICE("no visible signs of injuries.")]") if(length(org.implants)) output += " [SPAN_WARNING("I can feel something inside it.")]" to_chat(src, output) + if(painful_check) + custom_pain("Pain jolts through your body", 10, FALSE, null, TRUE) + if((isskeleton(H)) && (!H.w_uniform) && (!H.wear_suit)) H.play_xylophone() else diff --git a/html/changelogs/hellfirejag-anatomy-skill.yml b/html/changelogs/hellfirejag-anatomy-skill.yml new file mode 100644 index 00000000000..04b9661a5cf --- /dev/null +++ b/html/changelogs/hellfirejag-anatomy-skill.yml @@ -0,0 +1,4 @@ +author: Hellfirejag, TheGreyWolf +delete-after: True +changes: + - rscadd: "Implemented the Anatomy skill. Anatomy determines the quality of information received when medically examining your own injuries."