mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-08-22 21:46:13 +01:00
Initial Commit
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
/proc/generate_cold_pathogen()
|
||||
var/datum/pathogen/P = unpool(/datum/pathogen)
|
||||
P.forced_microbody = /datum/microbody/virus
|
||||
P.curable_by_suppression = 7
|
||||
P.setup(2, null, 0)
|
||||
P.add_symptom(pathogen_controller.path_to_symptom[/datum/pathogeneffects/malevolent/coughing])
|
||||
P.add_symptom(pathogen_controller.path_to_symptom[/datum/pathogeneffects/malevolent/indigestion])
|
||||
return P
|
||||
|
||||
/proc/generate_flu_pathogen()
|
||||
var/datum/pathogen/P = unpool(/datum/pathogen)
|
||||
P.forced_microbody = /datum/microbody/virus
|
||||
P.curable_by_suppression = 4
|
||||
P.setup(2, null, 0)
|
||||
P.add_symptom(pathogen_controller.path_to_symptom[/datum/pathogeneffects/malevolent/coughing])
|
||||
P.add_symptom(pathogen_controller.path_to_symptom[/datum/pathogeneffects/malevolent/sneezing])
|
||||
P.add_symptom(pathogen_controller.path_to_symptom[/datum/pathogeneffects/malevolent/muscleache])
|
||||
return P
|
||||
|
||||
/proc/generate_indigestion_pathogen()
|
||||
var/datum/pathogen/P = unpool(/datum/pathogen)
|
||||
P.curable_by_suppression = 18
|
||||
P.setup(2, null, 0)
|
||||
P.add_symptom(pathogen_controller.path_to_symptom[/datum/pathogeneffects/malevolent/indigestion])
|
||||
return P
|
||||
@@ -0,0 +1,181 @@
|
||||
datum/pathogeneffects/benevolent
|
||||
name = "Benevolent"
|
||||
rarity = RARITY_ABSTRACT
|
||||
|
||||
datum/pathogeneffects/benevolent/mending
|
||||
name = "Wound Mending"
|
||||
desc = "Slow paced brute damage healing."
|
||||
rarity = RARITY_UNCOMMON
|
||||
|
||||
disease_act(var/mob/M as mob, var/datum/pathogen/origin)
|
||||
if (!origin.symptomatic)
|
||||
return
|
||||
if (prob(origin.stage * 5))
|
||||
M.HealDamage("chest", origin.stage < 3 ? 1 : 2, 0)
|
||||
M.updatehealth()
|
||||
|
||||
react_to(var/R, var/zoom)
|
||||
if (R == "synthflesh")
|
||||
if (zoom)
|
||||
return "Microscopic damage on the synthetic flesh appears to be mended by the pathogen."
|
||||
|
||||
may_react_to()
|
||||
return "The pathogen appears to have the ability to bond with organic tissue."
|
||||
|
||||
datum/pathogeneffects/benevolent/healing
|
||||
name = "Burn Healing"
|
||||
desc = "Slow paced burn damage healing."
|
||||
rarity = RARITY_UNCOMMON
|
||||
|
||||
disease_act(var/mob/M as mob, var/datum/pathogen/origin)
|
||||
if (!origin.symptomatic)
|
||||
return
|
||||
if (prob(origin.stage * 5))
|
||||
M.HealDamage("chest", 0, origin.stage < 3 ? 1 : 2)
|
||||
M.updatehealth()
|
||||
|
||||
react_to(var/R, var/zoom)
|
||||
if (R == "synthflesh")
|
||||
if (zoom)
|
||||
return "The pathogen does not appear to mend the synthetic flesh. Perhaps something that might cause other types of injuries might help."
|
||||
if (R == "infernite")
|
||||
if (zoom)
|
||||
return "The pathogen repels the scalding hot chemical and quickly repairs any damage caused by it to organic tissue."
|
||||
|
||||
may_react_to()
|
||||
return "The pathogen appears to have the ability to bond with organic tissue."
|
||||
|
||||
datum/pathogeneffects/benevolent/detoxication
|
||||
name = "Detoxication"
|
||||
desc = "The pathogen aids the host body in metabolizing ethanol."
|
||||
rarity = RARITY_COMMON
|
||||
|
||||
disease_act(var/mob/M as mob, var/datum/pathogen/origin)
|
||||
if (!origin.symptomatic)
|
||||
return
|
||||
var/times = 1
|
||||
if (origin.stage > 3)
|
||||
times++
|
||||
if (origin.stage > 4)
|
||||
times++
|
||||
var/met = 0
|
||||
for (var/rid in M.reagents.reagent_list)
|
||||
var/datum/reagent/R = M.reagents.reagent_list[rid]
|
||||
if (rid == "ethanol" || istype(R, /datum/reagent/fooddrink/alcoholic))
|
||||
met = 1
|
||||
for (var/i = 1, i <= times, i++)
|
||||
if (R) //Wire: Fix for Cannot execute null.on mob life().
|
||||
R.on_mob_life()
|
||||
if (!R || R.disposed)
|
||||
break
|
||||
if (R && !R.disposed)
|
||||
M.reagents.remove_reagent(rid, R.depletion_rate * times)
|
||||
if (met)
|
||||
M.reagents.update_total()
|
||||
|
||||
react_to(var/R, var/zoom)
|
||||
if (R == "ethanol")
|
||||
return "The pathogen appears to have entirely metabolized the ethanol."
|
||||
|
||||
may_react_to()
|
||||
return "The pathogen appears to react with a pure intoxicant."
|
||||
|
||||
datum/pathogeneffects/benevolent/metabolisis
|
||||
name = "Accelerated Metabolisis"
|
||||
desc = "The pathogen accelerates the metabolisis of all chemicals present in the host body."
|
||||
rarity = RARITY_RARE
|
||||
|
||||
disease_act(var/mob/M as mob, var/datum/pathogen/origin)
|
||||
if (!origin.symptomatic)
|
||||
return
|
||||
var/times = 1
|
||||
if (origin.stage > 3)
|
||||
times++
|
||||
if (origin.stage > 4)
|
||||
times++
|
||||
var/met = 0
|
||||
for (var/rid in M.reagents.reagent_list)
|
||||
var/datum/reagent/R = M.reagents.reagent_list[rid]
|
||||
met = 1
|
||||
for (var/i = 1, i <= times, i++)
|
||||
if (R) //Wire: Fix for Cannot execute null.on mob life().
|
||||
R.on_mob_life()
|
||||
if (!R || R.disposed)
|
||||
break
|
||||
if (R && !R.disposed)
|
||||
M.reagents.remove_reagent(rid, R.depletion_rate * times)
|
||||
if (met)
|
||||
M.reagents.update_total()
|
||||
|
||||
|
||||
react_to(var/R, var/zoom)
|
||||
return "The pathogen appears to have entirely metabolized... all chemical agents in the dish."
|
||||
|
||||
may_react_to()
|
||||
return null
|
||||
|
||||
datum/pathogeneffects/benevolent/cleansing
|
||||
name = "Cleansing"
|
||||
desc = "The pathogen cleans the body of damage caused by toxins."
|
||||
rarity = RARITY_RARE
|
||||
|
||||
disease_act(var/mob/M as mob, var/datum/pathogen/origin)
|
||||
if (!origin.symptomatic)
|
||||
return
|
||||
if (prob(origin.stage * 5) && M.get_toxin_damage())
|
||||
M.take_toxin_damage(-1)
|
||||
if (origin.stage > 3)
|
||||
M.take_toxin_damage(-1)
|
||||
if (origin.stage > 4)
|
||||
M.take_toxin_damage(-1)
|
||||
M.updatehealth()
|
||||
if (prob(10))
|
||||
M.show_message("<span style=\"color:blue\">You feel cleansed.</span>")
|
||||
|
||||
react_to(var/R, var/zoom)
|
||||
return "The pathogen appears to have entirely metabolized... all chemical agents in the dish."
|
||||
|
||||
may_react_to()
|
||||
return null
|
||||
|
||||
datum/pathogeneffects/benevolent/oxygenconversion
|
||||
name = "Oxygen Conversion"
|
||||
desc = "The pathogen converts organic tissue into oxygen."
|
||||
rarity = RARITY_VERY_RARE
|
||||
|
||||
may_react_to()
|
||||
return "The pathogen appears to radiate a bubble of oxygen."
|
||||
|
||||
react_to(var/R, var/zoom)
|
||||
if (R == "synthflesh")
|
||||
return "The pathogen consumes the synthflesh and converts it into oxygen."
|
||||
|
||||
disease_act(var/mob/M as mob, var/datum/pathogen/origin)
|
||||
if (!origin.symptomatic)
|
||||
return
|
||||
if (M:losebreath > 0)
|
||||
M.TakeDamage("chest", M:losebreath * 2, 0)
|
||||
M:losebreath = 0
|
||||
if (prob(25))
|
||||
M.show_message("<span style=\"color:red\">You feel your body deteriorating as you breathe on.</span>")
|
||||
if (M.get_oxygen_deprivation())
|
||||
if (origin.stage != 0)
|
||||
M.take_oxygen_deprivation(0 - (origin.stage / 2))
|
||||
M.updatehealth()
|
||||
|
||||
datum/pathogeneffects/benevolent/oxygenproduction
|
||||
name = "Oxygen Production"
|
||||
desc = "The pathogen produces oxygen."
|
||||
rarity = RARITY_VERY_RARE
|
||||
|
||||
may_react_to()
|
||||
return "The pathogen appears to radiate a bubble of oxygen."
|
||||
|
||||
disease_act(var/mob/M as mob, var/datum/pathogen/origin)
|
||||
if (!origin.symptomatic)
|
||||
return
|
||||
if (M:losebreath > 0)
|
||||
M:losebreath = 0
|
||||
if (M.get_oxygen_deprivation())
|
||||
M.take_oxygen_deprivation(0 - origin.stage)
|
||||
M.updatehealth()
|
||||
@@ -0,0 +1,351 @@
|
||||
/**
|
||||
* Pathogen DNA
|
||||
*
|
||||
* The pathogen DNA sequence consists of two separately handled parts:
|
||||
* - The "private" sequence is basically a sequence that contains
|
||||
* - the unique identifier of the microbody of the pathogen, which must be defined in the /datum/microbody subclass.
|
||||
* the pathogen controller contains a lookup table of the existing microbody IDs for fast lookup, reducing search times from O(n) to O(1).
|
||||
* - the numeric values of the pathogen, sequentially, as two byte signed integers, which means each numeric value is encoded in the DNA sequence as four hexadecimal digits
|
||||
* - a single digit signifying the amount of stages of a pathogen
|
||||
* - a single digit signifying if the pathogen is symptomatic
|
||||
* at the time of writing this documentation, the sequence of the numeric values is:
|
||||
* mutativeness | mutation speed | advance speed | maliciousness | suppression threshold | stages
|
||||
* EXAMPLE: A pathogen that is a virus, with a mutativeness of 19, a mutation speed of 6, an advance speed of 5, a maliciousness of 7
|
||||
* and a suppression threshold of 5, 5 stages and symptomatic carries the following DNA sequence:
|
||||
* 00010013000600050007000551
|
||||
* DEVELOPER NOTE: The encoding is NOT two's complement as any coder would expect, due to the fact that I have no idea how
|
||||
* BYOND numbers are represented. The encoding of the two bytes is 2 byte one's complement. (I think. Whatever.)
|
||||
* NOTE: While any of these values are highly unlikely to ever pass 255, I'll leave it open for two bytes.
|
||||
* This private sequence is only ever printed and cannot be directly spliced. Modifying the numeric values is done through seed mutation logic.
|
||||
* Since this part of the DNA is never directly modified, this part is always calculated from the numeric values.
|
||||
* - The "public" sequence is the sequence that contains
|
||||
* - The suppressant of the pathogen. Each suppressant is given a round-randomized 3 quartet (1.5 byte) unique identifier by the pathogen controller upon round setup.
|
||||
* A lookup table of available suppressants is available in the pathogen controller for fast processing.
|
||||
* - A single separator to signal the end of suppressants and the beginning of carriers.
|
||||
* - All carriers, sequentially. Carriers are assigned 3 quartets as well, and they have their own lookup table.
|
||||
* - Anything I may have forgot to mention is also here.
|
||||
* - A single separator to signal the beginning of the symptoms.
|
||||
* - All symptoms of the pathogen sequentially. This might and will cause the DNA to inflate to a very large and complex sequence if a very mutative pathogen is introduced to the station.
|
||||
* A symptom is composed of R * 3 quartets, where R represents rarity, followed by a 'DNA separator' marked by a | in the DNA.
|
||||
* Rarity is a value from 1 to 5, where 1 is VERY COMMON and 5 is VERY RARE. All symptoms are assigned this value as their unique identifier and an unique identifier is generated for
|
||||
* each symptom at round setup following this pattern:
|
||||
* 1) All VERY_COMMON symptoms are assigned a symptom-unique round randomized 3 quartet (eg. 1F3 is now sweating and EE2 is now farting)
|
||||
* 2) All symptoms of rarity R (where R is the next lowest rarity category not yet processed) are assigned a 3R quartet. First, a set of available identifiers is generated by taking
|
||||
* each identifier for rarity R-1 symptoms, and prepending and appending the identifier of all VERY_COMMON symptoms. This will generate a moderate amount of collisions (for example
|
||||
* prepeding 1F3 to EE20AB yields the same as appending 0AB to 1F3EE2), which are then eliminated. Then, rarity R symptoms are each assigned a randomly pick()-ed identifier from this
|
||||
* list. If, due to an inbalance in the amount of symptoms available there is no ID that is left avaiable and the sequence will be a randomly generated 3R quartet. This, of course,
|
||||
* means that the symptom cannot be synthesized via pathology science that round. Tough luck.
|
||||
* At the time of writing this documentation, the numbers add up and all symptoms should be synthesizable. At current time, it is also hard to synthesize a VERY_RARE symptom. which
|
||||
* is intended and a good thing.
|
||||
* The DNA separators are a sort of 'resource' available to pathologists, although infinite of them is produceable through replicating DNA. If someone can come up with any reasonable way
|
||||
* to limit DNA separators, I am open to implementing it.
|
||||
* What is a DNA separator though? Well, as the above algorithm shows, the identifier sequence of each high tier symptom is composed of VALID sequences for lower tier symptoms. To be able
|
||||
* to determine which symptom is supposed to be a higher tier one, symptoms must be separated by a ~magical nucleic acid~ we call the DNA separator. This means that a pathogen of K symptoms
|
||||
* will contain K-1 DNA separators.
|
||||
* The pathogen controller will contain a symptom lookup table and an inverse table for looking up the numeric identifier.
|
||||
* Due to the nature of this, we are limited to 4096 (2^12, 3 quartets) VERY_COMMON symptoms. Oh the horror.
|
||||
* This part of the DNA is modifiable through splicing. During a splicing session, you can scrap parts of the DNA and introduce new parts from already existing DNA. Once the splicing session
|
||||
* is complete, the DNA is evaluated (compiled) and destroyed if it contains an invalid sequence (such as an attempt to create a tier three symptom, but no tier three symptom having that
|
||||
* specific DNA sequence). I believe pathologists will be kept busy by making their ~fancy symptoms~ all round, and it's not as straightforward as chemistry or as boring as genetics.
|
||||
* EXAMPLE: Suppose that sweating is 1F3, farting is EE2, coughing is sweating + farting (1F3EE2) and the heat weakness suppressant is 0C3.
|
||||
* The DNA sequence for a pathogen with the above three symptoms, no carriers and heat weakness would be:
|
||||
* 0C3||1F3|EE2|1F3EE2
|
||||
* During splicing, moving could only be done by moving coherent parts. A coherent part is a 3 quartet beginning at a 3 quartet boundary or after a DNA separator. This means one could move
|
||||
* 1F3 or EE2 out of 1F3EE2 but not 3EE or F3E. A single DNA separator is also a coherent part. A coherent part could only be moved to a boundary (ie. inserted between two existing coherent
|
||||
* parts)
|
||||
* EXAMPLE: Suppose that no symptom gained the unique identifier of farting + sweating (EE21F3). A pathologist splicing the above DNA sequence into
|
||||
* 0C3||1F3|EE21F3
|
||||
* would be in for a nasty surprise, as the DNA collapses, due to EE21F3 being an invalid sequence.
|
||||
* Due to the nature of the rolling unique identifiers, of course it does not mean EE21F3AB0 couldn't be a valid sequence, as a symptom with the sequence 1F3AB0 could exist, and a higher
|
||||
* tier symptom could have EE2 prepended to this. This means that only ELEMENTARY (3 quartet starting at boundary) subsets of a symptom's unique identifier is also guaranteed to be a
|
||||
* valid unique identifier.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pathogen mutate-and-effect graph
|
||||
*
|
||||
* When numeric values of pathogens are mutated, other values are mutated in the other direction. This graph defines the mutation of which values effect which other values.
|
||||
* (For every action, there is an equal and opposite reaction, except it's not equal because that would be annoying and I'm not trying to apply Newton's third law of motion)
|
||||
*
|
||||
* mutativeness ------------- advance_speed
|
||||
* | /
|
||||
* | maliciousness
|
||||
* | \
|
||||
* sthreshold --------------- mutation_speed
|
||||
*
|
||||
* ...sometimes I wish BYOND had pointers because it would be so much cleaner. I'm not going to use whatever twisted thing DM called refs.
|
||||
*/
|
||||
|
||||
datum/pathogendna
|
||||
var/seqnumeric = "00000000000000000000000000"
|
||||
var/seqsplice = ""
|
||||
|
||||
var/valid = 0
|
||||
|
||||
var/datum/pathogen/reference = null
|
||||
|
||||
New(var/datum/pathogen/P)
|
||||
if (P)
|
||||
reference = unpool(/datum/pathogen)
|
||||
reference.setup(0, P, 0, src)
|
||||
recalculate()
|
||||
reverse_engineer()
|
||||
valid = 1
|
||||
else
|
||||
reference = unpool(/datum/pathogen)
|
||||
valid = 0
|
||||
|
||||
proc/clone()
|
||||
var/datum/pathogendna/D = new(reference)
|
||||
return D
|
||||
|
||||
proc/manipulate(value, direction)
|
||||
var/datum/pathogendna/this = src
|
||||
src = null
|
||||
if (prob(2))
|
||||
del this
|
||||
return 0
|
||||
else if (prob(4))
|
||||
this.reference.mutate()
|
||||
this.recalculate()
|
||||
this.reverse_engineer()
|
||||
return -1
|
||||
if (direction > 0)
|
||||
direction = 1
|
||||
else
|
||||
direction = -1
|
||||
if (!this)
|
||||
return 0 // We somehow lost the DNA.
|
||||
switch (value)
|
||||
if ("mutativeness"):
|
||||
this.reference.mutativeness += rand(1, 3) * direction
|
||||
this.reference.advance_speed -= rand(0, 1) * direction
|
||||
this.reference.suppression_threshold -= rand(0, 1) * direction
|
||||
if ("suppression_threshold"):
|
||||
this.reference.suppression_threshold += rand(1, 3) * direction
|
||||
this.reference.mutation_speed -= rand(0, 1) * direction
|
||||
this.reference.mutativeness -= rand(0, 1) * direction
|
||||
if ("mutation_speed")
|
||||
this.reference.mutation_speed += rand(1, 3) * direction
|
||||
this.reference.suppression_threshold -= rand(0, 1) * direction
|
||||
this.reference.maliciousness -= rand(0, 1) * direction
|
||||
if ("maliciousness")
|
||||
this.reference.maliciousness += rand(1, 3) * direction
|
||||
this.reference.advance_speed -= rand(0, 1) * direction
|
||||
this.reference.mutation_speed -= rand(0, 1) * direction
|
||||
if ("advance_speed")
|
||||
this.reference.advance_speed += rand(1, 3) * direction
|
||||
this.reference.mutativeness -= rand(0, 1) * direction
|
||||
this.reference.maliciousness -= rand(0, 1) * direction
|
||||
if (this.reference.mutation_speed < 0)
|
||||
this.reference.mutation_speed = 0
|
||||
this.recalculate()
|
||||
return 1
|
||||
|
||||
proc/explode()
|
||||
var/list/ret = new/list()
|
||||
var/pos = 1
|
||||
while (pos < lentext(seqsplice))
|
||||
if (copytext(seqsplice, pos, pos + 1) != "|")
|
||||
ret += copytext(seqsplice, pos, pos + 3)
|
||||
pos += 3
|
||||
else
|
||||
ret += "|"
|
||||
pos += 1
|
||||
return ret
|
||||
|
||||
proc/implode(var/list/parts)
|
||||
var/newseq = ""
|
||||
for (var/i = 1, i <= parts.len, i++)
|
||||
newseq += parts[i]
|
||||
seqsplice = newseq
|
||||
valid = 0
|
||||
return
|
||||
|
||||
proc/get_sequences()
|
||||
var/list/seq = list()
|
||||
var/list/parts = explode()
|
||||
var/i = 1
|
||||
var/s = 0
|
||||
while (i < parts.len && s < 2)
|
||||
if (parts[i] == "|")
|
||||
s++
|
||||
i++
|
||||
if (s < 2)
|
||||
return seq
|
||||
var/act_seq = ""
|
||||
while (i < parts.len)
|
||||
if (parts[i] == "|")
|
||||
if (act_seq != "")
|
||||
seq += act_seq
|
||||
else
|
||||
return list() // error
|
||||
act_seq = ""
|
||||
else
|
||||
act_seq += parts[i]
|
||||
i++
|
||||
if (act_seq == "")
|
||||
return list()
|
||||
seq += act_seq
|
||||
return seq
|
||||
|
||||
// Pathogen numeric -> DNA/Private
|
||||
proc/recalculate()
|
||||
// BYOND number vars are unreliable. All numbers are rounded.
|
||||
var/uid = num2hexoc(round(src.reference.body_type.uniqueid), 4)
|
||||
var/mut = num2hexoc(round(src.reference.mutativeness), 4)
|
||||
var/mts = num2hexoc(round(src.reference.mutation_speed), 4)
|
||||
var/adv = num2hexoc(round(src.reference.advance_speed), 4)
|
||||
var/mal = num2hexoc(round(src.reference.maliciousness), 4)
|
||||
var/sup = num2hexoc(round(src.reference.suppression_threshold), 4)
|
||||
src.seqnumeric = "[uid][mut][mts][adv][mal][sup][src.reference.stages][src.reference.symptomatic]"
|
||||
|
||||
// DNA/Private -> Pathogen numeric
|
||||
proc/reevaluate_numeric()
|
||||
var/uid = hex2numoc(copytext(seqnumeric, 1, 5))
|
||||
var/mut = hex2numoc(copytext(seqnumeric, 5, 9))
|
||||
var/mts = hex2numoc(copytext(seqnumeric, 9, 13))
|
||||
var/adv = hex2numoc(copytext(seqnumeric, 13, 17))
|
||||
var/mal = hex2numoc(copytext(seqnumeric, 17, 21))
|
||||
var/sup = hex2numoc(copytext(seqnumeric, 21, 25))
|
||||
var/stages = text2num(copytext(seqnumeric, 25, 26))
|
||||
var/symptomatic = text2num(copytext(seqnumeric, 26, 27))
|
||||
src.reference.mutativeness = mut
|
||||
src.reference.mutation_speed = mts
|
||||
src.reference.advance_speed = adv
|
||||
src.reference.maliciousness = mal
|
||||
src.reference.suppression_threshold = sup
|
||||
src.reference.stages = stages
|
||||
src.reference.symptomatic = symptomatic
|
||||
for(var/T in pathogen_controller.path_to_microbody)
|
||||
var/datum/microbody/B = pathogen_controller.path_to_microbody[T]
|
||||
if (B.uniqueid == uid)
|
||||
src.reference.body_type = B
|
||||
src.reference.stages = B.stages
|
||||
break
|
||||
|
||||
// Pathogen data -> DNA/Public
|
||||
proc/reverse_engineer()
|
||||
src.seqsplice = pathogen_controller.suppressant_to_UID[reference.suppressant.type]
|
||||
src.seqsplice += "|"
|
||||
//for (var/datum/pathogen_carrier/C in src.reference.carriers)
|
||||
// src.seqsplice += pathogen_controller.carrier_to_UID[C.type]
|
||||
src.seqsplice += "|"
|
||||
var/first = 1
|
||||
for (var/datum/pathogeneffects/E in src.reference.effects)
|
||||
if (!first)
|
||||
src.seqsplice += "|"
|
||||
else
|
||||
first = 0
|
||||
src.seqsplice += pathogen_controller.symptom_to_UID[E.type]
|
||||
|
||||
// DNA/Public -> Pathogen data
|
||||
proc/reevaluate()
|
||||
// Move src reference so we can return false if evaluation fails (important for whatever is calling this)
|
||||
var/datum/pathogendna/this = src
|
||||
src = null
|
||||
var/desc = this.reference.desc
|
||||
var/name_base = this.reference.name_base
|
||||
var/mutation = this.reference.mutation
|
||||
var/uid = this.reference.pathogen_uid
|
||||
this.reference.clear()
|
||||
this.reference.desc = desc
|
||||
this.reference.name_base = name_base
|
||||
this.reference.base_mutation = mutation
|
||||
this.reference.pathogen_uid = uid
|
||||
this.reference.mutation = pathogen_controller.next_mutation[num2text(uid)]
|
||||
this.reference.stage = 1
|
||||
this.reference.name = "[name_base][mutation]"
|
||||
pathogen_controller.next_mutation[num2text(uid)] += 1
|
||||
this.reevaluate_numeric()
|
||||
// Partition the DNA for traversal.
|
||||
var/list/parts = this.explode()
|
||||
if (!(parts[1] in pathogen_controller.UID_to_suppressant))
|
||||
//log_game("[this.seqsplice] collapses: non-existent suppressant.")
|
||||
qdel(this) // Bad DNA: Invalid suppressant.
|
||||
return 0
|
||||
else
|
||||
if (this)
|
||||
var/supp = pathogen_controller.UID_to_suppressant[parts[1]]
|
||||
this.reference.suppressant = pathogen_controller.path_to_suppressant[supp]
|
||||
else
|
||||
return 0 // Somehow, we lost the DNA.
|
||||
if (parts[2] != "|")
|
||||
//log_game("[this.seqsplice] collapses: no separator after suppressant.")
|
||||
qdel(this)
|
||||
return 0 // Bad DNA: no separator after suppressant.
|
||||
var/pos = 2
|
||||
if (parts[3] == "|")
|
||||
pos = 4 // No carriers.
|
||||
else
|
||||
pos = 3
|
||||
while (pos <= parts.len && parts[pos] != "|")
|
||||
if (!(parts[pos] in pathogen_controller.UID_to_carrier))
|
||||
//log_game("[this.seqsplice] collapses: non-existent carrier.")
|
||||
qdel(this) // Bad DNA: Invalid carrier
|
||||
return 0
|
||||
else
|
||||
if (this)
|
||||
this.reference.carriers += pathogen_controller.UID_to_carrier[parts[pos]]
|
||||
else
|
||||
return 0 // Somehow, we lost the DNA.
|
||||
pos++
|
||||
if (pos == parts.len)
|
||||
//log_game("[this.seqsplice] collapses: no separator after carriers.")
|
||||
qdel(this) // Bad DNA: No ending separator after carriers.
|
||||
return 0
|
||||
pos++
|
||||
|
||||
// Assemble the list of symptoms.
|
||||
var/symptom = ""
|
||||
|
||||
while (pos <= parts.len)
|
||||
if (parts[pos] == "|")
|
||||
if (symptom != "")
|
||||
// Validate symptom
|
||||
if (!(symptom in pathogen_controller.UID_to_symptom))
|
||||
//log_game("[this.seqsplice] collapses: non-existent symptom [symptom].")
|
||||
qdel(this) // Bad DNA: DNA contains invalid symptom
|
||||
return 0
|
||||
else
|
||||
if (this)
|
||||
var/sym = pathogen_controller.UID_to_symptom[symptom]
|
||||
this.reference.effects += pathogen_controller.path_to_symptom[sym]
|
||||
symptom = ""
|
||||
else
|
||||
return 0 // Somehow, we lost the DNA.
|
||||
else
|
||||
//log_game("[this.seqsplice] collapses: two adjacent symptom separators.")
|
||||
qdel(this) // Bad DNA: DNA contains two adjacent separators
|
||||
return 0
|
||||
else
|
||||
symptom += parts[pos]
|
||||
pos++
|
||||
if (symptom != "")
|
||||
if (!(symptom in pathogen_controller.UID_to_symptom))
|
||||
//log_game("[this.seqsplice] collapses: non-existent symptom [symptom].")
|
||||
qdel(this) // Bad DNA: DNA contains invalid symptom
|
||||
return 0
|
||||
else
|
||||
if (this)
|
||||
var/sym = pathogen_controller.UID_to_symptom[symptom]
|
||||
this.reference.effects += pathogen_controller.path_to_symptom[sym]
|
||||
else
|
||||
return 0 // Somehow, we lost the DNA.
|
||||
// DNA has been completely evaluated if we reach this point in execution and it is a valid pathogen DNA. Hooray!
|
||||
// Build the available symptom list for the pathogen.
|
||||
this.reference.dnasample = this
|
||||
this.valid = 1
|
||||
return 1 // Success.
|
||||
|
||||
proc/regenerate_uid()
|
||||
src.reference.pathogen_uid = "[pathogen_controller.next_uid]"
|
||||
src.reference.mutation = pick(pathogen_controller.lnums)
|
||||
src.reference.name_base = pick(pathogen_controller.lalph) + pick(pathogen_controller.lnums) + pick(pathogen_controller.lalph)
|
||||
src.reference.name = src.reference.name_base + "[src.reference.mutation]"
|
||||
pathogen_controller.next_uid++
|
||||
|
||||
proc/move_mutation()
|
||||
src.reference.mutation = pathogen_controller.next_mutation[src.reference.pathogen_uid]
|
||||
pathogen_controller.next_mutation[src.reference.pathogen_uid] += 1
|
||||
src.reference.name = src.reference.name_base + "[src.reference.mutation]"
|
||||
@@ -0,0 +1,67 @@
|
||||
/proc/shakespearify(var/string)
|
||||
string = dd_replacetext(string, "your ", "[pick("thy", "thine")] ")
|
||||
string = dd_replacetext(string, " your", " [pick("thy", "thine")]")
|
||||
string = dd_replacetext(string, " is ", " be ")
|
||||
string = dd_replacetext(string, "you ", "thou ")
|
||||
string = dd_replacetext(string, " you", " thou")
|
||||
string = dd_replacetext(string, "are ", "art ")
|
||||
string = dd_replacetext(string, " are", " art")
|
||||
string = dd_replacetext(string, "does ", "doth ")
|
||||
string = dd_replacetext(string, " does", " doth")
|
||||
string = dd_replacetext(string, "do ", "doth ")
|
||||
string = dd_replacetext(string, " do", " doth")
|
||||
string = dd_replacetext(string, "she ", "the lady ")
|
||||
string = dd_replacetext(string, " she", " the lady")
|
||||
string = dd_replacetext(string, "i think", "methinks")
|
||||
return string
|
||||
|
||||
/mob/living/carbon/human/proc/become_ice_statue()
|
||||
var/obj/overlay/iceman = new /obj/overlay(get_turf(src))
|
||||
src.pixel_x = 0
|
||||
src.pixel_y = 0
|
||||
src.set_loc(iceman)
|
||||
iceman.name = "ice statue of [src.name]"
|
||||
iceman.desc = "We here at Space Station 13 believe in the transparency of our employees. It doesn't look like a functioning human can be retrieved from this."
|
||||
iceman.anchored = 0
|
||||
iceman.density = 1
|
||||
iceman.layer = MOB_LAYER
|
||||
iceman.dir = src.dir
|
||||
iceman.alpha = 128
|
||||
|
||||
var/ist = "body_f"
|
||||
if (src.gender == "male")
|
||||
ist = "body_m"
|
||||
var/icon/composite = icon('icons/mob/human.dmi', ist, null, 1)
|
||||
for(var/O in src.overlays)
|
||||
var/image/I = O
|
||||
composite.Blend(icon(I.icon, I.icon_state, null, 1), ICON_OVERLAY)
|
||||
composite.ColorTone( rgb(165,242,243) ) // ice
|
||||
iceman.icon = composite
|
||||
src.take_toxin_damage(INFINITY)
|
||||
src.ghostize()
|
||||
|
||||
/proc/generate_random_pathogen()
|
||||
var/datum/pathogen/P = unpool(/datum/pathogen)
|
||||
P.setup(1, null, 0)
|
||||
return P
|
||||
|
||||
/proc/wrap_pathogen(var/datum/reagents/reagents, var/datum/pathogen/P, var/units = 5)
|
||||
reagents.add_reagent("pathogen", units)
|
||||
var/datum/reagent/blood/pathogen/R = reagents.get_reagent("pathogen")
|
||||
if (R)
|
||||
R.pathogens[P.pathogen_uid] = P
|
||||
|
||||
/proc/ez_pathogen(var/stype)
|
||||
var/datum/pathogen/P = unpool(/datum/pathogen)
|
||||
var/datum/pathogen_cdc/cdc = P.generate_name()
|
||||
cdc.mutations += P.name
|
||||
cdc.mutations[P.name] = P
|
||||
P.generate_components(cdc, 0)
|
||||
P.generate_attributes(0)
|
||||
P.mutativeness = 0
|
||||
P.mutation_speed = 0
|
||||
P.advance_speed = 6
|
||||
P.suppression_threshold = max(1, P.suppression_threshold)
|
||||
P.add_symptom(pathogen_controller.path_to_symptom[stype])
|
||||
logTheThing("pathology", null, null, "Pathogen [P.name] created by quick-pathogen-proc with symptom [stype].")
|
||||
return P
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* Microbody notes
|
||||
*
|
||||
* A pathogen microbody identifies the cause of the disease.
|
||||
* Most of the real life causes for diseases have been added already.
|
||||
* Each microbody defines a specific characteristic for a pathogen:
|
||||
* - How fast does the infection spiral out of control on the station (mutativeness)
|
||||
* - How bad will the disease eventually evolve? (maliciousness multiplier)
|
||||
* - How fast is the evolution of the disease? (mutation speed multiplier)
|
||||
* - How powerful is a disease caused by the microbody (stages).
|
||||
* - What is a fertile soil to cultivate this pathogen? (growth medium)
|
||||
*
|
||||
*
|
||||
* We differentiate between two types of cures:
|
||||
* - Serum. Every microbody has a serum; there is nothing that is currently incurable. Of course not adding a cure for a specific
|
||||
* microbody will make all pathogens of that microbody incurable.
|
||||
* - Vaccine. Currently, only virii have vaccines; injecting someone with a vaccine for a pathogen will make them immune to said
|
||||
* pathogen and all its mutations. A traitor would use this for his very deadly airbourne pathogen to avoid getting infected
|
||||
* by it.
|
||||
*/
|
||||
|
||||
// A microscopic body, acting as a pathogen.
|
||||
datum/microbody
|
||||
var/name = "Microscopic body"
|
||||
var/singular = "microscopic body"
|
||||
var/plural = "microscopic bodies"
|
||||
|
||||
// The strength of the microbody. Used for randomization.
|
||||
var/strength = 2
|
||||
|
||||
// An inverse of rarity. A value of 10 means a ten times relative chance to a value of 1.
|
||||
var/commonness = 10
|
||||
|
||||
// Base mutativeness value for this microbody.
|
||||
var/mutativeness = 6
|
||||
|
||||
// Multiplier for randomly generated maliciousness and mutation speed with this microbody.
|
||||
var/maliciousness_multiplier = 1
|
||||
var/mutation_speed_multiplier = 1
|
||||
|
||||
// The amount of stages a pathogen with this microbody has.
|
||||
// Technically, this means there are less aggressive and more aggressive infections depending on the microbody.
|
||||
// Keep this value between 3 and 5.
|
||||
var/stages = 3
|
||||
|
||||
// Activity determines the probability of symptoms manifesting in each stage for a particular microbody.
|
||||
var/activity = list(20, 20, 20, 20, 20)
|
||||
|
||||
// The growth medium is the reagent whose presence will make pathogens of this microbody grow in petri dishes.
|
||||
// DO NOT set this to "blood" or "pathogen", only to a derivative.
|
||||
var/growth_medium = "water"
|
||||
|
||||
// The base reagent for cures to this specific microbody type. Will be used by the synth-o-matic. Keep this null for an incurable microbody.
|
||||
var/cure_base = "serum"
|
||||
|
||||
// Can you make a vaccine for this microbody? (Instant immunity)
|
||||
var/vaccination = 0
|
||||
|
||||
// The unique ID for this microbody. Used in public DNA.
|
||||
var/uniqueid = 0
|
||||
|
||||
// If specified, a special module is needed for the Synth-O-Matic to synthesize a cure for this microbody.
|
||||
var/module_id = null
|
||||
|
||||
// A list of reagent IDs, each of which is required for the growth of a pathogen.
|
||||
var/list/nutrients = list("water", "sugar", "sodium", "iron", "nitrogen")
|
||||
|
||||
// If 1, curing also immunizes to re-infection.
|
||||
var/auto_immunize = 0
|
||||
|
||||
// The amount of nutrition of each type required per unit of pathogen to continue cultivation.
|
||||
var/amount = 0.07
|
||||
|
||||
Del()
|
||||
CRASH("ALERT MICROBODY IS BEING DELETED")
|
||||
|
||||
disposing()
|
||||
CRASH("ALERT MICROBODY IS BEING DISPOSED")
|
||||
|
||||
datum/microbody/virus
|
||||
name = "Virus"
|
||||
singular = "virus"
|
||||
plural = "viruses"
|
||||
|
||||
mutativeness = 15
|
||||
maliciousness_multiplier = 2
|
||||
mutation_speed_multiplier = 3
|
||||
|
||||
stages = 5
|
||||
|
||||
activity = list(1, 5, 20, 30, 40)
|
||||
|
||||
// Grows in eggs.
|
||||
growth_medium = "egg"
|
||||
|
||||
cure_base = "antiviral"
|
||||
vaccination = 1
|
||||
auto_immunize = 1
|
||||
|
||||
uniqueid = 1
|
||||
module_id = "virii"
|
||||
|
||||
datum/microbody/bacteria
|
||||
name = "Bacteria"
|
||||
singular = "bacterium"
|
||||
plural = "bacteria"
|
||||
|
||||
mutativeness = 6
|
||||
maliciousness_multiplier = 1
|
||||
mutation_speed_multiplier = 1
|
||||
|
||||
activity = list(7, 15, 25, 30, 35)
|
||||
|
||||
stages = 3
|
||||
|
||||
growth_medium = "bacterialmedium"
|
||||
|
||||
cure_base = "spaceacillin"
|
||||
auto_immunize = 1
|
||||
|
||||
uniqueid = 2
|
||||
module_id = "bacteria"
|
||||
|
||||
datum/microbody/fungi
|
||||
name = "Fungi"
|
||||
singular = "fungus"
|
||||
plural = "fungi"
|
||||
|
||||
mutativeness = 0
|
||||
maliciousness_multiplier = 2
|
||||
mutation_speed_multiplier = 1
|
||||
|
||||
stages = 4
|
||||
|
||||
activity = list(7, 8, 10, 14, 25)
|
||||
|
||||
growth_medium = "fungalmedium"
|
||||
|
||||
cure_base = "biocide"
|
||||
|
||||
uniqueid = 3
|
||||
module_id = "fungi"
|
||||
|
||||
datum/microbody/parasite
|
||||
name = "Parasites"
|
||||
singular = "parasite"
|
||||
plural = "parasites"
|
||||
|
||||
mutativeness = 3
|
||||
maliciousness_multiplier = 4
|
||||
mutation_speed_multiplier = 3
|
||||
|
||||
stages = 5
|
||||
|
||||
activity = list(30, 20, 10, 8, 8)
|
||||
|
||||
growth_medium = "parasiticmedium"
|
||||
|
||||
cure_base = "biocide"
|
||||
|
||||
uniqueid = 4
|
||||
module_id = "parasite"
|
||||
|
||||
datum/microbody/gmcell
|
||||
name = "Great Mutatis cell"
|
||||
singular = "great mutatis cell"
|
||||
plural = "great mutatis cells"
|
||||
|
||||
strength = 10
|
||||
commonness = 2
|
||||
|
||||
activity = list(20, 20, 20, 20, 20)
|
||||
|
||||
mutativeness = 45
|
||||
maliciousness_multiplier = 7
|
||||
mutation_speed_multiplier = 5
|
||||
|
||||
stages = 5
|
||||
|
||||
// Grows in stable mutagen.
|
||||
// INTEGRATION NOTES: stable mutagen reagent ID.
|
||||
growth_medium = "dna_mutagen"
|
||||
|
||||
cure_base = "inhibitor"
|
||||
|
||||
uniqueid = 5
|
||||
module_id = "gmcell"
|
||||
|
||||
nutrients = list("dna_mutagen")
|
||||
amount = 0.35
|
||||
@@ -0,0 +1,421 @@
|
||||
#define MUTATION_MALICIOUS 1
|
||||
#define MUTATION_BENEVOLENT -1
|
||||
|
||||
#define MUTATION_EVOLUTION 1
|
||||
#define MUTATION_DEVOLUTION -1
|
||||
|
||||
/**
|
||||
* Pathogen Mutations
|
||||
*
|
||||
* All possible mutation effects are a child of /datum/pathogen_mutation.
|
||||
* These will be automatically chosen at random as candidates for mutation.
|
||||
* There are a number of factors deciding whether or not a certain kind of mutation will occur. If a mutation's criteria are not satisfied,
|
||||
* new mutations are chosen until one with satisfied criteria is found. The default mutations are defined so that no situation may arise
|
||||
* where a mutation cannot be picked. Regardless, if all mutations defined are unsatisfied, a mutation will not occur.
|
||||
*
|
||||
* Each mutation may occur exactly session_maximum times per mutation session.
|
||||
* This is in to prevent abusing the mutation system for gathering a large amount of symptoms quickly.
|
||||
* Symptom gaining mutations are also purposefully made harder to gain very deadly symptoms.
|
||||
*
|
||||
* Mutation criteria for malicious mutations:
|
||||
* - For a malicious mutation to occur on a pathogen, its maliciousness must be greater or equal to the mutation's maliciousness threshold.
|
||||
* - For this mutation to occur, its maliciousness must be no greater than its maliciousness limit, unless the limit is lower than the
|
||||
* threshold.
|
||||
* - For this mutation to occur, the pathogen's mutativeness must be greater than the mutativeness threshold if it's an evolution, or
|
||||
* lower than the mutativeness threshold if it's a devolution. It may also occur on equality.
|
||||
* - If all the above criteria are satisfied, the chance of this mutation actually occurring is
|
||||
* chance_base + maliciousness * chance_modifier
|
||||
*
|
||||
* Mutation criteria for benevolent mutations:
|
||||
* - For a benevolent mutation to occur on a pathogen, its maliciousness must be less or equal to the mutation's maliciousness threshold.
|
||||
* - For this mutation to occur, its maliciousness must be no less than its maliciousness limit, unless the limit is higher than the
|
||||
* threshold.
|
||||
* - For this mutation to occur, the pathogen's mutativeness must be greater than the mutativeness threshold if it's an evolution, or
|
||||
* lower than the mutativeness threshold if it's a devolution. It may also occur on equality.
|
||||
* - If all the above criteria are satisfied, the chance of this mutation actually occurring is
|
||||
* chance_base - maliciousness * chance_modifier
|
||||
*
|
||||
* The mutation code must be in the mutate proc of the child type. It will be executed automatically if the mutation occurs.
|
||||
*/
|
||||
|
||||
datum/pathogen_mutation
|
||||
var/name = "Pathogen Mutation"
|
||||
var/desc = "Generic mutation"
|
||||
var/malicious_type = MUTATION_MALICIOUS
|
||||
var/maliciousness_threshold = 0
|
||||
var/maliciousness_limit = -1
|
||||
|
||||
var/session_maximum = 1
|
||||
|
||||
var/chance_base = 50
|
||||
var/chance_modifier = 0
|
||||
|
||||
var/evolution_type = MUTATION_EVOLUTION
|
||||
var/mutativeness_threshold = 0
|
||||
|
||||
proc/may_occur(var/datum/pathogen/P)
|
||||
if (malicious_type * P.maliciousness >= malicious_type * maliciousness_threshold && (malicious_type * maliciousness_limit < malicious_type * maliciousness_threshold || malicious_type * P.maliciousness <= malicious_type * maliciousness_limit) && evolution_type * P.mutativeness >= evolution_type * mutativeness_threshold)
|
||||
if (prob(chance_base + malicious_type * P.maliciousness * chance_modifier))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
proc/mutate(var/datum/pathogen/P)
|
||||
return
|
||||
|
||||
// This mutation is a general purpose mutation which acts as a "mutation sink" - it absorbs mutations from the pool by existing and
|
||||
// occurring. This is mostly here for balance purposes.
|
||||
datum/pathogen_mutation/scramble
|
||||
name = "Attribute Scramble"
|
||||
desc = "Modifies the five primary attributes of a pathogen by an amount."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
session_maximum = 5
|
||||
evolution_type = MUTATION_DEVOLUTION
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return P.symptomatic && prob(20)
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
var/factor = rand(1, 4)
|
||||
P.mutativeness = P.mutativeness + factor * rand(-2, 2)
|
||||
P.maliciousness = P.maliciousness + factor * rand(-2, 2)
|
||||
P.suppression_threshold = P.suppression_threshold + factor * rand(-2, 2)
|
||||
P.advance_speed = P.advance_speed + factor * rand(-2, 2)
|
||||
P.mutation_speed = P.mutation_speed + factor * rand(-2, 2)
|
||||
|
||||
// This mutation exists to introduce a risk factor to getting mutations. Before this, mutations carried the pathogen in the desired
|
||||
// direction.
|
||||
datum/pathogen_mutation/lose_attributes
|
||||
name = "Lose All Attributes"
|
||||
desc = "Sets all five primary attributes of a pathogen to 0."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
evolution_type = MUTATION_DEVOLUTION
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return P.symptomatic && prob(8)
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.mutativeness = 0
|
||||
P.maliciousness = 0
|
||||
P.suppression_threshold = 0
|
||||
P.advance_speed = 0
|
||||
P.mutation_speed = 0
|
||||
|
||||
datum/pathogen_mutation/increase_generation
|
||||
name = "Increase Generation"
|
||||
desc = "Advances a pathogen to the next generation. Higher generation pathogens may overtake a lower generation infection of the same strain."
|
||||
malicious_type = MUTATION_BENEVOLENT
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return 1
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.generation++
|
||||
|
||||
datum/pathogen_mutation/become_asymptomatic
|
||||
name = "Become Asymptomatic"
|
||||
desc = "The mutated strain becomes asymptomatic."
|
||||
malicious_type = MUTATION_BENEVOLENT
|
||||
evolution_type = MUTATION_DEVOLUTION
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return P.symptomatic && prob(35)
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.symptomatic = 0
|
||||
|
||||
datum/pathogen_mutation/become_symptomatic
|
||||
name = "Become Symptomatic"
|
||||
desc = "The mutated strain becomes symptomatic."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return !P.symptomatic
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.symptomatic = 1
|
||||
|
||||
datum/pathogen_mutation/maliciousness_boost
|
||||
name = "Maliciousness Boost"
|
||||
desc = "Increases the maliciousness primary attribute of a pathogen."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
maliciousness_threshold = -25
|
||||
maliciousness_limit = 5
|
||||
|
||||
chance_base = 75
|
||||
chance_modifier = -5
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
if (P.symptomatic)
|
||||
return ..()
|
||||
return 0
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.maliciousness += rand(1,3)
|
||||
|
||||
datum/pathogen_mutation/benevolence_boost
|
||||
name = "Benevolence Boost"
|
||||
desc = "Reduces the maliciousness primary attribute of a pathogen."
|
||||
malicious_type = MUTATION_BENEVOLENT
|
||||
maliciousness_threshold = 25
|
||||
maliciousness_limit = -5
|
||||
|
||||
chance_base = 75
|
||||
chance_modifier = -5
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
if (P.symptomatic)
|
||||
return ..()
|
||||
return 0
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.maliciousness -= rand(1,3)
|
||||
|
||||
datum/pathogen_mutation/advance_boost
|
||||
name = "Advance Speed Boost"
|
||||
desc = "Increases the advance speed primary attribute of a pathogen."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
maliciousness_threshold = 15
|
||||
maliciousness_limit = 14
|
||||
|
||||
chance_base = 50
|
||||
chance_modifier = 5
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
if (P.symptomatic)
|
||||
return ..()
|
||||
return 0
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.advance_speed += rand(1,3)
|
||||
|
||||
datum/pathogen_mutation/advance_penalty
|
||||
name = "Advance Speed Penalty"
|
||||
desc = "Decreases the advance speed primary attribute of a pathogen."
|
||||
malicious_type = MUTATION_BENEVOLENT
|
||||
maliciousness_threshold = 20
|
||||
maliciousness_limit = 21
|
||||
|
||||
chance_base = 50
|
||||
chance_modifier = 5
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
if (P.symptomatic)
|
||||
return ..()
|
||||
return 0
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.advance_speed -= rand(1,3)
|
||||
|
||||
datum/pathogen_mutation/mutation_boost
|
||||
name = "Mutation Speed Boost"
|
||||
desc = "Increases the mutation speed primary attribute of a pathogen."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
maliciousness_threshold = -15
|
||||
maliciousness_limit = -16
|
||||
|
||||
chance_base = 50
|
||||
chance_modifier = 5
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
if (P.symptomatic)
|
||||
return ..()
|
||||
return 0
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.mutation_speed += rand(1,3)
|
||||
|
||||
datum/pathogen_mutation/mutation_penalty
|
||||
name = "Mutation Speed Penalty"
|
||||
desc = "Decreases the mutation speed primary attribute of a pathogen."
|
||||
malicious_type = MUTATION_BENEVOLENT
|
||||
maliciousness_threshold = 15
|
||||
maliciousness_limit = 16
|
||||
|
||||
chance_base = 50
|
||||
chance_modifier = 5
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return P.symptomatic && ..() && P.mutation_speed > 0
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.mutation_speed -= rand(1,3)
|
||||
if (P.mutation_speed < 0)
|
||||
P.mutation_speed = 0
|
||||
|
||||
datum/pathogen_mutation/increase_stages
|
||||
name = "More Stages"
|
||||
desc = "Increases the stages cap of a pathogen, up to 5."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
maliciousness_threshold = -25
|
||||
maliciousness_limit = -26
|
||||
|
||||
chance_base = 75
|
||||
chance_modifier = 0
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return ..() && P.stages < 5
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.stages++
|
||||
|
||||
datum/pathogen_mutation/decrease_stages
|
||||
name = "Less Stages"
|
||||
desc = "Decreases the stages cap of a pathogen, down to 3."
|
||||
malicious_type = MUTATION_BENEVOLENT
|
||||
maliciousness_threshold = 25
|
||||
maliciousness_limit = 26
|
||||
|
||||
chance_base = 75
|
||||
chance_modifier = 0
|
||||
|
||||
evolution_type = MUTATION_DEVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return ..() && P.stages > 3
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.stages--
|
||||
P.stage = min(P.stage, P.stages)
|
||||
|
||||
datum/pathogen_mutation/gain_symptom
|
||||
name = "Gain Symptom"
|
||||
desc = "Adds a new symptom to the pathogen."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
maliciousness_threshold = 15
|
||||
maliciousness_limit = 30
|
||||
|
||||
chance_base = 40
|
||||
chance_modifier = 8
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return P.symptomatic && ..()
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
var/retries = 10
|
||||
while (!P.generate_effect() && retries)
|
||||
retries--
|
||||
|
||||
datum/pathogen_mutation/gain_more_symptoms
|
||||
name = "Gain More Symptoms"
|
||||
desc = "Adds up to 3 new symptoms to the pathogen."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
maliciousness_threshold = 25
|
||||
maliciousness_limit = 70
|
||||
|
||||
chance_base = 40
|
||||
chance_modifier = 8
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return P.symptomatic && ..()
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
var/retries = 10
|
||||
for (var/i = 1, i <= rand(1,3), i++)
|
||||
while (!P.generate_effect() && retries)
|
||||
retries--
|
||||
|
||||
datum/pathogen_mutation/gain_strong_symptom
|
||||
name = "Gain Strong Symptom"
|
||||
desc = "Adds a new strong symptom to the pathogen."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
maliciousness_threshold = 65
|
||||
maliciousness_limit = 150
|
||||
|
||||
chance_base = 20
|
||||
chance_modifier = 8
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return P.symptomatic && ..()
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
var/retries = 10
|
||||
while (!P.generate_strong_effect() && retries)
|
||||
retries--
|
||||
|
||||
datum/pathogen_mutation/gain_more_strong_symptoms
|
||||
name = "Gain More Strong Symptoms"
|
||||
desc = "Adds up to 3 new strong symptoms to the pathogen."
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
maliciousness_threshold = 125
|
||||
maliciousness_limit = 100
|
||||
|
||||
chance_base = 10
|
||||
chance_modifier = 1
|
||||
|
||||
evolution_type = MUTATION_EVOLUTION
|
||||
mutativeness_threshold = 0
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return P.symptomatic && ..()
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
var/retries = 10
|
||||
for (var/i = 1, i <= rand(1,3), i++)
|
||||
while (!P.generate_strong_effect() && retries)
|
||||
retries--
|
||||
|
||||
datum/pathogen_mutation/lose_symptom
|
||||
name = "Lose Symptom"
|
||||
desc = "Removes a symptom from the pathogen."
|
||||
malicious_type = MUTATION_BENEVOLENT
|
||||
maliciousness_threshold = 50
|
||||
maliciousness_limit = 51
|
||||
|
||||
chance_base = 40
|
||||
chance_modifier = 8
|
||||
|
||||
evolution_type = MUTATION_DEVOLUTION
|
||||
mutativeness_threshold = 25
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
return P.symptomatic && ..() && P.effects.len
|
||||
|
||||
mutate(var/datum/pathogen/P)
|
||||
P.remove_symptom(pick(P.effects))
|
||||
|
||||
/*datum/pathogen_mutation/become_alternative
|
||||
name = "Become Alternative"
|
||||
desc = "A symptom of the pathogen may interchange itself with a more serious, or a milder alternative."
|
||||
|
||||
malicious_type = MUTATION_MALICIOUS
|
||||
session_maximum = 3
|
||||
|
||||
may_occur(var/datum/pathogen/P)
|
||||
if (!P.symptomatic || P.maliciousness == 0 || P.mutativeness < 5)
|
||||
return 0
|
||||
else
|
||||
for (var/datum/pathogeneffects/E in P.effects)
|
||||
if (P.maliciousness > 0)
|
||||
if (E.serious_alternatives.len)*/
|
||||
@@ -0,0 +1,319 @@
|
||||
/**
|
||||
* Pathogen suppressants
|
||||
*
|
||||
* A well identifiable trait of each pathogen which inhibits its growth. The method of identification is through colour.
|
||||
* Suppression cannot completely cure a pathogen, however, its destructive potential may be severely limited by suppression.
|
||||
*
|
||||
* Suppressants may react to events the same way symptoms can - as suppressants are instantiated per pathogen, they may have their
|
||||
* own internal state without breaking anything.
|
||||
*
|
||||
* Suppressants also play a large role in the synthesis of cure for all default microbodies - each suppressant indicates a
|
||||
* list of reagents which may be used for cure synthesis. Curing therefore requires at least some analysis of the pathogen.
|
||||
*/
|
||||
|
||||
/datum/suppressant
|
||||
var/name = "Suppressant"
|
||||
var/color = "transparent"
|
||||
var/desc = "The pathogen is not suppressed by any external effects."
|
||||
var/therapy = "unknown"
|
||||
|
||||
// A list of reagent IDs which may be used for cure synthesis with this suppressant.
|
||||
var/list/cure_synthesis = list()
|
||||
|
||||
// Override this to define when your suppression method should act.
|
||||
// Returns the new value for suppressed which is ONLY considered if suppressed is 0.
|
||||
// Is not called if suppressed is -1. A secondary resistance may overpower a primary weakness.
|
||||
proc/suppress_act(var/datum/pathogen/P)
|
||||
return
|
||||
|
||||
proc/ongrab(var/mob/target as mob, var/datum/pathogen/P)
|
||||
return
|
||||
proc/onpunched(var/mob/origin as mob, zone, var/datum/pathogen/P)
|
||||
proc/onpunch(var/mob/target as mob, zone, var/datum/pathogen/P )
|
||||
proc/ondisarm(var/mob/target as mob, isPushDown, var/datum/pathogen/P)
|
||||
proc/onshocked(var/datum/shockparam/param, var/datum/pathogen/P)
|
||||
proc/onsay(message, var/datum/pathogen/P)
|
||||
proc/onadd(var/datum/pathogen/P)
|
||||
proc/onemote(var/mob/target, message, var/datum/pathogen/P)
|
||||
|
||||
// While doing pathogen research, the suppression method may define how the pathogen reacts to certain reagents.
|
||||
// Returns null if the pathogen does not react to the reagent.
|
||||
// Returns a string describing what happened if it does react to the reagent.
|
||||
// NOTE: Conforming with the new chemistry system, R is now a reagent ID, not a reagent instance.
|
||||
proc/react_to(var/R)
|
||||
return ""
|
||||
|
||||
proc/may_react_to()
|
||||
return ""
|
||||
|
||||
/datum/suppressant/heat
|
||||
color = "blue"
|
||||
name = "Heat"
|
||||
desc = "The pathogen is suppressed by a high body temperature."
|
||||
therapy = "thermal"
|
||||
|
||||
cure_synthesis = list("napalm", "infernite")
|
||||
|
||||
suppress_act(var/datum/pathogen/P)
|
||||
if (P.infected.bodytemperature > 310 + P.suppression_threshold)
|
||||
if (P.stage > 3 && prob(P.advance_speed * 2))
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
P.stage--
|
||||
return 1
|
||||
return 0
|
||||
|
||||
may_react_to()
|
||||
return "A peculiar gland on the pathogen suggests it may be <b style='font-size:20px;color:red'>suppressed</b> by affecting its temperature."
|
||||
|
||||
react_to(var/R)
|
||||
if (R == "napalm" || R == "infernite")
|
||||
return "The pathogens are attemping to escape from the area affected by the [R]."
|
||||
else if (R in cure_synthesis)
|
||||
return "The pathogens are moving towards the area affected by the [R]"
|
||||
else return null
|
||||
|
||||
/datum/suppressant/cold
|
||||
color = "red"
|
||||
name = "Cold"
|
||||
desc = "The pathogen is suppressed by a low body temperature."
|
||||
therapy = "thermal"
|
||||
|
||||
cure_synthesis = list("cryostylane", "cryoxadone")
|
||||
|
||||
suppress_act(var/datum/pathogen/P)
|
||||
if (P.infected.bodytemperature < 300 - P.suppression_threshold)
|
||||
if (P.stage > 3 && prob(P.advance_speed * 2))
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
P.stage--
|
||||
return 1
|
||||
return 0
|
||||
|
||||
may_react_to()
|
||||
return "A peculiar gland on the pathogen suggests it may be <b style='font-size:20px;color:red'>suppressed</b> by affecting its temperature."
|
||||
|
||||
react_to(var/R)
|
||||
if (R == "napalm" || R == "infernite")
|
||||
return "The pathogens are moving towards the area affected by the [R]"
|
||||
else if (R in cure_synthesis)
|
||||
return "The pathogens are attemping to escape from the area affected by the [R]."
|
||||
else return null
|
||||
|
||||
/datum/suppressant/sleeping
|
||||
color = "green"
|
||||
name = "Sedative"
|
||||
desc = "The pathogen is suppressed by sleeping."
|
||||
therapy = "sedative"
|
||||
|
||||
suppress_act(var/datum/pathogen/P)
|
||||
if (P.infected.sleeping)
|
||||
P.symptom_data["suppressant"]++
|
||||
var/slept = P.symptom_data["suppressant"]
|
||||
if (slept > P.suppression_threshold)
|
||||
if (P.stage > 3 && prob(P.advance_speed * 4))
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
P.stage--
|
||||
P.symptom_data["suppressant"] = 0
|
||||
return 1
|
||||
else
|
||||
P.symptom_data["suppressant"] = 0
|
||||
return 0
|
||||
|
||||
cure_synthesis = list("morphine", "sonambutril")
|
||||
|
||||
onadd(var/datum/pathogen/P)
|
||||
P.symptom_data["suppressant"] = 0
|
||||
|
||||
may_react_to()
|
||||
return "Membrane patterns of the pathogen indicate it might be <b style='font-size:20px;color:red'>suppressed</b> by a reagent affecting neural activity."
|
||||
|
||||
react_to(var/R)
|
||||
if (R in cure_synthesis)
|
||||
return "The pathogens near the sedative appear to be in stasis."
|
||||
else return null
|
||||
|
||||
/datum/suppressant/brutemeds
|
||||
color = "black"
|
||||
name = "Brute Medicine"
|
||||
desc = "The pathogen is suppressed by brute medicine."
|
||||
therapy = "medical"
|
||||
|
||||
suppress_act(var/datum/pathogen/P)
|
||||
if (P.infected.reagents.has_reagent("stypic_powder", P.suppression_threshold) || P.infected.reagents.has_reagent("synthflesh", P.suppression_threshold))
|
||||
if (P.stage > 3 && prob(P.advance_speed * 2))
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
P.stage--
|
||||
return 1
|
||||
return 0
|
||||
|
||||
cure_synthesis = list("stypic_powder", "synthflesh")
|
||||
|
||||
may_react_to()
|
||||
return "The DNA repair processes of the pathogen indicate that it might be <b style='font-size:20px;color:red'>suppressed</b> by certain kinds of medicine."
|
||||
|
||||
react_to(var/R)
|
||||
if (R in cure_synthesis)
|
||||
return "The pathogens near the [R] appear to be weakened by the brute medicine's presence."
|
||||
else return null
|
||||
|
||||
/datum/suppressant/burnmeds
|
||||
color = "cyan"
|
||||
name = "Burn Medicine"
|
||||
desc = "The pathogen is suppressed by burn medicine."
|
||||
therapy = "medical"
|
||||
|
||||
suppress_act(var/datum/pathogen/P)
|
||||
if (P.infected.reagents.has_reagent("silver_sulfadiazine", P.suppression_threshold))
|
||||
if (P.stage > 3 && prob(P.advance_speed * 2))
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
P.stage--
|
||||
return 1
|
||||
return 0
|
||||
|
||||
cure_synthesis = list("silver_sulfadiazine")
|
||||
|
||||
may_react_to()
|
||||
return "The DNA repair processes of the pathogen indicate that it might be <b style='font-size:20px;color:red'>suppressed</b> by certain kinds of medicine."
|
||||
|
||||
react_to(var/R)
|
||||
if (R in cure_synthesis)
|
||||
return "The pathogens near the [R] appear to be weakened by the burn medicine's presence."
|
||||
else return null
|
||||
|
||||
/datum/suppressant/muscle
|
||||
color = "white"
|
||||
name = "Muscle"
|
||||
desc = "The pathogen is suppressed by disrupting muscle function."
|
||||
therapy = "sedative"
|
||||
|
||||
cure_synthesis = list("haloperidol", "neurotoxin")
|
||||
|
||||
suppress_act(var/datum/pathogen/P)
|
||||
if (P.infected.reagents.has_reagent("haloperidol", P.suppression_threshold) || P.infected.reagents.has_reagent("neurotoxin", P.suppression_threshold))
|
||||
if (P.stage > 3 && prob(P.advance_speed * 2))
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
P.stage--
|
||||
return 1
|
||||
return 0
|
||||
|
||||
onshocked(var/datum/shockparam/param, var/datum/pathogen/P)
|
||||
if (param.skipsupp)
|
||||
return
|
||||
if (P.stage > 3)
|
||||
var/better = 0
|
||||
if (param.amt > 50)
|
||||
P.stage = 3
|
||||
else if (param.amt > 30)
|
||||
if (prob(P.advance_speed * 2))
|
||||
P.stage = 3
|
||||
else
|
||||
P.stage--
|
||||
else if (param.amt > 15 && prob(P.advance_speed * 2))
|
||||
P.stage--
|
||||
better = 1
|
||||
if (param.amt > 30 || better)
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
if (P.suppressed == 0)
|
||||
P.suppressed = 1
|
||||
|
||||
may_react_to()
|
||||
return "Membrane patterns of the pathogen indicate it might be <b style='font-size:20px;color:red'>suppressed</b> by a reagent affecting neural activity."
|
||||
|
||||
react_to(var/R)
|
||||
if (R == "haloperidol")
|
||||
return "The pathogens near the [R] appear to move at a slower pace."
|
||||
if (R == "neurotoxin")
|
||||
return "The pathogens near the [R] appear to be confused."
|
||||
else return null
|
||||
|
||||
/datum/suppressant/fat
|
||||
color = "orange"
|
||||
name = "Fat"
|
||||
desc = "The pathogen is suppressed by fats."
|
||||
cure_synthesis = list("bad_grease", "grease", "porktonium")
|
||||
therapy = "gastronomical"
|
||||
|
||||
suppress_act(var/datum/pathogen/P)
|
||||
if (P.infected.reagents.has_reagent("bad_grease", P.suppression_threshold) || P.infected.reagents.has_reagent("grease", P.suppression_threshold) || P.infected.reagents.has_reagent("porktonium", P.suppression_threshold))
|
||||
if (P.stage > 3 && prob(P.advance_speed * 2))
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
P.stage--
|
||||
return 1
|
||||
return 0
|
||||
|
||||
may_react_to()
|
||||
return "An observation of the metabolizing processes of the pathogen shows that it might be <b style='font-size:20px;color:red'>suppressed</b> by certain kinds of foodstuffs."
|
||||
|
||||
react_to(var/datum/reagent/R)
|
||||
if (R in cure_synthesis)
|
||||
return "The pathogens near the fatty substance appear to be significantly heavier and slower than their unaffected counterparts."
|
||||
else return null
|
||||
|
||||
/datum/suppressant/chickensoup
|
||||
color = "pink"
|
||||
name = "Chicken Soup"
|
||||
desc = "The pathogen is suppressed by a nice bowl of old fashioned chicken soup."
|
||||
therapy = "gastronomical"
|
||||
|
||||
cure_synthesis = list("chickensoup")
|
||||
|
||||
suppress_act(var/datum/pathogen/P)
|
||||
if (P.infected.reagents.has_reagent("chickensoup", P.suppression_threshold))
|
||||
if (P.stage > 3 && prob(P.advance_speed * 2))
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
P.stage--
|
||||
return 1
|
||||
return 0
|
||||
|
||||
may_react_to()
|
||||
return "An observation of the metabolizing processes of the pathogen shows that it might be <b style='font-size:20px;color:red'>suppressed</b> by certain kinds of foodstuffs."
|
||||
|
||||
react_to(var/datum/reagent/R)
|
||||
if (R == "chickensoup")
|
||||
return "The pathogens near the chicken soup appear to be having a great meal and are ignorant of their surroundings."
|
||||
|
||||
/datum/suppressant/radiation
|
||||
color = "viridian"
|
||||
name = "Radiation"
|
||||
desc = "The pathogen is suppressed by radiation."
|
||||
therapy = "radioactive"
|
||||
|
||||
cure_synthesis = list("radium", "polonium", "uranium")
|
||||
|
||||
suppress_act(var/datum/pathogen/P)
|
||||
if (P.infected.reagents.has_reagent("radium", P.suppression_threshold * 2) || P.infected.reagents.has_reagent("polonium", P.suppression_threshold) || P.infected.reagents.has_reagent("uranium", P.suppression_threshold * 10) || P.infected.get_radiation() > P.suppression_threshold * 0.1)
|
||||
if (P.stage > 3 && prob(P.advance_speed * 2))
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
P.stage--
|
||||
return 1
|
||||
return 0
|
||||
|
||||
may_react_to()
|
||||
return "The chemical structure of the pathogen's membrane indicates it may be <b style='font-size:20px;color:red'>suppressed</b> by either gamma rays or mutagenic substances."
|
||||
|
||||
react_to(var/datum/reagent/R)
|
||||
if (R in cure_synthesis)
|
||||
return "The radiation emitted by the [R] is severely damaging the inner elements of the pathogen."
|
||||
|
||||
/datum/suppressant/mutagen
|
||||
color = "olive drab"
|
||||
name = "Mutagen"
|
||||
desc = "The pathogen is suppressed by mutagenic substances."
|
||||
therapy = "radioactive"
|
||||
|
||||
cure_synthesis = list("mutagen", "dna_mutagen")
|
||||
|
||||
suppress_act(var/datum/pathogen/P)
|
||||
if (P.infected.reagents.has_reagent("mutagen", P.suppression_threshold) || P.infected.reagents.has_reagent("dna_mutagen", P.suppression_threshold))
|
||||
if (P.stage > 3 && prob(P.advance_speed * 2))
|
||||
P.infected.show_message("<span style=\"color:blue\">You feel better.</span>")
|
||||
P.stage--
|
||||
return 1
|
||||
return 0
|
||||
|
||||
may_react_to()
|
||||
return "The chemical structure of the pathogen's membrane indicates it may be <b style='font-size:20px;color:red'>suppressed</b> by either gamma rays or mutagenic substances."
|
||||
|
||||
react_to(var/datum/reagent/R)
|
||||
if (R in cure_synthesis)
|
||||
return "The mutagenic substance is severely damaging the inner elements of the pathogen."
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,457 @@
|
||||
// A blood slide, used by the centrifuge.
|
||||
/obj/item/bloodslide
|
||||
name = "Blood Slide"
|
||||
icon = 'icons/obj/pathology.dmi'
|
||||
icon_state = "slide0"
|
||||
desc = "An item used by scientists and serial killers operating in the Miami area to store blood samples."
|
||||
|
||||
var/datum/reagent/blood/blood = null
|
||||
|
||||
flags = TABLEPASS | CONDUCT | FPRINT | NOSPLASH
|
||||
|
||||
New()
|
||||
..()
|
||||
var/datum/reagents/R = new /datum/reagents(5)
|
||||
src.reagents = R
|
||||
|
||||
attackby(obj/item/I as obj, mob/user as mob)
|
||||
return
|
||||
|
||||
on_reagent_change()
|
||||
reagents.maximum_volume = reagents.total_volume // This should make the blood slide... permanent.
|
||||
if (reagents.has_reagent("blood") || reagents.has_reagent("bloodc"))
|
||||
icon_state = "slide1"
|
||||
desc = "The blood slide contains a drop of blood."
|
||||
if (reagents.has_reagent("blood"))
|
||||
blood = reagents.get_reagent("blood")
|
||||
else if (reagents.has_reagent("bloodc"))
|
||||
blood = reagents.get_reagent("bloodc")
|
||||
if (blood == null)
|
||||
boutput(usr, "<span style=\"color:red\">Blood slides are not working. This is an error message, please page 1-800-555-MARQUESAS.</span>")
|
||||
return
|
||||
else
|
||||
desc = "This blood slide is contaminated and useless."
|
||||
|
||||
/obj/item/reagent_containers/glass/petridish
|
||||
name = "Petri Dish"
|
||||
icon = 'icons/obj/pathology.dmi'
|
||||
icon_state = "petri0"
|
||||
desc = "A dish tailored hold pathogen cultures."
|
||||
var/stage = 0
|
||||
|
||||
var/dirty = 0
|
||||
var/dirty_reason = ""
|
||||
var/datum/reagent/medium = null
|
||||
var/list/nutrition = list()
|
||||
|
||||
var/ctime = 8
|
||||
var/starving = 5
|
||||
rc_flags = 0
|
||||
|
||||
New()
|
||||
var/datum/reagents/R = new/datum/reagents(40)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
// Integration notes: stable mutagen ID.
|
||||
for (var/nutrient in pathogen_controller.nutrients)
|
||||
nutrition += nutrient
|
||||
nutrition[nutrient] = 0
|
||||
|
||||
examine()
|
||||
if (src.dirty || src.dirty_reason)
|
||||
..()
|
||||
boutput(usr, "<span style=\"color:red\">The petri dish appears to be incapable of growing any pathogen, and must be cleaned.</span>")
|
||||
return
|
||||
boutput(usr, "This is [src]")
|
||||
if (src.reagents.reagent_list["pathogen"])
|
||||
var/datum/reagent/blood/pathogen/P = src.reagents.reagent_list["pathogen"]
|
||||
boutput(usr, "<span style=\"color:blue\">It contains [P.volume] units of harvestable pathogen.</span>")
|
||||
if (src.medium)
|
||||
boutput(usr, "<span style=\"color:blue\">The petri dish is coated with [src.medium.name].</span>")
|
||||
boutput(usr, "Nutrients in the dish:")
|
||||
var/count = 0
|
||||
for (var/N in nutrition)
|
||||
if (nutrition[N])
|
||||
if (nutrition[N] != 1)
|
||||
boutput(usr, "<span style=\"color:blue\">[nutrition[N]] units of [N]</span>")
|
||||
else
|
||||
boutput(usr, "<span style=\"color:blue\">[nutrition[N]] unit of [N]</span>")
|
||||
count++
|
||||
if (!count)
|
||||
boutput(usr, "<span style=\"color:blue\">None.</span>")
|
||||
|
||||
afterattack(obj/target, mob/user , flag)
|
||||
if (istype(target, /obj/machinery/microscope))
|
||||
return
|
||||
var/amount = src.reagents.total_volume
|
||||
..(target, user, flag)
|
||||
if (amount && !src.reagents.total_volume)
|
||||
processing_items.Remove(src)
|
||||
for (var/N in nutrition)
|
||||
nutrition[N] = 0
|
||||
reagents.clear_reagents()
|
||||
if (src.medium)
|
||||
del src.medium
|
||||
src.medium = null
|
||||
ctime = 8
|
||||
starving = 5
|
||||
|
||||
process()
|
||||
if (dirty && (src in processing_items))
|
||||
processing_items -= src
|
||||
ctime--
|
||||
if (!src.reagents.reagent_list["pathogen"] )
|
||||
set_dirty("All viable pathogen has been harvested from the petri dish.")
|
||||
else
|
||||
var/datum/reagent/blood/pathogen/P = src.reagents.reagent_list["pathogen"]
|
||||
var/uid = P.pathogens[1]
|
||||
var/datum/pathogen/PT = P.pathogens[uid]
|
||||
if (medium.id != PT.body_type.growth_medium)
|
||||
set_dirty("The pathogen is unable to cultivate on the growth medium.")
|
||||
if (ctime <= 0)
|
||||
ctime = 8
|
||||
var/datum/reagent/blood/pathogen/P = src.reagents.reagent_list["pathogen"]
|
||||
var/uid = P.pathogens[1]
|
||||
var/datum/pathogen/PT = P.pathogens[uid]
|
||||
// Integration notes etc. stablemutagen reagent ID
|
||||
var/starvation = 0
|
||||
for (var/N in PT.body_type.nutrients)
|
||||
if (src.nutrition[N] < PT.body_type.amount * P.volume)
|
||||
starvation = 1
|
||||
src.nutrition[N] = 0
|
||||
else
|
||||
starving = 5
|
||||
src.nutrition[N] -= PT.body_type.amount * P.volume
|
||||
if (starvation && starving > 0)
|
||||
starving--
|
||||
if (starving == 5)
|
||||
if (stage < 4)
|
||||
stage++
|
||||
update_dish_icon()
|
||||
else
|
||||
P.volume = min(P.volume + 5, 30)
|
||||
src.reagents.update_total()
|
||||
else if (starving == 0)
|
||||
if (stage > 1)
|
||||
stage--
|
||||
update_dish_icon()
|
||||
else
|
||||
P.volume = max(P.volume - 5, 0)
|
||||
if (P.volume == 0)
|
||||
src.reagents.del_reagent("pathogen")
|
||||
src.reagents.update_total()
|
||||
set_dirty("The pathogen in the petri dish starved to death.")
|
||||
|
||||
on_reagent_change()
|
||||
if (reagents.total_volume < 0.5)
|
||||
return
|
||||
if (dirty)
|
||||
return
|
||||
|
||||
// Cultivation is already in progress in this dish. Depending on what reagent(s) were introduced, the process
|
||||
// halts, or reverses entirely.
|
||||
if (stage > 0)
|
||||
// At this stage, only the pathogen should be in the reagents list.
|
||||
for (var/R in src.reagents.reagent_list)
|
||||
var/datum/reagent/RE = src.reagents.reagent_list[R]
|
||||
// Sanity check the pathogen. Only a single type of pathogen can be cultivated in a petri dish.
|
||||
// Multiple types of reagents will immediately make the dish dirty.
|
||||
if (R == "pathogen")
|
||||
var/datum/reagent/blood/pathogen/P = src.reagents.reagent_list["pathogen"]
|
||||
if (P.pathogens.len > 1)
|
||||
// Too many pathogens. This culture is dead.
|
||||
set_dirty("The presence of multiple pathogens makes them unable to grow.")
|
||||
else if (R in pathogen_controller.media)
|
||||
if (R == medium.id)
|
||||
if (RE.pathogen_nutrition)
|
||||
for (var/N in RE.pathogen_nutrition)
|
||||
if (N in nutrition)
|
||||
nutrition[N] += RE.volume / RE.pathogen_nutrition.len
|
||||
else
|
||||
nutrition[N] = RE.volume / RE.pathogen_nutrition.len
|
||||
src.reagents.reagent_list -= R
|
||||
src.reagents.update_total()
|
||||
else
|
||||
// Malnutrition, a medium that normally rejects the grown pathogen type has been introduced.
|
||||
set_dirty("A growth medium incompatible with the pathogen is killing the culture.")
|
||||
else if (RE.pathogen_nutrition)
|
||||
for (var/N in RE.pathogen_nutrition)
|
||||
if (N in nutrition)
|
||||
nutrition[N] += RE.volume / RE.pathogen_nutrition.len
|
||||
else
|
||||
nutrition[N] = RE.volume / RE.pathogen_nutrition.len
|
||||
src.reagents.reagent_list -= R
|
||||
src.reagents.update_total()
|
||||
else
|
||||
// Foreign chemical, murdering the culture.
|
||||
set_dirty("The pathogen culture is unable to cultivate in the environment due to foreign chemicals.")
|
||||
else
|
||||
if (src.reagents.reagent_list.len == 1 && src.reagents.reagent_list[1] == "pathogen")
|
||||
return
|
||||
for (var/R in src.reagents.reagent_list)
|
||||
var/datum/reagent/RE = src.reagents.reagent_list[R]
|
||||
if (R == "pathogen")
|
||||
if (src.medium)
|
||||
if (!(src in processing_items))
|
||||
processing_items.Add(src)
|
||||
else if (R in pathogen_controller.media)
|
||||
if (src.medium && src.medium.id != R)
|
||||
set_dirty("There are multiple, incompatible growth media in the petri dish.")
|
||||
else if (!src.medium)
|
||||
src.medium = src.reagents.reagent_list[R]
|
||||
if (RE.pathogen_nutrition)
|
||||
for (var/N in RE.pathogen_nutrition)
|
||||
if (N in nutrition)
|
||||
nutrition[N] += RE.volume / RE.pathogen_nutrition.len
|
||||
else
|
||||
nutrition[N] = RE.volume / RE.pathogen_nutrition.len
|
||||
src.reagents.reagent_list -= R
|
||||
src.reagents.update_total()
|
||||
if (src.reagents.has_reagent("pathogen"))
|
||||
if (!(src in processing_items))
|
||||
processing_items.Add(src)
|
||||
else
|
||||
if (RE.pathogen_nutrition)
|
||||
for (var/N in RE.pathogen_nutrition)
|
||||
if (N in nutrition)
|
||||
nutrition[N] += RE.volume / RE.pathogen_nutrition.len
|
||||
else
|
||||
nutrition[N] = RE.volume / RE.pathogen_nutrition.len
|
||||
src.reagents.reagent_list -= R
|
||||
src.reagents.update_total()
|
||||
else if (RE.pathogen_nutrition)
|
||||
for (var/N in RE.pathogen_nutrition)
|
||||
if (N in nutrition)
|
||||
nutrition[N] += RE.volume / RE.pathogen_nutrition.len
|
||||
else
|
||||
nutrition[N] = RE.volume / RE.pathogen_nutrition.len
|
||||
src.reagents.reagent_list -= R
|
||||
src.reagents.update_total()
|
||||
else
|
||||
set_dirty("Foreign chemicals in the petri dish.")
|
||||
|
||||
proc/update_dish_icon()
|
||||
if (stage == 0)
|
||||
if (src.reagents.total_volume > 0)
|
||||
icon_state = "petri1"
|
||||
else
|
||||
icon_state = "petri0"
|
||||
else
|
||||
icon_state = "petri[stage]"
|
||||
|
||||
proc/set_dirty(var/reason)
|
||||
processing_items.Remove(src)
|
||||
dirty = 1
|
||||
stage = 0
|
||||
ctime = 8
|
||||
starving = 5
|
||||
dirty_reason = reason
|
||||
update_dish_icon()
|
||||
|
||||
flags = TABLEPASS | CONDUCT | FPRINT | OPENCONTAINER
|
||||
|
||||
|
||||
/obj/item/reagent_containers/glass/vial
|
||||
name = "vial"
|
||||
desc = "A vial. Can hold up to 5 units."
|
||||
icon = 'icons/obj/pathology.dmi'
|
||||
icon_state = "vial0"
|
||||
item_state = "vial"
|
||||
rc_flags = RC_FULLNESS | RC_VISIBLE | RC_SPECTRO
|
||||
|
||||
on_reagent_change()
|
||||
..()
|
||||
if (reagents.total_volume < 0.05)
|
||||
icon_state = "vial0"
|
||||
else
|
||||
icon_state = "vial1"
|
||||
|
||||
New()
|
||||
var/datum/reagents/R = new /datum/reagents(5)
|
||||
R.my_atom = src
|
||||
src.reagents = R
|
||||
..()
|
||||
|
||||
/obj/item/reagent_containers/glass/vial/prepared
|
||||
name = "Totally Safe(tm) pathogen sample"
|
||||
desc = "A vial. Can hold up to 5 units."
|
||||
icon = 'icons/obj/pathology.dmi'
|
||||
icon_state = "vial0"
|
||||
item_state = "vial"
|
||||
|
||||
New()
|
||||
..()
|
||||
spawn(20)
|
||||
var/datum/pathogen/P = unpool(/datum/pathogen)
|
||||
P.create_weak()
|
||||
var/datum/reagents/RE = src.reagents
|
||||
RE.add_reagent("pathogen", 5)
|
||||
var/datum/reagent/blood/pathogen/R = RE.get_reagent("pathogen")
|
||||
R.pathogens[P.pathogen_uid] = P
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/parasiticmedium
|
||||
name = "Beaker of Parasitic Medium"
|
||||
desc = "A mix of blood and flesh; fertile ground for some microbes."
|
||||
|
||||
icon_state = "beaker1"
|
||||
|
||||
New()
|
||||
..()
|
||||
src.reagents.add_reagent("parasiticmedium", 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/egg
|
||||
name = "Beaker of Eggs"
|
||||
desc = "Eggs; fertile ground for some microbes."
|
||||
|
||||
icon_state = "beaker1"
|
||||
|
||||
New()
|
||||
..()
|
||||
src.reagents.add_reagent("egg", 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/stablemut
|
||||
name = "Beaker of Stable Mutagen"
|
||||
desc = "Stable Mutagen; fertile ground for some microbes."
|
||||
|
||||
icon_state = "beaker1"
|
||||
|
||||
New()
|
||||
..()
|
||||
src.reagents.add_reagent("dna_mutagen", 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/bacterial
|
||||
name = "Beaker of Bacterial Growth Medium"
|
||||
desc = "Bacterial Growth Medium; fertile ground for some microbes."
|
||||
|
||||
icon_state = "beaker1"
|
||||
|
||||
New()
|
||||
..()
|
||||
src.reagents.add_reagent("bacterialmedium", 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/fungal
|
||||
name = "Beaker of Fungal Growth Medium"
|
||||
desc = "Fungal Growth Medium; fertile ground for some microbes."
|
||||
|
||||
icon_state = "beaker1"
|
||||
|
||||
New()
|
||||
..()
|
||||
src.reagents.add_reagent("fungalmedium", 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/antiviral
|
||||
name = "Beaker of Antiviral Agent"
|
||||
desc = "A beaker of a weak anti-viral agent."
|
||||
|
||||
icon_state = "beaker1"
|
||||
|
||||
New()
|
||||
..()
|
||||
src.reagents.add_reagent("antiviral", 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/biocides
|
||||
name = "Beaker of Biocides"
|
||||
desc = "A beaker of biocides. The label says 'do not feed to worms or mushrooms'. Curious."
|
||||
|
||||
icon_state = "beaker1"
|
||||
|
||||
New()
|
||||
..()
|
||||
src.reagents.add_reagent("biocide", 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/spaceacillin
|
||||
name = "Beaker of Spaceacillin"
|
||||
desc = "It's penicillin in space."
|
||||
|
||||
icon_state = "beaker1"
|
||||
|
||||
New()
|
||||
..()
|
||||
src.reagents.add_reagent("spaceacillin", 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/inhibitor
|
||||
name = "Beaker of Inhibition Agent"
|
||||
desc = "It's green, that's for sure."
|
||||
|
||||
icon_state = "beaker1"
|
||||
|
||||
New()
|
||||
..()
|
||||
src.reagents.add_reagent("inhibitor", 50)
|
||||
|
||||
/obj/item/serum_injector
|
||||
name = "Pathological Injector"
|
||||
desc = "A specialized injector for injecting patients with serums and vaccines."
|
||||
icon = 'icons/obj/pathology.dmi'
|
||||
icon_state = "serum"
|
||||
var/datum/pathogen/pathogen = null
|
||||
var/used = 1
|
||||
var/is_cure = 0
|
||||
var/is_vaccine = 0
|
||||
|
||||
New(Location, var/datum/pathogen/P, cure, vaccine)
|
||||
if (P && istype(P))
|
||||
src.name = "[src.name] (strain [P.name_base])"
|
||||
icon_state = "serum"
|
||||
src.pathogen = P
|
||||
src.is_cure = cure
|
||||
src.is_vaccine = vaccine
|
||||
used = 0
|
||||
else
|
||||
src.name = "empty [src.name]"
|
||||
icon_state = "serum0"
|
||||
used = 1
|
||||
..()
|
||||
|
||||
attack_self()
|
||||
return
|
||||
|
||||
proc/inject(var/mob/living/carbon/human/target, var/mob/user)
|
||||
if (is_cure)
|
||||
if (!is_vaccine)
|
||||
logTheThing("pathology", user, target, "injects %target% with the cure for [src.pathogen.name].")
|
||||
target.remission(src.pathogen)
|
||||
else
|
||||
logTheThing("pathology", user, target, "injects %target% with a vaccine for [src.pathogen.name].")
|
||||
target.immunity(src.pathogen)
|
||||
else
|
||||
if (target.infected(src.pathogen))
|
||||
logTheThing("pathology", user, target, "injects %target% with pathogen [src.pathogen.name] from a bad cure injector and infects them.")
|
||||
else
|
||||
logTheThing("pathology", user, target, "injects %target% with pathogen [src.pathogen.name] from a bad cure injector but they were unaffected.")
|
||||
src.pathogen = null
|
||||
used = 1
|
||||
|
||||
attack(mob/M as mob, mob/user as mob, def_zone)
|
||||
if (used)
|
||||
boutput(user, "<span style=\"color:red\">The [src.name] is empty.</span>")
|
||||
return
|
||||
if (istype(M, /mob/living/carbon/human))
|
||||
if (M != user)
|
||||
for (var/mob/V in viewers(M))
|
||||
boutput(V, "<span style=\"color:red\"><b>[user] is trying to inject [M] with the [src.name]!</b></span>")
|
||||
var/ML = M.loc
|
||||
var/UL = user.loc
|
||||
spawn (30)
|
||||
if (used)
|
||||
return
|
||||
if (user.equipped() == src && M.loc == ML && user.loc == UL)
|
||||
used = 1
|
||||
for (var/mob/V in viewers(M))
|
||||
boutput(V, "<span style=\"color:red\"><b>[user] is injects [M] with the [src.name]!</b></span>")
|
||||
src.name = "empty [src.name]"
|
||||
icon_state = "serum0"
|
||||
inject(M, user)
|
||||
else
|
||||
used = 1
|
||||
for (var/mob/V in viewers(M))
|
||||
boutput(V, "<span style=\"color:red\"><b>[user] injects [M] with the [src.name]!</b></span>")
|
||||
icon_state = "serum0"
|
||||
src.name = "empty [src.name]"
|
||||
inject(user, user)
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker
|
||||
afterattack(obj/target, mob/user , flag)
|
||||
if (istype(target, /obj/machinery/synthomatic))
|
||||
return
|
||||
..()
|
||||
Reference in New Issue
Block a user