[MIRROR] Disease Outbreak: Advanced v3 [MDB IGNORE] (#19174)

* Disease Outbreak: Advanced v3

* Update disease_outbreak.dm

---------

Co-authored-by: lessthanthree <83487515+lessthnthree@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-02-12 12:15:07 -08:00
committed by GitHub
co-authored by lessthanthree
parent 5d5c1b8e56
commit 5b855c4fe5
2 changed files with 271 additions and 48 deletions
+258 -48
View File
@@ -1,3 +1,24 @@
/// Advanced virus lower limit for symptoms
#define ADV_MIN_SYMPTOMS 3
/// Advanced virus upper limit for symptoms
#define ADV_MAX_SYMPTOMS 4
/// How long the virus stays hidden before announcement
#define ADV_ANNOUNCE_DELAY 75
/// Numerical define for medium severity advanced virus
#define ADV_DISEASE_MEDIUM 4
/// Numerical define for harmful severity advanced virus
#define ADV_DISEASE_HARMFUL 5
/// Numerical define for dangerous severity advanced virus
#define ADV_DISEASE_DANGEROUS 7
/// Percentile for low severity advanced virus
#define ADV_RNG_LOW 30
/// Percentile for mid severity advanced virus
#define ADV_RNG_MID 85
/// Percentile for low transmissibility advanced virus
#define ADV_SPREAD_LOW 30
/// Percentile for mid transmissibility advanced virus
#define ADV_SPREAD_MID 90
/datum/round_event_control/disease_outbreak
name = "Disease Outbreak: Classic"
typepath = /datum/round_event/disease_outbreak
@@ -5,7 +26,7 @@
min_players = 10
weight = 5
category = EVENT_CATEGORY_HEALTH
description = "A 'classic' virus will infect some members of the crew." //These are the ones with PERSONALITY
description = "A 'classic' virus will infect some members of the crew."
admin_setup = /datum/event_admin_setup/disease_outbreak
///Disease recipient candidates
var/list/disease_candidates = list()
@@ -35,8 +56,31 @@
continue
disease_candidates += candidate
/datum/event_admin_setup/disease_outbreak
///Admin selected disease, to be passed down to the round_event
var/virus_type
/// Checks for candidates. Returns false if there isn't enough
/datum/event_admin_setup/disease_outbreak/proc/candidate_check()
var/datum/round_event_control/disease_outbreak/disease_control = event_control
disease_control.generate_candidates() //can_spawn_event() is bypassed by admin_setup, so this makes sure that the candidates are still generated
return length(disease_control.disease_candidates)
/datum/event_admin_setup/disease_outbreak/prompt_admins()
var/candidate_count = candidate_check()
if(!candidate_count)
tgui_alert(usr, "There are no candidates eligible to recieve a disease!", "Error")
return ADMIN_CANCEL_EVENT
tgui_alert(usr, "[candidate_count] candidates found!", "Disease Outbreak")
if(tgui_alert(usr, "Select a specific disease?", "Sickening behavior", list("Yes", "No")) == "Yes")
virus_type = tgui_input_list(usr, "Warning: Some of these are EXTREMELY dangerous.","Bacteria Hysteria", subtypesof(/datum/disease))
/datum/event_admin_setup/disease_outbreak/apply_to_event(datum/round_event/disease_outbreak/event)
event.virus_type = virus_type
/datum/round_event/disease_outbreak
announce_when = 120
announce_when = ADV_ANNOUNCE_DELAY
///The disease type we will be spawning
var/datum/disease/virus_type
///Disease recipient candidates, passed from the round_event_control object
@@ -46,7 +90,7 @@
priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", ANNOUNCER_OUTBREAK7)
/datum/round_event/disease_outbreak/setup()
announce_when = rand(60, 180)
announce_when = ADV_ANNOUNCE_DELAY
/datum/round_event/disease_outbreak/start()
var/datum/round_event_control/disease_outbreak/disease_event = control
@@ -83,81 +127,247 @@
name = "Disease Outbreak: Advanced"
typepath = /datum/round_event/disease_outbreak/advanced
category = EVENT_CATEGORY_HEALTH
description = "An 'advanced' disease will infect some members of the crew." //These are the ones that get viro lynched!
weight = 10
description = "An 'advanced' disease will infect some members of the crew."
admin_setup = /datum/event_admin_setup/disease_outbreak/advanced
/datum/event_admin_setup/disease_outbreak/advanced
///Admin selected custom severity rating for the event
var/chosen_severity
///Admin selected custom value for the maximum symptoms this virus should have
var/chosen_max_symptoms
/**
* Admin virus customization
*
* If the admin wishes, give them the opportunity to select the severity and number of symptoms.
*/
/datum/event_admin_setup/disease_outbreak/advanced/prompt_admins()
var/candidate_count = candidate_check()
if(!candidate_count)
tgui_alert(usr, "There are no candidates eligible to recieve a disease!", "Error")
return ADMIN_CANCEL_EVENT
tgui_alert(usr, "[candidate_count] candidates found!", "Disease Outbreak")
if(tgui_alert(usr,"Customize your virus?", "Glorified Debug Tool", list("Yes", "No")) == "Yes")
chosen_severity = tgui_alert(usr, "Pick a severity!", "In the event of an airborne virus, try not to breathe.", list("Medium", "Harmful", "Dangerous"))
switch(chosen_severity)
if("Medium")
chosen_severity = ADV_DISEASE_MEDIUM
if("Harmful")
chosen_severity = ADV_DISEASE_HARMFUL
if("Dangerous")
chosen_severity = ADV_DISEASE_DANGEROUS
else
return ADMIN_CANCEL_EVENT
chosen_max_symptoms = tgui_input_number(usr, "How many symptoms do you want your virus to have?", "A pox upon ye!", 4, 15)
else
chosen_severity = null
chosen_max_symptoms = null
if(tgui_alert(usr,"Are you happy with your selections?", "Epidemic warning, Standby!", list("Yes", "Cancel")) != "Yes")
return ADMIN_CANCEL_EVENT
/datum/event_admin_setup/disease_outbreak/advanced/apply_to_event(datum/round_event/disease_outbreak/advanced/event)
event.max_severity = chosen_severity
event.max_symptoms = chosen_max_symptoms
/datum/round_event/disease_outbreak/advanced
///Number of symptoms for our virus
var/max_severity
//Maximum symptoms for our virus
var/max_symptoms
/**
* Generate virus base values
*
* Generates a virus with either the admin selected parameters for severity and symptoms
* or if it was not selected, randomly pick between the MIX and MAX configured in the defines.
*/
/datum/round_event/disease_outbreak/advanced/start()
var/datum/round_event_control/disease_outbreak/advanced/disease_event = control
afflicted += disease_event.disease_candidates
disease_event.disease_candidates.Cut() //Clean the list after use
disease_event.disease_candidates.Cut()
if(!max_symptoms)
max_symptoms = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes.
max_symptoms = clamp(max_symptoms, 3, 8) //Capping the virus symptoms prevents the event from becoming "smite one poor player with an -12 transmission hell virus" after a certain round length.
max_symptoms = rand(ADV_MIN_SYMPTOMS, ADV_MAX_SYMPTOMS)
if(!max_severity)
max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //Max severity doesn't need clamping
var/rng_severity = rand(1, 100)
if(rng_severity < ADV_RNG_LOW)
max_severity = ADV_DISEASE_MEDIUM
var/datum/disease/advance/advanced_disease = new /datum/disease/advance/random(max_symptoms, max_severity)
else if(rng_severity < ADV_RNG_MID)
max_severity = ADV_DISEASE_HARMFUL
var/list/name_symptoms = list() //for feedback
for(var/datum/symptom/new_symptom in advanced_disease.symptoms)
else
max_severity = ADV_DISEASE_DANGEROUS
var/datum/disease/advance/advanced_disease = new /datum/disease/advance/random/event(max_symptoms, max_severity)
var/list/name_symptoms = list()
for(var/datum/symptom/new_symptom as anything in advanced_disease.symptoms)
name_symptoms += new_symptom.name
var/mob/living/carbon/human/victim = pick_n_take(afflicted)
if(victim.ForceContractDisease(advanced_disease, FALSE))
message_admins("An event has triggered a random advanced virus outbreak on [ADMIN_LOOKUPFLW(victim)]! It has these symptoms: [english_list(name_symptoms)]")
log_game("An event has triggered a random advanced virus outbreak on [key_name(victim)]! It has these symptoms: [english_list(name_symptoms)].")
message_admins("An event has triggered a random advanced virus outbreak on [ADMIN_LOOKUPFLW(victim)]! It has these symptoms: [english_list(name_symptoms)]. It is transmissable via [advanced_disease.spread_text].")
log_game("An event has triggered a random advanced virus outbreak on [key_name(victim)]! It has these symptoms: [english_list(name_symptoms)]. It is transmissable via [advanced_disease.spread_text].")
announce_to_ghosts(victim)
else
log_game("An event attempted to trigger a random advanced virus outbreak on [key_name(victim)], but failed.")
/datum/event_admin_setup/disease_outbreak
///Admin selected disease, to be passed down to the round_event
var/virus_type
/datum/disease/advance/random/event
name = "Experimental Disease"
copy_type = /datum/disease/advance
/// Checks for candidates. Returns false if there isn't enough
/datum/event_admin_setup/disease_outbreak/proc/candidate_check()
var/datum/round_event_control/disease_outbreak/disease_control = event_control
disease_control.generate_candidates() //can_spawn_event() is bypassed by admin_setup, so this makes sure that the candidates are still generated
return length(disease_control.disease_candidates)
/datum/round_event/disease_outbreak/advance/setup()
announce_when = ADV_ANNOUNCE_DELAY
/datum/event_admin_setup/disease_outbreak/prompt_admins()
var/candidate_count = candidate_check()
if(!candidate_check())
tgui_alert(usr, "There are no candidates eligible to recieve a disease!", "Error")
return ADMIN_CANCEL_EVENT
tgui_alert(usr, "[candidate_count] candidates found!", "Disease Outbreak")
/**
* Generate advanced virus
*
* Uses the parameters to create a list of symptoms, picking from various severities
* Viral Evolution and Eternal Youth are special modifiers, so we roll separately.
*/
if(tgui_alert(usr, "Select a specific disease?", "Sickening behavior", list("Yes", "No")) == "Yes")
virus_type = tgui_input_list(usr, "Warning: Some of these are EXTREMELY dangerous.","Bacteria Hysteria", subtypesof(/datum/disease))
/datum/disease/advance/random/event/New(max_symptoms, max_severity)
var/list/datum/symptom/possible_symptoms = list(
/datum/symptom/beard,
/datum/symptom/chills,
/datum/symptom/choking,
/datum/symptom/confusion,
/datum/symptom/cough,
/datum/symptom/deafness,
/datum/symptom/dizzy,
/datum/symptom/fever,
/datum/symptom/headache,
/datum/symptom/itching,
/datum/symptom/shedding,
/datum/symptom/sneeze,
/datum/symptom/vomit,
/datum/symptom/weight_loss,
)
/datum/event_admin_setup/disease_outbreak/apply_to_event(datum/round_event/disease_outbreak/event)
event.virus_type = virus_type
switch(max_severity)
if(ADV_DISEASE_HARMFUL)
possible_symptoms += list(
/datum/symptom/disfiguration,
/datum/symptom/hallucigen,
/datum/symptom/polyvitiligo,
/datum/symptom/visionloss,
)
/datum/event_admin_setup/disease_outbreak/advanced
///Admin selected custom severity rating for the event
var/max_severity
///Admin selected custom value for the maximum symptoms this virus should have
var/max_symptoms
if(ADV_DISEASE_DANGEROUS)
possible_symptoms += list(
/datum/symptom/alkali,
/datum/symptom/asphyxiation,
/datum/symptom/fire,
/datum/symptom/flesh_death,
/datum/symptom/flesh_eating,
/datum/symptom/narcolepsy,
/datum/symptom/voice_change,
)
/datum/event_admin_setup/disease_outbreak/advanced/prompt_admins()
var/candidate_count = candidate_check()
if(!candidate_check())
tgui_alert(usr, "There are no candidates eligible to recieve a disease!", "Error")
return ADMIN_CANCEL_EVENT
tgui_alert(usr, "[candidate_count] candidates found!", "Disease Outbreak")
for(var/i in 1 to max_symptoms)
var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms)
if(chosen_symptom)
var/datum/symptom/new_symptom = new chosen_symptom
symptoms += new_symptom
if(tgui_alert(usr,"Customize your virus?", "Glorified Debug Tool", list("Yes", "No")) == "Yes")
max_severity = tgui_input_number(usr, "Select a custom severity for your virus!", "Plague Incorporation!", 3, 8)
max_symptoms = tgui_input_number(usr, "How many symptoms do you want your virus to have?", "A pox upon ye!", 3, 15)
if(prob(50))
symptoms += new /datum/symptom/viralevolution
/datum/event_admin_setup/disease_outbreak/advanced/apply_to_event(datum/round_event/disease_outbreak/advanced/event)
event.max_severity = max_severity
event.max_symptoms = max_symptoms
if(prob(50))
symptoms += new /datum/symptom/youth
Refresh()
name = "Sample #[rand(1, 9999)]"
/**
* Assign virus properties
*
* Now that we've picked our symptoms and severity, we determine the other stats
* (Stage Speed, Resistance, Transmissibility)
* The LOW/MID percentiles can be adjusted in the defines.
* If the virus is severity DANGEROUS we do not hide it from health scanners at event start.
* If the virus is airborne, also don't hide it.
*/
/datum/disease/advance/random/event/AssignProperties()
var/transmissibility = rand(1, 100)
addtimer(CALLBACK(src, PROC_REF(MakeVisible)), ((ADV_ANNOUNCE_DELAY * 2) - 10) SECONDS)
if(length(properties))
spreading_modifier = max(CEILING(0.4 * properties["transmittable"], 1), 1)
cure_chance = clamp(7.5 - (0.5 * properties["resistance"]), 5, 10) // Can be between 5 and 10
stage_prob = max(0.5 * properties["stage_rate"], 1)
SetSeverity(properties["severity"])
visibility_flags |= HIDDEN_SCANNER
switch(severity)
if("Dangerous", "BIOHAZARD")
visibility_flags &= ~HIDDEN_SCANNER
GenerateCure(properties)
if(transmissibility < ADV_SPREAD_LOW)
SetSpread(DISEASE_SPREAD_CONTACT_FLUIDS)
else if(transmissibility < ADV_SPREAD_MID)
SetSpread(DISEASE_SPREAD_CONTACT_SKIN)
else
SetSpread(DISEASE_SPREAD_AIRBORNE)
visibility_flags &= ~HIDDEN_SCANNER
else
CRASH("Advanced virus properties were empty or null!")
/**
* Set the transmission methods on the generated virus
*
* Apply the transmission methods we rolled in the AssignProperties proc
*/
/datum/disease/advance/random/event/SetSpread(spread_id)
switch(spread_id)
if(DISEASE_SPREAD_CONTACT_FLUIDS)
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS
spread_text = "fluids"
if(DISEASE_SPREAD_CONTACT_SKIN)
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN
spread_text = "skin contact"
if(DISEASE_SPREAD_AIRBORNE)
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_AIRBORNE
spread_text = "respiration"
/**
* Determine the cure
*
* Rolls one of six possible cure groups, then selects a cure from it and applies it to the virus.
*/
/datum/disease/advance/random/event/GenerateCure()
if(!length(properties))
stack_trace("Advanced virus properties were empty or null!")
return
var/res = rand(1, 6)
if(res == oldres)
return
cures = list(pick(advance_cures[res]))
oldres = res
// Get the cure name from the cure_id
var/datum/reagent/cure = GLOB.chemical_reagents_list[cures[1]]
cure_text = cure.name
#undef ADV_MIN_SYMPTOMS
#undef ADV_MAX_SYMPTOMS
#undef ADV_ANNOUNCE_DELAY
#undef ADV_DISEASE_MEDIUM
#undef ADV_DISEASE_HARMFUL
#undef ADV_DISEASE_DANGEROUS
#undef ADV_RNG_LOW
#undef ADV_RNG_MID
#undef ADV_SPREAD_LOW
#undef ADV_SPREAD_MID