[MIRROR] Virology Update #2 (#9884)

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-01-15 23:18:05 +01:00
committed by GitHub
co-authored by Cameron Lennox Kashargul
parent 3d9a3ed2dc
commit 7e30dc5335
25 changed files with 455 additions and 82 deletions
+2 -8
View File
@@ -36,6 +36,7 @@
/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
active_diseases += DD
@@ -83,14 +84,7 @@
if(nutrition > 300 && prob(nutrition/50))
return
var/list/zone_weights = list(
1 = head_ch,
2 = body_ch,
3 = hands_ch,
4 = feet_ch
)
var/target_zone = pick(zone_weights)
var/target_zone = pick(head_ch;1,body_ch;2,hands_ch;3,feet_ch;4)
if(ishuman(src))
var/mob/living/carbon/human/H = src
+24
View File
@@ -42,6 +42,7 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
var/allow_dead = FALSE
var/infect_synthetics = FALSE
var/processing = FALSE
var/has_timer = FALSE
/datum/disease/Destroy()
affected_mob = null
@@ -147,6 +148,23 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
remove_virus()
qdel(src)
/datum/disease/proc/start_cure_timer()
if(has_timer)
return
if(!(disease_flags & CURABLE))
return
has_timer = TRUE
addtimer(CALLBACK(src, PROC_REF(check_natural_immunity)), (1 HOUR) + rand( -20 MINUTES, 30 MINUTES), TIMER_DELETE_ME)
/datum/disease/proc/check_natural_immunity()
if(!(disease_flags & CURABLE))
return
if(prob(rand(10, 15)))
has_timer = FALSE
cure()
return
addtimer(CALLBACK(src, PROC_REF(check_natural_immunity)), rand(5 MINUTES, 10 MINUTES), TIMER_DELETE_ME)
/datum/disease/proc/IsSame(datum/disease/D)
if(ispath(D))
return istype(src, D)
@@ -173,8 +191,14 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
/datum/disease/proc/remove_virus()
affected_mob.viruses -= src
// Called when a disease is added onto a mob
/datum/disease/proc/Start()
return
// Called when a disease is removed from a mob
/datum/disease/proc/End()
return
// Called when the mob dies
/datum/disease/proc/OnDeath()
return
+14 -4
View File
@@ -1,10 +1,19 @@
GLOBAL_LIST_EMPTY(archive_diseases)
GLOBAL_LIST_INIT(advance_cures, list(
REAGENT_ID_SODIUMCHLORIDE, REAGENT_ID_SUGAR, REAGENT_ID_ORANGEJUICE,
REAGENT_ID_SPACEACILLIN, REAGENT_ID_GLUCOSE, REAGENT_ID_ETHANOL,
REAGENT_ID_LEPORAZINE, REAGENT_ID_IMPEDREZENE, REAGENT_ID_HEPANEPHRODAXON,
REAGENT_ID_SILVER, REAGENT_ID_GOLD
REAGENT_ID_SPACEACILLIN,
REAGENT_ID_ORANGEJUICE,
REAGENT_ID_ETHANOL,
REAGENT_ID_GLUCOSE,
REAGENT_ID_COPPER,
REAGENT_ID_LEAD,
REAGENT_ID_LITHIUM,
REAGENT_ID_RADIUM,
REAGENT_ID_MERCURY,
REAGENT_ID_BLISS,
REAGENT_ID_MUTAGEN,
REAGENT_ID_PHORON,
REAGENT_ID_SACID
))
/datum/disease/advance
@@ -13,6 +22,7 @@ GLOBAL_LIST_INIT(advance_cures, list(
form = "Advance Disease"
agent = "advance microbes"
max_stages = 5
disease_flags = CAN_NOT_POPULATE
spread_text = "Unknown"
viable_mobtypes = list(/mob/living/carbon/human)
@@ -1,3 +1,49 @@
/datum/disease/advance/random
name = "Experimental Disease"
var/randomname = TRUE
var/datum/symptom/setsymptom = null
var/max_symptoms_override
/datum/disease/advance/random/minor
name = "Minor Experimental Disease"
max_symptoms_override = 4
/datum/disease/advance/random/New(max_symptoms, max_level = 6, min_level = 1, list/guaranteed_symptoms = setsymptom)
if(!max_symptoms)
max_symptoms = (2 + rand(1, (VIRUS_SYMPTOM_LIMIT - 2)))
if(max_symptoms_override)
max_symptoms = (max_symptoms_override - rand(0, 2))
if(guaranteed_symptoms)
if(islist(guaranteed_symptoms))
max_symptoms -= length(guaranteed_symptoms)
else
guaranteed_symptoms = list(guaranteed_symptoms)
max_symptoms -= 1
var/list/datum/symptom/possible_symptoms = list()
for(var/datum/symptom/symptom as anything in subtypesof(/datum/symptom))
if(symptom in guaranteed_symptoms)
continue
if(initial(symptom.level) > max_level || initial(symptom.level) < min_level)
continue
if(initial(symptom.level) <= -1)
continue
possible_symptoms += symptom
for(var/i in 1 to max_symptoms)
var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms)
if(chosen_symptom)
symptoms += new chosen_symptom
for(var/guaranteed_symptom in guaranteed_symptoms)
symptoms += new guaranteed_symptom
/datum/disease/advance/random/macrophage
name = "Unknown Disease"
setsymptom = /datum/symptom/macrophage
/datum/disease/advance/random/blob
name = "Blob Spores"
setsymptom = /datum/symptom/blobspores
// Cold
/datum/disease/advance/cold/New(process = 1, datum/disease/advance/D, copy = 0)
@@ -14,3 +60,19 @@
name = "Flu"
symptoms = list(new /datum/symptom/cough)
..(process, D, copy)
// Macrophages
/datum/disease/advance/macrophage/New(process = 1, datum/disease/advance/D, copy = 0)
if(!D)
name = "Macrophages"
symptoms = list(new /datum/symptom/macrophage)
..(process, D, copy)
// Blob Spores
/datum/disease/advance/blobspores/New(process = 1, datum/disease/advance/D, copy = 0)
if(!D)
name = "Blob Spores"
symptoms = list(new /datum/symptom/blobspores)
..(process, D, copy)
@@ -0,0 +1,93 @@
/*
//////////////////////////////////////
Blob Spores
Slightly hidden
Major Increases to resistance.
Reduces stage speed.
Slight boost to transmission
Admin Level.
BONUS
The host coughs up blob spores
//////////////////////////////////////
*/
/datum/symptom/blobspores
name = "Blob Spores"
stealth = 1
resistance = 5
stage_speed = -2
transmittable = 1
level = -1
severity = 3
var/ready_to_pop
var/factory_blob
var/strong_blob
var/node_blob
/datum/symptom/blobspores/Start(datum/disease/advance/A)
if(!..())
return
if(A.totalResistance() >= 8)
factory_blob = TRUE
if(A.totalResistance() >= 5)
strong_blob = TRUE
if(A.totalResistance() >= 10)
node_blob = TRUE
/datum/symptom/blobspores/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1)
if(prob(2))
to_chat(M, span_notice("You feel bloated."))
if(prob(3) && !M.jitteriness)
to_chat(M, span_notice("You feel a bit jittery."))
M.jitteriness = 10
if(2)
if(prob(1) && ishuman(M))
var/mob/living/carbon/human/H = M
H.vomit(TRUE, FALSE)
if(3, 4)
if(prob(10))
to_chat(M, span_notice("You feel blobby?"))
if(5)
ready_to_pop = TRUE
if(prob(5))
M.audible_emote("coughs up a small amount of blood!")
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/bleeding_rng = rand(1, 2)
H.drip(bleeding_rng)
/datum/symptom/blobspores/OnDeath(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
M.visible_message(span_danger("[M] starts swelling grotesquely!"))
addtimer(CALLBACK(src, PROC_REF(pop), A, M), 10 SECONDS)
/datum/symptom/blobspores/proc/pop(datum/disease/advance/A, mob/living/M)
if(!A || !M)
return
var/list/blob_options = list(/obj/structure/blob/normal)
if(factory_blob)
blob_options += /obj/structure/blob/factory
if(strong_blob)
blob_options += /obj/structure/blob/shield
if(node_blob)
blob_options += /obj/structure/blob/node
var/pick_blob = pick(blob_options)
if(ready_to_pop)
for(var/i in 1 to rand(1, 6))
new /mob/living/simple_mob/blob/spore(M.loc)
new pick_blob(M.loc)
M.visible_message(span_danger("A huge mass of blob and blob spores burst out of [M]!"))
@@ -27,10 +27,10 @@ Bonus
/datum/symptom/shivering/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
to_chat(M, span_warning(pick("You feel cold.", "You start shivering.")))
if(M.bodytemperature > BODYTEMP_COLD_DAMAGE_LIMIT)
Chill(M, A)
var/mob/living/L = A.affected_mob
to_chat(L, span_warning(pick("You feel cold.", "You start shivering.")))
if(L.bodytemperature > BODYTEMP_COLD_DAMAGE_LIMIT)
Chill(L, A)
return
/datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A)
+11 -12
View File
@@ -87,34 +87,33 @@ Bonus
return
/datum/symptom/sneeze/bluespace/proc/SneezeTeleport(datum/disease/advance/A, var/mob/living/M)
/datum/symptom/sneeze/bluespace/proc/SneezeTeleport(datum/disease/advance/A, var/mob/living/mob)
var/list/destination = list()
var/mob/living/carbon/human/H = M
var/place
for(var/mob/living/carbon/human/B in range(A.stage, M))
if(B.can_be_drop_pred && H.can_be_drop_prey && H.devourable)
for(var/mob/living/carbon/human/B in range(A.stage, mob))
if(B.can_be_drop_pred && mob.can_be_drop_prey && mob.devourable)
destination += B.vore_selected
for(var/turf/T in range(A.stage, H))
for(var/turf/T in range(A.stage, mob))
if(istype(T, /turf/space)) // No danger, this is just a fun/vore symptom
continue
destination += T
if(isemptylist(destination))
to_chat(H, span_warning("You go to sneeze, but can't."))
to_chat(mob, span_warning("You go to sneeze, but can't."))
return FALSE
place = safepick(destination)
var/mob/living/carbon/human/unlucky = locate() in place
var/mob/living/unlucky = locate() in place
if(unlucky && !unlucky.is_incorporeal()) // CHOMPEdit
if(unlucky.can_be_drop_pred && H.can_be_drop_prey && H.devourable)
if(unlucky.can_be_drop_pred && mob.can_be_drop_prey && mob.devourable)
place = unlucky.vore_selected
else if(unlucky.devourable && unlucky.can_be_drop_prey && H.can_be_drop_pred)
unlucky.forceMove(H.vore_selected)
else if(unlucky.devourable && unlucky.can_be_drop_prey && mob.can_be_drop_pred)
unlucky.forceMove(mob.vore_selected)
H.emote("sneeze")
do_teleport(H, place)
mob.emote("sneeze")
do_teleport(mob, place)
return TRUE
@@ -36,7 +36,7 @@ Bonus
if(3, 4)
L.jitteriness += 10
else
if(L.reagents.get_reagent_amount(REAGENT_ID_HYPERZINE < 10))
if(L.reagents.get_reagent_amount(REAGENT_ID_HYPERZINE) < 10)
L.reagents.add_reagent(REAGENT_ID_HYPERZINE, 5)
if(prob(30))
L.jitteriness += 15
@@ -32,5 +32,10 @@ GLOBAL_LIST_INIT(list_symptoms, subtypesof(/datum/symptom))
/datum/symptom/proc/End(datum/disease/advance/A)
return
// Called when the disease activates. It's what makes your diseases work!
/datum/symptom/proc/Activate(datum/disease/advance/A)
return
// Called when the host dies
/datum/symptom/proc/OnDeath(datum/disease/advance/A)
return
@@ -25,13 +25,15 @@ Bonus
severity = 0
/datum/symptom/telepathy/Start(datum/disease/advance/A)
var/mob/living/carbon/human/H = A.affected_mob
H.dna.SetSEState(REMOTETALKBLOCK, 1)
domutcheck(H, null, TRUE)
to_chat(H, span_notice("Your mind expands..."))
if(iscarbon(A))
var/mob/living/carbon/human/H = A.affected_mob
H.dna.SetSEState(REMOTETALKBLOCK, 1)
domutcheck(H, null, TRUE)
to_chat(H, span_notice("Your mind expands..."))
/datum/symptom/telepathy/End(datum/disease/advance/A)
var/mob/living/carbon/human/H = A.affected_mob
H.dna.SetSEState(REMOTETALKBLOCK, 0)
domutcheck(H, null, TRUE)
to_chat(H, span_notice("Everything feels... Normal."))
if(iscarbon(A))
var/mob/living/carbon/human/H = A.affected_mob
H.dna.SetSEState(REMOTETALKBLOCK, 0)
domutcheck(H, null, TRUE)
to_chat(H, span_notice("Everything feels... Normal."))
+22 -21
View File
@@ -27,24 +27,25 @@ Bonus
/datum/symptom/visionloss/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
var/obj/item/organ/internal/eyes/eyes = M.internal_organs_by_name[O_EYES]
if(!eyes)
return
switch(A.stage)
if(1, 2)
to_chat(M, span_warning("Your eyes itch."))
if(3, 4)
to_chat(M, span_boldwarning("Your eyes burn!"))
M.eye_blurry = 20
eyes.take_damage(1)
else
to_chat(M, span_userdanger("Your eyes burn horrificly!"))
M.eye_blurry = 40
eyes.take_damage(5)
if(eyes.damage >= 10)
M.disabilities |= NEARSIGHTED
if(prob(eyes.damage - 10 + 1))
if(!M.eye_blind)
to_chat(M, span_userdanger("You go blind!"))
M.Blind(20)
if(iscarbon(A))
var/mob/living/carbon/M = A.affected_mob
var/obj/item/organ/internal/eyes/eyes = M.internal_organs_by_name[O_EYES]
if(!eyes)
return
switch(A.stage)
if(1, 2)
to_chat(M, span_warning("Your eyes itch."))
if(3, 4)
to_chat(M, span_boldwarning("Your eyes burn!"))
M.eye_blurry = 20
eyes.take_damage(1)
else
to_chat(M, span_userdanger("Your eyes burn horrificly!"))
M.eye_blurry = 40
eyes.take_damage(5)
if(eyes.damage >= 10)
M.disabilities |= NEARSIGHTED
if(prob(eyes.damage - 10 + 1))
if(!M.eye_blind)
to_chat(M, span_userdanger("You go blind!"))
M.Blind(20)
+1 -1
View File
@@ -9,7 +9,7 @@
viable_mobtypes = list(/mob/living/carbon/human)
desc = "If left untreated the subject will become very weak, and may vomit often."
severity = MINOR
disease_flags = CAN_CARRY|CAN_RESIST
disease_flags = CAN_CARRY|CAN_RESIST|CAN_NOT_POPULATE
visibility_flags = HIDDEN_PANDEMIC
required_organs = list(/obj/item/organ/internal/appendix)
bypasses_immunity = TRUE
+1 -1
View File
@@ -23,7 +23,7 @@
else if(prob(5))
affected_mob.emote("gasp")
if(prob(10))
to_chat(span_danger("You're starting to feel very weak..."))
to_chat(affected_mob, span_danger("You're starting to feel very weak..."))
if(4)
if(prob(10))
affected_mob.emote("cough")
+1 -1
View File
@@ -11,7 +11,7 @@
viable_mobtypes = list(/mob/living/carbon/human)
desc = "Nausea, sickness, and vomitting."
severity = MINOR
disease_flags = CURABLE
disease_flags = CURABLE|CAN_NOT_POPULATE
virus_heal_resistant = TRUE
/datum/disease/food_poisoning/stage_act()
+1
View File
@@ -9,6 +9,7 @@
agent = "Gravitokinetic Bipotential SADS+"
viable_mobtypes = list(/mob/living/carbon/human)
severity = BIOHAZARD
disease_flags = CAN_NOT_POPULATE
/datum/disease/gbs/stage_act()
if(!..())
+20
View File
@@ -421,6 +421,26 @@
containername = "Virology biohazard equipment"
access = access_medical_equip
/datum/supply_pack/med/disease
name = "Experimental Disease crate"
desc = "An experimental disease. Contains a multitude of symptoms."
contains = list(
/obj/item/reagent_containers/glass/bottle/culture/random_virus = 1
)
cost = 60
containertype = /obj/structure/closet/crate/freezer
access = access_medical_equip
/datum/supply_pack/med/disease_minor
name = "Minor Experimental Disease crate"
desc = "An experimental disease. Contains a weakened, untested viral culture."
contains = list(
/obj/item/reagent_containers/glass/bottle/culture/random_virus/minor = 1
)
cost = 40
containertype = /obj/structure/closet/crate/freezer
access = access_medical_equip
/datum/supply_pack/med/compactdefib
name = "Compact Defibrillator crate"
desc = "A compact defibrillator. Requires Medical Equipment access."