diff --git a/code/__defines/_lists.dm b/code/__defines/_lists.dm
index ebf923672dd..43c53308a24 100644
--- a/code/__defines/_lists.dm
+++ b/code/__defines/_lists.dm
@@ -47,3 +47,9 @@
#define reverseList(L) reverseRange(L.Copy())
#define islist(L) istype(L, /list)
+
+/// Performs an insertion on the given lazy list with the given key and value. If the value already exists, a new one will not be made.
+#define LAZYORASSOCLIST(lazy_list, key, value) \
+ LAZYINITLIST(lazy_list); \
+ LAZYINITLIST(lazy_list[key]); \
+ lazy_list[key] |= value;
diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm
index 6bdf7e73e5f..734da1990a4 100644
--- a/code/__defines/dcs/signals.dm
+++ b/code/__defines/dcs/signals.dm
@@ -185,6 +185,8 @@
#define COMSIG_ATOM_START_PULL "movable_start_pull"
///called on /living when someone starts pulling it (atom/movable/puller, state, force)
#define COMSIG_LIVING_START_PULL "living_start_pull"
+///from base atom/Exited(): (mob/user, obj/item/extrapolator/extrapolator, dry_run, list/result)
+#define COMSIG_ATOM_EXTRAPOLATOR_ACT "atom_extrapolator_act"
/////////////////
diff --git a/code/__defines/diseases.dm b/code/__defines/diseases.dm
index ac34e469b5e..3dd0d595ec3 100644
--- a/code/__defines/diseases.dm
+++ b/code/__defines/diseases.dm
@@ -1,3 +1,4 @@
+#define DISEASE_LIMIT 1
#define VIRUS_SYMPTOM_LIMIT 6
//Visibility Flags
@@ -11,20 +12,44 @@
#define CAN_NOT_POPULATE (1<<3)
//Spread Flags
-#define SPECIAL (1<<0)
-#define NON_CONTAGIOUS (1<<1)
-#define BLOOD (1<<2)
-#define CONTACT_FEET (1<<3)
-#define CONTACT_HANDS (1<<4)
-#define CONTACT_GENERAL (1<<5)
-#define AIRBORNE (1<<6)
+#define DISEASE_SPREAD_SPECIAL (1<<0)
+#define DISEASE_SPREAD_NON_CONTAGIOUS (1<<1)
+#define DISEASE_SPREAD_BLOOD (1<<2)
+#define DISEASE_SPREAD_FLUIDS (1<<3)
+#define DISEASE_SPREAD_CONTACT (1<<4)
+#define DISEASE_SPREAD_AIRBORNE (1<<5)
//Severity Defines
-#define NONTHREAT "No threat"
-#define MINOR "Minor"
-#define MEDIUM "Medium"
-#define HARMFUL "Harmful"
-#define DANGEROUS "Dangerous!"
-#define BIOHAZARD "BIOHAZARD THREAT!"
+#define DISEASE_BENEFICIAL "Beneficial"
+#define DISEASE_POSITIVE "Positive"
+#define DISEASE_NONTHREAT "No threat"
+#define DISEASE_MINOR "Minor"
+#define DISEASE_MEDIUM "Medium"
+#define DISEASE_HARMFUL "Harmful"
+#define DISEASE_DANGEROUS "Dangerous"
+#define DISEASE_BIOHAZARD "BIOHAZARD"
+#define DISEASE_PANDEMIC "PANDEMIC"
-#define SYMPTOM_ACTIVATION_PROB 3
+//Various Virus Flags
+#define NEEDS_ALL_CURES 0x1 /// If a virus requires EVERY cure in the cure list to become cured.
+#define SPREAD_DEAD 0x2 /// If a virus spreads to the dead and proceesses in them.
+#define INFECT_SYNTHETICS 0x4 /// If a synthetic can be infected with the virus.
+#define HAS_TIMER 0x8 /// If the cure timer is currently active.
+#define PROCESSING 0x10 /// If stage_act has been called and we are now processing.
+#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 EXTRAPOLATOR_RESULT_DISEASES "extrapolator_result_disease"
+#define EXTRAPOLATOR_RESULT_ACT_PRIORITY "extrapolator_result_action_priority"
+#define EXTRAPOLATOR_ACT_PRIORITY_SPECIAL "extrapolator_action_priority_special"
+#define EXTRAPOLATOR_ACT_PRIORITY_ISOLATE "extrapolator_action_priority_isolate"
+#define EXTRAPOLATOR_ACT_ADD_DISEASES(target_list, diseases)\
+ do {\
+ var/_D = ##diseases;\
+ if ((islist(_D) && length(_D)) || istype(_D, /datum/disease)) { \
+ LAZYORASSOCLIST(##target_list, EXTRAPOLATOR_RESULT_DISEASES, _D);\
+ }\
+ } while(0)
+#define EXTRAPOLATOR_ACT_CHECK(target_list, wanted_action_priority) (##target_list[EXTRAPOLATOR_RESULT_ACT_PRIORITY] == ##wanted_action_priority)
+#define EXTRAPOLATOR_ACT_SET(target_list, wanted_action_priority) (##target_list[EXTRAPOLATOR_RESULT_ACT_PRIORITY] = ##wanted_action_priority)
diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index b7c61460170..41b0dcc70e2 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -527,3 +527,10 @@
// Default name for accesories
#define DEVELOPER_WARNING_NAME "you should not see this..."
+
+// Green vomit
+#define VOMIT_TOXIC 1
+// Purple vomit
+#define VOMIT_PURPLE 2
+// Nanite vomit
+#define VOMIT_NANITE 3
diff --git a/code/controllers/subsystems/supply.dm b/code/controllers/subsystems/supply.dm
index a7610dea59c..69984d25d93 100644
--- a/code/controllers/subsystems/supply.dm
+++ b/code/controllers/subsystems/supply.dm
@@ -119,8 +119,8 @@ SUBSYSTEM_DEF(supply)
EC.contents[EC.contents.len]["quantity"] = cashmoney.worth
EC.value += EC.contents[EC.contents.len]["value"]
- if(istype(A, /obj/item/reagent_containers/glass/bottle/vaccine))
- var/obj/item/reagent_containers/glass/bottle/vaccine/sale_bottle = A
+ if(istype(A, /obj/item/reagent_containers/glass/beaker/vial/vaccine))
+ var/obj/item/reagent_containers/glass/beaker/vial/vaccine/sale_bottle = A
if(!istype(CR, /obj/structure/closet/crate/freezer))
EC.contents = list(
"error" = "Error: Product was improperly packaged. Send conents in freezer crate to preserve contents for transport."
diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm
index e40326a8707..0ba6e5dc91b 100644
--- a/code/datums/diseases/_MobProcs.dm
+++ b/code/datums/diseases/_MobProcs.dm
@@ -5,8 +5,22 @@
return TRUE
return FALSE
+/mob/proc/RemoveDisease(datum/disease/D)
+ viruses -= D
+ return TRUE
+
+/mob/proc/HasResistance(resistance)
+ if(resistances.Find(resistance))
+ return TRUE
+ return FALSE
+
+/mob/proc/IsInfected()
+ if(isemptylist(GetViruses()))
+ return FALSE
+ return TRUE
+
/mob/proc/CanContractDisease(datum/disease/D)
- if(stat == DEAD && !D.allow_dead)
+ if(stat == DEAD && !global_flag_check(D.virus_modifiers, SPREAD_DEAD))
return FALSE
if(D.GetDiseaseID() in GetResistances())
@@ -18,17 +32,22 @@
if(istype(D, /datum/disease/advance) && count_by_type(GetViruses(), /datum/disease/advance) > 0)
return FALSE
- if(!(type in D.viable_mobtypes))
- return -1
+ var/compatible_type = FALSE
+ for(var/type_to_test in D.viable_mobtypes)
+ if(ispath(type, type_to_test))
+ compatible_type = TRUE
+ break
+ if(!compatible_type)
+ return FALSE
if(isSynthetic())
- if(D.infect_synthetics)
+ if(global_flag_check(D.virus_modifiers, INFECT_SYNTHETICS))
return TRUE
return FALSE
return TRUE
-/mob/proc/ContractDisease(datum/disease/D)
+/mob/proc/ContractDisease(datum/disease/D, var/target_zone)
if(!CanContractDisease(D))
return 0
AddDisease(D)
@@ -41,7 +60,7 @@
DD.affected_mob = src
GLOB.active_diseases += DD
- var/list/skipped = list("affected_mob", "holder", "carrier", "stage", "type", "parent_type", "vars", "transformed")
+ 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)
@@ -49,35 +68,24 @@
continue
if(istype(DD.vars[V],/list))
var/list/L = D.vars[V]
- if(L)
+ 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/ContractDisease(datum/disease/D)
+/mob/living/carbon/human/ContractDisease(datum/disease/D, target_zone)
if(!CanContractDisease(D))
- return 0
+ return FALSE
var/obj/item/clothing/Cl = null
- var/passed = 1
+ var/passed = TRUE
- 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
+ var/head_chance = 80
+ var/body_chance = 100
+ var/hands_chance = 35/2
+ var/feet_chance = 15/2
if(prob(15/D.permeability_mod))
return
@@ -85,27 +93,37 @@
if(nutrition > 300 && prob(nutrition/50))
return
- var/target_zone = pick(head_ch;1,body_ch;2,hands_ch;3,feet_ch;4)
+ if(!target_zone)
+ target_zone = pick(list(
+ BP_HEAD = head_chance,
+ BP_TORSO = body_chance,
+ BP_R_HAND = hands_chance,
+ BP_L_HAND = hands_chance,
+ BP_R_FOOT = feet_chance,
+ BP_L_FOOT = feet_chance
+ ))
+ else
+ target_zone = check_zone(target_zone)
if(ishuman(src))
var/mob/living/carbon/human/H = src
switch(target_zone)
- if(1)
+ if(BP_HEAD)
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(BP_TORSO)
if(isobj(H.wear_suit))
Cl = H.wear_suit
passed = prob((Cl.permeability_coefficient*100) - 1)
if(passed && isobj(H.w_uniform))
Cl = H.w_uniform
passed = prob((Cl.permeability_coefficient*100) - 1)
- if(3)
+ if(BP_L_HAND, BP_R_HAND)
if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered & HANDS)
Cl = H.wear_suit
passed = prob((Cl.permeability_coefficient*100) - 1)
@@ -113,7 +131,7 @@
if(passed && isobj(H.gloves))
Cl = H.gloves
passed = prob((Cl.permeability_coefficient*100) - 1)
- if(4)
+ if(BP_L_FOOT, BP_R_FOOT)
if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered & FEET)
Cl = H.wear_suit
passed = prob((Cl.permeability_coefficient*100) - 1)
@@ -121,12 +139,20 @@
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)
AddDisease(D)
- return passed
+
+/mob/living/proc/AirborneContractDisease(datum/disease/D, force_spread)
+ if(((D.spread_flags & DISEASE_SPREAD_AIRBORNE) || force_spread) && prob(50*D.spreading_modifier) - 1)
+ ForceContractDisease(D)
+
+/mob/living/carbon/AirborneContractDisease(datum/disease/D, force_spread)
+ if(internal)
+ return
+ if(mNobreath in mutations)
+ return
+ ..()
/mob/proc/ForceContractDisease(datum/disease/D, respect_carrier)
if(!CanContractDisease(D))
@@ -136,22 +162,25 @@
return TRUE
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
- if(species.virus_immune && !D.bypasses_immunity)
- return FALSE
-
for(var/organ in D.required_organs)
- if(locate(organ) in internal_organs)
- continue
- if(locate(organ) in organs)
- continue
- return FALSE
+ if(!((locate(organ) in organs) || (locate(organ) in internal_organs)))
+ return FALSE
+
+ if(species.virus_immune && !global_flag_check(D.virus_modifiers, BYPASSES_IMMUNITY))
+ D.virus_modifiers |= CARRIER
+ else
+ D.virus_modifiers &= ~CARRIER
+
return ..()
/mob/living/carbon/human/monkey/CanContractDisease(datum/disease/D)
. = ..()
if(. == -1)
if(D.viable_mobtypes.Find(/mob/living/carbon/human))
- return 1
+ return
+
+/mob/living/proc/CanSpreadAirborneDisease()
+ return !is_mouth_covered()
/mob/living/proc/handle_diseases()
return
@@ -160,10 +189,24 @@
LAZYINITLIST(viruses)
return viruses
+/mob/proc/GetSpreadableViruses()
+ LAZYINITLIST(viruses)
+ var/list/viruses_to_return = list()
+ for(var/datum/disease/D in viruses)
+ if(D.spread_flags & (DISEASE_SPREAD_SPECIAL | DISEASE_SPREAD_NON_CONTAGIOUS))
+ continue
+ viruses_to_return += D
+ return viruses_to_return
+
/mob/proc/GetResistances()
LAZYINITLIST(resistances)
return resistances
+/mob/proc/AddResistances(resistance)
+ LAZYINITLIST(resistances)
+ resistances |= resistance
+ return TRUE
+
/client/proc/ReleaseVirus()
set category = "Fun.Event Kit"
set name = "Release Virus"
@@ -173,17 +216,24 @@
return FALSE
var/disease = tgui_input_list(usr, "Choose virus", "Viruses", subtypesof(/datum/disease), subtypesof(/datum/disease))
+
+ if(isnull(disease))
+ return FALSE
+
var/mob/living/carbon/human/H = tgui_input_list(usr, "Choose infectee", "Characters", human_mob_list)
- var/datum/disease/D = new disease
-
- if(isnull(D) || isnull(H))
+ if(isnull(H))
return FALSE
+ var/datum/disease/D = new disease
+
if(!H.HasDisease(D))
H.ForceContractDisease(D)
message_admins("[key_name_admin(usr)] has triggered a virus outbreak of [D.name]! Affected mob: [key_name_admin(H)]")
log_admin("[key_name_admin(usr)] infected [key_name_admin(H)] with [D.name]")
+ if(!GLOB.archive_diseases[D.GetDiseaseID()])
+ GLOB.archive_diseases[D.GetDiseaseID()] = D
+
return TRUE
diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm
index 43993056b50..c42ff2665d5 100644
--- a/code/datums/diseases/_disease.dm
+++ b/code/datums/diseases/_disease.dm
@@ -4,7 +4,8 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
//Flags
var/visibility_flags = 0
var/disease_flags = CURABLE|CAN_CARRY|CAN_RESIST
- var/spread_flags = AIRBORNE
+ var/spread_flags = DISEASE_SPREAD_AIRBORNE
+ var/virus_modifiers = NEEDS_ALL_CURES
//Fluff
/// Used for identification of viruses in the Medical Records Virus Database
@@ -20,34 +21,26 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
var/stage = 1
var/max_stages = 0
var/stage_prob = 4
+
/// The fraction of stages the virus must at least be at to show up on medical HUDs. Rounded up.
var/discovery_threshold = 0.5
- /// If TRUE, this virus will show up on medical HUDs. Automatically set when it reaches mid-stage.
- var/discovered = FALSE
// Other
var/list/viable_mobtypes = list()
var/mob/living/carbon/affected_mob
var/list/cures = list()
- var/infectivity = 65
+ var/infectivity = 10
var/cure_chance = 8
- var/carrier = FALSE
- var/bypasses_immunity = FALSE
- var/virus_heal_resistant = FALSE
+ var/spreading_modifier = 1
var/permeability_mod = 1
- var/severity = NONTHREAT
+ var/danger = DISEASE_MINOR
var/list/required_organs = list()
- var/needs_all_cures = TRUE
var/list/strain_data = list()
- var/allow_dead = FALSE
- var/infect_synthetics = FALSE
- var/processing = FALSE
- var/has_timer = FALSE
/datum/disease/Destroy()
affected_mob = null
GLOB.active_diseases.Remove(src)
- if(processing)
+ if(global_flag_check(virus_modifiers, PROCESSING))
End()
return ..()
@@ -56,11 +49,11 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
return FALSE
var/cure = has_cure()
- if(carrier && !cure)
+ if(global_flag_check(virus_modifiers, CARRIER) && !cure)
return FALSE
- if(!processing)
- processing = TRUE
+ if(!global_flag_check(virus_modifiers, PROCESSING))
+ virus_modifiers |= PROCESSING
Start()
stage = min(stage, max_stages)
@@ -72,8 +65,8 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
/datum/disease/proc/handle_stage_advance(has_cure = FALSE)
if(!has_cure && prob(stage_prob))
stage = min(stage + 1, max_stages)
- if(!discovered && stage >= CEILING(max_stages * discovery_threshold, 1))
- discovered = TRUE
+ if(!global_flag_check(virus_modifiers, DISCOVERED) && stage >= CEILING(max_stages * discovery_threshold, 1))
+ virus_modifiers |= DISCOVERED
/datum/disease/proc/handle_cure_testing(has_cure = FALSE)
if(has_cure && prob(cure_chance))
@@ -102,29 +95,32 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
if(affected_mob.bloodstr.has_reagent(C_id) || affected_mob.ingested.has_reagent(C_id))
cures_found++
- if(needs_all_cures && cures_found < length(cures))
+ if(global_flag_check(virus_modifiers, NEEDS_ALL_CURES) && cures_found < length(cures))
return FALSE
return cures_found
-/datum/disease/proc/spread(force_spread = 0)
+/datum/disease/proc/spread(var/force_spread = 0)
if(!affected_mob)
return
if(affected_mob.is_incorporeal())
return
- if((spread_flags & SPECIAL || spread_flags & NON_CONTAGIOUS || spread_flags & BLOOD) && !force_spread)
+ if(!(spread_flags & DISEASE_SPREAD_AIRBORNE) && !force_spread)
return
- if(affected_mob.bloodstr.has_reagent(REAGENT_ID_SPACEACILLIN) || (affected_mob.nutrition > 300 && prob(affected_mob.nutrition/50)))
+ if(affected_mob.stat == DEAD && !global_flag_check(virus_modifiers, SPREAD_DEAD) && !force_spread)
return
- var/spread_range = 1
+ if(affected_mob.reagents.has_reagent(REAGENT_ID_SPACEACILLIN) || (affected_mob.nutrition > 300 && prob(affected_mob.nutrition/50)))
+ return
+
+ var/spread_range = 2
if(force_spread)
spread_range = force_spread
- if(spread_flags & AIRBORNE)
+ if(spread_flags & DISEASE_SPREAD_AIRBORNE)
spread_range++
var/turf/target = affected_mob.loc
@@ -133,38 +129,41 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
if(C.is_incorporeal())
continue
var/turf/current = get_turf(C)
- if(current)
- while(TRUE)
- if(current == target)
- C.ContractDisease(src)
- break
- var/direction = get_dir(current, target)
- var/turf/next = get_step(current, direction)
- if(!current.CanZASPass(next))
- break
- current = next
+ if(disease_air_spread_walk(target, current))
+ C.AirborneContractDisease(src, force_spread)
+
+/proc/disease_air_spread_walk(turf/start, turf/end)
+ if(!start || !end)
+ return FALSE
+ while(TRUE)
+ if(end == start)
+ return TRUE
+ var/turf/Temp = get_step_towards(end, start)
+ if(!end.CanZASPass(Temp))
+ return FALSE
+ end = Temp
/datum/disease/proc/cure()
if(affected_mob)
if(disease_flags & CAN_RESIST)
if(!(type in affected_mob.GetResistances()))
- affected_mob.resistances += type
+ affected_mob.AddResistances(type)
remove_virus()
qdel(src)
/datum/disease/proc/start_cure_timer()
- if(has_timer)
+ if(global_flag_check(virus_modifiers, HAS_TIMER))
return
if(!(disease_flags & CURABLE))
return
- has_timer = TRUE
+ virus_modifiers |= HAS_TIMER
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
+ virus_modifiers &= ~HAS_TIMER
cure()
return
addtimer(CALLBACK(src, PROC_REF(check_natural_immunity)), rand(5 MINUTES, 10 MINUTES), TIMER_DELETE_ME)
@@ -180,20 +179,30 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease))
return D
/datum/disease/proc/GetDiseaseID()
- return type
+ return
+
+/datum/disease/proc/IsSpreadByBlood()
+ if(spread_flags & DISEASE_SPREAD_BLOOD)
+ return TRUE
+ return FALSE
+
+/datum/disease/proc/IsSpreadByFluids()
+ if(spread_flags & DISEASE_SPREAD_FLUIDS)
+ return TRUE
+ return FALSE
/datum/disease/proc/IsSpreadByTouch()
- if(spread_flags & CONTACT_FEET || spread_flags & CONTACT_HANDS || spread_flags & CONTACT_GENERAL)
+ if(spread_flags & DISEASE_SPREAD_CONTACT)
return TRUE
return FALSE
/datum/disease/proc/IsSpreadByAir()
- if(spread_flags & AIRBORNE)
+ if(spread_flags & DISEASE_SPREAD_AIRBORNE)
return TRUE
return FALSE
/datum/disease/proc/remove_virus()
- affected_mob.viruses -= src
+ affected_mob.RemoveDisease(src)
// Called when a disease is added onto a mob
/datum/disease/proc/Start()
diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm
index 56c2135a6ee..c8b71354921 100644
--- a/code/datums/diseases/advance/advance.dm
+++ b/code/datums/diseases/advance/advance.dm
@@ -26,22 +26,25 @@ GLOBAL_LIST_INIT(advance_cures, list(
spread_text = "Unknown"
viable_mobtypes = list(/mob/living/carbon/human)
- var/s_processing = FALSE
+ var/last_modified_by = "no CKEY"
+ var/resistance
+ var/stealth
+ var/stage_rate
+ var/transmission
+ var/severity
+ var/speed
var/list/symptoms = list()
+
+ var/s_processing = FALSE
var/id = ""
-/datum/disease/advance/New(process = 1, datum/disease/advance/D)
- if(!istype(D))
+/datum/disease/advance/New(process = TRUE, datum/disease/advance/D)
+ if(istype(D))
+ for(var/datum/symptom/S in D.symptoms)
+ symptoms += new S.type
+ else
D = null
- if(!symptoms || !length(symptoms))
-
- if(!D || !D.symptoms || !length(D.symptoms))
- symptoms = GenerateSymptoms(0, 2)
- else
- for(var/datum/symptom/S in D.symptoms)
- symptoms += new S.type
-
Refresh()
..(process, D)
return
@@ -80,7 +83,7 @@ GLOBAL_LIST_INIT(advance_cures, list(
return TRUE
-/datum/disease/advance/cure(resistance=1)
+/datum/disease/advance/cure(resistance = TRUE)
if(affected_mob)
var/id = "[GetDiseaseID()]"
if(resistance && !(id in affected_mob.GetResistances()))
@@ -150,8 +153,8 @@ GLOBAL_LIST_INIT(advance_cures, list(
return generated
/datum/disease/advance/proc/Refresh(new_name = FALSE, archive = FALSE)
- var/list/properties = GenerateProperties()
- AssignProperties(properties)
+ GenerateProperties()
+ AssignProperties()
id = null
if(!GLOB.archive_diseases[GetDiseaseID()])
@@ -160,82 +163,92 @@ GLOBAL_LIST_INIT(advance_cures, list(
GLOB.archive_diseases[GetDiseaseID()] = src // So we don't infinite loop
GLOB.archive_diseases[GetDiseaseID()] = new /datum/disease/advance(0, src, 1)
- var/datum/disease/advance/A = GLOB.archive_diseases[GetDiseaseID()]
- AssignName(A.name)
-
/datum/disease/advance/proc/GenerateProperties()
+ resistance = 0
+ stealth = 0
+ stage_rate = 0
+ transmission = 0
+ severity = 0
- if(!symptoms || !length(symptoms))
- CRASH("We did not have any symptoms before generating properties.")
+ var/c1sev
+ var/c2sev
+ var/c3sev
- var/list/properties = list("resistance" = 1, "stealth" = 0, "stage rate" = 1, "transmittable" = 1, "severity" = 0)
+ for(var/datum/symptom/S as() in symptoms)
+ resistance = S.resistance
+ stealth += S.stealth
+ stage_rate += S.stage_speed
+ transmission += S.transmission
+ for(var/datum/symptom/S as() in symptoms)
+ S.severityset(src)
+ switch(S.severity)
+ if(-INFINITY to 0)
+ c1sev += S.severity
+ if(1 to 2)
+ c2sev = max(c2sev, min(3, (S.severity + c2sev)))
+ if(3 to 4)
+ c2sev = max(c2sev, min(4, (S.severity + c2sev)))
+ if(5 to INFINITY)
+ if(c3sev >= 5)
+ c3sev += (S.severity -3)
+ else
+ c3sev += S.severity
- for(var/datum/symptom/S in symptoms)
+ severity += (max(c2sev, c3sev) + c1sev)
- properties["resistance"] += S.resistance
- properties["stealth"] += S.stealth
- properties["stage rate"] += S.stage_speed
- properties["transmittable"] += S.transmittable
- properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity symptom
+/datum/disease/advance/proc/AssignProperties()
- return properties
-
-/datum/disease/advance/proc/AssignProperties(list/properties = list())
-
- if(properties && length(properties))
- switch(properties["stealth"])
- if(2)
- visibility_flags = HIDDEN_SCANNER
- if(3 to INFINITY)
- visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC
-
- // The more symptoms we have, the less transmittable it is but some symptoms can make up for it.
- SetSpread(clamp(2 ** (properties["transmittable"] - length(symptoms)), BLOOD, AIRBORNE))
- permeability_mod = max(CEILING(0.4 * properties["transmittable"], 1), 1)
- cure_chance = 15 - clamp(properties["resistance"], -5, 5) // can be between 10 and 20
- stage_prob = max(properties["stage rate"], 2)
- SetSeverity(properties["severity"])
- GenerateCure(properties)
+ if(stealth >= 2)
+ visibility_flags |= HIDDEN_SCANNER
else
- CRASH("Our properties were empty or null!")
+ visibility_flags &= ~HIDDEN_SCANNER
-/datum/disease/advance/proc/SetSpread(spread_id)
- switch(spread_id)
- if(NON_CONTAGIOUS, SPECIAL)
- spread_text = "Non-contagious"
- if(CONTACT_GENERAL, CONTACT_HANDS, CONTACT_FEET)
- spread_text = "On contact"
- if(AIRBORNE)
- spread_text = "Airborne"
- if(BLOOD)
+ SetSpread()
+ permeability_mod = max(CEILING(0.4 * transmission, 1), 1)
+ cure_chance = 15 - clamp(resistance, -5, 5) // can be between 10 and 20
+ stage_prob = max(stage_rate, 2)
+ SetSeverity(severity)
+ GenerateCure()
+
+/datum/disease/advance/proc/SetSpread()
+ switch(transmission)
+ if(-INFINITY to 5)
+ spread_flags = DISEASE_SPREAD_BLOOD
spread_text = "Blood"
-
- spread_flags = spread_id
+ 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)
switch(level_sev)
- if(-INFINITY to 0)
- severity = NONTHREAT
+ if(-INFINITY to -2)
+ severity = DISEASE_BENEFICIAL
+ if(-1)
+ severity = DISEASE_POSITIVE
+ if(0)
+ severity = DISEASE_NONTHREAT
if(1)
- severity = MINOR
+ severity = DISEASE_MINOR
if(2)
- severity = MEDIUM
+ severity = DISEASE_MEDIUM
if(3)
- severity = HARMFUL
+ severity = DISEASE_HARMFUL
if(4)
- severity = DANGEROUS
+ severity = DISEASE_DANGEROUS
if(5 to INFINITY)
- severity = BIOHAZARD
+ severity = DISEASE_BIOHAZARD
else
severity = "Unknown"
-/datum/disease/advance/proc/GenerateCure(list/properties = list())
- if(properties && length(properties))
- var/res = clamp(properties["resistance"] - (length(symptoms) / 2), 1, length(GLOB.advance_cures))
- cures = list(GLOB.advance_cures[res])
- cure_text = cures[1]
+/datum/disease/advance/proc/GenerateCure()
+ var/res = clamp(resistance - (length(symptoms) / 2), 1, length(GLOB.advance_cures))
+ cures = list(GLOB.advance_cures[res])
+ cure_text = cures[1]
return
// Randomly generate a symptom, has a chance to lose or gain a symptom.
@@ -243,14 +256,15 @@ GLOBAL_LIST_INIT(advance_cures, list(
var/s = safepick(GenerateSymptoms(min_level, max_level, 1))
if(s)
AddSymptom(s)
- Refresh(1)
+ Refresh(TRUE)
return
+// Randomly generates a symptom from a given list, has a chance to lose or gain a symptom.
/datum/disease/advance/proc/PickyEvolve(var/list/datum/symptom/D)
var/s = safepick(D)
if(s)
AddSymptom(new s)
- Refresh(1)
+ Refresh(TRUE)
return
// Randomly remove a symptom.
@@ -259,12 +273,20 @@ GLOBAL_LIST_INIT(advance_cures, list(
var/s = safepick(symptoms)
if(s)
RemoveSymptom(s)
- Refresh(1)
+ Refresh(TRUE)
return
+// Randomly neuter a symptom.
+/datum/disease/advance/proc/Neuter()
+ if(symptoms.len)
+ var/s = safepick(symptoms)
+ if(s)
+ NeuterSymptom(s)
+ Refresh(TRUE)
+
// Name the disease.
-/datum/disease/advance/proc/AssignName(name = "Unknown")
- src.name = name
+/datum/disease/advance/proc/AssignName(new_name = "Unknown")
+ name = new_name
return
// Return a unique ID of the disease.
@@ -278,6 +300,10 @@ GLOBAL_LIST_INIT(advance_cures, list(
id = result
return id
+/datum/disease/advance/proc/Finalize()
+ for(var/datum/symptom/S in symptoms)
+ S.OnAdd(src)
+
// Add a symptom, if it is over the limit (with a small chance to be able to go over)
// we take a random symptom away and add the new one.
/datum/disease/advance/proc/AddSymptom(datum/symptom/S)
@@ -297,6 +323,13 @@ GLOBAL_LIST_INIT(advance_cures, list(
symptoms -= S
return
+// Neuters a symptom, allowing it only for stats.
+/datum/disease/advance/proc/NeuterSymptom(datum/symptom/S)
+ if(!S.neutered)
+ S.neutered = TRUE
+ S.name += " (neutered)"
+ S.OnRemove(src)
+
// Mix a list of advance diseases and return the mixed result.
/proc/Advance_Mix(list/D_list)
@@ -324,7 +357,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.Refresh(1)
+ to_return.Refresh(new_name = TRUE)
return to_return
/proc/SetViruses(datum/reagent/R, list/data)
@@ -342,7 +375,7 @@ GLOBAL_LIST_INIT(advance_cures, list(
set name = "Create Advanced Virus"
set desc = "Create an advanced virus and release it."
- if(!is_admin())
+ if(!is_admin(usr))
return FALSE
var/i = VIRUS_SYMPTOM_LIMIT
@@ -355,8 +388,8 @@ GLOBAL_LIST_INIT(advance_cures, list(
symptoms += "Done"
symptoms += GLOB.list_symptoms.Copy()
do
- if(usr)
- var/symptom = tgui_input_list(usr, "Choose a symptom to add ([i] remaining)", "Choose a Symptom", symptoms)
+ if(src)
+ var/symptom = tgui_input_list(src, "Choose a symptom to add ([i] remaining)", "Choose a Symptom", symptoms)
if(isnull(symptom))
return
else if(istext(symptom))
@@ -370,16 +403,16 @@ GLOBAL_LIST_INIT(advance_cures, list(
if(length(D.symptoms) > 0)
- var/new_name = tgui_input_text(usr, "Name your new disease.", "New Name")
+ var/new_name = tgui_input_text(src, "Name your new disease.", "New Name")
if(!new_name)
return FALSE
- D.AssignName(new_name)
- D.Refresh()
+ D.Refresh(new_name)
+ D.Finalize()
for(var/datum/disease/advance/AD in GLOB.active_diseases)
AD.Refresh()
- H = tgui_input_list(usr, "Choose infectee", "Infectees", human_mob_list)
+ H = tgui_input_list(src, "Choose infectee", "Infectees", human_mob_list)
if(isnull(H))
return FALSE
@@ -390,35 +423,7 @@ GLOBAL_LIST_INIT(advance_cures, list(
var/list/name_symptoms = list()
for(var/datum/symptom/S in D.symptoms)
name_symptoms += S.name
- message_admins("[key_name_admin(usr)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]")
- log_admin("[key_name_admin(usr)] infected [key_name_admin(H)] with [D.name]. It has these symptoms: [english_list(name_symptoms)]")
+ message_admins("[key_name_admin(src)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]")
+ 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/proc/totalStageSpeed()
- var/total_stage_speed = 0
- for(var/i in symptoms)
- var/datum/symptom/S = i
- total_stage_speed += S.stage_speed
- return total_stage_speed
-
-/datum/disease/advance/proc/totalStealth()
- var/total_stealth = 0
- for(var/i in symptoms)
- var/datum/symptom/S = i
- total_stealth += S.stealth
- return total_stealth
-
-/datum/disease/advance/proc/totalResistance()
- var/total_resistance = 0
- for(var/i in symptoms)
- var/datum/symptom/S = i
- total_resistance += S.resistance
- return total_resistance
-
-/datum/disease/advance/proc/totalTransmittable()
- var/total_transmittable = 0
- for(var/i in symptoms)
- var/datum/symptom/S = i
- total_transmittable += S.transmittable
- return total_transmittable
diff --git a/code/datums/diseases/advance/disease_preset.dm b/code/datums/diseases/advance/disease_preset.dm
index d23f4ddcbc4..597d5a5dd52 100644
--- a/code/datums/diseases/advance/disease_preset.dm
+++ b/code/datums/diseases/advance/disease_preset.dm
@@ -1,11 +1,9 @@
/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)
@@ -35,9 +33,10 @@
symptoms += new chosen_symptom
for(var/guaranteed_symptom in guaranteed_symptoms)
symptoms += new guaranteed_symptom
+ Finalize()
+ Refresh()
/datum/disease/advance/random/macrophage
- name = "Unknown Disease"
setsymptom = /datum/symptom/macrophage
/datum/disease/advance/random/blob
diff --git a/code/datums/diseases/advance/symptoms/blobspores.dm b/code/datums/diseases/advance/symptoms/blobspores.dm
index 8c8ef33d620..29887dfc1e4 100644
--- a/code/datums/diseases/advance/symptoms/blobspores.dm
+++ b/code/datums/diseases/advance/symptoms/blobspores.dm
@@ -15,27 +15,42 @@ BONUS
*/
/datum/symptom/blobspores
name = "Blob Spores"
+ desc = "This symptom causes the host to produce blob spores, which will leave the host at the later stages, and if the host dies, all of the spores will erupt from the host at the same time, while also producing a blob tile."
stealth = 1
- resistance = 5
+ resistance = 6
stage_speed = -2
- transmittable = 1
- level = -1
+ transmission = 1
+ level = 9
severity = 3
+ naturally_occuring = FALSE
+ symptom_delay_min = 20 SECONDS
+ symptom_delay_max = 40 SECONDS
+
+ threshold_descs = list(
+ "Resistance 8" = "Spawns a strong blob instead of a normal blob",
+ "Resistance 11" = "There is a chance to spawn a factory blob, instead of a normal blob.",
+ "Resistance 14" = "Has a chance to spawn a blob node instead of a normal blob"
+ )
var/ready_to_pop
var/factory_blob
var/strong_blob
var/node_blob
+/datum/symptom/blobspores/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.resistance >= 14)
+ severity += 1
+
/datum/symptom/blobspores/Start(datum/disease/advance/A)
if(!..())
return
- if(A.totalResistance() >= 8)
+ if(A.resistance >= 11)
factory_blob = TRUE
- if(A.totalResistance() >= 5)
+ if(A.resistance >= 8)
strong_blob = TRUE
- if(A.totalResistance() >= 10)
+ if(A.resistance >= 14)
node_blob = TRUE
/datum/symptom/blobspores/Activate(datum/disease/advance/A)
@@ -45,31 +60,35 @@ BONUS
switch(A.stage)
if(1)
- if(prob(2))
- to_chat(M, span_notice("You feel bloated."))
+ to_chat(M, span_notice("You feel bloated."))
- if(prob(3) && !M.jitteriness)
+ if(!M.jitteriness)
to_chat(M, span_notice("You feel a bit jittery."))
M.jitteriness = 10
if(2)
- if(prob(1) && ishuman(M))
+ if(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?"))
+ 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)
+ 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/OnStageChange(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stage == 5)
+ ready_to_pop = TRUE
/datum/symptom/blobspores/OnDeath(datum/disease/advance/A)
+ if(neutered)
+ return
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)
diff --git a/code/datums/diseases/advance/symptoms/choking.dm b/code/datums/diseases/advance/symptoms/choking.dm
index 24be1c1a153..eb3b492e494 100644
--- a/code/datums/diseases/advance/symptoms/choking.dm
+++ b/code/datums/diseases/advance/symptoms/choking.dm
@@ -16,37 +16,62 @@ Bonus
*/
/datum/symptom/choking
- name = "Choking"
- stealth = -3
- resistance = -2
- stage_speed = -2
- transmittable = -4
- level = 3
- severity = 3
+ name = "Acute Respiratory Distress Syndrome"
+ desc = "The virus causes shrinking of the host's lungs, causing severe asphyxiation."
+ stealth = -2
+ resistance = 0
+ stage_speed = -1
+ transmission = -2
+ level = 9
+ severity = 5
+ naturally_occuring = FALSE
+ base_message_chance = 15
+ symptom_delay_min = 10 SECONDS
+ symptom_delay_max = 30 SECONDS
+
+ var/paralysis = FALSE
+
+ threshold_descs = list(
+ "Transmission 8" = "Doubles the damage caused by the symptom."
+ )
+
+/datum/symptom/choking/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.transmission >= 8)
+ severity += 1
+
+/datum/symptom/choking/Start(datum/disease/advance/A)
+ if(!..())
+ return
+
+ if(A.transmission >= 8)
+ power = 2
/datum/symptom/choking/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(1, 2)
- to_chat(M, span_warning(pick("You're having difficulty breathing.", "Your breathing becomes heavy.")))
- if(3, 4)
- to_chat(M, span_boldwarning(pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")))
- Choke_stage_3_4(M, A)
- M.emote("gasp")
- else
- to_chat(M, span_userdanger(pick("You're choking!", "You can't breathe!")))
- Choke(M, A)
- M.emote("gasp")
+ if(!..())
+ return
+
+ var/mob/living/M = A.affected_mob
+ if(!M.needs_to_breathe() || M.stat == DEAD)
+ return
+
+ switch(A.stage)
+ if(3, 4)
+ to_chat(M, span_warning(pick("Your windpipe feels thin.", "Your lungs feel small-")))
+ Choke_stage_3_4(M, A)
+ M.emote("gasp")
+ if(5)
+ to_chat(M, span_userdanger(pick("Your lungs hurt!", "It hurts to breathe!")))
+ Choke(M, A)
+ M.emote("gasp")
return
/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A)
- var/get_damage = sqrtor0(21+A.totalStageSpeed()*0.5)+sqrtor0(16+A.totalStealth())
+ var/get_damage = rand(5, 10) * power
M.adjustOxyLoss(get_damage)
- return 1
+ return TRUE
/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A)
- var/get_damage = sqrtor0(21+A.totalStageSpeed()*0.5)+sqrtor0(16+A.totalStealth()*5)
+ var/get_damage = rand(2, 5) * power
M.adjustOxyLoss(get_damage)
- return 1
+ return TRUE
diff --git a/code/datums/diseases/advance/symptoms/cockroach.dm b/code/datums/diseases/advance/symptoms/cockroach.dm
new file mode 100644
index 00000000000..da7481a9f0d
--- /dev/null
+++ b/code/datums/diseases/advance/symptoms/cockroach.dm
@@ -0,0 +1,61 @@
+/datum/symptom/cockroach
+ name = "SBG Syndrome"
+ desc = "Causes bluespace synchronicity with nearby air channels, making the roaches infesting the station's scrubber crawl from the host's face."
+ stealth = 1
+ resistance = 2
+ stage_speed = 3
+ transmission = 1
+ level = 0
+ severity = 0
+ symptom_delay_min = 15 SECONDS
+ symptom_delay_max = 40 SECONDS
+
+ var/death_roaches = FALSE
+
+ threshold_descs = list(
+ "Stage Speed 8" = "Increases roach speed",
+ "Transmission 8" = "When the host dies, more roaches spawn."
+ )
+
+/datum/symptom/cockroach/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stage_rate >= 8)
+ symptom_delay_min = 5
+ symptom_delay_max = 15
+ if(A.transmission >= 8)
+ death_roaches = TRUE
+
+/datum/symptom/cockroach/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ if(M.stat == DEAD)
+ return
+ switch(A.stage)
+ if(2)
+ if(prob(base_message_chance))
+ to_chat(M, span_notice("You feel a tingle under your skin."))
+ if(3)
+ if(prob(base_message_chance))
+ to_chat(M, span_notice("Your pores feel drafty."))
+ if(prob(5))
+ to_chat(M, span_notice("You feel attuned to the atmosphere."))
+ if(4)
+ if(prob(base_message_chance))
+ to_chat(M, span_notice("You feel in tune with the station."))
+ if(5)
+ if(prob(base_message_chance))
+ M.visible_message(span_danger("[M] squirms as a cockroach crawl from their pores!"), span_userdanger("A cockroach crawls out of your face!!"))
+ new /mob/living/simple_mob/animal/passive/cockroach(M.loc)
+ if(prob(base_message_chance))
+ to_chat(M, span_notice("You feel something crawling in your pipes!"))
+
+/datum/symptom/cockroach/OnDeath(datum/disease/advance/A)
+ if(!..())
+ return
+ if(death_roaches)
+ var/mob/living/M = A.affected_mob
+ to_chat(M, span_warning("Your pores explode into a colony of roaches!"))
+ for(var/i in 1 to rand(1, 5))
+ new /mob/living/simple_mob/animal/passive/cockroach(M.loc)
diff --git a/code/datums/diseases/advance/symptoms/confusion.dm b/code/datums/diseases/advance/symptoms/confusion.dm
index dc28c109a23..1ba1d0ad74e 100644
--- a/code/datums/diseases/advance/symptoms/confusion.dm
+++ b/code/datums/diseases/advance/symptoms/confusion.dm
@@ -17,22 +17,45 @@ Bonus
/datum/symptom/confusion
name = "Confusion"
+ desc = "The virus interferes with the proper function of the neural system, leading to bouts of confusion and erratic movement."
stealth = 1
resistance = -1
stage_speed = -3
- transmittable = 0
- level = 4
+ transmission = 0
+ level = 3
severity = 2
+ base_message_chance = 25
+ symptom_delay_min = 15 SECONDS
+ symptom_delay_max = 30 SECONDS
+
+ threshold_descs = list(
+ "Transmission 6" = "Increases confusion duration.",
+ "Stealth 4" = "The symptom remains hidden until active."
+ )
+
+/datum/symptom/confusion/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.resistance >= 6)
+ severity += 1
+
+/datum/symptom/confusion/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.transmission >= 6)
+ power = 1.5
+ if(A.stealth >= 4)
+ supress_warning = TRUE
/datum/symptom/confusion/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/carbon/M = A.affected_mob
- switch(A.stage)
- if(1, 2, 3, 4)
- to_chat(M, span_warning(pick("Your head hurts.", "Your mind blanks for a moment.")))
- else
- to_chat(M, span_userdanger("You can't think straight!"))
- M.AdjustConfused(rand(16, 200))
-
- return
+ if(!..())
+ return
+ var/mob/living/L = A.affected_mob
+ if(L.stat == DEAD)
+ return
+ switch(A.stage)
+ if(1, 2, 3, 4)
+ if(prob(base_message_chance) && !supress_warning)
+ to_chat(L, span_warning(pick("Your head hurts", "Your mind blanks for a moment.")))
+ else
+ to_chat(L, span_userdanger("You can't think straight!"))
+ L.confused = min(50 * power, L.confused+8)
diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm
index cc932ab4cc9..440bbc7340e 100644
--- a/code/datums/diseases/advance/symptoms/cough.dm
+++ b/code/datums/diseases/advance/symptoms/cough.dm
@@ -17,25 +17,70 @@ BONUS
/datum/symptom/cough
name = "Cough"
+ desc = "The virus irritates the throat of the host, causing occasional coughing."
stealth = -1
resistance = 3
stage_speed = 1
- transmittable = 2
+ transmission = 2
level = 1
- severity = 1
+ severity = 0
+ base_message_chance = 15
+ symptom_delay_min = 15 SECONDS
+ symptom_delay_max = 45 SECONDS
+
+ var/infective = FALSE
+
+ threshold_descs = list(
+ "Resistance 3" = "Host will drop small items when coughing.",
+ "Resistance 10" = "Occasonally 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."
+ )
+
+/datum/symptom/cough/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.resistance >= 3)
+ severity += 1
+ if(A.resistance >= 10)
+ severity += 1
+
+/datum/symptom/cough/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stealth >= 4)
+ supress_warning = TRUE
+ if(A.resistance >= 3)
+ power = 1.5
+ if(A.resistance >= 10)
+ power = 2
+ if(A.stage_rate >= 6)
+ symptom_delay_max = 10
+ if(A.transmission >= 11)
+ infective = TRUE
/datum/symptom/cough/Activate(var/datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(1, 2, 3)
- to_chat(M, span_warning(pick("You swallow excess mucus", "You lightly cough.")))
- else
- M.emote("cough")
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ if(M.stat == DEAD)
+ return
+ switch(A.stage)
+ if(1, 2, 3)
+ if(prob(base_message_chance) && !supress_warning)
+ to_chat(M, span_warning(pick("Your throat itches.", "You lightly cough.")))
+ else
+ M.emote("cough")
+ if(power >= 1.5)
var/obj/item/I = M.get_active_hand()
- if(I && I.w_class == ITEMSIZE_SMALL)
- M.drop_item()
- if(!M.wear_mask) // Small spread if not wearing a mask
- A.spread(2)
- return
+ if(I && I.w_class == ITEMSIZE_COST_TINY)
+ M.drop_item(get_turf(M))
+ if(power >= 2 && prob(10))
+ to_chat(M, span_userdanger(pick("You have a coughing fit!", "You can't stop coughing!")))
+ M.Stun(5)
+ M.emote("cough")
+ 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))
+ addtimer(CALLBACK(A, TYPE_PROC_REF(/datum/disease, spread), 2), 20)
diff --git a/code/datums/diseases/advance/symptoms/damage_converter.dm b/code/datums/diseases/advance/symptoms/damage_converter.dm
index b47aa89a6c3..a57c407b8d7 100644
--- a/code/datums/diseases/advance/symptoms/damage_converter.dm
+++ b/code/datums/diseases/advance/symptoms/damage_converter.dm
@@ -20,7 +20,7 @@ Bonus
stealth = 1
resistance = -4
stage_speed = -4
- transmittable = -2
+ transmission = -2
level = 4
severity = 0
diff --git a/code/datums/diseases/advance/symptoms/deafness.dm b/code/datums/diseases/advance/symptoms/deafness.dm
index 21a44b2e9f4..d32bef5f04a 100644
--- a/code/datums/diseases/advance/symptoms/deafness.dm
+++ b/code/datums/diseases/advance/symptoms/deafness.dm
@@ -17,22 +17,50 @@ Bonus
/datum/symptom/deafness
name = "Deafness"
- stealth = 1
- resistance = -2
+ desc = "The virus causes inflammation of the eardrums, causing intermittent deafness."
+ stealth = -1
+ resistance = -1
stage_speed = 1
- transmittable = -3
- level = 4
- severity = 3
+ transmission = -3
+ level = 3
+ severity = 2
+ base_message_chance = 100
+ symptom_delay_min = 25 SECONDS
+ symptom_delay_max = 80 SECONDS
-/datum/symptom/deafness/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
+ threshold_descs = list(
+ "Resistance 9" = "Causes permanent hearing loss.",
+ "Stealth 4" = "The symptom remains hidden until active."
+ )
- switch(A.stage)
- if(3, 4)
- to_chat(M, span_warning("[pick("you hear a ringing in your ear.", "You ears pop.")]"))
- if(5)
- to_chat(M, span_userdanger("You ear pop and begin ringing loudly!"))
- M.ear_deaf += 20
- return
+/datum/symptom/deafness/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.resistance >= 9)
+ severity += 1
+
+/datum/symptom/deafness/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stealth >= 4)
+ supress_warning = TRUE
+ if(A.resistance >= 9)
+ power = 2
+
+/datum/symptom/deafness/Activate(var/datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/carbon/M = A.affected_mob
+ if(M.stat == DEAD)
+ return
+ switch(A.stage)
+ if(3, 4)
+ if(prob(base_message_chance) && !supress_warning)
+ to_chat(M, span_warning(pick("You hear a ringing in your ears.", "Your ears pop.")))
+ if(5)
+ if(power >= 2)
+ M.adjustEarDamage(100, 10)
+ to_chat(M, span_userdanger("Your ears pop painfully and start bleeding!"))
+ M.emote("scream")
+ else
+ to_chat(M, span_userdanger("Your ears pop and begin ringing loudly!"))
+ M.adjustEarDamage(0, 10)
diff --git a/code/datums/diseases/advance/symptoms/dizzy.dm b/code/datums/diseases/advance/symptoms/dizzy.dm
deleted file mode 100644
index 90bc8836b05..00000000000
--- a/code/datums/diseases/advance/symptoms/dizzy.dm
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-//////////////////////////////////////
-
-Dizziness
-
- Hidden.
- Lowers resistance considerably.
- Decreases stage speed.
- Reduced transmittability
- Intense Level.
-
-Bonus
- Shakes the affected mob's screen for short periods.
-
-//////////////////////////////////////
-*/
-
-/datum/symptom/dizzy
- name = "Dizziness"
- stealth = 2
- resistance = -2
- stage_speed = -3
- transmittable = -1
- level = 4
- severity = 2
-
-/datum/symptom/dizzy/Activate(var/datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(1, 2, 3, 4)
- to_chat(M, span_warning(pick("You feel dizzy.", "Your head spins.")))
- else
- to_chat(M, span_userdanger("A wave of dizziness washes over you!"))
- M.make_dizzy(10)
- return
diff --git a/code/datums/diseases/advance/symptoms/fever.dm b/code/datums/diseases/advance/symptoms/fever.dm
index 6e252e56cd9..bd3698eb54b 100644
--- a/code/datums/diseases/advance/symptoms/fever.dm
+++ b/code/datums/diseases/advance/symptoms/fever.dm
@@ -17,24 +17,54 @@ Bonus
/datum/symptom/fever
name = "Fever"
- stealth = 0
+ desc = "The virus causes a febrile response from the host, raising it's body temperature."
+ stealth = -1
resistance = 3
stage_speed = 3
- transmittable = 2
+ transmission = 2
level = 2
- severity = 2
+ severity = 0
+ base_message_chance = 20
+ symptom_delay_min = 25 SECONDS
+ symptom_delay_max = 50 SECONDS
-/datum/symptom/fever/Activate(var/datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/carbon/M = A.affected_mob
+ var/unsafe = FALSE
+
+ threshold_descs = list(
+ "Resistance 5" = "Increases fever intensity, fever can overheat and harm the host.",
+ "Resistance 10" = "Further increases fever intensity."
+ )
+
+/datum/symptom/fever/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.resistance >= 5)
+ severity += 1
+ if(A.resistance >= 10)
+ severity += 1
+
+/datum/symptom/fever/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.resistance >= 5)
+ power = 1.5
+ unsafe = TRUE
+ if(A.resistance >= 10)
+ power = 2.5
+
+/datum/symptom/fever/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/carbon/M = A.affected_mob
+ if(M.stat == DEAD)
+ return
+ if(!unsafe || A.stage < 4)
to_chat(M, span_warning(pick("You feel hot.", "You feel like you're burning.")))
- if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
- Heat(M, A)
+ else
+ to_chat(M, span_userdanger(pick("You feel too hot", "You feel like your blod is boiling.")))
+ set_body_temp(A.affected_mob, A)
- return
-
-/datum/symptom/fever/proc/Heat(var/mob/living/M, var/datum/disease/advance/A)
- var/get_heat = (sqrtor0(21+A.totalTransmittable()*2))+(sqrtor0(20+A.totalStageSpeed()*3))
- M.bodytemperature = min(M.bodytemperature + (get_heat * A.stage), BODYTEMP_HEAT_DAMAGE_LIMIT - 1)
- return TRUE
+/datum/symptom/fever/proc/set_body_temp(mob/living/M, datum/disease/advance/A)
+ if(!unsafe)
+ M.bodytemperature = min(M.bodytemperature + max((3 * power) * A.stage, (BODYTEMP_HEAT_DAMAGE_LIMIT - 1)))
+ else
+ M.bodytemperature = min(M.bodytemperature + max((3 * power) * A.stage, (BODYTEMP_HEAT_DAMAGE_LIMIT + 20)))
diff --git a/code/datums/diseases/advance/symptoms/fire.dm b/code/datums/diseases/advance/symptoms/fire.dm
index 956d778f5d5..abb9a24f25c 100644
--- a/code/datums/diseases/advance/symptoms/fire.dm
+++ b/code/datums/diseases/advance/symptoms/fire.dm
@@ -17,40 +17,70 @@ Bonus
/datum/symptom/fire
name = "Spontaneous Combustion"
+ desc = "The virus turns fat into an extremely flammable compound, and raises the body's temperature, making the host burst into flames spontaneously."
stealth = 1
- resistance = -4
- stage_speed = -4
- transmittable = -4
- level = 6
- severity = 5
+ resistance = -1
+ stage_speed = -2
+ transmission = -1
+ level = 7
+ severity = 4
+
+ base_message_chance = 20
+ symptom_delay_min = 40 SECONDS
+ symptom_delay_max = 85 SECONDS
+
+ var/infective = FALSE
+
+ threshold_descs = list(
+ "Stage Speed 4" = "Increases the intensity of the flames.",
+ "Stage Speed 8" = "Further increases the intensity of the flames.",
+ "Transmission 8" = "Host will spread the virus through skin flake when bursting into flames.",
+ "Stealth 4" = "The symptom remains hidden until active."
+ )
+
+/datum/symptom/fire/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stage_rate >= 4)
+ power = 1.5
+ if(A.stage_rate >= 8)
+ power = 2
+ if(A.stealth >= 4)
+ supress_warning = TRUE
+ if(A.transmission >= 8)
+ infective = TRUE
/datum/symptom/fire/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(3)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ switch(A.stage)
+ if(3)
+ if(prob(base_message_chance) && !supress_warning && M.stat != DEAD)
to_chat(M, span_warning(pick("You feel hot.", "You hear a crackling noise.", "You smell smoke.")))
- if(4)
- Firestacks_stage_4(M, A)
- M.IgniteMob()
- to_chat(M, span_userdanger("Your skin bursts into flames!"))
- M.emote("scream")
- if(5)
- Firestacks_stage_5(M, A)
- M.IgniteMob()
+ if(4)
+ Firestacks_stage_4(M, A)
+ M.IgniteMob()
+ to_chat(M, span_userdanger("Your skin bursts into flames!"))
+ M.emote("scream")
+ if(5)
+ Firestacks_stage_5(M, A)
+ M.IgniteMob()
+ if(M.stat != DEAD)
to_chat(M, span_userdanger("Your skin erupts into an inferno!"))
M.emote("scream")
return
/datum/symptom/fire/proc/Firestacks_stage_4(mob/living/M, datum/disease/advance/A)
- var/get_stacks = max((sqrtor0(20 + A.totalStageSpeed() * 2)) - (sqrtor0(16 + A.totalStealth())), 1)
- M.adjust_fire_stacks(get_stacks)
- M.adjustFireLoss(get_stacks * 0.5)
- return 1
+ M.adjust_fire_stacks(1 * power)
+ M.take_overall_damage(burn = 2 * power)
+ if(infective)
+ 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)
- var/get_stacks = max((sqrtor0(20 + A.totalStageSpeed() * 3))-(sqrtor0(16 + A.totalStealth())), 1)
- M.adjust_fire_stacks(get_stacks)
- M.adjustFireLoss(get_stacks)
- return 1
+ M.adjust_fire_stacks(3 * power)
+ M.take_overall_damage(burn = 5 * power)
+ if(infective)
+ 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/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm
index 00a5a273e7b..2e181a7bafb 100644
--- a/code/datums/diseases/advance/symptoms/flesh_eating.dm
+++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm
@@ -17,26 +17,57 @@ Bonus
/datum/symptom/flesh_eating
name = "Necrotizing Fasciitis"
+ desc = "The virus aggressively attacks the skin and blood, leading to extreme bleeding."
stealth = -3
- resistance = -4
+ resistance = -2
stage_speed = 0
- transmittable = -4
- level = 6
- severity = 5
+ transmission = -1
+ level = 7
+ severity = 4
+ base_message_chance = 50
+ symptom_delay_min = 20 SECONDS
+ symptom_delay_max = 60 SECONDS
+
+ var/bleed = FALSE
+ var/damage = FALSE
+
+ threshold_descs = list(
+ "Resistance 10" = "The host takes brute damage as their flesh is burst open.",
+ "Transmission 8" = "The host will bleed far more violently, loosing even more blood, and spraying infected blood everywhere."
+ )
+
+/datum/symptom/flesh_eating/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.resistance >= 10)
+ damage = TRUE
+ if(A.transmission >= 8)
+ power = 2
+ bleed = TRUE
/datum/symptom/flesh_eating/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(2,3)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ switch(A.stage)
+ if(2, 3)
+ if(prob(base_message_chance) && M.stat != DEAD)
to_chat(M, span_warning(pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")))
- if(4,5)
- to_chat(M, span_userdanger(pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")))
- Flesheat(M, A)
- return
+ if(4, 5)
+ if(M.stat != DEAD)
+ to_chat(M, span_userdanger(pick("You cringe as a violent pan takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")))
+ Flesheat(M, A)
/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
- var/get_damage = ((sqrtor0(16-A.totalStealth()))*5)
- M.adjustBruteLoss(get_damage)
- return 1
+ if(damage)
+ M.take_overall_damage(BRUTE = rand(15, 25))
+ if(ishuman(M))
+ return
+ var/mob/living/carbon/human/H = M
+ var/obj/item/organ/external/O = pick(H.organs)
+
+ if(bleed)
+ O.createwound(PIERCE, 5 * power)
+ else
+ O.createwound(BRUISE, 7.5 * power)
+ return TRUE
diff --git a/code/datums/diseases/advance/symptoms/flip.dm b/code/datums/diseases/advance/symptoms/flip.dm
index 2c9164a5365..48c01bc1f47 100644
--- a/code/datums/diseases/advance/symptoms/flip.dm
+++ b/code/datums/diseases/advance/symptoms/flip.dm
@@ -15,18 +15,20 @@ BONUS
//////////////////////////////////////
*/
-/datum/symptom/spyndrome
+/datum/symptom/flip
name = "Flippinov"
+ desc = "The virus hijacks the host's motor system, making them flip incontrollably."
stealth = 2
resistance = 0
stage_speed = 3
- transmittable = 1
+ transmission = 1
+ symptom_delay_min = 15 SECONDS
+ symptom_delay_max = 40 SECONDS
level = 1
severity = 0
-/datum/symptom/spyndrome/Activate(datum/disease/advance/A)
- ..()
-
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/L = A.affected_mob
- L.emote("flip")
+/datum/symptom/flip/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ M.emote("flip")
diff --git a/code/datums/diseases/advance/symptoms/genetics.dm b/code/datums/diseases/advance/symptoms/genetics.dm
new file mode 100644
index 00000000000..97d9082bc2a
--- /dev/null
+++ b/code/datums/diseases/advance/symptoms/genetics.dm
@@ -0,0 +1,134 @@
+/datum/symptom/genetic
+ name = "Basic Genetic Symptom (does nothing)"
+ stealth = 0
+ resistance = 0
+ stage_speed = 0
+ transmission = 0
+ level = -1
+ base_message_chance = 20
+ symptom_delay_min = 1
+ symptom_delay_max = 1
+ var/datum/gene/trait/mutation
+ var/passive_message
+ var/preset = FALSE
+
+/datum/symptom/genetic/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/carbon/human/H = A.affected_mob
+ if(mutation)
+ preset = H.dna.GetSEState(mutation.block)
+
+/datum/symptom/genetic/OnAdd(datum/disease/advance/A)
+ . = ..()
+ if(mutation && !preset)
+ var/mob/living/carbon/human/H = A.affected_mob
+ H.dna.SetSEState(mutation.block, TRUE)
+ domutcheck(H, null, TRUE)
+ H.UpdateAppearance()
+
+/datum/symptom/genetic/OnRemove(datum/disease/advance/A)
+ . = ..()
+ if(mutation && !preset)
+ var/mob/living/carbon/human/H = A.affected_mob
+ H.dna.SetSEState(mutation.block, FALSE)
+ domutcheck(H, null, TRUE)
+ H.UpdateAppearance()
+
+/datum/symptom/genetic/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/carbon/human/H = A.affected_mob
+ switch(A.stage)
+ if(4, 5)
+ if(passive_message && prob(2))
+ to_chat(H, passive_message)
+
+/*
+//////////////////////////////////////
+
+Telepathy
+
+ Hidden.
+ Decreases resistance.
+ Decreases stage speed significantly.
+ Decreases transmittablity tremendously.
+ Critical Level.
+
+Bonus
+ The user gains telepathy.
+
+//////////////////////////////////////
+*/
+
+/datum/symptom/genetic/telepathy
+ name = "Pineal Gland Decalcification"
+ stealth = 2
+ resistance = -2
+ stage_speed = -3
+ transmission = -4
+ level = 5
+ severity = 0
+
+/datum/symptom/genetic/telepathy/New()
+ . = ..()
+ mutation = get_gene_from_trait(/datum/trait/positive/superpower_remotetalk)
+
+/*
+//////////////////////////////////////
+
+Hematophagy
+
+ Little bit hidden.
+ Decreases resistance slightly.
+ Decreases stage speed tremendously.
+ Slightly increased transmittablity.
+ Intense level.
+
+BONUS
+ The host must feed on BLOOD
+
+//////////////////////////////////////
+*/
+
+/datum/symptom/genetic/hematophagy
+ name = "Hematophagy"
+ stealth = 1
+ resistance = -1
+ resistance = -4
+ transmission = 1
+ severity = 1
+
+/datum/symptom/genetic/hematophagy/New()
+ . = ..()
+ mutation = get_gene_from_trait(/datum/trait/positive/superpower_remotetalk)
+
+/*
+//////////////////////////////////////
+
+Pica
+
+ Not noticable or unnoticable.
+ Decreases resistance.
+ Increases stage speed.
+ Little transmittable.
+ Low Level.
+
+BONUS
+ The host gains hunger for any kind of object.
+
+//////////////////////////////////////
+*/
+
+/datum/symptom/genetic/pica
+ name = "Pica"
+ stealth = 0
+ resistance = -2
+ stage_speed = 3
+ transmission = 1
+ level = 1
+ severity = 0
+
+/datum/symptom/genetic/pica/New()
+ . = ..()
+ mutation = get_gene_from_trait(/datum/trait/neutral/trashcan)
diff --git a/code/datums/diseases/advance/symptoms/hair.dm b/code/datums/diseases/advance/symptoms/hair.dm
index 2b2342ae08a..fc41c3207c8 100644
--- a/code/datums/diseases/advance/symptoms/hair.dm
+++ b/code/datums/diseases/advance/symptoms/hair.dm
@@ -6,7 +6,7 @@ Alopecia
Noticable.
Decreases resistance slightly.
Reduces stage speed slightly.
- Transmittable.
+ transmission.
Intense Level.
BONUS
@@ -17,16 +17,19 @@ BONUS
/datum/symptom/shedding
name = "Alopecia"
- stealth = -1
- resistance = -1
- stage_speed = -1
- transmittable = 2
- level = 4
- severity = 1
+ desc = "The virus attacks hair follicles, making hair thin and brittle."
+ stealth = 0
+ resistance = 3
+ stage_speed = 2
+ transmission = 2
+ level = 5
+ severity = 0
+ base_message_chance = 50
+ symptom_delay_min = 45
+ symptom_delay_max = 90
/datum/symptom/shedding/Activate(datum/disease/advance/A)
- ..()
- if(!prob(SYMPTOM_ACTIVATION_PROB))
+ if(!..())
return
if(ishuman(A.affected_mob))
return
diff --git a/code/datums/diseases/advance/symptoms/hallucigen.dm b/code/datums/diseases/advance/symptoms/hallucigen.dm
index 4bd1e44401d..4db05f1878d 100644
--- a/code/datums/diseases/advance/symptoms/hallucigen.dm
+++ b/code/datums/diseases/advance/symptoms/hallucigen.dm
@@ -17,24 +17,67 @@ Bonus
/datum/symptom/hallucigen
name = "Hallucigen"
- stealth = -2
- resistance = -3
- stage_speed = -3
- transmittable = -1
- level = 5
- severity = 3
+ desc = "The virus stimulates the brain, causing occasional hallucinations."
+ stealth = 1
+ resistance = -1
+ stage_speed = 1
+ transmission = 1
+ level = 3
+ severity = 1
+ base_message_chance = 25
+ symptom_delay_min = 10 SECONDS
+ symptom_delay_max = 70 SECONDS
+
+ var/fake_healthy = FALSE
+
+ threshold_descs = list(
+ "Stage Speed 7" = "Increases the amount of hallucinations.",
+ "Stealth 2" = "The virus mimics positive symptoms"
+ )
+
+/datum/symptom/hallucigen/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.stage_rate >= 7)
+ severity += 1
+
+/datum/symptom/hallucigen/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stealth >= 2)
+ fake_healthy = TRUE
+ base_message_chance = 50
+ if(A.stage_rate >= 7)
+ power = 2
/datum/symptom/hallucigen/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/carbon/M = A.affected_mob
- switch(A.stage)
- if(1, 2)
- to_chat(M, span_warning(pick("Something appears in your peripheral vision, then winks out.", "You hear a faint whisper with no source.", "Your head aches.")))
- if(3, 4)
- to_chat(M, span_boldwarning(pick("Something is following you.", "You are being watched.", "You hear a whisper in your ear.", "Thumping footsteps slam toward you from nowhere.")))
- else
- to_chat(M, span_userdanger(pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")))
- M.hallucination = rand(5, 10)
+ if(!..())
+ return
+ var/mob/living/carbon/M = A.affected_mob
+ if(M.stat == DEAD)
+ return
+ var/list/healthy_messages = list(
+ "Your lungs feel great.",
+ "You realize you haven't been breathing",
+ "You don't feel the need to breathe.",
+ "Your eyes feel great.",
+ "You are now blinking manually.",
+ "You don't feel the need to blnk."
+ )
- return
+ switch(A.stage)
+ if(1, 2)
+ if(prob(base_message_chance))
+ if(!fake_healthy)
+ to_chat(M, span_notice(pick("Something appears in your peripheral vision, then winks out.", "You hear a faint whisper with no source.", "Your head aches.")))
+ else
+ to_chat(M, span_notice(pick(healthy_messages)))
+ if(3, 4)
+ if(prob(base_message_chance))
+ if(!fake_healthy)
+ to_chat(M, span_danger(pick("Something is following you.", "You are being watched.", "You hear a whisper in your ear.", "Thumping footsteps slam toward you from nowhere.")))
+ else
+ to_chat(M, span_notice(pick(healthy_messages)))
+ else
+ if(prob(base_message_chance))
+ to_chat(M, span_userdanger(pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something is in the shadows...")))
+ M.hallucination += (45 * power)
diff --git a/code/datums/diseases/advance/symptoms/headache.dm b/code/datums/diseases/advance/symptoms/headache.dm
index de84b21fc11..94cc4bccc2d 100644
--- a/code/datums/diseases/advance/symptoms/headache.dm
+++ b/code/datums/diseases/advance/symptoms/headache.dm
@@ -17,16 +17,55 @@ BONUS
/datum/symptom/headache
name = "Headache"
+ desc = "The virus causes inflammation inside the brain, causing constant headaches."
stealth = -1
resistance = 4
stage_speed = 2
- transmittable = 0
+ transmission = 0
level = 1
- severity = 1
+ severity = 0
+ base_message_chance = 100
+ symptom_delay_min = 20 SECONDS
+ symptom_delay_max = 40 SECONDS
-/datum/symptom/headache/Activate(var/datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- to_chat(M, span_warning(pick("Your head hurts.", "Your head starts pounding.")))
- return
+ threshold_descs = list(
+ "Stage Speed 6" = "Headaches will cause severe pain, that weakens the host.",
+ "Stage Speed 9" = "Headaches become less frequent but far more intense, preventing any action from the host.",
+ "Stealth 4" = "Reduces headache frequency until later stages."
+ )
+
+/datum/symptom/headache/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.stage_rate >= 6)
+ severity += 1
+ if(A.stage_rate >= 9)
+ severity += 1
+
+/datum/symptom/headache/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stealth >= 4)
+ base_message_chance = 50
+ if(A.stage_rate >= 6)
+ power = 2
+ if(A.stage_rate >= 9)
+ symptom_delay_min = 30 SECONDS
+ symptom_delay_max = 60 SECONDS
+ power = 3
+
+/datum/symptom/headache/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+
+ var/mob/living/M = A.affected_mob
+ if(M.stat == DEAD)
+ return
+ if(power < 2)
+ if(prob(base_message_chance) || A.stage >= 4)
+ to_chat(M, span_warning(pick("Your head hurts.", "Your head pounds.")))
+ if(power >= 2 && A.stage >= 4)
+ to_chat(M, span_danger(pick("Your head hurts a lot.", "Your head pounds incessantly.")))
+ M.Weaken(10)
+ if(power >= 3 && A.stage >= 5)
+ to_chat(M, span_userdanger(pick("Your head hurts!", "You feel a burning knife inside your brain!", "A wave of pain fills your brain!")))
+ M.Stun(15)
diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm
index 0d77fc6f072..78f23343f30 100644
--- a/code/datums/diseases/advance/symptoms/heal.dm
+++ b/code/datums/diseases/advance/symptoms/heal.dm
@@ -1,125 +1,222 @@
-/*
-//////////////////////////////////////
-
-Healing
-
- Little bit hidden.
- Lowers resistance tremendously.
- Decreases stage speed tremendously.
- Decreases transmittablity temrendously.
- Fatal Level.
-
-Bonus
- Heals toxins in the affected mob's blood stream.
-
-//////////////////////////////////////
-*/
-
/datum/symptom/heal
- name = "Toxic Filter"
- stealth = 1
- resistance = -4
- stage_speed = -4
- transmittable = -4
- level = 6
- severity = 0
+ name = "Basic Healing (does nothing)"
+ stealth = 0
+ resistance = 0
+ stage_speed = 0
+ transmission = 0
+ level = -1
+ base_message_chance = 20
+ symptom_delay_min = 1
+ symptom_delay_max = 1
+ var/passive_message = ""
+ threshold_descs = list(
+ "Stealth 4" = "Healing will no longer be visible to onlookers."
+ )
-/datum/symptom/heal/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB * 10))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(4, 5)
- Heal(M, A)
- return
-
-/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A)
- var/get_damage = max(0, (sqrtor0(20+A.totalStageSpeed())*(1+rand())))
- M.adjustToxLoss(-get_damage)
+/datum/symptom/heal/Start(datum/disease/advance/A)
+ if(!..())
+ return FALSE
return TRUE
-/*
-//////////////////////////////////////
+/datum/symptom/heal/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ switch(A.stage)
+ if(4, 5)
+ var/effectiveness = CanHeal(A)
+ if(!effectiveness)
+ if(passive_message && prob(2) && passive_message_condition(M))
+ to_chat(M, passive_message)
+ return
+ else
+ Heal(M, A, effectiveness)
+ return
-Metabolism
+/datum/symptom/heal/proc/CanHeal(datum/disease/advance/A)
+ return power
- Little bit hidden.
- Lowers resistance.
- Decreases stage speed.
- Decreases transmittablity temrendously.
- High Level.
+/datum/symptom/heal/proc/Heal(mob/living/M, /datum/disease/advance/A, actual_power = 1)
+ return TRUE
-Bonus
- Cures all diseases (except itself) and creates anti-bodies for them until the symptom dies.
+/datum/symptom/heal/proc/passive_message_condition(mob/living/M)
+ return TRUE
-//////////////////////////////////////
-*/
+/datum/symptom/heal/chem
+ name = "Toxolysis"
+ desc = "The virus rapidly breaks down any foreign chemicals in the bloodstream."
+ stealth = 0
+ resistance = -2
+ stage_speed = 2
+ transmission = -2
+ level = 6
+ power = 2
+ var/food_conversion = FALSE
+
+ threshold_descs = list(
+ "Resistance 7" = "Increases chem removal speed.",
+ "Stage Speed 6" = "Consumed chemicals nourish the host."
+ )
+
+/datum/symptom/heal/chem/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stage >= 6)
+ food_conversion = TRUE
+ if(A.resistance >= 7)
+ power = 4
+
+/datum/symptom/heal/chem/Heal(mob/living/carbon/human/H, datum/disease/advance/A, actual_power)
+ for(var/datum/reagent/R in H.bloodstr.reagent_list)
+ H.reagents.remove_reagent(R.type, actual_power)
+ if(food_conversion)
+ H.adjust_nutrition(2)
+ if(prob(2) && H.stat != DEAD)
+ to_chat(H, span_notice("You feel a mild warmth as your blood purifies itself."))
+
+
+/datum/symptom/growth
+ name = "Pituitary Disruption"
+ desc = "Causes uncontrolled growth in the subject."
+ stealth = -3
+ resistance = -2
+ stage_speed = 1
+ transmission = -2
+ level = 8
+ severity = 1
+ symptom_delay_min = 10 SECONDS
+ symptom_delay_max = 20 SECONDS
+
+ var/current_size = 1
+ var/tetsuo = FALSE
+ var/bruteheal = FALSE
+
+ var/datum/mind/ownermind
+
+ threshold_descs = list(
+ "Stage Speed 6" = "The disease heals brute damage at a fast rate, but causes expulsion of benign tumors.",
+ "Stage Speed 12" = "The disease heals brute damage incredibly fast, but deteriorates cell health and causes tumors to become more advanced. The disease will also regenerate lost limbs."
+ )
+
+/datum/symptom/growth/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stage_rate >= 6)
+ bruteheal = TRUE
+ if(A.stage_rate >= 12)
+ tetsuo = TRUE
+ power = 3
+
+ var/mob/living/carbon/human/H = A.affected_mob
+ ownermind = H.mind
+
+/datum/symptom/growth/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/carbon/human/H = A.affected_mob
+ switch(A.stage)
+ if(4, 5)
+ if(prob(5) && bruteheal)
+ if(H.stat != DEAD)
+ to_chat(H, span_userdanger("You retch, and a splatter of gore escapes your gullet!"))
+ H.vomit(lost_nutrition = 0, blood = TRUE, stun = FALSE)
+ // Spitting tumors go here! IF they get up-ported.
+ if(tetsuo)
+ var/list/missing = H.get_missing_limbs()
+ if(prob(35) && H.mind && ishuman(H) && H.stat != DEAD)
+ new /obj/effect/decal/cleanable/blood/gibs(H.loc)
+ if(missing.len)
+ for(var/Z in missing)
+ if(H.regenerate_limb(Z, TRUE))
+ playsound(H, 'sound/effects/blobattack.ogg', 50, 1)
+ H.visible_message(span_warning("[H]'s missing limbs reform, making a loud, grotesque sound!"), span_userdanger("You limbs regrow, making a loud, crunchy sound and giving you great pain!"))
+ H.emote("scream")
+ if(Z == BP_HEAD)
+ if(isliving(ownermind.current))
+ var/mob/living/owner = ownermind.current
+ if(owner.stat != DEAD)
+ ownermind = null
+ break
+ ownermind.transfer_to(H)
+ H.grab_ghost()
+ break
+ if(bruteheal)
+ H.heal_overall_damage(2 * power)
+ if(prob(33) && tetsuo)
+ H.adjustCloneLoss(1)
+ else
+ if(prob(base_message_chance) && H.stat != DEAD)
+ to_chat(H, span_notice(pick("You feel bloated.", "The station seems small.", "You are the strongest.")))
+ return
/datum/symptom/heal/metabolism
- name = "Anti-Bodies Metabolism"
+ name = "Metabolic Boost"
+ desc = "The virus causes the host's metabolism to accelerate rapidly, making them process chemicals twice as fast, but also causing increased hunger."
stealth = -1
- resistance = -1
- stage_speed = -1
- transmittable = -4
- level = 3
- severity = 0
- var/list/cured_diseases = list()
+ resistance = -2
+ stage_speed = 2
+ transmission = 1
+ level = 6
+ var/triple_metabolism = FALSE
+ var/reduced_hunger = FALSE
-/datum/symptom/heal/metabolism/Heal(mob/living/M, datum/disease/advance/A)
- var/cured = 0
- for(var/thing in M.GetViruses())
- var/datum/disease/D = thing
- if(D.virus_heal_resistant)
- continue
- if(D != A)
- cured = TRUE
- cured_diseases += D.GetDiseaseID()
- D.cure()
- if(cured)
- to_chat(M, span_notice("You feel much better."))
+ threshold_descs = list(
+ "Stealth 3" = "Reduces hunger rate.",
+ "Stage Speed 10" = "Chemical metabolization is tripled instead of doubled."
+ )
-/datum/symptom/heal/metabolism/End(datum/disease/advance/A)
- var/mob/living/M = A.affected_mob
- if(istype(M))
- if(length(cured_diseases))
- for(var/res in M.GetResistances())
- M.resistances -= res
- to_chat(M, span_warning("You feel weaker."))
+/datum/symptom/heal/metabolism/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stage_rate >= 10)
+ triple_metabolism = TRUE
+ if(A.stealth >= 3)
+ reduced_hunger = TRUE
-/*
-//////////////////////////////////////
+/datum/symptom/heal/metabolism/Heal(mob/living/carbon/human/H, datum/disease/advance/A, actual_power)
+ if(!istype(H))
+ return
+ if(H.ingested)
+ H.ingested.metabolize()
+ if(triple_metabolism)
+ H.ingested.metabolize()
+ var/lost_nutrition = 9 - (reduced_hunger * 5)
+ H.adjust_nutrition(-lost_nutrition * 0.1)
+ if(prob(2) && H.stat != DEAD)
+ to_chat(H, span_notice("You feel an odd gurgle in your stomach, as if it was working much faster than normal."))
+ return TRUE
-Longevity
+/datum/symptom/heal/oxygen
+ name = "Oxygenation"
+ desc = "The virus causes the host's body to produce oxygen, allowing self-respiration."
+ stealth = 1
+ resistance = -3
+ stage_speed = -3
+ transmission = -4
+ level = 8
+ base_message_chance = 5
+ symptom_delay_min = 5 SECONDS
+ symptom_delay_max = 20 SECONDS
+ var/regenerate_blood = FALSE
- Medium hidden boost.
- Large resistance boost.
- Large stage speed boost.
- Large transmittablity boost.
- High Level.
+ threshold_descs = list(
+ "Resistance 8" = "Additionally regenerates lost blood."
+ )
-Bonus
- After a certain amount of time the symptom will cure itself.
+/datum/symptom/heal/oxygen/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.resistance >= 8)
+ regenerate_blood = TRUE
-//////////////////////////////////////
-*/
+/datum/symptom/heal/oxygen/Heal(mob/living/carbon/human/H, datum/disease/advance/A, actual_power)
+ if(!istype(H))
+ return
+ if(H.getOxyLoss() > 0)
+ H.adjustOxyLoss(3 * power)
+ if(regenerate_blood && H.vessel.get_reagent_amount(REAGENT_ID_BLOOD) < H.species.blood_volume)
+ H.add_chemical_effect(CE_BLOODRESTORE, 1)
-/datum/symptom/heal/longevity
- name = "Longevity"
- stealth = 3
- resistance = 4
- stage_speed = 4
- transmittable = 4
- level = 3
- severity = 0
- var/longevity = 30
-
-/datum/symptom/heal/longevity/Heal(mob/living/M, datum/disease/advance/A)
- longevity -= 1
- if(!longevity)
- A.cure()
-
-/datum/symptom/heal/longevity/Start(datum/disease/advance/A)
- longevity = rand(initial(longevity) - 5, initial(longevity) + 5)
/*
//////////////////////////////////////
@@ -136,19 +233,19 @@ Bonus
Heals clone damage, treats radiation.
//////////////////////////////////////
-*/
/datum/symptom/heal/dna
name = "Deoxyribonucleic Acid Restoration"
stealth = -1
resistance = -1
stage_speed = 0
- transmittable = -3
+ transmission = -3
level = 5
severity = 0
/datum/symptom/heal/dna/Heal(var/mob/living/carbon/M, var/datum/disease/advance/A)
- var/amt_healed = max(0, (sqrtor0(20+A.totalStageSpeed()*(3+rand())))-(sqrtor0(16+A.totalStealth()*rand())))
+ var/amt_healed = max(0, (sqrtor0(20+A.stage_rate*(3+rand())))-(sqrtor0(16+A.stealth*rand())))
M.adjustBrainLoss(-amt_healed)
M.radiation = max(M.radiation - 3, 0)
return TRUE
+*/
diff --git a/code/datums/diseases/advance/symptoms/hematophagy.dm b/code/datums/diseases/advance/symptoms/hematophagy.dm
deleted file mode 100644
index 086c0400a99..00000000000
--- a/code/datums/diseases/advance/symptoms/hematophagy.dm
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-//////////////////////////////////////
-
-Hematophagy
-
- Little bit hidden.
- Decreases resistance slightly.
- Decreases stage speed tremendously.
- Slightly increased transmittablity.
- Intense level.
-
-BONUS
- The host must feed on BLOOD
-
-//////////////////////////////////////
-*/
-
-/datum/symptom/hematophagy
- name = "Hematophagy"
- stealth = 1
- resistance = -1
- resistance = -4
- transmittable = 1
- level = 4
- severity = 1
-
-/datum/symptom/hematophagy/Start(datum/disease/advance/A)
- if(ishuman(A.affected_mob))
- var/mob/living/carbon/human/H = A.affected_mob
-
- H.species.organic_food_coeff = 0
- H.species.bloodsucker = TRUE
-
- add_verb(H, /mob/living/carbon/human/proc/bloodsuck)
-
-/datum/symptom/hematophagy/End(datum/disease/advance/A)
- if(ishuman(A.affected_mob))
- var/mob/living/carbon/human/H = A.affected_mob
-
- H.species.organic_food_coeff = initial(H.species.organic_food_coeff)
- H.species.bloodsucker = initial(H.species.bloodsucker)
-
- remove_verb(H, /mob/living/carbon/human/proc/bloodsuck)
diff --git a/code/datums/diseases/advance/symptoms/itching.dm b/code/datums/diseases/advance/symptoms/itching.dm
index f9e67814439..5eeada1d924 100644
--- a/code/datums/diseases/advance/symptoms/itching.dm
+++ b/code/datums/diseases/advance/symptoms/itching.dm
@@ -17,16 +17,43 @@ BONUS
/datum/symptom/itching
name = "Itching"
+ desc = "The virus irritates the skin, causing itching."
stealth = 0
resistance = 3
stage_speed = 3
- transmittable = 1
+ transmission = 1
level = 1
- severity = 1
+ severity = 0
+ symptom_delay_min = 15 SECONDS
+ symptom_delay_max = 35 SECONDS
-/datum/symptom/itching/Activate(var/datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- to_chat(M, span_warning("Your [pick("back", "arm", "leg", "elbow", "head")] itches."))
- return
+ var/scratch = FALSE
+
+ threshold_descs = list(
+ "Transmission 6" = "Increases frequency of itching.",
+ "Stage Speed 7" = "The host will scratch itself when itchin, causing superficial damage."
+ )
+
+/datum/symptom/itching/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.transmission >= 6)
+ symptom_delay_min = 5 SECONDS
+ symptom_delay_max = 10 SECONDS
+ if(A.stage >= 7)
+ scratch = TRUE
+
+/datum/symptom/itching/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+
+ var/mob/living/carbon/M = A.affected_mob
+ if(M.stat >= DEAD)
+ return
+ var/picked_bodypart = pick(BP_HEAD, BP_TORSO, BP_R_ARM, BP_L_ARM, BP_R_LEG, BP_L_LEG)
+ var/obj/item/organ/bodypart = M.get_organ(picked_bodypart)
+ var/can_scratch = scratch && !M.incapacitated()
+ if(bodypart && !bodypart.robotic)
+ M.visible_message("[can_scratch ? span_warning("[M] scratches their [bodypart.name].") : ""]", span_notice("Your [bodypart.name] itches. [can_scratch ? " You scratch it." : ""]"))
+ if(can_scratch)
+ bodypart.take_damage(0.5)
diff --git a/code/datums/diseases/advance/symptoms/language.dm b/code/datums/diseases/advance/symptoms/language.dm
index 1f06e5c030c..7d3f95e83af 100644
--- a/code/datums/diseases/advance/symptoms/language.dm
+++ b/code/datums/diseases/advance/symptoms/language.dm
@@ -17,16 +17,36 @@ Bonus
/datum/symptom/language
name = "Lingual Disocation"
- stealth = 3
+ desc = "The virus attack the broca area of the brain, messing with the host's speech."
+ stealth = 0
resistance = 2
- stage_speed = -2
- transmittable = -1
- level = 3
+ stage_speed = 1
+ transmission = 1
+ level = 1
severity = 1
+ symptom_delay_min = 20 SECONDS
+ symptom_delay_max = 50 SECONDS
+
+ var/gibberish = FALSE
+
+ threshold_descs = list(
+ "Resistance 5" = "The host might end up speaking a completely made up language."
+ )
+
+/datum/symptom/language/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.resistance)
+ gibberish = TRUE
/datum/symptom/language/Activate(var/datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/carbon/human/H = A.affected_mob
- H.apply_default_language(pick(H.languages))
- return
+ if(!..())
+ return
+ var/mob/living/L = A.affected_mob
+ if(L.stat == DEAD)
+ return
+
+ if(gibberish && prob(10))
+ L.apply_default_language(LANGUAGE_GIBBERISH)
+ else
+ L.apply_default_language(pick(L.languages))
diff --git a/code/datums/diseases/advance/symptoms/light.dm b/code/datums/diseases/advance/symptoms/light.dm
new file mode 100644
index 00000000000..0d3e5b697d3
--- /dev/null
+++ b/code/datums/diseases/advance/symptoms/light.dm
@@ -0,0 +1,53 @@
+/datum/symptom/light
+ name = "Photosensitive muscle condensation"
+ desc = "The virus will cause muscles to contract when exposed to light, resulting in lowered speed, but increased durability. Muscles will become more malleable in the darkness, resulting in the host moving faster, but being more easily bruised."
+ stealth = 0
+ resistance = 2
+ stage_speed = -3
+ transmission = 0
+ level = 8
+ severity = -2
+ var/currenthealthmodifier
+ threshold_descs = list(
+ "Stealth 3" = "The virus causes a wider disparity between light and dark."
+ )
+
+/datum/symptom/light/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.stealth >= 3)
+ severity -= 1
+
+/datum/symptom/light/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stealth >= 3)
+ power = 2
+
+/datum/symptom/light/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/carbon/human/H = A.affected_mob
+ if(H.stat >= DEAD)
+ return
+ var/realpower = power
+ var/healthchange = min(1 * realpower, (10 * realpower) - currenthealthmodifier)
+ if(isturf(H.loc))
+ var/turf/T = H.loc
+ var/light_amount = min(1, T.get_lumcount()) - 0.5
+ if(light_amount < 0.5)
+ realpower = power * -1
+ healthchange = max(1 * realpower, (10 * realpower) - currenthealthmodifier)
+ if(prob(5))
+ to_chat(H, span_warning(pick("You feel vulnerable.", "Your limbs feel loose and limber.", "The dark makes you feel realxed.")))
+ else if(prob(5))
+ to_chat(H, span_warning(pick("Your muscles feel tight.", "You feel lethargic.", "Your muscles feel hard and tough.")))
+ if(A.stage >= 5)
+ currenthealthmodifier += healthchange
+ H.maxHealth += healthchange
+ H.health += healthchange
+
+/datum/symptom/light/End(datum/disease/advance/A)
+ . = ..()
+ var/mob/living/carbon/human/H = A.affected_mob
+ H.maxHealth -= currenthealthmodifier
+ H.health -= currenthealthmodifier
diff --git a/code/datums/diseases/advance/symptoms/macrophage.dm b/code/datums/diseases/advance/symptoms/macrophage.dm
index a04a3fc50fe..77ccb5d2e89 100644
--- a/code/datums/diseases/advance/symptoms/macrophage.dm
+++ b/code/datums/diseases/advance/symptoms/macrophage.dm
@@ -17,57 +17,84 @@ BONUS
/datum/symptom/macrophage
name = "Macrophage"
+ desc = "The virus grows within the host, ceasing to be microscopic and causing severe bodily harm. These Phages will seek out, attack, and infect more viable hosts."
stealth = -4
resistance = -1
stage_speed = -2
- transmittable = 2
- level = 6
+ transmission = 2
+ level = 9
severity = 2
+ symptom_delay_min = 40
+ symptom_delay_max = 60
var/gigagerms = FALSE
var/netspeed = 0
var/phagecounter = 10
+ threshold_descs = list(
+ "Stage Speed" = "The higher the stage speed, the more frequently will burst from the host.",
+ "Resistance" = "The higher the resistance, the more health phages will have, and the more damage the will do.",
+ "Transmission 10" = "Phages can be larger, and more aggressive.",
+ "Transmission 12" = "Phages will carry all diseases within the host, instead of only containing their own."
+ )
+
+/datum/symptom/macrophage/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.transmission >= 10)
+ severity += 2
+
/datum/symptom/macrophage/Start(datum/disease/advance/A)
- netspeed = max(1, A.stage)
- if(A.severity >= HARMFUL)
+ if(!..())
+ return
+ netspeed = max(1, A.stage_rate)
+ if(A.transmission >= 10)
gigagerms = TRUE
/datum/symptom/macrophage/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(1, 2, 3)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ switch(A.stage)
+ if(1, 2, 3)
+ if(prob(base_message_chance) && M.stat != DEAD)
to_chat(M, span_notice("Your skin crawls."))
- if(4)
+ if(4)
+ if(prob(base_message_chance))
M.visible_message(span_danger("Lumps form on [M]'s skin!"), span_userdanger("You cringe in pain as lumps form and move around on your skin!"))
- if(5)
- phagecounter -= max(2, A.totalStageSpeed())
- if(gigagerms && phagecounter <= 0)
- Burst(A, M, TRUE)
- phagecounter += 10
- while(phagecounter <= 0)
- phagecounter += 5
- Burst(A, M)
+ if(5)
+ phagecounter -= max(2, A.stage_rate)
+ if(gigagerms && phagecounter <= 0)
+ Burst(A, M, TRUE)
+ phagecounter += 10
+ while(phagecounter <= 0)
+ phagecounter += 5
+ Burst(A, M)
/datum/symptom/macrophage/proc/Burst(datum/disease/advance/A, var/mob/living/M, var/gigagerms = FALSE)
var/mob/living/simple_mob/vore/aggressive/macrophage/phage
- phage = new(M.loc)
- M.apply_damage(rand(1, 7))
- phage.viruses = A.Copy()
- phage.health += A.totalResistance()
- phage.maxHealth += A.totalResistance()
+
+ if(gigagerms)
+ phage = new /mob/living/simple_mob/vore/aggressive/macrophage/giant(get_turf((M.loc)))
+ phage.melee_damage_lower = rand(10, 15)
+ phage.melee_damage_upper = rand(15, 20)
+ M.apply_damage(rand(10, 20))
+ playsound(M, 'sound/effects/splat.ogg', 50, 1)
+ M.emote("scream")
+ else
+ phage = new(get_turf((M.loc)))
+ M.apply_damage(rand(1, 7))
+
+ phage.health += A.resistance
+ phage.maxHealth += A.resistance
phage.infections += A
phage.base_disease = A
- if(A.spread_flags & CONTACT_GENERAL)
+ if(A.transmission >= 12)
for(var/datum/disease/D in M.GetViruses())
- if((D.spread_flags & SPECIAL) || (D.spread_flags & NON_CONTAGIOUS))
+ if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_CONTACT))
continue
if(D == A)
continue
- phage.viruses += D
-
- M.visible_message(span_danger("A strange crearure bursts out of [M]!"), span_userdanger("A slimy creature bursts forth from your flesh!"))
- addtimer(CALLBACK(phage, TYPE_PROC_REF(/mob/living/simple_mob/vore/aggressive/macrophage, deathcheck)), 3000)
+ phage.infections += D
+ M.visible_message(span_danger("A strange creature burst out of [M]!"), span_userdanger("A slimy creature bursts forth from your flesh!"))
+ addtimer(CALLBACK(phage, TYPE_PROC_REF(/mob/living/simple_mob/vore/aggressive/macrophage, deathcheck)), 3 MINUTES)
diff --git a/code/datums/diseases/advance/symptoms/mlem.dm b/code/datums/diseases/advance/symptoms/mlem.dm
index e48329be9cc..ebd3c79eb4a 100644
--- a/code/datums/diseases/advance/symptoms/mlem.dm
+++ b/code/datums/diseases/advance/symptoms/mlem.dm
@@ -17,16 +17,49 @@ BONUS
/datum/symptom/mlem
name = "Mlemington"
+ desc = "The host uncontrollably licks their nose. Mlem."
stealth = 0
resistance = 3
stage_speed = 3
- transmittable = 1
+ transmission = 1
level = 1
severity = 1
+ var/infective = FALSE
+
+ threshold_descs = list(
+ "Resistance 5" = "The host may occasionally go on a mlemming spree.",
+ "Transmission 8" = "The host will spread the virus through saliva when mlemming."
+ )
+
+/datum/symptom/mlem/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.transmission >= 8)
+ infective = TRUE
+ severity += 1
+
+/datum/symptom/mlem/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.resistance >= 5)
+ power = 1.5
+
/datum/symptom/itching/Activate(var/datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- M.emote("mlem")
- return
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ if(M.stat == DEAD)
+ return
+ switch(A.stage)
+ if(1, 2, 3)
+ if(prob(base_message_chance))
+ to_chat(M, span_notice("You think about licking your nose..."))
+ else
+ M.emote("mlem")
+ if(power >= 1.5)
+ M.emote("mlem")
+ if(power >= 2)
+ M.emote("mlem")
+ addtimer(CALLBACK(M, TYPE_PROC_REF(/mob, emote), "mlem"), 2 SECONDS)
+ addtimer(CALLBACK(M, TYPE_PROC_REF(/mob, emote), "mlem"), 5 SECONDS)
+ addtimer(CALLBACK(M, TYPE_PROC_REF(/mob, emote), "mlem"), 8 SECONDS)
diff --git a/code/datums/diseases/advance/symptoms/necrotic_agent.dm b/code/datums/diseases/advance/symptoms/necrotic_agent.dm
index 24a3e9ff065..60dd226ed10 100644
--- a/code/datums/diseases/advance/symptoms/necrotic_agent.dm
+++ b/code/datums/diseases/advance/symptoms/necrotic_agent.dm
@@ -17,15 +17,16 @@ Bonus
/datum/symptom/necrotic_agent
name = "Necrotic Agent"
- stealth = -2
- resistance = -3
- stage_speed = -3
- transmittable = 0
+ desc = "Allows the virus to infect corpses, and work on the dead."
+ stealth = 2
+ resistance = -2
+ stage_speed = -1
+ transmission = 0
level = 6
severity = 3
-/datum/symptom/necrotic_agent/Start(datum/disease/advance/A)
- A.allow_dead = TRUE
+/datum/symptom/necrotic_agent/OnAdd(datum/disease/advance/A)
+ A.virus_modifiers |= SPREAD_DEAD
-/datum/symptom/necrotic_agent/End(datum/disease/advance/A)
- A.allow_dead = FALSE
+/datum/symptom/necrotic_agent/OnRemove(datum/disease/advance/A)
+ A.virus_modifiers &= ~SPREAD_DEAD
diff --git a/code/datums/diseases/advance/symptoms/oxygen.dm b/code/datums/diseases/advance/symptoms/oxygen.dm
deleted file mode 100644
index a0e04987003..00000000000
--- a/code/datums/diseases/advance/symptoms/oxygen.dm
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-//////////////////////////////////////
-
-Self-Respiration
-
- Slightly hidden.
- Lowers resistance significantly.
- Decreases stage speed significantly.
- Decreases transmittablity tremendously.
- Fatal Level.
-
-Bonus
- The body generates dexalin.
-
-//////////////////////////////////////
-*/
-
-/datum/symptom/oxygen
- name = "Self-Respiration"
- stealth = 1
- resistance = -3
- stage_speed = -3
- transmittable = -4
- level = 6
- severity = 0
-
-/datum/symptom/oxygen/Activate(var/datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB * 5))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(4, 5)
- if(M.reagents.get_reagent_amount(REAGENT_ID_DEXALIN) < 10)
- M.reagents.add_reagent(REAGENT_ID_DEXALIN, 10)
- else
- if(prob(SYMPTOM_ACTIVATION_PROB * 5))
- to_chat(M, span_notice(pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")))
- return
diff --git a/code/datums/diseases/advance/symptoms/photosensitivity.dm b/code/datums/diseases/advance/symptoms/photosensitivity.dm
index 5908bfb259c..77f08f1a360 100644
--- a/code/datums/diseases/advance/symptoms/photosensitivity.dm
+++ b/code/datums/diseases/advance/symptoms/photosensitivity.dm
@@ -20,7 +20,7 @@ Bonus
stealth = -2
resistance = 2
stage_speed = 1
- transmittable = -4
+ transmission = -4
level = 6
severity = 5
diff --git a/code/datums/diseases/advance/symptoms/pica.dm b/code/datums/diseases/advance/symptoms/pica.dm
deleted file mode 100644
index 6f8221a74b4..00000000000
--- a/code/datums/diseases/advance/symptoms/pica.dm
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-//////////////////////////////////////
-
-Pica
-
- Not noticable or unnoticable.
- Decreases resistance.
- Increases stage speed.
- Little transmittable.
- Low Level.
-
-BONUS
- The host gains hunger for any kind of object.
-
-//////////////////////////////////////
-*/
-
-/datum/symptom/pica
- name = "Pica"
- stealth = 0
- resistance = -2
- stage_speed = 3
- transmittable = 1
- level = 1
- severity = 0
-
-/datum/symptom/pica/Start(datum/disease/advance/A)
- add_verb(A.affected_mob, /mob/living/proc/eat_trash)
- add_verb(A.affected_mob, /mob/living/proc/toggle_trash_catching)
-
-/datum/symptom/pica/End(datum/disease/advance/A)
- remove_verb(A.affected_mob, /mob/living/proc/eat_trash)
- remove_verb(A.affected_mob, /mob/living/proc/toggle_trash_catching)
-
-/datum/symptom/pica/Activate(datum/disease/advance/A)
- ..()
-
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/list/nearby = oview(5, A.affected_mob)
- to_chat(A.affected_mob, span_warning("You could go fo a bite of [pick(nearby)]..."))
- else if (prob(SYMPTOM_ACTIVATION_PROB))
- if(ishuman(A.affected_mob))
- var/mob/living/carbon/human/H = A.affected_mob
- var/list/item = H.get_equipped_items()
- to_chat(H, span_warning("[pick(item)] looks oddly [pick("delicious", "tasty", "scrumptious", "inviting")]..."))
- return
diff --git a/code/datums/diseases/advance/symptoms/radiation.dm b/code/datums/diseases/advance/symptoms/radiation.dm
new file mode 100644
index 00000000000..0c926c1749d
--- /dev/null
+++ b/code/datums/diseases/advance/symptoms/radiation.dm
@@ -0,0 +1,108 @@
+/datum/symptom/radiation
+ name = "Irradiant Cells"
+ desc = "Causes the cells in the host's body to give off harmful radiation."
+ stealth = -1
+ resistance = 2
+ stage_speed = 1
+ transmission = 2
+ level = 7
+ severity = 3
+ symptom_delay_min = 10 SECONDS
+ symptom_delay_max = 40 SECONDS
+ threshold_descs = list(
+ "Speed 8" = "Host takes radiation damage faster."
+ )
+
+/datum/symptom/radiation/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.stage_rate >= 8)
+ severity += 1
+
+/datum/symptom/radiation/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stage_rate >= 8)
+ power = 2
+
+/datum/symptom/radiation/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/carbon/human/H = A.affected_mob
+ if(H.stat == DEAD)
+ return
+ switch(A.stage)
+ if(1)
+ if(prob(10))
+ to_chat(H, span_notice("You feel off..."))
+ if(2, 3)
+ if(prob(50))
+ to_chat(H, span_danger("You feel like the atoms inside you are beginning to split..."))
+ if(4, 5)
+ radiate(H)
+
+/datum/symptom/radiation/proc/radiate(mob/living/carbon/human/H)
+ to_chat(H, span_danger("You feel a wave of pain throughout your body!"))
+ H.radiation += 50 * power
+ return TRUE
+
+/datum/symptom/radconversion
+ name = "Aptopic Culling"
+ desc = "The virus causes infected cells to die off when exposed to radiation, causing open wounds to appear on the host's flesh. The end result of this process is the removal of radioactive contamination from the host."
+ stealth = 1
+ resistance = 1
+ stage_speed = 1
+ transmission = -2
+ level = 8
+ severity = 0
+ symptom_delay_min = 1
+ symptom_delay_max = 1
+
+ var/toxheal = FALSE
+ var/cellheal = FALSE
+
+ threshold_descs = list(
+ "Stage Speed 6" = "The disease also kills off contaminated cells, converting Toxin damage to Brute damage, at an efficient rate.",
+ "Resistance 12" = "The disease also kills off genetically damaged cells, coverting Genetic damage to Burn damage, an inefficient rate."
+ )
+
+/datum/symptom/radconversion/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.stage_rate >= 6)
+ severity -= 1
+ if(A.resistance >= 12)
+ severity -= 1
+
+/datum/symptom/radconversion/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stage_rate >= 6)
+ toxheal = TRUE
+ if(A.resistance >= 12)
+ cellheal = TRUE
+
+/datum/symptom/radconversion/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/carbon/human/H = A.affected_mob
+ if(A.stage >= 4)
+ if(H.radiation)
+ H.radiation -= max(H.radiation * 0.05, min(10, H.radiation))
+ H.take_overall_damage(2)
+ if(prob(5))
+ if(H.stat != DEAD)
+ to_chat(H, span_userdanger("A tear opens in your flesh!"))
+ blood_splatter(H.loc, H)
+ if(H.getToxLoss() && toxheal)
+ H.adjustToxLoss(-2)
+ H.take_overall_damage(1)
+ if(prob(5))
+ if(H.stat != DEAD)
+ to_chat(H, span_userdanger("A tear opens in your flesh!"))
+ blood_splatter(H.loc, H)
+ if(H.getCloneLoss() && cellheal)
+ H.adjustCloneLoss(-1)
+ H.take_overall_damage(burn = 2)
+ if(prob(5) && H.stat != DEAD)
+ to_chat(H, span_userdanger("A nasty rash appears on your skin!"))
+ else if (prob(2) && ((H.getCloneLoss() && cellheal) || (H.getToxLoss() && toxheal) || H.radiation) && H.stat != DEAD)
+ to_chat(H, span_notice("You feel a tingling sensation."))
diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm
index 8de86908419..fcce95fd09b 100644
--- a/code/datums/diseases/advance/symptoms/sensory.dm
+++ b/code/datums/diseases/advance/symptoms/sensory.dm
@@ -20,7 +20,7 @@ Bonus
stealth = -3
resistance = -4
stage_speed = -4
- transmittable = -3
+ transmission = -3
level = 5
severity = 0
@@ -47,7 +47,7 @@ Bonus
stealth = -1
resistance = -3
stage_speed = -2
- transmittable = -4
+ transmission = -4
level = 4
/datum/symptom/sensory_restoration/Activate(datum/disease/advance/A)
diff --git a/code/datums/diseases/advance/symptoms/shivering.dm b/code/datums/diseases/advance/symptoms/shivering.dm
index efe4b39f17e..ec556abef70 100644
--- a/code/datums/diseases/advance/symptoms/shivering.dm
+++ b/code/datums/diseases/advance/symptoms/shivering.dm
@@ -17,23 +17,53 @@ Bonus
/datum/symptom/shivering
name = "Shivering"
+ desc = "The virus inhibits the body's thermoregulation, cooling the body down."
stealth = 0
resistance = 2
stage_speed = 2
- transmittable = 2
+ transmission = 2
level = 2
- severity = 2
+ severity = 0
+ symptom_delay_min = 20 SECONDS
+ symptom_delay_max = 40 SECONDS
+
+ var/unsafe = FALSE
+
+ threshold_descs = list(
+ "Stage Speed 5" = "Increases cooling speed; The host can fall below safe temperature levels.",
+ "Stage Speed 10" = "Further increases cooling speed."
+ )
+
+/datum/symptom/shivering/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.stage_rate >= 5)
+ severity += 1
+ if(A.stage_rate >= 10)
+ severity += 1
+
+/datum/symptom/shivering/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stage_rate >= 5)
+ power = 1.5
+ unsafe = TRUE
+ if(A.stage_rate >= 10)
+ power = 2.5
/datum/symptom/shivering/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- 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
+ if(!..())
+ return
+ var/mob/living/carbon/M = A.affected_mob
+ if(M.stat == DEAD)
+ return
+ if(!unsafe || A.stage < 4)
+ to_chat(M, span_warning(pick("You feel cold.", "You shiver.")))
+ else
+ to_chat(M, span_userdanger(pick("You fel your blood run cold.", "You feel ice in your veins.", "You feel like you can't heat up.", "You shiver violently.")))
+ set_body_temp(M, A)
-/datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A)
- var/get_cold = (sqrtor0(16+A.totalStealth()*2))+(sqrtor0(21+A.totalResistance()*2))
- M.bodytemperature = max(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1)
- return 1
+/datum/symptom/shivering/proc/set_body_temp(var/mob/living/carbon/H, datum/disease/advance/A)
+ if(!unsafe)
+ H.bodytemperature = max(-((3 * power) * A.stage), (BODYTEMP_COLD_DAMAGE_LIMIT +1))
+ else
+ H.bodytemperature = max(-((3 * power) * A.stage), (BODYTEMP_COLD_DAMAGE_LIMIT - 20))
diff --git a/code/datums/diseases/advance/symptoms/size.dm b/code/datums/diseases/advance/symptoms/size.dm
index a0a71fe1b71..b01336d9997 100644
--- a/code/datums/diseases/advance/symptoms/size.dm
+++ b/code/datums/diseases/advance/symptoms/size.dm
@@ -17,82 +17,33 @@ BONUS
/datum/symptom/size
name = "Mass Revectoring"
- stealth = -4
- resistance = 1
+ desc = "The virus causes distortion of the host's body, causing it to change size."
+ stealth = 1
+ resistance = 0
stage_speed = 2
- transmittable = -2
+ transmission = 2
level = 4
- severity = 1
+ severity = 0
+ symptom_delay_min = 20 SECONDS
+ symptom_delay_max = 60 SECONDS
+ var/min_size = RESIZE_MINIMUM
+ var/max_size = RESIZE_MAXIMUM
/datum/symptom/size/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
-
- switch(A.stage)
- if(4, 5)
- M.emote("twitch")
- Resize(M, rand(25, 200))
-
-/datum/symptom/size/proc/Resize(mob/living/M, var/size)
- M.resize(size+M.size_multiplier/100)
-
-/*
-//////////////////////////////////////
-
-Enlargement Disorder
-
- Very noticeable.
- Increases resistance slightly.
- Increases stage speed.
- Decreases transmittablity
- Intense level.
-
-BONUS
- Grows the host to bigger sizes
-
-//////////////////////////////////////
-*/
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ switch(A.stage)
+ if(4, 5)
+ M.emote("twitch")
+ M.resize(pick(min_size, max_size))
/datum/symptom/size/grow
name = "Enlargement Disorder"
-
-/datum/symptom/size/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
-
- switch(A.stage)
- if(4, 5)
- M.emote("twitch")
- Resize(M, rand(100, 200))
-
-/*
-//////////////////////////////////////
-
-Dwindling Malady
-
- Very noticeable.
- Increases resistance slightly.
- Increases stage speed.
- Decreases transmittablity
- Intense level.
-
-BONUS
- Shrinks the host to small sizes
-
-//////////////////////////////////////
-*/
+ min_size = RESIZE_NORMAL
+ max_size = RESIZE_MAXIMUM
/datum/symptom/size/shrink
name = "Dwindling Malady"
-
-/datum/symptom/size/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
-
- switch(A.stage)
- if(4, 5)
- M.emote("twitch")
- Resize(M, rand(25, 100))
+ min_size = RESIZE_MINIMUM
+ max_size = RESIZE_NORMAL
diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm
index e1f226049f9..5c9d681206c 100644
--- a/code/datums/diseases/advance/symptoms/sneeze.dm
+++ b/code/datums/diseases/advance/symptoms/sneeze.dm
@@ -18,30 +18,43 @@ Bonus
/datum/symptom/sneeze
name = "Sneezing"
+ desc = "The virus causes irritation of the nasal cavity, making the host sneeze occasionally."
stealth = -2
resistance = 3
stage_speed = 0
- transmittable = 4
+ transmission = 4
+ symptom_delay_min = 15 SECONDS
+ symptom_delay_max = 40 SECONDS
level = 1
- severity = 1
+ severity = 0
+
+ var/infective = FALSE
+
+ threshold_descs = list(
+ "Stealth 4" = "The symptom remains hidden until active.",
+ "Trasmission 12" = "The host may spread the disease through sneezing."
+ )
+
+/datum/symptom/sneeze/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stealth >= 4)
+ supress_warning = TRUE
+ if(A.transmission >= 12)
+ infective = TRUE
/datum/symptom/sneeze/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(1, 2, 3)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ switch(A.stage)
+ if(1, 2, 3)
+ if(!supress_warning)
M.emote("sniff")
- else
- M.emote("sneeze")
- if(!M.wear_mask) // Spread only if they're not covering their face
- A.spread(5)
-
- if(prob(30) && !M.wear_mask) // Same for mucus
- var/obj/effect/decal/cleanable/mucus/icky = new(get_turf(M))
- icky.viruses |= A.Copy()
-
- return
+ else
+ M.emote("sneeze")
+ if(infective)
+ addtimer(CALLBACK(A, TYPE_PROC_REF(/datum/disease, spread), 4), 20)
/*
//////////////////////////////////////
@@ -61,33 +74,30 @@ Bonus
//////////////////////////////////////
*/
-/datum/symptom/sneeze/bluespace
+/datum/symptom/bsneeze
name = "Bluespace Sneezing"
+ desc = "The virus condenses bluespace particles in the host's nasal cavity, teleporting the host on sneeze."
stealth = -2
resistance = 3
stage_speed = 0
- transmittable = 1
+ transmission = 1
+ symptom_delay_min = 20 SECONDS
+ symptom_delay_max = 30 SECONDS
level = 4
severity = 3
-/datum/symptom/sneeze/bluespace/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(1, 2, 3)
+/datum/symptom/bsneeze/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ switch(A.stage)
+ if(1, 2, 3)
+ if(!supress_warning)
M.emote("sniff")
- else
- SneezeTeleport(A, M)
- if(!M.wear_mask)
- A.spread(A.stage)
- if(prob(30) && !M.wear_mask)
- var/obj/effect/decal/cleanable/mucus/icky = new(get_turf(M))
- icky.viruses |= A.Copy()
+ else
+ SneezeTeleport(A, A.affected_mob)
- return
-
-/datum/symptom/sneeze/bluespace/proc/SneezeTeleport(datum/disease/advance/A, var/mob/living/mob)
+/datum/symptom/bsneeze/proc/SneezeTeleport(datum/disease/advance/A, var/mob/living/mob)
var/list/destination = list()
var/place
diff --git a/code/datums/diseases/advance/symptoms/spin.dm b/code/datums/diseases/advance/symptoms/spin.dm
index 0dc0d7d6bf8..95ef7569b68 100644
--- a/code/datums/diseases/advance/symptoms/spin.dm
+++ b/code/datums/diseases/advance/symptoms/spin.dm
@@ -20,17 +20,33 @@ BONUS
stealth = 2
resistance = 0
stage_speed = 3
- transmittable = 1
+ transmission = 1
level = 1
+ symptom_delay_min = 15 SECONDS
+ symptom_delay_max = 35 SECONDS
severity = 0
+ threshold_descs = list(
+ "Resistance 6" = "The target will flip more violently."
+ )
-/datum/symptom/spyndrome/Activate(var/datum/disease/advance/A)
- ..()
+ var/bigspin = FALSE
- if(prob(SYMPTOM_ACTIVATION_PROB))
- if(A.affected_mob.buckled())
- to_chat(viewers(A.affected_mob), span_warning("[A.affected_mob.name] struggles violently against their restraints!"))
+/datum/symptom/spyndrome/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.resistance >= 6)
+ bigspin = TRUE
+
+/datum/symptom/spyndrome/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ switch(A.stage)
+ if(1, 2, 3)
+ if(prob(base_message_chance))
+ to_chat(M, span_notice("You can't stand still."))
else
- to_chat(viewers(A.affected_mob), span_warning("[A.affected_mob.name] spins around violently!"))
- A.affected_mob.emote("spin")
- return
+ if(bigspin)
+ M.emote("floorspin")
+ else
+ M.emote("spin")
diff --git a/code/datums/diseases/advance/symptoms/stimulant.dm b/code/datums/diseases/advance/symptoms/stimulant.dm
index 4861a442409..9378221e191 100644
--- a/code/datums/diseases/advance/symptoms/stimulant.dm
+++ b/code/datums/diseases/advance/symptoms/stimulant.dm
@@ -16,28 +16,69 @@ Bonus
*/
/datum/symptom/stimulant
- name = "Overactive Adrenal Gland"
- stealth = 0
- resistance = -1
+ name = "Hyperactivity"
+ desc = "The virus causes restlessness, nervousness and hyperactivity, increasing the rate at which the host needs to eat, but making them harder to tire out"
+ stealth = -4
+ resistance = 0
stage_speed = 2
- transmittable = -3
- level = 3
+ transmission = -3
+ level = 8
severity = 1
+ symptom_delay_min = 1
+ symptom_delay_max = 1
+
+ var/clearacc = FALSE
+
+ threshold_descs = list(
+ "Resistance 8" = "This virus causes an even greater rate of nutriment loss, able to cause starvation, but it's energy gain greatly increases.",
+ "Stage 8" = "The virus causes extreme nervousness and paranoia, resulting in occasional hallucinations, and extreme restlessness, but great overall energy."
+ )
+
+/datum/symptom/stimulant/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.resistance >= 8)
+ severity -= 1
+ if(A.stage_rate >= 8)
+ severity -= 1
+
+/datum/symptom/stimulant/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ power = initial(power)
+ if(A.resistance >= 8)
+ power += 2
+ if(A.stage_rate >= 8)
+ power += 1
+ clearacc = TRUE
/datum/symptom/stimulant/Activate(datum/disease/advance/A)
- ..()
-
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/L = A.affected_mob
- to_chat(L, span_notice("You feel a rush of energy inside you!"))
- switch(A.stage)
- if(1, 2)
- L.jitteriness += 5
- if(3, 4)
- L.jitteriness += 10
- else
- if(L.reagents.get_reagent_amount(REAGENT_ID_HYPERZINE) < 10)
- L.reagents.add_reagent(REAGENT_ID_HYPERZINE, 5)
- if(prob(30))
- L.jitteriness += 15
- return
+ if(!..())
+ return
+ var/mob/living/carbon/human/H = A.affected_mob
+ if(H.stat == DEAD)
+ return
+ switch(A.stage)
+ if(2 to 3)
+ if(prob(power) && H.stat)
+ H.jitteriness += (2 * power)
+ H.emote("twitch")
+ to_chat(H, span_notice("[pick("you feel energetic!", "You feel well-rested.", "You feel great!")]"))
+ if(4 to 5)
+ H.drowsyness = max(0, H.drowsyness - 10 * power)
+ H.AdjustSleeping(-10 * power)
+ H.AdjustStunned(-10 * power)
+ if(prob(power) && prob(50))
+ if(H.stat)
+ H.emote("twitch")
+ H.make_jittery(2 * power)
+ H.reagents.add_reagent(REAGENT_ID_HYPERZINE, 5)
+ to_chat(H, span_notice("[pick("You feel nevervous...", "You feel anxious.", "You feel like everything is moving in slow motion.")]"))
+ if(H.nutrition > 150 - (30 * power))
+ H.nutrition = max(150 - (30 * power), H.nutrition - (2 * power))
+ if(prob(25))
+ H.make_jittery(2 * power)
+ if(clearacc)
+ if(prob(power) && prob(50))
+ if(H.stat)
+ H.emote("scream")
+ H.hallucination = min(20, H.hallucination + (5 * power))
diff --git a/code/datums/diseases/advance/symptoms/symptoms.dm b/code/datums/diseases/advance/symptoms/symptoms.dm
index df5954f97b7..c7322cbb31b 100644
--- a/code/datums/diseases/advance/symptoms/symptoms.dm
+++ b/code/datums/diseases/advance/symptoms/symptoms.dm
@@ -5,16 +5,29 @@ GLOBAL_LIST_INIT(list_symptoms, subtypesof(/datum/symptom))
/datum/symptom
// Buffs/Debuffs the symptom has to the overall engineered disease.
var/name = ""
+ var/desc = "ERR://355. PanDEMIC was not able to initialize description!" // Someone forgot the description
+ var/threshold_descs = list()
var/stealth = 0
var/resistance = 0
var/stage_speed = 0
- var/transmittable = 0
+ var/transmission = 0
// The type level of the symptom. Higher is harder to generate.
var/level = 0
// The severity level of the symptom. Higher is more dangerous.
var/severity = 0
// The hash tag for our diseases, we will add it up with our other symptoms to get a unique id! ID MUST BE UNIQUE!!!
var/id = ""
+ var/supress_warning = FALSE
+ var/next_activaction = 0
+ var/symptom_delay_min = 1 SECONDS
+ var/symptom_delay_max = 1 SECONDS
+ var/naturally_occuring = TRUE // If this symptom can roll from random diseases
+
+ var/base_message_chance = 10
+ var/power = 1
+ // If the symptom is neutered or not. If it is, it will only affect stats
+ var/neutered = FALSE
+ var/stopped = FALSE // Used for Viral Suspended Animaton, stops a symptom but doesn't neuter it.
/datum/symptom/New()
var/list/S = GLOB.list_symptoms
@@ -24,18 +37,71 @@ GLOBAL_LIST_INIT(list_symptoms, subtypesof(/datum/symptom))
return
CRASH("We couldn't assign an ID!")
+/datum/symptom/proc/Copy()
+ var/datum/symptom/new_symp = new type
+ new_symp.name = name
+ new_symp.id = id
+ new_symp.neutered = neutered
+ return new_symp
+
// Called when processing of the advance disease, which holds this symptom, starts.
/datum/symptom/proc/Start(datum/disease/advance/A)
- return
+ if(neutered)
+ return FALSE
+ next_activaction = world.time + rand(symptom_delay_min, symptom_delay_max)
+ return TRUE
+
+/datum/symptom/proc/severityset(datum/disease/advance/A)
+ severity = initial(severity)
// Called when the advance disease is going to be deleted or when the advance disease stops processing.
/datum/symptom/proc/End(datum/disease/advance/A)
- return
+ if(neutered)
+ return FALSE
+ return TRUE
// Called when the disease activates. It's what makes your diseases work!
/datum/symptom/proc/Activate(datum/disease/advance/A)
- return
+ if(!A)
+ return FALSE
+ if(isbelly(A.affected_mob.loc)) // So you can eat people to "isolate" them. Or get eaten by a macrophage.
+ return FALSE
+ if(neutered || stopped)
+ return FALSE
+ if(world.time < next_activaction)
+ return FALSE
+ else
+ next_activaction = world.time + rand(symptom_delay_min, symptom_delay_max)
+ return TRUE
// Called when the host dies
/datum/symptom/proc/OnDeath(datum/disease/advance/A)
+ return !neutered
+
+// Called when the stage changes
+/datum/symptom/proc/OnStageChange(datum/disease/advance/A)
+ if(neutered || stopped)
+ return FALSE
+ return TRUE
+
+/datum/symptom/proc/OnAdd(datum/disease/advance/A)
return
+
+/datum/symptom/proc/OnRemove(datum/disease/advance/A)
+ return
+
+/datum/symptom/proc/generate_threshold_desc()
+ return
+
+/datum/symptom/proc/get_symptom_data()
+ var/list/data = list()
+ data["name"] = name
+ data["desc"] = desc
+ data["stealth"] = stealth
+ data["resistance"] = resistance
+ data["stage_speed"] = stage_speed
+ data["transmission"] = transmission
+ data["neutered"] = neutered
+ data["level"] = level
+ data["threshold_desc"] = threshold_descs
+ return data
diff --git a/code/datums/diseases/advance/symptoms/synthetic_infection.dm b/code/datums/diseases/advance/symptoms/synthetic_infection.dm
index 7bd565ec9e7..987eaf5d7df 100644
--- a/code/datums/diseases/advance/symptoms/synthetic_infection.dm
+++ b/code/datums/diseases/advance/symptoms/synthetic_infection.dm
@@ -20,7 +20,7 @@ Bonus
stealth = 1
resistance = 2
stage_speed = 0
- transmittable = 1
+ transmission = 1
level = 5
severity = 3
diff --git a/code/datums/diseases/advance/symptoms/telepathy.dm b/code/datums/diseases/advance/symptoms/telepathy.dm
deleted file mode 100644
index c87e3178be7..00000000000
--- a/code/datums/diseases/advance/symptoms/telepathy.dm
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-//////////////////////////////////////
-
-Telepathy
-
- Hidden.
- Decreases resistance.
- Decreases stage speed significantly.
- Decreases transmittablity tremendously.
- Critical Level.
-
-Bonus
- The user gains telepathy.
-
-//////////////////////////////////////
-*/
-
-/datum/symptom/telepathy
- name = "Pineal Gland Decalcification"
- stealth = 2
- resistance = -2
- stage_speed = -3
- transmittable = -4
- level = 5
- severity = 0
-
-/datum/symptom/telepathy/Start(datum/disease/advance/A)
- if(iscarbon(A))
- var/mob/living/carbon/human/H = A.affected_mob
- // Traitgenes Locate the gene from trait
- var/datum/gene/trait/G = get_gene_from_trait(/datum/trait/positive/superpower_remotetalk)
- H.dna.SetSEState(G.block, 1)
- domutcheck(H, null, TRUE)
- H.UpdateAppearance()
- to_chat(H, span_notice("Your mind expands..."))
-
-/datum/symptom/telepathy/End(datum/disease/advance/A)
- if(iscarbon(A))
- var/mob/living/carbon/human/H = A.affected_mob
- // Traitgenes Locate the gene from trait
- var/datum/gene/trait/G = get_gene_from_trait(/datum/trait/positive/superpower_remotetalk)
- H.dna.SetSEState(G.block, 0)
- domutcheck(H, null, TRUE)
- H.UpdateAppearance()
- to_chat(H, span_notice("Everything feels... Normal."))
diff --git a/code/datums/diseases/advance/symptoms/viral.dm b/code/datums/diseases/advance/symptoms/viral.dm
index 3c901f371de..43b00aec538 100644
--- a/code/datums/diseases/advance/symptoms/viral.dm
+++ b/code/datums/diseases/advance/symptoms/viral.dm
@@ -14,29 +14,20 @@ BONUS
//////////////////////////////////////
*/
/datum/symptom/viraladaptation
- name = "Viral self-adaptation"
+ name = "Viral Self-Adaptation"
+ desc = "The virus mimics the function of normal body cells, becoming harder to spot and to eradicate, but reducing it's speed."
stealth = 3
resistance = 5
stage_speed = -3
- transmittable = 0
- level = 3
+ transmission = 0
+ level = 4
severity = 0
-/datum/symptom/viraladaptation/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(1)
- to_chat(M, span_notice("You feel off, but no different from before."))
- if(5)
- to_chat(M, span_notice("You feel better, but nothing interesting happens."))
-
/*
//////////////////////////////////////
Viral evolution
- Moderate stealth reductopn.
+ Moderate stealth reduction.
Major decreases to resistance.
increases stage speed.
increase to transmission
@@ -48,20 +39,134 @@ BONUS
//////////////////////////////////////
*/
/datum/symptom/viralevolution
- name = "Viral evolutionary acceleration"
+ name = "Viral Evolutionary Acceleration"
+ desc = "The virus quickly adapts to spread as fast as possible both outside and inside a host. This, however, makes the virus easier to spot, and les able to fight off a cure."
stealth = -2
resistance = -3
stage_speed = 5
- transmittable = 3
- level = 3
- severity = 0
+ transmission = 3
+ level = 4
-/datum/symptom/viralevolution/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
+/datum/symptom/viralpower
+ name = "Viral Power Multiplier"
+ desc = "The vrus has more powerful symptoms. May have unpredictable effects."
+ stealth = 2
+ resistance = 2
+ stage_speed = 2
+ transmission = 2
+ level = -1
+ var/maxpower
+ var/powerbudget
+ var/scramble = FALSE
+ var/used = FALSE
+
+ threshold_descs = list(
+ "Transmission 8" = "Constantly scrambles the power of all symptoms.",
+ "Stage Speed 8" = "Doubles the power boost."
+ )
+
+/datum/symptom/viralpower/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.speed >= 8)
+ power = 2
+ if(A.transmission >= 8)
+ scramble = TRUE
+
+/datum/symptom/viralpower/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ if(!used)
+ for(var/datum/symptom/S as() in A.symptoms)
+ if(S == src)
+ return
+ S.power += power
+ maxpower += S.power
+ if(scramble)
+ powerbudget += power
+ maxpower += power
+ power = 0
+ used = TRUE
+ if(scramble)
+ var/datum/symptom/S = pick(A.symptoms)
+ if(S == src)
+ return
+ if(powerbudget && (prob(50) || powerbudget == maxpower))
+ S.power += 1
+ powerbudget -= 1
+ else if(S.power >= 2)
+ S.power -= 1
+ powerbudget += 1
+
+/datum/symptom/viralreverse
+ name = "Viral Aggressive Metabolism"
+ desc = "The virus sacrifices its long term survivability to nearly instantly fully spread inside a host. \
+ The virus will start at the last stage, but will eventually decay and die off by itself."
+ stealth = 1
+ resistance = 1
+ stage_speed = 3
+ transmission = -4
+ level = 4
+ symptom_delay_min = 1
+ symptom_delay_max = 1
+ threshold_descs = list(
+ "Stage Speed" = "Highest between these determines the amount before self-curing.",
+ "Stealth 4" = "Doubles the time before the virus self-cures."
+ )
+
+ var/time_to_cure
+
+/datum/symptom/viralreverse/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ if(time_to_cure > 0)
+ time_to_cure--
+ else
var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(1)
- to_chat(M, span_notice("You feel better, but no different from before."))
- if(5)
- to_chat(M,span_notice("You feel off, but nothing interesting happens."))
+ Heal(M, A)
+
+/datum/symptom/viralreverse/proc/Heal(mob/living/M, datum/disease/advance/A)
+ A.stage -= 1
+ if(A.stage < 2)
+ to_chat(M, span_notice("You suddenly feel healthy."))
+ A.cure(FALSE)
+
+/datum/symptom/viralreverse/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ A.stage = 5
+ if(A.stealth >= 4)
+ power = 2
+ time_to_cure = max(A.resistance, A.stage_rate) * 10 * power
+
+/datum/symptom/viralincubate
+ name = "Viral Suspended Animation"
+ desc = "The virus has very little effect until it reaches its final stage"
+ stealth = 4
+ resistance = -2
+ stage_speed = -2
+ transmission = 1
+ level = 4
+ symptom_delay_min = 1
+ symptom_delay_max = 1
+ var/list/captives = list()
+ var/used = FALSE
+
+/datum/symptom/viralincubate/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stage >= 5)
+ for(var/datum/symptom/S as() in captives)
+ S.stopped = FALSE
+ captives -= S
+ if(!LAZYLEN(captives))
+ stopped = TRUE
+ else if(!used)
+ for(var/datum/symptom/S as() in A.symptoms)
+ if(S.neutered)
+ continue
+ if(S == src)
+ continue
+ S.stopped = TRUE
+ captives += S
+ used = TRUE
diff --git a/code/datums/diseases/advance/symptoms/vision.dm b/code/datums/diseases/advance/symptoms/vision.dm
index 2710124db43..62da7032a88 100644
--- a/code/datums/diseases/advance/symptoms/vision.dm
+++ b/code/datums/diseases/advance/symptoms/vision.dm
@@ -17,35 +17,69 @@ Bonus
/datum/symptom/visionloss
name = "Hyphema"
+ desc = "The virus causes inflammation of the retina, leading to eye damage and eventually blindness."
stealth = -1
- resistance = -4
+ resistance = -3
stage_speed = -4
- transmittable = -3
- level = 5
- severity = 4
+ transmission = -2
+ level = 3
+ severity = 2
+ base_message_chance = 50
+ symptom_delay_min = 30 SECONDS
+ symptom_delay_max = 80 SECONDS
+
+ var/remove_eyes = FALSE
+
+ threshold_descs = list(
+ "Resistance 12" = "Weakens extraocular muscles, eventually leading to complete detachment of the eyes.",
+ "Stealth 4" = "The symptom remains hidden until active."
+ )
+
+/datum/symptom/visionloss/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.resistance >= 12)
+ severity += 1
+
+/datum/symptom/visionloss/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stealth >= 4)
+ supress_warning = TRUE
+ if(A.resistance >= 12)
+ remove_eyes = TRUE
/datum/symptom/visionloss/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- 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)
+ if(!..())
+ return
+ if(iscarbon(A.affected_mob))
+ 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)
+ if(prob(base_message_chance) && !supress_warning && M.stat != DEAD)
to_chat(M, span_warning("Your eyes itch."))
- if(3, 4)
+ if(3, 4)
+ if(M.stat != DEAD)
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)
+ M.eye_blurry = 20
+ eyes.take_damage(1)
+ else
+ M.eye_blurry += 20
+ eyes.take_damage(5)
+ if(eyes.damage >= 10)
+ M.disabilities |= NEARSIGHTED
+ if(prob(eyes.damage - 10 + 1))
+ if(!remove_eyes)
+ if(!M.is_blind())
+ if(M.stat != DEAD)
to_chat(M, span_userdanger("You go blind!"))
- M.Blind(20)
+ eyes.take_damage(eyes.max_damage)
+ else
+ M.visible_message(span_warning("[M]'s eyes fall out of their sockets!"), span_userdanger("Your eyes out of their sockets!"))
+ eyes.forceMove(get_turf(M))
+
+ else
+ if(M.stat != DEAD)
+ to_chat(M, span_userdanger("Your eyes burn horrifically!"))
diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm
index 06c2b0fafbf..99dc0332bd3 100644
--- a/code/datums/diseases/advance/symptoms/vomit.dm
+++ b/code/datums/diseases/advance/symptoms/vomit.dm
@@ -17,18 +17,48 @@ Bonus
/datum/symptom/vomit
name = "Vomiting"
+ desc = "The virus causes nausea and irritates the stomach, causing occasional vomit."
stealth = -2
resistance = 0
stage_speed = 1
- transmittable = 2
+ transmission = 2
level = 3
severity = 1
+ base_message_chance = 100
+ symptom_delay_min = 20 SECONDS
+ symptom_delay_max = 60 SECONDS
+
+ var/vomit_blood = FALSE
+ var/proj_vomit = 1
+
+ threshold_descs = list(
+ "Stage Speed 5" = "Host will vomit blood.",
+ "Transmission 6" = "Host will projectile vomit, increasing vomit range.",
+ "Stealth 4" = "The symptom remans hidden until active."
+ )
+
+/datum/symptom/vomit/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stealth >= 4)
+ supress_warning = FALSE
+ if(A.stage_rate >= 5)
+ vomit_blood = TRUE
+ if(A.transmission >= 6)
+ proj_vomit = 5
/datum/symptom/vomit/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
- if(prob(2))
- to_chat(M, span_warning(pick("you feel nauseated.", "You feel like you're going to throw up!")))
- if(prob(SYMPTOM_ACTIVATION_PROB))
- M.vomit()
+ if(M.stat == DEAD)
+ return
+ switch(A.stage)
+ if(1, 2, 3, 4)
+ if(prob(base_message_chance) && !supress_warning)
+ to_chat(M, span_warning(pick("You feel nauseated.", "You feel like you're going to throw up!")))
+ else
+ vomit(M)
+
+/datum/symptom/vomit/proc/vomit(mob/living/carbon/M)
+ M.vomit(20, vomit_blood, stun = 2, distance = proj_vomit)
diff --git a/code/datums/diseases/advance/symptoms/weakness.dm b/code/datums/diseases/advance/symptoms/weakness.dm
index 917be5a46ce..219eff1481f 100644
--- a/code/datums/diseases/advance/symptoms/weakness.dm
+++ b/code/datums/diseases/advance/symptoms/weakness.dm
@@ -20,7 +20,9 @@ Bonus
stealth = -1
resistance = -1
stage_speed = -2
- transmittable = -2
+ transmission = -2
+ symptom_delay_min = 20 SECONDS
+ symptom_delay_max = 60 SECONDS
level = 3
severity = 3
diff --git a/code/datums/diseases/advance/symptoms/weigh.dm b/code/datums/diseases/advance/symptoms/weigh.dm
deleted file mode 100644
index ceca8a77f59..00000000000
--- a/code/datums/diseases/advance/symptoms/weigh.dm
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-//////////////////////////////////////
-
-Weight Loss
-
- Very Very Noticable.
- Decreases resistance.
- Decreases stage speed.
- Reduced Transmittable.
- High level.
-
-Bonus
- Decreases the weight of the mob,
- forcing it to be skinny.
-
-//////////////////////////////////////
-*/
-
-/datum/symptom/weight_loss
- name = "Weight Loss"
- stealth = -3
- resistance = -2
- stage_speed = -2
- transmittable = -2
- level = 3
- severity = 1
-
-/datum/symptom/weight_loss/Activate(datum/disease/advance/A)
- ..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
- var/mob/living/M = A.affected_mob
- switch(A.stage)
- if(1, 2, 3, 4)
- to_chat(M, span_warning(pick("You feel hungry.", "You crave for food.")))
- else
- to_chat(M, span_warning(pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")))
- M.adjust_nutrition(-20)
diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm
new file mode 100644
index 00000000000..88eba6323b9
--- /dev/null
+++ b/code/datums/diseases/advance/symptoms/weight.dm
@@ -0,0 +1,65 @@
+/*
+//////////////////////////////////////
+
+Weight Loss
+
+ Very Very Noticable.
+ Decreases resistance.
+ Decreases stage speed.
+ Reduced Transmittable.
+ High level.
+
+Bonus
+ Decreases the weight of the mob,
+ forcing it to be skinny.
+
+//////////////////////////////////////
+*/
+
+/datum/symptom/weight_loss
+ name = "Weight Loss"
+ desc = "The virus mutates the host's metabolism, making it almost unable to gain nutrition from food."
+ stealth = 0
+ resistance = 2
+ stage_speed = -2
+ transmission = -1
+ level = 3
+ severity = 2
+ base_message_chance = 100
+ symptom_delay_min = 15 SECONDS
+ symptom_delay_max = 45 SECONDS
+
+ var/starving = TRUE
+
+ threshold_descs = list(
+ "Stealth 2" = "The symptom is less noticeable, and does not cause starvation."
+ )
+
+/datum/symptom/weight_loss/severityset(datum/disease/advance/A)
+ . = ..()
+ if(A.stealth >= 2)
+ severity -= 3
+
+/datum/symptom/weight_loss/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.stealth >= 2)
+ base_message_chance = 25
+ starving = FALSE
+
+/datum/symptom/weight_loss/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ if(M.stat == DEAD)
+ return
+ switch(A.stage)
+ if(1, 2, 3, 4)
+ if(prob(base_message_chance))
+ to_chat(M, span_warning(pick("You feel hungry.", "You crave for food.")))
+ else
+ if(prob(base_message_chance))
+ to_chat(M, span_warning(pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")))
+ M.adjust_nutrition(rand(10, 50))
+ if(starving)
+ M.adjust_nutrition(-100)
diff --git a/code/datums/diseases/advance/symptoms/youth.dm b/code/datums/diseases/advance/symptoms/youth.dm
new file mode 100644
index 00000000000..6597a0ad375
--- /dev/null
+++ b/code/datums/diseases/advance/symptoms/youth.dm
@@ -0,0 +1,42 @@
+/datum/symptom/youth
+ name = "Eternal Youth"
+ desc = "The virus becomes symbiotically connected to the cells in the host's body, preventing and reversing aging. \
+ The virus, in turn, becomes more resistant, spreads faster, and is harder to spot, although it doesn't thrive as well without a host."
+ stealth = 3
+ resistance = 4
+ stage_speed = 4
+ transmission = -4
+ level = 5
+ base_message_chance = 100
+ symptom_delay_min = 25 SECONDS
+ symptom_delay_max = 50 SECONDS
+
+/datum/symptom/youth/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/M = A.affected_mob
+ if(M.stat == DEAD)
+ return
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ switch(A.stage)
+ if(1)
+ if(H.age > 41)
+ //H.age = 41
+ to_chat(H, span_notice("You haven't had this much energy in years!"))
+ if(2)
+ if(H.age > 36)
+ //H.age = 36
+ to_chat(H, span_notice("You're suddenly in a good mood."))
+ if(3)
+ if(H.age > 31)
+ //H.age = 31
+ to_chat(H, span_notice("You begin to feel more lithe."))
+ if(4)
+ if(H.age > 26)
+ //H.age = 26
+ to_chat(H, span_notice("You feel reinvigorated."))
+ if(5)
+ if(H.age > 21)
+ //H.age = 21
+ to_chat(H, span_notice("You feel like you can take on the world!"))
diff --git a/code/datums/diseases/anxiety.dm b/code/datums/diseases/anxiety.dm
index c3ed12fa5cc..19afe869243 100644
--- a/code/datums/diseases/anxiety.dm
+++ b/code/datums/diseases/anxiety.dm
@@ -3,17 +3,16 @@
form = "Infection"
max_stages = 4
spread_text = "On contact"
- spread_flags = CONTACT_GENERAL
+ spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS | DISEASE_SPREAD_CONTACT
cure_text = REAGENT_ETHANOL
cures = list(REAGENT_ID_ETHANOL)
agent = "Excess Lepdopticides"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
desc = "If left untreated subject will regurgitate butterflies."
- severity = MINOR
+ danger = DISEASE_MINOR
/datum/disease/anxiety/stage_act()
- if(!..())
- return FALSE
+ ..()
switch(stage)
if(2)
if(prob(15))
diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm
index a414c138e3c..66e467e9614 100644
--- a/code/datums/diseases/appendicitis.dm
+++ b/code/datums/diseases/appendicitis.dm
@@ -2,22 +2,20 @@
form = "Condition"
name = "Appendicitis"
max_stages = 3
- spread_text = "Non-contagius"
- spread_flags = NON_CONTAGIOUS
+ spread_text = "Non-contagious"
+ disease_flags = CAN_CARRY|CAN_RESIST|CAN_NOT_POPULATE
+ spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
+ virus_modifiers = NEEDS_ALL_CURES | BYPASSES_IMMUNITY
cure_text = "Surgery"
agent = "Shitty Appendix"
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|CAN_NOT_POPULATE
+ danger = DISEASE_MINOR
visibility_flags = HIDDEN_PANDEMIC
required_organs = list(/obj/item/organ/internal/appendix)
- bypasses_immunity = TRUE
- virus_heal_resistant = TRUE
/datum/disease/appendicitis/stage_act()
- if(!..())
- return
+ ..()
switch(stage)
if(1)
if(prob(5))
diff --git a/code/datums/diseases/beesease.dm b/code/datums/diseases/beesease.dm
index be6923c7106..716bd3eac1d 100644
--- a/code/datums/diseases/beesease.dm
+++ b/code/datums/diseases/beesease.dm
@@ -3,17 +3,16 @@
form = "Infection"
max_stages = 4
spread_text = "On contact"
- spread_flags = CONTACT_GENERAL
+ spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS | DISEASE_SPREAD_CONTACT
cure_text = REAGENT_SUGAR
cures = list(REAGENT_ID_SUGAR)
agent = "Apidae Infection"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
desc = "If left untreated, subject will regurgitate bees."
- severity = BIOHAZARD
+ danger = DISEASE_MEDIUM
/datum/disease/beesease/stage_act()
- if(!..())
- return FALSE
+ ..()
switch(stage)
if(2)
if(prob(2))
diff --git a/code/datums/diseases/brainrot.dm b/code/datums/diseases/brainrot.dm
index b7fa0ea033c..452b4cb238c 100644
--- a/code/datums/diseases/brainrot.dm
+++ b/code/datums/diseases/brainrot.dm
@@ -2,7 +2,7 @@
name = "Brainrot"
max_stages = 4
spread_text = "On contact"
- spread_flags = CONTACT_GENERAL
+ spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS | DISEASE_SPREAD_CONTACT
cure_text = REAGENT_ALKYSINE
cures = list(REAGENT_ID_ALKYSINE)
agent = "Cryptococcus Cosmosis"
@@ -10,11 +10,10 @@
cure_chance = 15
desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication."
required_organs = list(/obj/item/organ/internal/brain)
- severity = HARMFUL
+ danger = DISEASE_HARMFUL
/datum/disease/brainrot/stage_act()
- if(!..())
- return FALSE
+ ..()
switch(stage)
if(2)
if(prob(2))
diff --git a/code/datums/diseases/choreomania.dm b/code/datums/diseases/choreomania.dm
index 01802a78016..835b2296800 100644
--- a/code/datums/diseases/choreomania.dm
+++ b/code/datums/diseases/choreomania.dm
@@ -2,6 +2,7 @@
name = "Choreomania"
max_stages = 3
spread_text = "Airborne"
+ spread_flags = DISEASE_SPREAD_AIRBORNE | DISEASE_SPREAD_CONTACT | DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS
cure_text = REAGENT_ADRANOL
cures = list(REAGENT_ID_ADRANOL)
cure_chance = 10
@@ -9,13 +10,12 @@
viable_mobtypes = list(/mob/living/carbon/human)
permeability_mod = 0.75
desc = "If left untreated the subject... Won't stop dancing!"
- severity = MINOR
+ danger = DISEASE_MINOR
var/list/dance = list(2,4,8,2,4,8,2,4,8,2,4,8,1,4,1,4,1,4,2,4,8,2)
/datum/disease/choreomania/stage_act()
- if(!..())
- return FALSE
+ ..()
switch(stage)
if(2)
if(prob(1))
@@ -31,8 +31,6 @@
for(var/D in dance)
affected_mob.dir = D
animate(affected_mob, pixel_x = 5, time = 5)
- sleep(3)
animate(affected_mob, pixel_x = -5, time = 5)
- animate(pixel_x = affected_mob.default_pixel_x, pixel_y = affected_mob.default_pixel_x, time = 2)
- sleep(3)
+ animate(affected_mob, pixel_x = affected_mob.default_pixel_x, pixel_y = affected_mob.default_pixel_x, time = 2)
return
diff --git a/code/datums/diseases/cold.dm b/code/datums/diseases/cold.dm
index f9576f857b2..f88ba69bc22 100644
--- a/code/datums/diseases/cold.dm
+++ b/code/datums/diseases/cold.dm
@@ -2,19 +2,18 @@
name = "The Cold"
max_stages = 3
spread_text = "Airborne"
- spread_flags = AIRBORNE
+ spread_flags = DISEASE_SPREAD_AIRBORNE
cure_text = "Rest & " + REAGENT_SPACEACILLIN
cures = list(REAGENT_ID_SPACEACILLIN, REAGENT_ID_CHICKENSOUP)
- needs_all_cures = FALSE
+ virus_modifiers = NONE //Does NOT have needs_all_cures
agent = "XY-rhinovirus"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
permeability_mod = 0.5
desc = "If left untreated the subject will contract the flu."
- severity = MINOR
+ danger = DISEASE_MINOR
/datum/disease/cold/stage_act()
- if(!..())
- return FALSE
+ ..()
switch(stage)
if(2)
if(affected_mob.stat == UNCONSCIOUS && prob(40))
@@ -59,7 +58,7 @@
if(prob(1))
to_chat(affected_mob, span_notice("Mucous runs down the back of your throat."))
if(prob(1) && prob(50))
- if(!affected_mob.resistances.Find(/datum/disease/flu))
+ if(affected_mob.HasResistance(/datum/disease/flu))
var/datum/disease/Flu = new /datum/disease/flu(0)
affected_mob.ContractDisease(Flu)
cure()
diff --git a/code/datums/diseases/cold9.dm b/code/datums/diseases/cold9.dm
index ff82a5cfb57..0fdda21c10d 100644
--- a/code/datums/diseases/cold9.dm
+++ b/code/datums/diseases/cold9.dm
@@ -3,28 +3,43 @@
medical_name = "ICE9 Cold"
max_stages = 3
spread_text = "On contact"
- spread_flags = CONTACT_GENERAL
+ spread_flags = DISEASE_SPREAD_CONTACT | DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS
cure_text = REAGENT_SPACEACILLIN
cures = list(REAGENT_ID_SPACEACILLIN)
agent = "ICE9-rhinovirus"
viable_mobtypes = list(/mob/living/carbon/human)
desc = "If left untreated the subject will slow, as if partly frozen."
- severity = HARMFUL
+ danger = DISEASE_HARMFUL
/datum/disease/cold9/stage_act()
- if(!..())
- return FALSE
- if(stage < 2)
- return
-
- var/stage_factor = stage - 1
- affected_mob.bodytemperature -= 7.5 * stage_factor
- if(prob(2 * stage_factor))
- affected_mob.say("*sneeze")
- if(prob(2 * stage_factor))
- affected_mob.say("*cough")
- if(prob(3 * stage_factor))
- to_chat(affected_mob, span_danger("Your throat feels sore."))
- if(prob(5 * stage_factor))
- to_chat(affected_mob, span_danger("You feel stiff."))
- affected_mob.adjustFireLoss(1)
+ ..()
+ switch(stage)
+ if(1)
+ if(prob(1))
+ affected_mob.emote("sniff")
+ if(2)
+ if(prob(10))
+ affected_mob.bodytemperature -= 2
+ if(prob(1) && prob(10))
+ to_chat(affected_mob, span_notice("You feel better."))
+ cure()
+ return
+ if(prob(1))
+ affected_mob.emote("sneeze")
+ if(prob(1))
+ affected_mob.emote("cough")
+ if(prob(1))
+ to_chat(affected_mob, span_danger("Your throat feels sore."))
+ if(prob(5))
+ to_chat(affected_mob, span_danger("You feel stiff."))
+ if(3)
+ if(prob(10))
+ affected_mob.bodytemperature -= 5
+ if(prob(1))
+ affected_mob.emote("sneeze")
+ if(prob(1))
+ affected_mob.emote("cough")
+ if(prob(1))
+ to_chat(affected_mob, span_danger("Your throat feels sore."))
+ if(prob(10))
+ to_chat(affected_mob, span_danger("You feel stiff."))
diff --git a/code/datums/diseases/darkness.dm b/code/datums/diseases/darkness.dm
index b340ca5d45d..f8df462591b 100644
--- a/code/datums/diseases/darkness.dm
+++ b/code/datums/diseases/darkness.dm
@@ -7,4 +7,4 @@
agent = "Bluespace Exposure"
viable_mobtypes = list(/mob/living/carbon/human)
desc = "If left untreated, subject will lose grip on reality."
- severity = HARMFUL
+ danger = HARMFUL
diff --git a/code/datums/diseases/fake_gbs.dm b/code/datums/diseases/fake_gbs.dm
index 4ab932e8cde..3f8b49bd772 100644
--- a/code/datums/diseases/fake_gbs.dm
+++ b/code/datums/diseases/fake_gbs.dm
@@ -2,13 +2,13 @@
name = "GBS"
max_stages = 5
spread_text = "On contact"
- spread_flags = CONTACT_GENERAL
+ spread_flags = DISEASE_SPREAD_CONTACT | DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS
cure_text = REAGENT_ADRANOL + " & " + REAGENT_SULFUR
cures = list(REAGENT_ID_ADRANOL, REAGENT_ID_SULFUR)
agent = "Gravitokinetic Bipotential SADS-"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
desc = "if left untreated death will occur."
- severity = BIOHAZARD // Mimics real GBS
+ danger = DISEASE_BIOHAZARD // Mimics real GBS
/datum/disease/fake_gbs/stage_act()
if(!..())
diff --git a/code/datums/diseases/flu.dm b/code/datums/diseases/flu.dm
index 4152623124a..da6b7033380 100644
--- a/code/datums/diseases/flu.dm
+++ b/code/datums/diseases/flu.dm
@@ -4,17 +4,16 @@
spread_text = "Airborne"
cure_text = REAGENT_SPACEACILLIN
cures = list(REAGENT_ID_SPACEACILLIN, REAGENT_ID_CHICKENSOUP)
- needs_all_cures = FALSE
+ virus_modifiers = NONE //Does NOT have needs_all_cures
cure_chance = 10
agent = "H13N1 flu virion"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
permeability_mod = 0.75
desc = "If left untreated the subject will feel quite unwell."
- severity = MINOR
+ danger = DISEASE_MINOR
/datum/disease/flu/stage_act()
- if(!..())
- return FALSE
+ ..()
switch(stage)
if(2)
if(affected_mob.lying && prob(20))
diff --git a/code/datums/diseases/food_poisoning.dm b/code/datums/diseases/food_poisoning.dm
index bfb9aa445a7..529a5e07dc3 100644
--- a/code/datums/diseases/food_poisoning.dm
+++ b/code/datums/diseases/food_poisoning.dm
@@ -3,16 +3,14 @@
max_stages = 3
stage_prob = 5
spread_text = "Non-Contagious"
- spread_flags = NON_CONTAGIOUS
+ spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
cure_text = "Sleep"
agent = REAGENT_SALMONELLA
cures = list(REAGENT_ID_CHICKENSOUP)
cure_chance = 10
viable_mobtypes = list(/mob/living/carbon/human)
- desc = "Nausea, sickness, and vomitting."
- severity = MINOR
- disease_flags = CURABLE|CAN_NOT_POPULATE
- virus_heal_resistant = TRUE
+ desc = "Nausea, sickness, and vomiting."
+ danger = DISEASE_MINOR
/datum/disease/food_poisoning/stage_act()
if(!..())
diff --git a/code/datums/diseases/gbs.dm b/code/datums/diseases/gbs.dm
index 3da7052495c..cd97f6fac8f 100644
--- a/code/datums/diseases/gbs.dm
+++ b/code/datums/diseases/gbs.dm
@@ -2,13 +2,13 @@
name = "GBS"
max_stages = 5
spread_text = "On contact"
- spread_flags = CONTACT_GENERAL
+ spread_flags = DISEASE_SPREAD_CONTACT | DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS
cure_text = REAGENT_ADRANOL + " & " + REAGENT_SULFUR
cures = list(REAGENT_ID_ADRANOL, REAGENT_ID_SULFUR)
cure_chance = 15
agent = "Gravitokinetic Bipotential SADS+"
viable_mobtypes = list(/mob/living/carbon/human)
- severity = BIOHAZARD
+ danger = DISEASE_PANDEMIC
disease_flags = CAN_NOT_POPULATE
/datum/disease/gbs/stage_act()
@@ -42,7 +42,7 @@
name = "Non-Contagious GBS"
stage_prob = 5
spread_text = "Non-contagious"
- spread_flags = NON_CONTAGIOUS
+ spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
cure_text = REAGENT_CRYOXADONE
cures = list(REAGENT_ID_CRYOXADONE)
cure_chance = 10
diff --git a/code/datums/diseases/lycancoughy.dm b/code/datums/diseases/lycancoughy.dm
index 7aba6ffc6ae..9172db1e119 100644
--- a/code/datums/diseases/lycancoughy.dm
+++ b/code/datums/diseases/lycancoughy.dm
@@ -3,13 +3,13 @@
form = "Infection"
max_stages = 4
spread_text = "On contact"
- spread_flags = CONTACT_GENERAL
+ spread_flags = DISEASE_SPREAD_CONTACT | DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_FLUIDS
cure_text = REAGENT_ETHANOL
cures = list(REAGENT_ID_ETHANOL)
agent = "Excess Snuggles"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
desc = "If left untreated subject will regurgitate... puppies."
- severity = HARMFUL
+ danger = DISEASE_HARMFUL
var/barklimit
var/list/puppy_types = list(/mob/living/simple_mob/animal/passive/dog/corgi/puppy)
var/list/plush_types = list(/obj/item/toy/plushie/orange_fox, /obj/item/toy/plushie/corgi, /obj/item/toy/plushie/robo_corgi, /obj/item/toy/plushie/pink_fox)
diff --git a/code/datums/diseases/magnitis.dm b/code/datums/diseases/magnitis.dm
index e791bb6c880..e0a80afe1d5 100644
--- a/code/datums/diseases/magnitis.dm
+++ b/code/datums/diseases/magnitis.dm
@@ -8,7 +8,7 @@
viable_mobtypes = list(/mob/living/carbon/human)
permeability_mod = 0.75
desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field."
- severity = MINOR
+ danger = DISEASE_MINOR
/datum/disease/magnitis/stage_act()
if(!..())
diff --git a/code/datums/diseases/roanoake.dm b/code/datums/diseases/roanoake.dm
index dac36d609f4..4e884004b63 100644
--- a/code/datums/diseases/roanoake.dm
+++ b/code/datums/diseases/roanoake.dm
@@ -10,10 +10,9 @@
cure_chance = 10
viable_mobtypes = list(/mob/living/carbon/human)
desc = "If left untreated, subject will become a xenochimera upon perishing."
- severity = BIOHAZARD
+ danger = DISEASE_BIOHAZARD
disease_flags = CURABLE
- virus_heal_resistant = TRUE
- allow_dead = TRUE
+ //allow_dead = TRUE //Unused
var/list/obj/item/organ/organ_list = list()
var/obj/item/organ/O
diff --git a/code/datums/outfits/jobs/medical.dm b/code/datums/outfits/jobs/medical.dm
index 6a4d120d37d..6e34c37b2bf 100644
--- a/code/datums/outfits/jobs/medical.dm
+++ b/code/datums/outfits/jobs/medical.dm
@@ -50,6 +50,7 @@
mask = /obj/item/clothing/mask/surgical
backpack = /obj/item/storage/backpack/virology
satchel_one = /obj/item/storage/backpack/satchel/vir
+ belt = /obj/item/extrapolator
/decl/hierarchy/outfit/job/medical/doctor/nurse
name = OUTFIT_JOB_NAME(JOB_ALT_NURSE)
diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm
index f31fbc7b45d..7bf3047c089 100644
--- a/code/datums/supplypacks/medical.dm
+++ b/code/datums/supplypacks/medical.dm
@@ -351,7 +351,7 @@
/datum/supply_pack/med/virus
name = "Virus culture crate"
desc = "Glass bottles with viral cultures. HANDLE WITH CARE. Requires Chief Medical Officer access."
- contains = list(/obj/item/reagent_containers/glass/bottle/culture/cold = 1, /obj/item/reagent_containers/glass/bottle/culture/flu = 1)
+ contains = list(/obj/item/reagent_containers/glass/beaker/vial/culture/cold = 1, /obj/item/reagent_containers/glass/beaker/vial/culture/flu = 1)
cost = 25
containertype = /obj/structure/closet/crate/secure/zenghu
containername = "Virus culture crate"
@@ -425,7 +425,7 @@
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
+ /obj/item/reagent_containers/glass/beaker/vial/culture/random_virus = 1
)
cost = 60
containertype = /obj/structure/closet/crate/freezer
@@ -435,7 +435,7 @@
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
+ /obj/item/reagent_containers/glass/beaker/vial/culture/random_virus/minor = 1
)
cost = 40
containertype = /obj/structure/closet/crate/freezer
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index a2704880168..7e3ecc2e4b1 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -483,17 +483,6 @@
. = 1
return 1
-/atom/proc/add_vomit_floor(mob/living/carbon/M as mob, var/toxvomit = 0)
- if( istype(src, /turf/simulated) )
- var/obj/effect/decal/cleanable/vomit/this = new /obj/effect/decal/cleanable/vomit(src)
-
- for(var/datum/disease/D in M.GetViruses())
- this.viruses |= D.Copy()
-
- // Make toxins vomit look different
- if(toxvomit)
- this.icon_state = "vomittox_[pick(1,4)]"
-
/atom/proc/clean_blood()
if(!simulated)
return
@@ -853,3 +842,15 @@ GLOBAL_LIST_EMPTY(icon_dimensions)
var/icon/my_icon = icon(icon_path)
GLOB.icon_dimensions[icon_path] = list("width" = my_icon.Width(), "height" = my_icon.Height())
return GLOB.icon_dimensions[icon_path]
+
+/**
+* Respond to our atom being checked by a virus extrapolator.
+*
+* Default behaviour is to send COMSIG_ATOM_EXTRAPOLATOR_ACT and return an empty list (which may be populated by the signal)
+*
+* Returns a list of viruses in the atom.
+* Include EXTRAPOLATOR_SPECIAL_HANDLED in the list if the extrapolation act has been handled by this proc or a signal, and should not be handled by the extrapolator itself.
+*/
+/atom/proc/extrapolator_act(mob/living/user, obj/item/extrapolator/extrapolator, dry_run = FALSE)
+ . = list(EXTRAPOLATOR_RESULT_DISEASES = list())
+ SEND_SIGNAL(src, COMSIG_ATOM_EXTRAPOLATOR_ACT, user, extrapolator, dry_run, .)
diff --git a/code/game/jobs/job/job_goodies.dm b/code/game/jobs/job/job_goodies.dm
index f4512d39fca..90ec8b2c1f7 100644
--- a/code/game/jobs/job/job_goodies.dm
+++ b/code/game/jobs/job/job_goodies.dm
@@ -511,8 +511,8 @@
/obj/item/storage/pill_bottle/spaceacillin = 150,
/obj/item/clothing/mask/surgical = 150,
/obj/item/clothing/gloves/sterile/latex = 150,
- /obj/item/reagent_containers/glass/bottle/culture/cold = 150,
- /obj/item/reagent_containers/glass/bottle/culture/flu = 150,
+ /obj/item/reagent_containers/glass/beaker/vial/culture/random_virus/minor = 150,
+ /obj/item/reagent_containers/glass/beaker/vial/culture/random_virus = 150,
/obj/item/reagent_containers/blood/OMinus = 100,
)
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 425a94528d4..6e5cccb616e 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -188,7 +188,7 @@
occupantData["health"] = H.health
occupantData["maxHealth"] = H.getMaxHealth()
- occupantData["hasVirus"] = LAZYLEN(H.viruses)
+ occupantData["hasVirus"] = H.IsInfected()
occupantData["bruteLoss"] = H.getBruteLoss()
occupantData["oxyLoss"] = H.getOxyLoss()
@@ -379,7 +379,7 @@
dat += (occupant.health > (occupant.getMaxHealth() / 2) ? span_blue(health_text) : span_red(health_text))
dat += "
"
- if(LAZYLEN(occupant.viruses))
+ if(occupant.IsInfected())
for(var/datum/disease/D in occupant.GetViruses())
if(D.visibility_flags & HIDDEN_SCANNER)
continue
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index 0b24e9276e2..e6cb5dc9003 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -173,7 +173,7 @@
if(MED_DATA_V_DATA)
data["virus"] = list()
for(var/datum/disease/D in GLOB.active_diseases)
- if(!D.discovered)
+ if(!global_flag_check(D.virus_modifiers, DISCOVERED))
continue
var/datum/data/record/v = GLOB.active_diseases[D]
data["virus"] += list(list("name" = v.fields["name"], "D" = "\ref[v]"))
diff --git a/code/game/machinery/pandemic.dm b/code/game/machinery/pandemic.dm
index dd245e07967..99ff2859db9 100644
--- a/code/game/machinery/pandemic.dm
+++ b/code/game/machinery/pandemic.dm
@@ -6,15 +6,16 @@
anchored = TRUE
icon = 'icons/obj/pandemic.dmi'
icon_state = "pandemic0"
+ idle_power_usage = 20
+ use_power = TRUE
+
var/temp_html = ""
- var/printing = null
- var/wait = null
- var/selected_strain_index = 1
+ var/printing = FALSE
+ var/wait = FALSE
var/obj/item/reagent_containers/beaker = null
-// PanDEMIC Bottle
-/obj/item/reagent_containers/glass/bottle/vaccine
- icon_state = "bottle10"
+// PanDEMIC Vial
+/obj/item/reagent_containers/glass/beaker/vial/vaccine
possible_transfer_amounts = (list(5, 10, 15))
volume = 15
@@ -26,200 +27,59 @@
stat |= BROKEN
update_icon()
-/obj/machinery/computer/pandemic/proc/GetViruses()
- if(beaker && beaker.reagents)
- if(length(beaker.reagents.reagent_list))
- var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
- if(BL)
- if(BL.data && BL.data["viruses"])
- var/list/viruses = BL.data["viruses"]
- return viruses
-
-/obj/machinery/computer/pandemic/proc/GetVirusByIndex(index)
- var/list/viruses = GetViruses()
- if(viruses && index > 0 && index <= length(viruses))
- return viruses[index]
-
-/obj/machinery/computer/pandemic/proc/GetResistances()
- if(beaker && beaker.reagents)
- if(length(beaker.reagents.reagent_list))
- var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
- if(BL)
- if(BL.data && BL.data["resistances"])
- var/list/resistances = BL.data["resistances"]
- return resistances
-
-/obj/machinery/computer/pandemic/proc/GetResistancesByIndex(index)
- var/list/resistances = GetResistances()
- if(resistances && index > 0 && index <= length(resistances))
- return resistances[index]
-
-/obj/machinery/computer/pandemic/proc/GetVirusTypeByIndex(index)
- var/datum/disease/D = GetVirusByIndex(index)
- if(D)
- return D.GetDiseaseID()
-
-/obj/machinery/computer/pandemic/proc/replicator_cooldown(waittime)
- wait = 1
- update_icon()
- spawn(waittime)
- wait = null
- update_icon()
- playsound(loc, 'sound/machines/ping.ogg', 30, 1)
-
/obj/machinery/computer/pandemic/update_icon()
if(stat & BROKEN)
icon_state = (beaker ? "pandemic1_b" : "pandemic0_b")
return
icon_state = "pandemic[(beaker)?"1":"0"][!(stat & NOPOWER) ? "" : "_nopower"]"
-/obj/machinery/computer/pandemic/proc/create_culture(name, bottle_type = "culture", cooldown = 50, vaccine = FALSE)
-
- var/obj/item/reagent_containers/glass/bottle/B
- if(vaccine)
- B = new /obj/item/reagent_containers/glass/bottle/vaccine(loc)
- B.name = "[name] vaccine"
- else
- B = new(loc)
- B.icon_state = "bottle10"
- B.name = "[name] [bottle_type] bottle"
-
- B.pixel_x = rand(-3, 3)
- B.pixel_y = rand(-3, 3)
- replicator_cooldown(cooldown)
- return B
-
/obj/machinery/computer/pandemic/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state)
- if(..())
+ . = ..()
+ if(.)
return
if(inoperable())
return
- . = TRUE
-
switch(action)
- if("clone_strain")
+ if("create_culture_bottle")
+ if(wait)
+ return FALSE
+ create_culture_bottle(params["index"])
+ return TRUE
+ if("create_vaccine_bottle")
if(wait)
atom_say("The replicator is not ready yet.")
- return
-
- var/strain_index = text2num(params["strain_index"])
- if(isnull(strain_index))
- atom_say("Unable to respond to command.")
- return
- var/datum/disease/virus = GetVirusByIndex(strain_index)
- var/datum/disease/D = null
- if(!virus)
- atom_say("Unable to find requested strain.")
- return
- var/type = virus.GetDiseaseID()
- if(!ispath(type))
- var/datum/disease/advance/A = GLOB.archive_diseases[type]
- if(A)
- D = new A.type(0, A)
- else if(type)
- if(type in GLOB.diseases) // Make sure this is a disease
- D = new type(0, null)
- if(!D)
- atom_say("Unable to synthesize requested strain.")
- return
- var/default_name = ""
- if(D.name == "Unknown" || D.name == "")
- default_name = replacetext(beaker.name, new/regex(" culture bottle\\Z", "g"), "")
- else
- default_name = D.name
- var/name = tgui_input_text(ui.user, "Name:", "Name the culture", default_name, MAX_NAME_LEN)
- if(name == null || wait)
- return
- var/obj/item/reagent_containers/glass/bottle/B = create_culture(name)
- B.desc = "A small bottle. Contains [D.agent] culture in synthblood medium."
- B.reagents.add_reagent(REAGENT_ID_BLOOD, 20, list("viruses" = list(D)))
- if("clone_vaccine")
- if(wait)
- atom_say("The replicator is not ready yet.")
- return
-
- var/resistance_index = text2num(params["resistance_index"])
- if(isnull(resistance_index))
- atom_say("Unable to find requested antibody.")
- return
- var/vaccine_type = GetResistancesByIndex(resistance_index)
- var/vaccine_name = "Unknown"
- if(!ispath(vaccine_type))
- if(GLOB.archive_diseases[vaccine_type])
- var/datum/disease/D = GLOB.archive_diseases[vaccine_type]
- if(D)
- vaccine_name = D.name
- else if(vaccine_type)
- var/datum/disease/D = new vaccine_type(0, null)
- if(D)
- vaccine_name = D.name
-
- if(!vaccine_type)
- atom_say("Unable to synthesize requested antibody.")
- return
-
- var/obj/item/reagent_containers/glass/bottle/vaccine/B = create_culture(vaccine_name, REAGENT_ID_VACCINE, 200, TRUE)
- B.reagents.add_reagent(REAGENT_ID_VACCINE, 15, list(vaccine_type))
- if(beaker && beaker.reagents && length(beaker.reagents.reagent_list))
- beaker.reagents.remove_reagent(REAGENT_ID_BLOOD, 5)
- if(!length(beaker.reagents.reagent_list))
- update_tgui_static_data(ui.user)
-
+ return FALSE
+ create_vaccine_bottle(params["index"])
+ return TRUE
if("eject_beaker")
eject_beaker()
update_tgui_static_data(ui.user)
+ return TRUE
if("destroy_eject_beaker")
beaker.reagents.clear_reagents()
eject_beaker()
update_tgui_static_data(ui.user)
- if("print_release_forms")
- var/strain_index = text2num(params["strain_index"])
+ return TRUE
+ if("empty_beaker")
+ beaker.reagents.clear_reagents()
+ return TRUE
+ if("rename_disease")
+ rename_disease(params["index"], params["name"])
+ return TRUE
+ if("print_release_form")
+ var/strain_index = text2num(params["index"])
if(isnull(strain_index))
atom_say("Unable to respond to command.")
- return
- var/type = GetVirusTypeByIndex(strain_index)
+ return FALSE
+ var/type = get_virus_id_by_index(strain_index)
if(!type)
atom_say("Unable to find requested strain.")
- return
+ return FALSE
var/datum/disease/advance/A = GLOB.archive_diseases[type]
if(!A)
atom_say("Unable to find requested strain.")
- return
- print_form(A, ui.user)
- if("name_strain")
- var/strain_index = text2num(params["strain_index"])
- if(isnull(strain_index))
- atom_say("Unable to respond to command.")
- return
- var/type = GetVirusTypeByIndex(strain_index)
- if(!type)
- atom_say("Unable to find requested strain.")
- return
- var/datum/disease/advance/A = GLOB.archive_diseases[type]
- if(!A)
- atom_say("Unable to find requested strain.")
- return
- if(A.name != "Unknown")
- atom_say("Request rejected. Strain already has a name.")
- return
- var/new_name = tgui_input_text(ui.user, "Name the Strain", "New Name", max_length = MAX_NAME_LEN)
- if(!new_name)
- return
- A.AssignName(new_name)
- for(var/datum/disease/advance/AD in GLOB.active_diseases)
- AD.Refresh()
- update_tgui_static_data(ui.user)
- if("switch_strain")
- var/strain_index = text2num(params["strain_index"])
- if(isnull(strain_index) || strain_index < 1)
- atom_say("Unable to respond to command.")
- return
- var/list/viruses = GetViruses()
- if(strain_index > length(viruses))
- atom_say("Unable to find requested strain.")
- return
- selected_strain_index = strain_index;
+ return FALSE
else
return FALSE
@@ -229,86 +89,35 @@
/obj/machinery/computer/pandemic/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
- ui = new(user, src, "PanDEMIC", name)
+ ui = new(user, src, "Pandemic", name)
ui.open()
/obj/machinery/computer/pandemic/tgui_data(mob/user)
- var/datum/reagent/blood/Blood = null
- if(beaker)
- var/datum/reagents/R = beaker.reagents
- for(var/datum/reagent/blood/B in R.reagent_list)
- if(B)
- Blood = B
- break
-
- var/list/data = list(
- "synthesisCooldown" = wait ? TRUE : FALSE,
- "beakerLoaded" = beaker ? TRUE : FALSE,
- "beakerContainsBlood" = Blood ? TRUE : FALSE,
- "beakerContainsVirus" = length(Blood?.data["viruses"]) != 0,
- "selectedStrainIndex" = selected_strain_index,
+ var/list/data = list()
+ data["is_ready"] = !wait
+ if(!beaker)
+ data["has_beaker"] = FALSE
+ data["has_blood"] = FALSE
+ return data
+ data["has_beaker"] = TRUE
+ data["beaker"] = list(
+ "volume" = round(beaker.reagents?.total_volume, 0.01) || 0,
+ "capacity" = beaker.volume
)
+ var/datum/reagent/blood/blood = locate() in beaker.reagents.reagent_list
+ if(!blood)
+ data["has_blood"] = FALSE
+ return data
+
+ data["has_blood"] = TRUE
+ data["blood"] = list()
+ data["blood"]["dna"] = blood.data["blood_DNA"] || "none"
+ data["blood"]["type"] = blood.data["blood_type"] || "none"
+ data["viruses"] = get_viruses_data(blood)
+ data["resistances"] = get_resistance_data(blood)
return data
-/obj/machinery/computer/pandemic/tgui_static_data(mob/user)
- var/list/data = list()
- . = data
-
- var/datum/reagent/blood/Blood = null
- if(beaker)
- var/datum/reagents/R = beaker.reagents
- for(var/datum/reagent/blood/B in R.reagent_list)
- if(B)
- Blood = B
- break
-
- var/list/strains = list()
- for(var/datum/disease/D in GetViruses())
- if(D.visibility_flags & HIDDEN_PANDEMIC)
- continue
-
- var/list/symptoms = list()
- if(istype(D, /datum/disease/advance))
- var/datum/disease/advance/A = D
- D = GLOB.archive_diseases[A.GetDiseaseID()]
- if(!D)
- CRASH("We weren't able to get the advance disease from the archive.")
- for(var/datum/symptom/S in A.symptoms)
- symptoms += list(list(
- "name" = S.name,
- "stealth" = S.stealth,
- "resistance" = S.resistance,
- "stageSpeed" = S.stage_speed,
- "transmissibility" = S.transmittable,
- "complexity" = S.level,
- ))
-
- strains += list(list(
- "commonName" = D.name,
- "description" = D.desc,
- "bloodDNA" = Blood.data["blood_DNA"],
- "bloodType" = Blood.data["blood_type"],
- "diseaseAgent" = D.agent,
- "possibleTreatments" = D.cure_text,
- "transmissionRoute" = D.spread_text,
- "symptoms" = symptoms,
- "isAdvanced" = istype(D, /datum/disease/advance),
- ))
- data["strains"] = strains
-
- var/list/resistances = list()
- for(var/resistance in GetResistances())
- if(!ispath(resistance))
- var/datum/disease/D = GLOB.archive_diseases[resistance]
- if(D)
- resistances += list(D.name)
- else if(resistance)
- var/datum/disease/D = new resistance(0, null)
- if(D)
- resistances += list(D.name)
- data["resistances"] = resistances
-
/obj/machinery/computer/pandemic/proc/eject_beaker()
set name = "Eject Beaker"
set category = "Object"
@@ -320,10 +129,13 @@
beaker.forceMove(loc)
beaker = null
icon_state = "pandemic0"
- selected_strain_index = 1
/obj/machinery/computer/pandemic/proc/print_form(datum/disease/advance/D, mob/living/user)
D = GLOB.archive_diseases[D.GetDiseaseID()]
+ if(!istype(D))
+ visible_message(span_warning("ERROR: Unable to print form."))
+ playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 1)
+ return
if(!(printing) && D)
var/reason = tgui_input_text(user,"Enter a reason for the release", "Write", multiline = TRUE)
if(!reason)
@@ -333,7 +145,7 @@
for(var/I in D.symptoms)
var/datum/symptom/S = I
english_symptoms += S.name
- var/symtoms = english_list(english_symptoms)
+ var/symptoms = english_list(english_symptoms)
var/signature
if(tgui_alert(user, "Would you like to add your signature?", "Signature", list("Yes","No")) == "Yes")
@@ -341,7 +153,7 @@
else
signature = ""
- printing = 1
+ printing = TRUE
var/obj/item/paper/P = new /obj/item/paper(loc)
visible_message(span_notice("[src] rattles and prints out a sheet of paper."))
playsound(loc, 'sound/machines/printer.ogg', 50, 1)
@@ -349,7 +161,7 @@
P.info = span_underline(span_huge(span_bold("