diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index c53bd3f99be..eeca2089ee8 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -157,7 +157,10 @@ var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) if(affecting.open == 0) - if(!affecting.bandage()) + var/bandaged = affecting.bandage() + var/disinfected = affecting.disinfect() + + if(!(bandaged || disinfected)) user << "\red The wounds on [M]'s [affecting.display_name] have already been treated." return 1 else @@ -174,7 +177,8 @@ else user.visible_message( "\blue [user] smears some bioglue over [W.desc] on [M]'s [affecting.display_name].", \ "\blue You smear some bioglue over [W.desc] on [M]'s [affecting.display_name]." ) - affecting.heal_damage(heal_brute,0) + if (bandaged) + affecting.heal_damage(heal_brute,0) use(1) else if (can_operate(H)) //Checks if mob is lying down on table for surgery diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 5bb5f53067b..f75f9e055dd 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -18,16 +18,10 @@ return icon('icons/mob/human.dmi',"blank") //Germs -/datum/organ/proc/get_cure_threshold() - //before reaching level three, the amount of spaceacillin required to cure infections scales between 5 and 30 units - //var/germ_scale = max((germ_level - INFECTION_LEVEL_ONE)/(INFECTION_LEVEL_THREE - INFECTION_LEVEL_ONE), 0) - //return min(5 + germ_scale*25, 30) - return 5 //Based on Hubble's suggestion - /datum/organ/proc/handle_antibiotics() var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - if (antibiotics <= get_cure_threshold()) + if (antibiotics < 5) return if (germ_level < INFECTION_LEVEL_ONE) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 3c999fc870c..5cf4d013022 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -377,13 +377,18 @@ Note that amputating the affected organ does in fact remove the infection from t if (owner.germ_level > W.germ_level && W.infection_check()) W.germ_level++ - //Infected wounds raise the organ's germ level - if (W.germ_level > germ_level && antibiotics < 5) //Badly infected wounds raise internal germ levels - 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 /datum/organ/external/proc/handle_germ_effects() var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - var/cure_threshold = get_cure_threshold() + + if (germ_level < INFECTION_LEVEL_ONE && prob(60)) //this could be an else clause, but it looks cleaner this way + germ_level-- //since germ_level increases at a rate of 1 per second with dirty wounds, prob(60) should give us about 5 minutes before level one. if(germ_level >= INFECTION_LEVEL_ONE) //having an infection raises your body temperature @@ -393,19 +398,34 @@ Note that amputating the affected organ does in fact remove the infection from t owner.bodytemperature++ if(prob(round(germ_level/10))) - if (antibiotics < cure_threshold) + if (antibiotics < 5) germ_level++ - if (prob(3)) //adjust this to tweak how fast people take toxin damage from infections + if (prob(5)) //adjust this to tweak how fast people take toxin damage from infections owner.adjustToxLoss(1) - if(germ_level >= INFECTION_LEVEL_TWO && antibiotics < cure_threshold) - //spread the infection + if(germ_level >= INFECTION_LEVEL_TWO && antibiotics < 5) + //spread the infection to internal organs + var/datum/organ/internal/target_organ = null //make internal organs become infected one at a time instead of all at once for (var/datum/organ/internal/I in internal_organs) - if (I.germ_level < germ_level) - I.germ_level++ + if (I.germ_level > 0 && I.germ_level < min(germ_level, INFECTION_LEVEL_TWO)) //once the organ reaches whatever we can give it, or level two, switch to a different one + if (!target_organ || I.germ_level > target_organ.germ_level) //choose the organ with the highest germ_level + target_organ = I + + if (!target_organ) + //figure out which organs we can spread germs to and pick one at random + var/list/candidate_organs = list() + for (var/datum/organ/internal/I in internal_organs) + if (I.germ_level < germ_level) + candidate_organs += I + if (candidate_organs.len) + target_organ = pick(candidate_organs) + + if (target_organ) + target_organ.germ_level++ - if (children) //To child organs + //spread the infection to child and parent organs + if (children) for (var/datum/organ/external/child in children) if (child.germ_level < germ_level && !(child.status & ORGAN_ROBOT)) if (child.germ_level < INFECTION_LEVEL_ONE*2 || prob(30)) @@ -438,7 +458,7 @@ Note that amputating the affected organ does in fact remove the infection from t // let the GC handle the deletion of the wound // Internal wounds get worse over time. Low temperatures (cryo) stop them. - if(W.internal && !W.is_treated() && owner.bodytemperature >= 170) + if(W.internal && !W.can_autoheal() && owner.bodytemperature >= 170) var/bicardose = owner.reagents.get_reagent_amount("bicaridine") var/inaprovaline = owner.reagents.get_reagent_amount("inaprovaline") if(!bicardose || !inaprovaline) //bicaridine and inaprovaline stop internal wounds from growing bigger with time, and also stop bleeding @@ -455,7 +475,7 @@ Note that amputating the affected organ does in fact remove the infection from t 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.is_treated() && W.wound_damage() < 50) + 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 @@ -470,8 +490,8 @@ Note that amputating the affected organ does in fact remove the infection from t // Salving also helps against infection if(W.germ_level > 0 && W.salved && prob(2)) - W.germ_level = 0 W.disinfected = 1 + W.germ_level = 0 // sync the organ's damage with its wounds src.update_damages() @@ -674,6 +694,15 @@ Note that amputating the affected organ does in fact remove the infection from t W.bandaged = 1 return rval +/datum/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 + /datum/organ/external/proc/clamp() var/rval = 0 src.status &= ~ORGAN_BLEEDING diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index 4753d7dc8f6..3721633dce7 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -32,7 +32,6 @@ src.owner = H /datum/organ/internal/process() - //Process infections if (!germ_level) return @@ -48,23 +47,23 @@ //** Handle the effects of infections var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") + if (germ_level < INFECTION_LEVEL_ONE/2 && prob(30)) + germ_level-- + if (germ_level >= INFECTION_LEVEL_ONE/2) //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes if(antibiotics < 5 && prob(round(germ_level/6))) germ_level++ - if(prob(1)) - take_damage(1,silent=prob(60)) if (germ_level >= INFECTION_LEVEL_TWO) var/datum/organ/external/parent = owner.get_organ(parent_organ) //spread germs - if (antibiotics < get_cure_threshold() && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) )) + if (antibiotics < 5 && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) )) parent.germ_level++ if (prob(3)) //about once every 30 seconds take_damage(1,silent=prob(30)) - /datum/organ/internal/proc/take_damage(amount, var/silent=0) if(src.robotic == 2) src.damage += (amount * 0.8) @@ -124,6 +123,11 @@ parent_organ = "chest" process() + ..() + if (germ_level > INFECTION_LEVEL_ONE) + if(prob(5)) + owner.emote("cough") //respitory tract infection + if(is_bruised()) if(prob(2)) spawn owner.emote("me", 1, "coughs up blood!") @@ -138,6 +142,14 @@ var/process_accuracy = 10 process() + ..() + if (germ_level > INFECTION_LEVEL_ONE) + if(prob(1)) + owner << "\red Your skin itches." + if (germ_level > INFECTION_LEVEL_TWO) + if(prob(1)) + spawn owner.vomit() + if(owner.life_tick % process_accuracy == 0) if(src.damage < 0) src.damage = 0 @@ -180,6 +192,7 @@ parent_organ = "head" process() //Eye damage replaces the old eye_stat var. + ..() if(is_bruised()) owner.eye_blurry = 20 if(is_broken()) diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm index 3f4073d3f1a..d20fc0dbfb4 100644 --- a/code/modules/organs/wound.dm +++ b/code/modules/organs/wound.dm @@ -85,24 +85,25 @@ proc/wound_damage() return src.damage / src.amount - // checks whether the wound has been appropriately treated - // always returns 1 for wounds that are too minor to need treatment - proc/is_treated() + 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.is_treated()) != !(src.is_treated())) 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 @@ -120,20 +121,28 @@ // 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 (is_treated() && damage < 10) + 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) && bleeding() //bruises only infectable if bleeding + 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 diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 7f352221f1a..2bb33f891ad 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -842,6 +842,18 @@ datum description = "Sterilizes wounds in preparation for surgery." reagent_state = LIQUID color = "#C8A5DC" // rgb: 200, 165, 220 + + //makes you squeaky clean + reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) + if (method == TOUCH) + M.germ_level -= min(volume*20, M.germ_level) + + reaction_obj(var/obj/O, var/volume) + O.germ_level -= min(volume*20, O.germ_level) + + reaction_turf(var/turf/T, var/volume) + T.germ_level -= min(volume*20, T.germ_level) + /* reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) src = null if (method==TOUCH) diff --git a/code/setup.dm b/code/setup.dm index 7e55158a213..a86e0665765 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -774,7 +774,7 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse #define INFECTION_LEVEL_ONE 100 #define INFECTION_LEVEL_TWO 500 -#define INFECTION_LEVEL_THREE 1500 +#define INFECTION_LEVEL_THREE 1000 /*