diff --git a/code/__DEFINES/mob.dm b/code/__DEFINES/mob.dm
index 588f8526ca1..dde491fbb80 100644
--- a/code/__DEFINES/mob.dm
+++ b/code/__DEFINES/mob.dm
@@ -2,17 +2,13 @@
// Organ defines.
#define ORGAN_CUT_AWAY 1
-#define ORGAN_GAUZED 2
-#define ORGAN_ATTACHABLE 4
-#define ORGAN_BLEEDING 8
-#define ORGAN_BROKEN 32
-#define ORGAN_DESTROYED 64
-#define ORGAN_ROBOT 128
-#define ORGAN_SPLINTED 256
-#define SALVED 512
-#define ORGAN_DEAD 1024
-#define ORGAN_MUTATED 2048
-#define ORGAN_ASSISTED 4096
+#define ORGAN_BROKEN 2
+#define ORGAN_DESTROYED 4
+#define ORGAN_ROBOT 8
+#define ORGAN_SPLINTED 16
+#define ORGAN_DEAD 32
+#define ORGAN_MUTATED 64
+#define ORGAN_ASSISTED 128
#define DROPLIMB_SHARP 0
#define DROPLIMB_BLUNT 1
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 2ab267ce5a8..ff313e62fb3 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -96,11 +96,7 @@
var/health_threshold_crit = 0
var/health_threshold_dead = -100
- var/organ_health_multiplier = 1
- var/organ_regeneration_multiplier = 1
-
var/bones_can_break = 1
- var/limbs_can_break = 1
var/revival_pod_plants = 1
var/revival_cloning = 1
@@ -632,14 +628,8 @@
config.slime_delay = value
if("animal_delay")
config.animal_delay = value
- if("organ_health_multiplier")
- config.organ_health_multiplier = value / 100
- if("organ_regeneration_multiplier")
- config.organ_regeneration_multiplier = value / 100
if("bones_can_break")
config.bones_can_break = value
- if("limbs_can_break")
- config.limbs_can_break = value
if("shuttle_refuel_delay")
config.shuttle_refuel_delay = text2num(value)
if("traitor_objectives_amount")
diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm
index 376e6d5a148..3bef09d2645 100644
--- a/code/game/gamemodes/changeling/powers/revive.dm
+++ b/code/game/gamemodes/changeling/powers/revive.dm
@@ -42,13 +42,11 @@
O.damage_state = "00"
O.germ_level = 0
QDEL_NULL(O.hidden)
- O.number_wounds = 0
O.open = 0
+ O.internal_bleeding = FALSE
O.perma_injury = 0
O.status = 0
O.trace_chemicals.Cut()
- QDEL_LIST(O.wounds)
- O.wound_update_accuracy = 1
for(var/obj/item/organ/internal/IO in H.internal_organs)
IO.damage = 0
IO.trace_chemicals.Cut()
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 6514ef82c47..c8cf45665cd 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -429,10 +429,8 @@
if(istype(E, /obj/item/organ/external/chest) && H.is_lung_ruptured())
organData["lungRuptured"] = 1
- for(var/datum/wound/W in E.wounds)
- if(W.internal)
- organData["internalBleeding"] = 1
- break
+ if(E.internal_bleeding)
+ organData["internalBleeding"] = 1
extOrganData.Add(list(organData))
@@ -580,9 +578,8 @@
var/splint = ""
var/internal_bleeding = ""
var/lung_ruptured = ""
- for(var/datum/wound/W in e.wounds) if(W.internal)
+ if(e.internal_bleeding)
internal_bleeding = "
Internal bleeding"
- break
if(istype(e, /obj/item/organ/external/chest) && occupant.is_lung_ruptured())
lung_ruptured = "Lung ruptured:"
if(e.status & ORGAN_SPLINTED)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 53b05ef48d1..c716d060d27 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -216,7 +216,7 @@ REAGENT SCANNER
user.show_message(text("Bone fractures detected. Advanced scanner required for location."), 1)
break
for(var/obj/item/organ/external/e in H.bodyparts)
- for(var/datum/wound/W in e.wounds) if(W.internal)
+ if(e.internal_bleeding)
user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1)
break
var/blood_id = H.get_blood_id()
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 04be0d53a1a..3be1404a030 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -96,8 +96,7 @@
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open == 0)
- affecting.bandage()
- affecting.disinfect()
+ affecting.germ_level = 0
user.visible_message("[user] bandages the wounds on [H]'s [affecting.name].", \
"You bandage the wounds on [H]'s [affecting.name]." )
@@ -142,7 +141,7 @@
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open == 0)
- affecting.salve()
+ affecting.germ_level = 0
user.visible_message("[user] salves the wounds on [H]'s [affecting.name].", \
"You salve the wounds on [H]'s [affecting.name]." )
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 15d9201b5cc..4de2dff6212 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -224,7 +224,7 @@
if(brutedamage > 0)
status = "bruised"
if(brutedamage > 20)
- status = "bleeding"
+ status = "battered"
if(brutedamage > 40)
status = "mangled"
if(brutedamage > 0 && burndamage > 0)
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index a409e8460db..c8171bcc47c 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -8,8 +8,6 @@
var/life_tick = 0 // The amount of life ticks that have processed on this mob.
- // total amount of wounds on mob, used to spread out healing and the like over all wounds
- var/number_wounds = 0
var/obj/item/handcuffed = null //Whether or not the mob is handcuffed
var/obj/item/legcuffed = null //Same as handcuffs but for legs. Bear traps use this.
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 70034def245..299006c102d 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -191,16 +191,6 @@
//ID
if(wear_id)
- /*var/id
- if(istype(wear_id, /obj/item/device/pda))
- var/obj/item/device/pda/pda = wear_id
- id = pda.owner
- else if(istype(wear_id, /obj/item/weapon/card/id)) //just in case something other than a PDA/ID card somehow gets in the ID slot :[
- var/obj/item/weapon/card/id/idcard = wear_id
- id = idcard.registered_name
- if(id && (id != real_name) && (get_dist(src, user) <= 1) && prob(10))
- msg += "[t_He] [t_is] wearing [bicon(wear_id)] \a [wear_id] yet something doesn't seem right...\n"
- else*/
msg += "[t_He] [t_is] wearing [bicon(wear_id)] \a [wear_id].\n"
//Jitters
@@ -212,80 +202,32 @@
if(100 to 200)
msg += "[t_He] [t_is] twitching ever so slightly.\n"
- //splints
- for(var/organ in list("l_leg","r_leg","l_arm","r_arm"))
- var/obj/item/organ/external/o = get_organ(organ)
- if(o && o.status & ORGAN_SPLINTED)
- msg += "[t_He] [t_has] a splint on his [o.name]!\n"
- if(suiciding)
- msg += "[t_He] appears to have commited suicide... there is no hope of recovery.\n"
-
- if(DWARF in mutations)
- msg += "[t_He] [t_is] a halfling!\n"
-
- var/distance = get_dist(user,src)
- if(istype(user, /mob/dead/observer) || user.stat == 2) // ghosts can see anything
- distance = 1
- if(src.stat)
- msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
- if((stat == 2 || src.health <= config.health_threshold_crit) && distance <= 3)
- msg += "[t_He] does not appear to be breathing.\n"
- if(istype(user, /mob/living/carbon/human) && !user.stat && distance <= 1)
- for(var/mob/O in viewers(user.loc, null))
- O.show_message("[user] checks [src]'s pulse.", 1)
- spawn(15)
- if(distance <= 1 && user.stat != 1)
- if(pulse == PULSE_NONE)
- to_chat(user, "[t_He] has no pulse[src.client ? "" : " and [t_his] soul has departed"]...")
- else
- to_chat(user, "[t_He] has a pulse!")
-
- msg += ""
- if(fire_stacks > 0)
- msg += "[t_He] [t_is] covered in something flammable.\n"
- if(fire_stacks < 0)
- msg += "[t_He] looks a little soaked.\n"
-
- switch(wetlevel)
- if(1)
- msg += "[t_He] looks a bit damp.\n"
- if(2)
- msg += "[t_He] looks a little bit wet.\n"
- if(3)
- msg += "[t_He] looks wet.\n"
- if(4)
- msg += "[t_He] looks very wet.\n"
- if(5)
- msg += "[t_He] looks absolutely soaked.\n"
-
- if(nutrition < NUTRITION_LEVEL_STARVING - 50)
- msg += "[t_He] [t_is] severely malnourished.\n"
- else if(nutrition >= NUTRITION_LEVEL_FAT)
- if(user.nutrition < NUTRITION_LEVEL_STARVING - 50)
- msg += "[t_He] [t_is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
- else
- msg += "[t_He] [t_is] quite chubby.\n"
-
- if(reagents.has_reagent("teslium"))
- msg += "[t_He] is emitting a gentle blue glow!\n"
-
- msg += ""
-
- if(getBrainLoss() >= 60)
- msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
-
- if(species.show_ssd && (!species.has_organ["brain"] || get_int_organ(/obj/item/organ/internal/brain)) && stat != DEAD)
- if(istype(src, /mob/living/carbon/human/interactive))
- msg += "[t_He] appears to be some sort of sick automaton: [t_his] eyes are glazed over and [t_his] mouth is slightly agape.\n"
- else if(!key)
- msg += "[t_He] [t_is] fast asleep. It doesn't look like they are waking up anytime soon.\n"
- else if(!client)
- msg += "[t_He] [t_has] suddenly fallen asleep, suffering from Space Sleep Disorder.\n"
+ var/appears_dead = FALSE
+ if(stat == DEAD || (status_flags & FAKEDEATH))
+ appears_dead = TRUE
+ if(suiciding)
+ msg += "[t_He] appears to have committed suicide... there is no hope of recovery.\n"
+ msg += "[t_He] [t_is] limp and unresponsive; there are no signs of life"
+ if(get_int_organ(/obj/item/organ/internal/brain))
+ if(!key)
+ var/foundghost = FALSE
+ if(mind)
+ for(var/mob/dead/observer/G in player_list)
+ if(G.mind == mind)
+ foundghost = TRUE
+ if(G.can_reenter_corpse == 0)
+ foundghost = FALSE
+ break
+ if(!foundghost)
+ msg += " and [t_his] soul has departed"
+ msg += "...\n"
if(!get_int_organ(/obj/item/organ/internal/brain))
msg += "It appears that [t_his] brain is missing...\n"
+ msg += ""
+
var/list/wound_flavor_text = list()
var/list/is_destroyed = list()
for(var/organ_tag in species.has_limbs)
@@ -296,89 +238,17 @@
var/obj/item/organ/external/E = bodyparts_by_name[organ_tag]
if(!E)
- wound_flavor_text["[organ_tag]"] = "[t_He] [t_is] missing [t_his] [organ_descriptor].\n"
- else if(E.is_stump())
- wound_flavor_text["[organ_tag]"] = "[t_He] [t_has] a stump where [t_his] [organ_descriptor] should be.\n"
+ wound_flavor_text["[organ_tag]"] = "[t_He] [t_is] missing [t_his] [organ_descriptor].\n"
else
- continue
+ if(!isSynthetic())
+ if(E.status & ORGAN_ROBOT)
+ wound_flavor_text["[E.limb_name]"] = "[t_He] [t_has] a robotic [E.name]!\n"
- for(var/obj/item/organ/external/temp in bodyparts)
- if(temp && !temp.is_stump())
- if(temp.status & ORGAN_ROBOT)
- if(!(temp.brute_dam + temp.burn_dam))
- if(!isSynthetic())
- wound_flavor_text["[temp.limb_name]"] = "[t_He] [t_has] a robotic [temp.name]!\n"
- continue
- else
- wound_flavor_text["[temp.limb_name]"] = "[t_He] [t_has] a robotic [temp.name]. It has"
- if(temp.brute_dam) switch(temp.brute_dam)
- if(0 to 20)
- wound_flavor_text["[temp.limb_name]"] += " some dents"
- if(21 to INFINITY)
- wound_flavor_text["[temp.limb_name]"] += pick(" a lot of dents"," severe denting")
- if(temp.brute_dam && temp.burn_dam)
- wound_flavor_text["[temp.limb_name]"] += " and"
- if(temp.burn_dam) switch(temp.burn_dam)
- if(0 to 20)
- wound_flavor_text["[temp.limb_name]"] += " some burns"
- if(21 to INFINITY)
- wound_flavor_text["[temp.limb_name]"] += pick(" a lot of burns"," severe melting")
- if(wound_flavor_text["[temp.limb_name]"])
- wound_flavor_text["[temp.limb_name]"] += "!\n"
- else if(temp.wounds.len > 0)
- var/list/wound_descriptors = list()
- for(var/datum/wound/W in temp.wounds)
- if(W.internal && !temp.open) continue // can't see internal wounds
- var/this_wound_desc = W.desc
- if(W.damage_type == BURN && W.salved) this_wound_desc = "salved [this_wound_desc]"
- if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]"
- else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]"
- if(this_wound_desc in wound_descriptors)
- wound_descriptors[this_wound_desc] += W.amount
- continue
- wound_descriptors[this_wound_desc] = W.amount
- if(wound_descriptors.len)
- var/list/flavor_text = list()
- var/list/no_exclude = list("gaping wound", "big gaping wound", "massive wound", "large bruise",\
- "huge bruise", "massive bruise", "severe burn", "large burn", "deep burn", "carbonised area")
- for(var/wound in wound_descriptors)
- switch(wound_descriptors[wound])
- if(1)
- if(!flavor_text.len)
- flavor_text += "[t_He] [t_has][prob(10) && !(wound in no_exclude) ? " what might be" : ""] a [wound]"
- else
- flavor_text += "[prob(10) && !(wound in no_exclude) ? " what might be" : ""] a [wound]"
- if(2)
- if(!flavor_text.len)
- flavor_text += "[t_He] [t_has][prob(10) && !(wound in no_exclude) ? " what might be" : ""] a pair of [wound]s"
- else
- flavor_text += "[prob(10) && !(wound in no_exclude) ? " what might be" : ""] a pair of [wound]s"
- if(3 to 5)
- if(!flavor_text.len)
- flavor_text += "[t_He] [t_has] several [wound]s"
- else
- flavor_text += " several [wound]s"
- if(6 to INFINITY)
- if(!flavor_text.len)
- flavor_text += "[t_He] [t_has] a bunch of [wound]s"
- else
- flavor_text += " a ton of [wound]\s"
- var/flavor_text_string = ""
- for(var/text = 1, text <= flavor_text.len, text++)
- if(text == flavor_text.len && flavor_text.len > 1)
- flavor_text_string += ", and"
- else if(flavor_text.len > 1 && text > 1)
- flavor_text_string += ","
- flavor_text_string += flavor_text[text]
- flavor_text_string += " on [t_his] [temp.name].
"
- wound_flavor_text["[temp.limb_name]"] = flavor_text_string
- else
- wound_flavor_text["[temp.limb_name]"] = ""
- else
- wound_flavor_text["[temp.limb_name]"] = ""
+ else if(E.status & ORGAN_SPLINTED)
+ wound_flavor_text["[E.limb_name]"] = "[t_He] [t_has] a splint on his [E.name]!\n"
- for(var/obj/item/I in temp.embedded_objects)
- msg += "[t_He] [t_has] \a [bicon(I)] [I] embedded in [t_his] [temp.name]!\n"
+ for(var/obj/item/I in E.embedded_objects)
+ msg += "[t_He] [t_has] \a [bicon(I)] [I] embedded in [t_his] [E.name]!\n"
//Handles the text strings being added to the actual description.
//If they have something that covers the limb, and it is not missing, put flavortext. If it is covered but bleeding, add other flavortext.
@@ -405,6 +275,55 @@
if(wound_flavor_text["r_foot"]&& (is_destroyed["right foot"] || (!shoes && !skipshoes)))
msg += wound_flavor_text["r_foot"]
+ var/temp = getBruteLoss() //no need to calculate each of these twice
+
+ if(temp)
+ var/brute_message = !isSynthetic() ? "bruising" : "denting"
+ if(temp < 30)
+ msg += "[t_He] [t_has] minor [brute_message ].\n"
+ else
+ msg += "[t_He] [t_has] severe [brute_message ]!\n"
+
+ temp = getFireLoss()
+ if(temp)
+ if(temp < 30)
+ msg += "[t_He] [t_has] minor burns.\n"
+ else
+ msg += "[t_He] [t_has] severe burns!\n"
+
+ temp = getCloneLoss()
+ if(temp)
+ if(temp < 30)
+ msg += "[t_He] [t_has] minor cellular damage.\n"
+ else
+ msg += "[t_He] [t_has] severe cellular damage.\n"
+
+
+ if(fire_stacks > 0)
+ msg += "[t_He] [t_is] covered in something flammable.\n"
+ if(fire_stacks < 0)
+ msg += "[t_He] looks a little soaked.\n"
+
+ switch(wetlevel)
+ if(1)
+ msg += "[t_He] looks a bit damp.\n"
+ if(2)
+ msg += "[t_He] looks a little bit wet.\n"
+ if(3)
+ msg += "[t_He] looks wet.\n"
+ if(4)
+ msg += "[t_He] looks very wet.\n"
+ if(5)
+ msg += "[t_He] looks absolutely soaked.\n"
+
+ if(nutrition < NUTRITION_LEVEL_STARVING - 50)
+ msg += "[t_He] [t_is] severely malnourished.\n"
+ else if(nutrition >= NUTRITION_LEVEL_FAT)
+ if(user.nutrition < NUTRITION_LEVEL_STARVING - 50)
+ msg += "[t_He] [t_is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
+ else
+ msg += "[t_He] [t_is] quite chubby.\n"
+
if(blood_volume < BLOOD_VOLUME_SAFE)
msg += "[t_He] [t_has] pale skin.\n"
@@ -416,10 +335,38 @@
else
msg += "[t_He] [t_is] bleeding!\n"
- if(digitalcamo)
- msg += "[t_He] [t_is] repulsively uncanny!\n"
+ if(reagents.has_reagent("teslium"))
+ msg += "[t_He] is emitting a gentle blue glow!\n"
+
+ msg += ""
+
+ if(!appears_dead)
+ if(stat == UNCONSCIOUS)
+ msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
+ else if(getBrainLoss() >= 60)
+ msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
+
+ if(get_int_organ(/obj/item/organ/internal/brain))
+ if(istype(src, /mob/living/carbon/human/interactive))
+ var/mob/living/carbon/human/interactive/auto = src
+ if(auto.showexaminetext)
+ msg += "[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.\n"
+ if(auto.debugexamine)
+ var/dodebug = auto.doing2string(auto.doing)
+ var/interestdebug = auto.interest2string(auto.interest)
+ msg += "[t_He] [t_is] appears to be [interestdebug] and [dodebug].\n"
+ else if(species.show_ssd)
+ if(!key)
+ msg += "[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely.\n"
+ else if(!client)
+ msg += "[t_He] [t_has] suddenly fallen asleep, suffering from Space Sleep Disorder. [t_He] may wake up soon.\n"
+
+ if(digitalcamo)
+ msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
+
if(!(skipface || ( wear_mask && ( wear_mask.flags_inv & HIDEFACE || wear_mask.flags_cover & MASKCOVERSMOUTH) ) ) && is_thrall(src) && in_range(user,src))
msg += "Their features seem unnaturally tight and drawn.\n"
+
if(decaylevel == 1)
msg += "[t_He] [t_is] starting to smell.\n"
if(decaylevel == 2)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index fb472128004..3b764e0a189 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1208,18 +1208,10 @@
for(var/obj/item/organ/internal/I in H.internal_organs)
types_of_int_organs |= I.type //Compiling the list of organ types. It is possible for organs to be missing from this list if they are absent from the mob.
- //Removing stumps.
- for(var/obj/item/organ/organ in H.contents)
- if(istype(organ, /obj/item/organ/external/stump)) //Get rid of all stumps.
- qdel(organ)
- H.contents -= organ //Making sure the list entry is removed.
- for(var/obj/item/organ/organ in H.bodyparts)
- if(istype(organ, /obj/item/organ/external/stump))
- qdel(organ)
- H.bodyparts -= organ //Making sure the list entry is removed.
+ //Clean up limbs
for(var/organ_name in H.bodyparts_by_name)
var/obj/item/organ/organ = H.bodyparts_by_name[organ_name]
- if(istype(organ, /obj/item/organ/external/stump) || !organ) //The !organ check is to account for mechanical limb (prostheses) losses, since those are handled in a way that leaves indexed but null list entries instead of stumps.
+ if(!organ) //The !organ check is to account for mechanical limb (prostheses) losses, since those are handled in a way that leaves indexed but null list entries instead of stumps.
qdel(organ)
H.bodyparts_by_name -= organ_name //Making sure the list entry is removed.
@@ -1598,7 +1590,7 @@
return
var/obj/item/organ/external/head/head_organ = get_organ("head")
- if(!head_organ || head_organ.is_stump() || (head_organ.status & ORGAN_DESTROYED)) //If the rock'em-sock'em robot's head came off during a fight, they shouldn't be able to change their screen/optics.
+ if(!head_organ || (head_organ.status & ORGAN_DESTROYED)) //If the rock'em-sock'em robot's head came off during a fight, they shouldn't be able to change their screen/optics.
to_chat(src, "Where's your head at? Can't change your monitor/display without one.")
return
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index b5796aee6d5..651cc2d4cb6 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -201,7 +201,7 @@ emp_act
qdel(src)
var/obj/item/organ/external/affecting = get_organ(ran_zone(user.zone_sel.selecting))
- if(!affecting || affecting.is_stump() || (affecting.status & ORGAN_DESTROYED))
+ if(!affecting || (affecting.status & ORGAN_DESTROYED))
to_chat(user, "They are missing that limb!")
return 1
var/hit_area = affecting.name
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 036202e1ae0..e7f3861eec1 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -52,9 +52,6 @@ var/global/default_martial_art = new/datum/martial_art
var/special_voice = "" // For changing our voice. Used by a symptom.
- var/last_dam = -1 //Used for determining if we need to process all organs or just some or even none.
- var/list/bad_external_organs = list()// organs we check until they are good.
-
var/hand_blood_color
var/name_override //For temporary visible name changes
diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm
index 3a8f6ff4f46..124f78aa75e 100644
--- a/code/modules/mob/living/carbon/human/human_organs.dm
+++ b/code/modules/mob/living/carbon/human/human_organs.dm
@@ -9,52 +9,24 @@
// Takes care of organ related updates, such as broken and missing limbs
/mob/living/carbon/human/proc/handle_organs()
-
- number_wounds = 0
- var/force_process = 0
- var/damage_this_tick = getBruteLoss() + getFireLoss() + getToxLoss()
- if(damage_this_tick > last_dam)
- force_process = 1
- last_dam = damage_this_tick
- if(force_process)
- bad_external_organs.Cut()
- for(var/obj/item/organ/external/Ex in bodyparts)
- bad_external_organs |= Ex
-
//processing internal organs is pretty cheap, do that first.
for(var/obj/item/organ/internal/I in internal_organs)
I.process()
+ for(var/obj/item/organ/external/E in bodyparts)
+ E.process()
+
+ if(!lying && world.time - l_move_time < 15)
+ //Moving around with fractured ribs won't do you any good
+ if(E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15))
+ var/obj/item/organ/internal/I = pick(E.internal_organs)
+ custom_pain("You feel broken bones moving in your [E.name]!", 1)
+ I.take_damage(rand(3,5))
+
//handle_stance()
handle_grasp()
handle_stance()
- if(!force_process && !bad_external_organs.len)
- return
-
- for(var/obj/item/organ/external/E in bad_external_organs)
- if(!E)
- continue
- if(!E.need_process())
- bad_external_organs -= E
- continue
- else
- E.process()
- number_wounds += E.number_wounds
-
- if(!lying && world.time - l_move_time < 15)
- //Moving around with fractured ribs won't do you any good
- if(E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15))
- var/obj/item/organ/internal/I = pick(E.internal_organs)
- custom_pain("You feel broken bones moving in your [E.name]!", 1)
- I.take_damage(rand(3,5))
-
- //Moving makes open wounds get infected much faster
- if(E.wounds.len)
- for(var/datum/wound/W in E.wounds)
- if(W.infection_check())
- W.germ_level += 1
-
/mob/living/carbon/human/proc/handle_stance()
// Don't need to process any of this if they aren't standing anyways
diff --git a/code/modules/mob/living/carbon/human/interactive/interactive.dm b/code/modules/mob/living/carbon/human/interactive/interactive.dm
index b1d9b5bc68f..4efca3178cc 100644
--- a/code/modules/mob/living/carbon/human/interactive/interactive.dm
+++ b/code/modules/mob/living/carbon/human/interactive/interactive.dm
@@ -72,6 +72,8 @@
var/forceProcess = 0
var/processTime = 10
var/speak_file = "npc_chatter.json"
+ var/debugexamine = FALSE //If we show debug info in our examine
+ var/showexaminetext = TRUE //If we show our telltale examine text
var/list/knownStrings = list()
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 6edc2f0ae75..a3be2de7eba 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -25,7 +25,7 @@
/mob/living/carbon/human/proc/has_organ(name)
var/obj/item/organ/external/O = bodyparts_by_name[name]
- return (O && !(O.status & ORGAN_DESTROYED) && !O.is_stump())
+ return (O && !(O.status & ORGAN_DESTROYED))
/mob/living/carbon/human/proc/has_organ_for_slot(slot)
switch(slot)
diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm
index 7e7ddc1c5af..1841ae50279 100644
--- a/code/modules/mob/living/carbon/human/species/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station.dm
@@ -643,12 +643,12 @@
var/list/missing_limbs = list()
for(var/l in bodyparts_by_name)
var/obj/item/organ/external/E = bodyparts_by_name[l]
- if(!istype(E) || istype(E, /obj/item/organ/external/stump))
+ if(!istype(E))
var/list/limblist = species.has_limbs[l]
var/obj/item/organ/external/limb = limblist["path"]
var/parent_organ = initial(limb.parent_organ)
var/obj/item/organ/external/parentLimb = bodyparts_by_name[parent_organ]
- if(!istype(parentLimb) || parentLimb.is_stump())
+ if(!istype(parentLimb))
continue
missing_limbs[initial(limb.name)] = l
@@ -674,21 +674,17 @@
var/stored_brute = 0
var/stored_burn = 0
if(istype(O))
- if(!O.is_stump())
- to_chat(src, "Your limb has already been replaced in some way!")
- return
- else
- to_chat(src, "You distribute the damaged tissue around your body, out of the way of your new pseudopod!")
- var/obj/item/organ/external/doomedStump = O
- stored_brute = doomedStump.brute_dam
- stored_burn = doomedStump.burn_dam
- qdel(O)
+ to_chat(src, "You distribute the damaged tissue around your body, out of the way of your new pseudopod!")
+ var/obj/item/organ/external/doomedStump = O
+ stored_brute = doomedStump.brute_dam
+ stored_burn = doomedStump.burn_dam
+ qdel(O)
var/limb_list = species.has_limbs[chosen_limb]
var/obj/item/organ/external/limb_path = limb_list["path"]
// Parent check
var/obj/item/organ/external/potential_parent = bodyparts_by_name[initial(limb_path.parent_organ)]
- if(!istype(potential_parent) || potential_parent.is_stump())
+ if(!istype(potential_parent))
to_chat(src, "You've lost the organ that you've been growing your new part on!")
return // No rayman for you
// Grah this line will leave a "not used" warning, in spite of the fact that the new() proc WILL do the thing.
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 31ce7f5b9e2..520bcbb8b3b 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -172,9 +172,8 @@ var/global/list/damage_icon_parts = list()
var/damage_appearance = ""
for(var/obj/item/organ/external/O in bodyparts)
- if(O.is_stump())
- continue
- if(O.status & ORGAN_DESTROYED) damage_appearance += "d"
+ if(O.status & ORGAN_DESTROYED)
+ damage_appearance += "d"
else
damage_appearance += O.damage_state
@@ -190,8 +189,6 @@ var/global/list/damage_icon_parts = list()
// blend the individual damage states with our icons
for(var/obj/item/organ/external/O in bodyparts)
- if(O.is_stump())
- continue
if(!(O.status & ORGAN_DESTROYED))
O.update_icon()
if(O.damage_state == "00") continue
@@ -241,7 +238,7 @@ var/global/list/damage_icon_parts = list()
for(var/organ_tag in species.has_limbs)
var/obj/item/organ/external/part = bodyparts_by_name[organ_tag]
- if(isnull(part) || part.is_stump() || (part.status & ORGAN_DESTROYED))
+ if(isnull(part) || (part.status & ORGAN_DESTROYED))
icon_key += "0"
else if(part.status & ORGAN_ROBOT)
icon_key += "2[part.model ? "-[part.model]": ""]"
@@ -368,7 +365,7 @@ var/global/list/damage_icon_parts = list()
//Body markings.
var/obj/item/organ/external/chest/chest_organ = get_organ("chest")
- if(chest_organ && !chest_organ.is_stump() && !(chest_organ.status & ORGAN_DESTROYED) && m_styles["body"])
+ if(chest_organ && !(chest_organ.status & ORGAN_DESTROYED) && m_styles["body"])
var/body_marking = m_styles["body"]
var/datum/sprite_accessory/body_marking_style = marking_styles_list[body_marking]
if(body_marking_style && body_marking_style.species_allowed && (species.name in body_marking_style.species_allowed))
@@ -378,7 +375,7 @@ var/global/list/damage_icon_parts = list()
markings_standing.Blend(b_marking_s, ICON_OVERLAY)
//Head markings.
var/obj/item/organ/external/head/head_organ = get_organ("head")
- if(head_organ && !head_organ.is_stump() && !(head_organ.status & ORGAN_DESTROYED) && m_styles["head"]) //If the head is destroyed, forget the head markings. This prevents floating optical markings on decapitated IPCs, for example.
+ if(head_organ && !(head_organ.status & ORGAN_DESTROYED) && m_styles["head"]) //If the head is destroyed, forget the head markings. This prevents floating optical markings on decapitated IPCs, for example.
var/head_marking = m_styles["head"]
var/datum/sprite_accessory/head_marking_style = marking_styles_list[head_marking]
if(head_marking_style && head_marking_style.species_allowed && (head_organ.species.name in head_marking_style.species_allowed))
@@ -398,7 +395,7 @@ var/global/list/damage_icon_parts = list()
overlays_standing[HEAD_ACC_OVER_LAYER] = null
var/obj/item/organ/external/head/head_organ = get_organ("head")
- if(!head_organ || head_organ.is_stump() || (head_organ.status & ORGAN_DESTROYED) )
+ if(!head_organ || (head_organ.status & ORGAN_DESTROYED) )
if(update_icons) update_icons()
return
@@ -435,7 +432,7 @@ var/global/list/damage_icon_parts = list()
overlays_standing[HAIR_LAYER] = null
var/obj/item/organ/external/head/head_organ = get_organ("head")
- if(!head_organ || head_organ.is_stump() || (head_organ.status & ORGAN_DESTROYED))
+ if(!head_organ || (head_organ.status & ORGAN_DESTROYED))
if(update_icons) update_icons()
return
@@ -484,7 +481,7 @@ var/global/list/damage_icon_parts = list()
overlays_standing[FHAIR_OVER_LAYER] = null
var/obj/item/organ/external/head/head_organ = get_organ("head")
- if(!head_organ || head_organ.is_stump() || (head_organ.status & ORGAN_DESTROYED))
+ if(!head_organ || (head_organ.status & ORGAN_DESTROYED))
if(update_icons) update_icons()
return
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index aadd5a74c1b..03bc97c2d73 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -867,19 +867,6 @@ var/list/slot_equipment_priority = list( \
/mob/proc/stripPanelEquip(obj/item/what, mob/who)
return
-
-/mob/proc/pull_damage()
- if(ishuman(src))
- var/mob/living/carbon/human/H = src
- if(H.health <= config.health_threshold_softcrit)
- for(var/name in H.bodyparts_by_name)
- var/obj/item/organ/external/e = H.bodyparts_by_name[name]
- if(e && H.lying)
- if(((e.status & ORGAN_BROKEN && !(e.status & ORGAN_SPLINTED)) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100))
- return 1
- break
- return 0
-
/mob/MouseDrop(mob/M as mob)
..()
if(M != usr) return
diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm
index db9d5f4821d..4a1343ad513 100644
--- a/code/modules/surgery/bones.dm
+++ b/code/modules/surgery/bones.dm
@@ -101,7 +101,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user]'s hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!" , \
" Your hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!")
- affected.createwound(BRUISE, 5)
+ affected.take_damage(5)
return 0
/datum/surgery_step/mend_skull
@@ -135,7 +135,7 @@
user.visible_message("[user]'s hand slips, damaging [target]'s face with \the [tool]!" , \
"Your hand slips, damaging [target]'s face with \the [tool]!")
var/obj/item/organ/external/head/h = affected
- h.createwound(BRUISE, 10)
+ h.take_damage(10)
h.disfigured = 1
return 0
diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm
index bd82e7192ae..9f5c2649980 100644
--- a/code/modules/surgery/cavity_implant.dm
+++ b/code/modules/surgery/cavity_implant.dm
@@ -61,7 +61,7 @@
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
user.visible_message(" [user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!", \
" Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!")
- affected.createwound(CUT, 20)
+ affected.take_damage(20)
/datum/surgery_step/cavity/make_space
name = "make cavity space"
@@ -188,8 +188,7 @@
" You put \the [tool] inside [target]'s [get_cavity(affected)] cavity." )
if((tool.w_class > get_max_wclass(affected)/2 && prob(50) && !(affected.status & ORGAN_ROBOT)))
to_chat(user, " You tear some vessels trying to fit the object in the cavity.")
- var/datum/wound/internal_bleeding/I = new ()
- affected.wounds += I
+ affected.internal_bleeding = TRUE
affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1)
user.drop_item()
affected.hidden = tool
diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm
index fbcd9a21c69..4d46bb69d75 100644
--- a/code/modules/surgery/encased.dm
+++ b/code/modules/surgery/encased.dm
@@ -61,7 +61,7 @@
user.visible_message(" [user]'s hand slips, cracking [target]'s [affected.encased] with \the [tool]!" , \
" Your hand slips, cracking [target]'s [affected.encased] with \the [tool]!" )
- affected.createwound(CUT, 20)
+ affected.take_damage(20)
affected.fracture()
return 0
@@ -113,7 +113,7 @@
var/self_msg = " Your hand slips, cracking [target]'s [affected.encased]!"
user.visible_message(msg, self_msg)
- affected.createwound(BRUISE, 20)
+ affected.take_damage(20)
affected.fracture()
return 0
@@ -164,7 +164,7 @@
var/self_msg = " Your hand slips, bending [target]'s [affected.encased] the wrong way!"
user.visible_message(msg, self_msg)
- affected.createwound(BRUISE, 20)
+ affected.take_damage(20)
affected.fracture()
return 0
diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm
index 28e0be1b046..b5c2bfa013c 100644
--- a/code/modules/surgery/face.dm
+++ b/code/modules/surgery/face.dm
@@ -50,7 +50,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user]'s hand slips, slicing [target]'s throat wth \the [tool]!" , \
" Your hand slips, slicing [target]'s throat wth \the [tool]!" )
- affected.createwound(CUT, 60)
+ affected.take_damage(60)
target.AdjustLoseBreath(4)
return 0
@@ -131,7 +131,6 @@
user.visible_message(" [user] cauterizes the incision on [target]'s face and neck with \the [tool].", \
" You cauterize the incision on [target]'s face and neck with \the [tool].")
affected.open = 0
- affected.status &= ~ORGAN_BLEEDING
var/obj/item/organ/external/head/h = affected
h.disfigured = 0
h.update_icon()
diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm
index d87458e3ed9..c051aae385c 100644
--- a/code/modules/surgery/generic.dm
+++ b/code/modules/surgery/generic.dm
@@ -47,14 +47,13 @@
user.visible_message(" [user] has made an incision on [target]'s [affected.name] with \the [tool].", \
" You have made an incision on [target]'s [affected.name] with \the [tool].",)
affected.open = 1
- affected.status |= ORGAN_BLEEDING
return 1
/datum/surgery_step/generic/cut_open/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user]'s hand slips, slicing open [target]'s [affected.name] in a wrong spot with \the [tool]!", \
" Your hand slips, slicing open [target]'s [affected.name] in a wrong spot with \the [tool]!")
- affected.createwound(CUT, 10)
+ affected.take_damage(10)
return 0
/datum/surgery_step/generic/clamp_bleeders
@@ -81,7 +80,6 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user] clamps bleeders in [target]'s [affected.name] with \the [tool].", \
" You clamp bleeders in [target]'s [affected.name] with \the [tool].")
- affected.clamp()
spread_germs_to_organ(affected, user, tool)
return 1
@@ -89,7 +87,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.name] with \the [tool]!", \
" Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!",)
- affected.createwound(CUT, 10)
+ affected.take_damage(10)
return 0
/datum/surgery_step/generic/retract_skin
@@ -173,7 +171,6 @@
" You cauterize the incision on [target]'s [affected.name] with \the [tool].")
affected.open = 0
affected.germ_level = 0
- affected.status &= ~ORGAN_BLEEDING
return 1
/datum/surgery_step/generic/cauterize/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -245,6 +242,6 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user]'s hand slips, sawing through the bone in [target]'s [affected.name] with \the [tool]!", \
" Your hand slips, sawwing through the bone in [target]'s [affected.name] with \the [tool]!")
- affected.createwound(CUT, 30)
+ affected.take_damage(30)
affected.fracture()
return 0
diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm
index 1991ce8ec21..afa0429bdc0 100644
--- a/code/modules/surgery/helpers.dm
+++ b/code/modules/surgery/helpers.dm
@@ -73,7 +73,6 @@
if(affecting)
affecting.open = 0
affecting.germ_level = 0
- affecting.status &= ~ORGAN_BLEEDING
qdel(current_surgery)
else if(current_surgery.can_cancel)
to_chat(user, "You need to hold a cautery in inactive hand to stop [M]'s surgery!")
diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm
index 773508c88ea..9674f4aec49 100644
--- a/code/modules/surgery/limb_augmentation.dm
+++ b/code/modules/surgery/limb_augmentation.dm
@@ -54,5 +54,4 @@
affected.open = 0
affected.germ_level = 0
- affected.status &= ~ORGAN_BLEEDING
return 1
\ No newline at end of file
diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm
index 8b2d2507041..9a2aa81f977 100644
--- a/code/modules/surgery/limb_reattach.dm
+++ b/code/modules/surgery/limb_reattach.dm
@@ -198,9 +198,6 @@
user.visible_message("[user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].", \
"You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].")
E.status &= ~ORGAN_DESTROYED
- var/obj/item/organ/external/stump = target.bodyparts_by_name["limb stump"]
- if(stump)
- stump.remove(target)
if(E.children)
for(var/obj/item/organ/external/C in E.children)
C.status &= ~ORGAN_DESTROYED
diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm
index d046311ff62..80167f5b38a 100644
--- a/code/modules/surgery/organs/blood.dm
+++ b/code/modules/surgery/organs/blood.dm
@@ -61,6 +61,7 @@
death()
var/temp_bleed = 0
+ var/internal_bleeding_rate = 0
//Bleeding out
for(var/X in bodyparts)
var/obj/item/organ/external/BP = X
@@ -79,8 +80,14 @@
if(BP.open)
temp_bleed += 0.5
+ if(BP.internal_bleeding)
+ internal_bleeding_rate += 0.5
+
bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
+ if(internal_bleeding_rate && !(status_flags & FAKEDEATH))
+ bleed(internal_bleeding_rate)
+
if(bleed_rate && !bleedsuppress && !(status_flags & FAKEDEATH))
bleed(bleed_rate)
diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm
index a84e63649d7..a4fdfa5bc6c 100644
--- a/code/modules/surgery/organs/organ.dm
+++ b/code/modules/surgery/organs/organ.dm
@@ -46,7 +46,6 @@ var/list/organ_cache = list()
/obj/item/organ/New(var/mob/living/carbon/holder)
..(holder)
- create_reagents(5)
if(!max_damage)
max_damage = min_broken_damage * 2
if(istype(holder))
@@ -101,11 +100,6 @@ var/list/organ_cache = list()
return
if(!owner)
- if(reagents && prob(40))
- reagents.remove_any(0.1)
- for(var/datum/reagent/R in reagents.reagent_list)
- R.reaction_turf(get_turf(src), 0.1)
-
// Maybe scale it down a bit, have it REALLY kick in once past the basic infection threshold
// Another mercy for surgeons preparing transplant organs
germ_level++
@@ -116,9 +110,6 @@ var/list/organ_cache = list()
if(germ_level >= INFECTION_LEVEL_THREE)
necrotize()
- if(damage >= max_damage)
- necrotize()
-
else if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
//** Handle antibiotics and curing infections
handle_antibiotics()
@@ -136,7 +127,7 @@ var/list/organ_cache = list()
return 1
if(is_found_within(/obj/structure/closet/crate/freezer))
return 1
- if(istype(loc,/turf))
+ if(isturf(loc))
if(world.time - last_freezer_update_time > freezer_update_period)
// I don't want to loop through everything in the tile constantly, especially since it'll be a pile of organs
// if the virologist releases gibbingtons again or something
@@ -251,10 +242,8 @@ var/list/organ_cache = list()
/obj/item/organ/proc/robotize() //Being used to make robutt hearts, etc
robotic = 2
status &= ~ORGAN_BROKEN
- status &= ~ORGAN_BLEEDING
status &= ~ORGAN_SPLINTED
status &= ~ORGAN_CUT_AWAY
- status &= ~ORGAN_ATTACHABLE
status &= ~ORGAN_DESTROYED
status |= ORGAN_ROBOT
status |= ORGAN_ASSISTED
@@ -316,10 +305,6 @@ var/list/organ_cache = list()
loc = get_turf(owner)
processing_objects |= src
- var/datum/reagent/blood/organ_blood
- if(reagents) organ_blood = reagents.get_reagent_from_id(owner.get_blood_id())
- if((!organ_blood || !organ_blood.data["blood_DNA"]) && (owner && !(NO_BLOOD in owner.species.species_traits)))
- owner.transfer_blood_to(src)
if(owner && vital && is_primary_organ()) // I'd do another check for species or whatever so that you couldn't "kill" an IPC by removing a human head from them, but it doesn't matter since they'll come right back from the dead
if(user)
diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm
index d01b5e5202e..2c5b31f6f94 100644
--- a/code/modules/surgery/organs/organ_external.dm
+++ b/code/modules/surgery/organs/organ_external.dm
@@ -25,7 +25,6 @@
var/brute_dam = 0
var/burn_dam = 0
var/max_size = 0
- var/last_dam = -1
var/icon/mob_icon
var/gendered_icon = 0
var/limb_name
@@ -34,15 +33,9 @@
var/cannot_break
var/s_tone = null
var/list/s_col = null // If this is instantiated, it should be a list of length 3
- var/list/wounds = list()
var/list/child_icons = list()
- var/number_wounds = 0 // cache the number of wounds, which is NOT wounds.len!
var/perma_injury = 0
- // 0: Don't fail when at full damage
- // 1: Neatly pop off at full damage, stop damage propogation
- // 2: Disintegrate at full damage, continue damage propogation
- var/fail_at_full_damage = 0
-
+ var/dismember_at_max_damage = FALSE
var/obj/item/organ/external/parent
var/list/obj/item/organ/external/children
@@ -60,14 +53,10 @@
var/obj/item/hidden = null
var/list/embedded_objects = list()
-
- // how often wounds should be updated, a higher number means less often
- var/wound_update_accuracy = 1
-
+ var/internal_bleeding = FALSE
var/amputation_point // Descriptive string used in amputation.
var/can_grasp
var/can_stand
- var/wound_cleanup_timer
/obj/item/organ/external/necrotize(update_sprite=TRUE)
if(status & (ORGAN_ROBOT|ORGAN_DEAD))
@@ -78,7 +67,6 @@
if(owner)
to_chat(owner, "You can't feel your [name] anymore...")
owner.update_body(update_sprite)
- owner.bad_external_organs |= src
if(vital)
owner.death()
@@ -99,12 +87,6 @@
QDEL_LIST(children)
- if(wound_cleanup_timer)
- deltimer(wound_cleanup_timer)
- wound_cleanup_timer = null
-
- QDEL_LIST(wounds)
-
QDEL_LIST(embedded_objects)
QDEL_NULL(hidden)
@@ -177,12 +159,7 @@
if(!parent.children)
parent.children = list()
parent.children.Add(src)
- //Remove all stump wounds since limb is not missing anymore
- for(var/datum/wound/lost_limb/W in parent.wounds)
- parent.wounds -= W
- qdel(W)
- break
- parent.update_damages()
+ parent.check_fracture()
/obj/item/organ/external/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H)
if(parent_organ != parent.limb_name)
@@ -194,8 +171,8 @@
DAMAGE PROCS
****************************************************/
-/obj/item/organ/external/take_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list())
- if(tough)
+/obj/item/organ/external/take_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list(), ignore_resists = FALSE)
+ if(tough && !ignore_resists)
brute = max(0, brute - 5)
burn = max(0, burn - 4)
@@ -205,8 +182,9 @@
if(status & ORGAN_DESTROYED)
return 0
- brute *= brute_mod
- burn *= burn_mod
+ if(!ignore_resists)
+ brute *= brute_mod
+ burn *= burn_mod
// Threshold needed to have a chance of hurting internal bits with something sharp
#define LIMB_SHARP_THRESH_INT_DMG 5
@@ -228,74 +206,63 @@
if(used_weapon)
add_autopsy_data("[used_weapon]", brute + burn)
- var/can_cut = (prob(brute*2) || sharp) && !(status & ORGAN_ROBOT)
- // If the limbs can break, make sure we don't exceed the maximum damage a limb can take before breaking
- if((brute_dam + burn_dam + brute + burn) < max_damage || !config.limbs_can_break)
- if(brute)
- if(can_cut)
- createwound( CUT, brute )
- else
- createwound( BRUISE, brute )
- if(burn)
- createwound( BURN, burn )
+ // Make sure we don't exceed the maximum damage a limb can take before dismembering
+ if((brute_dam + burn_dam + brute + burn) < max_damage)
+ brute_dam += brute
+ burn_dam += burn
+ check_for_internal_bleeding(brute)
else
//If we can't inflict the full amount of damage, spread the damage in other ways
//How much damage can we actually cause?
- var/can_inflict = max_damage * config.organ_health_multiplier - (brute_dam + burn_dam)
+ var/can_inflict = max_damage - (brute_dam + burn_dam)
if(can_inflict)
if(brute > 0)
//Inflict all burte damage we can
- if(can_cut)
- createwound( CUT, min(brute,can_inflict) )
- else
- createwound( BRUISE, min(brute,can_inflict) )
+ brute_dam = min(brute_dam + brute, brute_dam + can_inflict)
var/temp = can_inflict
//How much mroe damage can we inflict
can_inflict = max(0, can_inflict - brute)
//How much brute damage is left to inflict
brute = max(0, brute - temp)
+ check_for_internal_bleeding(brute)
if(burn > 0 && can_inflict)
//Inflict all burn damage we can
- createwound(BURN, min(burn,can_inflict))
+ burn_dam = min(burn_dam + burn, burn_dam + can_inflict)
//How much burn damage is left to inflict
burn = max(0, burn - can_inflict)
//If there are still hurties to dispense
if(burn || brute)
- if(fail_at_full_damage == 1 && body_part != UPPER_TORSO && body_part != LOWER_TORSO)
- droplimb(1) //Clean loss, just drop the limb and be done
- else
- //List organs we can pass it to
- var/list/obj/item/organ/external/possible_points = list()
- if(parent)
- possible_points += parent
- if(children) for(var/organ in children)
- if(organ) possible_points += organ
- if(forbidden_limbs.len)
- possible_points -= forbidden_limbs
- if(possible_points.len)
- //And pass the pain around
- var/obj/item/organ/external/target = pick(possible_points)
- target.take_damage(brute, burn, sharp, used_weapon, forbidden_limbs + src)
- if(fail_at_full_damage == 2 && body_part != UPPER_TORSO && body_part != LOWER_TORSO)
- var/losstype
- if(burn > brute)
- losstype = DROPLIMB_BURN
- else
- losstype = DROPLIMB_BLUNT
- droplimb(0, losstype) // less clean than a robot arm, doesn't buffer damage either
+ //List organs we can pass it to
+ var/list/obj/item/organ/external/possible_points = list()
+ if(parent)
+ possible_points += parent
+ if(children)
+ for(var/organ in children)
+ if(organ)
+ possible_points += organ
+ if(forbidden_limbs.len)
+ possible_points -= forbidden_limbs
+ if(possible_points.len)
+ //And pass the pain around
+ var/obj/item/organ/external/target = pick(possible_points)
+ target.take_damage(brute, burn, sharp, used_weapon, forbidden_limbs + src, ignore_resists = TRUE) //If the damage was reduced before, don't reduce it again
- // sync the organ's damage with its wounds
- src.update_damages()
+ if(dismember_at_max_damage && body_part != UPPER_TORSO && body_part != LOWER_TORSO) // We've ensured all damage to the mob is retained, now let's drop it, if necessary.
+ droplimb(1) //Clean loss, just drop the limb and be done
+
+ // See if bones need to break
+ check_fracture()
var/mob/living/carbon/owner_old = owner //Need to update health, but need a reference in case the below check cuts off a limb.
//If limb took enough damage, try to cut or tear it off
if(owner && loc == owner)
- if(!cannot_amputate && config.limbs_can_break && (brute_dam) >= (max_damage * config.organ_health_multiplier))
+ if(!cannot_amputate && (brute_dam) >= (max_damage))
if(prob(brute / 2))
if(sharp)
droplimb(0, DROPLIMB_SHARP)
- if(owner_old) owner_old.updatehealth()
+ if(owner_old)
+ owner_old.updatehealth()
return update_icon()
#undef LIMB_SHARP_THRESH_INT_DMG
@@ -307,27 +274,16 @@
if(status & ORGAN_ROBOT && !robo_repair)
return
- //Heal damage on the individual wounds
- for(var/datum/wound/W in wounds)
- if(brute == 0 && burn == 0)
- break
-
- // heal brute damage
- if(W.damage_type == CUT || W.damage_type == BRUISE)
- brute = W.heal_damage(brute)
- else if(W.damage_type == BURN)
- burn = W.heal_damage(burn)
+ brute_dam = max(brute_dam - brute, 0)
+ burn_dam = max(burn_dam - burn, 0)
if(internal)
status &= ~ORGAN_BROKEN
perma_injury = 0
- //Sync the organ's damage with its wounds
- src.update_damages()
owner.updatehealth()
- var/result = update_icon()
- return result
+ return update_icon()
/*
This function completely restores a damaged organ to perfect condition.
@@ -345,7 +301,7 @@ This function completely restores a damaged organ to perfect condition.
brute_dam = 0
burn_dam = 0
open = 0 //Closing all wounds.
- wounds.Cut() //Clears all wounds! Good as new.
+ internal_bleeding = FALSE
if(istype(src, /obj/item/organ/external/head) && disfigured) //If their head's disfigured, refigure it.
disfigured = 0
@@ -361,81 +317,12 @@ This function completely restores a damaged organ to perfect condition.
if(!owner)
processing_objects |= src
-
-/obj/item/organ/external/proc/createwound(var/type = CUT, var/damage)
- if(damage == 0) return
-
- //moved this before the open_wound check so that having many small wounds for example doesn't somehow protect you from taking internal damage
- //Possibly trigger an internal wound, too.
- var/local_damage = brute_dam + burn_dam + damage
- if(damage > 15 && type != BURN && local_damage > 30 && prob(damage) && !(status & ORGAN_ROBOT))
- var/datum/wound/internal_bleeding/I = new ()
- wounds += I
- owner.custom_pain("You feel something rip in your [name]!", 1)
-
- // first check whether we can widen an existing wound
- if(wounds.len > 0 && prob(max(50+(number_wounds-1)*10,90)))
- if((type == CUT || type == BRUISE) && damage >= 5)
- //we need to make sure that the wound we are going to worsen is compatible with the type of damage...
- var/list/compatible_wounds = list()
- for(var/datum/wound/W in wounds)
- if(W.can_worsen(type, damage))
- compatible_wounds += W
-
- if(compatible_wounds.len)
- var/datum/wound/W = pick(compatible_wounds)
- W.open_wound(damage)
- if(prob(25))
- if(status & ORGAN_ROBOT)
- owner.visible_message("The damage to [owner.name]'s [name] worsens.",\
- "The damage to your [name] worsens.",\
- "You hear the screech of abused metal.")
- else
- owner.visible_message("The wound on [owner.name]'s [name] widens with a nasty ripping noise.",\
- "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
- var/wound_type = get_wound_type(type, damage)
-
- if(wound_type)
- var/datum/wound/W = new wound_type(damage)
-
- //Check whether we can add the wound to an existing wound
- for(var/datum/wound/other in wounds)
- if(other.can_merge(W))
- other.merge_wound(W)
- W = null // to signify that the wound was added
- break
- if(W)
- wounds += W
-
/****************************************************
PROCESSING & UPDATING
****************************************************/
//Determines if we even need to process this organ.
-/obj/item/organ/external/proc/need_process()
- if(status & (ORGAN_CUT_AWAY|ORGAN_GAUZED|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_SPLINTED|ORGAN_DEAD|ORGAN_MUTATED))
- return 1
- if(brute_dam || burn_dam)
- return 1
- if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up.
- last_dam = brute_dam + burn_dam
- return 1
- else
- last_dam = brute_dam + burn_dam
- if(germ_level)
- return 1
- if(!wound_cleanup_timer && wounds.len)
- wound_cleanup_timer = addtimer(src, "cleanup_wounds", SecondsToTicks(600), 1, wounds)
-
- if(update_icon())
- owner.UpdateDamageIcon(1)
- return 0
-
/obj/item/organ/external/process()
if(owner)
if(parent)
@@ -444,10 +331,6 @@ This function completely restores a damaged organ to perfect condition.
owner.update_body(1)
return
- // Process wounds, doing healing etc. Only do this every few ticks to save processing power
- if(owner.life_tick % wound_update_accuracy == 0)
- update_wounds()
-
//Chem traces slowly vanish
if(owner.life_tick % 10 == 0)
for(var/chemID in trace_chemicals)
@@ -500,17 +383,10 @@ Note that amputating the affected organ does in fact remove the infection from t
/obj/item/organ/external/proc/handle_germ_sync()
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
- for(var/datum/wound/W in wounds)
- //Open wounds can become infected
- if(owner.germ_level > W.germ_level && W.infection_check())
- W.germ_level++
-
if(antibiotics < 5)
- for(var/datum/wound/W in wounds)
- //Infected wounds raise the organ's germ level
- if(W.germ_level > germ_level)
- germ_level++
- break //limit increase to a maximum of one per second
+ //Open wounds can become infected
+ if(owner.germ_level > germ_level && infection_check())
+ germ_level++
/obj/item/organ/external/handle_germ_effects()
@@ -557,92 +433,16 @@ Note that amputating the affected organ does in fact remove the infection from t
germ_level++
owner.adjustToxLoss(1)
-//Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections
-/obj/item/organ/external/proc/update_wounds()
-
- if((status & ORGAN_ROBOT)) //Robotic limbs don't heal or get worse.
- return
-
- for(var/datum/wound/W in wounds)
-
- // Internal wounds get worse over time. Low temperatures (cryo) stop them.
- if(W.internal && !W.can_autoheal() && owner.bodytemperature >= 170)
- var/bicardose = owner.reagents.get_reagent_amount("styptic_powder")
- if(!bicardose) //styptic powder stops internal wounds from growing bigger with time, and also stop bleeding
- W.open_wound(0.1 * wound_update_accuracy)
- owner.blood_volume = max(owner.blood_volume - (0.05 * W.damage * wound_update_accuracy), 0)
-
- owner.blood_volume = max(owner.blood_volume - (0.02 * W.damage * wound_update_accuracy), 0)
- if(prob(1 * wound_update_accuracy))
- owner.custom_pain("You feel a stabbing pain in your [name]!",1)
-
- //overdose of styptic powder begins healing IB
- if(owner.reagents.get_reagent_amount("styptic_powder") >= 30)
- W.damage = max(0, W.damage - 0.2)
-
- // slow healing
- var/heal_amt = 0
-
- // if damage >= 50 AFTER treatment then it's probably too severe to heal within the timeframe of a round.
- if(W.can_autoheal() && W.wound_damage() < 50)
- heal_amt += 0.5
-
- //we only update wounds once in [wound_update_accuracy] ticks so have to emulate realtime
- heal_amt = heal_amt * wound_update_accuracy
- //configurable regen speed woo, no-regen hardcore or instaheal hugbox, choose your destiny
- heal_amt = heal_amt * config.organ_regeneration_multiplier
- // amount of healing is spread over all the wounds
- heal_amt = heal_amt / (wounds.len + 1)
- // making it look prettier on scanners
- heal_amt = round(heal_amt,0.1)
- W.heal_damage(heal_amt)
-
- // Salving also helps against infection
- if(W.germ_level > 0 && W.salved && prob(2))
- W.disinfected = 1
- W.germ_level = 0
-
- // sync the organ's damage with its wounds
- src.update_damages()
- if(update_icon())
- owner.UpdateDamageIcon(1)
-
//Updates brute_damn and burn_damn from wound damages. Updates BLEEDING status.
-/obj/item/organ/external/proc/update_damages()
- number_wounds = 0
- brute_dam = 0
- burn_dam = 0
- status &= ~ORGAN_BLEEDING
- var/clamped = 0
+/obj/item/organ/external/proc/check_fracture()
+ if(config.bones_can_break && brute_dam > min_broken_damage && !(status & ORGAN_ROBOT))
+ fracture()
- var/mob/living/carbon/human/H
- if(istype(owner,/mob/living/carbon/human))
- H = owner
-
- for(var/datum/wound/W in wounds)
- if(W.damage_type == CUT || W.damage_type == BRUISE)
- brute_dam += W.damage
- else if(W.damage_type == BURN)
- burn_dam += W.damage
-
- if(!(status & ORGAN_ROBOT) && W.bleeding())
- W.bleed_timer--
- if(H && (NO_BLOOD in H.species.species_traits)) // Bloodless organic races are finicky
- W.clamped = 1
- W.bleed_timer = 0
- else
- status |= ORGAN_BLEEDING
-
- clamped |= W.clamped
-
- number_wounds += W.amount
-
- if(open && !clamped && (H && !(NO_BLOOD in H.species.species_traits)))
- status |= ORGAN_BLEEDING
-
- //Bone fractures
- if(config.bones_can_break && brute_dam > min_broken_damage * config.organ_health_multiplier && !(status & ORGAN_ROBOT))
- src.fracture()
+/obj/item/organ/external/proc/check_for_internal_bleeding(damage)
+ var/local_damage = brute_dam + damage
+ if(damage > 15 && local_damage > 30 && prob(damage) && !(status & ORGAN_ROBOT))
+ internal_bleeding = TRUE
+ owner.custom_pain("You feel something rip in your [name]!", 1)
// new damage icon system
// returns just the brute/burn damage code
@@ -710,22 +510,16 @@ Note that amputating the affected organ does in fact remove the infection from t
var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed().
// Let people make limbs become fun things when removed
var/atom/movable/dropped_part = remove(null, ignore_children)
- victim.traumatic_shock += 30
- wounds.Cut()
- if(parent && !nodamage)
- var/datum/wound/lost_limb/W = new (src, disintegrate, clean)
+ if(parent)
parent.children -= src
- if(clean)
- parent.wounds |= W
- parent.update_damages()
- else
- var/obj/item/organ/external/stump/stump = new (victim, 0, src)
- if(status & ORGAN_ROBOT)
- stump.robotize()
- stump.wounds |= W
- victim.bodyparts |= stump
- stump.update_damages()
+ if(!nodamage)
+ var/total_brute = brute_dam
+ var/total_burn = burn_dam
+ for(var/obj/item/organ/external/E in children) //Factor in the children's brute and burn into how much will transfer
+ total_brute += E.brute_dam
+ total_burn += E.burn_dam
+ parent.take_damage(total_brute, total_burn, ignore_resists = TRUE) //Transfer the full damage to the parent, bypass limb damage reduction.
parent = null
spawn(1)
@@ -746,6 +540,8 @@ Note that amputating the affected organ does in fact remove the infection from t
if(src && istype(loc,/turf))
dropped_part.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
dir = 2
+ brute_dam = 0
+ burn_dam = 0 //Reset the damage on the limb; the damage should have transferred to the parent; we don't want extra damage being re-applie when then limb is re-attached
return dropped_part
else
qdel(src) // If you flashed away to ashes, YOU FLASHED AWAY TO ASHES
@@ -754,9 +550,6 @@ Note that amputating the affected organ does in fact remove the infection from t
/****************************************************
HELPERS
****************************************************/
-/obj/item/organ/external/proc/is_stump()
- return 0
-
/obj/item/organ/external/proc/release_restraints(var/mob/living/carbon/human/holder)
if(!holder)
holder = owner
@@ -773,41 +566,6 @@ Note that amputating the affected organ does in fact remove the infection from t
"\The [holder.legcuffed.name] falls off you.")
holder.unEquip(holder.legcuffed)
-
-/obj/item/organ/external/proc/bandage()
- var/rval = 0
- src.status &= ~ORGAN_BLEEDING
- for(var/datum/wound/W in wounds)
- if(W.internal) continue
- rval |= !W.bandaged
- W.bandaged = 1
- return rval
-
-/obj/item/organ/external/proc/disinfect()
- var/rval = 0
- for(var/datum/wound/W in wounds)
- if(W.internal) continue
- rval |= !W.disinfected
- W.disinfected = 1
- W.germ_level = 0
- return rval
-
-/obj/item/organ/external/proc/clamp()
- var/rval = 0
- src.status &= ~ORGAN_BLEEDING
- for(var/datum/wound/W in wounds)
- if(W.internal) continue
- rval |= !W.clamped
- W.clamped = 1
- return rval
-
-/obj/item/organ/external/proc/salve()
- var/rval = 0
- for(var/datum/wound/W in wounds)
- rval |= !W.salved
- W.salved = 1
- return rval
-
/obj/item/organ/external/proc/fracture()
if(status & ORGAN_ROBOT)
return //ORGAN_BROKEN doesn't have the same meaning for robot limbs
@@ -833,7 +591,7 @@ Note that amputating the affected organ does in fact remove the infection from t
/obj/item/organ/external/proc/mend_fracture()
if(status & ORGAN_ROBOT)
return 0 //ORGAN_BROKEN doesn't have the same meaning for robot limbs
- if(brute_dam > min_broken_damage * config.organ_health_multiplier)
+ if(brute_dam > min_broken_damage)
return 0 //will just immediately fracture again
status &= ~ORGAN_BROKEN
@@ -845,7 +603,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(!make_tough)
brute_mod = 0.66
burn_mod = 0.66
- fail_at_full_damage = 1
+ dismember_at_max_damage = TRUE
else
tough = 1
// Robot parts also lack bones
@@ -885,10 +643,9 @@ Note that amputating the affected organ does in fact remove the infection from t
return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health?
/obj/item/organ/external/proc/has_infected_wound()
- for(var/datum/wound/W in wounds)
- if(W.germ_level > INFECTION_LEVEL_ONE)
- return 1
- return 0
+ if(germ_level > INFECTION_LEVEL_ONE)
+ return TRUE
+ return FALSE
/obj/item/organ/external/proc/is_usable()
if(((status & ORGAN_ROBOT) && get_damage() >= max_damage) && !tough) //robot limbs just become inoperable at max damage
@@ -898,9 +655,6 @@ Note that amputating the affected organ does in fact remove the infection from t
/obj/item/organ/external/proc/is_malfunctioning()
return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam) && !tough)
-/obj/item/organ/external/proc/open_enough_for_surgery()
- return (encased ? (open == 3) : (open == 2))
-
/obj/item/organ/external/remove(var/mob/living/user, var/ignore_children)
if(!owner)
@@ -917,7 +671,6 @@ Note that amputating the affected organ does in fact remove the infection from t
. = ..()
status |= ORGAN_DESTROYED
- victim.bad_external_organs -= src
// Attached organs also fly off.
if(!ignore_children)
@@ -972,17 +725,18 @@ Note that amputating the affected organ does in fact remove the infection from t
return 0
return src == O.bodyparts_by_name[limb_name]
-// The callback we use to remove wounds from an un-processed limb
-/obj/item/organ/external/proc/cleanup_wounds(var/list/slated_wounds)
- wound_cleanup_timer = null
- for(var/datum/wound/W in slated_wounds)
- if(!W)
- continue
- if(W.damage > 0)
- continue
- wounds -= W
- qdel(W)
+/obj/item/organ/external/proc/infection_check()
+ var/total_damage = brute_dam + burn_dam
+ if(total_damage)
+ if(total_damage < 10) //small amounts of damage aren't infectable
+ return FALSE
+ if(owner && owner.bleedsuppress && total_damage < 25)
+ return FALSE
+
+ var/dam_coef = round(total_damage / 10)
+ return prob(dam_coef * 10)
+ return FALSE
/obj/item/organ/external/serialize()
var/list/data = ..()
diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm
index bf7620a2cf4..f3edb2ec490 100644
--- a/code/modules/surgery/organs/organ_icon.dm
+++ b/code/modules/surgery/organs/organ_icon.dm
@@ -58,7 +58,7 @@ var/global/list/limb_icon_cache = list()
var/obj/item/organ/internal/eyes/eyes = owner.get_int_organ(/obj/item/organ/internal/eyes)//owner.internal_bodyparts_by_name["eyes"]
if(eyes) eyes.update_colour()
-/obj/item/organ/external/head/remove()
+/obj/item/organ/external/head/remove(mob/living/user, ignore_children)
get_icon()
. = ..()
@@ -172,7 +172,7 @@ var/global/list/limb_icon_cache = list()
gender = "f"
else
gender = "m"
- if(limb_name == "head" && !is_stump() && !(status & ORGAN_DESTROYED))
+ if(limb_name == "head" && !(status & ORGAN_DESTROYED))
var/obj/item/organ/external/head/head_organ = src
head_organ.handle_alt_icon()
diff --git a/code/modules/surgery/organs/organ_stump.dm b/code/modules/surgery/organs/organ_stump.dm
deleted file mode 100644
index 9d6c0183cb8..00000000000
--- a/code/modules/surgery/organs/organ_stump.dm
+++ /dev/null
@@ -1,28 +0,0 @@
-/obj/item/organ/external/stump
- name = "limb stump"
- icon_name = ""
- var/can_intake_reagents = 0
-
-/obj/item/organ/external/stump/New(var/mob/living/carbon/holder, var/internal, var/obj/item/organ/external/limb)
- if(istype(limb))
- limb_name = limb.limb_name
- body_part = limb.body_part
- amputation_point = limb.amputation_point
- parent_organ = limb.parent_organ
- wounds = limb.wounds
- ..(holder, internal)
- if(istype(limb))
- max_damage = limb.max_damage
- if((limb.status & ORGAN_ROBOT) && (!parent || (parent.status & ORGAN_ROBOT)))
- robotize() //if both limb and the parent are robotic, the stump is robotic too
-
-/obj/item/organ/external/stump/is_stump()
- return 1
-
-/obj/item/organ/external/stump/remove()
- ..()
- qdel(src)
- return null
-
-/obj/item/organ/external/stump/is_usable()
- return 0
diff --git a/code/modules/surgery/organs/subtypes/skrell.dm b/code/modules/surgery/organs/subtypes/skrell.dm
index 842088f2937..7e5785c7fa0 100644
--- a/code/modules/surgery/organs/subtypes/skrell.dm
+++ b/code/modules/surgery/organs/subtypes/skrell.dm
@@ -40,7 +40,7 @@
/obj/item/organ/internal/headpocket/on_owner_death()
empty_contents()
-/obj/item/organ/internal/headpocket/remove()
+/obj/item/organ/internal/headpocket/remove(mob/living/carbon/M, special = 0)
empty_contents()
. = ..()
diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm
index d3a76fab60c..bf2aeced0d4 100644
--- a/code/modules/surgery/organs/subtypes/standard.dm
+++ b/code/modules/surgery/organs/subtypes/standard.dm
@@ -46,6 +46,7 @@
w_class = WEIGHT_CLASS_BULKY // if you know what I mean ;)
body_part = LOWER_TORSO
vital = 1
+ cannot_amputate = TRUE
parent_organ = "chest"
amputation_point = "lumbar"
gendered_icon = 1
@@ -219,8 +220,8 @@
..()
-/obj/item/organ/external/head/take_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list())
- ..(brute, burn, sharp, used_weapon, forbidden_limbs)
+/obj/item/organ/external/head/take_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list(), ignore_resists = FALSE)
+ ..(brute, burn, sharp, used_weapon, forbidden_limbs, ignore_resists)
if(!disfigured)
if(brute_dam > 40)
if(prob(50))
diff --git a/code/modules/surgery/organs/wound.dm b/code/modules/surgery/organs/wound.dm
deleted file mode 100644
index b1f99b34d6b..00000000000
--- a/code/modules/surgery/organs/wound.dm
+++ /dev/null
@@ -1,344 +0,0 @@
-
-/****************************************************
- WOUNDS
-****************************************************/
-/datum/wound
- // number representing the current stage
- var/current_stage = 0
-
- // description of the wound
- var/desc = "wound" //default in case something borks
-
- // amount of damage this wound causes
- var/damage = 0
- // ticks of bleeding left.
- var/bleed_timer = 0
- // amount of damage the current wound type requires(less means we need to apply the next healing stage)
- var/min_damage = 0
-
- // is the wound bandaged?
- var/bandaged = 0
- // Similar to bandaged, but works differently
- var/clamped = 0
- // is the wound salved?
- var/salved = 0
- // is the wound disinfected?
- var/disinfected = 0
- var/created = 0
- // number of wounds of this type
- var/amount = 1
- // amount of germs in the wound
- var/germ_level = 0
-
- /* These are defined by the wound type and should not be changed */
-
- // stages such as "cut", "deep cut", etc.
- var/list/stages
- // internal wounds can only be fixed through surgery
- var/internal = 0
- // maximum stage at which bleeding should still happen. Beyond this stage bleeding is prevented.
- var/max_bleeding_stage = 0
- // one of CUT, BRUISE, BURN
- var/damage_type = CUT
- // whether this wound needs a bandage/salve to heal at all
- // the maximum amount of damage that this wound can have and still autoheal
- var/autoheal_cutoff = 15
-
-
-
-
- // helper lists
- var/tmp/list/desc_list = list()
- var/tmp/list/damage_list = list()
-
- New(var/damage)
-
- created = world.time
-
- // reading from a list("stage" = damage) is pretty difficult, so build two separate
- // lists from them instead
- for(var/V in stages)
- desc_list += V
- damage_list += stages[V]
-
- src.damage = damage
-
- // initialize with the appropriate stage
- src.init_stage(damage)
-
- bleed_timer += damage
-
- // returns 1 if there's a next stage, 0 otherwise
- proc/init_stage(var/initial_damage)
- current_stage = stages.len
-
- while(src.current_stage > 1 && src.damage_list[current_stage-1] <= initial_damage / src.amount)
- src.current_stage--
-
- src.min_damage = damage_list[current_stage]
- src.desc = desc_list[current_stage]
-
- // the amount of damage per wound
- proc/wound_damage()
- return src.damage / src.amount
-
- proc/can_autoheal()
- if(src.wound_damage() <= autoheal_cutoff)
- return 1
-
- return is_treated()
-
- // checks whether the wound has been appropriately treated
- proc/is_treated()
- if(damage_type == BRUISE || damage_type == CUT)
- return bandaged
- else if(damage_type == BURN)
- return salved
-
- // Checks whether other other can be merged into src.
- proc/can_merge(var/datum/wound/other)
- if(other.type != src.type) return 0
- if(other.current_stage != src.current_stage) return 0
- if(other.damage_type != src.damage_type) return 0
- if(!(other.can_autoheal()) != !(src.can_autoheal())) return 0
- if(!(other.bandaged) != !(src.bandaged)) return 0
- if(!(other.clamped) != !(src.clamped)) return 0
- if(!(other.salved) != !(src.salved)) return 0
- if(!(other.disinfected) != !(src.disinfected)) return 0
- //if(other.germ_level != src.germ_level) return 0
- return 1
-
- proc/merge_wound(var/datum/wound/other)
- src.damage += other.damage
- src.amount += other.amount
- src.bleed_timer += other.bleed_timer
- src.germ_level = max(src.germ_level, other.germ_level)
- src.created = max(src.created, other.created) //take the newer created time
-
- // checks if wound is considered open for external infections
- // untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger
- proc/infection_check()
- if(damage < 10) //small cuts, tiny bruises, and moderate burns shouldn't be infectable.
- return 0
- if(is_treated() && damage < 25) //anything less than a flesh wound (or equivalent) isn't infectable if treated properly
- return 0
- if(disinfected)
- germ_level = 0 //reset this, just in case
- return 0
-
- if(damage_type == BRUISE && !bleeding()) //bruises only infectable if bleeding
- return 0
-
- var/dam_coef = round(damage/10)
- switch(damage_type)
- if(BRUISE)
- return prob(dam_coef*5)
- if(BURN)
- return prob(dam_coef*10)
- if(CUT)
- return prob(dam_coef*20)
-
- return 0
-
- // heal the given amount of damage, and if the given amount of damage was more
- // than what needed to be healed, return how much heal was left
- // set @heals_internal to also heal internal organ damage
- proc/heal_damage(amount, heals_internal = 0)
- if(src.internal && !heals_internal)
- // heal nothing
- return amount
-
- var/healed_damage = min(src.damage, amount)
- amount -= healed_damage
- src.damage -= healed_damage
-
- while(src.wound_damage() < damage_list[current_stage] && current_stage < src.desc_list.len)
- current_stage++
- desc = desc_list[current_stage]
- src.min_damage = damage_list[current_stage]
-
- // return amount of healing still leftover, can be used for other wounds
- return amount
-
- // opens the wound again
- proc/open_wound(damage)
- src.damage += damage
- bleed_timer += damage
-
- while(src.current_stage > 1 && src.damage_list[current_stage-1] <= src.damage / src.amount)
- src.current_stage--
-
- src.desc = desc_list[current_stage]
- src.min_damage = damage_list[current_stage]
-
- // 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
- proc/can_worsen(damage_type, damage)
- if(src.damage_type != damage_type)
- return 0 //incompatible damage types
-
- if(src.amount > 1)
- return 0
-
- //with 1.5*, a shallow cut will be able to carry at most 30 damage,
- //37.5 for a deep cut
- //52.5 for a flesh wound, etc.
- var/max_wound_damage = 1.5*src.damage_list[1]
- if(src.damage + damage > max_wound_damage)
- return 0
-
- return 1
-
- proc/bleeding()
- if(src.internal)
- return 0 // internal wounds don't bleed in the sense of this function
-
- if(current_stage > max_bleeding_stage)
- return 0
-
- if(bandaged||clamped)
- return 0
-
- if(wound_damage() <= 30 && bleed_timer <= 0)
- return 0 //Bleed timer has run out. Wounds with more than 30 damage don't stop bleeding on their own.
-
- return (damage_type == BRUISE && wound_damage() >= 20 || damage_type == CUT && wound_damage() >= 5)
-
-/** WOUND DEFINITIONS **/
-
-//Note that the MINIMUM damage before a wound can be applied should correspond to
-//the damage amount for the stage with the same name as the wound.
-//e.g. /datum/wound/cut/deep should only be applied for 15 damage and up,
-//because in it's stages list, "deep cut" = 15.
-/proc/get_wound_type(var/type = CUT, var/damage)
- switch(type)
- if(CUT)
- switch(damage)
- if(70 to INFINITY)
- return /datum/wound/cut/massive
- if(60 to 70)
- return /datum/wound/cut/gaping_big
- if(50 to 60)
- return /datum/wound/cut/gaping
- if(25 to 50)
- return /datum/wound/cut/flesh
- if(15 to 25)
- return /datum/wound/cut/deep
- if(0 to 15)
- return /datum/wound/cut/small
- if(BRUISE)
- return /datum/wound/bruise
- if(BURN)
- switch(damage)
- if(50 to INFINITY)
- return /datum/wound/burn/carbonised
- if(40 to 50)
- return /datum/wound/burn/deep
- if(30 to 40)
- return /datum/wound/burn/severe
- if(15 to 30)
- return /datum/wound/burn/large
- if(0 to 15)
- return /datum/wound/burn/moderate
- return null //no wound
-
-/** CUTS **/
-/datum/wound/cut/small
- // Minor cuts have max_bleeding_stage set to the stage that bears the wound type's name.
- // The major cut types have the max_bleeding_stage set to the clot stage (which is accordingly given the "blood soaked" descriptor).
- max_bleeding_stage = 3
- stages = list("ugly ripped cut" = 20, "ripped cut" = 10, "cut" = 5, "healing cut" = 2, "small scab" = 0)
- damage_type = CUT
-
-/datum/wound/cut/deep
- max_bleeding_stage = 3
- stages = list("ugly deep ripped cut" = 25, "deep ripped cut" = 20, "deep cut" = 15, "clotted cut" = 8, "scab" = 2, "fresh skin" = 0)
- damage_type = CUT
-
-/datum/wound/cut/flesh
- max_bleeding_stage = 4
- stages = list("ugly ripped flesh wound" = 35, "ugly flesh wound" = 30, "flesh wound" = 25, "blood soaked clot" = 15, "large scab" = 5, "fresh skin" = 0)
- damage_type = CUT
-
-/datum/wound/cut/gaping
- max_bleeding_stage = 3
- stages = list("gaping wound" = 50, "large blood soaked clot" = 25, "blood soaked clot" = 15, "small angry scar" = 5, "small straight scar" = 0)
- damage_type = CUT
-
-/datum/wound/cut/gaping_big
- max_bleeding_stage = 3
- stages = list("big gaping wound" = 60, "healing gaping wound" = 40, "large blood soaked clot" = 25, "large angry scar" = 10, "large straight scar" = 0)
- damage_type = CUT
-
-datum/wound/cut/massive
- max_bleeding_stage = 3
- stages = list("massive wound" = 70, "massive healing wound" = 50, "massive blood soaked clot" = 25, "massive angry scar" = 10, "massive jagged scar" = 0)
- damage_type = CUT
-
-/** BRUISES **/
-/datum/wound/bruise
- stages = list("monumental bruise" = 80, "huge bruise" = 50, "large bruise" = 30,
- "moderate bruise" = 20, "small bruise" = 10, "tiny bruise" = 5)
- max_bleeding_stage = 3 //only large bruise and above can bleed.
- autoheal_cutoff = 30
- damage_type = BRUISE
-
-/** BURNS **/
-/datum/wound/burn/moderate
- stages = list("ripped burn" = 10, "moderate burn" = 5, "healing moderate burn" = 2, "fresh skin" = 0)
- damage_type = BURN
-
-/datum/wound/burn/large
- stages = list("ripped large burn" = 20, "large burn" = 15, "healing large burn" = 5, "fresh skin" = 0)
- damage_type = BURN
-
-/datum/wound/burn/severe
- stages = list("ripped severe burn" = 35, "severe burn" = 30, "healing severe burn" = 10, "burn scar" = 0)
- damage_type = BURN
-
-/datum/wound/burn/deep
- stages = list("ripped deep burn" = 45, "deep burn" = 40, "healing deep burn" = 15, "large burn scar" = 0)
- damage_type = BURN
-
-/datum/wound/burn/carbonised
- stages = list("carbonised area" = 50, "healing carbonised area" = 20, "massive burn scar" = 0)
- damage_type = BURN
-
-/** INTERNAL BLEEDING **/
-/datum/wound/internal_bleeding
- internal = 1
- stages = list("severed artery" = 30, "cut artery" = 20, "damaged artery" = 10, "bruised artery" = 5)
- autoheal_cutoff = 5
- max_bleeding_stage = 4 //all stages bleed. It's called internal bleeding after all.
-
-
-/** EXTERNAL ORGAN LOSS **/
-/datum/wound/lost_limb
-
-/datum/wound/lost_limb/New(var/obj/item/organ/external/lost_limb, var/losstype, var/clean)
- var/damage_amt = lost_limb.max_damage
- if(clean) damage_amt /= 2
-
- switch(losstype)
- if(DROPLIMB_SHARP, DROPLIMB_BLUNT)
- damage_type = CUT
- max_bleeding_stage = 3 //clotted stump and above can bleed.
- stages = list(
- "ripped stump" = damage_amt*1.3,
- "bloody stump" = damage_amt,
- "clotted stump" = damage_amt*0.5,
- "scarred stump" = 0
- )
- if(DROPLIMB_BURN)
- damage_type = BURN
- stages = list(
- "ripped charred stump" = damage_amt*1.3,
- "charred stump" = damage_amt,
- "scarred stump" = damage_amt*0.5,
- "scarred stump" = 0
- )
-
- ..(damage_amt)
-
-/datum/wound/lost_limb/can_merge(var/datum/wound/other)
- return 0 //cannot be merged
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index da41915249c..dc50a5cdf22 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -353,7 +353,7 @@
else if(istype(tool, /obj/item/stack/medical/bruise_pack) || istype(tool, /obj/item/stack/nanopaste))
dam_amt = 5
target.adjustToxLoss(10)
- affected.createwound(CUT, 5)
+ affected.take_damage(5)
for(var/obj/item/organ/internal/I in affected.internal_organs)
if(I && I.damage > 0 && !(I.tough))
@@ -401,7 +401,7 @@
if(affected)
user.visible_message(" [user]'s hand slips, damaging [target]'s [affected.name] with [tool]!", \
" Your hand slips, damaging [target]'s [affected.name] with [tool]!")
- affected.createwound(BRUISE, 20)
+ affected.take_damage(20)
else
user.visible_message(" [user]'s hand slips, damaging [target]'s [parse_zone(target_zone)] with [tool]!", \
" Your hand slips, damaging [target]'s [parse_zone(target_zone)] with [tool]!")
@@ -421,7 +421,7 @@
var/self_msg = " Your hand slips, tearing skin!"
user.visible_message(msg, self_msg)
if(affected)
- affected.createwound(BRUISE, 20)
+ affected.take_damage(20)
return 0
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index cfd6b8e632e..f18787f1fe4 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -33,14 +33,10 @@
if(ishuman(target))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
- if(!affected) return 0
+ if(!affected)
+ return 0
- var/internal_bleeding = 0
- for(var/datum/wound/W in affected.wounds)
- if(W.internal)
- internal_bleeding = 1
- break
- if(internal_bleeding)
+ if(affected.internal_bleeding)
return 1
return 0
@@ -75,15 +71,10 @@
/datum/surgery_step/fix_vein/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if(!affected) return 0
+ if(!affected)
+ return 0
- var/internal_bleeding = 0
- for(var/datum/wound/W in affected.wounds)
- if(W.internal)
- internal_bleeding = 1
- break
-
- return internal_bleeding
+ return affected.internal_bleeding
/datum/surgery_step/fix_vein/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
@@ -97,9 +88,7 @@
user.visible_message(" [user] has patched the damaged vein in [target]'s [affected.name] with \the [tool].", \
" You have patched the damaged vein in [target]'s [affected.name] with \the [tool].")
- for(var/datum/wound/W in affected.wounds) if(W.internal)
- affected.wounds -= W
- affected.update_damages()
+ affected.internal_bleeding = FALSE
if(ishuman(user) && prob(40))
var/mob/living/carbon/human/U = user
U.bloody_hands(target, 0)
@@ -159,7 +148,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(" [user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!", \
" Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!")
- affected.createwound(CUT, 20, 1)
+ affected.take_damage(20)
return 0
diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm
index 2815905eedc..58474a372c6 100644
--- a/code/modules/surgery/robotics.dm
+++ b/code/modules/surgery/robotics.dm
@@ -490,7 +490,7 @@
" Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!")
target.adjustToxLoss(5)
- affected.createwound(CUT, 5)
+ affected.take_damage(5)
for(var/obj/item/organ/internal/I in affected.internal_organs)
if(I)
diff --git a/config/example/game_options.txt b/config/example/game_options.txt
index 7246e0773fa..ae3cc153995 100644
--- a/config/example/game_options.txt
+++ b/config/example/game_options.txt
@@ -8,17 +8,6 @@ HEALTH_THRESHOLD_DEAD -100
## Determines whether bones can be broken through excessive damage to the organ
## 0 means bones can't break, 1 means they can
BONES_CAN_BREAK 1
-## Determines whether limbs can be amputated through excessive damage to the organ
-## 0 means limbs can't be amputated, 1 means they can
-LIMBS_CAN_BREAK 1
-
-## Multiplier which enables organs to take more damage before bones breaking or limbs being destroyed
-## 100 means normal, 50 means half
-ORGAN_HEALTH_MULTIPLIER 100
-
-## Multiplier which influences how fast organs regenerate naturally
-## 100 means normal, 50 means half
-ORGAN_REGENERATION_MULTIPLIER 0
### REVIVAL ###
## Whether pod plants work or not
diff --git a/paradise.dme b/paradise.dme
index 30b34017bcc..aabf27d6e61 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -2161,13 +2161,11 @@
#include "code\modules\surgery\organs\organ_external.dm"
#include "code\modules\surgery\organs\organ_icon.dm"
#include "code\modules\surgery\organs\organ_internal.dm"
-#include "code\modules\surgery\organs\organ_stump.dm"
#include "code\modules\surgery\organs\pain.dm"
#include "code\modules\surgery\organs\parasites.dm"
#include "code\modules\surgery\organs\robolimbs.dm"
#include "code\modules\surgery\organs\skeleton.dm"
#include "code\modules\surgery\organs\vocal_cords.dm"
-#include "code\modules\surgery\organs\wound.dm"
#include "code\modules\surgery\organs\subtypes\abductor.dm"
#include "code\modules\surgery\organs\subtypes\diona.dm"
#include "code\modules\surgery\organs\subtypes\drask.dm"