diff --git a/code/__DEFINES/damage_organs.dm b/code/__DEFINES/damage_organs.dm index ec97a717866..8601d48053a 100644 --- a/code/__DEFINES/damage_organs.dm +++ b/code/__DEFINES/damage_organs.dm @@ -92,3 +92,9 @@ // (e.g. 0.6 == 60% lost if 200 burn damage is taken). #define FLUIDLOSS_WIDE_BURN 0.3 //for burns from heat applied over a wider area, like from fire #define FLUIDLOSS_CONC_BURN 0.2 //for concentrated burns, like from lasers + +// The bandage levels a limb can have, basically how badly bandaged up their are +#define BANDAGE_LEVEL_NONE 0 +#define BANDAGE_LEVEL_LIGHT 1 +#define BANDAGE_LEVEL_MEDIUM 2 +#define BANDAGE_LEVEL_HEAVY 3 diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 9ea50eb2c19..1e2cea16f14 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -182,6 +182,7 @@ Contains: else to_chat(user, SPAN_WARNING("\The [src] is used up, but there are more wounds to treat on \the [affecting.name].")) use(used) + affecting.bandage_level = affecting.possible_bandage_level() H.update_bandages(TRUE) else if (can_operate(H)) //Checks if mob is lying down on table for surgery @@ -310,6 +311,7 @@ Contains: else to_chat(user, SPAN_WARNING("\The [src] is used up, but there are more wounds to treat on \the [affecting.name].")) use(used) + affecting.bandage_level = affecting.possible_bandage_level() H.update_bandages(TRUE) else if (can_operate(H)) //Checks if mob is lying down on table for surgery diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index e93b23a6c08..58de05c0edb 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -514,3 +514,71 @@ if(wrists.clean_blood()) update_inv_wrists(0) clean_blood(washshoes) + +/// Handles removing bandages from specific limbs or all of them at once, added conditionally based on whether the limb has any bandages on in the first place +/mob/living/carbon/human/proc/remove_bandages() + set name = "Remove Bandages" + set category = "IC" + set src in view(1) + + // to make this all easier, i'm restricting the verb actioner to humans only + var/mob/living/carbon/human/remover = usr + if(!istype(remover)) + to_chat(SPAN_WARNING("You cannot remove bandages!")) + return + + // get all the body parts covered by thick clothing, so you cant strip bandages from underneath someone's armour / voidsuit + var/covered_body_parts = get_covered_body_parts(TRUE) + + var/list/possible_limbs = list() + for(var/obj/item/organ/external/limb in organs) + if(covered_body_parts & limb.body_part) + continue + + if(limb.is_stump()) + continue + + // check if it even has bandages + var/bandage_level = limb.bandage_level + if(!bandage_level) + continue + + // if it has bandages, check whether it's possible to remove some + var/possible_bandage_level = limb.possible_bandage_level() + if(possible_bandage_level >= bandage_level) + continue + + possible_limbs[capitalize_first_letters(limb.name)] = limb + + if(!length(possible_limbs)) + to_chat(remover, SPAN_WARNING("\The [src] has no bandages you can remove!")) + return + + possible_limbs["All"] = TRUE + + var/selected_limb = tgui_input_list(remover, "Which limb would you like to remove the bandages from?", "Bandage Removal", possible_limbs, "All") + if(!selected_limb) + return + + if(!remover.Adjacent(src)) + to_chat(remover, SPAN_WARNING("You need to stay next to \the [src]!")) + return + + if(selected_limb == "All") + remover.visible_message(SPAN_NOTICE("\The [remover] begins removing bandages from all of \the [src]'s damaged limbs..."), SPAN_NOTICE("You begin removing bandages from all of \the [src]'s damaged limbs...")) + if(!do_after(remover, 3 SECONDS, src)) + return + possible_limbs -= "All" + for(var/limb_name in possible_limbs) + var/obj/item/organ/external/limb = possible_limbs[limb_name] + limb.bandage_level = limb.possible_bandage_level() + update_bandages() + remover.visible_message(SPAN_NOTICE("\The [remover] removed the bandages from all of \the [src]'s damaged limbs!"), SPAN_NOTICE("You removed the bandages from all of \the [src]'s damaged limbs!")) + else + var/obj/item/organ/external/limb = possible_limbs[selected_limb] + remover.visible_message(SPAN_NOTICE("\The [remover] begins removing bandages from \the [src]'s [limb.name]..."), SPAN_NOTICE("You begin removing bandages \the [src]'s [limb.name]...")) + if(!do_after(remover, 1 SECOND, src)) + return + limb.bandage_level = limb.possible_bandage_level() + update_bandages() + remover.visible_message(SPAN_NOTICE("\The [remover] removed the bandages from \the [src]'s [limb.name]!"), SPAN_NOTICE("You removed the bandages \the [src]'s [limb.name]!")) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index c200dc85c06..af31896fae6 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -951,7 +951,7 @@ var/bandage_icon = species.bandages_icon if(!bandage_icon) continue - var/bandage_level = O.bandage_level() + var/bandage_level = O.bandage_level if(bandage_level) health_images += image(bandage_icon, "[O.icon_name][bandage_level]") diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 721f48cfb76..6d880cd85b8 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -246,19 +246,32 @@ There are several things that need to be remembered: if(update_icons) update_icon() +/// Handles displaying bandages on the mob icon, and whether the mob should have the add/remove bandages verb attached to it /mob/living/carbon/human/proc/update_bandages(var/update_icons = TRUE) var/bandage_icon = species.bandages_icon if(!bandage_icon) return var/list/ovr - if(overlays_raw[MOB_DAMAGE_LAYER]) - for(var/obj/item/organ/external/O in organs) - if(O.is_stump()) - continue - var/bandage_level = O.bandage_level() - if(bandage_level) - LAZYADD(ovr, image(bandage_icon, "[O.icon_name][bandage_level]")) + for(var/obj/item/organ/external/O in organs) + if(O.is_stump()) + continue + var/bandage_level = O.bandage_level + if(bandage_level) + LAZYADD(ovr, image(bandage_icon, "[O.icon_name][bandage_level]")) + + // this next part handles whether the mob should have the Remove Bandages verb available + // obviously this is a little hacky, since this is the icon update function, but it's also the best place we loop through + // the various organs and calculate their bandage level + var/had_bandages = LAZYLEN(overlays_raw[BANDAGE_LAYER]) + var/has_bandages = LAZYLEN(ovr) + + // gained bandages + if(!had_bandages && has_bandages) + add_verb(src, /mob/living/carbon/human/proc/remove_bandages) + // lost bandages + else if(had_bandages && !has_bandages) + remove_verb(src, /mob/living/carbon/human/proc/remove_bandages) overlays_raw[BANDAGE_LAYER] = ovr if(update_icons) @@ -268,7 +281,6 @@ There are several things that need to be remembered: //eg: ammo counters, primed grenade flashing, etc. //"icon_file" is used automatically for inhands etc. to make sure it gets the correct inhand file /obj/item/proc/worn_overlays(icon_file) - . = null . = list() var/mutable_appearance/M = null if(build_from_parts) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index aca8eb09566..17e9e1f8920 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -153,6 +153,9 @@ var/body_hair var/painted = 0 + /// The amount of bandages on our sprite + var/bandage_level = BANDAGE_LEVEL_NONE + ///For special projectile gibbing calculation, dubbed "maiming" var/maim_bonus = 0 @@ -455,8 +458,6 @@ update_damages() if(owner) owner.updatehealth() //droplimb will call updatehealth() again if it does end up being called - if(status & ORGAN_BLEEDING) - owner.update_bandages() return update_icon() @@ -603,8 +604,10 @@ This function completely restores a damaged organ to perfect condition. //Possibly trigger an internal wound, too. var/local_damage = brute_dam + burn_dam + damage + var/is_burn_type_damage = (type in list(DAMAGE_BURN, LASER)) + if(damage > (min_broken_damage / 2) && local_damage > min_broken_damage && !(status & ORGAN_ROBOT)) - if(!(type in list(DAMAGE_BURN, LASER))) + if(!is_burn_type_damage) if(prob(damage) && sever_artery()) owner.custom_pain("You feel something rip in your [name]!", 25) @@ -616,7 +619,7 @@ This function completely restores a damaged organ to perfect condition. tendon.damage(new_brute) //Burn damage can cause fluid loss due to blistering and cook-off - if((type in list(DAMAGE_BURN, LASER)) && (damage > 5 || damage + burn_dam >= 15) && !BP_IS_ROBOTIC(src)) + if(is_burn_type_damage && (damage > 5 || damage + burn_dam >= 15) && !BP_IS_ROBOTIC(src)) var/fluid_loss_severity switch(type) if(DAMAGE_BURN) @@ -638,6 +641,12 @@ This function completely restores a damaged organ to perfect condition. if(compatible_wounds.len) var/datum/wound/W = pick(compatible_wounds) W.open_wound(damage) + + if(bandage_level) + owner.visible_message(SPAN_WARNING("The bandages on [owner.name]'s [name] gets [is_burn_type_damage ? "burnt" : "ripped"] off!"), SPAN_WARNING("The bandages on your [name] gets [is_burn_type_damage ? "burnt" : "ripped"] off!")) + bandage_level = BANDAGE_LEVEL_NONE + owner.update_bandages() + if(prob(25)) if(status & ORGAN_ROBOT) owner.visible_message(SPAN_WARNING("The damage to [owner.name]'s [name] worsens."),\ @@ -647,6 +656,7 @@ This function completely restores a damaged organ to perfect condition. owner.visible_message(SPAN_WARNING("The wound on [owner.name]'s [name] widens with a nasty ripping noise."),\ SPAN_WARNING("The wound on your [name] widens with a nasty ripping noise."),\ "You hear a nasty ripping noise, as if flesh is being torn apart.") + return //Creating wound @@ -664,6 +674,11 @@ This function completely restores a damaged organ to perfect condition. if(W) wounds += W + if(bandage_level) + owner.visible_message(SPAN_WARNING("The bandages on [owner.name]'s [name] gets [is_burn_type_damage ? "burnt" : "ripped"] off!"), SPAN_WARNING("The bandages on your [name] gets [is_burn_type_damage ? "burnt" : "ripped"] off!")) + bandage_level = BANDAGE_LEVEL_NONE + owner.update_bandages() + /**************************************************** PROCESSING & UPDATING ****************************************************/ diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 7c36614aeb9..4c2583beedd 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -348,16 +348,17 @@ var/list/robot_hud_colours = list("#ffffff","#cccccc","#aaaaaa","#888888","#6666 hud_damage_image.color = hud_colours[max(1,min(Ceiling(dam_state*hud_colours.len),hud_colours.len))] return hud_damage_image -/obj/item/organ/external/proc/bandage_level() +/// Returns the possible bandage level the external can have right now, see medical.dm for usage +/obj/item/organ/external/proc/possible_bandage_level() if(damage_state_text() == "00") - return 0 + return BANDAGE_LEVEL_NONE if(!is_bandaged()) - return 0 + return BANDAGE_LEVEL_NONE if(burn_dam + brute_dam == 0) - . = 0 + . = BANDAGE_LEVEL_NONE else if (burn_dam + brute_dam < (max_damage * 0.25 / 2)) - . = 1 + . = BANDAGE_LEVEL_LIGHT else if (burn_dam + brute_dam < (max_damage * 0.75 / 2)) - . = 2 + . = BANDAGE_LEVEL_MEDIUM else - . = 3 + . = BANDAGE_LEVEL_HEAVY diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm index 0e6ab4b3749..2378b051078 100644 --- a/code/modules/organs/wound.dm +++ b/code/modules/organs/wound.dm @@ -185,6 +185,8 @@ src.desc = desc_list[current_stage] src.min_damage = damage_list[current_stage] + src.bandaged = FALSE + // returns whether this wound can absorb the given amount of damage. // this will prevent large amounts of damage being trapped in less severe wound types /datum/wound/proc/can_worsen(damage_type, damage) diff --git a/html/changelogs/geeves-persistent_bandages.yml b/html/changelogs/geeves-persistent_bandages.yml new file mode 100644 index 00000000000..61ba0c164ca --- /dev/null +++ b/html/changelogs/geeves-persistent_bandages.yml @@ -0,0 +1,7 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Bandages now do not disappear as damage heals, instead, a special Remove Bandages verb must be used to remove bandages. This cannot be used to re-open wounds for now, and can only be used if the bandage would've downgraded / disappeared at that point." + - balance: "Taking damage on a bandaged limb now removes the bandages."