diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index e6917bc8830..7a7213b12bf 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -534,6 +534,17 @@ Turf and target are seperate in case you want to teleport some distance from a t loc = loc.loc return loc +/* +Returns 1 if the chain up to the area contains the given typepath +0 otherwise +*/ +/atom/proc/is_found_within(var/typepath) + var/atom/A = src + while(A.loc) + if(istype(A.loc, typepath)) + return 1 + A = A.loc + return 0 // the on-close client verb // called when a browser popup window is closed after registering with proc/onclose() diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index c3abfec87d7..10ca0ae1fbf 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -23,6 +23,8 @@ var/list/organ_cache = list() germ_level = 0 var/datum/dna/dna var/datum/species/species + var/needs_preservation_update = 1 + var/is_in_freezer = 0 /obj/item/organ/Destroy() if(!owner) @@ -106,7 +108,6 @@ var/list/organ_cache = list() if(status & ORGAN_DEAD) return - // Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature? if(is_preserved()) return @@ -121,8 +122,11 @@ var/list/organ_cache = list() if(B && prob(40)) reagents.remove_reagent("blood",0.1) blood_splatter(src,B,1) - - germ_level += rand(2,6) + // 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++ + if(germ_level >= INFECTION_LEVEL_ONE) + germ_level += rand(2,6) if(germ_level >= INFECTION_LEVEL_TWO) germ_level += rand(2,6) if(germ_level >= INFECTION_LEVEL_THREE) @@ -141,20 +145,27 @@ var/list/organ_cache = list() die() /obj/item/organ/proc/is_preserved() - if(istype(loc,/obj/item/organ)) - var/obj/item/organ/O = loc - return O.is_preserved() - if(istype(loc,/obj/item/device/mmi)) // Brain items are qdel'd when put in an MMI, and recreated in perfection when removed. - return 1 // This is all silly, but I can use this when I have MMIs actually store the brain -- Crazylemon - if(istype(loc,/obj/item/bodybag/cryobag)) + 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(istype(loc,/obj/structure/closet/crate/freezer)) + 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)) - for(var/obj/structure/closet/crate/freezer/F in loc.contents) - if(F.opened) - return 1 - break + if(needs_preservation_update) + // 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 + // There's probably a much less silly way of doing this, but BYOND native algorithms are stupidly naive + is_in_freezer = 0 + for(var/obj/structure/closet/crate/freezer/F in loc.contents) + if(F.opened) + is_in_freezer = 1 // on the same tile, close enough, should keep organs much fresher on avg + break + needs_preservation_update = 0 + spawn(100) // (100 / 10) once every 10 seconds + needs_preservation_update = 1 + return is_in_freezer // I'd like static varibles, please // You can do your cool location temperature organ preserving effects here! return 0 @@ -194,6 +205,7 @@ var/list/organ_cache = list() /obj/item/organ/proc/rejuvenate() damage = 0 + germ_level = 0 /obj/item/organ/proc/is_damaged() return damage > 0 diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 1c6ca1d176b..866ff0a1eef 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -79,24 +79,28 @@ switch(stage) if(0) if(istype(W,/obj/item/weapon/scalpel)) + spread_germs_to_organ(src,user) user.visible_message("[user] cuts [src] open with [W]!") stage++ return if(1) if(istype(W,/obj/item/weapon/retractor)) + spread_germs_to_organ(src,user) user.visible_message("[user] cracks [src] open like an egg with [W]!") stage++ return if(2) if(istype(W,/obj/item/weapon/hemostat)) + spread_germs_to_organ(O,user) if(contents.len) var/obj/item/removing = pick(contents) removing.loc = get_turf(user.loc) var/obj/item/organ/O = removing if(istype(O)) O.status |= ORGAN_CUT_AWAY + spread_germs_to_organ(O,user) // This wouldn't be any cleaner than the actual surgery O.removed(user) - else if(!(user.l_hand && user.r_hand)) + if(!(user.l_hand && user.r_hand)) user.put_in_hands(removing) user.visible_message("[user] extracts [removing] from [src] with [W]!") else diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index b0b840d138c..b7c4e059c3a 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -136,6 +136,7 @@ for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) if(I.robotic < 2) + spread_germs_to_organ(I, user) user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ "You start treating damage to [target]'s [I.name] with [tool_name]." ) @@ -236,6 +237,7 @@ var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) + spread_germs_to_organ(I, user) I.status |= ORGAN_CUT_AWAY fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -289,6 +291,7 @@ if(target.op_stage.current_organ) var/obj/item/organ/O = target.internal_organs_by_name[target.op_stage.current_organ] if(O && istype(O)) + spread_germs_to_organ(O, user) O.removed(user) target.op_stage.current_organ = null @@ -369,6 +372,7 @@ var/obj/item/organ/O = tool if(istype(O)) O.replaced(target,affected) + spread_germs_to_organ(O, user) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("\red [user]'s hand slips, damaging \the [tool]!", \ @@ -419,6 +423,7 @@ var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) I.status &= ~ORGAN_CUT_AWAY + spread_germs_to_organ(I, user) fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index d353c4f49f7..9a743891511 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -66,7 +66,7 @@ /datum/surgery_step/proc/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) return null -/proc/spread_germs_to_organ(obj/item/organ/external/E, mob/living/carbon/human/user) +/proc/spread_germs_to_organ(obj/item/organ/E, mob/living/carbon/human/user) if(!istype(user) || !istype(E)) return var/germ_level = user.germ_level