From 65b8eafe8e00929b53c71813730d98db317c9f32 Mon Sep 17 00:00:00 2001 From: cib Date: Mon, 4 Mar 2013 12:19:12 +0100 Subject: [PATCH] Added internal organs. They can be hurt by their parent organ getting hurt. Ruptured lungs are now represented as damage to the lungs internal organ. --- code/datums/organs/organ_external.dm | 11 +++- code/datums/organs/organ_internal.dm | 52 ++++++++++++++++ code/datums/organs/pain.dm | 7 +++ code/game/machinery/adv_med.dm | 7 ++- code/modules/mob/living/carbon/human/human.dm | 21 ++++--- code/modules/mob/living/carbon/human/life.dm | 26 ++++++++ code/modules/surgery/ribcage.dm | 60 +++++++++++++++---- 7 files changed, 163 insertions(+), 21 deletions(-) diff --git a/code/datums/organs/organ_external.dm b/code/datums/organs/organ_external.dm index 7710fb6a4f7..31dc038c2cb 100644 --- a/code/datums/organs/organ_external.dm +++ b/code/datums/organs/organ_external.dm @@ -25,6 +25,9 @@ var/datum/organ/external/parent var/list/datum/organ/external/children + // Internal organs of this body part + var/list/datum/organ/internal/internal_organs + var/damage_msg = "\red You feel an intense pain" var/broken_description @@ -93,6 +96,13 @@ droplimb(1) return + // High brute damage or sharp objects may damage internal organs + if(internal_organs != null) if( (sharp && brute >= 5) || brute >= 10) if(prob(5)) + // Damage an internal organ + var/datum/organ/internal/I = pick(internal_organs) + I.take_damage(brute / 2) + brute -= brute / 2 + if(status & ORGAN_BROKEN && prob(40) && brute) owner.emote("scream") //getting hit on broken hand hurts if(used_weapon) @@ -555,7 +565,6 @@ max_damage = 150 min_broken_damage = 75 body_part = UPPER_TORSO - var/ruptured_lungs = 0 /datum/organ/external/groin name = "groin" diff --git a/code/datums/organs/organ_internal.dm b/code/datums/organs/organ_internal.dm index c6490c71c86..f670b39420f 100644 --- a/code/datums/organs/organ_internal.dm +++ b/code/datums/organs/organ_internal.dm @@ -1,6 +1,8 @@ /**************************************************** INTERNAL ORGANS ****************************************************/ + +/* /datum/organ/internal name = "internal" var/damage = 0 @@ -62,3 +64,53 @@ var/lungs = null var/stomach = null +*/ + +/mob/living/carbon/human/var/list/internal_organs = list() + +/datum/organ/internal + // amount of damage to the organ + var/damage = 0 + var/min_bruised_damage = 10 + var/min_broken_damage = 30 + var/parent_organ = "chest" + +/datum/organ/internal/proc/is_bruised() + return damage >= min_bruised_damage + +/datum/organ/internal/proc/is_broken() + return damage >= min_broken_damage + + +/datum/organ/internal/New(mob/living/carbon/human/H) + ..() + var/datum/organ/external/E = H.organs_by_name[src.parent_organ] + if(E.internal_organs == null) + E.internal_organs = list() + E.internal_organs += src + H.internal_organs[src.name] = src + src.owner = H + +/datum/organ/internal/proc/take_damage(amount) + src.damage += amount + + var/datum/organ/external/parent = owner.get_organ(parent_organ) + owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1) + +/datum/organ/internal/heart + name = "heart" + parent_organ = "chest" + + +/datum/organ/internal/lungs + name = "lungs" + parent_organ = "chest" + +/datum/organ/internal/liver + name = "liver" + parent_organ = "chest" + + +/datum/organ/internal/kidney + name = "kidney" + parent_organ = "chest" \ No newline at end of file diff --git a/code/datums/organs/pain.dm b/code/datums/organs/pain.dm index 750cd75f33a..820ef5a077c 100644 --- a/code/datums/organs/pain.dm +++ b/code/datums/organs/pain.dm @@ -81,3 +81,10 @@ mob/living/carbon/human/proc/handle_pain() maxdam = dam if(damaged_organ) pain(damaged_organ.display_name, maxdam, 0) + + // Damage to internal organs hurts a lot. + for(var/organ_name in internal_organs) + var/datum/organ/internal/I = internal_organs[organ_name] + if(I.damage > 2) if(prob(2)) + var/datum/organ/external/parent = get_organ(I.parent_organ) + src.custom_pain("You feel a sharp pain in your [parent.display_name]", 1) \ No newline at end of file diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index ef556cbc701..52282558e7a 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -286,7 +286,7 @@ for(var/datum/wound/W in e.wounds) if(W.internal) internal_bleeding = "
Internal Bleeding" break - if(istype(e, /datum/organ/external/chest) && e:ruptured_lungs) + if(istype(e, /datum/organ/external/chest) && occupant.is_lung_ruptured()) lung_ruptured = "Lung Ruptured:" if(e.status & ORGAN_SPLINTED) splint = "Splinted:" @@ -305,6 +305,11 @@ else dat += "[e.display_name]--Not Found" dat += "" + for(var/organ_name in occupant.internal_organs) + var/datum/organ/internal/i = occupant.internal_organs[organ_name] + dat += "" + dat += "[i.name]N/A[i.damage]None:" + dat += "" dat += "" else dat += "\The [src] is empty." diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1adee6f3054..666ba1d820c 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -38,6 +38,11 @@ organs_by_name["l_foot"] = new/datum/organ/external/l_foot(organs_by_name["l_leg"]) organs_by_name["r_foot"] = new/datum/organ/external/r_foot(organs_by_name["r_leg"]) + new/datum/organ/internal/heart(src) + new/datum/organ/internal/lungs(src) + new/datum/organ/internal/liver(src) + new/datum/organ/internal/kidney(src) + // connect feet to legs and hands to arms /* var/datum/organ/external/organ = organs_by_name["l_hand"] @@ -899,26 +904,24 @@ H.brainmob.mind.transfer_to(src) del(H) - var/datum/organ/external/chest/E = get_organ("chest") - if(E.ruptured_lungs == 1) - E.ruptured_lungs = 0 + for(var/datum/organ/internal/I in internal_organs) + I.damage = 0 for (var/datum/disease/virus in viruses) virus.cure() ..() /mob/living/carbon/human/proc/is_lung_ruptured() - var/datum/organ/external/chest/E = get_organ("chest") - return E.ruptured_lungs - + var/datum/organ/internal/lungs/L = internal_organs["lungs"] + return L.is_bruised() /mob/living/carbon/human/proc/rupture_lung() - var/datum/organ/external/chest/E = get_organ("chest") + var/datum/organ/internal/lungs/L = internal_organs["lungs"] - if(E.ruptured_lungs == 0) + if(!L.is_bruised()) src.custom_pain("You feel a stabbing pain in your chest!", 1) + L.damage = L.min_bruised_damage - E.ruptured_lungs = 1 /* /mob/living/carbon/human/verb/simulate() set name = "sim" diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index d24f835153f..63931927e84 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -155,6 +155,16 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //At this point, we dun care which blood we are adding to, as long as they get more blood. B.volume = B.volume + 0.1 // regenerate blood VERY slowly + // Damaged heart virtually reduces the blood volume, as the blood isn't + // being pumped properly anymore. + var/datum/organ/internal/heart/heart = internal_organs["heart"] + switch(heart.damage) + if(5 to 10) + blood_volume *= 0.8 + if(11 to 20) + blood_volume *= 0.5 + if(21 to INFINITY) + blood_volume *= 0.3 switch(blood_volume) if(BLOOD_VOLUME_SAFE to 10000) @@ -1044,6 +1054,22 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 var/datum/organ/O = pick(organs) O.trace_chemicals[A.name] = 100 + var/damaged_liver_process_accuracy = 10 + if(life_tick % damaged_liver_process_accuracy == 0) + // Damaged liver means some chemicals are very dangerous + var/datum/organ/internal/liver/liver = internal_organs["liver"] + if(liver.damage >= liver.min_bruised_damage) + for(var/datum/reagent/R in src.reagents.reagent_list) + // Ethanol and all drinks are bad + if(istype(R, /datum/reagent/ethanol)) + adjustToxLoss(0.1 * damaged_liver_process_accuracy) + + // Can't cope with toxins at all + for(var/toxin in list("toxin", "plasma", "sacid", "pacid", "cyanide", "lexorin", "amatoxin", "chloralhydrate", "carpotoxin", "zombiepowder", "mindbreaker")) + if(src.reagents.has_reagent(toxin)) + adjustToxLoss(0.3 * damaged_liver_process_accuracy) + + updatehealth() return //TODO: DEFERRED diff --git a/code/modules/surgery/ribcage.dm b/code/modules/surgery/ribcage.dm index de5325f9821..b4d304b0eea 100644 --- a/code/modules/surgery/ribcage.dm +++ b/code/modules/surgery/ribcage.dm @@ -109,7 +109,7 @@ affected.fracture() if (prob(40)) user.visible_message("\red Rib pierces the lung!") - affected.ruptured_lungs = 1 + target.rupture_lung() /datum/surgery_step/ribcage/mend_ribcage required_tool = /obj/item/weapon/bonegel @@ -168,9 +168,9 @@ ////////////////////////////////////////////////////////////////// -// LUNG SURGERY // +// CHEST INTERNAL ORGAN SURGERY // ////////////////////////////////////////////////////////////////// -/datum/surgery_step/ribcage/fix_lungs +/datum/surgery_step/ribcage/fix_chest_internal required_tool = /obj/item/weapon/scalpel allowed_tools = list(/obj/item/weapon/shard, /obj/item/weapon/kitchenknife) @@ -178,19 +178,59 @@ max_duration = 90 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.is_lung_ruptured() && target.op_stage.ribcage == 2 + var/is_chest_organ_damaged = 0 + var/datum/organ/external/chest/chest = target.get_organ("chest") + for(var/datum/organ/internal/I in chest.internal_organs) if(I.damage > 0) + is_chest_organ_damaged = 1 + break + return ..() && is_chest_organ_damaged && target.op_stage.ribcage == 2 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts mending the rupture in [target]'s lungs with \the [tool].", \ - "You start mending the rupture in [target]'s lungs with \the [tool]." ) + var/datum/organ/internal/heart/heart = target.internal_organs["heart"] + var/datum/organ/internal/lungs/lungs = target.internal_organs["lungs"] + var/datum/organ/internal/liver/liver = target.internal_organs["liver"] + var/datum/organ/internal/liver/kidney = target.internal_organs["kidney"] + + if(lungs.damage > 0) + user.visible_message("[user] starts mending the rupture in [target]'s lungs with \the [tool].", \ + "You start mending the rupture in [target]'s lungs with \the [tool]." ) + if(heart.damage > 0) + user.visible_message("[user] starts mending the bruises on [target]'s heart with \the [tool].", \ + "You start mending the bruises on [target]'s heart with \the [tool]." ) + if(liver.damage > 0) + user.visible_message("[user] starts mending the bruises on [target]'s liver with \the [tool].", \ + "You start mending the bruises on [target]'s liver with \the [tool]." ) + if(kidney.damage > 0) + user.visible_message("[user] starts mending the bruises on [target]'s liver with \the [tool].", \ + "You start mending the bruises on [target]'s kidney with \the [tool]." ) target.custom_pain("The pain in your chest is living hell!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ("chest") - user.visible_message("\blue [user] mends the rupture in [target]'s lungs with \the [tool].", \ - "\blue You mend the rupture in [target]'s lungs with \the [tool]." ) - affected.ruptured_lungs = 0 + var/datum/organ/internal/heart/heart = target.internal_organs["heart"] + var/datum/organ/internal/lungs/lungs = target.internal_organs["lungs"] + var/datum/organ/internal/liver/liver = target.internal_organs["liver"] + var/datum/organ/internal/liver/kidney = target.internal_organs["kidney"] + + if(lungs.damage > 0) + user.visible_message("\blue [user] mends the rupture in [target]'s lungs with \the [tool].", \ + "\blue You mend the rupture in [target]'s lungs with \the [tool]." ) + lungs.damage = 0 + + if(heart.damage > 0) + user.visible_message("\blue [user] treats the bruises on [target]'s heart with \the [tool].", \ + "\blue You treats the bruises on [target]'s heart with \the [tool]." ) + heart.damage = 0 + + if(liver.damage > 0) + user.visible_message("\blue [user] treats the bruises on [target]'s liver with \the [tool].", \ + "\blue You treats the bruises on [target]'s liver with \the [tool]." ) + liver.damage = 0 + + if(kidney.damage > 0) + user.visible_message("\blue [user] treats the bruises on [target]'s kidney with \the [tool].", \ + "\blue You treats the bruises on [target]'s kidney with \the [tool]." ) + kidney.damage = 0 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/datum/organ/external/chest/affected = target.get_organ("chest")