Merge pull request #5308 from mwerezak/wound-infections

Re-enables infections, implements a wound infection system, improves body temperatures
This commit is contained in:
Chinsky
2014-06-22 22:04:25 +04:00
27 changed files with 612 additions and 219 deletions
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+4 -4
View File
@@ -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
+22 -6
View File
@@ -21,9 +21,25 @@ 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--
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)
C.bad_external_organs |= O
severity--
+11
View File
@@ -1,3 +1,10 @@
/mob/living/carbon/Life()
..()
// Increase germ_level regularly
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)
. = ..()
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(8))
germ_level++
/mob/living/carbon/relaymove(var/mob/user, direction)
if(user in src.stomach_contents)
@@ -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 > 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
continue
@@ -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."
+133 -90
View File
@@ -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
@@ -316,9 +320,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
@@ -619,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!"
@@ -650,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)
@@ -668,60 +681,63 @@
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
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 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
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 > BODYTEMP_HEAT_DAMAGE_LIMIT) //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
//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.
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)
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN, used_weapon = "High Body Temperature")
if(species.heat_level_1 to species.heat_level_2)
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
if(400 to 1000)
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN, used_weapon = "High Body Temperature")
if(species.heat_level_2 to species.heat_level_3)
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
if(1000 to INFINITY)
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN, used_weapon = "High Body Temperature")
if(species.heat_level_3 to INFINITY)
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, 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)
apply_damage(COLD_DAMAGE_LEVEL_1, BURN, used_weapon = "Low Body Temperature")
if(species.cold_level_2 to species.cold_level_1)
take_overall_damage(burn=COLD_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1)
if(120 to 200)
apply_damage(COLD_DAMAGE_LEVEL_2, BURN, used_weapon = "Low Body Temperature")
if(species.cold_level_3 to species.cold_level_2)
take_overall_damage(burn=COLD_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1)
if(-INFINITY to 120)
apply_damage(COLD_DAMAGE_LEVEL_3, BURN, used_weapon = "Low Body Temperature")
if(-INFINITY to species.cold_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
@@ -729,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
@@ -737,17 +754,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(species && species.flags & IS_SYNTHETIC)
bodytemperature += 1 * TEMPERATURE_DAMAGE_COEFFICIENT
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
@@ -774,27 +783,40 @@
temp_change = (temperature - current)
return temp_change
*/
proc/stabilize_temperature_from_calories()
var/body_temperature_difference = 310.15 - bodytemperature
proc/stabilize_body_temperature()
//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 260.15) //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(260.15 to 360.15)
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(360.15 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.
@@ -1074,12 +1096,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
@@ -1091,6 +1107,7 @@
else //ALIVE. LIGHTS ARE ON
updatehealth() //TODO
if(!in_stasis)
stabilize_body_temperature() //Body temperature adjusts itself
handle_organs() //Optimized.
handle_blood()
@@ -1215,14 +1232,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()
@@ -1449,17 +1463,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
+11 -4
View File
@@ -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"
@@ -317,15 +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 = 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
@@ -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
@@ -200,22 +200,39 @@
user.show_message("\t Damage Specifics: <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
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) ? "<font color='red'><b>DESTROYED</b></font> " :"",\
(org.electronics_damage > 0) ? "<font color='#FFA500'>[org.electronics_damage]</font>" :0, \
(org.brute_damage > 0) ? "<font color='red'>[org.brute_damage]</font>" :0, \
(org.toggled) ? "Toggled ON" : "<font color='red'>Toggled OFF</font>",\
(org.powered) ? "Power ON" : "<font color='red'>Power OFF</font>"),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, /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) ? "<font color='red'><b>DESTROYED</b></font> " :"",\
(org.electronics_damage > 0) ? "<font color='#FFA500'>[org.electronics_damage]</font>" :0, \
(org.brute_damage > 0) ? "<font color='red'>[org.brute_damage]</font>" :0, \
(org.toggled) ? "Toggled ON" : "<font color='red'>Toggled OFF</font>",\
(org.powered) ? "Power ON" : "<font color='red'>Power OFF</font>"),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))
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)
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) ? "<font color='#FFA500'>[org.burn_dam]</font>" :0),1)
else
user.show_message("\blue \t Components are OK.",1)
user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]&deg;C ([M.bodytemperature*1.8-459.67]&deg;F)", 1)
src.add_fingerprint(user)
return
+22 -43
View File
@@ -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
@@ -46,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
@@ -62,53 +70,24 @@
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 (!lying && world.timeofday - l_move_time < 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))
//Moving makes open wounds get infected much faster
if (E.wounds.len)
for(var/datum/wound/W in E.wounds)
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.is_usable() || malfunction || (broken && !(E.status & ORGAN_SPLINTED)))
if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
if (!E.is_usable() || E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)))
leg_tally-- // let it fail even if just foot&leg
// standing is poor
if(leg_tally <= 0 && !paralysis && !(lying || resting) && prob(5))
if(species && species.flags & NO_PAIN)
+116 -34
View File
@@ -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
@@ -298,7 +296,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)
return 1
return 0
/datum/organ/external/process()
@@ -330,50 +331,89 @@ This function completely restores a damaged organ to perfect condition.
if(!(status & ORGAN_BROKEN))
perma_injury = 0
//Infections
update_germs()
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
/*
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.
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++
//Open wounds can become infected
if (owner.germ_level > W.germ_level && W.infection_check())
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_ONE && prob(round(germ_level/100)))
germ_level++
owner.adjustToxLoss(1)
if(germ_level > GANGREN_LEVEL_TWO)
germ_level++
owner.adjustToxLoss(1)
/*
if(germ_level > GANGREN_LEVEL_TERMINAL)
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
if (germ_level > 0 && antibiotics > 5)
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
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)))
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
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 << "<span class='notice'>You can't feel your [display_name] anymore...</span>"
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()
@@ -684,9 +724,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
@@ -703,6 +743,32 @@ 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(brute_dam + 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, "[(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!")
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)
/****************************************************
ORGAN DEFINES
****************************************************/
@@ -731,6 +797,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"
@@ -748,6 +818,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"
@@ -783,6 +857,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"
@@ -791,6 +869,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"
+33 -2
View File
@@ -21,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]
@@ -30,6 +31,37 @@
H.internal_organs[src.name] = src
src.owner = H
/datum/organ/internal/process()
//Process infections
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) ))
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)
@@ -40,7 +72,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 +127,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"
+1 -1
View File
@@ -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)
@@ -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"
+1 -1
View File
@@ -37,7 +37,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()