GLOBAL_LIST_INIT(infected_contact_mobs, list()) GLOBAL_LIST_INIT(virusDB, list()) /datum/disease /// Symptomy choroby. AQ: w Monke ta zmienna jest w code/datums/diseases/_disease.dm, u nas wcześniej była tylko na advance. var/list/symptoms = list() //the disease's antigens, that the body's immune_system will read to produce corresponding antibodies. Without antigens, a disease cannot be cured. var/list/antigen = list() //alters a pathogen's propensity to mutate. Set to FALSE to forbid a pathogen from ever mutating. var/mutation_modifier = TRUE //the antibody concentration at which the disease will fully exit the body var/strength = 100 //the percentage of the strength at which effects will start getting disabled by antibodies. var/robustness = 100 //chance to cure the disease at every proc when the body is getting cooked alive. var/max_bodytemperature = T0C+100 //very low temperatures will stop the disease from activating/progressing var/min_bodytemperature = 120 ///split category used for predefined diseases atm var/category = DISEASE_NORMAL //logging var/log = "" var/origin = "Unknown" var/logged_virusfood = FALSE var/fever_warning = FALSE //cosmetic var/color var/pattern = 1 var/pattern_color ///pathogenic warfare - If you have a second disease of a form name in the list they will start fighting. var/list/can_kill = list("Bacteria") //When an opportunity for the disease to spread_flags to a mob arrives, runs this percentage through prob() //Ignored if infected materials are ingested (injected with infected blood, eating infected meat) var/infectionchance = 20 var/infectionchance_base = 20 //ticks increases by [speed] every time the disease activates. Drinking Virus Food also accelerates the process by 10. var/ticks = 0 // AQ: var/speed siedzi na /datum/disease/acute (nasz advance ma wlasne pole speed) var/stageprob = 25 //when spreading to another mob, that new carrier has the disease's stage reduced by stage_variance var/stage_variance = -1 var/uniqueID = 0// 0000 to 9999, set when the pathogen gets initially created var/subID = 0// 000 to 9999, set if the pathogen underwent effect or antigen mutation var/childID = 0// 01 to 99, incremented as the pathogen gets analyzed after a mutation //bitflag showing which transmission types are allowed for this disease var/allowed_transmission = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_AIRBORNE /datum/disease/proc/roll_antigen(list/factors = list()) if (factors.len <= 0) antigen = list(pick(GLOB.all_antigens)) antigen |= pick(GLOB.all_antigens) else var/selected_first_antigen = pick( factors[ANTIGEN_BLOOD];ANTIGEN_BLOOD, factors[ANTIGEN_COMMON];ANTIGEN_COMMON, factors[ANTIGEN_RARE];ANTIGEN_RARE, factors[ANTIGEN_ALIEN];ANTIGEN_ALIEN, ) antigen = list(pick(antigen_family(selected_first_antigen))) var/selected_second_antigen = pick( factors[ANTIGEN_BLOOD];ANTIGEN_BLOOD, factors[ANTIGEN_COMMON];ANTIGEN_COMMON, factors[ANTIGEN_RARE];ANTIGEN_RARE, factors[ANTIGEN_ALIEN];ANTIGEN_ALIEN, ) antigen |= pick(antigen_family(selected_second_antigen)) /datum/disease/proc/get_effect(index) if(!index) return pick(symptoms) return symptoms[clamp(index,0,symptoms.len)] /datum/disease/proc/GetImmuneData(mob/living/mob) var/lowest_stage = stage var/highest_concentration = 0 if (mob.immune_system) var/immune_system = mob.immune_system.GetImmunity() var/list/antibodies = immune_system[2] var/subdivision = (strength - ((robustness * strength) / 100)) / max_stages //for each antigen, we measure the corresponding antibody concentration in the carrier's immune system //the less robust the pathogen, the more likely that further stages' effects won't activate at a given concentration for (var/A in antigen) var/concentration = antibodies[A] highest_concentration = max(highest_concentration,concentration) var/i = lowest_stage while (i > 0) if (concentration > (strength - i * subdivision)) lowest_stage = i-1 i-- return list(lowest_stage,highest_concentration) /datum/disease/acute/cure(add_resistance = TRUE, mob/living/carbon/target, safe = FALSE) target = target || affected_mob || usr if(!istype(affected_mob) || QDELING(affected_mob)) return for(var/datum/symptom/acute/symptom in symptoms) symptom.disable_effect(target, src, safe) target.diseases -= src target.med_hud_set_status() log_virus("[affected_mob.name] was cured of virus [real_name()] at [loc_name(affected_mob.loc)]", list("disease_data" = admin_details(), "location" = loc_name(affected_mob.loc))) //--Plague Stuff-- /* var/datum/faction/plague_mice/plague = find_active_faction_by_type(/datum/faction/plague_mice) if (plague && ("[uniqueID]-[subID]" == plague.diseaseID)) plague.update_hud_icons() */ //---------------- var/list/pathogen_info = filter_disease_by_spread(affected_mob.diseases, required = DISEASE_SPREAD_CONTACT_SKIN) if(!length(pathogen_info)) GLOB.infected_contact_mobs -= affected_mob if(affected_mob.pathogen) for(var/mob/living/goggle_wearer in GLOB.virus_viewers) goggle_wearer.client?.images -= affected_mob.pathogen // Add resistance by boosting whichever antigen is needed if(add_resistance && target.immune_system) var/boosted_antigen var/boosted_antigen_level for(var/antigen in src.antigen) var/level = target.immune_system.antibodies[antigen] if(level >= strength) return else if(!boosted_antigen || (boosted_antigen_level > level)) boosted_antigen = antigen boosted_antigen_level = level if(boosted_antigen) target.immune_system.antibodies[boosted_antigen] = max(strength + 10, boosted_antigen_level) /datum/disease/acute/proc/activate(mob/living/mob, starved = FALSE, seconds_per_tick) if(!affected_mob) return_parent() if((mob.stat == DEAD) && !process_dead) return //Searing body temperatures cure diseases, on top of killing you. if(mob.bodytemperature > max_bodytemperature) cure(add_resistance = FALSE, target = mob) return if(disease_flags & DISEASE_DORMANT) return if(!(mob.mob_biotypes in infectable_biotypes)) return if(mob.immune_system) if(prob(10 - (robustness * 0.1))) //100 robustness don't auto cure mob.immune_system.NaturalImmune() if(!mob.immune_system.CanInfect(src)) cure(target = mob) return //Freezing body temperatures halt diseases completely if(mob.bodytemperature < min_bodytemperature) return //Virus food speeds up disease progress if(!ismouse(mob)) if(mob.reagents?.has_reagent(/datum/reagent/consumable/virus_food)) mob.reagents.remove_reagent(/datum/reagent/consumable/virus_food, 0.1) if(!logged_virusfood) log += "
[ROUND_TIME()] Virus Fed ([mob.reagents.get_reagent_amount(/datum/reagent/consumable/virus_food)]U)" logged_virusfood=1 ticks += 10 else logged_virusfood=0 if(prob(strength * 0.1)) incubate(mob, 1) //Moving to the next stage if(ticks > stage*100 && prob(stageprob)) incubate(mob, 1) if(stage < max_stages) log += "
[ROUND_TIME()] NEXT STAGE ([stage])" stage++ ticks = 0 //Pathogen killing each others for (var/datum/disease/acute/enemy_pathogen as anything in mob.diseases) if(enemy_pathogen == src) continue if ((enemy_pathogen.form in can_kill) && strength > enemy_pathogen.strength) log += "
[ROUND_TIME()] destroyed enemy [enemy_pathogen.form] #[enemy_pathogen.uniqueID]-[enemy_pathogen.subID] ([strength] > [enemy_pathogen.strength])" enemy_pathogen.cure(target = mob) // This makes it so that only ever gets affected by the equivalent of one virus so antags don't just stack a bunch if(starved) return var/list/immune_data = GetImmuneData(mob) if(!istype(mob, /mob/living/simple_animal/mouse/plague) && (!carrier)) //plague mice don't trigger effects to not kill em for(var/datum/symptom/acute/e in symptoms) if (e.can_run_effect(immune_data[1], seconds_per_tick)) e.run_effect(mob, src) //fever is a reaction of the body's immune system to the infection. The higher the antibody concentration (and the disease still not cured), the higher the fever if (mob.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT - 15)//but we won't go all the way to burning up just because of a fever, probably var/fever = round((robustness / 100) * (immune_data[2] / 10) * (stage / max_stages)) switch (mob.mob_size) if (MOB_SIZE_TINY) mob.bodytemperature += fever*0.2 if (MOB_SIZE_SMALL) mob.bodytemperature += fever*0.5 if (MOB_SIZE_HUMAN) mob.bodytemperature += fever if (MOB_SIZE_LARGE) mob.bodytemperature += fever*1.5 if (MOB_SIZE_HUGE) mob.bodytemperature += fever*2 if (fever > 0 && prob(3)) switch (fever_warning) if (0) to_chat(mob, span_warning("You feel a fever coming on, your body warms up and your head hurts a bit.")) fever_warning++ if (1) if (mob.bodytemperature > 320) to_chat(mob, span_warning("Your palms are sweaty.")) fever_warning++ if (2) if (mob.bodytemperature > 335) to_chat(mob, span_warning("Your knees are weak.")) fever_warning++ if (3) if (mob.bodytemperature > 350) to_chat(mob, span_warning("Your arms are heavy.")) fever_warning++ ticks += speed //horrible, awful, stolen code from disease/advance. But it WORKS /datum/disease/acute var/list/properties = list() /// Licznik tempa (w Monke stoi na /datum/disease, u nas advance ma juz wlasne `speed`). var/speed = 1 /// Nasz /datum/disease/Copy() kopiuje tylko pola z Bee, wiec pola disease2 dopisujemy tutaj. /datum/disease/acute/Copy() var/datum/disease/acute/copy = ..() if(!istype(copy)) return copy var/static/list/acute_vars = list( "antigen", "mutation_modifier", "strength", "robustness", "max_bodytemperature", "min_bodytemperature", "category", "log", "origin", "logged_virusfood", "fever_warning", "color", "pattern", "pattern_color", "can_kill", "infectionchance", "infectionchance_base", "ticks", "speed", "stageprob", "stage_variance", "uniqueID", "subID", "childID", "allowed_transmission", "symptoms", ) for(var/field in acute_vars) var/value = vars[field] if(islist(value)) var/list/listed = value value = listed.Copy() copy.vars[field] = value var/list/copied_symptoms = list() for(var/datum/symptom/acute/symptom as anything in symptoms) var/datum/symptom/acute/copied = symptom.Copy() copied_symptoms += copied SEND_SIGNAL(copied, COMSIG_SYMPTOM_ATTACH, copy) copy.symptoms = copied_symptoms return copy /// Calls on GenerateProperties and AssignProperties to set a disease severity. From `disease/advance` /datum/disease/acute/proc/Refresh_Acute(new_name = FALSE) GenerateProperties_Acute() assign_properties_Acute() /// Generates the list for the severity with severity defined at 0, then calls on symtomps severity for final. /datum/disease/acute/proc/GenerateProperties_Acute() properties = list("severity" = 0) for(var/datum/symptom/acute/S in symptoms) if(!S.neutered) properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity non-neutered symptom /datum/disease/acute/proc/assign_properties_Acute() if(length(properties)) set_severity_Acute(properties["severity"]) else CRASH("Our properties were empty or null!") ///sets a serverity level based on the properties["severity"] value of the disease /datum/disease/acute/proc/set_severity_Acute(level_sev) switch(level_sev) if(-INFINITY to 0) danger = DISEASE_SEVERITY_POSITIVE if(1) danger = DISEASE_SEVERITY_NONTHREAT if(2) danger = DISEASE_SEVERITY_MINOR if(3) danger = DISEASE_SEVERITY_MEDIUM if(4) danger = DISEASE_SEVERITY_HARMFUL if(5) danger = DISEASE_SEVERITY_DANGEROUS if(6 to INFINITY) danger = DISEASE_SEVERITY_BIOHAZARD else danger = "Unknown"