Porting a load of disease/symptoms code updates.

This commit is contained in:
Ghommie
2019-10-05 07:14:25 +02:00
parent 7dada70447
commit 3d22f4ec60
26 changed files with 357 additions and 153 deletions

View File

@@ -35,6 +35,7 @@
#define LOG_GAME (1 << 12) #define LOG_GAME (1 << 12)
#define LOG_ADMIN_PRIVATE (1 << 13) #define LOG_ADMIN_PRIVATE (1 << 13)
#define LOG_ASAY (1 << 14) #define LOG_ASAY (1 << 14)
#define LOG_VIRUS (1 << 15)
//Individual logging panel pages //Individual logging panel pages
#define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK) #define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK)

View File

@@ -165,6 +165,7 @@
#define OBESITY "obesity" #define OBESITY "obesity"
#define MAGIC_TRAIT "magic" #define MAGIC_TRAIT "magic"
#define TRAUMA_TRAIT "trauma" #define TRAUMA_TRAIT "trauma"
#define DISEASE_TRAIT "disease"
#define SPECIES_TRAIT "species" #define SPECIES_TRAIT "species"
#define ORGAN_TRAIT "organ" #define ORGAN_TRAIT "organ"
#define JOB_TRAIT "job" #define JOB_TRAIT "job"

View File

@@ -58,6 +58,10 @@
if (CONFIG_GET(flag/log_game)) if (CONFIG_GET(flag/log_game))
WRITE_LOG(GLOB.world_game_log, "GAME: [text]") WRITE_LOG(GLOB.world_game_log, "GAME: [text]")
/proc/log_virus(text)
if (CONFIG_GET(flag/log_virus))
WRITE_LOG(GLOB.world_virus_log, "VIRUS: [text]")
/proc/log_access(text) /proc/log_access(text)
if (CONFIG_GET(flag/log_access)) if (CONFIG_GET(flag/log_access))
WRITE_LOG(GLOB.world_game_log, "ACCESS: [text]") WRITE_LOG(GLOB.world_game_log, "ACCESS: [text]")

View File

@@ -26,6 +26,8 @@ GLOBAL_VAR(query_debug_log)
GLOBAL_PROTECT(query_debug_log) GLOBAL_PROTECT(query_debug_log)
GLOBAL_VAR(world_job_debug_log) GLOBAL_VAR(world_job_debug_log)
GLOBAL_PROTECT(world_job_debug_log) GLOBAL_PROTECT(world_job_debug_log)
GLOBAL_VAR(world_virus_log)
GLOBAL_PROTECT(world_virus_log)
GLOBAL_LIST_EMPTY(bombers) GLOBAL_LIST_EMPTY(bombers)
GLOBAL_PROTECT(bombers) GLOBAL_PROTECT(bombers)

View File

@@ -14,7 +14,7 @@
/datum/config_entry/string/stationname // station name (the name of the station in-game) /datum/config_entry/string/stationname // station name (the name of the station in-game)
/datum/config_entry/number/lobby_countdown // In between round countdown. /datum/config_entry/number/lobby_co untdown // In between round countdown.
config_entry_value = 120 config_entry_value = 120
min_val = 0 min_val = 0
@@ -39,6 +39,8 @@
/datum/config_entry/flag/log_game // log game events /datum/config_entry/flag/log_game // log game events
/datum/config_entry/flag/log_virus // log virology data
/datum/config_entry/flag/log_vote // log voting /datum/config_entry/flag/log_vote // log voting
/datum/config_entry/flag/log_whisper // log client whisper /datum/config_entry/flag/log_whisper // log client whisper

View File

@@ -234,7 +234,7 @@
/datum/component/storage/proc/quick_empty(mob/M) /datum/component/storage/proc/quick_empty(mob/M)
var/atom/A = parent var/atom/A = parent
if((!ishuman(M) && (A.loc != M)) || (M.stat != CONSCIOUS) || M.restrained() || !M.canmove) if(!M.canUseStorage() || !A.Adjacent(M) || M.incapacitated())
return return
if(check_locked(null, M, TRUE)) if(check_locked(null, M, TRUE))
return FALSE return FALSE

View File

@@ -144,3 +144,9 @@
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs))) if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
return FALSE return FALSE
return ..() return ..()
/mob/living/proc/CanSpreadAirborneDisease()
return !is_mouth_covered()
/mob/living/carbon/CanSpreadAirborneDisease()
return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating("bio") >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating("bio") >= 25)))

View File

@@ -55,6 +55,13 @@
D.after_add() D.after_add()
infectee.med_hud_set_status() infectee.med_hud_set_status()
var/turf/source_turf = get_turf(infectee)
log_virus("[key_name(infectee)] was infected by virus: [src.admin_details()] at [loc_name(source_turf)]")
//Return a string for admin logging uses, should describe the disease in detail
/datum/disease/proc/admin_details()
return "[src.name] : [src.type]"
/datum/disease/proc/stage_act() /datum/disease/proc/stage_act()
var/cure = has_cure() var/cure = has_cure()
@@ -65,15 +72,17 @@
if(!cure) if(!cure)
if(prob(stage_prob)) if(prob(stage_prob))
stage = min(stage + 1,max_stages) update_stage(min(stage + 1,max_stages))
else else
if(prob(cure_chance)) if(prob(cure_chance))
stage = max(stage - 1, 1) update_stage(max(stage - 1, 1))
if(disease_flags & CURABLE) if(disease_flags & CURABLE)
if(cure && prob(cure_chance)) if(cure && prob(cure_chance))
cure() cure()
/datum/disease/proc/update_stage(new_stage)
stage = new_stage
/datum/disease/proc/has_cure() /datum/disease/proc/has_cure()
if(!(disease_flags & CURABLE)) if(!(disease_flags & CURABLE))

View File

@@ -31,9 +31,9 @@
var/id = "" var/id = ""
var/processing = FALSE var/processing = FALSE
var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology
var/oldres var/oldres //To prevent setting new cures unless resistance changes.
// The order goes from easy to cure to hard to cure. // The order goes from easy to cure to hard to cure. Keep in mind that sentient diseases pick two cures from tier 6 and up, ensure they wont react away in bodies.
var/static/list/advance_cures = list( var/static/list/advance_cures = list(
list( // level 1 list( // level 1
"copper", "silver", "iodine", "iron", "carbon" "copper", "silver", "iodine", "iron", "carbon"
@@ -110,15 +110,22 @@
return return
if(symptoms && symptoms.len) if(symptoms && symptoms.len)
if(!processing) if(!processing)
processing = TRUE processing = TRUE
for(var/datum/symptom/S in symptoms) for(var/datum/symptom/S in symptoms)
S.Start(src) if(S.Start(src)) //this will return FALSE if the symptom is neutered
S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10)
S.on_stage_change(src)
for(var/datum/symptom/S in symptoms) for(var/datum/symptom/S in symptoms)
S.Activate(src) S.Activate(src)
// Tell symptoms stage changed
/datum/disease/advance/update_stage(new_stage)
..()
for(var/datum/symptom/S in symptoms)
S.on_stage_change(src)
// Compares type then ID. // Compares type then ID.
/datum/disease/advance/IsSame(datum/disease/advance/D) /datum/disease/advance/IsSame(datum/disease/advance/D)
@@ -138,9 +145,18 @@
A.properties = properties.Copy() A.properties = properties.Copy()
A.id = id A.id = id
A.mutable = mutable A.mutable = mutable
A.oldres = oldres
//this is a new disease starting over at stage 1, so processing is not copied //this is a new disease starting over at stage 1, so processing is not copied
return A return A
//Describe this disease to an admin in detail (for logging)
/datum/disease/advance/admin_details()
var/list/name_symptoms = list()
for(var/datum/symptom/S in symptoms)
name_symptoms += S.name
return "[name] sym:[english_list(name_symptoms)] r:[totalResistance()] s:[totalStealth()] ss:[totalStageSpeed()] t:[totalTransmittable()]"
/* /*
NEW PROCS NEW PROCS
@@ -191,6 +207,10 @@
/datum/disease/advance/proc/Refresh(new_name = FALSE) /datum/disease/advance/proc/Refresh(new_name = FALSE)
GenerateProperties() GenerateProperties()
AssignProperties() AssignProperties()
if(processing && symptoms && symptoms.len)
for(var/datum/symptom/S in symptoms)
S.Start(src)
S.on_stage_change(src)
id = null id = null
var/the_id = GetDiseaseID() var/the_id = GetDiseaseID()
@@ -342,28 +362,28 @@
return id return id
// Add a symptom, if it is over the limit (with a small chance to be able to go over) // Add a symptom, if it is over the limit we take a random symptom away and add the new one.
// we take a random symptom away and add the new one.
/datum/disease/advance/proc/AddSymptom(datum/symptom/S) /datum/disease/advance/proc/AddSymptom(datum/symptom/S)
if(HasSymptom(S)) if(HasSymptom(S))
return return
if(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1)) if(!(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1)))
symptoms += S
else
RemoveSymptom(pick(symptoms)) RemoveSymptom(pick(symptoms))
symptoms += S symptoms += S
S.OnAdd(src)
// Simply removes the symptom. // Simply removes the symptom.
/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S) /datum/disease/advance/proc/RemoveSymptom(datum/symptom/S)
symptoms -= S symptoms -= S
S.OnRemove(src)
// Neuter a symptom, so it will only affect stats // Neuter a symptom, so it will only affect stats
/datum/disease/advance/proc/NeuterSymptom(datum/symptom/S) /datum/disease/advance/proc/NeuterSymptom(datum/symptom/S)
if(!S.neutered) if(!S.neutered)
S.neutered = TRUE S.neutered = TRUE
S.name += " (neutered)" S.name += " (neutered)"
S.OnRemove(src)
/* /*
@@ -417,7 +437,7 @@
var/i = VIRUS_SYMPTOM_LIMIT var/i = VIRUS_SYMPTOM_LIMIT
var/datum/disease/advance/D = new(0, null) var/datum/disease/advance/D = new()
D.symptoms = list() D.symptoms = list()
var/list/symptoms = list() var/list/symptoms = list()
@@ -445,9 +465,6 @@
D.AssignName(new_name) D.AssignName(new_name)
D.Refresh() D.Refresh()
for(var/datum/disease/advance/AD in SSdisease.active_diseases)
AD.Refresh()
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
if(!is_station_level(H.z)) if(!is_station_level(H.z))
continue continue
@@ -458,8 +475,8 @@
var/list/name_symptoms = list() var/list/name_symptoms = list()
for(var/datum/symptom/S in D.symptoms) for(var/datum/symptom/S in D.symptoms)
name_symptoms += S.name name_symptoms += S.name
message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]") message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.admin_details()]")
log_virus("[key_name(user)] has triggered a custom virus outbreak of [D.admin_details()]!")
/datum/disease/advance/proc/totalStageSpeed() /datum/disease/advance/proc/totalStageSpeed()
return properties["stage_rate"] return properties["stage_rate"]

View File

@@ -70,6 +70,6 @@ BONUS
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 6) addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 6)
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 12) addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 12)
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 18) addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 18)
if(infective) if(infective && M.CanSpreadAirborneDisease())
A.spread(1) A.spread(1)

View File

@@ -219,8 +219,10 @@
level = 8 level = 8
passive_message = "<span class='notice'>The pain from your wounds makes you feel oddly sleepy...</span>" passive_message = "<span class='notice'>The pain from your wounds makes you feel oddly sleepy...</span>"
var/deathgasp = FALSE var/deathgasp = FALSE
var/stabilize = FALSE
var/active_coma = FALSE //to prevent multiple coma procs var/active_coma = FALSE //to prevent multiple coma procs
threshold_desc = "<b>Stealth 2:</b> Host appears to die when falling into a coma.<br>\ threshold_desc = "<b>Stealth 2:</b> Host appears to die when falling into a coma.<br>\
<b>Resistance 4:</b> The virus also stabilizes the host while they are in critical condition.<br>\
<b>Stage Speed 7:</b> Increases healing speed." <b>Stage Speed 7:</b> Increases healing speed."
/datum/symptom/heal/coma/Start(datum/disease/advance/A) /datum/symptom/heal/coma/Start(datum/disease/advance/A)
@@ -228,9 +230,25 @@
return return
if(A.properties["stage_rate"] >= 7) if(A.properties["stage_rate"] >= 7)
power = 1.5 power = 1.5
if(A.properties["resistance"] >= 4)
stabilize = TRUE
if(A.properties["stealth"] >= 2) if(A.properties["stealth"] >= 2)
deathgasp = TRUE deathgasp = TRUE
/datum/symptom/heal/coma/on_stage_change(datum/disease/advance/A) //mostly copy+pasted from the code for self-respiration's TRAIT_NOBREATH stuff
if(!..())
return FALSE
if(A.stage >= 4 && stabilize)
ADD_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
else
REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
return TRUE
/datum/symptom/heal/coma/End(datum/disease/advance/A)
if(!..())
return
REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
/datum/symptom/heal/coma/CanHeal(datum/disease/advance/A) /datum/symptom/heal/coma/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob var/mob/living/M = A.affected_mob
if(HAS_TRAIT(M, TRAIT_DEATHCOMA)) if(HAS_TRAIT(M, TRAIT_DEATHCOMA))

View File

@@ -50,3 +50,19 @@ Bonus
if(prob(base_message_chance)) if(prob(base_message_chance))
to_chat(M, "<span class='notice'>[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]</span>") to_chat(M, "<span class='notice'>[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]</span>")
return return
/datum/symptom/oxygen/on_stage_change(datum/disease/advance/A)
if(!..())
return FALSE
var/mob/living/carbon/M = A.affected_mob
if(A.stage >= 4)
ADD_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT)
else
REMOVE_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT)
return TRUE
/datum/symptom/oxygen/End(datum/disease/advance/A)
if(!..())
return
if(A.stage >= 4)
REMOVE_TRAIT(A.affected_mob, TRAIT_NOBREATH, DISEASE_TRAIT)

View File

@@ -48,4 +48,5 @@ Bonus
M.emote("sniff") M.emote("sniff")
else else
M.emote("sneeze") M.emote("sneeze")
if(M.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth
A.spread(4 + power) A.spread(4 + power)

View File

@@ -8,12 +8,14 @@
level = 5 level = 5
severity = 0 severity = 0
/datum/symptom/undead_adaptation/Start(datum/disease/advance/A) /datum/symptom/undead_adaptation/OnAdd(datum/disease/advance/A)
if(!..())
return
A.process_dead = TRUE A.process_dead = TRUE
A.infectable_biotypes |= MOB_UNDEAD A.infectable_biotypes |= MOB_UNDEAD
/datum/symptom/undead_adaptation/OnRemove(datum/disease/advance/A)
A.process_dead = FALSE
A.infectable_biotypes -= MOB_UNDEAD
/datum/symptom/inorganic_adaptation /datum/symptom/inorganic_adaptation
name = "Inorganic Biology" name = "Inorganic Biology"
desc = "The virus can survive and replicate even in an inorganic environment, increasing its resistance and infection rate." desc = "The virus can survive and replicate even in an inorganic environment, increasing its resistance and infection rate."
@@ -24,7 +26,8 @@
level = 5 level = 5
severity = 0 severity = 0
/datum/symptom/inorganic_adaptation/Start(datum/disease/advance/A) /datum/symptom/inorganic_adaptation/OnAdd(datum/disease/advance/A)
if(!..())
return
A.infectable_biotypes |= MOB_INORGANIC A.infectable_biotypes |= MOB_INORGANIC
/datum/symptom/inorganic_adaptation/OnRemove(datum/disease/advance/A)
A.infectable_biotypes -= MOB_INORGANIC

View File

@@ -38,11 +38,10 @@
return return
CRASH("We couldn't assign an ID!") CRASH("We couldn't assign an ID!")
// Called when processing of the advance disease, which holds this symptom, starts. // Called when processing of the advance disease that holds this symptom infects a host and upon each Refresh() of that advance disease.
/datum/symptom/proc/Start(datum/disease/advance/A) /datum/symptom/proc/Start(datum/disease/advance/A)
if(neutered) if(neutered)
return FALSE return FALSE
next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) //so it doesn't instantly activate on infection
return TRUE return TRUE
// Called when the advance disease is going to be deleted or when the advance disease stops processing. // Called when the advance disease is going to be deleted or when the advance disease stops processing.
@@ -60,6 +59,11 @@
next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10)
return TRUE return TRUE
/datum/symptom/proc/on_stage_change(datum/disease/advance/A)
if(neutered)
return FALSE
return TRUE
/datum/symptom/proc/Copy() /datum/symptom/proc/Copy()
var/datum/symptom/new_symp = new type var/datum/symptom/new_symp = new type
new_symp.name = name new_symp.name = name
@@ -69,3 +73,9 @@
/datum/symptom/proc/generate_threshold_desc() /datum/symptom/proc/generate_threshold_desc()
return return
/datum/symptom/proc/OnAdd(datum/disease/advance/A) //Overload when a symptom needs to be active before processing, like changing biotypes.
return
/datum/symptom/proc/OnRemove(datum/disease/advance/A) //But dont forget to remove them too.
return

View File

@@ -96,7 +96,7 @@
if(BODY_ZONE_PRECISE_MOUTH) if(BODY_ZONE_PRECISE_MOUTH)
if((M.head && M.head.flags_cover & HEADCOVERSMOUTH) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH)) if(M.is_mouth_covered())
to_chat(user, "<span class='notice'>You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSMOUTH) ? "helmet" : "mask"] first.</span>") to_chat(user, "<span class='notice'>You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSMOUTH) ? "helmet" : "mask"] first.</span>")
return return

View File

@@ -100,6 +100,7 @@ GLOBAL_VAR(restart_counter)
GLOB.picture_log_directory = "data/picture_logs/[override_dir]" GLOB.picture_log_directory = "data/picture_logs/[override_dir]"
GLOB.world_game_log = "[GLOB.log_directory]/game.log" GLOB.world_game_log = "[GLOB.log_directory]/game.log"
GLOB.world_virus_log = "[GLOB.log_directory]/virus.log"
GLOB.world_attack_log = "[GLOB.log_directory]/attack.log" GLOB.world_attack_log = "[GLOB.log_directory]/attack.log"
GLOB.world_pda_log = "[GLOB.log_directory]/pda.log" GLOB.world_pda_log = "[GLOB.log_directory]/pda.log"
GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log" GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log"

View File

@@ -5,25 +5,48 @@ is currently following.
*/ */
GLOBAL_LIST_INIT(disease_ability_singletons, list( GLOBAL_LIST_INIT(disease_ability_singletons, list(
new /datum/disease_ability/action/cough(), new /datum/disease_ability/action/cough,
new /datum/disease_ability/action/sneeze(), new /datum/disease_ability/action/sneeze,
new /datum/disease_ability/action/infect(), new /datum/disease_ability/action/infect,
new /datum/disease_ability/symptom/cough(), new /datum/disease_ability/symptom/mild/cough,
new /datum/disease_ability/symptom/sneeze(),\ new /datum/disease_ability/symptom/mild/sneeze,
new /datum/disease_ability/symptom/hallucigen(), new /datum/disease_ability/symptom/medium/shedding,
new /datum/disease_ability/symptom/choking(), new /datum/disease_ability/symptom/medium/beard,
new /datum/disease_ability/symptom/confusion(), new /datum/disease_ability/symptom/medium/hallucigen,
new /datum/disease_ability/symptom/youth(), new /datum/disease_ability/symptom/medium/choking,
new /datum/disease_ability/symptom/vomit(), new /datum/disease_ability/symptom/medium/confusion,
new /datum/disease_ability/symptom/voice_change(), new /datum/disease_ability/symptom/medium/vomit,
new /datum/disease_ability/symptom/visionloss(), new /datum/disease_ability/symptom/medium/voice_change,
new /datum/disease_ability/symptom/viraladaptation(), new /datum/disease_ability/symptom/medium/visionloss,
new /datum/disease_ability/symptom/vitiligo(), new /datum/disease_ability/symptom/medium/deafness,
new /datum/disease_ability/symptom/sensory_restoration(), new /datum/disease_ability/symptom/powerful/narcolepsy,
new /datum/disease_ability/symptom/itching(), new /datum/disease_ability/symptom/medium/fever,
new /datum/disease_ability/symptom/weight_loss(), new /datum/disease_ability/symptom/medium/shivering,
new /datum/disease_ability/symptom/metabolism_heal(), new /datum/disease_ability/symptom/medium/headache,
new /datum/disease_ability/symptom/coma_heal() new /datum/disease_ability/symptom/medium/nano_boost,
new /datum/disease_ability/symptom/medium/nano_destroy,
new /datum/disease_ability/symptom/medium/viraladaptation,
new /datum/disease_ability/symptom/medium/viralevolution,
new /datum/disease_ability/symptom/medium/vitiligo,
new /datum/disease_ability/symptom/medium/revitiligo,
new /datum/disease_ability/symptom/medium/itching,
new /datum/disease_ability/symptom/medium/heal/weight_loss,
new /datum/disease_ability/symptom/medium/heal/sensory_restoration,
new /datum/disease_ability/symptom/medium/heal/mind_restoration,
new /datum/disease_ability/symptom/powerful/fire,
new /datum/disease_ability/symptom/powerful/flesh_eating,
new /datum/disease_ability/symptom/powerful/genetic_mutation,
new /datum/disease_ability/symptom/powerful/inorganic_adaptation,
new /datum/disease_ability/symptom/powerful/heal/starlight,
new /datum/disease_ability/symptom/powerful/heal/oxygen,
new /datum/disease_ability/symptom/powerful/heal/chem,
new /datum/disease_ability/symptom/powerful/heal/metabolism,
new /datum/disease_ability/symptom/powerful/heal/dark,
new /datum/disease_ability/symptom/powerful/heal/water,
new /datum/disease_ability/symptom/powerful/heal/plasma,
new /datum/disease_ability/symptom/powerful/heal/radiation,
new /datum/disease_ability/symptom/powerful/heal/coma,
new /datum/disease_ability/symptom/powerful/youth
)) ))
/datum/disease_ability /datum/disease_ability
@@ -55,6 +78,12 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
transmittable += initial(S.transmittable) transmittable += initial(S.transmittable)
threshold_block += "<br><br>[initial(S.threshold_desc)]" threshold_block += "<br><br>[initial(S.threshold_desc)]"
stat_block = "Resistance: [resistance]<br>Stealth: [stealth]<br>Stage Speed: [stage_speed]<br>Transmissibility: [transmittable]<br><br>" stat_block = "Resistance: [resistance]<br>Stealth: [stealth]<br>Stage Speed: [stage_speed]<br>Transmissibility: [transmittable]<br><br>"
if(symptoms.len == 1) //lazy boy's dream
name = initial(S.name)
if(short_desc == "")
short_desc = initial(S.desc)
if(long_desc == "")
long_desc = initial(S.desc)
/datum/disease_ability/proc/CanBuy(mob/camera/disease/D) /datum/disease_ability/proc/CanBuy(mob/camera/disease/D)
if(world.time < D.next_adaptation_time) if(world.time < D.next_adaptation_time)
@@ -77,8 +106,10 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
for(var/T in symptoms) for(var/T in symptoms)
var/datum/symptom/S = new T() var/datum/symptom/S = new T()
SD.symptoms += S SD.symptoms += S
S.OnAdd(SD)
if(SD.processing) if(SD.processing)
S.Start(SD) if(S.Start(SD))
S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10)
SD.Refresh() SD.Refresh()
for(var/T in actions) for(var/T in actions)
var/datum/action/A = new T() var/datum/action/A = new T()
@@ -105,6 +136,7 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
var/datum/symptom/S = locate(T) in SD.symptoms var/datum/symptom/S = locate(T) in SD.symptoms
if(S) if(S)
SD.symptoms -= S SD.symptoms -= S
S.OnRemove(SD)
if(SD.processing) if(SD.processing)
S.End(SD) S.End(SD)
qdel(S) qdel(S)
@@ -152,6 +184,7 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
return FALSE return FALSE
to_chat(D, "<span class='notice'>You force [L.real_name] to cough.</span>") to_chat(D, "<span class='notice'>You force [L.real_name] to cough.</span>")
L.emote("cough") L.emote("cough")
if(L.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth
var/datum/disease/advance/sentient_disease/SD = D.hosts[L] var/datum/disease/advance/sentient_disease/SD = D.hosts[L]
SD.spread(2) SD.spread(2)
StartCooldown() StartCooldown()
@@ -185,6 +218,7 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
return FALSE return FALSE
to_chat(D, "<span class='notice'>You force [L.real_name] to sneeze.</span>") to_chat(D, "<span class='notice'>You force [L.real_name] to sneeze.</span>")
L.emote("sneeze") L.emote("sneeze")
if(L.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth
var/datum/disease/advance/sentient_disease/SD = D.hosts[L] var/datum/disease/advance/sentient_disease/SD = D.hosts[L]
for(var/mob/living/M in oview(4, SD.affected_mob)) for(var/mob/living/M in oview(4, SD.affected_mob))
@@ -235,154 +269,192 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
StartCooldown() StartCooldown()
return TRUE return TRUE
//passive symptom abilities /*******************BASE SYMPTOM TYPES*******************/
// cost is for convenience and can be changed. If you're changing req_tot_points then don't use the subtype...
//healing costs more so you have to techswitch from naughty disease otherwise we'd have friendly disease for easy greentext (no fun!)
/datum/disease_ability/symptom/cough /datum/disease_ability/symptom/mild
name = "Involuntary Coughing"
symptoms = list(/datum/symptom/cough)
cost = 2 cost = 2
required_total_points = 4 required_total_points = 4
category = "Symptom (Weak)"
/datum/disease_ability/symptom/medium
cost = 4
required_total_points = 8
category = "Symptom"
/datum/disease_ability/symptom/medium/heal
cost = 5
category = "Symptom (+)"
/datum/disease_ability/symptom/powerful
cost = 4
required_total_points = 16
category = "Symptom (Strong)"
/datum/disease_ability/symptom/powerful/heal
cost = 8
category = "Symptom (Strong+)"
/******MILD******/
/datum/disease_ability/symptom/mild/cough
name = "Involuntary Coughing"
symptoms = list(/datum/symptom/cough)
short_desc = "Cause victims to cough intermittently." short_desc = "Cause victims to cough intermittently."
long_desc = "Cause victims to cough intermittently, spreading your infection if your transmissibility is high." long_desc = "Cause victims to cough intermittently, spreading your infection if your transmissibility is high."
/datum/disease_ability/symptom/sneeze /datum/disease_ability/symptom/mild/sneeze
name = "Involuntary Sneezing" name = "Involuntary Sneezing"
symptoms = list(/datum/symptom/sneeze) symptoms = list(/datum/symptom/sneeze)
cost = 2
required_total_points = 4
short_desc = "Cause victims to sneeze intermittently." short_desc = "Cause victims to sneeze intermittently."
long_desc = "Cause victims to sneeze intermittently, spreading your infection and also increasing transmissibility and resistance, at the cost of stealth." long_desc = "Cause victims to sneeze intermittently, spreading your infection and also increasing transmissibility and resistance, at the cost of stealth."
/datum/disease_ability/symptom/beard /******MEDIUM******/
//I don't think I need to justify the fact that this is the best symptom
name = "Beard Growth"
symptoms = list(/datum/symptom/beard)
cost = 1
required_total_points = 8
short_desc = "Cause all victims to grow a luscious beard."
long_desc = "Cause all victims to grow a luscious beard. Decreases stats slightly. Ineffective against Santa Claus."
/datum/disease_ability/symptom/hallucigen /datum/disease_ability/symptom/medium/shedding
name = "Hallucinations" symptoms = list(/datum/symptom/shedding)
/datum/disease_ability/symptom/medium/beard
symptoms = list(/datum/symptom/beard)
short_desc = "Cause all victims to grow a luscious beard."
long_desc = "Cause all victims to grow a luscious beard. Ineffective against Santa Claus."
/datum/disease_ability/symptom/medium/hallucigen
symptoms = list(/datum/symptom/hallucigen) symptoms = list(/datum/symptom/hallucigen)
cost = 4
required_total_points = 8
short_desc = "Cause victims to hallucinate." short_desc = "Cause victims to hallucinate."
long_desc = "Cause victims to hallucinate. Decreases stats, especially resistance." long_desc = "Cause victims to hallucinate. Decreases stats, especially resistance."
/datum/disease_ability/symptom/medium/choking
/datum/disease_ability/symptom/choking
name = "Choking"
symptoms = list(/datum/symptom/choking) symptoms = list(/datum/symptom/choking)
cost = 4
required_total_points = 8
short_desc = "Cause victims to choke." short_desc = "Cause victims to choke."
long_desc = "Cause victims to choke, threatening asphyxiation. Decreases stats, especially transmissibility." long_desc = "Cause victims to choke, threatening asphyxiation. Decreases stats, especially transmissibility."
/datum/disease_ability/symptom/medium/confusion
/datum/disease_ability/symptom/confusion
name = "Confusion"
symptoms = list(/datum/symptom/confusion) symptoms = list(/datum/symptom/confusion)
cost = 4
required_total_points = 8
short_desc = "Cause victims to become confused." short_desc = "Cause victims to become confused."
long_desc = "Cause victims to become confused intermittently." long_desc = "Cause victims to become confused intermittently."
/datum/disease_ability/symptom/medium/vomit
/datum/disease_ability/symptom/youth
name = "Eternal Youth"
symptoms = list(/datum/symptom/youth)
cost = 4
required_total_points = 8
short_desc = "Cause victims to become eternally young."
long_desc = "Cause victims to become eternally young. Provides boosts to all stats except transmissibility."
/datum/disease_ability/symptom/vomit
name = "Vomiting"
symptoms = list(/datum/symptom/vomit) symptoms = list(/datum/symptom/vomit)
cost = 4
required_total_points = 8
short_desc = "Cause victims to vomit." short_desc = "Cause victims to vomit."
long_desc = "Cause victims to vomit. Slightly increases transmissibility. Vomiting also also causes the victims to lose nutrition and removes some toxin damage." long_desc = "Cause victims to vomit. Slightly increases transmissibility. Vomiting also also causes the victims to lose nutrition and removes some toxin damage."
/datum/disease_ability/symptom/medium/voice_change
/datum/disease_ability/symptom/voice_change
name = "Voice Changing"
symptoms = list(/datum/symptom/voice_change) symptoms = list(/datum/symptom/voice_change)
cost = 4
required_total_points = 8
short_desc = "Change the voice of victims." short_desc = "Change the voice of victims."
long_desc = "Change the voice of victims, causing confusion in communications." long_desc = "Change the voice of victims, causing confusion in communications."
/datum/disease_ability/symptom/medium/visionloss
/datum/disease_ability/symptom/visionloss
name = "Vision Loss"
symptoms = list(/datum/symptom/visionloss) symptoms = list(/datum/symptom/visionloss)
cost = 4
required_total_points = 8
short_desc = "Damage the eyes of victims, eventually causing blindness." short_desc = "Damage the eyes of victims, eventually causing blindness."
long_desc = "Damage the eyes of victims, eventually causing blindness. Decreases all stats." long_desc = "Damage the eyes of victims, eventually causing blindness. Decreases all stats."
/datum/disease_ability/symptom/medium/deafness
symptoms = list(/datum/symptom/deafness)
/datum/disease_ability/symptom/viraladaptation /datum/disease_ability/symptom/medium/fever
name = "Self-Adaptation" symptoms = list(/datum/symptom/fever)
/datum/disease_ability/symptom/medium/shivering
symptoms = list(/datum/symptom/shivering)
/datum/disease_ability/symptom/medium/headache
symptoms = list(/datum/symptom/headache)
/datum/disease_ability/symptom/medium/nano_boost
symptoms = list(/datum/symptom/nano_boost)
/datum/disease_ability/symptom/medium/nano_destroy
symptoms = list(/datum/symptom/nano_destroy)
/datum/disease_ability/symptom/medium/viraladaptation
symptoms = list(/datum/symptom/viraladaptation) symptoms = list(/datum/symptom/viraladaptation)
cost = 4
required_total_points = 8
short_desc = "Cause your infection to become more resistant to detection and eradication." short_desc = "Cause your infection to become more resistant to detection and eradication."
long_desc = "Cause your infection to mimic the function of normal body cells, becoming much harder to spot and to eradicate, but reducing its speed." long_desc = "Cause your infection to mimic the function of normal body cells, becoming much harder to spot and to eradicate, but reducing its speed."
/datum/disease_ability/symptom/medium/viralevolution
symptoms = list(/datum/symptom/viralevolution)
/datum/disease_ability/symptom/vitiligo /datum/disease_ability/symptom/medium/vitiligo
name = "Skin Paleness"
symptoms = list(/datum/symptom/vitiligo) symptoms = list(/datum/symptom/vitiligo)
cost = 1
required_total_points = 8
short_desc = "Cause victims to become pale."
long_desc = "Cause victims to become pale. Decreases all stats."
/datum/disease_ability/symptom/medium/revitiligo
symptoms = list(/datum/symptom/revitiligo)
/datum/disease_ability/symptom/sensory_restoration /datum/disease_ability/symptom/medium/itching
name = "Sensory Restoration"
symptoms = list(/datum/symptom/sensory_restoration)
cost = 4
required_total_points = 8
short_desc = "Regenerate eye and ear damage of victims."
long_desc = "Regenerate eye and ear damage of victims."
/datum/disease_ability/symptom/itching
name = "Itching"
symptoms = list(/datum/symptom/itching) symptoms = list(/datum/symptom/itching)
cost = 4
required_total_points = 8
short_desc = "Cause victims to itch." short_desc = "Cause victims to itch."
long_desc = "Cause victims to itch, increasing all stats except stealth." long_desc = "Cause victims to itch, increasing all stats except stealth."
/datum/disease_ability/symptom/medium/heal/weight_loss
/datum/disease_ability/symptom/weight_loss
name = "Weight Loss"
symptoms = list(/datum/symptom/weight_loss) symptoms = list(/datum/symptom/weight_loss)
cost = 4
required_total_points = 8
short_desc = "Cause victims to lose weight." short_desc = "Cause victims to lose weight."
long_desc = "Cause victims to lose weight, and make it almost impossible for them to gain nutrition from food. Reduced nutrition allows your infection to spread more easily from hosts, especially by sneezing." long_desc = "Cause victims to lose weight, and make it almost impossible for them to gain nutrition from food. Reduced nutrition allows your infection to spread more easily from hosts, especially by sneezing."
/datum/disease_ability/symptom/medium/heal/sensory_restoration
symptoms = list(/datum/symptom/sensory_restoration)
short_desc = "Regenerate eye and ear damage of victims."
long_desc = "Regenerate eye and ear damage of victims."
/datum/disease_ability/symptom/metabolism_heal /datum/disease_ability/symptom/medium/heal/mind_restoration
name = "Metabolic Boost" symptoms = list(/datum/symptom/mind_restoration)
/******POWERFUL******/
/datum/disease_ability/symptom/powerful/fire
symptoms = list(/datum/symptom/fire)
/datum/disease_ability/symptom/powerful/flesh_eating
symptoms = list(/datum/symptom/flesh_eating)
/*
/datum/disease_ability/symptom/powerful/genetic_mutation
symptoms = list(/datum/symptom/genetic_mutation)
cost = 8
*/
/datum/disease_ability/symptom/powerful/inorganic_adaptation
symptoms = list(/datum/symptom/inorganic_adaptation)
/datum/disease_ability/symptom/powerful/narcolepsy
symptoms = list(/datum/symptom/narcolepsy)
/datum/disease_ability/symptom/powerful/youth
symptoms = list(/datum/symptom/youth)
short_desc = "Cause victims to become eternally young."
long_desc = "Cause victims to become eternally young. Provides boosts to all stats except transmissibility."
/****HEALING SUBTYPE****/
/datum/disease_ability/symptom/powerful/heal/starlight
symptoms = list(/datum/symptom/heal/starlight)
/datum/disease_ability/symptom/powerful/heal/oxygen
symptoms = list(/datum/symptom/oxygen)
/datum/disease_ability/symptom/powerful/heal/chem
symptoms = list(/datum/symptom/heal/chem)
/datum/disease_ability/symptom/powerful/heal/metabolism
symptoms = list(/datum/symptom/heal/metabolism) symptoms = list(/datum/symptom/heal/metabolism)
cost = 4
required_total_points = 16
short_desc = "Increase the metabolism of victims, causing them to process chemicals and grow hungry faster." short_desc = "Increase the metabolism of victims, causing them to process chemicals and grow hungry faster."
long_desc = "Increase the metabolism of victims, causing them to process chemicals twice as fast and grow hungry more quickly." long_desc = "Increase the metabolism of victims, causing them to process chemicals twice as fast and grow hungry more quickly."
/datum/disease_ability/symptom/powerful/heal/dark
symptoms = list(/datum/symptom/heal/darkness)
/datum/disease_ability/symptom/coma_heal /datum/disease_ability/symptom/powerful/heal/water
name = "Regenerative Coma" symptoms = list(/datum/symptom/heal/water)
/datum/disease_ability/symptom/powerful/heal/plasma
symptoms = list(/datum/symptom/heal/plasma)
/datum/disease_ability/symptom/powerful/heal/radiation
symptoms = list(/datum/symptom/heal/radiation)
/datum/disease_ability/symptom/powerful/heal/coma
symptoms = list(/datum/symptom/heal/coma) symptoms = list(/datum/symptom/heal/coma)
cost = 8
required_total_points = 16
short_desc = "Cause victims to fall into a healing coma when hurt." short_desc = "Cause victims to fall into a healing coma when hurt."
long_desc = "Cause victims to fall into a healing coma when hurt." long_desc = "Cause victims to fall into a healing coma when hurt."

View File

@@ -51,6 +51,7 @@
if(cures.len) if(cures.len)
return return
var/list/not_used = advance_cures.Copy() var/list/not_used = advance_cures.Copy()
not_used.Cut(1, 6) // Removes the first five tiers of cures.
cures = list(pick(pick_n_take(not_used)), pick(pick_n_take(not_used))) cures = list(pick(pick_n_take(not_used)), pick(pick_n_take(not_used)))
// Get the cure name from the cure_id // Get the cure name from the cure_id

View File

@@ -18,7 +18,7 @@ the new instance inside the host to be updated to the template's stats.
layer = BELOW_MOB_LAYER layer = BELOW_MOB_LAYER
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
sight = SEE_SELF|SEE_THRU sight = SEE_SELF|SEE_THRU
initial_language_holder = /datum/language_holder/empty initial_language_holder = /datum/language_holder/universal
var/freemove = TRUE var/freemove = TRUE
var/freemove_end = 0 var/freemove_end = 0
@@ -43,7 +43,7 @@ the new instance inside the host to be updated to the template's stats.
var/move_delay = 1 var/move_delay = 1
var/next_adaptation_time = 0 var/next_adaptation_time = 0
var/adaptation_cooldown = 1200 var/adaptation_cooldown = 600
var/list/purchased_abilities var/list/purchased_abilities
var/list/unpurchased_abilities var/list/unpurchased_abilities
@@ -118,10 +118,28 @@ the new instance inside the host to be updated to the template's stats.
follow_next(Dir & NORTHWEST) follow_next(Dir & NORTHWEST)
last_move_tick = world.time last_move_tick = world.time
/mob/camera/disease/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
. = ..()
var/atom/movable/to_follow = speaker
if(radio_freq)
var/atom/movable/virtualspeaker/V = speaker
to_follow = V.source
var/link
if(to_follow in hosts)
link = FOLLOW_LINK(src, to_follow)
else
link = ""
// Recompose the message, because it's scrambled by default
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
to_chat(src, "[link] [message]")
/mob/camera/disease/mind_initialize() /mob/camera/disease/mind_initialize()
. = ..() . = ..()
if(!mind.has_antag_datum(/datum/antagonist/disease)) if(!mind.has_antag_datum(/datum/antagonist/disease))
mind.add_antag_datum(/datum/antagonist/disease) mind.add_antag_datum(/datum/antagonist/disease)
var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
medsensor.add_hud_to(src)
/mob/camera/disease/proc/pick_name() /mob/camera/disease/proc/pick_name()
var/static/list/taken_names var/static/list/taken_names
@@ -247,9 +265,12 @@ the new instance inside the host to be updated to the template's stats.
if(!move_listener) if(!move_listener)
move_listener = L.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/follow_mob))) move_listener = L.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/follow_mob)))
else else
if(L)
L.TakeComponent(move_listener) L.TakeComponent(move_listener)
if(QDELING(move_listener)) if(QDELING(move_listener))
move_listener = null move_listener = null
else
QDEL_NULL(move_listener)
follow_mob() follow_mob()
/mob/camera/disease/proc/follow_next(reverse = FALSE) /mob/camera/disease/proc/follow_next(reverse = FALSE)

View File

@@ -30,5 +30,8 @@
loc = destination loc = destination
Moved(oldloc, NONE, TRUE) Moved(oldloc, NONE, TRUE)
/mob/camera/canUseStorage()
return FALSE
/mob/camera/emote(act, m_type=1, message = null, intentional = FALSE) /mob/camera/emote(act, m_type=1, message = null, intentional = FALSE)
return return

View File

@@ -20,6 +20,9 @@ INITIALIZE_IMMEDIATE(/mob/dead)
set_focus(src) set_focus(src)
return INITIALIZE_HINT_NORMAL return INITIALIZE_HINT_NORMAL
/mob/dead/canUseStorage()
return FALSE
/mob/dead/dust(just_ash, drop_items, force) //ghosts can't be vaporised. /mob/dead/dust(just_ash, drop_items, force) //ghosts can't be vaporised.
return return

View File

@@ -346,6 +346,11 @@
if(stat || IsUnconscious() || IsStun() || IsKnockdown() || recoveringstam || (!ignore_restraints && restrained(ignore_grab))) // CIT CHANGE - adds recoveringstam check here if(stat || IsUnconscious() || IsStun() || IsKnockdown() || recoveringstam || (!ignore_restraints && restrained(ignore_grab))) // CIT CHANGE - adds recoveringstam check here
return TRUE return TRUE
/mob/living/canUseStorage()
if (get_num_arms() <= 0)
return FALSE
return TRUE
/mob/living/proc/InCritical() /mob/living/proc/InCritical()
return (health <= crit_threshold && (stat == SOFT_CRIT || stat == UNCONSCIOUS)) return (health <= crit_threshold && (stat == SOFT_CRIT || stat == UNCONSCIOUS))

View File

@@ -810,6 +810,9 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) /mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
return return
/mob/proc/canUseStorage()
return FALSE
/mob/proc/faction_check_mob(mob/target, exact_match) /mob/proc/faction_check_mob(mob/target, exact_match)
if(exact_match) //if we need an exact match, we need to do some bullfuckery. if(exact_match) //if we need an exact match, we need to do some bullfuckery.
var/list/faction_src = faction.Copy() var/list/faction_src = faction.Copy()

View File

@@ -201,6 +201,8 @@
B.reagents.add_reagent("blood", 20, data) B.reagents.add_reagent("blood", 20, data)
wait = TRUE wait = TRUE
update_icon() update_icon()
var/turf/source_turf = get_turf(src)
log_virus("A culture bottle was printed for the virus [A.admin_details()] at [loc_name(source_turf)] by [key_name(usr)]")
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50) addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50)
. = TRUE . = TRUE
if("create_vaccine_bottle") if("create_vaccine_bottle")

View File

@@ -146,6 +146,9 @@ LOG_MANIFEST
## Enable logging pictures ## Enable logging pictures
# LOG_PICTURES # LOG_PICTURES
## log virus and actions
LOG_VIRUS
##Log camera pictures - Must have picture logging enabled ##Log camera pictures - Must have picture logging enabled
PICTURE_LOGGING_CAMERA PICTURE_LOGGING_CAMERA