mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 10:33:30 +01:00
Merge remote-tracking branch 'upstream/master' into lungsss
# Conflicts: # code/modules/mob/living/carbon/alien/humanoid/life.dm # code/modules/mob/living/carbon/human/life.dm # code/modules/mob/living/carbon/human/species/station.dm # code/modules/surgery/surgery.dm
This commit is contained in:
@@ -101,7 +101,7 @@
|
||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||
user.visible_message("<span class='warning'> [user]'s hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!</span>" , \
|
||||
"<span class='warning'> Your hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!</span>")
|
||||
affected.createwound(BRUISE, 5)
|
||||
affected.take_damage(5)
|
||||
return 0
|
||||
|
||||
/datum/surgery_step/mend_skull
|
||||
@@ -135,7 +135,7 @@
|
||||
user.visible_message("<span class='warning'>[user]'s hand slips, damaging [target]'s face with \the [tool]!</span>" , \
|
||||
"<span class='warning'>Your hand slips, damaging [target]'s face with \the [tool]!</span>")
|
||||
var/obj/item/organ/external/head/h = affected
|
||||
h.createwound(BRUISE, 10)
|
||||
h.take_damage(10)
|
||||
h.disfigured = 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
|
||||
user.visible_message("<span class='warning'> [user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!</span>", \
|
||||
"<span class='warning'> Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!</span>")
|
||||
affected.createwound(CUT, 20)
|
||||
affected.take_damage(20)
|
||||
|
||||
/datum/surgery_step/cavity/make_space
|
||||
name = "make cavity space"
|
||||
@@ -188,8 +188,7 @@
|
||||
"<span class='notice'> You put \the [tool] inside [target]'s [get_cavity(affected)] cavity.</span>" )
|
||||
if((tool.w_class > get_max_wclass(affected)/2 && prob(50) && !(affected.status & ORGAN_ROBOT)))
|
||||
to_chat(user, "<span class='warning'> You tear some vessels trying to fit the object in the cavity.</span>")
|
||||
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
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
user.visible_message("<span class='warning'> [user]'s hand slips, cracking [target]'s [affected.encased] with \the [tool]!</span>" , \
|
||||
"<span class='warning'> Your hand slips, cracking [target]'s [affected.encased] with \the [tool]!</span>" )
|
||||
|
||||
affected.createwound(CUT, 20)
|
||||
affected.take_damage(20)
|
||||
affected.fracture()
|
||||
|
||||
return 0
|
||||
@@ -113,7 +113,7 @@
|
||||
var/self_msg = "<span class='warning'> Your hand slips, cracking [target]'s [affected.encased]!</span>"
|
||||
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 = "<span class='warning'> Your hand slips, bending [target]'s [affected.encased] the wrong way!</span>"
|
||||
user.visible_message(msg, self_msg)
|
||||
|
||||
affected.createwound(BRUISE, 20)
|
||||
affected.take_damage(20)
|
||||
affected.fracture()
|
||||
|
||||
return 0
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||
user.visible_message("<span class='warning'> [user]'s hand slips, slicing [target]'s throat wth \the [tool]!</span>" , \
|
||||
"<span class='warning'> Your hand slips, slicing [target]'s throat wth \the [tool]!</span>" )
|
||||
affected.createwound(CUT, 60)
|
||||
affected.take_damage(60)
|
||||
target.AdjustLoseBreath(4)
|
||||
|
||||
return 0
|
||||
@@ -131,7 +131,6 @@
|
||||
user.visible_message("<span class='notice'> [user] cauterizes the incision on [target]'s face and neck with \the [tool].</span>", \
|
||||
"<span class='notice'> You cauterize the incision on [target]'s face and neck with \the [tool].</span>")
|
||||
affected.open = 0
|
||||
affected.status &= ~ORGAN_BLEEDING
|
||||
var/obj/item/organ/external/head/h = affected
|
||||
h.disfigured = 0
|
||||
h.update_icon()
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||
if(affected == null)
|
||||
return 0
|
||||
if(affected.status & ORGAN_DESTROYED)
|
||||
return 0
|
||||
if(affected.status & ORGAN_ROBOT)
|
||||
return 0
|
||||
return 1
|
||||
@@ -47,14 +45,13 @@
|
||||
user.visible_message("<span class='notice'> [user] has made an incision on [target]'s [affected.name] with \the [tool].</span>", \
|
||||
"<span class='notice'> You have made an incision on [target]'s [affected.name] with \the [tool].</span>",)
|
||||
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("<span class='warning'> [user]'s hand slips, slicing open [target]'s [affected.name] in a wrong spot with \the [tool]!</span>", \
|
||||
"<span class='warning'> Your hand slips, slicing open [target]'s [affected.name] in a wrong spot with \the [tool]!</span>")
|
||||
affected.createwound(CUT, 10)
|
||||
affected.take_damage(10)
|
||||
return 0
|
||||
|
||||
/datum/surgery_step/generic/clamp_bleeders
|
||||
@@ -81,7 +78,6 @@
|
||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||
user.visible_message("<span class='notice'> [user] clamps bleeders in [target]'s [affected.name] with \the [tool]</span>.", \
|
||||
"<span class='notice'> You clamp bleeders in [target]'s [affected.name] with \the [tool].</span>")
|
||||
affected.clamp()
|
||||
spread_germs_to_organ(affected, user, tool)
|
||||
return 1
|
||||
|
||||
@@ -89,7 +85,7 @@
|
||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||
user.visible_message("<span class='warning'> [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.name] with \the [tool]!</span>", \
|
||||
"<span class='warning'> Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!</span>",)
|
||||
affected.createwound(CUT, 10)
|
||||
affected.take_damage(10)
|
||||
return 0
|
||||
|
||||
/datum/surgery_step/generic/retract_skin
|
||||
@@ -173,7 +169,6 @@
|
||||
"<span class='notice'> You cauterize the incision on [target]'s [affected.name] with \the [tool].</span>")
|
||||
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)
|
||||
@@ -218,8 +213,6 @@
|
||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||
if(affected == null)
|
||||
return 0
|
||||
if(affected.status & ORGAN_DESTROYED)
|
||||
return 0
|
||||
return !affected.cannot_amputate
|
||||
|
||||
/datum/surgery_step/generic/amputate/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
|
||||
@@ -245,6 +238,6 @@
|
||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||
user.visible_message("<span class='warning'> [user]'s hand slips, sawing through the bone in [target]'s [affected.name] with \the [tool]!</span>", \
|
||||
"<span class='warning'> Your hand slips, sawwing through the bone in [target]'s [affected.name] with \the [tool]!</span>")
|
||||
affected.createwound(CUT, 30)
|
||||
affected.take_damage(30)
|
||||
affected.fracture()
|
||||
return 0
|
||||
|
||||
@@ -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, "<span class='warning'>You need to hold a cautery in inactive hand to stop [M]'s surgery!</span>")
|
||||
|
||||
@@ -54,5 +54,4 @@
|
||||
|
||||
affected.open = 0
|
||||
affected.germ_level = 0
|
||||
affected.status &= ~ORGAN_BLEEDING
|
||||
return 1
|
||||
@@ -165,10 +165,6 @@
|
||||
H.h_style = "Bald"
|
||||
H.f_style = "Shaved"
|
||||
target.m_styles["head"] = "None"
|
||||
E.status &= ~ORGAN_DESTROYED
|
||||
if(E.children)
|
||||
for(var/obj/item/organ/external/C in E.children)
|
||||
C.status &= ~ORGAN_DESTROYED
|
||||
|
||||
|
||||
/datum/surgery_step/limb/connect
|
||||
@@ -197,13 +193,6 @@
|
||||
var/obj/item/organ/external/E = target.get_organ(target_zone)
|
||||
user.visible_message("<span class='notice'>[user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].</span>", \
|
||||
"<span class='notice'>You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].</span>")
|
||||
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
|
||||
target.update_body()
|
||||
target.updatehealth()
|
||||
target.UpdateDamageIcon()
|
||||
@@ -254,10 +243,6 @@
|
||||
var/new_limb_type = organ_data["path"]
|
||||
var/obj/item/organ/external/new_limb = new new_limb_type(target)
|
||||
new_limb.robotize(L.model_info)
|
||||
new_limb.status &= ~ORGAN_DESTROYED
|
||||
if(new_limb.children)
|
||||
for(var/obj/item/organ/external/C in new_limb.children)
|
||||
C.status &= ~ORGAN_DESTROYED
|
||||
if(L.sabotaged)
|
||||
new_limb.sabotaged = 1
|
||||
target.update_body()
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
status = ORGAN_ROBOT
|
||||
var/implant_color = "#FFFFFF"
|
||||
var/implant_overlay
|
||||
tough = 1 //not easyly broken by combat damage
|
||||
sterile = 1 //not very germy
|
||||
tough = TRUE // Immune to damage
|
||||
sterile = TRUE // Doesn't accumulate germs
|
||||
robotic = 2 // these are cybernetic after all
|
||||
|
||||
/obj/item/organ/internal/cyberimp/New(var/mob/M = null)
|
||||
|
||||
@@ -18,9 +18,6 @@
|
||||
/mob/living/carbon/human/handle_blood()
|
||||
var/list/blood_data = get_blood_data(get_blood_id())//PROCCEPTION
|
||||
|
||||
if(in_stasis)
|
||||
return
|
||||
|
||||
if(NO_BLOOD in species.species_traits)
|
||||
bleed_rate = 0
|
||||
return
|
||||
@@ -61,6 +58,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 +77,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)
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ var/list/organ_cache = list()
|
||||
var/freezer_update_period = 100
|
||||
var/is_in_freezer = 0
|
||||
|
||||
var/sterile = 0 //can the organ be infected by germs?
|
||||
var/tough = 0 //can organ be easily damaged?
|
||||
var/sterile = FALSE //can the organ be infected by germs?
|
||||
var/tough = FALSE //can organ be easily damaged?
|
||||
|
||||
|
||||
/obj/item/organ/Destroy()
|
||||
@@ -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))
|
||||
@@ -96,16 +95,11 @@ var/list/organ_cache = list()
|
||||
return
|
||||
|
||||
//Process infections
|
||||
if((status & ORGAN_ROBOT) || sterile ||(owner && (IS_PLANT in owner.species.species_traits)))
|
||||
if((status & ORGAN_ROBOT) || sterile || (owner && (IS_PLANT in owner.species.species_traits)))
|
||||
germ_level = 0
|
||||
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,27 +110,20 @@ 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()
|
||||
handle_germ_effects()
|
||||
|
||||
//check if we've hit max_damage
|
||||
if(damage >= max_damage)
|
||||
necrotize()
|
||||
|
||||
/obj/item/organ/proc/is_preserved()
|
||||
if(istype(loc,/obj/item/device/mmi))
|
||||
germ_level = max(0, germ_level - 1) // So a brain can slowly recover from being left out of an MMI
|
||||
return 1
|
||||
if(is_found_within(/obj/item/bodybag/cryobag))
|
||||
return 1
|
||||
if(is_found_within(/obj/structure/closet/crate/freezer))
|
||||
return 1
|
||||
if(istype(loc,/turf))
|
||||
if(is_found_within(/obj/machinery/clonepod))
|
||||
return 1
|
||||
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
|
||||
@@ -179,12 +166,12 @@ var/list/organ_cache = list()
|
||||
if(antibiotics < 5 && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) ))
|
||||
parent.germ_level++
|
||||
|
||||
/obj/item/organ/internal/handle_germ_effects()
|
||||
..()
|
||||
if(germ_level >= INFECTION_LEVEL_TWO)
|
||||
if(prob(3)) //about once every 30 seconds
|
||||
take_damage(1,silent=prob(30))
|
||||
|
||||
/obj/item/organ/proc/receive_chem(chemical as obj)
|
||||
return 0
|
||||
|
||||
/obj/item/organ/proc/rejuvenate()
|
||||
damage = 0
|
||||
germ_level = 0
|
||||
@@ -204,7 +191,7 @@ var/list/organ_cache = list()
|
||||
return damage >= min_bruised_damage
|
||||
|
||||
/obj/item/organ/proc/is_broken()
|
||||
return (damage >= min_broken_damage || (status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED)))
|
||||
return (damage >= min_broken_damage || ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED)))
|
||||
|
||||
//Germs
|
||||
/obj/item/organ/proc/handle_antibiotics()
|
||||
@@ -248,25 +235,25 @@ var/list/organ_cache = list()
|
||||
if(parent && !silent)
|
||||
owner.custom_pain("Something inside your [parent.name] hurts a lot.", 1)
|
||||
|
||||
//check if we've hit max_damage
|
||||
if(damage >= max_damage)
|
||||
necrotize()
|
||||
|
||||
/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
|
||||
|
||||
/obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc
|
||||
robotize(1) //Skip the icon/name setting that occurs in robotize to avoid having to reset the icon file.
|
||||
status &= ~ORGAN_ROBOT
|
||||
status |= ORGAN_ASSISTED
|
||||
robotic = 1
|
||||
min_bruised_damage = 15
|
||||
min_broken_damage = 35
|
||||
|
||||
/obj/item/organ/emp_act(severity)
|
||||
/obj/item/organ/external/emp_act(severity)
|
||||
if(!(status & ORGAN_ROBOT))
|
||||
return
|
||||
if(tough)
|
||||
@@ -316,10 +303,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)
|
||||
|
||||
@@ -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, "<span class='notice'>You can't feel your [name] anymore...</span>")
|
||||
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)
|
||||
@@ -115,26 +97,24 @@
|
||||
switch(open)
|
||||
if(0)
|
||||
if(istype(W,/obj/item/weapon/scalpel))
|
||||
spread_germs_to_organ(src,user, W)
|
||||
spread_germs_to_organ(src, user, W)
|
||||
user.visible_message("<span class='danger'><b>[user]</b> cuts [src] open with [W]!</span>")
|
||||
open++
|
||||
return
|
||||
if(1)
|
||||
if(istype(W,/obj/item/weapon/retractor))
|
||||
spread_germs_to_organ(src,user, W)
|
||||
spread_germs_to_organ(src, user, W)
|
||||
user.visible_message("<span class='danger'><b>[user]</b> cracks [src] open like an egg with [W]!</span>")
|
||||
open++
|
||||
return
|
||||
if(2)
|
||||
if(istype(W,/obj/item/weapon/hemostat))
|
||||
spread_germs_to_organ(src,user, W)
|
||||
spread_germs_to_organ(src, user, W)
|
||||
if(contents.len)
|
||||
var/obj/item/removing = pick(contents)
|
||||
var/obj/item/organ/internal/O = removing
|
||||
if(istype(O))
|
||||
O.status |= ORGAN_CUT_AWAY
|
||||
if(!O.sterile)
|
||||
spread_germs_to_organ(O,user, W) // This wouldn't be any cleaner than the actual surgery
|
||||
spread_germs_to_organ(O, user, W) // This wouldn't be any cleaner than the actual surgery
|
||||
user.put_in_hands(removing)
|
||||
user.visible_message("<span class='danger'><b>[user]</b> extracts [removing] from [src] with [W]!</span>")
|
||||
else
|
||||
@@ -161,7 +141,6 @@
|
||||
|
||||
/obj/item/organ/external/replaced(var/mob/living/carbon/human/target)
|
||||
owner = target
|
||||
status = status & ~ORGAN_DESTROYED
|
||||
forceMove(owner)
|
||||
if(istype(owner))
|
||||
if(!isnull(owner.bodyparts_by_name[limb_name]))
|
||||
@@ -177,12 +156,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,19 +168,17 @@
|
||||
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)
|
||||
|
||||
if((brute <= 0) && (burn <= 0))
|
||||
return 0
|
||||
|
||||
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
|
||||
@@ -219,83 +191,71 @@
|
||||
// Damage an internal organ
|
||||
if(internal_organs && internal_organs.len)
|
||||
var/obj/item/organ/internal/I = pick(internal_organs)
|
||||
if(!I.tough)//mostly for cybernetic organs
|
||||
I.take_damage(brute / 2)
|
||||
brute -= brute / 2
|
||||
I.take_damage(brute * 0.5)
|
||||
brute -= brute * 0.5
|
||||
|
||||
if(status & ORGAN_BROKEN && prob(40) && brute)
|
||||
owner.emote("scream") //getting hit on broken hand hurts
|
||||
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 +267,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 +294,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,93 +310,14 @@ 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("<span class='alert'>The damage to [owner.name]'s [name] worsens.</span>",\
|
||||
"<span class='alert'>The damage to your [name] worsens.</span>",\
|
||||
"You hear the screech of abused metal.")
|
||||
else
|
||||
owner.visible_message("<span class='alert'>The wound on [owner.name]'s [name] widens with a nasty ripping noise.</span>",\
|
||||
"<span class='alert'>The wound on your [name] widens with a nasty ripping noise.</span>",\
|
||||
"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)
|
||||
if(parent.status & ORGAN_DESTROYED)
|
||||
status |= ORGAN_DESTROYED
|
||||
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)
|
||||
@@ -484,7 +354,7 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
*/
|
||||
/obj/item/organ/external/proc/update_germs()
|
||||
|
||||
if(status & (ORGAN_ROBOT|ORGAN_DESTROYED) || (IS_PLANT in owner.species.species_traits)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
|
||||
if((status & ORGAN_ROBOT) || (IS_PLANT in owner.species.species_traits)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
|
||||
germ_level = 0
|
||||
return
|
||||
|
||||
@@ -500,17 +370,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,99 +420,20 @@ 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
|
||||
/obj/item/organ/external/proc/damage_state_text()
|
||||
if(status & ORGAN_DESTROYED)
|
||||
return "--"
|
||||
|
||||
var/tburn = 0
|
||||
var/tbrute = 0
|
||||
|
||||
@@ -710,22 +494,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 +524,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 +534,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 +550,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 +575,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,9 +587,9 @@ 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
|
||||
tough = TRUE
|
||||
// Robot parts also lack bones
|
||||
// This is so surgery isn't kaput, let's see how this does
|
||||
encased = null
|
||||
@@ -885,22 +627,18 @@ 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
|
||||
return
|
||||
return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD))
|
||||
return !(status & (ORGAN_MUTATED|ORGAN_DEAD))
|
||||
|
||||
/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)
|
||||
@@ -916,9 +654,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)
|
||||
for(var/obj/item/organ/external/O in children)
|
||||
@@ -972,17 +707,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 = ..()
|
||||
|
||||
@@ -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")
|
||||
var/obj/item/organ/external/head/head_organ = src
|
||||
head_organ.handle_alt_icon()
|
||||
|
||||
|
||||
@@ -401,20 +401,17 @@
|
||||
//High toxins levels are dangerous
|
||||
if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("charcoal"))
|
||||
//Healthy liver suffers on its own
|
||||
if(src.damage < min_broken_damage)
|
||||
src.damage += 0.2 * PROCESS_ACCURACY
|
||||
if(damage < min_broken_damage)
|
||||
take_damage(0.2 * PROCESS_ACCURACY)
|
||||
//Damaged one shares the fun
|
||||
else
|
||||
var/obj/item/organ/internal/O = pick(owner.internal_organs)
|
||||
if(O)
|
||||
O.damage += 0.2 * PROCESS_ACCURACY
|
||||
O.take_damage(0.2 * PROCESS_ACCURACY)
|
||||
|
||||
//Detox can heal small amounts of damage
|
||||
if(src.damage && src.damage < src.min_bruised_damage && owner.reagents.has_reagent("charcoal"))
|
||||
src.damage -= 0.2 * PROCESS_ACCURACY
|
||||
|
||||
if(src.damage < 0)
|
||||
src.damage = 0
|
||||
if(damage && damage < min_bruised_damage && owner.reagents.has_reagent("charcoal"))
|
||||
take_damage(-0.2 * PROCESS_ACCURACY)
|
||||
|
||||
// Get the effectiveness of the liver.
|
||||
var/filter_effect = 3
|
||||
@@ -424,7 +421,7 @@
|
||||
filter_effect -= 2
|
||||
|
||||
// Damaged liver means some chemicals are very dangerous
|
||||
if(src.damage >= src.min_bruised_damage)
|
||||
if(damage >= min_bruised_damage)
|
||||
for(var/datum/reagent/R in owner.reagents.reagent_list)
|
||||
// Ethanol and all drinks are bad
|
||||
if(istype(R, /datum/reagent/consumable/ethanol))
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -2,28 +2,18 @@
|
||||
origin_tech = "biotech=5"
|
||||
icon_state = "xgibmid2"
|
||||
var/list/alien_powers = list()
|
||||
tough = 1
|
||||
sterile = 1
|
||||
|
||||
///obj/item/organ/internal/xenos/New()
|
||||
// for(var/A in alien_powers)
|
||||
// if(ispath(A))
|
||||
// alien_powers -= A
|
||||
// alien_powers += new A(src)
|
||||
// ..()
|
||||
tough = TRUE
|
||||
sterile = TRUE
|
||||
|
||||
///can be changed if xenos get an update..
|
||||
/obj/item/organ/internal/xenos/insert(mob/living/carbon/M, special = 0)
|
||||
..()
|
||||
for(var/P in alien_powers)
|
||||
M.verbs |= P
|
||||
//M.verbs |= alien_powers.Copy()
|
||||
|
||||
/obj/item/organ/internal/xenos/remove(mob/living/carbon/M, special = 0)
|
||||
for(var/P in alien_powers)
|
||||
M.verbs -= P
|
||||
//M.verbs -= alien_powers.Copy()
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/item/organ/internal/xenos/prepare_eat()
|
||||
|
||||
@@ -435,7 +435,7 @@ var/static/regex/multispin_words = regex("like a record baby")
|
||||
playsound(get_turf(owner), 'sound/items/bikehorn.ogg', 300, 1)
|
||||
if(owner.mind && owner.mind.assigned_role == "Clown")
|
||||
for(var/mob/living/carbon/C in listeners)
|
||||
C.slip(0,7 * power_multiplier)
|
||||
C.slip("your feet", 0, 7 * power_multiplier)
|
||||
next_command = world.time + cooldown_stun
|
||||
else
|
||||
next_command = world.time + cooldown_meme
|
||||
|
||||
@@ -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
|
||||
@@ -200,7 +200,7 @@
|
||||
return
|
||||
|
||||
for(var/obj/item/organ/internal/I in affected.internal_organs)
|
||||
if(I && I.damage > 0)
|
||||
if(I && I.damage)
|
||||
if(I.robotic < 2 && !istype (tool, /obj/item/stack/nanopaste))
|
||||
if(!(I.sterile))
|
||||
spread_germs_to_organ(I, user, tool)
|
||||
@@ -238,7 +238,7 @@
|
||||
for(var/obj/item/organ/internal/I in affected.internal_organs)
|
||||
if(I)
|
||||
I.surgeryize()
|
||||
if(I && I.damage > 0)
|
||||
if(I && I.damage)
|
||||
if(I.robotic < 2 && !istype (tool, /obj/item/stack/nanopaste))
|
||||
user.visible_message("<span class='notice'> [user] treats damage to [target]'s [I.name] with [tool_name].</span>", \
|
||||
"<span class='notice'> You treat damage to [target]'s [I.name] with [tool_name].</span>" )
|
||||
@@ -264,8 +264,6 @@
|
||||
user.visible_message("<span class='notice'> [user] has transplanted [tool] into [target]'s [parse_zone(target_zone)].</span>",
|
||||
"<span class='notice'> You have transplanted [tool] into [target]'s [parse_zone(target_zone)].</span>")
|
||||
|
||||
I.status &= ~ORGAN_CUT_AWAY
|
||||
|
||||
else if(current_type == "extract")
|
||||
var/mob/living/simple_animal/borer/B = target.has_brain_worms()
|
||||
if(target_zone == "head" && B && B.host == target)
|
||||
@@ -280,7 +278,6 @@
|
||||
|
||||
add_logs(user, target, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]")
|
||||
spread_germs_to_organ(I, user, tool)
|
||||
I.status |= ORGAN_CUT_AWAY
|
||||
var/obj/item/thing = I.remove(target)
|
||||
if(!istype(thing))
|
||||
thing.forceMove(get_turf(target))
|
||||
@@ -353,10 +350,10 @@
|
||||
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))
|
||||
if(I && I.damage && !(I.tough))
|
||||
I.take_damage(dam_amt,0)
|
||||
|
||||
return 0
|
||||
@@ -401,7 +398,7 @@
|
||||
if(affected)
|
||||
user.visible_message("<span class='warning'> [user]'s hand slips, damaging [target]'s [affected.name] with [tool]!</span>", \
|
||||
"<span class='warning'> Your hand slips, damaging [target]'s [affected.name] with [tool]!</span>")
|
||||
affected.createwound(BRUISE, 20)
|
||||
affected.take_damage(20)
|
||||
else
|
||||
user.visible_message("<span class='warning'> [user]'s hand slips, damaging [target]'s [parse_zone(target_zone)] with [tool]!</span>", \
|
||||
"<span class='warning'> Your hand slips, damaging [target]'s [parse_zone(target_zone)] with [tool]!</span>")
|
||||
@@ -421,7 +418,7 @@
|
||||
var/self_msg = "<span class='warning'> Your hand slips, tearing skin!</span>"
|
||||
user.visible_message(msg, self_msg)
|
||||
if(affected)
|
||||
affected.createwound(BRUISE, 20)
|
||||
affected.take_damage(20)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
@@ -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("<span class='notice'> [user] has patched the damaged vein in [target]'s [affected.name] with \the [tool].</span>", \
|
||||
"<span class='notice'> You have patched the damaged vein in [target]'s [affected.name] with \the [tool].</span>")
|
||||
|
||||
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("<span class='warning'> [user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!</span>", \
|
||||
"<span class='warning'> Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!</span>")
|
||||
affected.createwound(CUT, 20, 1)
|
||||
affected.take_damage(20)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
@@ -56,8 +56,6 @@
|
||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||
if(affected == null)
|
||||
return 0
|
||||
if(affected.status & ORGAN_DESTROYED)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/surgery_step/robotics/external
|
||||
@@ -400,7 +398,7 @@
|
||||
|
||||
var/found_damaged_organ = FALSE
|
||||
for(var/obj/item/organ/internal/I in affected.internal_organs)
|
||||
if(I && I.damage > 0 && I.robotic >= 2)
|
||||
if(I && I.damage && I.robotic >= 2)
|
||||
user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \
|
||||
"You start mending the damage to [target]'s [I.name]'s mechanisms.")
|
||||
found_damaged_organ = TRUE
|
||||
@@ -425,7 +423,7 @@
|
||||
if(!hasorgans(target))
|
||||
return
|
||||
for(var/obj/item/organ/internal/I in affected.internal_organs)
|
||||
if(I && I.damage > 0)
|
||||
if(I && I.damage)
|
||||
if(I.robotic >= 2)
|
||||
user.visible_message("<span class='notice'> [user] repairs [target]'s [I.name] with [tool].</span>", \
|
||||
"<span class='notice'> You repair [target]'s [I.name] with [tool].</span>" )
|
||||
@@ -443,8 +441,6 @@
|
||||
user.visible_message("<span class='notice'> [user] has reattached [target]'s [I].</span>" , \
|
||||
"<span class='notice'> You have reattached [target]'s [I].</span>")
|
||||
|
||||
if(I && istype(I))
|
||||
I.status &= ~ORGAN_CUT_AWAY
|
||||
else if(current_type == "install")
|
||||
user.visible_message("<span class='notice'> [user] has installed \the [tool] into [target]'s [affected.name].</span>", \
|
||||
"<span class='notice'> You have installed \the [tool] into [target]'s [affected.name].</span>")
|
||||
@@ -461,7 +457,6 @@
|
||||
|
||||
add_logs(user, target, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]")
|
||||
spread_germs_to_organ(I, user)
|
||||
I.status |= ORGAN_CUT_AWAY
|
||||
var/obj/item/thing = I.remove(target)
|
||||
if(!istype(thing))
|
||||
thing.forceMove(get_turf(target))
|
||||
@@ -490,7 +485,7 @@
|
||||
"<span class='warning'> Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!</span>")
|
||||
|
||||
target.adjustToxLoss(5)
|
||||
affected.createwound(CUT, 5)
|
||||
affected.take_damage(5)
|
||||
|
||||
for(var/obj/item/organ/internal/I in affected.internal_organs)
|
||||
if(I)
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
return null
|
||||
|
||||
/proc/spread_germs_to_organ(obj/item/organ/E, mob/living/carbon/human/user, obj/item/tool)
|
||||
if(!istype(user) || !istype(E))
|
||||
if(!istype(user) || !istype(E) || !(E.status & ORGAN_ROBOT) || E.sterile)
|
||||
return
|
||||
|
||||
var/germ_level = user.germ_level
|
||||
@@ -189,12 +189,11 @@
|
||||
//germ spread from surgeon touching the patient
|
||||
if(user.gloves)
|
||||
germ_level = user.gloves.germ_level
|
||||
if(!(E.status & ORGAN_ROBOT)) //Germs on robotic limbs bad
|
||||
E.germ_level = max(germ_level,E.germ_level) //as funny as scrubbing microbes out with clean gloves is - no.
|
||||
spread_germs_by_incision(E,tool)//germ spread from environement to patient
|
||||
E.germ_level += germ_level
|
||||
spread_germs_by_incision(E, tool) //germ spread from environement to patient
|
||||
|
||||
/proc/spread_germs_by_incision(obj/item/organ/external/E,obj/item/tool)
|
||||
if(!istype(E,/obj/item/organ/external))
|
||||
if(!istype(E, /obj/item/organ/external))
|
||||
return
|
||||
|
||||
var/germs = 0
|
||||
@@ -202,7 +201,7 @@
|
||||
for(var/mob/living/carbon/human/H in view(2, E.loc))//germs from people
|
||||
if(AStar(E.loc, H.loc, /turf/proc/Distance, 2, simulated_only = 0))
|
||||
if((!(BREATHLESS in H.mutations) || !(NO_BREATHE in H.species.species_traits)) && !H.wear_mask) //wearing a mask helps preventing people from breathing cooties into open incisions
|
||||
germs+=H.germ_level/4
|
||||
germs += H.germ_level * 0.25
|
||||
|
||||
for(var/obj/effect/decal/cleanable/M in view(2, E.loc))//germs from messes
|
||||
if(AStar(E.loc, M.loc, /turf/proc/Distance, 2, simulated_only = 0))
|
||||
@@ -213,7 +212,7 @@
|
||||
germs += 30
|
||||
|
||||
if(E.internal_organs.len)
|
||||
germs = germs / E.internal_organs.len
|
||||
germs = germs / (E.internal_organs.len + 1) // +1 for the external limb this eventually applies to; let's not multiply germs now.
|
||||
for(var/obj/item/organ/internal/O in E.internal_organs)
|
||||
if(!(O.status & ORGAN_ROBOT))
|
||||
O.germ_level += germs
|
||||
|
||||
Reference in New Issue
Block a user