diff --git a/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm b/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm index 25ed81365c5e..928aea5fb269 100644 --- a/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm +++ b/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm @@ -1146,10 +1146,7 @@ icon_state = "warningline_white"; dir = 8 }, -/obj/machinery/vending/medical{ - req_access = list("theatre"); - products = list(/obj/item/stack/medical/gauze=0,/obj/item/reagent_containers/syringe=7,/obj/item/reagent_containers/dropper=3,/obj/item/healthanalyzer=0,/obj/item/wrench/medical=0,/obj/item/stack/sticky_tape/surgical=0,/obj/item/healthanalyzer/wound=0,/obj/item/stack/medical/ointment=0,/obj/item/stack/medical/suture=1,/obj/item/stack/medical/bone_gel/four=1,/obj/item/cane/white=2) - }, +/obj/machinery/vending/medical/infested_frigate, /turf/open/floor/pod/dark, /area/ruin/space/has_grav/infested_frigate) "sQ" = ( diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm index 5b77598d0550..48857e26ff76 100644 --- a/_maps/map_files/NorthStar/north_star.dmm +++ b/_maps/map_files/NorthStar/north_star.dmm @@ -28139,6 +28139,13 @@ /obj/structure/stairs/west, /turf/open/floor/pod/light, /area/station/maintenance/floor1/port) +"hAV" = ( +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/structure/table/glass, +/obj/item/bonesetter, +/obj/item/stack/medical/bone_gel, +/turf/open/floor/iron/white/textured, +/area/station/medical/treatment_center) "hBe" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /turf/open/floor/iron/white, @@ -71649,7 +71656,7 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /obj/structure/table/glass, /obj/item/bonesetter, -/obj/item/stack/medical/bone_gel/four, +/obj/item/stack/medical/bone_gel, /obj/structure/sign/departments/medbay/alt/directional/south, /turf/open/floor/iron/white/textured, /area/station/medical/treatment_center) diff --git a/_maps/shuttles/emergency_lance.dmm b/_maps/shuttles/emergency_lance.dmm index dcfd9ceb6f38..191a65e6b934 100644 --- a/_maps/shuttles/emergency_lance.dmm +++ b/_maps/shuttles/emergency_lance.dmm @@ -1509,7 +1509,7 @@ /obj/item/stack/medical/ointment{ pixel_x = 5 }, -/obj/item/stack/medical/bone_gel/four, +/obj/item/stack/medical/bone_gel, /turf/open/floor/iron/dark/textured, /area/shuttle/escape) "WI" = ( diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index 693b82b20900..18a07c0d0197 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -241,6 +241,9 @@ #define SPT_PROB(prob_per_second_percent, seconds_per_tick) (prob(100*SPT_PROB_RATE((prob_per_second_percent)/100, (seconds_per_tick)))) // ) +// This value per these many units. Very unnecessary but helpful for readability (For example wanting 30 units of synthflesh to heal 50 damage - VALUE_PER(50, 30)) +#define VALUE_PER(value, per) (value / per) + #define GET_TRUE_DIST(a, b) (a == null || b == null) ? -1 : max(abs(a.x -b.x), abs(a.y-b.y), abs(a.z-b.z)) //We used to use linear regression to approximate the answer, but Mloc realized this was actually faster. diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index cfb3a2411196..f762929ba54b 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -93,6 +93,8 @@ #define REAGENT_NO_RANDOM_RECIPE (1<<7) ///Does this reagent clean things? #define REAGENT_CLEANS (1<<8) +///Does this reagent affect wounds? Used to check if some procs should be ran. +#define REAGENT_AFFECTS_WOUNDS (1<<9) //Chemical reaction flags, for determining reaction specialties ///Convert into impure/pure on reaction completion diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm index fb0b38e44be4..c6729edf7f3f 100644 --- a/code/datums/wounds/_wounds.dm +++ b/code/datums/wounds/_wounds.dm @@ -548,7 +548,7 @@ return base_xadone_progress_to_qdel * severity /// When synthflesh is applied to the victim, we call this. No sense in setting up an entire chem reaction system for wounds when we only care for a few chems. Probably will change in the future -/datum/wound/proc/on_synthflesh(power) +/datum/wound/proc/on_synthflesh(reac_volume) return /// Called when the patient is undergoing stasis, so that having fully treated a wound doesn't make you sit there helplessly until you think to unbuckle them @@ -642,18 +642,21 @@ return "[desc]." /datum/wound/proc/get_scanner_description(mob/user) - return "Type: [name]\nSeverity: [severity_text()]\nDescription: [desc]\nRecommended Treatment: [treat_text]" + return "Type: [name]\nSeverity: [severity_text(simple = FALSE)]\nDescription: [desc]\nRecommended Treatment: [treat_text]" -/datum/wound/proc/severity_text() +/datum/wound/proc/get_simple_scanner_description(mob/user) + return "[name] detected!\nRisk: [severity_text(simple = TRUE)]\nDescription: [simple_desc ? simple_desc : desc]\nTreatment Guide: [simple_treat_text]\nHomemade Remedies: [homemade_treat_text]" + +/datum/wound/proc/severity_text(simple = FALSE) switch(severity) if(WOUND_SEVERITY_TRIVIAL) return "Trivial" if(WOUND_SEVERITY_MODERATE) - return "Moderate" + return "Moderate" + (simple ? "!" : "") if(WOUND_SEVERITY_SEVERE) - return "Severe" + return "Severe" + (simple ? "!!" : "") if(WOUND_SEVERITY_CRITICAL) - return "Critical" + return "Critical" + (simple ? "!!!" : "") /// Returns TRUE if our limb is the head or chest, FALSE otherwise. /// Essential in the sense of "we cannot live without it". diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm index f0bc8e11348d..c84c0598b642 100644 --- a/code/datums/wounds/bones.dm +++ b/code/datums/wounds/bones.dm @@ -195,6 +195,10 @@ status_effect_type = /datum/status_effect/wound/blunt/bone/moderate scar_keyword = "dislocate" + simple_desc = "Patient's bone has been dislocated, causing limping or reduced dexterity." + simple_treat_text = "Bandaging the wound will reduce its impact until treated with a bonesetter. Most commonly, it is treated by aggressively grabbing someone and helpfully wrenching the limb in place, though there's room for malfeasance when doing this." + homemade_treat_text = "Besides bandaging and wrenching, bone setters can be printed in lathes and utilized on oneself at the cost of great pain. As a last resort, crushing the patient with a firelock has sometimes been noted to fix their dislocated limb." + /datum/wound_pregen_data/bone/dislocate abstract = FALSE @@ -330,6 +334,11 @@ wound_flags = (ACCEPTS_GAUZE | MANGLES_INTERIOR) regen_ticks_needed = 120 // ticks every 2 seconds, 240 seconds, so roughly 4 minutes default + simple_desc = "Patient's bone has cracked in the middle, drastically reducing limb functionality." + simple_treat_text = "Bandaging the wound will reduce its impact until surgically treated with bone gel and surgical tape." + homemade_treat_text = "Bone gel and surgical tape may be applied directly to the wound, though this is quite difficult for most people to do so individually unless they've dosed themselves with one or more painkillers (Morphine and Miner's Salve have been known to help)" + + /datum/wound_pregen_data/bone/hairline abstract = FALSE @@ -361,6 +370,10 @@ wound_flags = (ACCEPTS_GAUZE | MANGLES_INTERIOR) regen_ticks_needed = 240 // ticks every 2 seconds, 480 seconds, so roughly 8 minutes default + simple_desc = "Patient's bones have effectively shattered completely, causing total immobilization of the limb." + simple_treat_text = "Bandaging the wound will slightly reduce its impact until surgically treated with bone gel and surgical tape." + homemade_treat_text = "Although this is extremely difficult and slow to function, Bone gel and surgical tape may be applied directly to the wound, though this is nigh-impossible for most people to do so individually unless they've dosed themselves with one or more painkillers (Morphine and Miner's Salve have been known to help)" + /datum/wound_pregen_data/bone/compound abstract = FALSE diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index 96b0b108cfdd..42203c4f2a70 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -47,14 +47,9 @@ victim.visible_message(span_danger("The infection on the remnants of [victim]'s [limb.plaintext_zone] shift and bubble nauseatingly!"), span_warning("You can feel the infection on the remnants of your [limb.plaintext_zone] coursing through your veins!"), vision_distance = COMBAT_MESSAGE_RANGE) return - if(victim.reagents) - if(victim.reagents.has_reagent(/datum/reagent/medicine/antipathogenic/spaceacillin)) - sanitization += 0.9 - if(victim.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine/)) - sanitization += 0.9 - if(victim.reagents.has_reagent(/datum/reagent/medicine/mine_salve)) - sanitization += 0.3 - flesh_healing += 0.5 + for(var/datum/reagent/reagent as anything in victim.reagents.reagent_list) + if(reagent.chemical_flags & REAGENT_AFFECTS_WOUNDS) + reagent.on_burn_wound_processing() if(limb.current_gauze) limb.seep_gauze(WOUND_BURN_SANITIZATION_RATE * seconds_per_tick) @@ -262,8 +257,8 @@ if(sanitization > 0) infestation = max(infestation - (0.1 * WOUND_BURN_SANITIZATION_RATE * seconds_per_tick), 0) -/datum/wound/burn/flesh/on_synthflesh(amount) - flesh_healing += amount * 0.5 // 20u patch will heal 10 flesh standard +/datum/wound/burn/flesh/on_synthflesh(reac_volume) + flesh_healing += reac_volume * 0.5 // 20u patch will heal 10 flesh standard /datum/wound_pregen_data/flesh_burn abstract = TRUE @@ -284,11 +279,16 @@ examine_desc = "is badly burned and breaking out in blisters" occur_text = "breaks out with violent red burns" severity = WOUND_SEVERITY_MODERATE + damage_multiplier_penalty = 1.1 threshold_penalty = 30 // burns cause significant decrease in limb integrity compared to other wounds status_effect_type = /datum/status_effect/wound/burn/flesh/moderate flesh_damage = 5 scar_keyword = "burnmoderate" + simple_desc = "Patient's skin is burned, weakening the limb and multiplying percieved damage!" + simple_treat_text = "Ointment will speed up recovery, as will regenerative mesh. Risk of infection is negligible." + homemade_treat_text = "Healthy tea will speed up recovery. Salt, or preferably a salt-water mixture, will sanitize the wound, but the former will cause skin irritation, increasing the risk of infection." + /datum/wound_pregen_data/flesh_burn/second_degree abstract = FALSE @@ -303,6 +303,7 @@ examine_desc = "appears seriously charred, with aggressive red splotches" occur_text = "chars rapidly, exposing ruined tissue and spreading angry red burns" severity = WOUND_SEVERITY_SEVERE + damage_multiplier_penalty = 1.2 threshold_penalty = 40 status_effect_type = /datum/status_effect/wound/burn/flesh/severe treatable_by = list(/obj/item/flashlight/pen/paramedic, /obj/item/stack/medical/ointment, /obj/item/stack/medical/mesh) @@ -310,6 +311,10 @@ flesh_damage = 12.5 scar_keyword = "burnsevere" + simple_desc = "Patient's skin is badly burned, significantly weakening the limb and compounding further damage!!" + simple_treat_text = "Bandages will speed up recovery, as will ointment or regenerative mesh. Spaceacilin, sterilizine, and 'Miner's Salve' will help with infection." + homemade_treat_text = "Healthy tea will speed up recovery. Salt, or preferably a salt-water mixture, will sanitize the wound, but the former especially will cause skin irritation and dehydration, speeding up infection. Space Cleaner can be used as disinfectant in a pinch." + /datum/wound_pregen_data/flesh_burn/third_degree abstract = FALSE @@ -324,6 +329,7 @@ examine_desc = "is a ruined mess of blanched bone, melted fat, and charred tissue" occur_text = "vaporizes as flesh, bone, and fat melt together in a horrifying mess" severity = WOUND_SEVERITY_CRITICAL + damage_multiplier_penalty = 1.3 sound_effect = 'sound/effects/wounds/sizzle2.ogg' threshold_penalty = 80 status_effect_type = /datum/status_effect/wound/burn/flesh/critical @@ -332,6 +338,10 @@ flesh_damage = 20 scar_keyword = "burncritical" + simple_desc = "Patient's skin is destroyed and tissue charred, leaving the limb with almost no integrity and a drastic chance of infection!!!" + simple_treat_text = "Immediately bandage the wound and treat it with ointment or regenerative mesh. Spaceacilin, sterilizine, or 'Miner's Salve' will stave off infection. Seek professional care immediately, before sepsis sets in and the wound becomes untreatable." + homemade_treat_text = "Healthy tea will help with recovery. A salt-water mixture, topically applied, might help stave off infection in the short term, but pure table salt is NOT recommended. Space Cleaner can be used as disinfectant in a pinch." + /datum/wound_pregen_data/flesh_burn/fourth_degree abstract = FALSE @@ -346,6 +356,8 @@ examine_desc = "appears to have holy symbols painfully branded into their flesh, leaving severe burns." occur_text = "chars rapidly into a strange pattern of holy symbols, burned into the flesh." + simple_desc = "Patient's skin has had strange markings burned onto it, significantly weakening the limb and compounding further damage!!" + /datum/wound_pregen_data/flesh_burn/third_degree/holy abstract = FALSE can_be_randomly_generated = FALSE diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm index cc0e95a4761d..82f49b035032 100644 --- a/code/datums/wounds/pierce.dm +++ b/code/datums/wounds/pierce.dm @@ -108,9 +108,9 @@ if (limb) // parent can cause us to be removed, so its reasonable to check if we're still applied adjust_blood_flow(-0.03 * power) // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort -/datum/wound/pierce/bleed/on_synthflesh(power) +/datum/wound/pierce/bleed/on_synthflesh(reac_volume) . = ..() - adjust_blood_flow(-0.025 * power) // 20u * 0.05 = -1 blood flow, less than with slashes but still good considering smaller bleed rates + adjust_blood_flow(-0.025 * reac_volume) // 20u * 0.05 = -1 blood flow, less than with slashes but still good considering smaller bleed rates /// If someone is using a suture to close this puncture /datum/wound/pierce/bleed/proc/suture(obj/item/stack/medical/suture/I, mob/user) @@ -202,6 +202,9 @@ status_effect_type = /datum/status_effect/wound/pierce/moderate scar_keyword = "piercemoderate" + simple_treat_text = "Bandaging the wound will reduce blood loss, help the wound close by itself quicker, and speed up the blood recovery period. The wound itself can be slowly sutured shut." + homemade_treat_text = "Tea stimulates the body's natural healing systems, slightly fastening clotting. The wound itself can be rinsed off on a sink or shower as well. Other remedies are unnecessary." + /datum/wound_pregen_data/flesh_pierce/breakage abstract = FALSE @@ -230,6 +233,9 @@ status_effect_type = /datum/status_effect/wound/pierce/severe scar_keyword = "piercesevere" + simple_treat_text = "Bandaging the wound is essential, and will reduce blood loss. Afterwards, the wound can be sutured shut, preferably while the patient is resting and/or grasping their wound." + homemade_treat_text = "Bed sheets can be ripped up to make makeshift gauze. Flour, table salt, or salt mixed with water can be applied directly to stem the flow, though unmixed salt will irritate the skin and worsen natural healing. Resting and grabbing your wound will also reduce bleeding." + /datum/wound_pregen_data/flesh_pierce/open_puncture abstract = FALSE @@ -258,6 +264,9 @@ scar_keyword = "piercecritical" wound_flags = (ACCEPTS_GAUZE | MANGLES_EXTERIOR | CAN_BE_GRASPED) + simple_treat_text = "Bandaging the wound is of utmost importance, as is seeking direct medical attention - Death will ensue if treatment is delayed whatsoever, with lack of oxygen killing the patient, thus Food, Iron, and saline solution is always recommended after treatment. This wound will not naturally seal itself." + homemade_treat_text = "Bed sheets can be ripped up to make makeshift gauze. Flour, salt, and saltwater topically applied will help. Dropping to the ground and grabbing your wound will reduce blood flow." + /datum/wound_pregen_data/flesh_pierce/cavity abstract = FALSE diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index 35a3a3758ac2..410f48d9d576 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -232,9 +232,9 @@ if (limb) // parent can cause us to be removed, so its reasonable to check if we're still applied adjust_blood_flow(-0.03 * power) // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort -/datum/wound/slash/flesh/on_synthflesh(power) +/datum/wound/slash/flesh/on_synthflesh(reac_volume) . = ..() - adjust_blood_flow(-0.075 * power) // 20u * 0.075 = -1.5 blood flow, pretty good for how little effort it is + adjust_blood_flow(-0.075 * reac_volume) // 20u * 0.075 = -1.5 blood flow, pretty good for how little effort it is /// If someone's putting a laser gun up to our cut to cauterize it /datum/wound/slash/flesh/proc/las_cauterize(obj/item/gun/energy/laser/lasgun, mob/user) @@ -257,8 +257,15 @@ var/improv_penalty_mult = (I.tool_behaviour == TOOL_CAUTERY ? 1 : 1.25) // 25% longer and less effective if you don't use a real cautery var/self_penalty_mult = (user == victim ? 1.5 : 1) // 50% longer and less effective if you do it to yourself - user.visible_message(span_danger("[user] begins cauterizing [victim]'s [limb.plaintext_zone] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I]...")) - if(!do_after(user, base_treat_time * self_penalty_mult * improv_penalty_mult, target=victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + var/treatment_delay = base_treat_time * self_penalty_mult * improv_penalty_mult + + if(HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + treatment_delay *= 0.5 + user.visible_message(span_danger("[user] begins expertly cauterizing [victim]'s [limb.plaintext_zone] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I], keeping the holo-image indications in mind...")) + else + user.visible_message(span_danger("[user] begins cauterizing [victim]'s [limb.plaintext_zone] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I]...")) + + if(!do_after(user, treatment_delay, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) return var/bleeding_wording = (!limb.can_bleed() ? "cuts" : "bleeding") user.visible_message(span_green("[user] cauterizes some of the [bleeding_wording] on [victim]."), span_green("You cauterize some of the [bleeding_wording] on [victim].")) @@ -321,6 +328,9 @@ status_effect_type = /datum/status_effect/wound/slash/flesh/moderate scar_keyword = "slashmoderate" + simple_treat_text = "Bandaging the wound will reduce blood loss, help the wound close by itself quicker, and speed up the blood recovery period. The wound itself can be slowly sutured shut." + homemade_treat_text = "Tea stimulates the body's natural healing systems, slightly fastening clotting. The wound itself can be rinsed off on a sink or shower as well. Other remedies are unnecessary." + /datum/wound/slash/flesh/moderate/update_descriptions() if(!limb.can_bleed()) occur_text = "is cut open" @@ -348,6 +358,9 @@ status_effect_type = /datum/status_effect/wound/slash/flesh/severe scar_keyword = "slashsevere" + simple_treat_text = "Bandaging the wound is essential, and will reduce blood loss. Afterwards, the wound can be sutured shut, preferably while the patient is resting and/or grasping their wound." + homemade_treat_text = "Bed sheets can be ripped up to make makeshift gauze. Flour, table salt, or salt mixed with water can be applied directly to stem the flow, though unmixed salt will irritate the skin and worsen natural healing. Resting and grabbing your wound will also reduce bleeding." + /datum/wound_pregen_data/flesh_slash/laceration abstract = FALSE @@ -375,6 +388,8 @@ status_effect_type = /datum/status_effect/wound/slash/flesh/critical scar_keyword = "slashcritical" wound_flags = (ACCEPTS_GAUZE | MANGLES_EXTERIOR | CAN_BE_GRASPED) + simple_treat_text = "Bandaging the wound is of utmost importance, as is seeking direct medical attention - Death will ensue if treatment is delayed whatsoever, with lack of oxygen killing the patient, thus Food, Iron, and saline solution is always recommended after treatment. This wound will not naturally seal itself." + homemade_treat_text = "Bed sheets can be ripped up to make makeshift gauze. Flour, salt, and saltwater topically applied will help. Dropping to the ground and grabbing your wound will reduce blood flow." /datum/wound/slash/flesh/critical/update_descriptions() if (!limb.can_bleed()) @@ -384,7 +399,6 @@ abstract = FALSE wound_path_to_generate = /datum/wound/slash/flesh/critical - threshold_minimum = 80 /datum/wound/slash/flesh/moderate/many_cuts diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm index 74fd325e87cf..214fc019957e 100644 --- a/code/game/objects/items/devices/scanners/health_analyzer.dm +++ b/code/game/objects/items/devices/scanners/health_analyzer.dm @@ -4,6 +4,8 @@ #define SCANMODE_COUNT 2 // Update this to be the number of scan modes if you add more #define SCANNER_CONDENSED 0 #define SCANNER_VERBOSE 1 +// Not updating above count because you're not meant to switch to this mode. +#define SCANNER_NO_MODE -1 /obj/item/healthanalyzer name = "health analyzer" @@ -26,6 +28,8 @@ var/scanmode = SCANMODE_HEALTH var/advanced = FALSE custom_price = PAYCHECK_COMMAND + /// If this analyzer will give a bonus to wound treatments apon woundscan. + var/give_wound_treatment_bonus = FALSE /obj/item/healthanalyzer/Initialize(mapload) . = ..() @@ -72,6 +76,7 @@ user.visible_message(span_notice("[user] analyzes [M]'s vitals.")) balloon_alert(user, "analyzing vitals") + playsound(user.loc, 'sound/items/healthanalyzer.ogg', 50) switch (scanmode) if (SCANMODE_HEALTH) @@ -451,6 +456,9 @@ if(!user.can_perform_action(src, NEED_LITERACY|NEED_LIGHT) || user.is_blind()) return + if(mode == SCANNER_NO_MODE) + return + mode = !mode to_chat(user, mode == SCANNER_VERBOSE ? "The scanner now shows specific limb damage." : "The scanner no longer shows limb damage.") @@ -460,57 +468,90 @@ desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy." advanced = TRUE +#define AID_EMOTION_NEUTRAL "neutral" +#define AID_EMOTION_HAPPY "happy" +#define AID_EMOTION_WARN "cautious" +#define AID_EMOTION_ANGRY "angery" +#define AID_EMOTION_SAD "sad" + /// Displays wounds with extended information on their status vs medscanners -/proc/woundscan(mob/user, mob/living/carbon/patient, obj/item/healthanalyzer/wound/scanner) +/proc/woundscan(mob/user, mob/living/carbon/patient, obj/item/healthanalyzer/scanner, simple_scan = FALSE) if(!istype(patient) || user.incapacitated()) return var/render_list = "" - for(var/i in patient.get_wounded_bodyparts()) - var/obj/item/bodypart/wounded_part = i + var/advised = FALSE + for(var/limb in patient.get_wounded_bodyparts()) + var/obj/item/bodypart/wounded_part = limb render_list += "Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]" - for(var/k in wounded_part.wounds) - var/datum/wound/W = k - render_list += "
[W.get_scanner_description()]
\n" + for(var/limb_wound in wounded_part.wounds) + var/datum/wound/current_wound = limb_wound + render_list += "
[simple_scan ? current_wound.get_simple_scanner_description() : current_wound.get_scanner_description()]
\n" + if (scanner.give_wound_treatment_bonus) + ADD_TRAIT(current_wound, TRAIT_WOUND_SCANNED, ANALYZER_TRAIT) + if(!advised) + to_chat(user, span_notice("You notice how bright holo-images appear over your [(length(wounded_part.wounds) || length(patient.get_wounded_bodyparts()) ) > 1 ? "various wounds" : "wound"]. They seem to be filled with helpful information, this should make treatment easier!")) + advised = TRUE render_list += "
" if(render_list == "") - if(istype(scanner)) + if(simple_scan) + var/obj/item/healthanalyzer/simple/simple_scanner = scanner // Only emit the cheerful scanner message if this scan came from a scanner - playsound(scanner, 'sound/machines/ping.ogg', 50, FALSE) - to_chat(user, span_notice("\The [scanner] makes a happy ping and briefly displays a smiley face with several exclamation points! It's really excited to report that [patient] has no wounds!")) - else - to_chat(user, "No wounds detected in subject.") + playsound(simple_scanner, 'sound/machines/ping.ogg', 50, FALSE) + to_chat(user, span_notice("\The [simple_scanner] makes a happy ping and briefly displays a smiley face with several exclamation points! It's really excited to report that [patient] has no wounds!")) + simple_scanner.show_emotion(AID_EMOTION_HAPPY) + to_chat(user, "No wounds detected in subject.") else to_chat(user, examine_block(jointext(render_list, "")), type = MESSAGE_TYPE_INFO) - -/obj/item/healthanalyzer/wound - name = "first aid analyzer" - icon_state = "adv_spectrometer" - desc = "A prototype MeLo-Tech medical scanner used to diagnose injuries and recommend treatment for serious wounds, but offers no further insight into the patient's health. You hope the final version is less annoying to read!" + if(simple_scan) + var/obj/item/healthanalyzer/simple/simple_scanner = scanner + simple_scanner.show_emotion(AID_EMOTION_WARN) + playsound(simple_scanner, 'sound/machines/twobeep.ogg', 50, FALSE) + + +/obj/item/healthanalyzer/simple + name = "wound analyzer" + icon_state = "first_aid" + desc = "A helpful, child-proofed, and most importantly, extremely cheap MeLo-Tech medical scanner used to diagnose injuries and recommend treatment for serious wounds. While it might not sound very informative for it to be able to tell you if you have a gaping hole in your body or not, it applies a temporary holoimage near the wound with information that is guaranteed to double the efficacy and speed of treatment." + mode = SCANNER_NO_MODE + // Cooldown for when the analyzer will allow you to ask it for encouragement. Don't get greedy! var/next_encouragement - var/greedy - -/obj/item/healthanalyzer/wound/attack_self(mob/user) + // The analyzer's current emotion. Affects the sprite overlays and if it's going to prick you for being greedy or not. + var/emotion = AID_EMOTION_NEUTRAL + // Encouragements to play when attack_selfing + var/list/encouragements = list("briefly displays a happy face, gazing emptily at you", "briefly displays a spinning cartoon heart", "displays an encouraging message about eating healthy and exercising", \ + "reminds you that everyone is doing their best", "displays a message wishing you well", "displays a sincere thank-you for your interest in first-aid", "formally absolves you of all your sins") + // How often one can ask for encouragement + var/patience = 10 SECONDS + give_wound_treatment_bonus = TRUE + +/obj/item/healthanalyzer/simple/attack_self(mob/user) if(next_encouragement < world.time) playsound(src, 'sound/machines/ping.ogg', 50, FALSE) - var/list/encouragements = list("briefly displays a happy face, gazing emptily at you", "briefly displays a spinning cartoon heart", "displays an encouraging message about eating healthy and exercising", \ - "reminds you that everyone is doing their best", "displays a message wishing you well", "displays a sincere thank-you for your interest in first-aid", "formally absolves you of all your sins") to_chat(user, span_notice("\The [src] makes a happy ping and [pick(encouragements)]!")) next_encouragement = world.time + 10 SECONDS - greedy = FALSE - else if(!greedy) - to_chat(user, span_warning("\The [src] displays an eerily high-definition frowny face, chastizing you for asking it for too much encouragement.")) - greedy = TRUE + show_emotion(AID_EMOTION_HAPPY) + else if(emotion != AID_EMOTION_ANGRY) + greed_warning(user) else - playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) - if(isliving(user)) - var/mob/living/L = user - to_chat(L, span_warning("\The [src] makes a disappointed buzz and pricks your finger for being greedy. Ow!")) - L.adjustBruteLoss(4) - L.dropItemToGround(src) - -/obj/item/healthanalyzer/wound/attack(mob/living/carbon/patient, mob/living/carbon/human/user) + violence(user) + +/obj/item/healthanalyzer/simple/proc/greed_warning(mob/user) + to_chat(user, span_warning("\The [src] displays an eerily high-definition frowny face, chastizing you for asking it for too much encouragement.")) + show_emotion(AID_EMOTION_ANGRY) + +/obj/item/healthanalyzer/simple/proc/violence(mob/user) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + if(isliving(user)) + var/mob/living/L = user + to_chat(L, span_warning("\The [src] makes a disappointed buzz and pricks your finger for being greedy. Ow!")) + flick(icon_state + "_pinprick", src) + L.adjustBruteLoss(4) + L.dropItemToGround(src) + show_emotion(AID_EMOTION_HAPPY) + +/obj/item/healthanalyzer/simple/attack(mob/living/carbon/patient, mob/living/carbon/human/user) if(!user.can_read(src) || user.is_blind()) return @@ -518,14 +559,129 @@ user.visible_message(span_notice("[user] scans [patient] for serious injuries."), span_notice("You scan [patient] for serious injuries.")) if(!istype(patient)) + playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE) + to_chat(user, span_notice("\The [src] makes a sad buzz and briefly displays an unhappy face, indicating it can't scan [patient].")) + show_emotion(AI_EMOTION_SAD) + return + + woundscan(user, patient, src, simple_scan = TRUE) + flick(icon_state + "_pinprick", src) + +/obj/item/healthanalyzer/simple/update_overlays() + . = ..() + switch(emotion) + if(AID_EMOTION_HAPPY) + . += mutable_appearance(icon, "+no_wounds") + if(AID_EMOTION_WARN) + . += mutable_appearance(icon, "+wound_warn") + if(AID_EMOTION_ANGRY) + . += mutable_appearance(icon, "+angry") + if(AID_EMOTION_SAD) + . += mutable_appearance(icon, "+fail_scan") + +/// Sets a new emotion display on the scanner, and resets back to neutral in a moment +/obj/item/healthanalyzer/simple/proc/show_emotion(new_emotion) + emotion = new_emotion + update_appearance(UPDATE_OVERLAYS) + if (emotion != AID_EMOTION_NEUTRAL) + addtimer(CALLBACK(src, PROC_REF(reset_emotions), AID_EMOTION_NEUTRAL), 2 SECONDS) + +// Resets visible emotion back to neutral +/obj/item/healthanalyzer/simple/proc/reset_emotions() + emotion = AID_EMOTION_NEUTRAL + update_appearance(UPDATE_OVERLAYS) + +/obj/item/healthanalyzer/simple/miner + name = "mining wound analyzer" + icon_state = "miner_aid" + desc = "A helpful, child-proofed, and most importantly, extremely cheap MeLo-Tech medical scanner used to diagnose injuries and recommend treatment for serious wounds. While it might not sound very informative for it to be able to tell you if you have a gaping hole in your body or not, it applies a temporary holoimage near the wound with information that is guaranteed to double the efficacy and speed of treatment. This one has a cool aesthetic antenna that doesn't actually do anything!" + +/obj/item/healthanalyzer/simple/disease + name = "disease state analyzer" + desc = "Another of MeLo-Tech's dubiously useful medsci scanners, the disease analyzer is a pretty rare find these days - NT found out that giving their hospitals the lowest-common-denominator pandemic equipment resulted in too much financial loss of life to be profitable. There's rumours that the inbuilt AI is jealous of the first aid analyzer's success." + icon_state = "disease_aid" + mode = SCANNER_NO_MODE + encouragements = list("encourages you to take your medication", "briefly displays a spinning cartoon heart", "reasures you about your condition", \ + "reminds you that everyone is doing their best", "displays a message wishing you well", "displays a message saying how proud it is that you're taking care of yourself", "formally absolves you of all your sins") + patience = 20 SECONDS + +/obj/item/healthanalyzer/simple/disease/greed_warning(mob/user) + to_chat(user, span_warning("\The [src] displays an eerily high-definition frowny face, chastizing you for asking it for too much encouragement.")) + show_emotion(AID_EMOTION_ANGRY) + +/obj/item/healthanalyzer/simple/disease/violence(mob/user) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + if(isliving(user)) + var/mob/living/L = user + to_chat(L, span_warning("\The [src] makes a disappointed buzz and pricks your finger for being greedy. Ow!")) + flick(icon_state + "_pinprick", src) + L.adjustBruteLoss(1) + L.reagents.add_reagent(/datum/reagent/toxin, rand(1, 3)) + L.dropItemToGround(src) + show_emotion(AID_EMOTION_ANGRY) + +/obj/item/healthanalyzer/simple/disease/attack(mob/living/carbon/patient, mob/living/carbon/human/user) + if(!user.can_read(src) || user.is_blind()) + return + + add_fingerprint(user) + user.visible_message(span_notice("[user] scans [patient] for diseases."), span_notice("You scan [patient] for diseases.")) + + if(!istype(user)) playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE) to_chat(user, span_notice("\The [src] makes a sad buzz and briefly displays a frowny face, indicating it can't scan [patient].")) + emotion = AID_EMOTION_SAD + update_appearance(UPDATE_OVERLAYS) return - woundscan(user, patient, src) + diseasescan(user, patient, src) // this updates emotion + update_appearance(UPDATE_OVERLAYS) + flick(icon_state + "_pinprick", src) + +/obj/item/healthanalyzer/simple/disease/update_overlays() + . = ..() + switch(emotion) + if(AID_EMOTION_HAPPY) + . += mutable_appearance(icon, "+not_infected") + if(AID_EMOTION_WARN) + . += mutable_appearance(icon, "+infected") + if(AID_EMOTION_ANGRY) + . += mutable_appearance(icon, "+rancurous") + if(AID_EMOTION_SAD) + . += mutable_appearance(icon, "+unknown_scan") + if(emotion != AID_EMOTION_NEUTRAL) + addtimer(CALLBACK(src, PROC_REF(reset_emotions)), 4 SECONDS) // longer on purpose + +//Checks the individual for any diseases that are visible to the scanner, and displays the diseases in the attacked to the attacker. +/proc/diseasescan(mob/user, mob/living/carbon/patient, obj/item/healthanalyzer/simple/scanner) + if(!istype(patient) || user.incapacitated()) + return + + var/list/render = list() + for(var/datum/disease/disease as anything in patient.diseases) + if(!(disease.visibility_flags & HIDDEN_SCANNER)) + render += "Warning: [disease.form] detected\n\ +
Name: [disease.name].\nType: [disease.spread_text].\nStage: [disease.stage]/[disease.max_stages].\nPossible Cure: [disease.cure_text]
\ +
" + + if(!length(render)) + playsound(scanner, 'sound/machines/ping.ogg', 50, FALSE) + to_chat(user, span_notice("\The [scanner] makes a happy ping and briefly displays a smiley face with several exclamation points! It's really excited to report that [patient] has no diseases!")) + scanner.emotion = AID_EMOTION_HAPPY + else + to_chat(user, span_notice(render.Join(""))) + scanner.emotion = AID_EMOTION_WARN + playsound(scanner, 'sound/machines/twobeep.ogg', 50, FALSE) #undef SCANMODE_HEALTH #undef SCANMODE_WOUND #undef SCANMODE_COUNT #undef SCANNER_CONDENSED #undef SCANNER_VERBOSE +#undef SCANNER_NO_MODE + +#undef AID_EMOTION_NEUTRAL +#undef AID_EMOTION_HAPPY +#undef AID_EMOTION_WARN +#undef AID_EMOTION_ANGRY +#undef AID_EMOTION_SAD diff --git a/code/game/objects/items/devices/scanners/sequence_scanner.dm b/code/game/objects/items/devices/scanners/sequence_scanner.dm index 2422b262f326..2492168577ad 100644 --- a/code/game/objects/items/devices/scanners/sequence_scanner.dm +++ b/code/game/objects/items/devices/scanners/sequence_scanner.dm @@ -27,6 +27,7 @@ if (!HAS_TRAIT(target, TRAIT_GENELESS) && !HAS_TRAIT(target, TRAIT_BADDNA)) user.visible_message(span_notice("[user] analyzes [target]'s genetic sequence.")) balloon_alert(user, "sequence analyzed") + playsound(user.loc, 'sound/items/healthanalyzer.ogg', 50) // close enough gene_scan(target, user) else user.visible_message(span_notice("[user] fails to analyze [target]'s genetic sequence."), span_warning("[target] has no readable genetic sequence!")) diff --git a/code/game/objects/items/devices/scanners/slime_scanner.dm b/code/game/objects/items/devices/scanners/slime_scanner.dm index 81b197bfaf80..e3db7895dd8b 100644 --- a/code/game/objects/items/devices/scanners/slime_scanner.dm +++ b/code/game/objects/items/devices/scanners/slime_scanner.dm @@ -2,7 +2,7 @@ name = "slime scanner" desc = "A device that analyzes a slime's internal composition and measures its stats." icon = 'icons/obj/device.dmi' - icon_state = "adv_spectrometer" + icon_state = "slime_scanner" inhand_icon_state = "analyzer" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 39ff2fe2defa..09dbc6aeb8d4 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -165,6 +165,9 @@ // gauze is only relevant for wounds, which are handled in the wounds themselves /obj/item/stack/medical/gauze/try_heal(mob/living/patient, mob/user, silent) + + var/treatment_delay = (user == patient ? self_delay : other_delay) + var/obj/item/bodypart/limb = patient.get_bodypart(check_zone(user.zone_selected)) if(!limb) patient.balloon_alert(user, "missing limb!") @@ -174,8 +177,9 @@ return var/gauzeable_wound = FALSE + var/datum/wound/woundies for(var/i in limb.wounds) - var/datum/wound/woundies = i + woundies = i if(woundies.wound_flags & ACCEPTS_GAUZE) gauzeable_wound = TRUE break @@ -184,11 +188,19 @@ return if(limb.current_gauze && (limb.current_gauze.absorption_capacity * 1.2 > absorption_capacity)) // ignore if our new wrap is < 20% better than the current one, so someone doesn't bandage it 5 times in a row - patient.balloon_alert(user, "already bandaged!") + patient.balloon_alert(user, pick("already bandaged!", "bandage is clean!")) // good enough return - user.visible_message(span_warning("[user] begins wrapping the wounds on [patient]'s [limb.plaintext_zone] with [src]..."), span_warning("You begin wrapping the wounds on [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone] with [src]...")) - if(!do_after(user, (user == patient ? self_delay : other_delay), target=patient)) + if(HAS_TRAIT(woundies, TRAIT_WOUND_SCANNED)) + treatment_delay *= 0.5 + if(user == patient) + to_chat(user, span_notice("You keep in mind the indications from the holo-image about your injury, and expertly begin wrapping your wounds with [src].")) + else + user.visible_message(span_warning("[user] begins expertly wrapping the wounds on [patient]'s [limb.plaintext_zone] with [src]..."), span_warning("You begin quickly wrapping the wounds on [patient]'s [limb.plaintext_zone] with [src], keeping the holo-image indications in mind...")) + else + user.visible_message(span_warning("[user] begins wrapping the wounds on [patient]'s [limb.plaintext_zone] with [src]..."), span_warning("You begin wrapping the wounds on [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone] with [src]...")) + + if(!do_after(user, treatment_delay, target = patient)) return user.visible_message("[user] applies [src] to [patient]'s [limb.plaintext_zone].", "You bandage the wounds on [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone].") @@ -400,7 +412,7 @@ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - amount = 1 + amount = 5 self_delay = 20 grind_results = list(/datum/reagent/bone_dust = 10, /datum/reagent/carbon = 10) novariants = TRUE @@ -433,8 +445,8 @@ use(1) return BRUTELOSS -/obj/item/stack/medical/bone_gel/four - amount = 4 +/obj/item/stack/medical/bone_gel/one + amount = 1 /obj/item/stack/medical/poultice name = "mourning poultices" diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 21fc18326239..0c41e435b1df 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -273,7 +273,7 @@ /obj/item/storage/belt/medical/paramedic/PopulateContents() SSwardrobe.provide_type(/obj/item/sensor_device, src) SSwardrobe.provide_type(/obj/item/stack/medical/gauze/twelve, src) - SSwardrobe.provide_type(/obj/item/stack/medical/bone_gel/four, src) + SSwardrobe.provide_type(/obj/item/stack/medical/bone_gel, src) SSwardrobe.provide_type(/obj/item/stack/sticky_tape/surgical, src) SSwardrobe.provide_type(/obj/item/reagent_containers/syringe, src) SSwardrobe.provide_type(/obj/item/reagent_containers/cup/bottle/ammoniated_mercury, src) @@ -299,7 +299,7 @@ SSwardrobe.provide_type(/obj/item/pinpointer/crew, src) SSwardrobe.provide_type(/obj/item/scalpel/advanced, src) SSwardrobe.provide_type(/obj/item/retractor/advanced, src) - SSwardrobe.provide_type(/obj/item/stack/medical/bone_gel/four, src) + SSwardrobe.provide_type(/obj/item/stack/medical/bone_gel, src) SSwardrobe.provide_type(/obj/item/cautery/advanced, src) SSwardrobe.provide_type(/obj/item/surgical_drapes, src) update_appearance() diff --git a/code/game/objects/items/storage/boxes/job_boxes.dm b/code/game/objects/items/storage/boxes/job_boxes.dm index 4ae3de9cadc8..01468fa9a8ce 100644 --- a/code/game/objects/items/storage/boxes/job_boxes.dm +++ b/code/game/objects/items/storage/boxes/job_boxes.dm @@ -62,6 +62,7 @@ /obj/item/storage/box/survival/mining/PopulateContents() ..() new /obj/item/crowbar/red(src) + new /obj/item/healthanalyzer/simple/miner(src) // Engineer survival box /obj/item/storage/box/survival/engineer diff --git a/code/game/objects/items/storage/medkit.dm b/code/game/objects/items/storage/medkit.dm index 32a043c6aea6..79bd7fa9a7aa 100644 --- a/code/game/objects/items/storage/medkit.dm +++ b/code/game/objects/items/storage/medkit.dm @@ -41,7 +41,7 @@ /obj/item/stack/medical/suture = 2, /obj/item/stack/medical/mesh = 2, /obj/item/reagent_containers/hypospray/medipen = 1, - /obj/item/healthanalyzer = 1, + /obj/item/healthanalyzer/simple = 1, ) generate_items_inside(items_inside,src) @@ -54,7 +54,7 @@ if(empty) return var/static/items_inside = list( - /obj/item/healthanalyzer/wound = 1, + /obj/item/healthanalyzer/simple = 1, /obj/item/stack/medical/gauze = 1, /obj/item/stack/medical/suture/emergency = 1, /obj/item/stack/medical/ointment = 1, @@ -196,10 +196,12 @@ if(empty) return var/static/items_inside = list( - /obj/item/storage/pill_bottle/multiver/less = 1, + /obj/item/storage/pill_bottle/multiver/less = 1, /obj/item/reagent_containers/syringe/syriniver = 3, /obj/item/storage/pill_bottle/potassiodide = 1, - /obj/item/reagent_containers/hypospray/medipen/penacid = 1) + /obj/item/reagent_containers/hypospray/medipen/penacid = 1, + /obj/item/healthanalyzer/simple/disease = 1, + ) generate_items_inside(items_inside,src) /obj/item/storage/medkit/o2 @@ -241,7 +243,9 @@ /obj/item/reagent_containers/pill/patch/libital = 3, /obj/item/stack/medical/gauze = 1, /obj/item/storage/pill_bottle/probital = 1, - /obj/item/reagent_containers/hypospray/medipen/salacid = 1) + /obj/item/reagent_containers/hypospray/medipen/salacid = 1, + /obj/item/healthanalyzer/simple = 1, + ) generate_items_inside(items_inside,src) /obj/item/storage/medkit/advanced diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm index 099ff13b136b..7ae14716e356 100644 --- a/code/modules/cargo/packs/medical.dm +++ b/code/modules/cargo/packs/medical.dm @@ -91,7 +91,7 @@ /obj/item/reagent_containers/blood/o_minus, /obj/item/storage/pill_bottle/mining, /obj/item/reagent_containers/pill/neurine, - /obj/item/stack/medical/bone_gel/four = 2, + /obj/item/stack/medical/bone_gel = 2, /obj/item/vending_refill/medical, /obj/item/vending_refill/drugs, ) diff --git a/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm b/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm index ec3813cfd567..df0715a4bd98 100644 --- a/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm +++ b/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm @@ -406,7 +406,7 @@ /datum/chemical_reaction/drink/squirt_cider results = list(/datum/reagent/consumable/ethanol/squirt_cider = 4) - required_reagents = list(/datum/reagent/water = 2, /datum/reagent/consumable/tomatojuice = 2, /datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/salt = 1) + required_reagents = list(/datum/reagent/water/salt = 2, /datum/reagent/consumable/tomatojuice = 2, /datum/reagent/consumable/nutriment = 1) mix_message = "The mix swirls and turns a bright red that reminds you of an apple's skin." reaction_tags = REACTION_TAG_DRINK | REACTION_TAG_EASY | REACTION_TAG_OTHER diff --git a/code/modules/food_and_drinks/recipes/soup_mixtures.dm b/code/modules/food_and_drinks/recipes/soup_mixtures.dm index ceb207a85ae2..e4912ebfa0ad 100644 --- a/code/modules/food_and_drinks/recipes/soup_mixtures.dm +++ b/code/modules/food_and_drinks/recipes/soup_mixtures.dm @@ -524,8 +524,8 @@ /datum/chemical_reaction/food/soup/chili_sin_carne required_reagents = list( - /datum/reagent/water = 40, - /datum/reagent/consumable/salt = 5, + /datum/reagent/water = 30, + /datum/reagent/water/salt = 10, ) required_ingredients = list( /obj/item/food/grown/chili = 1, @@ -1043,8 +1043,8 @@ /datum/chemical_reaction/food/soup/electron required_reagents = list( - /datum/reagent/water = 45, - /datum/reagent/consumable/salt = 5, + /datum/reagent/water = 40, + /datum/reagent/water/salt = 10, ) required_ingredients = list( /obj/item/food/grown/mushroom/jupitercup = 1, @@ -1607,8 +1607,8 @@ /datum/chemical_reaction/food/soup/rice_porridge required_reagents = list( - /datum/reagent/water = 30, - /datum/reagent/consumable/salt = 5, + /datum/reagent/water = 20, + /datum/reagent/water/salt = 10, ) required_ingredients = list( /obj/item/food/boiledrice = 1, diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm index d0bdfeffff7d..c7807653fc54 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm @@ -422,8 +422,7 @@ reqs = list( /obj/item/reagent_containers/cup/beaker/large = 1, /obj/item/food/grown/cucumber = 10, - /datum/reagent/water = 10, - /datum/reagent/consumable/salt = 10, + /datum/reagent/water/salt = 20, ) result = /obj/item/storage/fancy/pickles_jar category = CAT_MISCFOOD diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index a7ce024a6598..0ee131a70069 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -185,6 +185,10 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) return holder.remove_reagent(type, metabolization_rate * M.metabolism_efficiency * seconds_per_tick) //By default it slowly disappears. +/// Called in burns.dm *if* the reagent has the REAGENT_AFFECTS_WOUNDS process flag +/datum/reagent/proc/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound) + return + /* Used to run functions before a reagent is transfered. Returning TRUE will block the transfer attempt. Primarily used in reagents/reaction_agents diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 9b175be23c81..97136467650d 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -421,10 +421,39 @@ affected_mob.AdjustSleeping(-20 * REM * seconds_per_tick) if(affected_mob.getToxLoss() && SPT_PROB(10, seconds_per_tick)) affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype) + var/to_chatted = FALSE + for(var/datum/wound/iter_wound as anything in affected_mob.all_wounds) + if(SPT_PROB(10, seconds_per_tick)) + var/helped = iter_wound.tea_life_process() + if(!to_chatted && helped) + to_chat(affected_mob, span_notice("A calm, relaxed feeling suffuses you. Your wounds feel a little healthier.")) + to_chatted = TRUE affected_mob.adjust_bodytemperature(20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal()) ..() . = TRUE +// Different handling, different name. +// Returns FALSE by default so broken bones and 'loss' wounds don't give a false message +/datum/wound/proc/tea_life_process() + return FALSE + +// Slowly increase (gauzed) clot rate +/datum/wound/pierce/bleed/tea_life_process() + gauzed_clot_rate += 0.1 + return TRUE + +// Slowly increase clot rate +/datum/wound/slash/flesh/tea_life_process() + clot_rate += 0.2 + return TRUE + +// There's a designated burn process, but I felt this would be better for consistency with the rest of the reagent's procs +/datum/wound/burn/flesh/tea_life_process() + // Sanitizes and heals, but with a limit + flesh_healing = (flesh_healing > 0.1) ? flesh_healing : flesh_healing + 0.02 + infestation_rate = max(infestation_rate - 0.005, 0) + return TRUE + /datum/reagent/consumable/lemonade name = "Lemonade" description = "Sweet, tangy lemonade. Good for the soul." diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index a56cec033887..03d7e1085230 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -442,6 +442,40 @@ new/obj/effect/decal/cleanable/food/salt(exposed_turf) +/datum/reagent/consumable/salt/expose_mob(mob/living/exposed_mob, methods, reac_volume) + . = ..() + var/mob/living/carbon/carbies = exposed_mob + if(!(methods & (PATCH|TOUCH|VAPOR))) + return + for(var/datum/wound/iter_wound as anything in carbies.all_wounds) + iter_wound.on_salt(reac_volume, carbies) + +// Salt can help with wounds by soaking up fluid, but undiluted salt will also cause irritation from the loose crystals, and it might soak up the body's water as well! +// A saltwater mixture would be best, but we're making improvised chems here, not real ones. +/datum/wound/proc/on_salt(reac_volume, mob/living/carbon/carbies) + return + +/datum/wound/pierce/bleed/on_salt(reac_volume, mob/living/carbon/carbies) + adjust_blood_flow(-0.06 * reac_volume, initial_flow * 0.6) // 20u of a salt shacker * 0.1 = -1.6~ blood flow, but is always clamped to, at best, third blood loss from that wound. + // Crystal irritation worsening recovery. + gauzed_clot_rate *= 0.65 + to_chat(carbies, span_notice("The salt bits seep in and stick to [lowertext(src)], painfully irritating the skin but soaking up most of the blood.")) + +/datum/wound/slash/flesh/on_salt(reac_volume, mob/living/carbon/carbies) + adjust_blood_flow(-0.1 * reac_volume, initial_flow * 0.5) // 20u of a salt shacker * 0.1 = -2~ blood flow, but is always clamped to, at best, halve blood loss from that wound. + // Crystal irritation worsening recovery. + clot_rate *= 0.75 + to_chat(carbies, span_notice("The salt bits seep in and stick to [lowertext(src)], painfully irritating the skin but soaking up most of the blood.")) + +/datum/wound/burn/flesh/on_salt(reac_volume) + // Slightly sanitizes and disinfects, but also increases infestation rate (some bacteria are aided by salt), and decreases flesh healing (can damage the skin from moisture absorption) + sanitization += VALUE_PER(0.4, 30) * reac_volume + infestation -= max(VALUE_PER(0.3, 30) * reac_volume, 0) + infestation_rate += VALUE_PER(0.12, 30) * reac_volume + flesh_healing -= max(VALUE_PER(5, 30) * reac_volume, 0) + to_chat(victim, span_notice("The salt bits seep in and stick to [lowertext(src)], painfully irritating the skin! After a few moments, it feels marginally better.")) + + /datum/reagent/consumable/blackpepper name = "Black Pepper" description = "A powder ground from peppercorns. *AAAACHOOO*" @@ -602,9 +636,38 @@ reagent_state = SOLID color = "#FFFFFF" // rgb: 0, 0, 0 taste_description = "chalky wheat" - chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS default_container = /obj/item/reagent_containers/condiment/flour +/datum/reagent/consumable/flour/expose_mob(mob/living/exposed_mob, methods, reac_volume) + . = ..() + var/mob/living/carbon/carbies = exposed_mob + if(!(methods & (PATCH|TOUCH|VAPOR))) + return + for(var/datum/wound/iter_wound as anything in carbies.all_wounds) + iter_wound.on_flour(reac_volume, carbies) + +/datum/wound/proc/on_flour(reac_volume, mob/living/carbon/carbies) + return + +/datum/wound/pierce/bleed/on_flour(reac_volume, mob/living/carbon/carbies) + adjust_blood_flow(-0.015 * reac_volume) // 30u of a flour sack * 0.015 = -0.45~ blood flow, prettay good + to_chat(carbies, span_notice("The flour seeps into [lowertext(src)], painfully drying it up and absorbing some of the blood.")) + // When some nerd adds infection for wounds, make this increase the infection + +/datum/wound/slash/flesh/on_flour(reac_volume, mob/living/carbon/carbies) + adjust_blood_flow(-0.04 * reac_volume) // 30u of a flour sack * 0.04 = -1.25~ blood flow, pretty good! + to_chat(carbies, span_notice("The flour seeps into [lowertext(src)], painfully drying some of it up and absorbing a little blood.")) + // When some nerd adds infection for wounds, make this increase the infection + +// Don't pour flour onto burn wounds, it increases infection risk! Very unwise. Backed up by REAL info from REAL professionals. +// https://www.reuters.com/article/uk-factcheck-flour-burn-idUSKCN26F2N3 +/datum/wound/burn/flesh/on_flour(reac_volume) + to_chat(victim, span_notice("The flour seeps into [lowertext(src)], spiking you with intense pain! That probably wasn't a good idea...")) + sanitization -= min(0, 1) + infestation += 0.2 + return + /datum/reagent/consumable/flour/expose_turf(turf/exposed_turf, reac_volume) . = ..() if(isspaceturf(exposed_turf)) @@ -670,6 +733,37 @@ description = "A slippery solution." color = "#DBCE95" taste_description = "slime" + chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS + +// Starch has similar absorbing properties to flour (Stronger here because it's rarer) +/datum/reagent/consumable/corn_starch/expose_mob(mob/living/exposed_mob, methods, reac_volume) + . = ..() + var/mob/living/carbon/carbies = exposed_mob + if(!(methods & (PATCH|TOUCH|VAPOR))) + return + for(var/datum/wound/iter_wound as anything in carbies.all_wounds) + iter_wound.on_starch(reac_volume, carbies) + +/datum/wound/proc/on_starch(reac_volume, mob/living/carbon/carbies) + return + +/datum/wound/pierce/bleed/on_starch(reac_volume, mob/living/carbon/carbies) + adjust_blood_flow(-0.03 * reac_volume) + to_chat(carbies, span_notice("The slimey starch seeps into [lowertext(src)], painfully drying some of it up and absorbing a little blood.")) + // When some nerd adds infection for wounds, make this increase the infection + return + +/datum/wound/slash/flesh/on_starch(reac_volume, mob/living/carbon/carbies) + adjust_blood_flow(-0.06 * reac_volume) + to_chat(carbies, span_notice("The slimey starch seeps into [lowertext(src)], painfully drying it up and absorbing some of the blood.")) + // When some nerd adds infection for wounds, make this increase the infection + return + +/datum/wound/burn/flesh/on_starch(reac_volume, mob/living/carbon/carbies) + to_chat(carbies, span_notice("The slimey starch seeps into [lowertext(src)], spiking you with intense pain! That probably wasn't a good idea...")) + sanitization -= min(0, 0.5) + infestation += 0.1 + return /datum/reagent/consumable/corn_syrup name = "Corn Syrup" diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 4936b28bebde..af21dd9543f1 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -322,7 +322,7 @@ color = "#6D6374" metabolization_rate = 0.4 * REAGENTS_METABOLISM ph = 2.6 - chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS /datum/reagent/medicine/mine_salve/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) affected_mob.adjustBruteLoss(-0.25 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) @@ -356,6 +356,10 @@ . = ..() metabolizer.remove_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type) +/datum/reagent/medicine/mine_salve/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound) + burn_wound.sanitization += 0.3 + burn_wound.flesh_healing += 0.5 + /datum/reagent/medicine/omnizine name = "Omnizine" description = "Slowly heals all damage types. Overdose will cause damage in all types instead." diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 5401cae2985a..d5d6f68b3f27 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -291,6 +291,53 @@ //You don't belong in this world, monster! chems.remove_reagent(type, chems.get_reagent_amount(src.type)) +/datum/reagent/water/salt + name = "Saltwater" + description = "Water, but salty. Smells like... the station infirmary?" + color = "#aaaaaa9d" // rgb: 170, 170, 170, 77 (alpha) + taste_description = "the sea" + cooling_temperature = 3 + chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_CLEANS + default_container = /obj/item/reagent_containers/cup/glass/waterbottle + +/datum/glass_style/shot_glass/water/salt + required_drink_type = /datum/reagent/water/salt + icon_state = "shotglassclear" + +/datum/glass_style/drinking_glass/water/salt + required_drink_type = /datum/reagent/water/salt + name = "glass of saltwater" + desc = "If you have a sore throat, gargle some saltwater and watch the pain go away. Can be used as a very improvised topical medicine against wounds." + icon_state = "glass_clear" + +/datum/reagent/water/salt/expose_mob(mob/living/exposed_mob, methods, reac_volume) + . = ..() + var/mob/living/carbon/carbies = exposed_mob + if(!(methods & (PATCH|TOUCH|VAPOR))) + return + for(var/datum/wound/iter_wound as anything in carbies.all_wounds) + iter_wound.on_saltwater(reac_volume, carbies) + +// Mixed salt with water! All the help of salt with none of the irritation. Plus increased volume. +/datum/wound/proc/on_saltwater(reac_volume, mob/living/carbon/carbies) + return + +/datum/wound/pierce/bleed/on_saltwater(reac_volume, mob/living/carbon/carbies) + adjust_blood_flow(-0.06 * reac_volume, initial_flow * 0.6) + to_chat(carbies, span_notice("The salt water splashes over [lowertext(src)], soaking up the blood.")) + +/datum/wound/slash/flesh/on_saltwater(reac_volume, mob/living/carbon/carbies) + adjust_blood_flow(-0.1 * reac_volume, initial_flow * 0.5) + to_chat(carbies, span_notice("The salt water splashes over [lowertext(src)], soaking up the blood.")) + +/datum/wound/burn/flesh/on_saltwater(reac_volume) + // Similar but better stats from normal salt. + sanitization += VALUE_PER(0.6, 30) * reac_volume + infestation -= max(VALUE_PER(0.5, 30) * reac_volume, 0) + infestation_rate += VALUE_PER(0.07, 30) * reac_volume + to_chat(victim, span_notice("The salt water splashes over [lowertext(src)], soaking up the... miscellaneous fluids. It feels somewhat better afterwards.")) + return + /datum/reagent/water/holywater name = "Holy Water" description = "Water blessed by some deity." @@ -1084,7 +1131,7 @@ color = "#D0EFEE" // space cleaner but lighter taste_description = "bitterness" ph = 10.5 - chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS /datum/reagent/space_cleaner/sterilizine/expose_mob(mob/living/carbon/exposed_carbon, methods=TOUCH, reac_volume) . = ..() @@ -1094,6 +1141,9 @@ for(var/datum/surgery/surgery as anything in exposed_carbon.surgeries) surgery.speed_modifier = max(0.2, surgery.speed_modifier) +/datum/reagent/space_cleaner/sterilizine/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound) + burn_wound.sanitization += 0.9 + /datum/reagent/iron name = "Iron" description = "Pure iron is a metal." @@ -1301,14 +1351,14 @@ /datum/reagent/space_cleaner name = "Space Cleaner" - description = "A compound used to clean things. Now with 50% more sodium hypochlorite!" + description = "A compound used to clean things. Now with 50% more sodium hypochlorite! Can be used to clean wounds, but it's not really meant for that." color = "#A5F0EE" // rgb: 165, 240, 238 taste_description = "sourness" reagent_weight = 0.6 //so it sprays further - penetrates_skin = NONE + penetrates_skin = VAPOR var/clean_types = CLEAN_WASH ph = 5.5 - chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_CLEANS + chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_CLEANS|REAGENT_AFFECTS_WOUNDS turf_exposure = TRUE /datum/reagent/space_cleaner/expose_obj(obj/exposed_obj, reac_volume) @@ -1335,6 +1385,13 @@ if(methods & (TOUCH|VAPOR)) exposed_mob.wash(clean_types) +/datum/reagent/space_cleaner/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound) + burn_wound.sanitization += 0.3 + if(prob(5)) + to_chat(burn_wound.victim, span_notice("Your [burn_wound] stings and burns from the [src] covering it! It does look pretty clean though.")) + burn_wound.victim.adjustToxLoss(0.5) + burn_wound.limb.receive_damage(burn = 0.5, wound_bonus = CANT_WOUND) + /datum/reagent/space_cleaner/ez_clean name = "EZ Clean" description = "A powerful, acidic cleaner sold by Waffle Co. Affects organic matter while leaving other objects unaffected." diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index 103890aaa797..8edab30eee11 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -93,7 +93,7 @@ /datum/chemical_reaction/medicine/salglu_solution results = list(/datum/reagent/medicine/salglu_solution = 3) - required_reagents = list(/datum/reagent/consumable/salt = 1, /datum/reagent/water = 1, /datum/reagent/consumable/sugar = 1) + required_reagents = list(/datum/reagent/water/salt = 2, /datum/reagent/consumable/sugar = 1) reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_ORGAN /datum/chemical_reaction/medicine/mine_salve @@ -141,8 +141,8 @@ reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_OTHER /datum/chemical_reaction/medicine/pen_acid - results = list(/datum/reagent/medicine/pen_acid = 6) - required_reagents = list(/datum/reagent/fuel = 1, /datum/reagent/chlorine = 1, /datum/reagent/ammonia = 1, /datum/reagent/toxin/formaldehyde = 1, /datum/reagent/sodium = 1, /datum/reagent/toxin/cyanide = 1) + results = list(/datum/reagent/medicine/pen_acid = 5) + required_reagents = list(/datum/reagent/fuel = 1, /datum/reagent/ammonia = 1, /datum/reagent/toxin/formaldehyde = 1, /datum/reagent/consumable/salt = 1, /datum/reagent/toxin/cyanide = 1) reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_OTHER /datum/chemical_reaction/medicine/sal_acid diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index 30c8edc0e614..667100e8b0a3 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -35,8 +35,8 @@ reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_EXPLOSIVE /datum/chemical_reaction/sodiumchloride - results = list(/datum/reagent/consumable/salt = 3) - required_reagents = list(/datum/reagent/water = 1, /datum/reagent/sodium = 1, /datum/reagent/chlorine = 1) + results = list(/datum/reagent/consumable/salt = 2) + required_reagents = list(/datum/reagent/sodium = 1, /datum/reagent/chlorine = 1) // That's what I said! Sodium Chloride! reaction_tags = REACTION_TAG_EASY | REACTION_TAG_FOOD /datum/chemical_reaction/stable_plasma @@ -771,6 +771,11 @@ required_catalysts = list(/datum/reagent/water/holywater = 1) reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_PLANT | REACTION_TAG_OTHER +/datum/chemical_reaction/saltwater + results = list(/datum/reagent/water/salt = 2) + required_reagents = list(/datum/reagent/water = 1, /datum/reagent/consumable/salt = 1) + reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRINK | REACTION_TAG_ORGAN + /datum/chemical_reaction/exotic_stabilizer results = list(/datum/reagent/exotic_stabilizer = 2) required_reagents = list(/datum/reagent/plasma_oxide = 1,/datum/reagent/stabilizing_agent = 1) @@ -798,7 +803,7 @@ /datum/chemical_reaction/bone_gel/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) var/location = get_turf(holder.my_atom) for(var/i in 1 to created_volume) - new /obj/item/stack/medical/bone_gel(location) + new /obj/item/stack/medical/bone_gel/one(location) ////Ice and water diff --git a/code/modules/reagents/chemistry/recipes/toxins.dm b/code/modules/reagents/chemistry/recipes/toxins.dm index b4e80e01cd02..0fcae783d899 100644 --- a/code/modules/reagents/chemistry/recipes/toxins.dm +++ b/code/modules/reagents/chemistry/recipes/toxins.dm @@ -307,8 +307,8 @@ reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DAMAGING | REACTION_TAG_OTHER /datum/chemical_reaction/heparin - results = list(/datum/reagent/toxin/heparin = 4) - required_reagents = list(/datum/reagent/toxin/formaldehyde = 1, /datum/reagent/sodium = 1, /datum/reagent/chlorine = 1, /datum/reagent/lithium = 1) + results = list(/datum/reagent/toxin/heparin = 3) + required_reagents = list(/datum/reagent/toxin/formaldehyde = 1, /datum/reagent/consumable/salt = 1, /datum/reagent/lithium = 1) mix_message = "The mixture thins and loses all color." is_cold_recipe = FALSE required_temp = 100 diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index c3066f0536e3..8df5e8b6d596 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -336,9 +336,9 @@ if(WOUND_SEVERITY_MODERATE) check_list += "\t [span_warning("Your [name] is suffering [wound.a_or_from] [lowertext(wound.name)]!")]" if(WOUND_SEVERITY_SEVERE) - check_list += "\t [span_boldwarning("Your [name] is suffering [wound.a_or_from] [lowertext(wound.name)]!")]" - if(WOUND_SEVERITY_CRITICAL) check_list += "\t [span_boldwarning("Your [name] is suffering [wound.a_or_from] [lowertext(wound.name)]!!")]" + if(WOUND_SEVERITY_CRITICAL) + check_list += "\t [span_boldwarning("Your [name] is suffering [wound.a_or_from] [lowertext(wound.name)]!!!")]" for(var/obj/item/embedded_thing in embedded_objects) var/stuck_word = embedded_thing.isEmbedHarmless() ? "stuck" : "embedded" diff --git a/code/modules/surgery/bodyparts/wounds.dm b/code/modules/surgery/bodyparts/wounds.dm index 3d2a6c4056eb..16123c1e871a 100644 --- a/code/modules/surgery/bodyparts/wounds.dm +++ b/code/modules/surgery/bodyparts/wounds.dm @@ -306,6 +306,10 @@ var/dam_mul = 1 //initial(wound_damage_multiplier) + // we can (normally) only have one wound per type, but remember there's multiple types (smites like :B:loodless can generate multiple cuts on a limb) + for(var/datum/wound/iter_wound as anything in wounds) + dam_mul *= iter_wound.damage_multiplier_penalty + if(!LAZYLEN(wounds) && current_gauze && !replaced) // no more wounds = no need for the gauze anymore owner.visible_message(span_notice("\The [current_gauze.name] on [owner]'s [name] falls away."), span_notice("The [current_gauze.name] on your [parse_zone(body_zone)] falls away.")) QDEL_NULL(current_gauze) diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index d48484b36951..9198e81f121a 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -254,9 +254,12 @@ name = "surgical processor" desc = "A device for scanning and initiating surgeries from a disk or operating computer." icon = 'icons/obj/device.dmi' - icon_state = "spectrometer" + icon_state = "surgical_processor" item_flags = NOBLUDGEON + // List of surgeries downloaded into the device. var/list/loaded_surgeries = list() + // If a surgery has been downloaded in. Will cause the display to have a noticeable effect - helps to realize you forgot to load anything in. + var/downloaded = TRUE /obj/item/surgical_processor/Initialize(mapload) . = ..() @@ -304,8 +307,15 @@ var/obj/machinery/computer/operating/surgery_computer = design_holder loaded_surgeries |= surgery_computer.advanced_surgeries playsound(src, 'sound/machines/terminal_success.ogg', 25, TRUE) + downloaded = TRUE + update_appearance(UPDATE_OVERLAYS) return TRUE +/obj/item/surgical_processor/update_overlays() + . = ..() + if(downloaded) + . += mutable_appearance(src.icon, "+downloaded") + /obj/item/surgical_processor/proc/check_surgery(mob/user, datum/surgery/surgery, mob/patient) SIGNAL_HANDLER diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index 635b31137e7f..36cf4076fa51 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -13,10 +13,10 @@ /obj/item/healthanalyzer = 4, /obj/item/wrench/medical = 1, /obj/item/stack/sticky_tape/surgical = 3, - /obj/item/healthanalyzer/wound = 4, + /obj/item/healthanalyzer/simple = 4, /obj/item/stack/medical/ointment = 2, /obj/item/stack/medical/suture = 2, - /obj/item/stack/medical/bone_gel/four = 4, + /obj/item/stack/medical/bone_gel = 4, /obj/item/cane/white = 2, /obj/item/clothing/glasses/eyepatch/medical = 2, ) @@ -48,6 +48,23 @@ req_access = list(ACCESS_SYNDICATE) initial_language_holder = /datum/language_holder/syndicate +/obj/machinery/vending/medical/infested_frigate + req_access = list("theatre") + products = list( + /obj/item/stack/medical/gauze = 0, + /obj/item/reagent_containers/syringe = 7, + /obj/item/reagent_containers/dropper = 3, + /obj/item/healthanalyzer = 0, + /obj/item/wrench/medical = 0, + /obj/item/stack/sticky_tape/surgical = 0, + /obj/item/healthanalyzer/simple = 0, + /obj/item/stack/medical/ointment = 0, + /obj/item/stack/medical/suture = 1, + /obj/item/stack/medical/bone_gel = 1, + /obj/item/cane/white = 2, + /obj/item/clothing/glasses/eyepatch/medical = 2, + ) + //Created out of a necessity to get these dumb chems out of the medical tools vendor. /obj/machinery/vending/drugs name = "\improper NanoDrug Plus" diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index 82b2de354a86..4fd120bdc487 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -13,8 +13,8 @@ /obj/item/reagent_containers/medigel/libital = 2, /obj/item/reagent_containers/medigel/aiuri = 2, /obj/item/reagent_containers/medigel/sterilizine = 1, - /obj/item/healthanalyzer/wound = 2, - /obj/item/stack/medical/bone_gel/four = 2, + /obj/item/healthanalyzer/simple = 2, + /obj/item/stack/medical/bone_gel = 2, ) contraband = list( /obj/item/reagent_containers/pill/tox = 2, diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 680fcd279384..2b6773c543d2 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/sound/items/healthanalyzer.ogg b/sound/items/healthanalyzer.ogg new file mode 100644 index 000000000000..56fd762cdde7 Binary files /dev/null and b/sound/items/healthanalyzer.ogg differ diff --git a/tools/UpdatePaths/Scripts/75851_bone_gel_four.txt b/tools/UpdatePaths/Scripts/75851_bone_gel_four.txt new file mode 100644 index 000000000000..8941726db595 --- /dev/null +++ b/tools/UpdatePaths/Scripts/75851_bone_gel_four.txt @@ -0,0 +1 @@ +/obj/item/stack/medical/bone_gel/four : /obj/item/stack/medical/bone_gel{@OLD} \ No newline at end of file