From 9ef1216147ab5793060b4ca31fd59d32a4a6f66a Mon Sep 17 00:00:00 2001 From: mwerezak Date: Thu, 19 Jun 2014 18:11:39 -0400 Subject: [PATCH 01/16] Updates l_move_time to use world.time --- code/game/atoms_movable.dm | 4 ++-- code/modules/mob/living/carbon/human/human.dm | 2 +- code/modules/organs/organ.dm | 2 +- code/modules/vehicles/vehicle.dm | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 1326e65e5e..41da5ea7c8 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -15,8 +15,8 @@ /atom/movable/Move() var/atom/A = src.loc . = ..() - src.move_speed = world.timeofday - src.l_move_time - src.l_move_time = world.timeofday + src.move_speed = world.time - src.l_move_time + src.l_move_time = world.time src.m_flag = 1 if ((A != src.loc && A && A.z == src.z)) src.last_move = get_dir(A, src.loc) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 2925449d0e..c25a712ec7 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1220,7 +1220,7 @@ return usr << "Don't move until counting is finished." - var/time = world.timeofday + var/time = world.time sleep(60) if(usr.l_move_time >= time) //checks if our mob has moved during the sleep() usr << "You moved while counting. Try again." diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 47a7f67a07..953676585b 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -74,7 +74,7 @@ //Moving around with fractured ribs won't do you any good if (broken && E.internal_organs && prob(15)) - if (!lying && world.timeofday - l_move_time < 15) + if (!lying && world.time - l_move_time < 15) var/datum/organ/internal/I = pick(E.internal_organs) custom_pain("You feel broken bones moving in your [E.display_name]!", 1) I.take_damage(rand(3,5)) diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index 6ae7f3ee14..0ba37cb562 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -36,7 +36,7 @@ //spawn the cell you want in each vehicle /obj/vehicle/Move() - if(world.timeofday > l_move_time + move_delay) + if(world.time > l_move_time + move_delay) if(on && powered && cell.charge < power_use) turn_off() From d512d62869b0530d737f17df8fc40dd9a1ba2199 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Thu, 19 Jun 2014 21:25:59 -0400 Subject: [PATCH 02/16] Re-enables organ infections, adds wound infection --- code/game/atoms.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 11 ++++++ .../mob/living/carbon/human/examine.dm | 4 +-- code/modules/mob/living/carbon/human/life.dm | 7 ++-- code/modules/organs/organ.dm | 10 ++++-- code/modules/organs/organ_external.dm | 36 +++++++++++-------- code/setup.dm | 10 +++++- 7 files changed, 54 insertions(+), 26 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 351216b8bf..3253f272d0 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -10,7 +10,7 @@ var/last_bumped = 0 var/pass_flags = 0 var/throwpass = 0 - var/germ_level = 0 // The higher the germ level, the more germ on the atom. + var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom. ///Chemistry. var/datum/reagents/reagents = null diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 0e6d130a56..441af0673d 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1,3 +1,10 @@ +/mob/living/carbon/Life() + ..() + + // Increase germ_level regularly + if(germ_level < GERM_LEVEL_AMBIENT) //if you're just standing there, you shouldn't get more germs beyond an ambient level + germ_level++ //increase by 1 per second + /mob/living/carbon/Move(NewLoc, direct) . = ..() if(.) @@ -7,6 +14,10 @@ src.nutrition -= HUNGER_FACTOR/10 if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360) src.bodytemperature += 2 + + // Moving around increases germ_level faster + if(germ_level < GERM_LEVEL_MOVE_CAP && prob(1)) + germ_level++ /mob/living/carbon/relaymove(var/mob/user, direction) if(user in src.stomach_contents) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 9cc0e22dfc..ad2bd377db 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -284,8 +284,8 @@ var/this_wound_desc = W.desc if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]" else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]" - if(W.germ_level > 1000) this_wound_desc = "badly infected [this_wound_desc]" - else if(W.germ_level > 100) this_wound_desc = "lightly infected [this_wound_desc]" + if(W.germ_level > GANGREN_LEVEL_TWO) this_wound_desc = "badly infected [this_wound_desc]" + else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]" if(this_wound_desc in wound_descriptors) wound_descriptors[this_wound_desc] += W.amount continue diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 2640f85819..c7cbbf5965 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1215,14 +1215,11 @@ if(druggy) druggy = max(druggy-1, 0) -/* - // Increase germ_level regularly - if(prob(40)) - germ_level += 1 + // If you're dirty, your gloves will become dirty, too. if(gloves && germ_level > gloves.germ_level && prob(10)) gloves.germ_level += 1 -*/ + return 1 proc/handle_regular_hud_updates() diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 953676585b..13823602b7 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -72,12 +72,18 @@ if(E.status & ORGAN_BROKEN && !(E.status & ORGAN_SPLINTED) ) broken = 1 + if (!lying && world.time - l_move_time < 15) //Moving around with fractured ribs won't do you any good - if (broken && E.internal_organs && prob(15)) - if (!lying && world.time - l_move_time < 15) + if (broken && E.internal_organs && prob(15)) var/datum/organ/internal/I = pick(E.internal_organs) custom_pain("You feel broken bones moving in your [E.display_name]!", 1) I.take_damage(rand(3,5)) + + //Moving makes open wounds get infected much faster + if (E.wounds.len) + for(var/datum/wound/W in E.wounds) + if (W.can_infect()) + W.germ_level += 1 //Special effects for limbs. if(E.name in list("l_hand","l_arm","r_hand","r_arm")) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index acd9efcb65..992bf8ed7f 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -295,7 +295,10 @@ This function completely restores a damaged organ to perfect condition. if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up. last_dam = brute_dam + burn_dam return 1 - last_dam = brute_dam + burn_dam + else + last_dam = brute_dam + burn_dam + if(germ_level > GANGREN_LEVEL_ONE) + return 1 return 0 /datum/organ/external/process() @@ -331,31 +334,34 @@ This function completely restores a damaged organ to perfect condition. return //Updating germ levels. Handles organ germ levels and necrosis. -#define GANGREN_LEVEL_ONE 100 -#define GANGREN_LEVEL_TWO 1000 -#define GANGREN_LEVEL_TERMINAL 2500 -#define GERM_TRANSFER_AMOUNT germ_level/500 +//#define GERM_TRANSFER_AMOUNT germ_level/500 /datum/organ/external/proc/update_germs() - if(status & ORGAN_ROBOT|ORGAN_DESTROYED) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. + if(status & (ORGAN_ROBOT|ORGAN_DESTROYED)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. germ_level = 0 return - if(germ_level > 0 && owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs + if(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) + //Open wounds can become infected + if (owner.germ_level > W.germ_level && W.can_infect()) + W.germ_level++ + + //Infected wounds raise the organ's germ level + 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_TWO) germ_level++ owner.adjustToxLoss(1) + + else if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still + germ_level += 1 + owner.adjustToxLoss(1) + + /* if(germ_level > GANGREN_LEVEL_TERMINAL) if (!(status & ORGAN_DEAD)) diff --git a/code/setup.dm b/code/setup.dm index 3c190f1e2a..9cb3645c79 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -765,4 +765,12 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse //Shuttle moving status #define SHUTTLE_IDLE 0 #define SHUTTLE_WARMUP 1 -#define SHUTTLE_INTRANSIT 2 \ No newline at end of file +#define SHUTTLE_INTRANSIT 2 + +//Germs and infection +//These numbers have been calculated so that an untreated cut will become a serious infection after 50 minutes. +#define GERM_LEVEL_AMBIENT 120 //maximum germ level you can reach by standing still +#define GERM_LEVEL_MOVE_CAP 300 //maximum germ level you can reach by running around +#define GANGREN_LEVEL_ONE 50 +#define GANGREN_LEVEL_TWO 1000 +#define GANGREN_LEVEL_TERMINAL 2500 From 82a85c2bae5bcd6d0c22678b898c92f4e7471999 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Thu, 19 Jun 2014 21:39:56 -0400 Subject: [PATCH 03/16] Tweaks wound infection a bit --- code/modules/mob/living/carbon/carbon.dm | 6 +++--- code/modules/mob/living/carbon/human/examine.dm | 2 +- code/modules/organs/organ_external.dm | 9 +++++---- code/setup.dm | 6 +++--- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 441af0673d..3b35984931 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -2,8 +2,8 @@ ..() // Increase germ_level regularly - if(germ_level < GERM_LEVEL_AMBIENT) //if you're just standing there, you shouldn't get more germs beyond an ambient level - germ_level++ //increase by 1 per second + if(germ_level < GERM_LEVEL_AMBIENT && prob(80)) //if you're just standing there, you shouldn't get more germs beyond an ambient level + germ_level++ /mob/living/carbon/Move(NewLoc, direct) . = ..() @@ -16,7 +16,7 @@ src.bodytemperature += 2 // Moving around increases germ_level faster - if(germ_level < GERM_LEVEL_MOVE_CAP && prob(1)) + if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8)) germ_level++ /mob/living/carbon/relaymove(var/mob/user, direction) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index ad2bd377db..f5ef826bdd 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -284,7 +284,7 @@ var/this_wound_desc = W.desc if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]" else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]" - if(W.germ_level > GANGREN_LEVEL_TWO) this_wound_desc = "badly infected [this_wound_desc]" + if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]" else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]" if(this_wound_desc in wound_descriptors) wound_descriptors[this_wound_desc] += W.amount diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 992bf8ed7f..7a600b5a4d 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -353,13 +353,14 @@ This function completely restores a damaged organ to perfect condition. 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/10))) //aiming for a light infection to become serious after 40 minutes, standing still + germ_level += 1 + if (prob(50)) + owner.adjustToxLoss(1) + if(germ_level > GANGREN_LEVEL_TWO) germ_level++ owner.adjustToxLoss(1) - - else if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still - germ_level += 1 - owner.adjustToxLoss(1) /* diff --git a/code/setup.dm b/code/setup.dm index 9cb3645c79..016aaea9c2 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -769,8 +769,8 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse //Germs and infection //These numbers have been calculated so that an untreated cut will become a serious infection after 50 minutes. -#define GERM_LEVEL_AMBIENT 120 //maximum germ level you can reach by standing still -#define GERM_LEVEL_MOVE_CAP 300 //maximum germ level you can reach by running around -#define GANGREN_LEVEL_ONE 50 +#define GERM_LEVEL_AMBIENT 110 //maximum germ level you can reach by standing still +#define GERM_LEVEL_MOVE_CAP 200 //maximum germ level you can reach by running around +#define GANGREN_LEVEL_ONE 100 #define GANGREN_LEVEL_TWO 1000 #define GANGREN_LEVEL_TERMINAL 2500 From ffbad1ef158395cc2bf853f8bd7176c68e3721cb Mon Sep 17 00:00:00 2001 From: mwerezak Date: Thu, 19 Jun 2014 22:41:32 -0400 Subject: [PATCH 04/16] Spaceacillin cures infected organs --- code/modules/organs/organ_external.dm | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 7a600b5a4d..813f63e8fe 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -297,7 +297,7 @@ This function completely restores a damaged organ to perfect condition. return 1 else last_dam = brute_dam + burn_dam - if(germ_level > GANGREN_LEVEL_ONE) + if(germ_level) return 1 return 0 @@ -353,12 +353,15 @@ This function completely restores a damaged organ to perfect condition. if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels germ_level++ + var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") + if (antibiotics > 5) + if (prob(4*antibiotics)) germ_level-- + if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still germ_level += 1 - if (prob(50)) - owner.adjustToxLoss(1) + owner.adjustToxLoss(1) - if(germ_level > GANGREN_LEVEL_TWO) + if(germ_level > GANGREN_LEVEL_TWO && antibiotics < 30) //overdosing is necessary to stop severe infections germ_level++ owner.adjustToxLoss(1) From 032061522b8f2dbedb1ebeab5c4b434d250656a7 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 20 Jun 2014 13:37:07 -0400 Subject: [PATCH 05/16] Body temperature damage now uses species values --- code/modules/mob/living/carbon/human/life.dm | 27 +++++++++----------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index c7cbbf5965..666b3a9e91 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -677,50 +677,46 @@ if(adjusted_pressure < species.warning_low_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.phoron < MOLES_PHORON_VISIBLE) return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp - //Body temperature is adjusted in two steps. Firstly your body tries to stabilize itself a bit. - if(stat != 2) - stabilize_temperature_from_calories() - - //After then, it reacts to the surrounding atmosphere based on your thermal protection - if(loc_temp < BODYTEMP_COLD_DAMAGE_LIMIT) //Place is colder than we are + //Body temperature adjusts depending on surrounding atmosphere based on your thermal protection + if(loc_temp < species.cold_level_1) //Place is colder than we are var/thermal_protection = get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. if(thermal_protection < 1) var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX) bodytemperature += amt - else if (loc_temp > BODYTEMP_HEAT_DAMAGE_LIMIT) //Place is hotter than we are + else if (loc_temp > species.heat_level_1) //Place is hotter than we are var/thermal_protection = get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. if(thermal_protection < 1) var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) bodytemperature += amt // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. - if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT) + if(bodytemperature > species.heat_level_1) //Body temperature is too hot. fire_alert = max(fire_alert, 1) if(status_flags & GODMODE) return 1 //godmode switch(bodytemperature) - if(360 to 400) + if(species.heat_level_1 to species.heat_level_2) apply_damage(HEAT_DAMAGE_LEVEL_1, BURN, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 2) - if(400 to 1000) + if(species.heat_level_2 to species.heat_level_3) apply_damage(HEAT_DAMAGE_LEVEL_2, BURN, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 2) - if(1000 to INFINITY) + if(species.heat_level_3 to INFINITY) apply_damage(HEAT_DAMAGE_LEVEL_3, BURN, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 2) - else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT) + else if(bodytemperature < species.cold_level_1) fire_alert = max(fire_alert, 1) if(status_flags & GODMODE) return 1 //godmode if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) switch(bodytemperature) - if(200 to 260) + if(species.cold_level_2 to species.cold_level_1) apply_damage(COLD_DAMAGE_LEVEL_1, BURN, used_weapon = "Low Body Temperature") fire_alert = max(fire_alert, 1) - if(120 to 200) + if(species.cold_level_3 to species.cold_level_2) apply_damage(COLD_DAMAGE_LEVEL_2, BURN, used_weapon = "Low Body Temperature") fire_alert = max(fire_alert, 1) - if(-INFINITY to 120) + if(-INFINITY to species.cold_level_3) apply_damage(COLD_DAMAGE_LEVEL_3, BURN, used_weapon = "Low Body Temperature") fire_alert = max(fire_alert, 1) @@ -1091,6 +1087,7 @@ else //ALIVE. LIGHTS ARE ON updatehealth() //TODO if(!in_stasis) + stabilize_temperature_from_calories() //Body temperature adjusts itself handle_organs() //Optimized. handle_blood() From cf5ff7e9922fc9e5f7569ec366833900cea89f2d Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 20 Jun 2014 18:18:02 -0400 Subject: [PATCH 06/16] Body temperature fixes and updates Body temperature regulation is now based on species, and environmental temperature now respects the air density when affecting living/humans. This also fixes some bugs with heat/cold protection handling and improves the way synthetic species body temperatures are handled to be much more logical. IPCs always gain temperature but cool down because of their environment. When the heat transfer to the environment is reduced because of the lack of air, this will cause IPCs to heat up. As well, having an infection will increase your body temperature, and body scanners now detect infections. --- code/game/machinery/adv_med.dm | 8 ++++ code/game/objects/items/devices/scanners.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 45 +++++++++++--------- code/modules/mob/living/carbon/species.dm | 7 +++ code/modules/organs/organ.dm | 5 ++- code/modules/organs/organ_external.dm | 21 +++++---- code/modules/organs/wound.dm | 2 +- code/setup.dm | 8 ++-- 8 files changed, 63 insertions(+), 35 deletions(-) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index c400185a45..c395e3b714 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -293,6 +293,7 @@ var/splint = "" var/internal_bleeding = "" var/lung_ruptured = "" + var/infection = "" for(var/datum/wound/W in e.wounds) if(W.internal) internal_bleeding = "
Internal bleeding" break @@ -308,6 +309,13 @@ robot = "Prosthetic:" if(e.open) open = "Open:" + switch (e.germ_level) + if (150 to 500) + infection = "Infection - Minor:" + if (500 to INFECTION_LEVEL_TWO) + infection = "Infection - Severe:" + if (INFECTION_LEVEL_TWO to INFINITY) + infection = "Infection - Septic:" var/unknown_body = 0 for(var/I in e.implants) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index c0b230b4a7..f62e2dcda7 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -161,7 +161,7 @@ REAGENT SCANNER if(e.status & ORGAN_BROKEN) if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED))) user << "\red Unsecured fracture in subject [limb]. Splinting recommended for transport." - if(e.is_infected()) + if(e.has_infected_wound()) user << "\red Infected wound detected in subject [limb]. Disinfection recommended." for(var/name in H.organs_by_name) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 666b3a9e91..a32724357e 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -674,20 +674,27 @@ else loc_temp = environment.temperature - if(adjusted_pressure < species.warning_low_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.phoron < MOLES_PHORON_VISIBLE) + if(adjusted_pressure < species.warning_high_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - bodytemperature) < 20 && bodytemperature < species.heat_level_1 && bodytemperature > species.cold_level_1 && environment.phoron < MOLES_PHORON_VISIBLE) return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp //Body temperature adjusts depending on surrounding atmosphere based on your thermal protection - if(loc_temp < species.cold_level_1) //Place is colder than we are + var/temp_adj = 0 + if(loc_temp < bodytemperature) //Place is colder than we are var/thermal_protection = get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. if(thermal_protection < 1) - var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX) - bodytemperature += amt - else if (loc_temp > species.heat_level_1) //Place is hotter than we are + temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR) //this will be negative + else if (loc_temp > bodytemperature) //Place is hotter than we are var/thermal_protection = get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. if(thermal_protection < 1) - var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) - bodytemperature += amt + temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR) + + //Use heat transfer as proportional to the gas density. However, we only care about the relative density vs standard 101 kPa/20 C air. Therefore we can use mole ratios + var/relative_density = environment.total_moles() / MOLES_CELLSTANDARD + temp_adj *= relative_density + + if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX + if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX + bodytemperature += temp_adj // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. if(bodytemperature > species.heat_level_1) @@ -738,12 +745,8 @@ bodytemperature += 0.5 * TEMPERATURE_DAMAGE_COEFFICIENT //Synthetics suffer overheating in a vaccuum. ~Z else - - if(species && species.flags & IS_SYNTHETIC) - bodytemperature += 1 * TEMPERATURE_DAMAGE_COEFFICIENT - if( !(COLD_RESISTANCE in mutations)) - adjustBruteLoss( LOW_PRESSURE_DAMAGE ) + apply_damage(LOW_PRESSURE_DAMAGE, BRUTE, used_weapon = "Low Pressure") pressure_alert = -2 else pressure_alert = -1 @@ -770,23 +773,27 @@ temp_change = (temperature - current) return temp_change */ - - proc/stabilize_temperature_from_calories() - var/body_temperature_difference = 310.15 - bodytemperature + + proc/stabilize_body_temperature() + if (species && species.flags & IS_SYNTHETIC) + bodytemperature += species.synth_temp_gain //that CPU/posibrain just keeps putting out heat. + return + + var/body_temperature_difference = species.body_temperature - bodytemperature if (abs(body_temperature_difference) < 0.5) return //fuck this precision switch(bodytemperature) - if(-INFINITY to 260.15) //260.15 is 310.15 - 50, the temperature where you start to feel effects. + if(-INFINITY to species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects. if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up. nutrition -= 2 var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) // log_debug("Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]") bodytemperature += recovery_amt - if(260.15 to 360.15) + if(species.cold_level_1 to species.heat_level_1) var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR // log_debug("Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]") bodytemperature += recovery_amt - if(360.15 to INFINITY) //360.15 is 310.15 + 50, the temperature where you start to feel effects. + if(species.heat_level_1 to INFINITY) //360.15 is 310.15 + 50, the temperature where you start to feel effects. //We totally need a sweat system cause it totally makes sense...~ var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers // log_debug("Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]") @@ -1087,7 +1094,7 @@ else //ALIVE. LIGHTS ARE ON updatehealth() //TODO if(!in_stasis) - stabilize_temperature_from_calories() //Body temperature adjusts itself + stabilize_body_temperature() //Body temperature adjusts itself handle_organs() //Optimized. handle_blood() diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm index 028e93e5bb..8b0550655d 100644 --- a/code/modules/mob/living/carbon/species.dm +++ b/code/modules/mob/living/carbon/species.dm @@ -28,6 +28,9 @@ var/heat_level_1 = 360 // Heat damage level 1 above this point. var/heat_level_2 = 400 // Heat damage level 2 above this point. var/heat_level_3 = 1000 // Heat damage level 2 above this point. + + var/body_temperature = 310.15 //non-IS_SYNTHETIC species will try to stabilize at this temperature. (also affects temperature processing) + var/synth_temp_gain = 0 //IS_SYNTHETIC species will gain this much temperature every second var/darksight = 2 var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure. @@ -279,6 +282,8 @@ heat_level_2 = 3000 heat_level_3 = 4000 + body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not + flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN blood_color = "#004400" @@ -326,6 +331,8 @@ heat_level_1 = 2000 heat_level_2 = 3000 heat_level_3 = 4000 + + synth_temp_gain = 6.7 //round(40 / BODYTEMP_COLD_DIVISOR, 0.1) //this should cause IPCs to stabilize at ~60 C in a 20 C environment. Based on some CPU operating temperatures flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 13823602b7..fb2a8ccfe1 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -5,6 +5,9 @@ var/list/datum/autopsy_data/autopsy_data = list() var/list/trace_chemicals = list() // traces of chemicals in the organ, // links chemical IDs to number of ticks for which they'll stay in the blood + + var/germ_level = 0 // INTERNAL germs inside the organ, this is BAD if it's greater than INFECTION_LEVEL_ONE + proc/process() return 0 @@ -82,7 +85,7 @@ //Moving makes open wounds get infected much faster if (E.wounds.len) for(var/datum/wound/W in E.wounds) - if (W.can_infect()) + if (W.infection_check()) W.germ_level += 1 //Special effects for limbs. diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 813f63e8fe..9c8bed00ab 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -40,8 +40,6 @@ var/obj/item/hidden = null var/list/implants = list() - // INTERNAL germs inside the organ, this is BAD if it's greater 0 - var/germ_level = 0 // how often wounds should be updated, a higher number means less often var/wound_update_accuracy = 1 @@ -345,7 +343,7 @@ This function completely restores a damaged organ to perfect condition. //Syncing germ levels with external wounds for(var/datum/wound/W in wounds) //Open wounds can become infected - if (owner.germ_level > W.germ_level && W.can_infect()) + if (owner.germ_level > W.germ_level && W.infection_check()) W.germ_level++ //Infected wounds raise the organ's germ level @@ -356,12 +354,17 @@ This function completely restores a damaged organ to perfect condition. var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") if (antibiotics > 5) if (prob(4*antibiotics)) germ_level-- + + if(germ_level > INFECTION_LEVEL_ONE) + //having an infection raises your body temperature + var/temperature_increase = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.bodytemperature += temperature_increase - if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still - germ_level += 1 - owner.adjustToxLoss(1) + if(prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still + germ_level += 1 + owner.adjustToxLoss(1) - if(germ_level > GANGREN_LEVEL_TWO && antibiotics < 30) //overdosing is necessary to stop severe infections + if(germ_level > INFECTION_LEVEL_TWO && antibiotics < 30) //overdosing is necessary to stop severe infections germ_level++ owner.adjustToxLoss(1) @@ -691,9 +694,9 @@ This function completely restores a damaged organ to perfect condition. /datum/organ/external/proc/get_damage() //returns total damage return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health? -/datum/organ/external/proc/is_infected() +/datum/organ/external/proc/has_infected_wound() for(var/datum/wound/W in wounds) - if(W.germ_level > 100) + if(W.germ_level > 150) return 1 return 0 diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm index a789248627..e2763d4697 100644 --- a/code/modules/organs/wound.dm +++ b/code/modules/organs/wound.dm @@ -119,7 +119,7 @@ // 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() + proc/infection_check() if (is_treated() && damage < 10) return 0 if (disinfected) diff --git a/code/setup.dm b/code/setup.dm index 016aaea9c2..4a671571ea 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -38,7 +38,7 @@ #define BODYTEMP_AUTORECOVERY_MINIMUM 10 //Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50. #define BODYTEMP_COLD_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster. #define BODYTEMP_HEAT_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster. -#define BODYTEMP_COOLING_MAX 30 //The maximum number of degrees that your body can cool in 1 tick, when in a cold area. +#define BODYTEMP_COOLING_MAX -30 //The maximum number of degrees that your body can cool in 1 tick, when in a cold area. #define BODYTEMP_HEATING_MAX 30 //The maximum number of degrees that your body can heat up in 1 tick, when in a hot area. #define BODYTEMP_HEAT_DAMAGE_LIMIT 360.15 // The limit the human body can take before it starts taking damage from heat. @@ -771,6 +771,6 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse //These numbers have been calculated so that an untreated cut will become a serious infection after 50 minutes. #define GERM_LEVEL_AMBIENT 110 //maximum germ level you can reach by standing still #define GERM_LEVEL_MOVE_CAP 200 //maximum germ level you can reach by running around -#define GANGREN_LEVEL_ONE 100 -#define GANGREN_LEVEL_TWO 1000 -#define GANGREN_LEVEL_TERMINAL 2500 +#define INFECTION_LEVEL_ONE 100 +#define INFECTION_LEVEL_TWO 1000 +#define INFECTION_LEVEL_TERMINAL 2500 From 1b86e3548fbe6c3ad8cd7fa6d124609ee3654ae6 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 20 Jun 2014 21:02:24 -0400 Subject: [PATCH 07/16] Cleans up organ processing --- code/game/machinery/adv_med.dm | 6 +-- code/modules/mob/living/carbon/human/life.dm | 9 ---- code/modules/organs/organ.dm | 42 ++------------- code/modules/organs/organ_external.dm | 56 ++++++++++++++++++-- code/modules/organs/organ_internal.dm | 4 +- 5 files changed, 61 insertions(+), 56 deletions(-) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index c395e3b714..f49d8f76df 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -311,11 +311,11 @@ open = "Open:" switch (e.germ_level) if (150 to 500) - infection = "Infection - Minor:" + infection = "Light Infection:" if (500 to INFECTION_LEVEL_TWO) - infection = "Infection - Severe:" + infection = "Serious Infection:" if (INFECTION_LEVEL_TWO to INFINITY) - infection = "Infection - Septic:" + infection = "Septic:" var/unknown_body = 0 for(var/I in e.implants) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index a32724357e..5ef87cd1e2 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -316,9 +316,6 @@ if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return - var/datum/organ/internal/lungs/L = internal_organs["lungs"] - L.process() - var/datum/gas_mixture/environment = loc.return_air() var/datum/gas_mixture/breath @@ -1077,12 +1074,6 @@ if(!(species.flags & IS_SYNTHETIC)) handle_trace_chems() - var/datum/organ/internal/liver/liver = internal_organs["liver"] - liver.process() - - var/datum/organ/internal/eyes/eyes = internal_organs["eyes"] - eyes.process() - updatehealth() return //TODO: DEFERRED diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index fb2a8ccfe1..50c0a7dedf 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -65,19 +65,10 @@ else E.process() number_wounds += E.number_wounds - //Robotic limb malfunctions - var/malfunction = 0 - if (E.status & ORGAN_ROBOT && prob(E.brute_dam + E.burn_dam)) - malfunction = 1 - - //Broken limbs hurt too - var/broken = 0 - if(E.status & ORGAN_BROKEN && !(E.status & ORGAN_SPLINTED) ) - broken = 1 if (!lying && world.time - l_move_time < 15) //Moving around with fractured ribs won't do you any good - if (broken && E.internal_organs && prob(15)) + if (E.is_broken() && E.internal_organs && prob(15)) var/datum/organ/internal/I = pick(E.internal_organs) custom_pain("You feel broken bones moving in your [E.display_name]!", 1) I.take_damage(rand(3,5)) @@ -88,36 +79,13 @@ if (W.infection_check()) W.germ_level += 1 - //Special effects for limbs. - if(E.name in list("l_hand","l_arm","r_hand","r_arm")) - var/obj/item/c_hand //Getting what's in this hand - var/hand - if(E.name == "l_hand" || E.name == "l_arm") - c_hand = l_hand - hand = "left hand" - if(E.name == "r_hand" || E.name == "r_arm") - c_hand = r_hand - hand = "right hand" - if (c_hand) - - if(broken) - u_equip(c_hand) - var/emote_scream = pick("screams in pain and", "let's out a sharp hiss and", "cries out and") - emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand]!") - if(malfunction) - u_equip(c_hand) - emote("me", 1, "drops what they were holding, their [hand] malfunctioning!") - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src) - spark_system.attach(src) - spark_system.start() - spawn(10) - del(spark_system) - - else if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying) + if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying) if (!E.is_usable() || malfunction || (broken && !(E.status & ORGAN_SPLINTED))) leg_tally-- // let it fail even if just foot&leg + for(var/datum/organ/internal/I in internal_organs) + I.process() + // standing is poor if(leg_tally <= 0 && !paralysis && !(lying || resting) && prob(5)) if(species && species.flags & NO_PAIN) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 9c8bed00ab..711987871a 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -328,6 +328,7 @@ This function completely restores a damaged organ to perfect condition. if(!(status & ORGAN_BROKEN)) perma_injury = 0 + //Infections update_germs() return @@ -352,23 +353,22 @@ This function completely restores a damaged organ to perfect condition. germ_level++ var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - if (antibiotics > 5) + if (germ_level > 0 && antibiotics > 5) if (prob(4*antibiotics)) germ_level-- if(germ_level > INFECTION_LEVEL_ONE) //having an infection raises your body temperature var/temperature_increase = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_TWO, 1) - owner.bodytemperature += temperature_increase + if (owner.bodytemperature < temperature_increase) + owner.bodytemperature++ if(prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still germ_level += 1 owner.adjustToxLoss(1) - + if(germ_level > INFECTION_LEVEL_TWO && antibiotics < 30) //overdosing is necessary to stop severe infections germ_level++ owner.adjustToxLoss(1) - - /* if(germ_level > GANGREN_LEVEL_TERMINAL) if (!(status & ORGAN_DEAD)) @@ -713,6 +713,36 @@ This function completely restores a damaged organ to perfect condition. /datum/organ/external/proc/is_usable() return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD)) +/datum/organ/external/proc/is_broken() + return ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED)) + +/datum/organ/external/proc/is_malfunctioning() + return ((status & ORGAN_ROBOT) && prob(E.brute_dam + E.burn_dam)) + +//for arms and hands +/datum/organ/external/proc/process_grasp(var/obj/item/c_hand, var/hand_name) + if (!c_hand) + return + + if(is_broken()) + owner.u_equip(c_hand) + var/emote_scream = pick("screams in pain and", "lets out a sharp cry and", "cries out and") + owner.emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand_name]!") + if(is_malfunctioning()) + owner.u_equip(c_hand) + owner.emote("me", 1, "drops what they were holding, their [hand_name] malfunctioning!") + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, src) + spark_system.attach(src) + spark_system.start() + spawn(10) + del(spark_system) + +//legs +//returns 1 if this organ can support standing +/datum/organ/external/proc/can_support_standing() + if (!E.is_usable() || malfunction || (broken && !(E.status & ORGAN_SPLINTED))) + /**************************************************** ORGAN DEFINES ****************************************************/ @@ -741,6 +771,10 @@ This function completely restores a damaged organ to perfect condition. max_damage = 50 min_broken_damage = 20 body_part = ARM_LEFT + + process() + ..() + process_grasp(owner.l_hand, "left hand") /datum/organ/external/l_leg name = "l_leg" @@ -758,6 +792,10 @@ This function completely restores a damaged organ to perfect condition. max_damage = 50 min_broken_damage = 20 body_part = ARM_RIGHT + + process() + ..() + process_grasp(owner.r_hand, "right hand") /datum/organ/external/r_leg name = "r_leg" @@ -793,6 +831,10 @@ This function completely restores a damaged organ to perfect condition. max_damage = 30 min_broken_damage = 15 body_part = HAND_RIGHT + + process() + ..() + process_grasp(owner.r_hand, "right hand") /datum/organ/external/l_hand name = "l_hand" @@ -801,6 +843,10 @@ This function completely restores a damaged organ to perfect condition. max_damage = 30 min_broken_damage = 15 body_part = HAND_LEFT + + process() + ..() + process_grasp(owner.l_hand, "left hand") /datum/organ/external/head name = "head" diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index bb1ce19ad2..e5fd53725e 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -10,6 +10,7 @@ var/min_broken_damage = 30 var/parent_organ = "chest" var/robotic = 0 //For being a robot + var/germ_level = 0 /datum/organ/internal/proc/rejuvenate() damage=0 @@ -40,7 +41,6 @@ if (!silent) owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1) - /datum/organ/internal/proc/emp_act(severity) switch(robotic) if(0) @@ -96,7 +96,7 @@ owner.drip(10) if(prob(4)) spawn owner.emote("me", 1, "gasps for air!") - owner.losebreath += 5 + owner.losebreath += 15 /datum/organ/internal/liver name = "liver" From 244b43c657e6e9e53c7c35a965d6252a37c1b01b Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 20 Jun 2014 21:35:05 -0400 Subject: [PATCH 08/16] Infections now spread between organs Infections can now spread between internal and external organs. Also changes the organ_failure random event to cause an infection instead. --- code/game/machinery/adv_med.dm | 23 +++++++----- code/modules/events/organ_failure.dm | 26 ++++++++++---- code/modules/organs/organ.dm | 16 +++++---- code/modules/organs/organ_external.dm | 52 ++++++++++++++------------- code/modules/organs/organ_internal.dm | 29 ++++++++++++++- code/setup.dm | 3 +- 6 files changed, 101 insertions(+), 48 deletions(-) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index f49d8f76df..ec5529c80c 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -293,7 +293,6 @@ var/splint = "" var/internal_bleeding = "" var/lung_ruptured = "" - var/infection = "" for(var/datum/wound/W in e.wounds) if(W.internal) internal_bleeding = "
Internal bleeding" break @@ -310,12 +309,12 @@ if(e.open) open = "Open:" switch (e.germ_level) - if (150 to 500) - infection = "Light Infection:" - if (500 to INFECTION_LEVEL_TWO) - infection = "Serious Infection:" - if (INFECTION_LEVEL_TWO to INFINITY) - infection = "Septic:" + if (INFECTION_LEVEL_ONE + 50 to INFECTION_LEVEL_TWO) + infected = "Mild Infection:" + if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_THREE) + infected = "Acute Infection:" + if (INFECTION_LEVEL_THREE to INFINITY) + infected = "Septic:" var/unknown_body = 0 for(var/I in e.implants) @@ -340,8 +339,16 @@ mech = "Assisted:" if(i.robotic == 2) mech = "Mechanical:" + + var/infection = "None" + switch (i.germ_level) + if (1 to INFECTION_LEVEL_TWO) + infection = "Mild Infection:" + if (INFECTION_LEVEL_TWO to INFINITY) + infection = "Acute Infection:" + dat += "" - dat += "[i.name]N/A[i.damage]None:[mech]" + dat += "[i.name]N/A[i.damage][infection]:[mech]" dat += "" dat += "" if(occupant.sdisabilities & BLIND) diff --git a/code/modules/events/organ_failure.dm b/code/modules/events/organ_failure.dm index 80e7f807dd..f954891b90 100644 --- a/code/modules/events/organ_failure.dm +++ b/code/modules/events/organ_failure.dm @@ -21,9 +21,23 @@ datum/event/organ_failure/start() while(severity > 0 && candidates.len) var/mob/living/carbon/human/C = candidates[1] - // Bruise one of their organs - var/O = pick(C.internal_organs) - var/datum/organ/internal/I = C.internal_organs[O] - I.damage = I.min_bruised_damage - candidates.Remove(C) - severity-- \ No newline at end of file + var/acute = prob(15) + if (prob(75)) + //internal organ infection + var/O = pick(C.internal_organs) + var/datum/organ/internal/I = C.internal_organs[O] + + if (acute) + I.germ_level = max(INFECTION_LEVEL_TWO, I.germ_level) + else + I.germ_level = max(rand(INFECTION_LEVEL_ONE,INFECTION_LEVEL_ONE*2), I.germ_level) + else + //external organ infection + var/datum/organ/external/O = pick(C.organs) + + if (acute) + O.germ_level = max(INFECTION_LEVEL_TWO, O.germ_level) + else + O.germ_level = max(rand(INFECTION_LEVEL_ONE,INFECTION_LEVEL_ONE*2), O.germ_level) + + severity-- diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 50c0a7dedf..b5761df24c 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -49,13 +49,18 @@ if(damage_this_tick > last_dam) force_process = 1 last_dam = damage_this_tick - if(!force_process && !bad_external_organs.len) - return if(force_process) bad_external_organs.Cut() for(var/datum/organ/external/Ex in organs) bad_external_organs += Ex - + + //processing internal organs is pretty cheap, do that first. + for(var/datum/organ/internal/I in internal_organs) + I.process() + + if(!force_process && !bad_external_organs.len) + return + for(var/datum/organ/external/E in bad_external_organs) if(!E) continue @@ -80,11 +85,8 @@ W.germ_level += 1 if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying) - if (!E.is_usable() || malfunction || (broken && !(E.status & ORGAN_SPLINTED))) + if (!E.is_usable() || E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED))) leg_tally-- // let it fail even if just foot&leg - - for(var/datum/organ/internal/I in internal_organs) - I.process() // standing is poor if(leg_tally <= 0 && !paralysis && !(lying || resting) && prob(5)) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 711987871a..9ebfbb8098 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -333,7 +333,6 @@ This function completely restores a damaged organ to perfect condition. return //Updating germ levels. Handles organ germ levels and necrosis. -//#define GERM_TRANSFER_AMOUNT germ_level/500 /datum/organ/external/proc/update_germs() if(status & (ORGAN_ROBOT|ORGAN_DESTROYED)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. @@ -356,34 +355,41 @@ This function completely restores a damaged organ to perfect condition. if (germ_level > 0 && antibiotics > 5) if (prob(4*antibiotics)) germ_level-- - if(germ_level > INFECTION_LEVEL_ONE) + if(germ_level >= INFECTION_LEVEL_ONE) //having an infection raises your body temperature - var/temperature_increase = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_TWO, 1) + var/temperature_increase = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_THREE, 1) if (owner.bodytemperature < temperature_increase) owner.bodytemperature++ if(prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still - germ_level += 1 + germ_level++ owner.adjustToxLoss(1) - if(germ_level > INFECTION_LEVEL_TWO && antibiotics < 30) //overdosing is necessary to stop severe infections - germ_level++ - owner.adjustToxLoss(1) -/* - if(germ_level > GANGREN_LEVEL_TERMINAL) + if(germ_level >= INFECTION_LEVEL_TWO) + //spread the infection + for (var/datum/organ/internal/I in internal_organs) + if (I.germ_level < germ_level) + I.germ_level++ + + if (children) //To child organs + 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)) + child.germ_level++ + + if (parent) + if (parent.germ_level < germ_level && !(parent.status & ORGAN_ROBOT)) + if (parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30)) + parent.germ_level++ + + if(germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) //overdosing is necessary to stop severe infections 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) -*/ + + germ_level++ + owner.adjustToxLoss(1) + //Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections /datum/organ/external/proc/update_wounds() @@ -717,7 +723,7 @@ This function completely restores a damaged organ to perfect condition. return ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED)) /datum/organ/external/proc/is_malfunctioning() - return ((status & ORGAN_ROBOT) && prob(E.brute_dam + E.burn_dam)) + return ((status & ORGAN_ROBOT) && prob(brute_dam + burn_dam)) //for arms and hands /datum/organ/external/proc/process_grasp(var/obj/item/c_hand, var/hand_name) @@ -727,7 +733,7 @@ This function completely restores a damaged organ to perfect condition. if(is_broken()) owner.u_equip(c_hand) var/emote_scream = pick("screams in pain and", "lets out a sharp cry and", "cries out and") - owner.emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand_name]!") + owner.emote("me", 1, "[(owner.species && owner.species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand_name]!") if(is_malfunctioning()) owner.u_equip(c_hand) owner.emote("me", 1, "drops what they were holding, their [hand_name] malfunctioning!") @@ -738,10 +744,6 @@ This function completely restores a damaged organ to perfect condition. spawn(10) del(spark_system) -//legs -//returns 1 if this organ can support standing -/datum/organ/external/proc/can_support_standing() - if (!E.is_usable() || malfunction || (broken && !(E.status & ORGAN_SPLINTED))) /**************************************************** ORGAN DEFINES diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index e5fd53725e..7df2bc90e2 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -10,7 +10,6 @@ var/min_broken_damage = 30 var/parent_organ = "chest" var/robotic = 0 //For being a robot - var/germ_level = 0 /datum/organ/internal/proc/rejuvenate() damage=0 @@ -22,6 +21,7 @@ return damage >= min_broken_damage + /datum/organ/internal/New(mob/living/carbon/human/H) ..() var/datum/organ/external/E = H.organs_by_name[src.parent_organ] @@ -31,6 +31,33 @@ H.internal_organs[src.name] = src src.owner = H +/datum/organ/internal/process() + + //Process infections + if (!germ_level) + return + + var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") + + if (germ_level > 0 && antibiotics > 5) + if (prob(4*antibiotics)) germ_level-- + if (antibiotics > 30) germ_level-- + + if (germ_level >= INFECTION_LEVEL_ONE/2) + if(prob(round(germ_level/6))) //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes + germ_level++ + if(prob(1)) + take_damage(1,silent=0) + + if (germ_level >= INFECTION_LEVEL_TWO) + var/datum/organ/external/parent = owner.get_organ(parent_organ) + if (parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) )) + parent.germ_level++ + + if (prob(5)) //about once every 20 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) diff --git a/code/setup.dm b/code/setup.dm index 4a671571ea..520e83afc1 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -772,5 +772,6 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse #define GERM_LEVEL_AMBIENT 110 //maximum germ level you can reach by standing still #define GERM_LEVEL_MOVE_CAP 200 //maximum germ level you can reach by running around #define INFECTION_LEVEL_ONE 100 -#define INFECTION_LEVEL_TWO 1000 +#define INFECTION_LEVEL_TWO 500 +#define INFECTION_LEVEL_THREE 1000 #define INFECTION_LEVEL_TERMINAL 2500 From 0c060d144b5da0cb1a7addde8675f93374c67ae7 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 21 Jun 2014 11:08:09 -0400 Subject: [PATCH 09/16] IPCs now need to be scanned with a robotanalyzer --- code/game/objects/items/devices/scanners.dm | 10 ++++ .../mob/living/silicon/robot/component.dm | 50 ++++++++++++------- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index f62e2dcda7..ffdd959c55 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -92,6 +92,16 @@ REAGENT SCANNER usr << "\red You don't have the dexterity to do this!" return user.visible_message(" [user] has analyzed [M]'s vitals."," You have analyzed [M]'s vitals.") + + if (!istype(M, /mob/living/carbon) || (ishuman(M) && (M:species.flags & IS_SYNTHETIC))) + //these sensors are designed for organic life + user.show_message("\blue Analyzing Results for ERROR:\n\t Overall Status: ERROR") + user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1) + user.show_message("\t Damage Specifics: -- - -- - -- - --") + user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) //temperature is still temperature, though + user.show_message("\red Warning: Blood Level ERROR: --% --cl.\blue Type: ERROR") + user.show_message("\blue Subject's pulse: -- bpm.") + var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss()))) var/OX = M.getOxyLoss() > 50 ? "[M.getOxyLoss()]" : M.getOxyLoss() var/TX = M.getToxLoss() > 50 ? "[M.getToxLoss()]" : M.getToxLoss() diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index cee310ae59..85574fb390 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -188,7 +188,7 @@ if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") user << "\red You don't have the dexterity to do this!" return - if(!istype(M, /mob/living/silicon/robot)) + if(!istype(M, /mob/living/silicon/robot) && !(ishuman(M) && (M:species.flags & IS_SYNTHETIC))) user << "\red You can't analyze non-robotic things!" return @@ -201,21 +201,37 @@ if(M.tod && M.stat == DEAD) user.show_message("\blue Time of Disable: [M.tod]") - var/mob/living/silicon/robot/H = M - var/list/damaged = H.get_damaged_components(1,1,1) - user.show_message("\blue Localized Damage:",1) - if(length(damaged)>0) - for(var/datum/robot_component/org in damaged) - user.show_message(text("\blue \t []: [][] - [] - [] - []", \ - capitalize(org.name), \ - (org.installed == -1) ? "DESTROYED " :"",\ - (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \ - (org.brute_damage > 0) ? "[org.brute_damage]" :0, \ - (org.toggled) ? "Toggled ON" : "Toggled OFF",\ - (org.powered) ? "Power ON" : "Power OFF"),1) - else - user.show_message("\blue \t Components are OK.",1) - if(H.emagged && prob(5)) - user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1) + if (istype(M, var/mob/living/silicon/robot)) + var/mob/living/silicon/robot/H = M + var/list/damaged = H.get_damaged_components(1,1,1) + user.show_message("\blue Localized Damage:",1) + if(length(damaged)>0) + for(var/datum/robot_component/org in damaged) + user.show_message(text("\blue \t []: [][] - [] - [] - []", \ + capitalize(org.name), \ + (org.installed == -1) ? "DESTROYED " :"",\ + (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \ + (org.brute_damage > 0) ? "[org.brute_damage]" :0, \ + (org.toggled) ? "Toggled ON" : "Toggled OFF",\ + (org.powered) ? "Power ON" : "Power OFF"),1) + else + user.show_message("\blue \t Components are OK.",1) + if(H.emagged && prob(5)) + user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1) + + if (ishuman(M) && (M:species.flags & IS_SYNTHETIC)) + user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) + + var/list/damaged = H.get_damaged_organs(1,1) + user.show_message("\blue Localized Damage, Brute/Electronics:",1) + if(length(damaged)>0) + for(var/datum/organ/external/org in damaged) + user.show_message(text("\blue \t []: [] - []", \ + capitalize(org.display_name), \ + (org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \ + (org.burn_dam > 0) ? "[org.burn_dam]" :0),1) + else + user.show_message("\blue \t Components are OK.",1) + src.add_fingerprint(user) return From b9fa4330873fa154a3807a3fdf75de3ece25210b Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 21 Jun 2014 16:53:18 -0400 Subject: [PATCH 10/16] Adds suit cooling device Also: Breathing in hot/cold air will affect your body temperature. Fixes old body temperature stabilization code not working. Thermometer icon now adjusts based on species. Reduced BODYTEMP_AUTORECOVERY_MINIMUM to a less ridiculous value. --- baystation12.dme | 1 + code/game/gamemodes/cult/cult_items.dm | 2 +- .../objects/items/devices/suit_cooling.dm | 161 ++++++++++++++++++ .../game/objects/items/weapons/tanks/tanks.dm | 1 + code/modules/clothing/clothing.dm | 2 +- code/modules/clothing/spacesuits/ninja.dm | 2 +- code/modules/clothing/spacesuits/rig.dm | 8 +- code/modules/mob/living/carbon/human/life.dm | 158 +++++++++++------ .../xenoarchaeology/tools/anomaly_suit.dm | 2 +- code/setup.dm | 2 +- 10 files changed, 280 insertions(+), 59 deletions(-) create mode 100644 code/game/objects/items/devices/suit_cooling.dm diff --git a/baystation12.dme b/baystation12.dme index 43733732a0..6a75afbf28 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -487,6 +487,7 @@ #include "code\game\objects\items\devices\pipe_painter.dm" #include "code\game\objects\items\devices\powersink.dm" #include "code\game\objects\items\devices\scanners.dm" +#include "code\game\objects\items\devices\suit_cooling.dm" #include "code\game\objects\items\devices\taperecorder.dm" #include "code\game\objects\items\devices\traitordevices.dm" #include "code\game\objects\items\devices\transfer_valve.dm" diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 4e38f4fe44..d55417c5f5 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -98,7 +98,7 @@ item_state = "cult_armour" desc = "A bulky suit of armour, bristling with spikes. It looks space proof." w_class = 3 - allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency_oxygen) + allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit) slowdown = 1 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0 \ No newline at end of file diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm new file mode 100644 index 0000000000..4035ab3c0c --- /dev/null +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -0,0 +1,161 @@ +/obj/item/device/suit_cooling_unit + name = "portable suit cooling unit" + desc = "A portable heat sink and liquid cooled radiator that can be hooked up to a space suit's existing temperature controls to provide industrial levels of cooling." + w_class = 4 + icon = 'icons/obj/power.dmi' //temporary, I hope + icon_state = "portgen0" + slot_flags = SLOT_BACK //you can carry it on your back if you want, but it won't do anything unless attached to suit storage + + var/on = 0 //is it turned on? + var/cover_open = 0 //is the cover open? + var/obj/item/weapon/cell/cell + var/max_cooling = 12 //in degrees per second - probably don't need to mess with heat capacity here + var/charge_consumption = 16.6 //charge per second at max_cooling + var/thermostat = T20C + + //TODO: make it heat up the surroundings when not in space + +/obj/item/device/suit_cooling_unit/proc/cool_mob(mob/M) + if (!on || !cell) return + + //make sure they have a suit and we are attached to it + if (!attached_to_suit(M)) + return + + var/mob/living/carbon/human/H = M + + var/efficiency = H.get_pressure_protection() //you need to have a good seal for effective cooling + var/env_temp = get_environment_temperature() //wont save you from a fire + var/temp_adj = min(H.bodytemperature - max(thermostat, env_temp), max_cooling) + + if (temp_adj < 0) //only cools, doesn't heat + return + + var/charge_usage = (temp_adj/max_cooling)*charge_consumption + + H.bodytemperature -= temp_adj*efficiency + + cell.use(charge_usage) + + if(cell.charge <= 0) + turn_off() + +/obj/item/device/suit_cooling_unit/proc/get_environment_temperature() + if (ishuman(loc)) + var/mob/living/carbon/human/H = loc + if(istype(H.loc, /obj/mecha)) + var/obj/mecha/M = loc + return M.return_temperature() + else if(istype(H.loc, /obj/machinery/atmospherics/unary/cryo_cell)) + return H.loc:air_contents.temperature + + var/turf/T = get_turf(src) + if(istype(T, /turf/space)) + return 0 //space has no temperature, this just makes sure the cooling unit works in space + + var/datum/gas_mixture/environment = T.return_air() + if (!environment) + return 0 + + return environment.temperature + +/obj/item/device/suit_cooling_unit/proc/attached_to_suit(mob/M) + if (!ishuman(M)) + return 0 + + var/mob/living/carbon/human/H = M + + if (!H.wear_suit || H.s_store != src) + return 0 + + return 1 + +/obj/item/device/suit_cooling_unit/proc/turn_on() + if(!cell) + return + if(cell.charge <= 0) + return + + on = 1 + updateicon() + +/obj/item/device/suit_cooling_unit/proc/turn_off() + if (ismob(src.loc)) + src.loc << "\The [src] clicks and whines as it powers down." //let them know + on = 0 + updateicon() + +/obj/item/device/suit_cooling_unit/attack_self(mob/user as mob) + if(cover_open && cell) + if(ishuman(user)) + user.put_in_hands(cell) + else + cell.loc = get_turf(loc) + + cell.add_fingerprint(user) + cell.updateicon() + + user << "You remove the [src.cell]." + src.cell = null + updateicon() + return + + //TODO use a UI like the air tanks + if(on) + turn_off() + else + turn_on() + if (on) + user << "You switch on the [src]." + +/obj/item/device/suit_cooling_unit/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/screwdriver)) + if(cover_open) + cover_open = 0 + user << "You screw the panel into place." + else + cover_open = 1 + user << "You unscrew the panel." + updateicon() + return + + if (istype(W, /obj/item/weapon/cell)) + if(cover_open) + if(cell) + user << "There is a [cell] already installed here." + else + user.drop_item() + W.loc = src + cell = W + user << "You insert the [cell]." + updateicon() + return + + return ..() + +/obj/item/device/suit_cooling_unit/proc/updateicon() + return 0 //TODO + +/obj/item/device/suit_cooling_unit/examine() + set src in view(1) + + ..() + + if (on) + if (attached_to_suit(src.loc)) + usr << "It's switched on and running." + else + usr << "It's switched on, but not attached to anything." + else + usr << "It is switched off." + + if (cover_open) + if(cell) + usr << "The panel is open, exposing the [cell]." + else + usr << "The panel is open." + + if (cell) + usr << "The charge meter reads [round(cell.percent())]%." + else + usr << "It doesn't have a power cell installed." \ No newline at end of file diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 6623c99cb3..8b883f818a 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -6,6 +6,7 @@ icon = 'icons/obj/tank.dmi' flags = FPRINT | TABLEPASS | CONDUCT slot_flags = SLOT_BACK + w_class = 3 pressure_resistance = ONE_ATMOSPHERE*5 diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 84acdb6aca..76e4bb01d2 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -220,7 +220,7 @@ BLIND // can't see anything permeability_coefficient = 0.02 flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit) slowdown = 3 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL diff --git a/code/modules/clothing/spacesuits/ninja.dm b/code/modules/clothing/spacesuits/ninja.dm index c146bb21a5..c51594e0e6 100644 --- a/code/modules/clothing/spacesuits/ninja.dm +++ b/code/modules/clothing/spacesuits/ninja.dm @@ -13,7 +13,7 @@ desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." icon_state = "s-ninja" item_state = "s-ninja_suit" - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/weapon/cell) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell) slowdown = 0 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0.2 diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm index ab3f723674..995e116717 100644 --- a/code/modules/clothing/spacesuits/rig.dm +++ b/code/modules/clothing/spacesuits/rig.dm @@ -55,7 +55,7 @@ item_state = "eng_hardsuit" slowdown = 1 armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80) - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd) heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE @@ -359,7 +359,7 @@ slowdown = 1 w_class = 3 armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60) - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs) siemens_coefficient = 0.6 species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox") @@ -402,7 +402,7 @@ name = "medical hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding." item_state = "medical_hardsuit" - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical) armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50) //Security @@ -421,7 +421,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor." item_state = "sec_hardsuit" armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10) - allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/melee/baton) + allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton) siemens_coefficient = 0.7 diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 5ef87cd1e2..04f49d78ce 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -129,12 +129,10 @@ G.process() -/mob/living/carbon/human/calculate_affecting_pressure(var/pressure) - ..() - var/pressure_difference = abs( pressure - ONE_ATMOSPHERE ) - +//Much like get_heat_protection(), this returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. +/mob/living/carbon/human/proc/get_pressure_protection() var/pressure_adjustment_coefficient = 1 //Determins how much the clothing you are wearing protects you in percent. - + if(head && (head.flags & STOPSPRESSUREDMAGE)) pressure_adjustment_coefficient -= PRESSURE_HEAD_REDUCTION_COEFFICIENT @@ -147,10 +145,16 @@ if(S.can_breach && S.damage) var/pressure_loss = S.damage * 0.1 pressure_adjustment_coefficient += pressure_loss - + pressure_adjustment_coefficient = min(1,max(pressure_adjustment_coefficient,0)) //So it isn't less than 0 or larger than 1. + + return 1 - pressure_adjustment_coefficient //want 0 to be bad protection, 1 to be good protection - pressure_difference = pressure_difference * pressure_adjustment_coefficient +/mob/living/carbon/human/calculate_affecting_pressure(var/pressure) + ..() + var/pressure_difference = abs( pressure - ONE_ATMOSPHERE ) + + pressure_difference = pressure_difference * (1 - get_pressure_protection()) if(pressure > ONE_ATMOSPHERE) return ONE_ATMOSPHERE + pressure_difference @@ -616,14 +620,14 @@ adjustOxyLoss(-5) // Hot air hurts :( - if( (abs(310.15 - breath.temperature) > 50) && !(COLD_RESISTANCE in mutations)) + if( (breath.temperature < species.cold_level_1 || breath.temperature > species.heat_level_1) && !(COLD_RESISTANCE in mutations)) if(status_flags & GODMODE) return 1 if(breath.temperature < species.cold_level_1) if(prob(20)) - src << "\red You feel your face freezing and an icicle forming in your lungs!" + src << "\red You feel your face freezing and icicles forming in your lungs!" else if(breath.temperature > species.heat_level_1) if(prob(20)) src << "\red You feel your face burning and a searing heat in your lungs!" @@ -647,9 +651,21 @@ if(species.heat_level_3 to INFINITY) apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat") fire_alert = max(fire_alert, 2) - - //Temporary fixes to the alerts. - + + //breathing in hot/cold air also heats/cools you a bit + var/temp_adj = breath.temperature - bodytemperature + if (temp_adj < 0) + temp_adj /= (BODYTEMP_COLD_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed + else + temp_adj /= (BODYTEMP_HEAT_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed + + var/relative_density = breath.total_moles() / (MOLES_CELLSTANDARD * BREATH_PERCENTAGE) + temp_adj *= relative_density + + if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX + if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX + //world << "Breath: [breath.temperature], [src]: [bodytemperature], Adjusting: [temp_adj]" + bodytemperature += temp_adj return 1 proc/handle_environment(datum/gas_mixture/environment) @@ -665,7 +681,6 @@ if(istype(loc, /obj/mecha)) var/obj/mecha/M = loc loc_temp = M.return_temperature() - else if(istype(get_turf(src), /turf/space)) else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) loc_temp = loc:air_contents.temperature else @@ -691,6 +706,7 @@ if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX + //world << "Environment: [loc_temp], [src]: [bodytemperature], Adjusting: [temp_adj]" bodytemperature += temp_adj // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. @@ -700,13 +716,17 @@ if(status_flags & GODMODE) return 1 //godmode switch(bodytemperature) if(species.heat_level_1 to species.heat_level_2) - apply_damage(HEAT_DAMAGE_LEVEL_1, BURN, used_weapon = "High Body Temperature") + //I'm thinking it might be better to use adjustFireloss here instead of apply_damage so that damage is spread evenly across organs, instead of being dealt mostly to the chest + //apply_damage(HEAT_DAMAGE_LEVEL_1, BURN, used_weapon = "High Body Temperature") + adjustFireloss(HEAT_DAMAGE_LEVEL_1) fire_alert = max(fire_alert, 2) if(species.heat_level_2 to species.heat_level_3) - apply_damage(HEAT_DAMAGE_LEVEL_2, BURN, used_weapon = "High Body Temperature") + //apply_damage(HEAT_DAMAGE_LEVEL_2, BURN, used_weapon = "High Body Temperature") + adjustFireloss(HEAT_DAMAGE_LEVEL_2) fire_alert = max(fire_alert, 2) if(species.heat_level_3 to INFINITY) - apply_damage(HEAT_DAMAGE_LEVEL_3, BURN, used_weapon = "High Body Temperature") + //apply_damage(HEAT_DAMAGE_LEVEL_3, BURN, used_weapon = "High Body Temperature") + adjustFireloss(HEAT_DAMAGE_LEVEL_3) fire_alert = max(fire_alert, 2) else if(bodytemperature < species.cold_level_1) @@ -715,13 +735,17 @@ if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) switch(bodytemperature) if(species.cold_level_2 to species.cold_level_1) - apply_damage(COLD_DAMAGE_LEVEL_1, BURN, used_weapon = "Low Body Temperature") + //I'm thinking it might be better to use adjustFireloss here instead of apply_damage so that damage is spread evenly across organs, instead of being dealt mostly to the chest + //apply_damage(COLD_DAMAGE_LEVEL_1, BURN, used_weapon = "Low Body Temperature") + adjustFireloss(COLD_DAMAGE_LEVEL_1) fire_alert = max(fire_alert, 1) if(species.cold_level_3 to species.cold_level_2) - apply_damage(COLD_DAMAGE_LEVEL_2, BURN, used_weapon = "Low Body Temperature") + //apply_damage(COLD_DAMAGE_LEVEL_2, BURN, used_weapon = "Low Body Temperature") + adjustFireloss(COLD_DAMAGE_LEVEL_2) fire_alert = max(fire_alert, 1) if(-INFINITY to species.cold_level_3) - apply_damage(COLD_DAMAGE_LEVEL_3, BURN, used_weapon = "Low Body Temperature") + //apply_damage(COLD_DAMAGE_LEVEL_3, BURN, used_weapon = "Low Body Temperature") + adjustFireloss(COLD_DAMAGE_LEVEL_3) fire_alert = max(fire_alert, 1) // Account for massive pressure differences. Done by Polymorph @@ -729,7 +753,7 @@ if(status_flags & GODMODE) return 1 //godmode if(adjusted_pressure >= species.hazard_high_pressure) - adjustBruteLoss( min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) ) + adjustBruteLoss(min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)) pressure_alert = 2 else if(adjusted_pressure >= species.warning_high_pressure) pressure_alert = 1 @@ -737,13 +761,9 @@ pressure_alert = 0 else if(adjusted_pressure >= species.hazard_low_pressure) pressure_alert = -1 - - if(species && species.flags & IS_SYNTHETIC) - bodytemperature += 0.5 * TEMPERATURE_DAMAGE_COEFFICIENT //Synthetics suffer overheating in a vaccuum. ~Z - else if( !(COLD_RESISTANCE in mutations)) - apply_damage(LOW_PRESSURE_DAMAGE, BRUTE, used_weapon = "Low Pressure") + adjustBruteLoss(LOW_PRESSURE_DAMAGE) pressure_alert = -2 else pressure_alert = -1 @@ -772,29 +792,38 @@ */ proc/stabilize_body_temperature() - if (species && species.flags & IS_SYNTHETIC) + //TODO find a better place to put this + if (s_store && istype(s_store, /obj/item/device/suit_cooling_unit)) + var/obj/item/device/suit_cooling_unit/CU = s_store + CU.cool_mob(src) + + if (species.flags & IS_SYNTHETIC) bodytemperature += species.synth_temp_gain //that CPU/posibrain just keeps putting out heat. return var/body_temperature_difference = species.body_temperature - bodytemperature + if (abs(body_temperature_difference) < 0.5) return //fuck this precision - switch(bodytemperature) - if(-INFINITY to species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects. - if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up. - nutrition -= 2 - var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) + + if(bodytemperature < species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects. + if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up. + nutrition -= 2 + var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) + //world << "Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]" // log_debug("Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]") - bodytemperature += recovery_amt - if(species.cold_level_1 to species.heat_level_1) - var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR + bodytemperature += recovery_amt + else if(species.cold_level_1 <= bodytemperature && bodytemperature <= species.heat_level_1) + var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR + //world << "Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]" // log_debug("Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]") - bodytemperature += recovery_amt - if(species.heat_level_1 to INFINITY) //360.15 is 310.15 + 50, the temperature where you start to feel effects. - //We totally need a sweat system cause it totally makes sense...~ - var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers + bodytemperature += recovery_amt + else if(bodytemperature > species.heat_level_1) //360.15 is 310.15 + 50, the temperature where you start to feel effects. + //We totally need a sweat system cause it totally makes sense...~ + var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers + //world << "Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]" // log_debug("Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]") - bodytemperature += recovery_amt + bodytemperature += recovery_amt //This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, UPPER_TORSO, LOWER_TORSO, etc. See setup.dm for the full list) proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to. @@ -1441,17 +1470,46 @@ else fire.icon_state = "fire0" if(bodytemp) - switch(bodytemperature) //310.055 optimal body temp - if(370 to INFINITY) bodytemp.icon_state = "temp4" - if(350 to 370) bodytemp.icon_state = "temp3" - if(335 to 350) bodytemp.icon_state = "temp2" - if(320 to 335) bodytemp.icon_state = "temp1" - if(300 to 320) bodytemp.icon_state = "temp0" - if(295 to 300) bodytemp.icon_state = "temp-1" - if(280 to 295) bodytemp.icon_state = "temp-2" - if(260 to 280) bodytemp.icon_state = "temp-3" - else bodytemp.icon_state = "temp-4" - + if (!species) + switch(bodytemperature) //310.055 optimal body temp + if(370 to INFINITY) bodytemp.icon_state = "temp4" + if(350 to 370) bodytemp.icon_state = "temp3" + if(335 to 350) bodytemp.icon_state = "temp2" + if(320 to 335) bodytemp.icon_state = "temp1" + if(300 to 320) bodytemp.icon_state = "temp0" + if(295 to 300) bodytemp.icon_state = "temp-1" + if(280 to 295) bodytemp.icon_state = "temp-2" + if(260 to 280) bodytemp.icon_state = "temp-3" + else bodytemp.icon_state = "temp-4" + else + var/temp_step + if (bodytemperature >= species.body_temperature) + temp_step = (species.heat_level_1 - species.body_temperature)/4 + + if (bodytemperature >= species.heat_level_1) + bodytemp.icon_state = "temp4" + else if (bodytemperature >= species.body_temperature + temp_step*3) + bodytemp.icon_state = "temp3" + else if (bodytemperature >= species.body_temperature + temp_step*2) + bodytemp.icon_state = "temp2" + else if (bodytemperature >= species.body_temperature + temp_step*1) + bodytemp.icon_state = "temp1" + else + bodytemp.icon_state = "temp0" + + else if (bodytemperature < species.body_temperature) + temp_step = (species.body_temperature - species.cold_level_1)/4 + + if (bodytemperature <= species.cold_level_1) + bodytemp.icon_state = "temp-4" + else if (bodytemperature <= species.body_temperature - temp_step*3) + bodytemp.icon_state = "temp-3" + else if (bodytemperature <= species.body_temperature - temp_step*2) + bodytemp.icon_state = "temp-2" + else if (bodytemperature <= species.body_temperature - temp_step*1) + bodytemp.icon_state = "temp-1" + else + bodytemp.icon_state = "temp0" if(blind) if(blinded) blind.layer = 18 else blind.layer = 0 diff --git a/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm b/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm index 05e6d02d35..67ac1bd867 100644 --- a/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm +++ b/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm @@ -20,7 +20,7 @@ icon_state = "cespace_suit" item_state = "cespace_suit" armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100) - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit) /obj/item/clothing/head/helmet/space/anomaly name = "Excavation hood" diff --git a/code/setup.dm b/code/setup.dm index 520e83afc1..724a42c8bb 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -35,7 +35,7 @@ #define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 //This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount. #define BODYTEMP_AUTORECOVERY_DIVISOR 12 //This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive. -#define BODYTEMP_AUTORECOVERY_MINIMUM 10 //Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50. +#define BODYTEMP_AUTORECOVERY_MINIMUM 1 //Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50. #define BODYTEMP_COLD_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster. #define BODYTEMP_HEAT_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster. #define BODYTEMP_COOLING_MAX -30 //The maximum number of degrees that your body can cool in 1 tick, when in a cold area. From 1a57ed735531f91c5b3707e98b0e49b71769e19b Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 21 Jun 2014 16:55:07 -0400 Subject: [PATCH 11/16] Having an infection raises your body temperature Also the toxin damage taken during INFECTION_LEVEL_ONE is greatly reduced. Fixes robotic internal organs getting infections. Fixes the organ_failure random event. Forgot to set the affected organ as needing processing. --- code/modules/events/organ_failure.dm | 2 ++ code/modules/organs/organ_external.dm | 8 +++++--- code/modules/organs/organ_internal.dm | 10 +++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/code/modules/events/organ_failure.dm b/code/modules/events/organ_failure.dm index f954891b90..1499afcb45 100644 --- a/code/modules/events/organ_failure.dm +++ b/code/modules/events/organ_failure.dm @@ -39,5 +39,7 @@ datum/event/organ_failure/start() O.germ_level = max(INFECTION_LEVEL_TWO, O.germ_level) else O.germ_level = max(rand(INFECTION_LEVEL_ONE,INFECTION_LEVEL_ONE*2), O.germ_level) + + C.bad_external_organs |= O severity-- diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 9ebfbb8098..47450621da 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -357,12 +357,14 @@ This function completely restores a damaged organ to perfect condition. if(germ_level >= INFECTION_LEVEL_ONE) //having an infection raises your body temperature - var/temperature_increase = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_THREE, 1) - if (owner.bodytemperature < temperature_increase) + var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_THREE, 1) + owner.species.body_temperature + if (owner.bodytemperature < fever_temperature) + //world << "fever: [owner.bodytemperature] < [fever_temperature], raising temperature." owner.bodytemperature++ if(prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still - germ_level++ + if (prob(5)) + germ_level++ owner.adjustToxLoss(1) if(germ_level >= INFECTION_LEVEL_TWO) diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index 7df2bc90e2..d5e1b19b6c 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -37,18 +37,22 @@ if (!germ_level) return + if (robotic >= 2) //TODO make robotic internal and external organs separate types of organ instead of a flag + germ_level = 0 + return + var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - + if (germ_level > 0 && antibiotics > 5) if (prob(4*antibiotics)) germ_level-- if (antibiotics > 30) germ_level-- - + if (germ_level >= INFECTION_LEVEL_ONE/2) if(prob(round(germ_level/6))) //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes germ_level++ if(prob(1)) take_damage(1,silent=0) - + if (germ_level >= INFECTION_LEVEL_TWO) var/datum/organ/external/parent = owner.get_organ(parent_organ) if (parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) )) From 95285575738c16135d8fcc9fa7d48ad03f79c0ac Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 21 Jun 2014 16:58:20 -0400 Subject: [PATCH 12/16] IPCs actually take heat damage from temperature now Also fixes the healthanalyzer still not scanning IPCs properly (scanning them when it shouldn't) --- code/game/objects/items/devices/scanners.dm | 5 +++-- code/modules/mob/living/carbon/species.dm | 10 +++++----- code/modules/mob/living/silicon/robot/component.dm | 11 ++++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index ffdd959c55..22caeb2090 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -97,10 +97,11 @@ REAGENT SCANNER //these sensors are designed for organic life user.show_message("\blue Analyzing Results for ERROR:\n\t Overall Status: ERROR") user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1) - user.show_message("\t Damage Specifics: -- - -- - -- - --") - user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) //temperature is still temperature, though + user.show_message("\t Damage Specifics: ? - ? - ? - ?") + user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) user.show_message("\red Warning: Blood Level ERROR: --% --cl.\blue Type: ERROR") user.show_message("\blue Subject's pulse: -- bpm.") + return var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss()))) var/OX = M.getOxyLoss() > 50 ? "[M.getOxyLoss()]" : M.getOxyLoss() diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm index 8b0550655d..b171bfb884 100644 --- a/code/modules/mob/living/carbon/species.dm +++ b/code/modules/mob/living/carbon/species.dm @@ -322,17 +322,17 @@ burn_mod = 1 warning_low_pressure = 50 - hazard_low_pressure = 10 + hazard_low_pressure = 0 cold_level_1 = 50 cold_level_2 = -1 cold_level_3 = -1 - heat_level_1 = 2000 - heat_level_2 = 3000 - heat_level_3 = 4000 + heat_level_1 = 500 //gives them about 25 seconds in space before taking damage + heat_level_2 = 1000 + heat_level_3 = 2000 - synth_temp_gain = 6.7 //round(40 / BODYTEMP_COLD_DIVISOR, 0.1) //this should cause IPCs to stabilize at ~60 C in a 20 C environment. Based on some CPU operating temperatures + synth_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment. flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index 85574fb390..d97d2a5391 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -200,8 +200,8 @@ user.show_message("\t Damage Specifics: [BU] - [BR]") if(M.tod && M.stat == DEAD) user.show_message("\blue Time of Disable: [M.tod]") - - if (istype(M, var/mob/living/silicon/robot)) + + if (istype(M, /mob/living/silicon/robot)) var/mob/living/silicon/robot/H = M var/list/damaged = H.get_damaged_components(1,1,1) user.show_message("\blue Localized Damage:",1) @@ -220,8 +220,7 @@ user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1) if (ishuman(M) && (M:species.flags & IS_SYNTHETIC)) - user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) - + var/mob/living/carbon/human/H = M var/list/damaged = H.get_damaged_organs(1,1) user.show_message("\blue Localized Damage, Brute/Electronics:",1) if(length(damaged)>0) @@ -232,6 +231,8 @@ (org.burn_dam > 0) ? "[org.burn_dam]" :0),1) else user.show_message("\blue \t Components are OK.",1) - + + user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) + src.add_fingerprint(user) return From 7500275c41b87821a67cc9afc311af5d8c2d27af Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 21 Jun 2014 17:07:38 -0400 Subject: [PATCH 13/16] Fixes bad capitalization in proc call --- code/modules/mob/living/carbon/human/life.dm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 04f49d78ce..73f7988703 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -716,17 +716,17 @@ if(status_flags & GODMODE) return 1 //godmode switch(bodytemperature) if(species.heat_level_1 to species.heat_level_2) - //I'm thinking it might be better to use adjustFireloss here instead of apply_damage so that damage is spread evenly across organs, instead of being dealt mostly to the chest + //I'm thinking it might be better to use adjustFireLoss here instead of apply_damage so that damage is spread evenly across organs, instead of being dealt mostly to the chest //apply_damage(HEAT_DAMAGE_LEVEL_1, BURN, used_weapon = "High Body Temperature") - adjustFireloss(HEAT_DAMAGE_LEVEL_1) + adjustFireLoss(HEAT_DAMAGE_LEVEL_1) fire_alert = max(fire_alert, 2) if(species.heat_level_2 to species.heat_level_3) //apply_damage(HEAT_DAMAGE_LEVEL_2, BURN, used_weapon = "High Body Temperature") - adjustFireloss(HEAT_DAMAGE_LEVEL_2) + adjustFireLoss(HEAT_DAMAGE_LEVEL_2) fire_alert = max(fire_alert, 2) if(species.heat_level_3 to INFINITY) //apply_damage(HEAT_DAMAGE_LEVEL_3, BURN, used_weapon = "High Body Temperature") - adjustFireloss(HEAT_DAMAGE_LEVEL_3) + adjustFireLoss(HEAT_DAMAGE_LEVEL_3) fire_alert = max(fire_alert, 2) else if(bodytemperature < species.cold_level_1) @@ -735,17 +735,17 @@ if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) switch(bodytemperature) if(species.cold_level_2 to species.cold_level_1) - //I'm thinking it might be better to use adjustFireloss here instead of apply_damage so that damage is spread evenly across organs, instead of being dealt mostly to the chest + //I'm thinking it might be better to use adjustFireLoss here instead of apply_damage so that damage is spread evenly across organs, instead of being dealt mostly to the chest //apply_damage(COLD_DAMAGE_LEVEL_1, BURN, used_weapon = "Low Body Temperature") - adjustFireloss(COLD_DAMAGE_LEVEL_1) + adjustFireLoss(COLD_DAMAGE_LEVEL_1) fire_alert = max(fire_alert, 1) if(species.cold_level_3 to species.cold_level_2) //apply_damage(COLD_DAMAGE_LEVEL_2, BURN, used_weapon = "Low Body Temperature") - adjustFireloss(COLD_DAMAGE_LEVEL_2) + adjustFireLoss(COLD_DAMAGE_LEVEL_2) fire_alert = max(fire_alert, 1) if(-INFINITY to species.cold_level_3) //apply_damage(COLD_DAMAGE_LEVEL_3, BURN, used_weapon = "Low Body Temperature") - adjustFireloss(COLD_DAMAGE_LEVEL_3) + adjustFireLoss(COLD_DAMAGE_LEVEL_3) fire_alert = max(fire_alert, 1) // Account for massive pressure differences. Done by Polymorph From c5d14da6027dff91894a3f1646e5a74ac045f12b Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 21 Jun 2014 20:38:50 -0400 Subject: [PATCH 14/16] Fixes pressure and temperature damage for autopsies --- code/modules/mob/living/carbon/human/life.dm | 25 +++++++------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 73f7988703..3654b2d5f2 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -716,17 +716,13 @@ if(status_flags & GODMODE) return 1 //godmode switch(bodytemperature) if(species.heat_level_1 to species.heat_level_2) - //I'm thinking it might be better to use adjustFireLoss here instead of apply_damage so that damage is spread evenly across organs, instead of being dealt mostly to the chest - //apply_damage(HEAT_DAMAGE_LEVEL_1, BURN, used_weapon = "High Body Temperature") - adjustFireLoss(HEAT_DAMAGE_LEVEL_1) + take_overall_damage(burn=HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 2) if(species.heat_level_2 to species.heat_level_3) - //apply_damage(HEAT_DAMAGE_LEVEL_2, BURN, used_weapon = "High Body Temperature") - adjustFireLoss(HEAT_DAMAGE_LEVEL_2) + take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 2) if(species.heat_level_3 to INFINITY) - //apply_damage(HEAT_DAMAGE_LEVEL_3, BURN, used_weapon = "High Body Temperature") - adjustFireLoss(HEAT_DAMAGE_LEVEL_3) + take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 2) else if(bodytemperature < species.cold_level_1) @@ -735,17 +731,13 @@ if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) switch(bodytemperature) if(species.cold_level_2 to species.cold_level_1) - //I'm thinking it might be better to use adjustFireLoss here instead of apply_damage so that damage is spread evenly across organs, instead of being dealt mostly to the chest - //apply_damage(COLD_DAMAGE_LEVEL_1, BURN, used_weapon = "Low Body Temperature") - adjustFireLoss(COLD_DAMAGE_LEVEL_1) + take_overall_damage(burn=COLD_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 1) if(species.cold_level_3 to species.cold_level_2) - //apply_damage(COLD_DAMAGE_LEVEL_2, BURN, used_weapon = "Low Body Temperature") - adjustFireLoss(COLD_DAMAGE_LEVEL_2) + take_overall_damage(burn=COLD_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 1) if(-INFINITY to species.cold_level_3) - //apply_damage(COLD_DAMAGE_LEVEL_3, BURN, used_weapon = "Low Body Temperature") - adjustFireLoss(COLD_DAMAGE_LEVEL_3) + take_overall_damage(burn=COLD_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 1) // Account for massive pressure differences. Done by Polymorph @@ -753,7 +745,8 @@ if(status_flags & GODMODE) return 1 //godmode if(adjusted_pressure >= species.hazard_high_pressure) - adjustBruteLoss(min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)) + var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) + take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure") pressure_alert = 2 else if(adjusted_pressure >= species.warning_high_pressure) pressure_alert = 1 @@ -763,7 +756,7 @@ pressure_alert = -1 else if( !(COLD_RESISTANCE in mutations)) - adjustBruteLoss(LOW_PRESSURE_DAMAGE) + take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure") pressure_alert = -2 else pressure_alert = -1 From 5bd975850a80a31c9aff137bf6dcc479404aa0d8 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 21 Jun 2014 20:41:29 -0400 Subject: [PATCH 15/16] Less terrible sprite for suit cooling device Also adds a few of them to EVA storage. --- .../objects/items/devices/suit_cooling.dm | 16 +++++++++++++--- icons/obj/device.dmi | Bin 21408 -> 22389 bytes maps/tgstation2.dmm | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index 4035ab3c0c..2fcf545d9b 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -2,8 +2,8 @@ name = "portable suit cooling unit" desc = "A portable heat sink and liquid cooled radiator that can be hooked up to a space suit's existing temperature controls to provide industrial levels of cooling." w_class = 4 - icon = 'icons/obj/power.dmi' //temporary, I hope - icon_state = "portgen0" + icon = 'icons/obj/device.dmi' //temporary, I hope + icon_state = "suitcooler0" slot_flags = SLOT_BACK //you can carry it on your back if you want, but it won't do anything unless attached to suit storage var/on = 0 //is it turned on? @@ -15,6 +15,10 @@ //TODO: make it heat up the surroundings when not in space +/obj/item/device/suit_cooling_unit/New() + cell = new/obj/item/weapon/cell() //comes with the crappy default power cell - high-capacity ones shouldn't be hard to find + cell.loc = src + /obj/item/device/suit_cooling_unit/proc/cool_mob(mob/M) if (!on || !cell) return @@ -134,7 +138,13 @@ return ..() /obj/item/device/suit_cooling_unit/proc/updateicon() - return 0 //TODO + if (cover_open) + if (cell) + icon_state = "suitcooler1" + else + icon_state = "suitcooler2" + else + icon_state = "suitcooler0" /obj/item/device/suit_cooling_unit/examine() set src in view(1) diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 54ea7f9f4cb645d195137648b5e3049bc3518f6d..bf2b6c4d5bf4d60bc714c113cb1a921e9e1298d5 100644 GIT binary patch literal 22389 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 KZ&_hZi2Dx@B1*CV diff --git a/maps/tgstation2.dmm b/maps/tgstation2.dmm index 89d11b60da..b293a3e7cc 100644 --- a/maps/tgstation2.dmm +++ b/maps/tgstation2.dmm @@ -1626,7 +1626,7 @@ "aFn" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/table/reinforced,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cable_coil{pixel_x = 3; pixel_y = -7},/obj/item/weapon/cable_coil{pixel_x = 3; pixel_y = -7},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/ai_monitored/storage/eva) "aFo" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "aFp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/oxygen,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating,/area/storage/emergency2) -"aFq" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/device/modkit/tajaran,/obj/item/device/modkit/tajaran,/obj/item/device/modkit/tajaran,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/ai_monitored/storage/eva) +"aFq" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/device/modkit/tajaran,/obj/item/device/modkit/tajaran,/obj/item/device/modkit/tajaran,/obj/item/device/suit_cooling_unit,/obj/item/device/suit_cooling_unit,/obj/item/device/suit_cooling_unit,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/ai_monitored/storage/eva) "aFr" = (/obj/machinery/light_switch{pixel_y = 28},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; icon_state = "off"; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/wood,/area/bridge/meeting_room) "aFs" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor,/area/hallway/primary/fore) "aFt" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/fore) From 5305de5ecb2d17bc4bb770fe3f2805827eec86ba Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 22 Jun 2014 09:51:38 -0400 Subject: [PATCH 16/16] Fixed misplaced prob(), added notes --- code/modules/organs/organ_external.dm | 29 ++++++++++++++++++++++----- code/setup.dm | 3 +-- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 47450621da..903e370b6b 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -333,6 +333,25 @@ This function completely restores a damaged organ to perfect condition. return //Updating germ levels. Handles organ germ levels and necrosis. +/* +The INFECTION_LEVEL values defined in setup.dm control the time it takes to reach the different +infection levels. Since infection growth is exponential, you can adjust the time it takes to get +from one germ_level to another using the rough formula: + +desired_germ_level = initial_germ_level*e^(desired_time_in_seconds/1000) + +So if I wanted it to take an average of 15 minutes to get from level one (100) to level two +I would set INFECTION_LEVEL_TWO to 100*e^(15*60/1000) = 245. Note that this is the average time, +the actual time is dependent on RNG. + +INFECTION_LEVEL_ONE below this germ level nothing happens, and the infection doesn't grow +INFECTION_LEVEL_TWO above this germ level the infection will start to spread to internal and adjacent organs +INFECTION_LEVEL_THREE above this germ level the player will take additional toxin damage per second, and will die in minutes without + antitox. also, above this germ level you will need to overdose on spaceacillin to reduce the germ_level. + +Note that amputating the affected organ does in fact remove the infection from the +player's body, though, antitox and spaceacillin are easy enough to get I doubt it will ever be needed. +*/ /datum/organ/external/proc/update_germs() if(status & (ORGAN_ROBOT|ORGAN_DESTROYED)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. @@ -353,7 +372,7 @@ This function completely restores a damaged organ to perfect condition. var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") if (germ_level > 0 && antibiotics > 5) - if (prob(4*antibiotics)) germ_level-- + if (prob(4*antibiotics)) germ_level-- //the higher the germ level the more antibiotics you'll need. if(germ_level >= INFECTION_LEVEL_ONE) //having an infection raises your body temperature @@ -362,10 +381,10 @@ This function completely restores a damaged organ to perfect condition. //world << "fever: [owner.bodytemperature] < [fever_temperature], raising temperature." owner.bodytemperature++ - if(prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still - if (prob(5)) - germ_level++ - owner.adjustToxLoss(1) + if(prob(round(germ_level/10))) + germ_level++ + if (prob(5)) //adjust this to tweak how fast people take toxin damage from infections + owner.adjustToxLoss(1) if(germ_level >= INFECTION_LEVEL_TWO) //spread the infection diff --git a/code/setup.dm b/code/setup.dm index 724a42c8bb..a444f3a2fb 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -768,10 +768,9 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse #define SHUTTLE_INTRANSIT 2 //Germs and infection -//These numbers have been calculated so that an untreated cut will become a serious infection after 50 minutes. #define GERM_LEVEL_AMBIENT 110 //maximum germ level you can reach by standing still #define GERM_LEVEL_MOVE_CAP 200 //maximum germ level you can reach by running around + #define INFECTION_LEVEL_ONE 100 #define INFECTION_LEVEL_TWO 500 #define INFECTION_LEVEL_THREE 1000 -#define INFECTION_LEVEL_TERMINAL 2500