From f18ece09261f80a91d0062a7cd6df6e7c872ec52 Mon Sep 17 00:00:00 2001 From: Ryll Ryll <3589655+Ryll-Ryll@users.noreply.github.com> Date: Mon, 30 Nov 2020 11:51:40 -0500 Subject: [PATCH] Small refactor for medical stack items (#55213) Someone DM'd me asking a question about what the 'heal' var was for on aloe, I looked into it and realized it was an unnecessary variable that just replicated what heal_brute and heal_burn do. I then realized there was quite a lot of unnecessary copypasta in medical stack code, so I made some changes to make it neater and added some documentation in to boot --- code/game/objects/items/stacks/medical.dm | 242 ++++++++-------------- 1 file changed, 92 insertions(+), 150 deletions(-) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index c880a1ce856..95faced3ed6 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -15,16 +15,19 @@ cost = 250 source = /datum/robot_energy_storage/medical merge_type = /obj/item/stack/medical - var/self_delay = 50 + /// How long it takes to apply it to yourself + var/self_delay = 5 SECONDS + /// How long it takes to apply it to someone else var/other_delay = 0 + /// If we've still got more and the patient is still hurt, should we keep going automatically? var/repeating = FALSE - /// How much brute we heal per application + /// How much brute we heal per application. This is the only number that matters for simplemobs var/heal_brute /// How much burn we heal per application var/heal_burn /// How much we reduce bleeding per application on cut wounds var/stop_bleeding - /// How much sanitization to apply to burns on application + /// How much sanitization to apply to burn wounds on application var/sanitization /// How much we add to flesh_healing for burn wounds on application var/flesh_regeneration @@ -33,49 +36,66 @@ . = ..() try_heal(M, user) - -/obj/item/stack/medical/proc/try_heal(mob/living/M, mob/user, silent = FALSE) - if(!M.can_inject(user, TRUE)) +/// In which we print the message that we're starting to heal someone, then we try healing them. Does the do_after whether or not it can actually succeed on a targeted mob +/obj/item/stack/medical/proc/try_heal(mob/living/patient, mob/user, silent = FALSE) + if(!patient.can_inject(user, TRUE)) return - if(M == user) + if(patient == user) if(!silent) - user.visible_message("[user] starts to apply \the [src] on [user.p_them()]self...", "You begin applying \the [src] on yourself...") - if(!do_mob(user, M, self_delay, extra_checks=CALLBACK(M, /mob/living/proc/can_inject, user, TRUE))) + user.visible_message("[user] starts to apply [src] on [user.p_them()]self...", "You begin applying [src] on yourself...") + if(!do_mob(user, patient, self_delay, extra_checks=CALLBACK(patient, /mob/living/proc/can_inject, user, TRUE))) return else if(other_delay) if(!silent) - user.visible_message("[user] starts to apply \the [src] on [M].", "You begin applying \the [src] on [M]...") - if(!do_mob(user, M, other_delay, extra_checks=CALLBACK(M, /mob/living/proc/can_inject, user, TRUE))) + user.visible_message("[user] starts to apply [src] on [patient].", "You begin applying [src] on [patient]...") + if(!do_mob(user, patient, other_delay, extra_checks=CALLBACK(patient, /mob/living/proc/can_inject, user, TRUE))) return - if(heal(M, user)) - log_combat(user, M, "healed", src.name) + if(heal(patient, user)) + log_combat(user, patient, "healed", src.name) use(1) if(repeating && amount > 0) - try_heal(M, user, TRUE) + try_heal(patient, user, TRUE) -/obj/item/stack/medical/proc/heal(mob/living/M, mob/user) - return +/// Apply the actual effects of the healing if it's a simple animal, goes to [/obj/item/stack/medical/proc/heal_carbon] if it's a carbon, returns TRUE if it works, FALSE if it doesn't +/obj/item/stack/medical/proc/heal(mob/living/patient, mob/user) + if(patient.stat == DEAD) + to_chat(user, "[patient] is dead! You can not help [patient.p_them()].") + return + if(isanimal(patient) && heal_brute) // only brute can heal + var/mob/living/simple_animal/critter = patient + if (!critter.healable) + to_chat(user, "You cannot use [src] on [patient]!") + return FALSE + else if (critter.health == critter.maxHealth) + to_chat(user, "[patient] is at full health.") + return FALSE + user.visible_message("[user] applies [src] on [patient].", "You apply [src] on [patient].") + patient.heal_bodypart_damage((heal_brute * 0.5)) + return TRUE + if(iscarbon(patient)) + return heal_carbon(patient, user, heal_brute, heal_burn) + to_chat(user, "You can't heal [patient] with [src]!") +/// The healing effects on a carbon patient. Since we have extra details for dealing with bodyparts, we get our own fancy proc. Still returns TRUE on success and FALSE on fail /obj/item/stack/medical/proc/heal_carbon(mob/living/carbon/C, mob/user, brute, burn) var/obj/item/bodypart/affecting = C.get_bodypart(check_zone(user.zone_selected)) if(!affecting) //Missing limb? to_chat(user, "[C] doesn't have \a [parse_zone(user.zone_selected)]!") return FALSE if(affecting.status != BODYPART_ORGANIC) //Limb must be organic to be healed - RR - to_chat(user, "\The [src] won't work on a robotic limb!") + to_chat(user, "[src] won't work on a robotic limb!") return FALSE if(affecting.brute_dam && brute || affecting.burn_dam && burn) - user.visible_message("[user] applies \the [src] on [C]'s [affecting.name].", "You apply \the [src] on [C]'s [affecting.name].") + user.visible_message("[user] applies [src] on [C]'s [affecting.name].", "You apply [src] on [C]'s [affecting.name].") var/previous_damage = affecting.get_damage() if(affecting.heal_damage(brute, burn)) C.update_damage_overlays() post_heal_effects(max(previous_damage - affecting.get_damage(), 0), C, user) return TRUE - to_chat(user, "[C]'s [affecting.name] can not be healed with \the [src]!") + to_chat(user, "[C]'s [affecting.name] can not be healed with [src]!") return FALSE - ///Override this proc for special post heal effects. /obj/item/stack/medical/proc/post_heal_effects(amount_healed, mob/living/carbon/healed_mob, mob/user) return @@ -88,30 +108,11 @@ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_brute = 40 - self_delay = 40 - other_delay = 20 + self_delay = 4 SECONDS + other_delay = 2 SECONDS grind_results = list(/datum/reagent/medicine/c2/libital = 10) merge_type = /obj/item/stack/medical/bruise_pack -/obj/item/stack/medical/bruise_pack/heal(mob/living/M, mob/user) - if(M.stat == DEAD) - to_chat(user, "[M] is dead! You can not help [M.p_them()].") - return - if(isanimal(M)) - var/mob/living/simple_animal/critter = M - if (!(critter.healable)) - to_chat(user, "You cannot use \the [src] on [M]!") - return FALSE - else if (critter.health == critter.maxHealth) - to_chat(user, "[M] is at full health.") - return FALSE - user.visible_message("[user] applies \the [src] on [M].", "You apply \the [src] on [M].") - M.heal_bodypart_damage((heal_brute/2)) - return TRUE - if(iscarbon(M)) - return heal_carbon(M, user, heal_brute, heal_burn) - to_chat(user, "You can't heal [M] with \the [src]!") - /obj/item/stack/medical/bruise_pack/suicide_act(mob/user) user.visible_message("[user] is bludgeoning [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") return (BRUTELOSS) @@ -122,8 +123,8 @@ gender = PLURAL singular_name = "medical gauze" icon_state = "gauze" - self_delay = 50 - other_delay = 20 + self_delay = 5 SECONDS + other_delay = 2 SECONDS max_amount = 12 amount = 6 grind_results = list(/datum/reagent/cellulose = 2) @@ -158,7 +159,6 @@ return user.visible_message("[user] begins wrapping the wounds on [M]'s [limb.name] with [src]...", "You begin wrapping the wounds on [user == M ? "your" : "[M]'s"] [limb.name] with [src]...") - if(!do_after(user, (user == M ? self_delay : other_delay), target=M)) return @@ -182,27 +182,35 @@ return ..() /obj/item/stack/medical/gauze/suicide_act(mob/living/user) - user.visible_message("[user] begins tightening \the [src] around [user.p_their()] neck! It looks like [user.p_they()] forgot how to use medical supplies!") + user.visible_message("[user] begins tightening [src] around [user.p_their()] neck! It looks like [user.p_they()] forgot how to use medical supplies!") return OXYLOSS /obj/item/stack/medical/gauze/improvised name = "improvised gauze" singular_name = "improvised gauze" desc = "A roll of cloth roughly cut from something that does a decent job of stabilizing wounds, but less efficiently so than real medical gauze." - self_delay = 60 - other_delay = 30 + self_delay = 6 SECONDS + other_delay = 3 SECONDS absorption_rate = 0.15 absorption_capacity = 4 merge_type = /obj/item/stack/medical/gauze/improvised + /* + The idea is for the following medical devices to work like a hybrid of the old brute packs and tend wounds, + they heal a little at a time, have reduced healing density and does not allow for rapid healing while in combat. + However they provice graunular control of where the healing is directed, this makes them better for curing work-related cuts and scrapes. + + The interesting limb targeting mechanic is retained and i still believe they will be a viable choice, especially when healing others in the field. + */ + /obj/item/stack/medical/suture name = "suture" desc = "Basic sterile sutures used to seal up cuts and lacerations and stop bleeding." gender = PLURAL singular_name = "suture" icon_state = "suture" - self_delay = 30 - other_delay = 10 + self_delay = 3 SECONDS + other_delay = 1 SECONDS amount = 10 max_amount = 10 repeating = TRUE @@ -228,27 +236,6 @@ grind_results = list(/datum/reagent/medicine/polypyr = 1) merge_type = /obj/item/stack/medical/suture/medicated -/obj/item/stack/medical/suture/heal(mob/living/M, mob/user) - . = ..() - if(M.stat == DEAD) - to_chat(user, "[M] is dead! You can not help [M.p_them()].") - return - if(iscarbon(M)) - return heal_carbon(M, user, heal_brute, heal_burn) - if(isanimal(M)) - var/mob/living/simple_animal/critter = M - if (!(critter.healable)) - to_chat(user, "You cannot use \the [src] on [M]!") - return FALSE - else if (critter.health == critter.maxHealth) - to_chat(user, "[M] is at full health.") - return FALSE - user.visible_message("[user] applies \the [src] on [M].", "You apply \the [src] on [M].") - M.heal_bodypart_damage(heal_brute) - return TRUE - - to_chat(user, "You can't heal [M] with \the [src]!") - /obj/item/stack/medical/ointment name = "ointment" desc = "Basic burn ointment, rated effective for second degree burns with proper bandaging, though it's still an effective stabilizer for worse burns. Not terribly good at outright healing burns though." @@ -259,8 +246,8 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' amount = 8 max_amount = 8 - self_delay = 40 - other_delay = 20 + self_delay = 4 SECONDS + other_delay = 2 SECONDS heal_burn = 5 flesh_regeneration = 2.5 @@ -268,16 +255,8 @@ grind_results = list(/datum/reagent/medicine/c2/lenturi = 10) merge_type = /obj/item/stack/medical/ointment -/obj/item/stack/medical/ointment/heal(mob/living/M, mob/user) - if(M.stat == DEAD) - to_chat(user, "[M] is dead! You can not help [M.p_them()].") - return - if(iscarbon(M)) - return heal_carbon(M, user, heal_brute, heal_burn) - to_chat(user, "You can't heal [M] with \the [src]!") - /obj/item/stack/medical/ointment/suicide_act(mob/living/user) - user.visible_message("[user] is squeezing \the [src] into [user.p_their()] mouth! [user.p_do(TRUE)]n't [user.p_they()] know that stuff is toxic?") + user.visible_message("[user] is squeezing [src] into [user.p_their()] mouth! [user.p_do(TRUE)]n't [user.p_they()] know that stuff is toxic?") return TOXLOSS /obj/item/stack/medical/mesh @@ -286,8 +265,8 @@ gender = PLURAL singular_name = "mesh piece" icon_state = "regen_mesh" - self_delay = 30 - other_delay = 10 + self_delay = 3 SECONDS + other_delay = 1 SECONDS amount = 15 heal_burn = 10 max_amount = 15 @@ -311,33 +290,23 @@ else return ..() -/obj/item/stack/medical/mesh/heal(mob/living/M, mob/user) - . = ..() - if(M.stat == DEAD) - to_chat(user, "[M] is dead! You can not help [M.p_them()].") - return - if(iscarbon(M)) - return heal_carbon(M, user, heal_brute, heal_burn) - to_chat(user, "You can't heal [M] with \the [src]!") - - /obj/item/stack/medical/mesh/try_heal(mob/living/M, mob/user, silent = FALSE) if(!is_open) to_chat(user, "You need to open [src] first.") return - . = ..() + return ..() /obj/item/stack/medical/mesh/AltClick(mob/living/user) if(!is_open) to_chat(user, "You need to open [src] first.") return - . = ..() + return ..() /obj/item/stack/medical/mesh/attack_hand(mob/user) if(!is_open && user.get_inactive_held_item() == src) to_chat(user, "You need to open [src] first.") return - . = ..() + return ..() /obj/item/stack/medical/mesh/attack_self(mob/user) if(!is_open) @@ -346,7 +315,7 @@ update_icon() playsound(src, 'sound/items/poster_ripped.ogg', 20, TRUE) return - . = ..() + return ..() /obj/item/stack/medical/mesh/advanced name = "advanced regenerative mesh" @@ -368,50 +337,22 @@ /obj/item/stack/medical/aloe name = "aloe cream" - desc = "A healing paste you can apply on wounds." + desc = "A healing paste for minor cuts and burns." gender = PLURAL singular_name = "aloe cream" icon_state = "aloe_paste" - self_delay = 20 - other_delay = 10 + self_delay = 2 SECONDS + other_delay = 1 SECONDS novariants = TRUE amount = 20 max_amount = 20 repeating = TRUE - var/heal = 3 + heal_brute = 3 + heal_burn = 3 grind_results = list(/datum/reagent/consumable/aloejuice = 1) merge_type = /obj/item/stack/medical/aloe -/obj/item/stack/medical/aloe/heal(mob/living/M, mob/user) - . = ..() - if(M.stat == DEAD) - to_chat(user, "[M] is dead! You can not help [M.p_them()].") - return FALSE - if(iscarbon(M)) - return heal_carbon(M, user, heal, heal) - if(isanimal(M)) - var/mob/living/simple_animal/critter = M - if (!(critter.healable)) - to_chat(user, "You cannot use \the [src] on [M]!") - return FALSE - else if (critter.health == critter.maxHealth) - to_chat(user, "[M] is at full health.") - return FALSE - user.visible_message("[user] applies \the [src] on [M].", "You apply \the [src] on [M].") - M.heal_bodypart_damage(heal, heal) - return TRUE - - to_chat(user, "You can't heal [M] with the \the [src]!") - - /* - The idea is for these medical devices to work like a hybrid of the old brute packs and tend wounds, - they heal a little at a time, have reduced healing density and does not allow for rapid healing while in combat. - However they provice graunular control of where the healing is directed, this makes them better for curing work-related cuts and scrapes. - - The interesting limb targeting mechanic is retained and i still believe they will be a viable choice, especially when healing others in the field. - */ - /obj/item/stack/medical/bone_gel name = "bone gel" singular_name = "bone gel" @@ -433,26 +374,27 @@ return /obj/item/stack/medical/bone_gel/suicide_act(mob/user) - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.visible_message("[C] is squirting all of \the [src] into [C.p_their()] mouth! That's not proper procedure! It looks like [C.p_theyre()] trying to commit suicide!") - if(do_after(C, 2 SECONDS)) - C.emote("scream") - for(var/i in C.bodyparts) - var/obj/item/bodypart/bone = i - var/datum/wound/blunt/severe/oof_ouch = new - oof_ouch.apply_wound(bone) - var/datum/wound/blunt/critical/oof_OUCH = new - oof_OUCH.apply_wound(bone) + if(!iscarbon(user)) + return + var/mob/living/carbon/C = user + C.visible_message("[C] is squirting all of [src] into [C.p_their()] mouth! That's not proper procedure! It looks like [C.p_theyre()] trying to commit suicide!") + if(!do_after(C, 2 SECONDS)) + C.visible_message("[C] screws up like an idiot and still dies anyway!") + return (BRUTELOSS) - for(var/i in C.bodyparts) - var/obj/item/bodypart/bone = i - bone.receive_damage(brute=60) - use(1) - return (BRUTELOSS) - else - C.visible_message("[C] screws up like an idiot and still dies anyway!") - return (BRUTELOSS) + C.emote("scream") + for(var/i in C.bodyparts) + var/obj/item/bodypart/bone = i + var/datum/wound/blunt/severe/oof_ouch = new + oof_ouch.apply_wound(bone) + var/datum/wound/blunt/critical/oof_OUCH = new + oof_OUCH.apply_wound(bone) + + for(var/i in C.bodyparts) + var/obj/item/bodypart/bone = i + bone.receive_damage(brute=60) + use(1) + return (BRUTELOSS) /obj/item/stack/medical/poultice name = "mourning poultices" @@ -472,10 +414,10 @@ merge_type = /obj/item/stack/medical/poultice /obj/item/stack/medical/poultice/heal(mob/living/M, mob/user) - . = .. () if(iscarbon(M)) playsound(src, 'sound/misc/soggy.ogg', 30, TRUE) return heal_carbon(M, user, heal_brute, heal_burn) + return ..() /obj/item/stack/medical/poultice/post_heal_effects(amount_healed, mob/living/carbon/healed_mob, mob/user) . = ..()