From e8f8138e0497332c8489e3b197e96bb95e3931c3 Mon Sep 17 00:00:00 2001 From: Chinsky Date: Fri, 22 Feb 2013 23:06:37 +0400 Subject: [PATCH 1/4] Added priority system for surgery steps. Steps with higher priority would be attempted first. Added preparation step for item insertion surgery. --- baystation12.dme | 1 + code/__HELPERS/global_lists.dm | 1 + code/modules/surgery/appendix.dm | 1 + code/modules/surgery/bones.dm | 1 + code/modules/surgery/braincore.dm | 1 + code/modules/surgery/eye.dm | 1 + code/modules/surgery/face.dm | 1 + code/modules/surgery/other.dm | 118 +----------------------------- code/modules/surgery/ribcage.dm | 3 +- code/modules/surgery/surgery.dm | 17 +++++ 10 files changed, 27 insertions(+), 118 deletions(-) diff --git a/baystation12.dme b/baystation12.dme index e1657ada89..734f6ae931 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1174,6 +1174,7 @@ #include "code\modules\surgery\eye.dm" #include "code\modules\surgery\face.dm" #include "code\modules\surgery\generic.dm" +#include "code\modules\surgery\implant.dm" #include "code\modules\surgery\other.dm" #include "code\modules\surgery\ribcage.dm" #include "code\modules\surgery\robolimbs.dm" diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index d0b8b90d6b..566a587b8a 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -66,6 +66,7 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al for(var/T in paths) var/datum/surgery_step/S = new T surgery_steps += S + sort_surgeries() /* // Uncomment to debug chemical reaction list. /client/verb/debug_chemical_list() diff --git a/code/modules/surgery/appendix.dm b/code/modules/surgery/appendix.dm index 9443b7aca3..027e323c57 100644 --- a/code/modules/surgery/appendix.dm +++ b/code/modules/surgery/appendix.dm @@ -4,6 +4,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/appendectomy/ + priority = 2 can_infect = 1 blood_level = 1 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index 95d173acbe..e0eaab854f 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -4,6 +4,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/glue_bone + priority = 2 required_tool = /obj/item/weapon/bonegel allowed_tools = list(/obj/item/weapon/screwdriver) can_infect = 1 diff --git a/code/modules/surgery/braincore.dm b/code/modules/surgery/braincore.dm index e809f3cb95..d08d6d9878 100644 --- a/code/modules/surgery/braincore.dm +++ b/code/modules/surgery/braincore.dm @@ -4,6 +4,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/brain/ + priority = 2 blood_level = 1 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) return target_zone == "head" && hasorgans(target) diff --git a/code/modules/surgery/eye.dm b/code/modules/surgery/eye.dm index 224afc5af8..8f100aee17 100644 --- a/code/modules/surgery/eye.dm +++ b/code/modules/surgery/eye.dm @@ -4,6 +4,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/eye + priority = 2 can_infect = 1 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm index 2e6e0c65d0..90ce1d8134 100644 --- a/code/modules/surgery/face.dm +++ b/code/modules/surgery/face.dm @@ -4,6 +4,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/face + priority = 2 can_infect = 0 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index 3c3dd477b4..d75bb538f3 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -5,6 +5,7 @@ /datum/surgery_step/fix_vein + priority = 2 required_tool = /obj/item/weapon/FixOVein allowed_tools = list(/obj/item/weapon/cable_coil) can_infect = 1 @@ -45,120 +46,3 @@ user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!" , \ "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!") affected.take_damage(5, 0) - -////////////////////////////////////////////////////////////////// -// IMPLANT REMOVAL SURGERY // -////////////////////////////////////////////////////////////////// - -/datum/surgery_step/implant_removal - required_tool = /obj/item/weapon/hemostat - allowed_tools = list(/obj/item/weapon/wirecutters, /obj/item/weapon/kitchen/utensil/fork) - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - return affected.open == 2 && !(affected.status & ORGAN_BLEEDING) - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts poking around inside the incision on [target]'s [affected.display_name] with \the [tool].", \ - "You start poking around inside the incision on [target]'s [affected.display_name] with \the [tool]" ) - target.custom_pain("The pain in your chest is living hell!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) - - var/find_prob = 0 - if (affected.implants.len) - var/obj/item/weapon/implant/imp = affected.implants[1] - if (imp.islegal()) - find_prob +=60 - else - find_prob +=40 - if (isright(tool)) - find_prob +=20 - if (prob(find_prob)) - user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.display_name] with \the [tool].", \ - "\blue You take something out of incision on [target]'s [affected.display_name]s with \the [tool]." ) - affected.implants -= imp - imp.loc = get_turf(target) - imp.imp_in = null - imp.implanted = 0 - else if (affected.hidden) - user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.display_name] with \the [tool].", \ - "\blue You take something out of incision on [target]'s [affected.display_name]s with \the [tool]." ) - affected.hidden.loc = get_turf(target) - if(!affected.hidden.blood_DNA) - affected.hidden.blood_DNA = list() - affected.hidden.blood_DNA[target.dna.unique_enzymes] = target.dna.b_type - affected.hidden.update_icon() - affected.hidden = null - - else - user.visible_message("\blue [user] could not find anything inside [target]'s [affected.display_name], and pulls \the [tool] out.", \ - "\blue You could not find anything inside [target]'s [affected.display_name]." ) - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!") - affected.createwound(CUT, 20) - if (affected.implants.len) - var/fail_prob = 10 - if (!isright(tool)) - fail_prob += 30 - if (prob(fail_prob)) - var/obj/item/weapon/implant/imp = affected.implants[1] - user.visible_message("\red Something beeps inside [target]'s [affected.display_name]!") - playsound(imp.loc, 'sound/items/countdown.ogg', 75, 1, -3) - spawn(25) - imp.activate() - -////////////////////////////////////////////////////////////////// -// ITEM PLACEMENT SURGERY // -////////////////////////////////////////////////////////////////// - -/datum/surgery_step/item_place - required_tool = /obj/item - - min_duration = 80 - max_duration = 100 - var/max_size = 2 //maximum w_class of item that fits. - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - if (affected.name in list("chest","groin","head")) - max_size = 3 - else - max_size = 2 - return affected.open == 2 && !(affected.status & ORGAN_BLEEDING) && tool.w_class <= max_size && !affected.hidden - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts putting [tool] inside the incision on [target]'s [affected.display_name].", \ - "You start putting [tool] inside the incision on [target]'s [affected.display_name]." ) - target.custom_pain("The pain in your chest is living hell!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) - - user.visible_message("\blue [user] puts [tool] inside [target]'s [affected.display_name].", \ - "\blue You put [tool] inside [target]'s [affected.display_name]." ) - if (tool.w_class > max_size/2 && prob(50)) - user << "\red You tear some vessels trying to fit such big object in this cavity." - var/datum/wound/internal_bleeding/I = new (15) - affected.wounds += I - affected.owner.custom_pain("You feel something rip in your [affected.display_name]!", 1) - user.drop_item() - affected.hidden = tool - tool.loc = target - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \ - "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!") - affected.createwound(CUT, 20) diff --git a/code/modules/surgery/ribcage.dm b/code/modules/surgery/ribcage.dm index 04c09cd02e..de5325f982 100644 --- a/code/modules/surgery/ribcage.dm +++ b/code/modules/surgery/ribcage.dm @@ -3,6 +3,7 @@ // GENERIC RIBCAGE SURGERY // ////////////////////////////////////////////////////////////////// /datum/surgery_step/ribcage + priority = 2 can_infect = 1 blood_level = 1 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -195,4 +196,4 @@ var/datum/organ/external/chest/affected = target.get_organ("chest") user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s chest with \the [tool]!", \ "\red Your hand slips, slicing an artery inside [target]'s chest with \the [tool]!") - affected.createwound(CUT, 20) \ No newline at end of file + affected.createwound(CUT, 20) diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 0b2919214d..62b9afb52c 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -1,6 +1,7 @@ /* SURGERY STEPS */ /datum/surgery_step + var/priority = 0 //steps with higher priority would be attempted first // type path referencing the required tool for this step var/required_tool = null @@ -78,6 +79,22 @@ proc/do_surgery(mob/living/M, mob/living/user, obj/item/tool) return 1 //don't want to do weapony things after surgery return 0 +proc/sort_surgeries() + var/gap = surgery_steps.len + var/swapped = 1 + while (gap > 1 || swapped) + swapped = 0 + if(gap > 1) + gap = round(gap / 1.247330950103979) + if(gap < 1) + gap = 1 + for(var/i = 1; gap + i <= surgery_steps.len; i++) + var/datum/surgery_step/l = surgery_steps[i] //Fucking hate + var/datum/surgery_step/r = surgery_steps[gap+i] //how lists work here + if(l.priority < r.priority) + surgery_steps.Swap(i, gap + i) + swapped = 1 + /datum/surgery_status/ var/eyes = 0 var/face = 0 From f50fd49032229829388b1ba5d06c765394d90461 Mon Sep 17 00:00:00 2001 From: Chinsky Date: Fri, 22 Feb 2013 23:12:27 +0400 Subject: [PATCH 2/4] Gangrene! Now germ level for organ has three thresholds. LEVEL 1: Occasional (prob(10) every tick) tox damage and germ level raise. LEVEL 2: In addition to that, tox damage and germ level raise every tick. LEVEL 3: Limb necrosis. Currently does nothing but icon change. Also at this stage germs start leaking to connected organs, so amputations is necessary. --- code/datums/organs/organ_external.dm | 58 +++++++++++++++---- code/datums/organs/wound.dm | 17 ++++++ .../mob/living/carbon/human/update_icons.dm | 4 ++ code/setup.dm | 1 + 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/code/datums/organs/organ_external.dm b/code/datums/organs/organ_external.dm index a90389dc21..b8da2f66a4 100644 --- a/code/datums/organs/organ_external.dm +++ b/code/datums/organs/organ_external.dm @@ -31,6 +31,7 @@ var/status = 0 var/open = 0 var/stage = 0 + var/cavity = 0 var/obj/item/hidden = null var/list/implants = list() @@ -239,25 +240,64 @@ // process wounds, doing healing etc., only do this every 4 ticks to save processing power if(owner.life_tick % wound_update_accuracy == 0) update_wounds() + + //Dismemberment if(status & ORGAN_DESTROYED) if(!destspawn && config.limbs_can_break) droplimb() return - if(!(status & ORGAN_BROKEN)) - perma_injury = 0 if(parent) if(parent.status & ORGAN_DESTROYED) status |= ORGAN_DESTROYED owner.update_body(1) return + + //Bone fracurtes if(config.bones_can_break && brute_dam > min_broken_damage * config.organ_health_multiplier && !(status & ORGAN_ROBOT)) src.fracture() - if(germ_level > 0) - for(var/datum/wound/W in wounds) if(!W.bandaged && !W.salved) - W.germ_level = max(W.germ_level, germ_level) + if(!(status & ORGAN_BROKEN)) + perma_injury = 0 + + update_germs() update_icon() return +//Updating germ levels. Handles organ germ levels and necrosis. +#define GANGREN_LEVEL_ONE 100 +#define GANGREN_LEVEL_TWO 105 +#define GANGREN_LEVEL_TERMINAL 110 +#define GERM_TRANSFER_AMOUNT germ_level/500 +/datum/organ/external/proc/update_germs() + if(germ_level > 0 && owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs + //Syncing germ levels with external wounds + for(var/datum/wound/W in wounds) + if(!W.bandaged && !W.salved) + W.germ_level = max(W.germ_level, germ_level) //Wounds get all the germs + if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels + germ_level++ + + if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/100))) + germ_level++ + owner.adjustToxLoss(1) + + if(germ_level > GANGREN_LEVEL_TWO) + germ_level++ + owner.adjustToxLoss(1) + + if(germ_level > GANGREN_LEVEL_TERMINAL) + if (!(status & ORGAN_DEAD)) + status |= ORGAN_DEAD + owner << "You can't feel your [display_name] anymore..." + owner.update_body(1) + if (prob(10)) //Spreading the fun + if (children) //To child organs + for (var/datum/organ/external/child in children) + if (!(child.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT))) + child.germ_level += round(GERM_TRANSFER_AMOUNT) + if (parent) + if (!(parent.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT))) + parent.germ_level += round(GERM_TRANSFER_AMOUNT) + //Updating wounds. Handles wound natural healing, internal bleedings and infections /datum/organ/external/proc/update_wounds() for(var/datum/wound/W in wounds) @@ -281,14 +321,12 @@ // amount of healing is spread over all the wounds W.heal_damage((wound_update_accuracy * amount * W.amount * config.organ_regeneration_multiplier) / (20*owner.number_wounds+1)) - if(W.germ_level > 100 && prob(10)) - owner.adjustToxLoss(1 * wound_update_accuracy) - if(W.germ_level > 1000) - owner.adjustToxLoss(1 * wound_update_accuracy) - // Salving also helps against infection if(W.germ_level > 0 && W.salved && prob(2)) W.germ_level = 0 + W.disinfected = 1 + + // sync the organ's damage with its wounds src.update_damages() diff --git a/code/datums/organs/wound.dm b/code/datums/organs/wound.dm index b90ddfca81..90909a3f62 100644 --- a/code/datums/organs/wound.dm +++ b/code/datums/organs/wound.dm @@ -96,6 +96,23 @@ else if(damage_type == BURN) return salved + // 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/can_infect() + if (is_treated() && damage < 10) + return 0 + if (disinfected) + return 0 + var/dam_coef = round(damage/10) + switch (damage_type) + if (BRUISE) + return prob(dam_coef*5) && bleeding() //bruises only infectable if bleeding + 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 diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 478416aae1..88b96a13de 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -222,6 +222,7 @@ proc/get_damage_icon_part(damage_state, body_part) var/husk_color_mod = rgb(96,88,80) var/hulk_color_mod = rgb(48,224,40) var/plant_color_mod = rgb(144,224,144) + var/necrosis_color_mod = rgb(10,50,0) var/husk = (HUSK in src.mutations) //100% unnecessary -Agouri //nope, do you really want to iterate through src.mutations repeatedly? -Pete var/fat = (FAT in src.mutations) @@ -283,6 +284,9 @@ proc/get_damage_icon_part(damage_state, body_part) temp = new /icon(icobase, "[part.icon_name]") if(part.status & ORGAN_ROBOT) temp.GrayScale() + if(part.status & ORGAN_DEAD) + temp.ColorTone(necrosis_color_mod) + temp.SetIntensity(0.7) else if(!skeleton) if(husk) temp.ColorTone(husk_color_mod) diff --git a/code/setup.dm b/code/setup.dm index 33202de26f..e3cc19a30f 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -580,6 +580,7 @@ var/list/TAGGERLOCATIONS = list("Disposals", #define ORGAN_ROBOT 128 #define ORGAN_SPLINTED 256 #define SALVED 512 +#define ORGAN_DEAD 1024 #define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued. From a8fdc167291aabbca2c48d2cfb5cd75ed2029ac7 Mon Sep 17 00:00:00 2001 From: Chinsky Date: Fri, 22 Feb 2013 23:13:22 +0400 Subject: [PATCH 3/4] Debug verb to check how long it would take for gangrene to kick in. --- code/modules/mob/living/carbon/human/human.dm | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 491a457e64..218637c384 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -920,3 +920,31 @@ E.ruptured_lungs = 1 +/mob/living/carbon/human/verb/simulate() + set name = "sim" + set background = 1 + + var/damage = input("Wound damage","Wound damage") as num + + var/germs = 0 + var/tdamage = 0 + var/ticks = 0 + while (germs < 2501 && ticks < 100000 && round(damage/10)*20) + diary << "VIRUS TESTING: [ticks] : germs [germs] tdamage [tdamage] prob [round(damage/10)*20]" + ticks++ + if (prob(round(damage/10)*20)) + germs++ + if (germs == 100) + world << "Reached stage 1 in [ticks] ticks" + if (germs > 100) + if (prob(10)) + damage++ + germs++ + if (germs == 1000) + world << "Reached stage 2 in [ticks] ticks" + if (germs > 1000) + damage++ + germs++ + if (germs == 2500) + world << "Reached stage 3 in [ticks] ticks" + world << "Mob took [tdamage] tox damage" \ No newline at end of file From 83eb9cac83dd4da7df0132c356adb0bcd24868c4 Mon Sep 17 00:00:00 2001 From: Chinsky Date: Fri, 22 Feb 2013 23:24:33 +0400 Subject: [PATCH 4/4] Commented out gangrene for now. I suck at branches, it got caught with my surgery fixes. --- code/datums/organs/organ_external.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/datums/organs/organ_external.dm b/code/datums/organs/organ_external.dm index b8da2f66a4..7710fb6a4f 100644 --- a/code/datums/organs/organ_external.dm +++ b/code/datums/organs/organ_external.dm @@ -264,8 +264,8 @@ //Updating germ levels. Handles organ germ levels and necrosis. #define GANGREN_LEVEL_ONE 100 -#define GANGREN_LEVEL_TWO 105 -#define GANGREN_LEVEL_TERMINAL 110 +#define GANGREN_LEVEL_TWO 1000 +#define GANGREN_LEVEL_TERMINAL 2500 #define GERM_TRANSFER_AMOUNT germ_level/500 /datum/organ/external/proc/update_germs() if(germ_level > 0 && owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs @@ -283,7 +283,7 @@ if(germ_level > GANGREN_LEVEL_TWO) germ_level++ owner.adjustToxLoss(1) - +/* if(germ_level > GANGREN_LEVEL_TERMINAL) if (!(status & ORGAN_DEAD)) status |= ORGAN_DEAD @@ -297,6 +297,7 @@ if (parent) if (!(parent.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT))) parent.germ_level += round(GERM_TRANSFER_AMOUNT) +*/ //Updating wounds. Handles wound natural healing, internal bleedings and infections /datum/organ/external/proc/update_wounds()