Infection chance proc improvements

Instead of magic type bits, the infection protection value of clothing is mostly based on it's bio armor value, which is much more flexible. Also gloves and shoes to contribute to protection values, and adjusts surgical mask bio protection.
Hardsuits gain voidsuit level bio protection, when sealed.
Wearing a face mask helps prevent others from catching airborne diseases.
Also fixes #7909
This commit is contained in:
unknown
2015-01-22 11:10:57 -05:00
committed by mwerezak
parent d836103b22
commit 7590bbac99
7 changed files with 68 additions and 51 deletions
+50 -40
View File
@@ -1,49 +1,58 @@
//Returns 1 if mob can be infected, 0 otherwise. Checks his clothing.
proc/get_infection_chance(var/mob/living/carbon/M, var/vector = "Airborne")
var/score = 0
//Returns 1 if mob can be infected, 0 otherwise.
proc/infection_check(var/mob/living/carbon/M, var/vector = "Airborne")
if (!istype(M))
return 0
if(istype(M, /mob/living/carbon/human))
var/protection = M.getarmor(null, "bio") //gets the full body bio armour value, weighted by body part coverage.
var/score = round(0.06*protection) //scales 100% protection to 6.
if (vector == "Airborne")
if(M.internal) //not breathing infected air helps greatly
score = 30
if(M.wear_mask)
score += 5
if(istype(M:wear_mask, /obj/item/clothing/mask/surgical) && !M.internal)
score += 10
if(istype(M:wear_suit, /obj/item/clothing/suit/space) && istype(M:head, /obj/item/clothing/head/helmet/space))
score += 20
if(istype(M:wear_suit, /obj/item/clothing/suit/bio_suit) && istype(M:head, /obj/item/clothing/head/bio_hood))
score += 30
switch(vector)
if("Airborne")
if(M.internal)
score = 6 //not breathing infected air helps greatly
var/obj/item/I = M.wear_mask
//masks provide a small bonus and can replace overall bio protection
score = max(score, round(0.06*I.armor["bio"]))
if (istype(I, /obj/item/clothing/mask))
score += 1 //this should be added after
if("Contact")
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
//gloves provide a larger bonus
if (istype(H.gloves, /obj/item/clothing/gloves))
score += 2
if (vector == "Contact")
if(M:gloves) score += 15
if(istype(M:wear_suit, /obj/item/clothing/suit/space) && istype(M:head, /obj/item/clothing/head/helmet/space))
score += 15
if(istype(M:wear_suit, /obj/item/clothing/suit/bio_suit) && istype(M:head, /obj/item/clothing/head/bio_hood))
score += 15
// log_debug("[M]'s resistance to [vector] viruses: [score]")
if(score >= 30)
if(score >= 6)
return 0
else if(score == 25 && prob(99))
else if(score >= 5 && prob(99))
return 0
else if(score == 20 && prob(95))
else if(score >= 4 && prob(95))
return 0
else if(score == 15 && prob(75))
else if(score >= 3 && prob(75))
return 0
else if(score == 10 && prob(55))
else if(score >= 2 && prob(55))
return 0
else if(score == 5 && prob(35))
else if(score >= 1 && prob(35))
return 0
// log_debug("Infection got through")
return 1
//Similar to infection check, but used for when M is spreading the virus.
/proc/infection_spreading_check(var/mob/living/carbon/M, var/vector = "Airborne")
if (!istype(M))
return 0
var/protection = M.getarmor(null, "bio") //gets the full body bio armour value, weighted by body part coverage.
if (vector == "Airborne")
var/obj/item/I = M.wear_mask
if (istype(I))
protection = max(protection, round(0.06*I.armor["bio"]))
return prob(protection)
//Checks if table-passing table can reach target (5 tile radius)
proc/airborne_can_reach(turf/source, turf/target)
var/obj/dummy = new(source)
@@ -84,17 +93,14 @@ proc/airborne_can_reach(turf/source, turf/target)
// log_debug("Infecting [M]")
if(prob(disease.infectionchance) || forced)
// certain clothes can prevent an infection
if(!forced && !get_infection_chance(M, disease.spreadtype))
return
if(forced || (infection_check(M, disease.spreadtype) && prob(disease.infectionchance)))
var/datum/disease2/disease/D = disease.getcopy()
D.minormutate()
// log_debug("Adding virus")
M.virus2["[D.uniqueID]"] = D
M.hud_updateflag |= 1 << STATUS_HUD
//Infects mob M with disease D
/proc/infect_mob(var/mob/living/carbon/M, var/datum/disease2/disease/D)
infect_virus2(M,D,1)
@@ -126,12 +132,15 @@ proc/airborne_can_reach(turf/source, turf/target)
// log_debug("Attempting virus [ID]")
var/datum/disease2/disease/V = virus2[ID]
if(V.spreadtype != vector) continue
//It's hard to get other people sick if you're in an airtight suit.
if(!infection_spreading_check(src, V.spreadtype)) continue
if (vector == "Airborne")
if(airborne_can_reach(get_turf(src), get_turf(victim)))
// log_debug("In range, infecting")
infect_virus2(victim,V)
else
// else
// log_debug("Could not reach target")
if (vector == "Contact")
@@ -148,7 +157,7 @@ proc/airborne_can_reach(turf/source, turf/target)
var/mob/living/carbon/human/H = victim
var/datum/organ/external/select_area = H.get_organ(src.zone_sel.selecting)
var/list/clothes = list(H.head, H.wear_mask, H.wear_suit, H.w_uniform, H.gloves, H.shoes)
for(var/obj/item/clothing/C in clothes )
for(var/obj/item/clothing/C in clothes)
if(C && istype(C))
if(C.body_parts_covered & select_area.body_part)
nudity = 0
@@ -156,4 +165,5 @@ proc/airborne_can_reach(turf/source, turf/target)
for (var/ID in victim.virus2)
var/datum/disease2/disease/V = victim.virus2[ID]
if(V && V.spreadtype != vector) continue
if(!infection_spreading_check(victim, V.spreadtype)) continue
infect_virus2(src,V)