/
githubmirror
/
vgstation13
Обзор
Документация
Войти
/
githubmirror
/
vgstation13
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
Bleeding-Edge
code/modules/virus2/helpers.dm
380 строк
13 KB
jwhitak
Random Runtime Fixes (#37135)
17 сен 2024, 22:52
Не верифицирован
17 сен 2024, 22:52
67ab14a
Код
Авторство
О чём код?
//Build random disease type /proc/get_random_weighted_disease(var/operation = WDISH) var/list/possibles = subtypesof(/datum/disease2/disease) - typesof(/datum/disease2/disease/predefined) - /datum/disease2/disease/meme/super var/list/weighted_list = list() for(var/P in possibles) var/datum/disease2/disease/D = new P var/weight = D.type_weight[operation] if (weight != 0) weighted_list[D] = weight return pickweight(weighted_list) //////////////////////////////////////////////////// //Checks if table-passing table can reach target (5 tile radius) //For the record that proc is only used by the "Gregarious Impetus" symptom and super/toxic farts. /proc/airborne_can_reach(turf/source, turf/target, var/radius=5) var/obj/dummy = new(source) dummy.flags = FPRINT dummy.pass_flags = PASSTABLE for(var/i=0, i<radius, i++) if(!step_towards(dummy, target)) break var/rval = (target.Adjacent(dummy.loc)) dummy.forceMove(null) dummy = null return rval /////////////////////////////////////////// // // // STERILITY CHECKS ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // /////////////////////////////////////////// //AIRBORNE /mob/living/proc/check_airborne_sterility() return 0 /mob/living/carbon/human/check_airborne_sterility() var/block = 0 if (wear_mask && (wear_mask.body_parts_covered & MOUTH) && prob(wear_mask.sterility)) block = 1 if (head && (head.body_parts_covered & MOUTH) && prob(head.sterility)) block = 1 return block /mob/living/carbon/monkey/check_airborne_sterility() var/block = 0 if (wear_mask && (wear_mask.body_parts_covered & MOUTH) && prob(wear_mask.sterility)) block = 1 if (hat && (hat.body_parts_covered & MOUTH) && prob(hat.sterility)) block = 1 return block ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //CONTACT /mob/living/proc/check_contact_sterility(var/body_part) return 0 /mob/living/carbon/human/check_contact_sterility(var/body_part) var/list/clothing_to_check = list( wear_mask, w_uniform, head, wear_suit, back, gloves, handcuffed, legcuffed, belt, shoes, wear_mask, glasses, ears, wear_id) for (var/thing in clothing_to_check) var/obj/item/cloth = thing if(istype(cloth) && (cloth.body_parts_covered & body_part) && prob(cloth.sterility)) return TRUE return FALSE /mob/living/carbon/monkey/check_contact_sterility(var/body_part) var/list/clothing_to_check = list( wear_mask, uniform, hat, back, handcuffed, legcuffed, glasses,) for (var/thing in clothing_to_check) var/obj/item/cloth = thing if(istype(cloth) && (cloth.body_parts_covered & body_part) && prob(cloth.sterility)) return TRUE return FALSE ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //VALID COLONY (spread SPREAD_COLONY) /mob/living/carbon/suitable_colony() return FALSE /mob/living/carbon/human/suitable_colony() var/obj/item/clothing = wear_suit if(clothing && clothing.pressure_resistance > ONE_ATMOSPHERE) return TRUE return FALSE /mob/living/carbon/monkey/suitable_colony() var/obj/item/clothing = uniform if(istype(clothing,/obj/item/clothing/monkeyclothes/space)) //Also covers sanity if null return TRUE return FALSE /proc/attempt_colony(var/atom/A, var/datum/disease2/disease/D,var/info) if(!(D.spread & SPREAD_COLONY)) return FALSE if(A.suitable_colony()) A.infect_disease2(D, notes="(Colonized[info ? ", [info]" : ""])") return TRUE return FALSE ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //BLEEDING (bleeding body parts allow SPREAD_BLOOD to infect) /mob/living/proc/check_bodypart_bleeding(var/body_part) return 0 /mob/living/carbon/human/check_bodypart_bleeding(var/body_part) var/bleeding = 0 switch(body_part) if (HEAD)//head-patting var/datum/organ/external/head = organs_by_name[LIMB_HEAD] if(head?.status & ORGAN_BLEEDING) bleeding = 1 if (FULL_TORSO)//hugging, lying over infected blood, broken dishes var/datum/organ/external/chest = organs_by_name[LIMB_CHEST] if(chest?.status & ORGAN_BLEEDING) bleeding = 1 if (FEET)//walking over infected blood, broken dishes var/datum/organ/external/l_foot = organs_by_name[LIMB_LEFT_FOOT] if(l_foot?.status & ORGAN_BLEEDING) bleeding = 1 var/datum/organ/external/r_foot = organs_by_name[LIMB_RIGHT_FOOT] if(r_foot?.status & ORGAN_BLEEDING) bleeding = 1 if (HANDS)//walking over infected blood, broken dishes var/datum/organ/external/hand/l_hand = organs_by_name[LIMB_LEFT_HAND] if(l_hand?.status & ORGAN_BLEEDING) bleeding = 1 var/datum/organ/external/hand/r_hand = organs_by_name[LIMB_RIGHT_HAND] if(r_hand?.status & ORGAN_BLEEDING) bleeding = 1 return bleeding //until monkeys can bleed or have open wounds, they're safe on that end. /mob/living/simple_animal/mouse/check_bodypart_bleeding(var/body_part) return splat//visibly bleeding /////////////////////////////////////////// // // // INFECTION ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // /////////////////////////////////////////// //This proc is called when the disease has already bypassed clothing and other protections //The only checks left are for antibodies/sterility and the disease's infection chance /atom/proc/infect_disease2(var/datum/disease2/disease/disease,var/forced = 0, var/notes="") return 0 //MOBS var/list/infected_contact_mobs = list() /mob/living/infect_disease2(var/datum/disease2/disease/disease,var/forced = 0, var/notes="") if(!istype(disease)) return 0 if(disease.spread == 0)//in case admins bus'd in a non-spreadable disease. return 0 if(!can_be_infected())//humans, monkeys, mouse, for now return 0 if ("[disease.uniqueID]-[disease.subID]" in virus2) return 0 if(immune_system && !immune_system.CanInfect(disease)) return 0 if(prob(disease.infectionchance) || forced) var/datum/disease2/disease/D = disease.getcopy() if (D.infectionchance > 10) D.infectionchance = max(10, D.infectionchance - 10)//The virus gets weaker as it jumps from people to people D.stage = clamp(D.stage+D.stage_variance, 1, D.max_stage) D.log += "<br />[timestamp()] Infected [key_name(src)] [notes]. Infection chance now [D.infectionchance]%" virus2["[D.uniqueID]-[D.subID]"] = D D.AddToGoggleView(src) //--Plague Stuff-- var/datum/faction/plague_mice/plague = find_active_faction_by_type(/datum/faction/plague_mice) if (plague && ("[D.uniqueID]-[D.subID]" == plague.diseaseID)) var/datum/objective/plague/O = locate() in plague.objective_holder.objectives if (O && !istype(src, /mob/living/simple_animal/mouse/plague)) O.total_infections++ plague.update_hud_icons() //--Cult Stuff-- if (disease.category == DISEASE_CULT) var/datum/faction/bloodcult/cult = find_active_faction_by_type(/datum/faction/bloodcult) cult?.check_ritual("cursed_infection", src) //---------------- for (var/obj/item/device/pda/p in contents) if (istype(p.scanning_app,/datum/pda_app/cart/scanner/medical)) playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) if("[disease.uniqueID]-[disease.subID]" in virusDB) var/datum/data/record/V = virusDB["[disease.uniqueID]-[disease.subID]"] var/risk = "warning" switch (V.fields["danger"]) if ("*DANGEROUS*") risk = "danger" if ("Safe") risk = "notice" to_chat(src, "[bicon(p)]<span class='[risk]'>Infection Detected! [V.fields["name"]][V.fields["nickname"] ? " \"[V.fields["nickname"]]\"" : ""] has entered your body.</span>") else to_chat(src, "[bicon(p)]<span class='danger'>Infection Detected! Unknown [D.form] has entered your body.</span>") return 1 return 0 /mob/living/proc/infect_disease2_predefined(var/category, var/forced, var/notes) if(!global_diseases[category]) return infect_disease2(global_diseases[category], forced, notes) //ITEMS var/list/infected_items = list() /obj/item/infect_disease2(var/datum/disease2/disease/disease,var/forced = 0, var/notes="",var/decay = 1) if(!istype(disease)) return 0 if(disease.spread == 0) return 0 if (prob(sterility)) return 0 if ("[disease.uniqueID]-[disease.subID]" in virus2) return 0 if(prob(disease.infectionchance) || forced) var/datum/disease2/disease/D = disease.getcopy() D.log += "<br />[timestamp()] Infected \a [src] [notes]" virus2["[D.uniqueID]-[D.subID]"] = D infected_items |= src if (!pathogen) pathogen = image('icons/effects/effects.dmi',src,"pathogen_contact") pathogen.plane = HUD_PLANE pathogen.layer = HUD_ABOVE_ITEM_LAYER pathogen.appearance_flags = RESET_COLOR|RESET_ALPHA for (var/mob/L in science_goggles_wearers) if (L.client) L.client.images |= pathogen if (decay) spawn((disease.infectionchance/10) MINUTES) remove_disease2("[D.uniqueID]-[D.subID]") return 1 return 0 /atom/proc/remove_disease2(var/diseaseID) return 0 /obj/item/remove_disease2(var/diseaseID) if (diseaseID) if (diseaseID in virus2) virus2[diseaseID] = null virus2.Remove(diseaseID) else virus2 = list() if (virus2 && virus2.len <= 0) infected_items -= src if (pathogen) for (var/mob/L in science_goggles_wearers) if (L.client) L.client.images -= pathogen ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //MEDHUD STUFF // Returns 1 if patient has virus2 that medHUDs would pick up. // Otherwise returns 0 /proc/has_recorded_virus2(var/mob/living/carbon/patient) var/highest_danger = 0 for (var/ID in patient.virus2) if (ID in virusDB) highest_danger = max(highest_danger,1) var/datum/data/record/v = virusDB[ID] if (v.fields["danger"]) switch (v.fields["danger"]) if ("*DANGEROUS*") highest_danger = max(highest_danger,3) if ("Undetermined") highest_danger = max(highest_danger,1) if ("Safe") highest_danger = max(highest_danger,2) return highest_danger // This one doesn't really belong here, but old disease code has no helpers, so // Returns 1 if patient has old-style disease that medHUDs would pick up. // Otherwise returns 0 /proc/has_recorded_disease(var/mob/living/carbon/patient) for(var/datum/disease/D in patient.viruses) if(!D.hidden[SCANNER]) return 1 return 0 // combination of above two procs /proc/has_any_recorded_disease(var/mob/living/carbon/patient) if(has_recorded_disease(patient)) return 1 else if (has_recorded_virus2(patient)) return 1 return 0 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /proc/filter_disease_by_spread(var/list/diseases = list(), var/required = 0, var/forbidden = 0) if (!diseases || diseases.len <= 0) return list() var/list/result = list() for (var/ID in diseases) var/datum/disease2/disease/V = diseases[ID] if ((!required || (V.spread & required)) && (!forbidden || !(V.spread & forbidden))) result[ID] = V return result ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /proc/get_part_from_limb(var/limb) var/part = FULL_TORSO switch (limb) if(LIMB_HEAD) part = HEAD if(LIMB_LEFT_HAND) part = HAND_LEFT if(LIMB_RIGHT_HAND) part = HAND_RIGHT if(LIMB_LEFT_ARM) part = ARM_LEFT if(LIMB_RIGHT_ARM) part = ARM_RIGHT if(LIMB_GROIN) part = LOWER_TORSO if(LIMB_LEFT_LEG) part = LEG_LEFT if(LIMB_RIGHT_LEG) part = LEG_RIGHT if(LIMB_LEFT_FOOT) part = FOOT_LEFT if(LIMB_RIGHT_FOOT) part = FOOT_RIGHT if(TARGET_MOUTH) part = MOUTH if("eyes") part = EYES return part ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /proc/spread_disease_among_crew(var/datum/disease2/disease/D, var/reason = "4noraisin") var/list/candidates = list() for(var/mob/living/candidate in player_list) if(candidate.z == map.zMainStation && candidate.client && candidate.stat != DEAD && candidate.can_be_infected() && candidate.immune_system.CanInfect(D)) candidates += candidate if(!candidates.len) return var/infected = 1 + round(candidates.len/10) for (var/i = 1 to infected) var/mob/living/candidate = pick(candidates) candidates -= candidate candidate.infect_disease2(D,1, reason)