diff --git a/code/__defines/_reagents.dm b/code/__defines/_reagents.dm index 48ed8b6bf7..bd947977d7 100644 --- a/code/__defines/_reagents.dm +++ b/code/__defines/_reagents.dm @@ -283,6 +283,14 @@ #define REAGENT_ID_PHORONVIRUSFOOD "phoronvirusfood" #define REAGENT_WEAKPHORONVIRUSFOOD "Weakened phoronic virus food" #define REAGENT_ID_WEAKPHORONVIRUSFOOD "weakphoronvirusfood" +#define REAGENT_URANIUMVIRUSFOOD "Unstable virus food" +#define REAGENT_ID_URANIUMVIRUSFOOD "uraniumvirusfood" +#define REAGENT_UNSTABLEURANIUMVIRUSFOOD "Unstable uranium gel" +#define REAGENT_ID_UNSTABLEURANIUMVIRUSFOOD "unstableuraniumvirusfood" +#define REAGENT_STABLEURANIUMVIRUSFOOD "Stable uranium gel" +#define REAGENT_ID_STABLEURANIUMVIRUSFOOD_ALT "stableuraniumvirusfood_alt" +#define REAGENT_STABLEURANIUMVIRUSFOOD_ALT "Stable uranium gel" +#define REAGENT_ID_STABLEURANIUMVIRUSFOOD "stableuraniumvirusfood" #define REAGENT_SIZEVIRUSFOOD "Sizeoxadone virus food" #define REAGENT_ID_SIZEVIRUSFOOD "sizevirusfood" diff --git a/code/__defines/diseases.dm b/code/__defines/diseases.dm index 3dd0d595ec..b546b3e0dc 100644 --- a/code/__defines/diseases.dm +++ b/code/__defines/diseases.dm @@ -18,6 +18,7 @@ #define DISEASE_SPREAD_FLUIDS (1<<3) #define DISEASE_SPREAD_CONTACT (1<<4) #define DISEASE_SPREAD_AIRBORNE (1<<5) +#define DISEASE_SPREAD_FALTERED (1<<6) //Severity Defines #define DISEASE_BENEFICIAL "Beneficial" @@ -39,6 +40,8 @@ #define CARRIER 0x20 /// If we are a carrier for the virus but we will not be affected by it. #define BYPASSES_IMMUNITY 0x40 /// If this virus bypasses immunity. #define DISCOVERED 0x80 /// If applied, this virus will show up on medical HUDs. Automatically set when it reaches mid-stage. +#define DORMANT 0x100 /// If applied, the virus is dormant and will not act or spread. +#define FALTERED 0x200 /// If applied, the virus is faltered and will only spread by intentional injection. #define EXTRAPOLATOR_RESULT_DISEASES "extrapolator_result_disease" #define EXTRAPOLATOR_RESULT_ACT_PRIORITY "extrapolator_result_action_priority" diff --git a/code/__defines/traits.dm b/code/__defines/traits.dm index 3a05f89586..0cb55c1911 100644 --- a/code/__defines/traits.dm +++ b/code/__defines/traits.dm @@ -211,5 +211,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define FERVEATIUM_TRAIT "ferveatium" */ +#define STRONG_IMMUNITY_TRAIT "strongimmunity" + #define ORGANICS 1 #define SYNTHETICS 2 diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index ca694bee03..53809e85b8 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -5,6 +5,10 @@ return TRUE return FALSE +/mob/proc/addDisease(datum/disease/D) + LAZYADD(viruses, D) + return TRUE + /mob/proc/RemoveDisease(datum/disease/D) LAZYREMOVE(viruses, D) return TRUE @@ -29,8 +33,13 @@ if(HasDisease(D)) return FALSE - if(istype(D, /datum/disease/advance) && count_by_type(GetViruses(), /datum/disease/advance) > 0) - return FALSE + if(istype(D, /datum/disease/advance)) + var/active_diseases = 0 + for(var/datum/disease/AD in GetViruses()) + if(!(AD.virus_modifiers & DORMANT)) // You can have as many dormant diseases as you want + active_diseases++ + if(active_diseases > 0) // But ONLY one active disease + return FALSE var/compatible_type = FALSE for(var/type_to_test in D.viable_mobtypes) @@ -50,31 +59,9 @@ /mob/proc/ContractDisease(datum/disease/D, var/target_zone) if(!CanContractDisease(D)) return 0 - AddDisease(D) + D.infect(src) return TRUE -/mob/proc/AddDisease(datum/disease/D, respect_carrier = FALSE) - var/datum/disease/DD = new D.type(1, D, 0) - DD.start_cure_timer() - viruses += DD - DD.affected_mob = src - GLOB.active_diseases += DD - - var/list/skipped = list("affected_mob", "holder", "carrier", "stage", "type", "parent_type", "vars", "transformed", "_active_timers") - if(respect_carrier) - skipped -= "carrier" - for(var/V in DD.vars) - if(V in skipped) - continue - if(istype(DD.vars[V],/list)) - var/list/L = D.vars[V] - if(islist(L)) - DD.vars[V] = L.Copy() - else - DD.vars[V] = D.vars[V] - - log_admin("[key_name(src)] has contracted the virus \"[DD]\"") - /mob/living/carbon/human/ContractDisease(datum/disease/D, target_zone) if(!CanContractDisease(D)) return FALSE @@ -144,7 +131,7 @@ passed = prob((Cl.permeability_coefficient*100) - 1) if(passed) - AddDisease(D) + D.infect(src) /mob/living/proc/AirborneContractDisease(datum/disease/D, force_spread) if(((D.spread_flags & DISEASE_SPREAD_AIRBORNE) || force_spread) && prob(50*D.spreading_modifier) - 1) @@ -161,7 +148,7 @@ if(!CanContractDisease(D)) return FALSE - AddDisease(D, respect_carrier) + D.infect(src, respect_carrier) return TRUE /mob/living/carbon/human/CanContractDisease(datum/disease/D) diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index c42ff2665d..7b2922155e 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -44,6 +44,14 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease)) End() return ..() +/datum/disease/proc/infect(var/mob/living/infectee, make_copy = TRUE) + var/datum/disease/D = make_copy ? Copy() : src + infectee.addDisease(D) + D.affected_mob = infectee + GLOB.active_diseases += D + + log_admin("[key_name(src)] has contracted the virus \"[D]\"") + /datum/disease/proc/stage_act() if(!affected_mob) return FALSE diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 2bb672a23b..0b088cb74f 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -58,6 +58,8 @@ GLOBAL_LIST_INIT(advance_cures, list( /datum/disease/advance/stage_act() if(!..()) return FALSE + if(global_flag_check(virus_modifiers, DORMANT)) + return FALSE if(symptoms && length(symptoms)) if(!s_processing) @@ -92,6 +94,8 @@ GLOBAL_LIST_INIT(advance_cures, list( QDEL_LIST(A.symptoms) for(var/datum/symptom/S as anything in symptoms) A.symptoms += S.Copy() + A.virus_modifiers = virus_modifiers + A.spread_flags = spread_flags A.disease_flags = disease_flags A.resistance = resistance A.stealth = stealth @@ -213,7 +217,7 @@ GLOBAL_LIST_INIT(advance_cures, list( /datum/disease/advance/proc/AssignProperties() - if(stealth >= 2) + if(global_flag_check(virus_modifiers, DORMANT) || stealth >= 2) visibility_flags |= HIDDEN_SCANNER else visibility_flags &= ~HIDDEN_SCANNER @@ -226,16 +230,23 @@ GLOBAL_LIST_INIT(advance_cures, list( GenerateCure() /datum/disease/advance/proc/SetSpread() - switch(transmission) - if(-INFINITY to 5) - spread_flags = DISEASE_SPREAD_BLOOD - spread_text = "Blood" - if(6 to 10) - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS - spread_text = "Fluids" - if(11 to INFINITY) - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS | DISEASE_SPREAD_CONTACT - spread_text = "On Contact" + if(global_flag_check(virus_modifiers, FALTERED)) + spread_flags = DISEASE_SPREAD_FALTERED + spread_text = "Intentional Injection" + if(global_flag_check(virus_modifiers, DORMANT)) + spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS + spread_text = "None" + else + switch(transmission) + if(-INFINITY to 5) + spread_flags = DISEASE_SPREAD_BLOOD + spread_text = "Blood" + if(6 to 10) + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS + spread_text = "Fluids" + if(11 to INFINITY) + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS | DISEASE_SPREAD_CONTACT + spread_text = "On Contact" /datum/disease/advance/proc/SetSeverity(level_sev) @@ -299,6 +310,15 @@ GLOBAL_LIST_INIT(advance_cures, list( NeuterSymptom(s) Refresh(TRUE) +// Falter the disease, making it non-spreadable. +/datum/disease/advance/proc/Falter() + if(global_flag_check(virus_modifiers, FALTERED)) + return + else + virus_modifiers |= FALTERED + spread_flags = DISEASE_SPREAD_BLOOD + spread_text = "Intentional Injection" + // Name the disease. /datum/disease/advance/proc/AssignName(new_name = "Unknown") Refresh() @@ -378,6 +398,7 @@ GLOBAL_LIST_INIT(advance_cures, list( // Should be only 1 entry left, but if not let's only return a single entry var/datum/disease/advance/to_return = pick(diseases) + to_return.disease_flags &= ~DORMANT to_return.Refresh(new_name = TRUE) return to_return @@ -448,3 +469,11 @@ GLOBAL_LIST_INIT(advance_cures, list( log_admin("[key_name_admin(src)] infected [key_name_admin(H)] with [D.name]. It has these symptoms: [english_list(name_symptoms)]") return TRUE + +/datum/disease/advance/infect(var/mob/living/infectee, make_copy = TRUE) + var/datum/disease/advance/A = make_copy ? Copy() : src + infectee.addDisease(A) + A.affected_mob = infectee + GLOB.active_diseases += A + + log_admin("[key_name(src)] has contracted the virus \"[A]\"") diff --git a/code/datums/diseases/advance/disease_preset.dm b/code/datums/diseases/advance/disease_preset.dm index 0478603009..3c03ef81af 100644 --- a/code/datums/diseases/advance/disease_preset.dm +++ b/code/datums/diseases/advance/disease_preset.dm @@ -35,6 +35,32 @@ symptoms += new guaranteed_symptom Finalize() +/mob/living/carbon/human/proc/give_random_dormant_disease(biohazard = 25, min_symptoms = 2, max_symptoms = 4, min_level = 4, max_level = 9, list/guaranteed_symptoms = list()) + . = FALSE + var/sickrisk = 1 + + if(isSynthetic() || species.virus_immune || HAS_TRAIT(src, STRONG_IMMUNITY_TRAIT)) // Don't bother + return + + switch(get_species()) + if(SPECIES_UNATHI, SPECIES_TAJARAN) // Mice devourers + sickrisk = 0.5 + if(SPECIES_XENOCHIMERA) + // Ronoake Syndrome will go here :) + return + if(SPECIES_PROMETHEAN) // Too clean + return + + if(prob(min(100, (biohazard * sickrisk)))) + var/symptom_amt = rand(min_symptoms, max_symptoms) + var/datum/disease/advance/dormant_disease = new /datum/disease/advance/random(symptom_amt, max_level, min_level, guaranteed_symptoms) + dormant_disease.virus_modifiers |= DORMANT + dormant_disease.spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS + dormant_disease.spread_text = "None" + dormant_disease.visibility_flags |= HIDDEN_SCANNER + ForceContractDisease(dormant_disease, TRUE) + return TRUE + /datum/disease/advance/random/macrophage setsymptom = /datum/symptom/macrophage diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm index 440bbc7340..e0ef528eef 100644 --- a/code/datums/diseases/advance/symptoms/cough.dm +++ b/code/datums/diseases/advance/symptoms/cough.dm @@ -32,10 +32,10 @@ BONUS threshold_descs = list( "Resistance 3" = "Host will drop small items when coughing.", - "Resistance 10" = "Occasonally causes coughing fits that stun the host.", + "Resistance 10" = "Occasionally causes coughing fits that stun the host.", "Stage Speed 6" = "Increases cough frequency", "Stealth 4" = "The symptom remains hidden until active.", - "Transmission 11" = "The hosts coughing will occasonally spread the virus." + "Transmission 11" = "The hosts coughing will occasionally spread the virus." ) /datum/symptom/cough/severityset(datum/disease/advance/A) @@ -82,5 +82,5 @@ BONUS addtimer(CALLBACK(M, TYPE_PROC_REF(/mob, emote), "cough"), 1 SECONDS) addtimer(CALLBACK(M, TYPE_PROC_REF(/mob, emote), "cough"), 3 SECONDS) addtimer(CALLBACK(M, TYPE_PROC_REF(/mob, emote), "cough"), 6 SECONDS) - if(infective && prob(50)) + if(infective && !(A.spread_flags & DISEASE_SPREAD_FALTERED) && prob(50)) addtimer(CALLBACK(A, TYPE_PROC_REF(/datum/disease, spread), 2), 20) diff --git a/code/datums/diseases/advance/symptoms/fire.dm b/code/datums/diseases/advance/symptoms/fire.dm index abb9a24f25..0896422a90 100644 --- a/code/datums/diseases/advance/symptoms/fire.dm +++ b/code/datums/diseases/advance/symptoms/fire.dm @@ -74,13 +74,13 @@ Bonus /datum/symptom/fire/proc/Firestacks_stage_4(mob/living/M, datum/disease/advance/A) M.adjust_fire_stacks(1 * power) M.take_overall_damage(burn = 2 * power) - if(infective) + if(infective && !(A.spread_flags & DISEASE_SPREAD_FALTERED)) M.visible_message(span_danger("[M] bursts into flames, spreading burning sparks about the area!")) return TRUE /datum/symptom/fire/proc/Firestacks_stage_5(mob/living/M, datum/disease/advance/A) M.adjust_fire_stacks(3 * power) M.take_overall_damage(burn = 5 * power) - if(infective) + if(infective && !(A.spread_flags & DISEASE_SPREAD_FALTERED)) M.visible_message(span_danger("[M] bursts into flames, spreading burning sparks about the area!")) return TRUE diff --git a/code/datums/diseases/advance/symptoms/macrophage.dm b/code/datums/diseases/advance/symptoms/macrophage.dm index 77ccb5d2e8..f5ea92b790 100644 --- a/code/datums/diseases/advance/symptoms/macrophage.dm +++ b/code/datums/diseases/advance/symptoms/macrophage.dm @@ -91,7 +91,7 @@ BONUS if(A.transmission >= 12) for(var/datum/disease/D in M.GetViruses()) - if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_CONTACT)) + if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_CONTACT) || (D.spread_flags & DISEASE_SPREAD_FALTERED)) continue if(D == A) continue diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm index 5c9d681206..2ab63957c9 100644 --- a/code/datums/diseases/advance/symptoms/sneeze.dm +++ b/code/datums/diseases/advance/symptoms/sneeze.dm @@ -53,7 +53,7 @@ Bonus M.emote("sniff") else M.emote("sneeze") - if(infective) + if(infective && !(A.spread_flags & DISEASE_SPREAD_FALTERED)) addtimer(CALLBACK(A, TYPE_PROC_REF(/datum/disease, spread), 4), 20) /* diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index b22e8e8d77..adf62dd5f8 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -70,6 +70,8 @@ VAR_PROTECTED/exclusive_mail_goodies = FALSE // If this job's mail goodies compete with generic goodies. VAR_PROTECTED/mail_color = "#FFF" + var/list/symptoms // A list of symptoms that this job might have when we roll a dormant diseas. + /datum/job/New() . = ..() department_accounts = department_accounts || departments_managed diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index de4f38e087..da02cc495a 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -461,9 +461,10 @@ var/global/datum/controller/occupations/job_master // Stick their fingerprints on literally everything job.apply_fingerprints(H) - // Only non-silicons get post-job-equip equipment + // Only non-silicons get post-job-equip equipment and dormant diseases if(!(job.mob_type & JOB_SILICON)) H.equip_post_job() + H.give_random_dormant_disease(guaranteed_symptoms = job.symptoms) // If some custom items could not be equipped before, try again now. for(var/thing in custom_equip_leftovers) diff --git a/code/game/objects/items/devices/extrapolator.dm b/code/game/objects/items/devices/extrapolator.dm index 3aecfab6ce..59bc9f1b8c 100644 --- a/code/game/objects/items/devices/extrapolator.dm +++ b/code/game/objects/items/devices/extrapolator.dm @@ -162,7 +162,9 @@ var/list/properties if(global_flag_check(advance_disease.virus_modifiers, CARRIER)) LAZYADD(properties, "carrier") - message += "[advance_disease.name][LAZYLEN(properties) ? " ([properties.Join(", ")])" : ""], stage [advance_disease.stage]/5" + if(global_flag_check(advance_disease.virus_modifiers, FALTERED)) + LAZYADD(properties, "faltered") + message += span_info("[advance_disease.name][LAZYLEN(properties) ? " ([properties.Join(", ")])" : ""], [global_flag_check(advance_disease.virus_modifiers, DORMANT) ? "dormant virus" : "stage [advance_disease.stage]/5"]") if(extracted_ids[advance_disease.GetDiseaseID()]) message += "This virus has been extracted by \the [src] previously." message += "[advance_disease.name] has the following symptoms:" @@ -234,23 +236,21 @@ /obj/item/extrapolator/proc/create_culture(mob/living/user, datum/disease/advance/disease) . = FALSE - var/datum/disease/advance/D = disease.Copy() + disease = disease.Copy() + disease.virus_modifiers &= ~DORMANT var/list/data = list("viruses" = list(disease)) if(user.get_active_hand() != src) to_chat(user, span_warning("The extrapolator must be held in your active hand to work!")) return var/obj/item/reagent_containers/glass/beaker/vial/culture_bottle = new(user.drop_location()) - culture_bottle.name = "[D.name] culture bottle" - culture_bottle.desc = "A small bottle. Contains [D.agent] culture in synthblood medium." + culture_bottle.name = "[disease.name] culture bottle" + culture_bottle.desc = "A small bottle. Contains [disease.agent] culture in synthblood medium." culture_bottle.reagents.add_reagent(REAGENT_ID_BLOOD, 5, data) user.put_in_hands(culture_bottle) playsound(src, 'sound/machines/ping.ogg', vol = 30, vary = TRUE) COOLDOWN_START(src, usage_cooldown, 1 SECONDS) - extracted_ids[D.GetDiseaseID()] = TRUE + extracted_ids[disease.GetDiseaseID()] = TRUE return TRUE -/obj/item/extrapolator/tier4 - default_scanning_module = /obj/item/stock_parts/scanning_module/hyper - /obj/item/extrapolator/tier5 default_scanning_module = /obj/item/stock_parts/scanning_module/omni diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index e66059ae9c..2b3bf4d875 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -134,6 +134,21 @@ icon_state = "syringe" starts_with = list(/obj/item/reagent_containers/syringe = 7) +/obj/item/storage/box/old_syringes + name = "box of syringes" + desc = "A box full of syringes. They look old." + icon_state = "syringe" + starts_with = list(/obj/item/reagent_containers/syringe/old = 2) // Old syringes guaranteed in each box! + +/obj/item/storage/box/old_syringes/Initialize(mapload) + var/syringe + for(var/i in 1 to 8) + if(prob(25)) + continue + syringe = pick(subtypesof(/obj/item/reagent_containers/syringe)) + new syringe(src) + . = ..() + /obj/item/storage/box/syringegun name = "box of syringe gun cartridges" desc = "A box full of compressed gas cartridges." diff --git a/code/game/objects/random/maintenance.dm b/code/game/objects/random/maintenance.dm index 25c7393fff..91aad93139 100644 --- a/code/game/objects/random/maintenance.dm +++ b/code/game/objects/random/maintenance.dm @@ -199,6 +199,7 @@ something, make sure it's not in one of the other lists.*/ prob(3);/obj/item/storage/box/beakers, prob(2);/obj/item/storage/box/bodybags, prob(3);/obj/item/storage/box/syringes, + prob(3);/obj/item/storage/box/old_syringes, prob(3);/obj/item/storage/box/gloves, prob(2);/obj/item/storage/belt/medical/emt, prob(2);/obj/item/storage/belt/medical, diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index de1fa84390..662f864300 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -102,7 +102,7 @@ return FALSE if(H.GetViruses()) for(var/datum/disease/D in H.GetSpreadableViruses()) - if(D.danger == DISEASE_POSITIVE || D.danger == DISEASE_BENEFICIAL) + if(D.danger == DISEASE_POSITIVE || D.danger == DISEASE_BENEFICIAL || D.disease_flags & DORMANT || D.spread_flags & DISEASE_SPREAD_FALTERED) continue return FALSE return TRUE diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index e2b8e37c69..616d2b78d6 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -218,7 +218,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/pda, /obj/item/radio/headset, /obj/item/paicard, - /obj/item/reagent_containers/hypospray/autoinjector/biginjector/glucose + /obj/item/reagent_containers/hypospray/autoinjector/biginjector/glucose, + /obj/item/reagent_containers/syringe/old ) uncommon_loot = list( @@ -276,7 +277,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/poster/custom, /obj/item/newspaper, /obj/item/paper/crumpled, - /obj/item/paper/crumpled/bloody + /obj/item/paper/crumpled/bloody, + /obj/item/reagent_containers/syringe/old ) uncommon_loot = list( @@ -323,7 +325,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/storage/box/smokes, /obj/item/storage/box/metalfoam, /obj/item/storage/box/handcuffs, - /obj/item/storage/box/seccarts + /obj/item/storage/box/seccarts, + /obj/item/storage/box/old_syringes, ) rare_loot = list( diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm index fbec657561..34d79de63e 100644 --- a/code/game/objects/structures/trash_pile_vr.dm +++ b/code/game/objects/structures/trash_pile_vr.dm @@ -306,6 +306,7 @@ prob(3);/obj/item/clothing/accessory/knuckledusters, prob(3);/obj/item/clothing/gloves/heavy_engineer, prob(3);/obj/item/reagent_containers/syringe/drugs, + prob(3);/obj/item/reagent_containers/syringe/old, prob(2);/obj/item/implanter/sizecontrol, prob(2);/obj/item/handcuffs/fuzzy, prob(2);/obj/item/handcuffs/legcuffs/fuzzy, diff --git a/code/modules/mob/living/carbon/human/species/station/traits/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits/neutral.dm index bb53567a64..34dc8b6e33 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits/neutral.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits/neutral.dm @@ -1714,3 +1714,26 @@ cost = 0 hidden = FALSE //Disabled on Virgo // CHOMPEdit added_component_path = /datum/component/nutrition_size_change/shrinking + +/datum/trait/neutral/disease_carrier + name = "Disease Carrier" + desc = "Your species is a carrier of diseases! Watch out for virologists." + excludes = list(/datum/trait/neutral/strongimmunesystem) + cost = 0 + can_take = ORGANICS + custom_only = FALSE + +/datum/trait/neutral/disease_carrier/apply(datum/species/S, mob/living/carbon/human/H, trait_prefs) + ..() + H.give_random_dormant_disease(200, 2, 3, 1, 9) + +/datum/trait/neutral/strongimmunesystem + name = "Strong Immune System" + desc = "Your immune system is so strong, that not even dormant diseases can survive in you." + cost = 0 + + can_take = ORGANICS + +/datum/trait/neutral/strongimmunesystem/apply(datum/species/S, mob/living/carbon/human/H, trait_prefs) + ..() + ADD_TRAIT(H, STRONG_IMMUNITY_TRAIT, ROUNDSTART_TRAIT) diff --git a/code/modules/mob/living/carbon/human/species/station/traits/positive.dm b/code/modules/mob/living/carbon/human/species/station/traits/positive.dm index 06c0bae7e2..c0327ec089 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits/positive.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits/positive.dm @@ -492,3 +492,11 @@ desc = "Allows you to build a cocoon around yourself, using it to transform your body if you desire." cost = 0 category = 0 + +/datum/trait/positive/virus_immune + name = "Virus Immune" + desc = "You are immune to viruses." + cost = 1 + + can_take = ORGANICS + var_changes = list("virus_immune" = TRUE) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm index 0b58f2e72c..d0649cf76b 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm @@ -96,7 +96,7 @@ if (body_color == "black") holder_type = /obj/item/holder/mouse/black - if(prob(25)) + if(prob(40)) LAZYINITLIST(rat_diseases) rat_diseases += new /datum/disease/advance/random(rand(1, 5), 9, 1) diff --git a/code/modules/reagents/reactions/instant/virology.dm b/code/modules/reagents/reactions/instant/virology.dm index de517a456c..aa9e82431d 100644 --- a/code/modules/reagents/reactions/instant/virology.dm +++ b/code/modules/reagents/reactions/instant/virology.dm @@ -40,9 +40,37 @@ required_reagents = list(REAGENT_ID_INAPROVALINE = 1, REAGENT_ID_MUTAGENVIRUSFOOD = 1) result_amount = 2 +/decl/chemical_reaction/instant/virus_food_uranium + name = REAGENT_URANIUMVIRUSFOOD + id = REAGENT_ID_URANIUMVIRUSFOOD + result = REAGENT_ID_URANIUMVIRUSFOOD + required_reagents = list(REAGENT_ID_URANIUM = 1, REAGENT_ID_VIRUSFOOD = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/virus_food_uranium_unstable + name = REAGENT_UNSTABLEURANIUMVIRUSFOOD + id = REAGENT_ID_UNSTABLEURANIUMVIRUSFOOD + result = REAGENT_ID_UNSTABLEURANIUMVIRUSFOOD + required_reagents = list(REAGENT_ID_URANIUM = 1, REAGENT_ID_PHORONVIRUSFOOD = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/virus_food_uranium_stable + name = REAGENT_STABLEURANIUMVIRUSFOOD + id = REAGENT_ID_STABLEURANIUMVIRUSFOOD + result = REAGENT_ID_STABLEURANIUMVIRUSFOOD + required_reagents = list(REAGENT_ID_PHORON = 5, REAGENT_ID_URANIUM = 5, REAGENT_ID_SILVER = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/virus_food_uranium_stable_alt + name = REAGENT_STABLEURANIUMVIRUSFOOD_ALT + id = REAGENT_ID_STABLEURANIUMVIRUSFOOD_ALT + result = REAGENT_ID_STABLEURANIUMVIRUSFOOD + required_reagents = list(REAGENT_ID_PHORON = 5, REAGENT_ID_URANIUM = 5, REAGENT_ID_GOLD = 5) + result_amount = 1 + /decl/chemical_reaction/instant/virus_food_size name = REAGENT_SIZEVIRUSFOOD - id = "sizeoxadonevirusfood" + id = REAGENT_ID_SIZEVIRUSFOOD result = REAGENT_ID_SIZEVIRUSFOOD required_reagents = list(REAGENT_ID_SIZEOXADONE = 1, REAGENT_ID_PHORONVIRUSFOOD = 1) result_amount = 2 @@ -129,6 +157,27 @@ level_min = 1 level_max = 1 +/decl/chemical_reaction/instant/mix_virus/mix_virus_10 + name = "Mix Virus 10" + id = "mixvirus10" + required_reagents = list(REAGENT_ID_URANIUMVIRUSFOOD = 1) + level_min = 6 + level_max = 7 + +/decl/chemical_reaction/instant/mix_virus/mix_virus_11 + name = "Mix Virus 11" + id = "mixvirus11" + required_reagents = list(REAGENT_ID_UNSTABLEURANIUMVIRUSFOOD = 1) + level_min = 7 + level_max = 7 + +/decl/chemical_reaction/instant/mix_virus/mix_virus_12 + name = "Mix Virus 12" + id = "mixvirus12" + required_reagents = list(REAGENT_ID_STABLEURANIUMVIRUSFOOD = 1) + level_min = 8 + level_max = 8 + /decl/chemical_reaction/instant/mix_virus/picky/size name = "Mix Virus Size" id = "mixvirussize" @@ -172,3 +221,16 @@ var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"] if(D) D.Neuter() + +/decl/chemical_reaction/instant/falter_virus + name = "Falter Virus" + id = "faltervirus" + required_reagents = list(REAGENT_ID_SPACEACILLIN = 1) + catalysts = list(REAGENT_ID_BLOOD = 1) + +/decl/chemical_reaction/instant/falter_virus/on_reaction(var/datum/reagents/holder) + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list + if(B && B.data) + var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"] + if(D) + D.Falter() diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index e1a0d9d632..59c17ae82b 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -38,7 +38,6 @@ drop_sound = 'sound/items/drop/glass.ogg' pickup_sound = 'sound/items/pickup/glass.ogg' - /obj/item/reagent_containers/syringe/Initialize(mapload) . = ..() update_icon() @@ -496,6 +495,17 @@ icon_state = "[rounded_vol]" item_state = "syringe_[rounded_vol]" +/obj/item/reagent_containers/syringe/old + name = "old syringe" + desc = "An old, broken syringe. Are you sure it's a good idea to pick it up without gloves?" + mode = SYRINGE_BROKEN + +/obj/item/reagent_containers/syringe/old/Initialize(mapload) + . = ..() + if(prob(75)) + var/datum/disease/advance/new_disease = new /datum/disease/advance/random(rand(1, 3), rand(7, 9), 2) + src.viruses += new_disease + #undef SYRINGE_DRAW #undef SYRINGE_INJECT #undef SYRINGE_BROKEN diff --git a/code/modules/reagents/reagents/virology.dm b/code/modules/reagents/reagents/virology.dm index a4f3471ff8..a90b3a414f 100644 --- a/code/modules/reagents/reagents/virology.dm +++ b/code/modules/reagents/reagents/virology.dm @@ -48,6 +48,23 @@ description = "Mutates viruses when mixed in blood. This one seems to have been weakened, but still strong." color = "#CEC3C6" +/datum/reagent/uranium/uraniumvirusfood + name = REAGENT_URANIUMVIRUSFOOD + id = REAGENT_ID_URANIUMVIRUSFOOD + description = "Mutates viruses when mixed in blood. This one seems to glow lightly." + color = "#D18AA5" + +/datum/reagent/uranium/uraniumvirusfood/unstable + name = REAGENT_UNSTABLEURANIUMVIRUSFOOD + id = REAGENT_ID_UNSTABLEURANIUMVIRUSFOOD + description = "Mutates viruses when mixed in blood. This one seems be lightly warm." + color = "#D18AA5" + +/datum/reagent/uranium/uraniumvirusfood/stable + name = REAGENT_STABLEURANIUMVIRUSFOOD + id = REAGENT_ID_STABLEURANIUMVIRUSFOOD + description = "Mutates viruses when mixed in blood. This one seems to be stable." + /datum/reagent/toxin/phoron/phoronvirusfood/sizevirusfood name = REAGENT_SIZEVIRUSFOOD id = REAGENT_ID_SIZEVIRUSFOOD