Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rework: Virology #3703

Merged
merged 19 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions code/__HELPERS/global_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -158,25 +158,25 @@

// Init disease archive
GLOB.archive_diseases += list(
"sneeze" = new /datum/disease/advance/preset/cold(),
"cough" = new /datum/disease/advance/preset/flu(),
"voice_change" = new /datum/disease/advance/preset/voice_change(),
"heal" = new /datum/disease/advance/preset/heal(),
"hallucigen" = new /datum/disease/advance/preset/hullucigen(),
"sensory_restoration" = new /datum/disease/advance/preset/sensory_restoration(),
"mind_restoration" = new /datum/disease/advance/preset/mind_restoration(),
"damage_converter:heal:viralevolution" = new /datum/disease/advance/preset/advanced_regeneration(),
"dizzy:flesh_eating:viraladaptation:youth" = new /datum/disease/advance/preset/stealth_necrosis(),
"beard:itching:voice_change" = new /datum/disease/advance/preset/pre_kingstons(),
"love" = new /datum/disease/advance/preset/love(),
"aggression" = new /datum/disease/advance/preset/aggression(),
"obsession" = new /datum/disease/advance/preset/obsession(),
"confusion" = new /datum/disease/advance/preset/confusion(),
"bones" = new /datum/disease/advance/preset/bones(),
"laugh" = new /datum/disease/advance/preset/laugh(),
"moan" = new /datum/disease/advance/preset/moan(),
"infection" = new /datum/disease/advance/preset/infection(),
"hallucigen:laugh:moan" = new /datum/disease/advance/preset/pre_loyalty()
"sneeze" = new /datum/disease/virus/advance/preset/sneezing(),
"cough" = new /datum/disease/virus/advance/preset/cough(),
"voice_change" = new /datum/disease/virus/advance/preset/voice_change(),
"heal" = new /datum/disease/virus/advance/preset/heal(),
"hallucigen" = new /datum/disease/virus/advance/preset/hullucigen(),
"sensory_restoration" = new /datum/disease/virus/advance/preset/sensory_restoration(),
"mind_restoration" = new /datum/disease/virus/advance/preset/mind_restoration(),
"damage_converter:heal:viralevolution" = new /datum/disease/virus/advance/preset/advanced_regeneration(),
"dizzy:flesh_eating:viraladaptation:youth" = new /datum/disease/virus/advance/preset/stealth_necrosis(),
"beard:itching:voice_change" = new /datum/disease/virus/advance/preset/pre_kingstons(),
"love" = new /datum/disease/virus/advance/preset/love(),
"aggression" = new /datum/disease/virus/advance/preset/aggression(),
"obsession" = new /datum/disease/virus/advance/preset/obsession(),
"confusion" = new /datum/disease/virus/advance/preset/confusion(),
"bones" = new /datum/disease/virus/advance/preset/bones(),
"laugh" = new /datum/disease/virus/advance/preset/laugh(),
"moan" = new /datum/disease/virus/advance/preset/moan(),
"infection" = new /datum/disease/virus/advance/preset/infection(),
"hallucigen:laugh:moan" = new /datum/disease/virus/advance/preset/pre_loyalty()
)

//creates every subtype of prototype (excluding prototype) and adds it to list L.
Expand Down
245 changes: 122 additions & 123 deletions code/datums/diseases/_MobProcs.dm
Original file line number Diff line number Diff line change
@@ -1,135 +1,134 @@
/mob/proc/HasDisease(disease_type_or_instance)
var/datum/disease/D1
if(ispath(disease_type_or_instance))
D1 = new disease_type_or_instance()
else
D1 = disease_type_or_instance
if(!istype(D1))
return FALSE

for(var/datum/disease/D2 in diseases)
if(D2.IsSame(D1))
Dimach marked this conversation as resolved.
Show resolved Hide resolved
Dimach marked this conversation as resolved.
Show resolved Hide resolved
Dimach marked this conversation as resolved.
Show resolved Hide resolved
return TRUE
return FALSE

/mob/proc/CureAllDiseases(need_immunity = TRUE)
for(var/datum/disease/D in diseases)
D.cure(need_immunity = need_immunity)

/mob/proc/HasDisease(datum/disease/D)
for(var/thing in viruses)
var/datum/disease/DD = thing
if(D.IsSame(DD))
return 1
return 0


/**
* A special checks for this type of mob
*
* Returns:
* * TRUE - if can contract disease
* * FALSE - otherwise
*/
/mob/proc/CanContractDisease(datum/disease/D)
if(stat == DEAD)
return FALSE

if(D.GetDiseaseID() in resistances)
return FALSE

if(HasDisease(D))
return FALSE
return TRUE

if(istype(D, /datum/disease/advance) && count_by_type(viruses, /datum/disease/advance) > 0)
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
if((VIRUSIMMUNE in dna.species.species_traits) && !D.ignore_immunity)
return FALSE
for(var/thing in D.required_organs)
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
return FALSE
return ..()

if(!(type in D.viable_mobtypes))
return -1 //for stupid fucking monkies

return TRUE

/**
* Checking mob's protection against disease D by the chosen method in chosen zone
* Returns:
* * TRUE - mob has protected from the virus
* * FALSE - otherwise
*/
/mob/proc/CheckVirusProtection(datum/disease/virus/V, act_type = BITES|CONTACT|AIRBORNE, zone)
if(prob(15/V.permeability_mod))
return TRUE

/mob/proc/ContractDisease(datum/disease/D)
if(!CanContractDisease(D))
return 0
D.Contract(src)

/mob/living/carbon/ContractDisease(datum/disease/D)
if(!CanContractDisease(D))
return 0

var/obj/item/clothing/Cl = null
var/passed = 1

var/head_ch = 100
var/body_ch = 100
var/hands_ch = 25
var/feet_ch = 25

if(D.spread_flags & CONTACT_HANDS)
head_ch = 0
body_ch = 0
hands_ch = 100
feet_ch = 0
if(D.spread_flags & CONTACT_FEET)
head_ch = 0
body_ch = 0
hands_ch = 0
feet_ch = 100

if(prob(15/D.permeability_mod))
return

if(satiety > 0 && prob(satiety/10)) // positive satiety makes it harder to contract the disease.
return

var/target_zone = pick(head_ch;1,body_ch;2,hands_ch;3,feet_ch;4)

if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src

switch(target_zone)
if(1)
if(isobj(H.head) && !istype(H.head, /obj/item/paper))
Cl = H.head
passed = prob((Cl.permeability_coefficient*100) - 1)
if(passed && isobj(H.wear_mask))
Cl = H.wear_mask
passed = prob((Cl.permeability_coefficient*100) - 1)
if(2)
if(isobj(H.wear_suit))
Cl = H.wear_suit
passed = prob((Cl.permeability_coefficient*100) - 1)
if(passed && isobj(slot_w_uniform))
Cl = slot_w_uniform
passed = prob((Cl.permeability_coefficient*100) - 1)
if(3)
if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&HANDS)
Cl = H.wear_suit
passed = prob((Cl.permeability_coefficient*100) - 1)

if(passed && isobj(H.gloves))
Cl = H.gloves
passed = prob((Cl.permeability_coefficient*100) - 1)
if(4)
if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&FEET)
Cl = H.wear_suit
passed = prob((Cl.permeability_coefficient*100) - 1)

if(passed && isobj(H.shoes))
Cl = H.shoes
passed = prob((Cl.permeability_coefficient*100) - 1)


if(!passed && (D.spread_flags & AIRBORNE) && !internal)
passed = (prob((50*D.permeability_mod) - 1))

if(passed)
D.Contract(src)
if(satiety > 0 && prob(satiety/10))
return TRUE

//virus must to pass all the checks stated in act_type
if((act_type & BITES) && !CheckBitesProtection(V, zone))
return FALSE

/**
* Forces the mob to contract a virus. If the mob can have viruses. Ignores clothing and other protection
* Returns TRUE if it succeeds. False if it doesn't
*
* Arguments:
* * D - the disease the mob will try to contract
*/
//Same as ContractDisease, except never overidden clothes checks
/mob/proc/ForceContractDisease(datum/disease/D)
if(!CanContractDisease(D))
if((act_type & CONTACT) && !CheckContactProtection(V, zone))
return FALSE
D.Contract(src)
return TRUE

if((act_type & AIRBORNE) && !CheckAirborneProtection(V, zone))
return FALSE

/mob/living/carbon/human/CanContractDisease(datum/disease/D)
if((VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity)
return 0
for(var/thing in D.required_organs)
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
return 0
return ..()
return TRUE

/mob/living/carbon/human/lesser/monkey/CanContractDisease(datum/disease/D)
. = ..()
if(. == -1)
if(D.viable_mobtypes.Find(/mob/living/carbon/human))
return 1 //this is stupid as fuck but because monkeys are only half the time actually subtypes of humans they need this
//Returns TRUE, if mob protected
/mob/proc/CheckBitesProtection(datum/disease/virus/V, zone)
return FALSE

/mob/proc/CheckContactProtection(datum/disease/virus/V, zone)
return FALSE

/mob/proc/CheckAirborneProtection(datum/disease/virus/V, zone)
return FALSE

/mob/living/CheckBitesProtection(datum/disease/virus/V, zone = BODY_ZONE_CHEST)
return ..() || prob(run_armor_check(zone, "melee") / V.permeability_mod)

/mob/living/carbon/human/CheckContactProtection(datum/disease/virus/V, zone)
if(..())
return TRUE

var/zone_text
if(!zone)
zone_text = pick(40; "head", 40; "chest", 10; "l_arm", 10; "l_leg")
else
if(istype(zone, /obj/item/organ/external))
var/obj/item/organ/external/E = zone
zone_text = E.limb_name
else
zone_text = zone

switch(zone_text)
if("head", "eyes", "mouth")
if(ClothingVirusProtection(head) || ClothingVirusProtection(wear_mask))
return TRUE
if("chest", "groin", "tail", "wing")
if(ClothingVirusProtection(wear_suit) || ClothingVirusProtection(w_uniform))
return TRUE
if("l_arm", "r_arm", "l_hand", "r_hand")
if(istype(wear_suit) && (wear_suit.body_parts_covered & HANDS) && ClothingVirusProtection(wear_suit))
return TRUE
if(ClothingVirusProtection(gloves))
return TRUE
if("l_leg", "r_leg", "l_foot", "r_foot")
if(istype(wear_suit) && (wear_suit.body_parts_covered & FEET) && ClothingVirusProtection(wear_suit))
return TRUE
if(ClothingVirusProtection(shoes))
return TRUE

return FALSE

/mob/living/carbon/human/CheckAirborneProtection(datum/disease/virus/V, zone)
if(..())
return TRUE

var/internals_mod = internal ? 1 : 0.2
var/permeability_mod = clamp((2 - V.permeability_mod), 0.1, 1)
var/mask_protection_mod = 1
if(wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH))
mask_protection_mod = 0.3
if(istype(wear_mask, /obj/item/clothing/mask/breath))
mask_protection_mod = 0.4
if(istype(wear_mask, /obj/item/clothing/mask/gas))
mask_protection_mod = 0.6
if(istype(wear_mask, /obj/item/clothing/mask/surgical) || istype(wear_mask, /obj/item/clothing/mask/breath/medical))
mask_protection_mod = 0.9

if(prob(100 * permeability_mod * internals_mod * mask_protection_mod))
return TRUE

return FALSE

/mob/living/carbon/human/proc/ClothingVirusProtection(obj/item/Clothing)
//permeability_coefficient == 0.01 => 99% defense; permeability_coefficient == 1 => 0% defense
if(istype(Clothing) && prob(100 * (1 - Clothing.permeability_coefficient)))
return TRUE
return FALSE
Loading
Loading