mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-05-18 14:39:01 +01:00
1525 lines
59 KiB
Plaintext
1525 lines
59 KiB
Plaintext
#define COOLDOWN_MULTIPLIER 1
|
|
|
|
#define INFECT_NONE 0
|
|
#define INFECT_TOUCH 1
|
|
#define INFECT_AREA 3
|
|
#define INFECT_AREA_LARGE 5
|
|
|
|
// --SYMPTOM RARITIES--
|
|
// All symptom contains a rarity value. Use these constants to describe their rarity.
|
|
// For malevolent symptoms:
|
|
// RARITY_VERY_COMMON: The symptoms are barely noticable. Should not affect gameplay significantly or infect in a large area.
|
|
// RARITY_COMMON: The symptoms are noticeable, and may cause occasional inconveniences. May infect in a large area (instead).
|
|
// RARITY_UNCOMMON: The symptoms may do occasional damage or longer stuns.
|
|
// RARITY_RARE: The symptoms have a ramp in stages from relatively mundane to rather deadly.
|
|
// RARITY_VERY_RARE: You are fucked.
|
|
// For benevolent symptoms:
|
|
// RARITY_VERY_COMMON: As for malevolents, except in the positive direction obviously.
|
|
// RARITY_COMMON: The symptom may heal slightly or give an insignificant boost to any statistic.
|
|
// RARITY_UNCOMMON: Commonly symptoms which may give you an upper hand in a fight.
|
|
// RARITY_RARE: Power-healing and heavy offense/defense symptoms. May contain downsides.
|
|
// RARITY_VERY_RARE: God complex with actual godlike powers, traitor items infused in body. Should contain flipsides.
|
|
// And for all:
|
|
// RARITY_ABSTRACT: Used strictly for categorization. ABSTRACT symptoms will never appear.
|
|
// ie. if lingual is a symptom category with multiple subsymptoms (for easy mutex), it should be abstract.
|
|
#define RARITY_VERY_COMMON 10
|
|
#define RARITY_COMMON 5
|
|
#define RARITY_UNCOMMON 3
|
|
#define RARITY_RARE 2
|
|
#define RARITY_VERY_RARE 1
|
|
#define RARITY_ABSTRACT 0
|
|
|
|
datum/pathogen_cdc
|
|
var/uid = null
|
|
var/patient_zero = null
|
|
var/patient_zero_kname = ""
|
|
var/creation_time = null
|
|
var/microbody_type = null
|
|
|
|
var/list/infections = list()
|
|
var/list/mutations = list()
|
|
|
|
New(var/pathogen_uid)
|
|
creation_time = world.time / 600
|
|
src.uid = pathogen_uid
|
|
|
|
datum/controller/pathogen
|
|
var/list/next_mutation = new/list()
|
|
var/list/pathogen_trees = new/list()
|
|
var/next_uid = 1
|
|
|
|
var/list/UID_to_symptom
|
|
var/list/symptom_to_UID
|
|
var/list/UID_to_suppressant
|
|
var/list/suppressant_to_UID
|
|
var/list/microbody_to_UID
|
|
var/list/UID_to_carrier
|
|
var/list/carrier_to_UID
|
|
|
|
var/list/path_to_symptom = list()
|
|
var/list/path_to_microbody = list()
|
|
var/list/path_to_suppressant = list()
|
|
var/list/path_to_mutation = list()
|
|
var/list/disabled_mutations = list()
|
|
|
|
var/list/pathogen_affected_reagents = list("blood", "pathogen", "bloodc")
|
|
|
|
var/list/microbody_choices = list()
|
|
var/choicemax = 0
|
|
|
|
var/list/l_vc
|
|
var/list/l_c
|
|
var/list/l_u
|
|
var/list/l_r
|
|
var/list/l_vr
|
|
|
|
var/list/lnums = list()
|
|
var/list/lalph = list()
|
|
|
|
var/list/nutrients = list()
|
|
var/list/media = list()
|
|
var/list/cure_bases = list()
|
|
|
|
proc/get_microbody(var/strength)
|
|
var/datum/microbody/M
|
|
var/finished = 0
|
|
var/tried = 0
|
|
while (!finished)
|
|
var/choice = rand(1, choicemax)
|
|
for (var/datum/choice/C in microbody_choices)
|
|
if (C.min <= choice && choice <= C.max)
|
|
M = C.target
|
|
if (M.strength <= strength)
|
|
finished = 1
|
|
else
|
|
tried++
|
|
if (tried > 10)
|
|
return M
|
|
return M
|
|
|
|
proc/mob_infected(var/datum/pathogen/P, var/mob/living/carbon/human/H)
|
|
var/datum/pathogen_cdc/CDC = src.pathogen_trees[P.name_base]
|
|
if (!CDC)
|
|
return
|
|
if (!CDC.patient_zero)
|
|
CDC.patient_zero = H
|
|
CDC.patient_zero_kname = "[H]"
|
|
if (!(P.name in CDC.mutations))
|
|
CDC.mutations += P.name
|
|
var/datum/pathogen/template = unpool(/datum/pathogen)
|
|
template.setup(0, P, 0)
|
|
CDC.mutations[P.name] = template
|
|
if (!(H in CDC.infections))
|
|
CDC.infections += H
|
|
CDC.infections[H] = P.name
|
|
|
|
proc/mob_cured(var/datum/pathogen/P, var/mob/living/carbon/human/H)
|
|
var/datum/pathogen_cdc/CDC = src.pathogen_trees[P.name_base]
|
|
if (!CDC)
|
|
return
|
|
if (H in CDC.infections)
|
|
CDC.infections -= H
|
|
|
|
proc/patient_zero(var/datum/pathogen_cdc/CDC, var/topic_holder)
|
|
if (CDC.patient_zero)
|
|
return replacetext(CDC.patient_zero_kname, "%holder%", "\ref[topic_holder]")
|
|
|
|
Topic(href, href_list)
|
|
var/key = usr.ckey
|
|
var/th = locate(href_list["topic_holder"])
|
|
switch(href_list["action"])
|
|
if ("setstate")
|
|
cdc_state[key] = text2num(href_list["state"])
|
|
if ("strain_cure")
|
|
var/strain = href_list["strain"]
|
|
var/datum/pathogen_cdc/CDC = pathogen_trees[strain]
|
|
var/count = 0
|
|
for (var/mob/living/carbon/human/H in world)
|
|
if (CDC.uid in H.pathogens)
|
|
H.cured(H.pathogens[CDC.uid])
|
|
count++
|
|
message_admins("[key_name(usr)] cured [count] humans from pathogen strain [strain].")
|
|
if ("strain_details")
|
|
cdc_state[key] = href_list["strain"]
|
|
if ("pathogen_creator")
|
|
var/datum/pathogen/P = src.cdc_creator[usr.ckey]
|
|
switch (href_list["do"])
|
|
if ("reset")
|
|
src.gen_empty(usr.ckey)
|
|
|
|
if ("body_type")
|
|
var/list/types = list()
|
|
for (var/btpath in src.path_to_microbody)
|
|
var/datum/microbody/MB = src.path_to_microbody[btpath]
|
|
types += MB.name
|
|
types[MB.name] = MB
|
|
var/chosen = input("Which microbody?", "Microbody", types[1]) in types
|
|
P.body_type = types[chosen]
|
|
P.maliciousness = rand(-2, 6)
|
|
P.mutation_speed = rand(-2, 10)
|
|
P.suppression_threshold = rand(1,3) * P.maliciousness
|
|
P.suppression_threshold += rand(-5, 10)
|
|
P.advance_speed = rand(-2, 7)
|
|
P.mutativeness = P.body_type.mutativeness
|
|
P.symptomatic = 1
|
|
P.generation = 1
|
|
P.maliciousness *= P.body_type.maliciousness_multiplier
|
|
P.mutation_speed *= P.body_type.mutation_speed_multiplier
|
|
P.stages = P.body_type.stages
|
|
|
|
if ("suppressant")
|
|
var/list/types = list()
|
|
for (var/spath in src.path_to_suppressant)
|
|
var/datum/suppressant/S = src.path_to_suppressant[spath]
|
|
types += S.name
|
|
types[S.name] = S
|
|
var/chosen = input("Which suppresant?", "Suppressant", types[1]) in types
|
|
P.suppressant = types[chosen]
|
|
P.desc = "[P.suppressant.color] dodecahedrical [P.body_type.plural]"
|
|
|
|
if ("add")
|
|
var/list/types = list()
|
|
for (var/efpath in src.path_to_symptom)
|
|
var/datum/pathogeneffects/EF = src.path_to_symptom[efpath]
|
|
types += EF.name
|
|
types[EF.name] = EF
|
|
var/chosen = input("Which symptom?", "Add new symptom", types[1]) in types
|
|
if (!(types[chosen] in P.effects))
|
|
P.effects += types[chosen]
|
|
var/datum/pathogeneffects/EF = types[chosen]
|
|
EF.onadd(P)
|
|
|
|
if ("remove")
|
|
var/datum/pathogeneffects/EF = locate(href_list["which"])
|
|
if (EF in P.effects)
|
|
P.effects -= EF
|
|
|
|
if ("advance_speed")
|
|
P.advance_speed = input("New advance speed?", "Advance speed", P.advance_speed) as num
|
|
if ("mutation_speed")
|
|
P.mutation_speed = input("New mutation speed?", "mutation speed", P.mutation_speed) as num
|
|
if ("maliciousness")
|
|
P.maliciousness = input("New maliciousness?", "Maliciousness", P.maliciousness) as num
|
|
if ("mutativeness")
|
|
P.mutativeness = input("New mutativeness?", "Mutativeness", P.mutativeness) as num
|
|
if ("suppression_threshold")
|
|
P.suppression_threshold = input("New suppression threshold?", "Suppression threshold", P.suppression_threshold) as num
|
|
if ("symptomatic")
|
|
P.symptomatic = !P.symptomatic
|
|
if ("stages")
|
|
var/value = P.stages
|
|
var/newval = input("New stages (3-5)?", "Stages", value) as num
|
|
if (newval >= 3 && newval <= 5)
|
|
P.stages = newval
|
|
if ("create")
|
|
P.dnasample = new/datum/pathogendna(P)
|
|
P.pathogen_uid = "[next_uid]"
|
|
next_uid++
|
|
|
|
pathogen_trees += P.name_base
|
|
var/datum/pathogen_cdc/CDC = new /datum/pathogen_cdc(P.pathogen_uid)
|
|
pathogen_trees[P.name_base] = CDC
|
|
next_mutation[P.pathogen_uid] = P.mutation + 1
|
|
CDC.microbody_type = "[P.body_type]"
|
|
CDC.mutations += P.name
|
|
CDC.mutations[P.name] = P
|
|
|
|
message_admins("[key_name(usr)] created a new pathogen ([P]) via the creator.")
|
|
src.gen_empty(usr.ckey)
|
|
|
|
if ("strain_data")
|
|
var/datum/pathogen_cdc/CDC = locate(href_list["which"])
|
|
var/name = href_list["name"]
|
|
var/datum/pathogen/reference = CDC.mutations[name]
|
|
switch (href_list["data"])
|
|
if ("advance_speed")
|
|
var/value = reference.advance_speed
|
|
var/newval = input("New advance speed?", "Advance speed", value) as num
|
|
for (var/mob/living/carbon/human/H in CDC.infections)
|
|
if (CDC.uid in H.pathogens)
|
|
var/datum/pathogen/target = H.pathogens[CDC.uid]
|
|
if (target.name == name)
|
|
target.advance_speed = newval
|
|
reference.advance_speed = newval
|
|
message_admins("[key_name(usr)] set the advance speed on pathogen strain mutation [name] to [newval].")
|
|
if ("mutation_speed")
|
|
var/value = reference.mutation_speed
|
|
var/newval = input("New mutation speed?", "Mutation speed", value) as num
|
|
for (var/mob/living/carbon/human/H in CDC.infections)
|
|
if (CDC.uid in H.pathogens)
|
|
var/datum/pathogen/target = H.pathogens[CDC.uid]
|
|
if (target.name == name)
|
|
target.mutation_speed = newval
|
|
reference.mutation_speed = newval
|
|
message_admins("[key_name(usr)] set the mutation speed on pathogen strain mutation [name] to [newval].")
|
|
if ("maliciousness")
|
|
var/value = reference.maliciousness
|
|
var/newval = input("New maliciousness?", "Maliciousness", value) as num
|
|
for (var/mob/living/carbon/human/H in CDC.infections)
|
|
if (CDC.uid in H.pathogens)
|
|
var/datum/pathogen/target = H.pathogens[CDC.uid]
|
|
if (target.name == name)
|
|
target.maliciousness = newval
|
|
reference.maliciousness = newval
|
|
message_admins("[key_name(usr)] set the maliciousness on pathogen strain mutation [name] to [newval].")
|
|
if ("mutativeness")
|
|
var/value = reference.mutativeness
|
|
var/newval = input("New mutativeness?", "Mutativeness", value) as num
|
|
for (var/mob/living/carbon/human/H in CDC.infections)
|
|
if (CDC.uid in H.pathogens)
|
|
var/datum/pathogen/target = H.pathogens[CDC.uid]
|
|
if (target.name == name)
|
|
target.mutativeness = newval
|
|
reference.mutativeness = newval
|
|
message_admins("[key_name(usr)] set the mutativeness on pathogen strain mutation [name] to [newval].")
|
|
if ("suppression_threshold")
|
|
var/value = reference.suppression_threshold
|
|
var/newval = input("New suppression threshold?", "Suppression threshold", value) as num
|
|
for (var/mob/living/carbon/human/H in CDC.infections)
|
|
if (CDC.uid in H.pathogens)
|
|
var/datum/pathogen/target = H.pathogens[CDC.uid]
|
|
if (target.name == name)
|
|
target.suppression_threshold = newval
|
|
reference.suppression_threshold = newval
|
|
message_admins("[key_name(usr)] set the suppression threshold on pathogen strain mutation [name] to [newval].")
|
|
if ("symptomatic")
|
|
var/value = reference.symptomatic
|
|
var/newval = !value
|
|
for (var/mob/living/carbon/human/H in CDC.infections)
|
|
if (CDC.uid in H.pathogens)
|
|
var/datum/pathogen/target = H.pathogens[CDC.uid]
|
|
if (target.name == name)
|
|
target.symptomatic = newval
|
|
reference.symptomatic = newval
|
|
message_admins("[key_name(usr)] set the symptomaticity for pathogen strain mutation [name] to [newval ? "Yes" : "No"].")
|
|
if ("stages")
|
|
var/value = reference.stages
|
|
var/newval = input("New stages (3-5)?", "Stages", value) as num
|
|
if (newval >= 3 && newval <= 5)
|
|
for (var/mob/living/carbon/human/H in CDC.infections)
|
|
if (CDC.uid in H.pathogens)
|
|
var/datum/pathogen/target = H.pathogens[CDC.uid]
|
|
if (target.name == name)
|
|
target.stages = newval
|
|
reference.stages = newval
|
|
message_admins("[key_name(usr)] set the stages on pathogen strain mutation [name] to [newval].")
|
|
if ("cure")
|
|
var/count = 0
|
|
for (var/mob/living/carbon/human/H in world)
|
|
if (CDC.uid in H.pathogens)
|
|
var/datum/pathogen/P = H.pathogens[CDC.uid]
|
|
if (P.name == name)
|
|
H.cured(P)
|
|
count++
|
|
message_admins("[key_name(usr)] cured [count] humans from pathogen strain mutation [name].")
|
|
if ("infect")
|
|
var/mob/living/carbon/human/target = input("Who would you like to infect with this mutation?", "Infect") as mob in world
|
|
if (!istype(target))
|
|
boutput(usr, "<span style=\"color:red\">Cannot infect that. Must be human.</span>")
|
|
else
|
|
target.infected(reference)
|
|
message_admins("[key_name(usr)] infected [target] with [name].")
|
|
if ("spawn")
|
|
var/obj/item/reagent_containers/glass/vial/V = new /obj/item/reagent_containers/glass/vial(get_turf(usr))
|
|
var/datum/reagent/blood/pathogen/RE = new /datum/reagent/blood/pathogen()
|
|
RE.volume = 5
|
|
RE.pathogens += reference.pathogen_uid
|
|
RE.pathogens[reference.pathogen_uid] = reference
|
|
RE.holder = V.reagents
|
|
V.reagents.reagent_list += RE.id
|
|
V.reagents.reagent_list[RE.id] = RE
|
|
V.reagents.update_total()
|
|
if ("microbody_data")
|
|
var/datum/microbody/MB = locate(href_list["which"])
|
|
switch (href_list["data"])
|
|
if ("stages")
|
|
var/new_stages = input("Stage cap for [MB] microbodies? (3-5)", "Stage cap", MB.stages) as num
|
|
if (new_stages >= 3 && new_stages <= 5)
|
|
MB.stages = new_stages
|
|
message_admins("[key_name(usr)] set the initial stage cap for pathogen microbody [MB.plural] to [new_stages].")
|
|
if ("vaccinable")
|
|
MB.vaccination = !MB.vaccination
|
|
message_admins("[key_name(usr)] set the vaccinability for pathogen microbody [MB.plural] to [MB.vaccination ? "On" : "Off"].")
|
|
if ("activity")
|
|
var/stage = text2num(href_list["stage"])
|
|
var/new_act = input("New activity percentage for stage [stage] of [MB] (0-100)?", "Activity", MB.activity[stage]) as num
|
|
if (new_act >= 0 && new_act <= 100)
|
|
MB.activity[stage] = new_act
|
|
message_admins("[key_name(usr)] set the activity for pathogen microbody [MB.plural] on stage [stage] to [new_act].")
|
|
if ("mutativeness")
|
|
MB.mutativeness = input("New base mutativeness for [MB]? The higher, the more likely it is to mutate on transmission.", "Base mutativeness", MB.mutativeness) as num
|
|
message_admins("[key_name(usr)] set the initial mutativeness for pathogen microbody [MB.plural] to [MB.mutativeness].")
|
|
if ("mutation_data")
|
|
var/datum/pathogen_mutation/MUT = locate(href_list["which"])
|
|
switch (href_list["data"])
|
|
if ("info")
|
|
alert(usr, MUT.desc)
|
|
if ("session_maximum")
|
|
MUT.session_maximum = input("New session maximum for [MUT]? The higher, the more times this mutation can occur during one mutation proc call.", "Session maximum", MUT.session_maximum) as num
|
|
message_admins("[key_name(usr)] set the session maximum for pathogen mutation [MUT] to [MUT.session_maximum].")
|
|
if ("chance_base")
|
|
var/new_chn = input("New base chance of [MUT] occurrence (0-100)?", "Activity", MUT.chance_base) as num
|
|
if (new_chn >= 0 && new_chn <= 100)
|
|
MUT.chance_base = new_chn
|
|
message_admins("[key_name(usr)] set the base chance for pathogen mutation [MUT] to [new_chn].")
|
|
if ("disable")
|
|
src.path_to_mutation -= MUT.type
|
|
src.disabled_mutations += MUT.type
|
|
src.disabled_mutations[MUT.type] = MUT
|
|
message_admins("[key_name(usr)] disabled pathogen mutation [MUT].")
|
|
if ("enable")
|
|
src.disabled_mutations -= MUT.type
|
|
src.path_to_mutation += MUT.type
|
|
src.path_to_mutation[MUT.type] = MUT
|
|
message_admins("[key_name(usr)] enabled pathogen mutation [MUT].")
|
|
if ("symptom_data")
|
|
var/datum/pathogeneffects/EF = locate(href_list["which"])
|
|
switch (href_list["data"])
|
|
if ("info")
|
|
alert(usr, EF.desc)
|
|
cdc_main(th)
|
|
|
|
var/list/cdc_creator = list()
|
|
var/list/cdc_state = list()
|
|
var/static/list/states = list("strains", "symptoms", "microbodies", "suppressants", "mutations", "pathogen creator")
|
|
proc/severity_color(var/datum/pathogeneffects/EF)
|
|
if (EF.rarity == RARITY_ABSTRACT)
|
|
return "[EF]"
|
|
var/color_value = round(255 / EF.rarity)
|
|
if (istype(EF, /datum/pathogeneffects/malevolent))
|
|
return "<span style='color: rgb([color_value], 0, 0)'>[EF]</span>"
|
|
else
|
|
return "<span style='color: rgb(0, [color_value], 0)'>[EF]</span>"
|
|
|
|
proc/cdc_main(var/topic_holder)
|
|
if (!usr || !usr.client)
|
|
return
|
|
if (!usr.client.holder)
|
|
boutput(usr, "<span style=\"color:red\">Visitors of the CDC are not allowed to interact with the equipment!</span>")
|
|
return
|
|
if (usr.client.holder.level < LEVEL_PA)
|
|
boutput(usr, "<span style=\"color:red\">I'm sorry, you require a security clearance of Primary Researcher to go in there. Protocol and all. You know.</span>")
|
|
return
|
|
var/state = 1
|
|
if (usr.ckey in cdc_state)
|
|
state = cdc_state[usr.ckey]
|
|
else
|
|
cdc_state += usr.ckey
|
|
cdc_state[usr.ckey] = 1
|
|
var/stylesheet = {"<style>
|
|
.pathology-table { width: 100%; text-align: left; border-spacing: 0; border-collapse: collapse; }
|
|
.pathology-table thead th { background-color: #000066; color: white; font-weight: bold; border: none; }
|
|
.pathology-table td { border: none; border-bottom: 1px solid black; }
|
|
.pathology-table .small { font-size: 0.75em; }
|
|
.pathology-table .name { font-weight: bold; }
|
|
</style>"}
|
|
var/output = "<html><title>Center for Disease Control</title><head>[stylesheet]</head><body><h2>Center for Disease Control</h2>"
|
|
for (var/i = 1, i <= src.states.len, i++)
|
|
if (i != 1)
|
|
output += " - "
|
|
if (state != i)
|
|
output += "<a href='?src=\ref[src];action=setstate;state=[i];topic_holder=\ref[topic_holder]'>[states[i]]</a>"
|
|
else
|
|
output += "<span style='color:#dd0000; font-weight:bold'>[states[i]]</span>"
|
|
output += "<br>"
|
|
if (istext(state))
|
|
output += "<h3>Details for pathogen strain [state]</h3>"
|
|
if (state in pathogen_trees)
|
|
var/datum/pathogen_cdc/CDC = pathogen_trees[state]
|
|
output += "<table class='pathology-table'><thead><tr><th>Mutation name</th><th>Symptoms</th><th class='small'>Primary attributes</th><th>Symptomatic</th><th>Stages</th><th>Infected</th><th>Actions</th></thead><tbody>"
|
|
for (var/name in CDC.mutations)
|
|
output += "<tr>"
|
|
var/datum/pathogen/P = CDC.mutations[name]
|
|
output += "<td>[name]</td>"
|
|
var/symptoms = ""
|
|
var/first = 1
|
|
for (var/datum/pathogeneffects/EF in P.effects)
|
|
if (first)
|
|
symptoms = severity_color(EF)
|
|
first = 0
|
|
else
|
|
symptoms += "<BR>[severity_color(EF)]"
|
|
output += "<td>[symptoms]</td>"
|
|
|
|
output += "<td>"
|
|
output += "Advance speed: <a href='?src=\ref[src];action=strain_data;which=\ref[CDC];name=[name];data=advance_speed;topic_holder=\ref[topic_holder]'>[P.advance_speed]</a><BR>"
|
|
output += "Maliciousness: <a href='?src=\ref[src];action=strain_data;which=\ref[CDC];name=[name];data=maliciousness;topic_holder=\ref[topic_holder]'>[P.maliciousness]</a><BR>"
|
|
output += "Mutation speed: <a href='?src=\ref[src];action=strain_data;which=\ref[CDC];name=[name];data=mutation_speed;topic_holder=\ref[topic_holder]'>[P.mutation_speed]</a><BR>"
|
|
output += "Mutativeness: <a href='?src=\ref[src];action=strain_data;which=\ref[CDC];name=[name];data=mutativeness;topic_holder=\ref[topic_holder]'>[P.mutativeness]</a><BR>"
|
|
output += "Suppression: <a href='?src=\ref[src];action=strain_data;which=\ref[CDC];name=[name];data=suppression_threshold;topic_holder=\ref[topic_holder]'>[P.suppression_threshold]</a><BR>"
|
|
output += "</td>"
|
|
|
|
output += "<td><a href='?src=\ref[src];action=strain_data;which=\ref[CDC];name=[name];data=symptomatic;topic_holder=\ref[topic_holder]'>[P.symptomatic ? "Yes" : "No"]</a></td>"
|
|
output += "<td><a href='?src=\ref[src];action=strain_data;which=\ref[CDC];name=[name];data=stages;topic_holder=\ref[topic_holder]'>[P.stages]</a></td>"
|
|
|
|
var/infected = 0
|
|
for (var/mob/living/carbon/human/H in CDC.infections)
|
|
var/pname = CDC.infections[H]
|
|
if (pname == P.name)
|
|
infected++
|
|
output += "<td>[infected]</td>"
|
|
output += "<td>"
|
|
output += "<a href='?src=\ref[src];action=strain_data;which=\ref[CDC];name=[name];data=spawn;topic_holder=\ref[topic_holder]'>(SPAWN)</a><br>"
|
|
output += "<a href='?src=\ref[src];action=strain_data;which=\ref[CDC];name=[name];data=infect;topic_holder=\ref[topic_holder]'>(INFECT)</a><br>"
|
|
output += "<a href='?src=\ref[src];action=strain_data;which=\ref[CDC];name=[name];data=cure;topic_holder=\ref[topic_holder]'>(CURE)</a><br>"
|
|
output += "<a href='?src=\ref[topic_holder];action=view_logs_pathology_strain;presearch=[P.name]'>(LOGS)</a>"
|
|
output += "</td>"
|
|
output += "</tr>"
|
|
else
|
|
output += "<h3>This pathogen no longer exists.</h3>"
|
|
else
|
|
switch (states[state])
|
|
if ("strains")
|
|
output += "<table class='pathology-table'><thead><tr><th>Created</th><th>Strain name</th><th>UID</th><th>Patient Zero</th><th>Infected</th><th>Immune</th><th>Microbody</th><th>Cure all</th><th>Details</th><th>Logs</th></thead><tbody>"
|
|
for (var/pathogen_name in pathogen_trees)
|
|
var/datum/pathogen_cdc/CDC = pathogen_trees[pathogen_name]
|
|
output += "<tr>"
|
|
output += "<td class='name'>[round(CDC.creation_time)]M</td>"
|
|
output += "<td class='name'>[pathogen_name]</td>"
|
|
output += "<td>[CDC.uid]</td>"
|
|
if (CDC.patient_zero)
|
|
output += "<td>[CDC.patient_zero_kname]</td>"
|
|
else
|
|
output += "<td>No infections yet</td>"
|
|
var/infections = 0
|
|
var/immunities = 0
|
|
for (var/mob/living/carbon/human/M in world)
|
|
if (CDC.uid in M.pathogens)
|
|
infections++
|
|
else if (CDC.uid in M.immunities)
|
|
immunities++
|
|
output += "<td>[infections]</td>"
|
|
output += "<td>[immunities]</td>"
|
|
output += "<td>[CDC.microbody_type]</td>"
|
|
output += "<td><a href='?src=\ref[src];action=strain_cure;strain=[pathogen_name];topic_holder=\ref[topic_holder]'>(CURE)</a></td>"
|
|
output += "<td><a href='?src=\ref[src];action=strain_details;strain=[pathogen_name];topic_holder=\ref[topic_holder]'>(VIEW)</a></td>"
|
|
output += "<td><a href='?src=\ref[topic_holder];action=view_logs_pathology_strain;presearch=[pathogen_name]'>(LOGS)</a></td>"
|
|
output += "</tr>"
|
|
output += "</tbody></table>"
|
|
if ("microbodies")
|
|
output += "<h3>Changes to stage cap and base mutativeness only affects future pathogens.</h3>"
|
|
output += "<table class='pathology-table'><thead><tr><th>Name</th><th>Medium</tħ><th>Nutrition</th><th>Stages</th><th>Vaccinable</th><th>Activity</th><th>Base mutativeness</th></thead><tbody>"
|
|
for (var/microbody_path in src.path_to_microbody)
|
|
output += "<tr>"
|
|
var/datum/microbody/MB = src.path_to_microbody[microbody_path]
|
|
output += "<td class='name'>[MB]</td>"
|
|
output += "<td class='small'>[MB.growth_medium]</td>"
|
|
var/nutrition = ""
|
|
var/first = 1
|
|
for (var/nutrient in MB.nutrients)
|
|
if (first)
|
|
first = 0
|
|
else
|
|
nutrition += "<BR>"
|
|
nutrition += "[nutrient]"
|
|
output += "<td>[nutrition]</td>"
|
|
output += "<td><a href='?src=\ref[src];action=microbody_data;which=\ref[MB];data=stages;topic_holder=\ref[topic_holder]'>[MB.stages]</a></td>"
|
|
output += "<td><a href='?src=\ref[src];action=microbody_data;which=\ref[MB];data=vaccinable;topic_holder=\ref[topic_holder]'>[MB.vaccination ? "Yes" : "No"]</a></td>"
|
|
output += "<td>"
|
|
for (var/stage = 1, stage <= 5, stage++)
|
|
if (stage != 1)
|
|
output += "<br>"
|
|
output += "<a href='?src=\ref[src];action=microbody_data;which=\ref[MB];data=activity;stage=[stage];topic_holder=\ref[topic_holder]'>[MB.activity[stage]]%</a>"
|
|
output += "</td>"
|
|
output += "<td><a href='?src=\ref[src];action=microbody_data;which=\ref[MB];data=mutativeness;topic_holder=\ref[topic_holder]'>[MB.mutativeness]</a></td>"
|
|
output += "</tr>"
|
|
output += "</tbody></table>"
|
|
if ("mutations")
|
|
output += "<h3>Enabled mutations</h3>"
|
|
output += "<table class='pathology-table'><thead><tr><th>Name</th><th>Info</th><th>Session maximum</th><th>Base occurrence chance</th><th>Disable</th></thead><tbody>"
|
|
for (var/mutation_path in src.path_to_mutation)
|
|
output += "<tr>"
|
|
var/datum/pathogen_mutation/MUT = src.path_to_mutation[mutation_path]
|
|
output += "<td class='name'>[MUT]</td>"
|
|
output += "<td><a href='?src=\ref[src];action=mutation_data;which=\ref[MUT];data=info;topic_holder=\ref[topic_holder]'>Show information</a></td>"
|
|
output += "<td><a href='?src=\ref[src];action=mutation_data;which=\ref[MUT];data=session_maximum;topic_holder=\ref[topic_holder]'>[MUT.session_maximum]</a></td>"
|
|
output += "<td><a href='?src=\ref[src];action=mutation_data;which=\ref[MUT];data=chance_base;topic_holder=\ref[topic_holder]'>[MUT.chance_base]%</a></td>"
|
|
output += "<td><a href='?src=\ref[src];action=mutation_data;which=\ref[MUT];data=disable;topic_holder=\ref[topic_holder]'>Disable</a></td>"
|
|
output += "</tr>"
|
|
output += "</tbody></table><br>"
|
|
|
|
output += "<h3>Disabled mutations</h3>"
|
|
output += "<table class='pathology-table'><thead><tr><th>Name</th><th>Info</th><th>Session maximum</th><th>Base occurrence chance</th><th>Enable</th></thead><tbody>"
|
|
for (var/mutation_path in src.disabled_mutations)
|
|
output += "<tr>"
|
|
var/datum/pathogen_mutation/MUT = src.disabled_mutations[mutation_path]
|
|
output += "<td class='name'>[MUT]</td>"
|
|
output += "<td><a href='?src=\ref[src];action=mutation_data;which=\ref[MUT];data=info;topic_holder=\ref[topic_holder]'>Show information</a></td>"
|
|
output += "<td><a href='?src=\ref[src];action=mutation_data;which=\ref[MUT];data=session_maximum;topic_holder=\ref[topic_holder]'>[MUT.session_maximum]</a></td>"
|
|
output += "<td><a href='?src=\ref[src];action=mutation_data;which=\ref[MUT];data=chance_base;topic_holder=\ref[topic_holder]'>[MUT.chance_base]%</a></td>"
|
|
output += "<td><a href='?src=\ref[src];action=mutation_data;which=\ref[MUT];data=enable;topic_holder=\ref[topic_holder]'>Enable</a></td>"
|
|
output += "</tr>"
|
|
output += "</tbody></table>"
|
|
if ("symptoms")
|
|
output += "<table class='pathology-table'><thead><tr><th>Name</th><th>Info</th><th>Infection range</th><th>Infection coefficient</th><th>Rarity</th><th>DNA</th></thead><tbody>"
|
|
for (var/sym_path in src.path_to_symptom)
|
|
var/datum/pathogeneffects/EF = src.path_to_symptom[sym_path]
|
|
output += "<tr>"
|
|
output += "<td>[EF]</td>"
|
|
output += "<td><a href='?src=\ref[src];action=symptom_data;which=\ref[EF];data=info;topic_holder=\ref[topic_holder]'>Show information</a></td>"
|
|
output += "<td>[EF.infect_type]</td>"
|
|
output += "<td>[EF.infection_coefficient]</td>"
|
|
switch (EF.rarity)
|
|
if (RARITY_ABSTRACT)
|
|
output += "<td>Non-existent</td>"
|
|
if (RARITY_VERY_COMMON)
|
|
output += "<td>Very common</td>"
|
|
if (RARITY_COMMON)
|
|
output += "<td>Common</td>"
|
|
if (RARITY_UNCOMMON)
|
|
output += "<td>Uncommon</td>"
|
|
if (RARITY_RARE)
|
|
output += "<td>Rare</td>"
|
|
if (RARITY_VERY_RARE)
|
|
output += "<td>Very Rare</td>"
|
|
var/DNA = src.symptom_to_UID[EF.type]
|
|
output += "<td>[DNA]</td>"
|
|
output += "</tr>"
|
|
if ("suppressants")
|
|
output += "<table class='pathology-table'><thead><tr><th>Name</th><th>Suppression reagents</th></thead><tbody>"
|
|
for (var/sup_path in src.path_to_suppressant)
|
|
output += "<tr>"
|
|
var/datum/suppressant/S = src.path_to_suppressant[sup_path]
|
|
output += "<td>[S]</td>"
|
|
var/first = 1
|
|
var/supp = ""
|
|
for (var/reagent in S.cure_synthesis)
|
|
if (first)
|
|
first = 0
|
|
else
|
|
supp += "<BR>"
|
|
supp += "[reagent]"
|
|
output += "<td>[supp]</td>"
|
|
output += "</tr>"
|
|
if ("pathogen creator")
|
|
if (!(usr.ckey in src.cdc_creator))
|
|
src.gen_empty(usr.ckey)
|
|
var/datum/pathogen/P = src.cdc_creator[usr.ckey]
|
|
output += "<h3>Pathogen Creator</h3>"
|
|
output += "<b>Strain: </b> [P.name_base]<br>"
|
|
output += "<b>Base mutation:</b> [P.mutation]<br>"
|
|
output += "<b>Name: </b> [P.name]<br>"
|
|
if (P.suppressant)
|
|
output += "<b>Description: </b> [P.desc]<br>"
|
|
|
|
if (!P.body_type)
|
|
output += "<a href='?src=\ref[src];action=pathogen_creator;do=body_type;topic_holder=\ref[topic_holder]'>Assign microbody</a><br>"
|
|
else
|
|
output += "<b>Microbody:</b> [P.body_type]<br>"
|
|
output += "<b>Stages:</b> <a href='?src=\ref[src];action=pathogen_creator;do=stages;topic_holder=\ref[topic_holder]'>[P.stages]</a><br>"
|
|
output += "<b>Advance speed:</b> <a href='?src=\ref[src];action=pathogen_creator;do=advance_speed;topic_holder=\ref[topic_holder]'>[P.advance_speed]</a><br>"
|
|
output += "<b>Maliciousness:</b> <a href='?src=\ref[src];action=pathogen_creator;do=maliciousness;topic_holder=\ref[topic_holder]'>[P.maliciousness]</a><br>"
|
|
output += "<b>Mutation speed:</b> <a href='?src=\ref[src];action=pathogen_creator;do=mutation_speed;topic_holder=\ref[topic_holder]'>[P.mutation_speed]</a><br>"
|
|
output += "<b>Mutativeness:</b> <a href='?src=\ref[src];action=pathogen_creator;do=mutativeness;topic_holder=\ref[topic_holder]'>[P.mutativeness]</a><br>"
|
|
output += "<b>Symptomatic:</b> <a href='?src=\ref[src];action=pathogen_creator;do=symptomatic;topic_holder=\ref[topic_holder]'>[P.symptomatic ? "Yes" : "No"]</a><br>"
|
|
output += "<b>Suppression threshold:</b> <a href='?src=\ref[src];action=pathogen_creator;do=suppression_threshold;topic_holder=\ref[topic_holder]'>[P.suppression_threshold]</a><br>"
|
|
if (!P.suppressant)
|
|
output += "<a href='?src=\ref[src];action=pathogen_creator;do=suppressant;topic_holder=\ref[topic_holder]'>Assign suppressant</a><br>"
|
|
else
|
|
output += "<b>Suppressant: </b>[P.suppressant]<br><br>"
|
|
output += "<b>Effects: </b><br>"
|
|
if (P.effects.len)
|
|
for (var/datum/pathogeneffects/EF in P.effects)
|
|
output += "- [EF] <a href='?src=\ref[src];action=pathogen_creator;do=remove;which=\ref[EF];topic_holder=\ref[topic_holder]'>(remove)</a><br>"
|
|
else
|
|
output += " -- None -- <br>"
|
|
output += "<a href='?src=\ref[src];action=pathogen_creator;do=add;topic_holder=\ref[topic_holder]'>Add effect</a><br><br>"
|
|
output += "<a href='?src=\ref[src];action=pathogen_creator;do=reset;topic_holder=\ref[topic_holder]'>Reset pathogen</a>"
|
|
if (P.body_type && P.suppressant && P.effects.len)
|
|
output += " -- <a href='?src=\ref[src];action=pathogen_creator;do=create;topic_holder=\ref[topic_holder]'>Create pathogen</a>"
|
|
else
|
|
output += "<h1>NOTHING TO SEE HERE YET</h1>"
|
|
output += "</body></html>"
|
|
usr << browse(output, "window=cdc;size=800x480")
|
|
|
|
proc/gen_empty(var/key)
|
|
if (!(key in src.cdc_creator))
|
|
src.cdc_creator += key
|
|
var/datum/pathogen/P = unpool(/datum/pathogen)
|
|
P.mutation = pick(lnums)
|
|
do
|
|
P.name_base = pick(lalph) + pick(lnums) + pick(lalph)
|
|
while (P.name_base in pathogen_trees)
|
|
P.name = P.name_base + P.mutation
|
|
P.mutation = text2num(P.mutation)
|
|
P.base_mutation = 0
|
|
src.cdc_creator[key] = P
|
|
|
|
New()
|
|
UID_to_symptom = list()
|
|
symptom_to_UID = list()
|
|
UID_to_suppressant = list()
|
|
suppressant_to_UID = list()
|
|
UID_to_carrier = list()
|
|
carrier_to_UID = list()
|
|
microbody_to_UID = list()
|
|
|
|
for (var/T in typesof(/datum/microbody) - /datum/microbody)
|
|
var/datum/microbody/B = new T()
|
|
microbody_to_UID[T] = B.uniqueid
|
|
path_to_microbody[T] = B
|
|
|
|
if (!(B.growth_medium in media))
|
|
media += B.growth_medium
|
|
if (!(B.cure_base in cure_bases))
|
|
cure_bases += B.cure_base
|
|
for (var/nutrient in B.nutrients)
|
|
if (!(nutrient in nutrients))
|
|
nutrients += nutrient
|
|
|
|
var/datum/choice/C = new
|
|
C.target = B
|
|
C.min = choicemax + 1
|
|
choicemax += B.commonness
|
|
C.max = choicemax
|
|
microbody_choices += C
|
|
|
|
var/list/available_mutations = typesof(/datum/pathogen_mutation) - /datum/pathogen_mutation
|
|
for (var/mutation in available_mutations)
|
|
path_to_mutation[mutation] += new mutation()
|
|
|
|
var/list/eff = typesof(/datum/pathogeneffects)
|
|
l_vc = list()
|
|
l_c = list()
|
|
l_u = list()
|
|
l_r = list()
|
|
l_vr = list()
|
|
for (var/E in eff)
|
|
var/datum/pathogeneffects/inst = new E()
|
|
if (inst.rarity == RARITY_ABSTRACT)
|
|
continue
|
|
path_to_symptom[E] = inst
|
|
switch (inst.rarity)
|
|
if (RARITY_VERY_COMMON)
|
|
l_vc += E
|
|
|
|
if (RARITY_COMMON)
|
|
l_c += E
|
|
|
|
if (RARITY_UNCOMMON)
|
|
l_u += E
|
|
|
|
if (RARITY_RARE)
|
|
l_r += E
|
|
|
|
if (RARITY_VERY_RARE)
|
|
l_vr += E
|
|
|
|
var/list/used = list()
|
|
var/list/vc = list()
|
|
var/list/cp = list()
|
|
var/list/cu = list()
|
|
var/list/up = list()
|
|
var/list/uu = list()
|
|
var/list/rp = list()
|
|
var/list/ru = list()
|
|
var/list/vrp = list()
|
|
var/list/vru = list()
|
|
|
|
for (var/T in (typesof(/datum/suppressant) - /datum/suppressant))
|
|
var/r
|
|
do
|
|
r = num2hex(rand(0, 4095), 3)
|
|
while (r in used)
|
|
suppressant_to_UID[T] = r
|
|
UID_to_suppressant[r] = T
|
|
path_to_suppressant[T] = new T()
|
|
used += r
|
|
|
|
/*for (var/T in typesof(/datum/pathogen_carrier))
|
|
var/r
|
|
do
|
|
r = num2hex(rand(0, 4095), 3)
|
|
while (r in used)
|
|
carrier_to_UID[T] = r
|
|
UID_to_carrier[r] = new T()
|
|
used += r*/
|
|
|
|
// Assemble VERY_COMMON
|
|
for (var/T in l_vc)
|
|
var/r
|
|
do
|
|
r = num2hex(rand(0, 4095), 3)
|
|
while (r in used)
|
|
symptom_to_UID[T] = r
|
|
UID_to_symptom[r] = T
|
|
used += r
|
|
vc += r
|
|
|
|
// Create COMMON possibilities
|
|
for (var/p1 in vc)
|
|
for (var/p2 in vc)
|
|
if (!((p1 + p2) in cp))
|
|
cp += p1 + p2
|
|
if (!((p2 + p1) in cp))
|
|
cp += p2 + p1
|
|
|
|
// Assemble COMMON
|
|
for (var/T in l_c)
|
|
var/r
|
|
if (cp.len)
|
|
r = pick(cp)
|
|
else
|
|
do
|
|
r = pick(vc) + num2hex(rand(0, 4095), 3)
|
|
while (r in cu)
|
|
cp -= r
|
|
symptom_to_UID[T] = r
|
|
UID_to_symptom[r] = T
|
|
cu += r
|
|
|
|
// Create UNCOMMON possibilities
|
|
for (var/p1 in cu)
|
|
for (var/p2 in vc)
|
|
if (!((p1 + p2) in cp))
|
|
up += p1 + p2
|
|
if (!((p2 + p1) in cp))
|
|
up += p2 + p1
|
|
|
|
// Assemble UNCOMMON
|
|
for (var/T in l_u)
|
|
var/r
|
|
if (up.len)
|
|
r = pick(up)
|
|
else
|
|
do
|
|
r = pick(cu) + num2hex(rand(0, 4095), 3)
|
|
while (r in uu)
|
|
up -= r
|
|
symptom_to_UID[T] = r
|
|
UID_to_symptom[r] = T
|
|
uu += r
|
|
|
|
// Create RARE possibilities
|
|
for (var/p1 in uu)
|
|
for (var/p2 in vc)
|
|
if (!((p1 + p2) in cp))
|
|
rp += p1 + p2
|
|
if (!((p2 + p1) in cp))
|
|
rp += p2 + p1
|
|
|
|
// Assemble RARE
|
|
for (var/T in l_r)
|
|
var/r
|
|
if (rp.len)
|
|
r = pick(rp)
|
|
else
|
|
do
|
|
r = pick(uu) + num2hex(rand(0, 4095), 3)
|
|
while (r in ru)
|
|
rp -= r
|
|
symptom_to_UID[T] = r
|
|
UID_to_symptom[r] = T
|
|
ru += r
|
|
|
|
// Create VERY_RARE possibilities
|
|
for (var/p1 in ru)
|
|
for (var/p2 in vc)
|
|
if (!((p1 + p2) in cp))
|
|
vrp += p1 + p2
|
|
if (!((p2 + p1) in cp))
|
|
vrp += p2 + p1
|
|
|
|
// Assemble VERY_RARE
|
|
for (var/T in l_vr)
|
|
var/r
|
|
if (vrp.len)
|
|
r = pick(vrp)
|
|
else
|
|
do
|
|
r = pick(ru) + num2hex(rand(0, 4095), 3)
|
|
while (r in vru)
|
|
vrp -= r
|
|
symptom_to_UID[T] = r
|
|
UID_to_symptom[r] = T
|
|
vru += r
|
|
|
|
for (var/i = 1, i <= 99, i++)
|
|
lnums += "[i]"
|
|
for (var/i = text2ascii("A"), i <= text2ascii("Z"), i++)
|
|
lalph += ascii2text(i)
|
|
|
|
var/global/datum/controller/pathogen/pathogen_controller = new()
|
|
|
|
// A choice assistant datum
|
|
datum/choice
|
|
var/target
|
|
|
|
var/min = 0
|
|
var/max = 10
|
|
|
|
// todo: remove this, port.
|
|
// A wrapper record returned by the onshocked event of a pathogen symptom.
|
|
datum/shockparam
|
|
var/amt
|
|
var/wattage
|
|
var/skipsupp
|
|
|
|
// A pathogen. How surprising.
|
|
datum/pathogen
|
|
var/name // The full 'scientific' name for the pathogen (eg. H5N1)
|
|
var/name_base // The 'scientific' name without the mutation part (eg. H5N)
|
|
var/pathogen_uid // The unique identifier of the pathogen family. All pathogens with the same UID are cured by the same vaccine.
|
|
var/mutation // The mutation identifier of the pathogen (eg. for H5N1: 1). Unique for each mutation. Sequential.
|
|
var/desc // What a scientist might see when he looks at this pathogen through a microscope (eg. blue stringy viruses)
|
|
var/stages // How far the pathogen may advance? Higher stages allow for more malicious/benevolent effects of symptoms. (3 to 5)
|
|
// The amount of stages is determined by the body type. The most potent of all are viruses and parasites.
|
|
var/list/carriers = list() // A list of carriers to this pathogen. Currently unused.
|
|
var/list/effects = list() // A list of symptoms exhibited by those infected with this pathogen.
|
|
var/stage // The current stage of the pathogen.
|
|
var/advance_speed // The speed at which this pathogen advances stages. An advance speed of N means a flat N% chance to advance each tick.
|
|
var/mutativeness // The speed at which this pathogen mutates. A mutativeness of N means that it has a flat N% chance to mutate upon infection.
|
|
var/maliciousness // The maliciousness of mutations. The higher this value, the more likely it is that the pathogen will mutate in a malevolent way.
|
|
var/mutation_speed // The rate at which the pathogen mutates. This value defines how many different mutations will occur during a single mutation session.
|
|
// Mutation Speed is on a log3 scale of mutations.
|
|
// This means that to achieve the next mutation count (as in, mutate one more time compared to the current state), one needs to tripe
|
|
// the mutation speed of the pathogen. 1 mutation will occur for a speed of 0 to 8, 2 for 9 to 26, 3 for 27 to 80, etc. No mutation will
|
|
// occur if this value is less than 0.
|
|
var/base_mutation // Currently unused.
|
|
var/datum/microbody/body_type // The body type of the pathogen, which determines the base mutativeness and the method of synthesizing a cure.
|
|
var/mob/infected // The mob that is infected with this pathogen.
|
|
var/cooldown = 3 // An internal 'cooldown' so that the pathogen doesn't instantly advance to stage 5.
|
|
var/suppression_threshold // The pathogen's resistance to suppression. The higher this value, the more extreme conditions are required to suppress the pathogen.
|
|
|
|
var/list/mutex = list() // These symptoms are explicitly disallowed by a mutex.
|
|
var/symptomatic = 1 // If 0, the pathogen is mostly dormant on the mob. Symptoms may still decide to ignore this.
|
|
var/generation = 1 // Higher generation pathogens may replace lower generation pathogens on mobs.
|
|
|
|
var/datum/pathogendna/dnasample = null // A reference of what the pathogen's DNA looks like. This reference is passed around
|
|
// and copied only when coming into contact with something that directly works with
|
|
// the DNA itself.
|
|
|
|
var/datum/suppressant/suppressant // The method of suppression for the pathogen. This is picked from all children of /datum/suppressant with an equal
|
|
// probability. I might try to work out a system for rarities once, but it's very low on the priority list. To add a suppression method,
|
|
// just define a child for /datum/suppressant and please make sure it's not an already existing colour.
|
|
|
|
var/suppressed = 0 // A suppression indicator. After every roll for advancement, suppression is reset to 0 and a cooldown is set. Processes of the pathogen
|
|
// and the symptoms both may decide to set this flag during this cooldown. The pathogen immediately fails the advance roll if it is suppressed.
|
|
// With this being available, symptoms may define their own resistances and vulnerabilities. Setting this to -1 will make all current symptoms'
|
|
// vulnerability checks immediately fail - ie. the symptoms' weaknesses will not suppress the pathogen. On the flipside, setting this to 2 will
|
|
// make all current symptoms' resistance check immediately fail, ie. the symptoms' resistances will not prevent suppression. It would be good
|
|
// practice to build all symptoms consistently with this concept.
|
|
// Each disease has their primary suppression method, which provides their colour. The primary suppression method is relevant only if after
|
|
// all the symptoms acting, suppressed does not equal -1. Primary suppression methods may suppress the pathogen further: Even if a symptom
|
|
// has a weakness powerful enough to force it back a stage, a primary suppression method is also such a weakness that it may be pushed back
|
|
// yet another stage.
|
|
// A pathogen that cannot be currently suppressed (ie. is strengthened somehow) may advance regardless of advance speed.
|
|
// Be sensible when defining suppressions for symptoms. It shouldn't cure the pathogen, and it seldom should push the pathogen back below stage 3.
|
|
// TL;DR
|
|
// -1: Cannot be suppressed. May cause a negative advance speed pathogen to advance anyway.
|
|
// 0: Will not be suppressed.
|
|
// 1: Will be suppressed.
|
|
// 2: Will surely be suppressed.
|
|
|
|
var/in_remission = 0 // Pathogens in remission are being cured by the body. Set by the curing reagent.
|
|
var/forced_microbody = null // If not null, this pathogen will be generated with a specific microbody.
|
|
var/curable_by_suppression = 0 // If not 0, represents a probability of becoming regressive through suppression. If negative, randomly generated.
|
|
var/rads = 0 // The pathogen may mutate inside someone according to rads.
|
|
var/rad_mutate_cooldown = 0 // The amount of ticks to wait before we can mutate again due to radiation.
|
|
var/ticked = 0
|
|
|
|
var/list/symptom_data = list() // Symptom data container.
|
|
|
|
disposing()
|
|
clear()
|
|
|
|
proc/clear()
|
|
name = ""
|
|
name_base = ""
|
|
pathogen_uid = 0
|
|
mutation = 0
|
|
desc = ""
|
|
stages = 1
|
|
carriers = list()
|
|
effects = list()
|
|
stage = 1
|
|
generation = 1
|
|
symptomatic = 1
|
|
advance_speed = 0
|
|
mutativeness = 0
|
|
maliciousness = 0
|
|
mutation_speed = 0
|
|
base_mutation = 0
|
|
body_type = null
|
|
infected = null
|
|
cooldown = 3
|
|
suppression_threshold = 0
|
|
mutex = list()
|
|
dnasample = null
|
|
suppressant = null
|
|
suppressed = 0
|
|
in_remission = 0
|
|
rads = 0
|
|
rad_mutate_cooldown = 0
|
|
ticked = 0
|
|
symptom_data = list()
|
|
|
|
forced_microbody = initial(forced_microbody)
|
|
curable_by_suppression = initial(curable_by_suppression)
|
|
|
|
proc/clone()
|
|
var/datum/pathogen/P = unpool(/datum/pathogen)
|
|
P.setup(0, src, 0)
|
|
return P
|
|
|
|
proc/do_prefab(var/strength = 0)
|
|
clear()
|
|
var/cdc = generate_name()
|
|
generate_components(cdc)
|
|
generate_attributes(strength)
|
|
|
|
New()
|
|
setup(0, null, 0)
|
|
|
|
unpooled()
|
|
clear()
|
|
setup(0, null, 0)
|
|
|
|
proc/create_weak()
|
|
randomize(0)
|
|
|
|
proc/cdc_announce(var/mob/M)
|
|
var/datum/pathogen_cdc/CDC = null
|
|
if (name_base in pathogen_controller.pathogen_trees)
|
|
CDC = pathogen_controller.pathogen_trees[name_base]
|
|
else
|
|
CDC = new /datum/pathogen_cdc(pathogen_uid)
|
|
pathogen_controller.pathogen_trees[name_base] = CDC
|
|
pathogen_controller.next_mutation[pathogen_uid] = mutation + 1
|
|
CDC.microbody_type = body_type
|
|
CDC.mutations += name
|
|
CDC.mutations[name] = clone()
|
|
return
|
|
|
|
proc/generate_name()
|
|
src.mutation = pick(pathogen_controller.lnums)
|
|
do
|
|
src.name_base = pick(pathogen_controller.lalph) + pick(pathogen_controller.lnums) + pick(pathogen_controller.lalph)
|
|
while (src.name_base in pathogen_controller.pathogen_trees)
|
|
src.name = name_base + mutation
|
|
src.mutation = text2num(mutation)
|
|
src.base_mutation = 0
|
|
|
|
src.pathogen_uid = "[pathogen_controller.next_uid]"
|
|
pathogen_controller.next_uid++
|
|
|
|
pathogen_controller.pathogen_trees += src.name_base
|
|
var/datum/pathogen_cdc/cdc = new /datum/pathogen_cdc(src.pathogen_uid)
|
|
pathogen_controller.pathogen_trees[src.name_base] = cdc
|
|
pathogen_controller.next_mutation[src.pathogen_uid] = mutation + 1
|
|
|
|
// if (ticker)
|
|
// if (ticker.current_state == GAME_STATE_PLAYING)
|
|
// message_admins("Pathogen tree [src.name_base] entering play.")
|
|
|
|
return cdc
|
|
|
|
proc/generate_components(var/datum/pathogen_cdc/cdc, var/strength)
|
|
var/supp_t = pick(pathogen_controller.path_to_suppressant)
|
|
suppressant = pathogen_controller.path_to_suppressant[supp_t]
|
|
suppressant.onadd(src)
|
|
|
|
if (!forced_microbody)
|
|
src.body_type = pathogen_controller.get_microbody(strength + 5)
|
|
cdc.microbody_type = "[src.body_type]"
|
|
else
|
|
src.body_type = pathogen_controller.path_to_microbody[forced_microbody]
|
|
cdc.microbody_type = "[src.body_type]"
|
|
|
|
proc/generate_randomized_effects(var/strength)
|
|
var/adj_strength = strength - 8
|
|
if (strength != -1)
|
|
var/effcount = pick(1, prob(50); 2, prob(25); 3, prob(10); 4, prob(10); 5)
|
|
for (var/i = 0, i < effcount, i++)
|
|
var/val = rand(adj_strength, adj_strength + 8)
|
|
if (val < 6)
|
|
generate_weak_effect()
|
|
else if (val < 14)
|
|
generate_effect()
|
|
else
|
|
generate_strong_effect()
|
|
|
|
proc/generate_attributes(var/strength)
|
|
var/adj_strength = strength - 8
|
|
src.maliciousness = rand(-2, 6) + rand(adj_strength - 8, adj_strength + 8)
|
|
src.mutation_speed = rand(-2, 10) + rand(adj_strength - 8, adj_strength + 8)
|
|
|
|
src.suppression_threshold += rand(1,3) * maliciousness + rand(-5, 10) + rand(adj_strength - 8, adj_strength + 8)
|
|
src.advance_speed = rand(-2, 7) + rand(adj_strength - 8, adj_strength + 8)
|
|
|
|
src.mutativeness = src.body_type.mutativeness
|
|
|
|
src.maliciousness *= src.body_type.maliciousness_multiplier
|
|
src.mutation_speed *= src.body_type.mutation_speed_multiplier
|
|
|
|
if (src.curable_by_suppression < 0 && strength < 10)
|
|
src.curable_by_suppression = rand(-10 + strength, 10 - strength)
|
|
if (src.curable_by_suppression < 0)
|
|
src.curable_by_suppression = 0
|
|
else
|
|
src.curable_by_suppression = 0
|
|
|
|
src.stages = src.body_type.stages
|
|
|
|
var/shape = pick("stringy", "snake", "blob", "spherical", "tetrahedral", "star shaped", "tesselated")
|
|
src.desc = "[src.suppressant.color] [shape] [src.body_type.plural]"
|
|
|
|
src.symptomatic = 1
|
|
src.generation = 1
|
|
src.stage = 1
|
|
|
|
proc/randomize(var/strength)
|
|
var/datum/pathogen_cdc/cdc = generate_name()
|
|
cdc.mutations += src.name
|
|
cdc.mutations[src.name] = src
|
|
generate_randomized_effects(strength)
|
|
generate_components(cdc, strength)
|
|
generate_attributes(strength)
|
|
|
|
logTheThing("pathology", null, null, "Pathogen [name] created by randomization.")
|
|
|
|
proc/setup(status, var/datum/pathogen/origin, may_mutate, var/datum/pathogendna/sample = null)
|
|
if (status == 0 && !origin)
|
|
return
|
|
src.in_remission = 0
|
|
if (origin)
|
|
src.mutation = origin.mutation
|
|
src.name = origin.name
|
|
src.name_base = origin.name_base
|
|
src.stages = origin.stages
|
|
src.desc = origin.desc
|
|
src.carriers = list()
|
|
src.effects = origin.effects.Copy()
|
|
for (var/datum/pathogeneffects/E in src.effects)
|
|
E.onadd(src)
|
|
src.pathogen_uid = origin.pathogen_uid
|
|
src.suppressant = new origin.suppressant.type()
|
|
src.suppressant.onadd(src)
|
|
src.stage = 1
|
|
src.generation = origin.generation
|
|
src.symptomatic = origin.symptomatic
|
|
src.advance_speed = origin.advance_speed
|
|
src.mutativeness = origin.mutativeness
|
|
src.mutation_speed = origin.mutation_speed
|
|
src.body_type = origin.body_type
|
|
src.maliciousness = origin.maliciousness
|
|
src.suppression_threshold = origin.suppression_threshold
|
|
if (src.mutativeness && may_mutate)
|
|
if (prob(src.mutativeness))
|
|
mutate()
|
|
else
|
|
if (sample)
|
|
src.dnasample = sample
|
|
else
|
|
src.dnasample = origin.dnasample
|
|
else
|
|
if (sample)
|
|
src.dnasample = sample
|
|
else
|
|
src.dnasample = origin.dnasample
|
|
src.curable_by_suppression = origin.curable_by_suppression
|
|
else if (status == 1)
|
|
src.randomize(8)
|
|
if (sample)
|
|
src.dnasample = sample
|
|
else
|
|
src.dnasample = new/datum/pathogendna(src)
|
|
else if (!origin && status == 2)
|
|
src.do_prefab()
|
|
if (sample)
|
|
src.dnasample = sample
|
|
else
|
|
src.dnasample = new/datum/pathogendna(src)
|
|
|
|
|
|
proc/generate_weak_effect()
|
|
switch(rand(1,100))
|
|
if (1 to 70)
|
|
return src.add_new_symptom(pathogen_controller.l_vc)
|
|
if (71 to 97)
|
|
return src.add_new_symptom(pathogen_controller.l_c)
|
|
if (98 to 100)
|
|
return src.add_new_symptom(pathogen_controller.l_u)
|
|
|
|
proc/generate_effect()
|
|
switch(rand(1,100))
|
|
if (1 to 60) // 60%
|
|
return src.add_new_symptom(pathogen_controller.l_vc)
|
|
if (61 to 85) // 25%
|
|
return src.add_new_symptom(pathogen_controller.l_c)
|
|
if (86 to 94) // 8%
|
|
return src.add_new_symptom(pathogen_controller.l_u)
|
|
if (95 to 98) // 4%
|
|
return src.add_new_symptom(pathogen_controller.l_r)
|
|
if (99 to 100) // 2%
|
|
return src.add_new_symptom(pathogen_controller.l_vr)
|
|
|
|
proc/generate_strong_effect()
|
|
switch(rand(1,100))
|
|
if (1 to 40) // 40%
|
|
return src.add_new_symptom(pathogen_controller.l_vc)
|
|
if (41 to 70) // 30%
|
|
return src.add_new_symptom(pathogen_controller.l_c)
|
|
if (71 to 85) // 15%
|
|
return src.add_new_symptom(pathogen_controller.l_u)
|
|
if (86 to 93) // 8%
|
|
return src.add_new_symptom(pathogen_controller.l_r)
|
|
if (94 to 100) // 7%
|
|
return src.add_new_symptom(pathogen_controller.l_vr)
|
|
|
|
// Invoked when the pathogen mutates. This will change the active instance of the pathogen accordingly.
|
|
// Does not occur randomly, only upon infection.
|
|
// In the future, applying radiation to infected people may mutate the pathogen.
|
|
proc/mutate()
|
|
base_mutation = mutation
|
|
mutation = pathogen_controller.next_mutation[src.pathogen_uid]
|
|
pathogen_controller.next_mutation[src.pathogen_uid] += 1
|
|
name = name_base + "[mutation]"
|
|
mutativeness = round(mutativeness / 1.66)
|
|
logTheThing("pathology", null, null, "Pathogen strain [name_base] mutated creating [name].")
|
|
var/count = mutation_speed
|
|
if (count < 0)
|
|
return
|
|
if (count > 0 && count < 2)
|
|
count = 1
|
|
if (count > 3)
|
|
count = round(log(3, count))
|
|
var/list/used_mutations = list()
|
|
var/retries = 10
|
|
for (var/i = 1, i <= count, i++)
|
|
var/T = pick(pathogen_controller.path_to_mutation)
|
|
var/datum/pathogen_mutation/mut = pathogen_controller.path_to_mutation[T]
|
|
if (T in used_mutations)
|
|
if (used_mutations[T] >= mut.session_maximum)
|
|
continue
|
|
else
|
|
used_mutations[T]++
|
|
else
|
|
used_mutations[T] = 1
|
|
if (mut.may_occur(src))
|
|
mut.mutate(src)
|
|
logTheThing("pathology", null, null, "[mut] occurred on [name].")
|
|
else
|
|
if (retries)
|
|
i--
|
|
retries--
|
|
else
|
|
logTheThing("pathology", null, null, "[mut] could not occur on [name].")
|
|
dnasample = new(src)
|
|
|
|
proc/process()
|
|
disease_act()
|
|
if (rads)
|
|
if (rads < 1)
|
|
rads = 0
|
|
else
|
|
rads /= 2
|
|
if (infected)
|
|
var/mob/living/carbon/human/M = infected
|
|
if (istype(M))
|
|
var/rad = M.get_radiation()
|
|
rads += rad
|
|
if (M.reagents)
|
|
var/datum/reagent/R = M.reagents.get_reagent("mutagen")
|
|
if (istype(R))
|
|
rads += R.volume
|
|
if (rads && suppressed <= 0)
|
|
if (prob(rads))
|
|
logTheThing("pathology", infected, null, "'s infection of [name] mutated due to radiation levels of [rads].")
|
|
mutate()
|
|
rad_mutate_cooldown = 26
|
|
if (ticked)
|
|
ticked = 0
|
|
suppressed = 0
|
|
if (rad_mutate_cooldown > 0)
|
|
rad_mutate_cooldown--
|
|
else if (rad_mutate_cooldown < 0) //??
|
|
rad_mutate_cooldown = 0
|
|
|
|
// This is the real thing, wrapped by process().
|
|
proc/disease_act()
|
|
var/list/acted = list()
|
|
var/order = pick(0,1)
|
|
if (order)
|
|
for (var/datum/effect in src.effects)
|
|
if (effect.type in acted)
|
|
continue
|
|
acted += effect.type
|
|
if (prob(body_type.activity[stage]))
|
|
effect:disease_act(infected, src)
|
|
else
|
|
for (var/i = src.effects.len, i > 0, i--)
|
|
var/datum/effect = src.effects[i]
|
|
if (effect.type in acted)
|
|
continue
|
|
acted += effect.type
|
|
if (prob(body_type.activity[stage]))
|
|
effect:disease_act(infected, src)
|
|
if (!cooldown)
|
|
if (in_remission)
|
|
if (prob(abs(advance_speed)))
|
|
if (stage == 1)
|
|
infected.cured(src)
|
|
else
|
|
reduce()
|
|
return
|
|
if (suppressed != -1)
|
|
var/result = suppressant.suppress_act(src)
|
|
if (suppressed == 0)
|
|
suppressed = result
|
|
if (advance_speed > 0)
|
|
if (prob(min(advance_speed, 4)))
|
|
if (suppressed < 1)
|
|
advance()
|
|
else if (stage > 3)
|
|
reduce()
|
|
else if (advance_speed < 0)
|
|
if (suppressed == -1)
|
|
if (prob(4))
|
|
advance()
|
|
else
|
|
if (prob(-advance_speed))
|
|
reduce()
|
|
if (suppressed > 0)
|
|
if (curable_by_suppression && prob(curable_by_suppression))
|
|
in_remission = 1
|
|
ticked = 1
|
|
else
|
|
cooldown--
|
|
|
|
// A safe method for advancing the pathogen's stage.
|
|
proc/advance()
|
|
if (stage != stages)
|
|
stage++
|
|
cooldown = COOLDOWN_MULTIPLIER * 3 + 2 * stage
|
|
|
|
// The polar opposite of advance(). It causes the pathogen to safely reduce a stage if it can.
|
|
proc/reduce()
|
|
if (stage > 1)
|
|
stage--
|
|
cooldown = COOLDOWN_MULTIPLIER * 3 + 2 * stage
|
|
else
|
|
infected.cured(src)
|
|
|
|
// Carrier query. Currently unused.
|
|
proc/is_carried_by(var/reagent)
|
|
return (reagent in pathogen_controller.pathogen_affected_reagents)
|
|
|
|
proc/remission()
|
|
in_remission = 1
|
|
|
|
//=============================================================================
|
|
// Events
|
|
//=============================================================================
|
|
// In the following chapter you will encounter the definition for event handlers.
|
|
// Event handlers are available for both pathogens and symptoms.
|
|
//
|
|
// Defining new events
|
|
// ---------------------
|
|
// 1) Add your event handler here. The event handler should call the event handlers of all symptoms.
|
|
// 2) Define a default event handler in /datum/pathogeneffects. This is necessary so that all symptoms continue working, even if they don't respond to that event.
|
|
// 3) Define a default event handler in /datum/suppressant. This is necessary so that all suppression methods continue working, even if they don't respond to that event.
|
|
// 4) Override the event handler in the symptoms where you want it to react.
|
|
// 5) Call each affecting pathogen's event handler when the event is triggered.
|
|
//
|
|
// Defining existing events for symptoms
|
|
// ---------------------------------------
|
|
// All events are structured, so that if they take X arguments in the pathogen, they take X+2 arguments in the pathogen effect, so the first argument is always the
|
|
// affected mob, while the last argument is always the affecting pathogen. The equivalent event of the pathogen symptoms has the same name as the pathogen's wrapper
|
|
// event.
|
|
// A good practice is to follow these standards.
|
|
// To define an event for an effect, simply override the appropriate event handler. The pathogen code automatically handles calling these events at the appropriate time.
|
|
//
|
|
|
|
// Act when grabbing a mob. Does not return anything, the grab always happens.
|
|
// This event is only fired when the PASSIVE grab comes into play.
|
|
// @TODO: Extend this event to all grab levels. Add the possibility of vetoing.
|
|
proc/ongrab(var/mob/target as mob)
|
|
for (var/effect in src.effects)
|
|
effect:ongrab(infected, target, src)
|
|
suppressant.ongrab(target, src)
|
|
|
|
// Act when punched by a mob. Returns a multiplier for the damage done by the punch.
|
|
// A hardened skin symptom might make good use of it one day (AT THE TIME OF WRITING THIS COMMENT THAT DID NOT EXIST OKAY)
|
|
proc/onpunched(var/mob/origin as mob, zone)
|
|
var/ret = 1
|
|
for (var/effect in src.effects)
|
|
ret *= effect:onpunched(infected, origin, zone, src)
|
|
suppressant.onpunched(origin, zone, src)
|
|
return ret
|
|
|
|
// Act when punching a mob. Returns a multipier for the damage done by the punch.
|
|
// This opens up the availability for both hulk (quad-damage anyone?) and muscle deficiency diseases.
|
|
// Returning 0 from any symptom vetoes the punch.
|
|
proc/onpunch(var/mob/target as mob, zone)
|
|
var/ret = 1
|
|
for (var/effect in src.effects)
|
|
ret *= effect:onpunch(infected, target, zone, src)
|
|
suppressant.onpunch(target, zone, src)
|
|
return ret
|
|
|
|
// Act when successfully disarming or pushing down a mob. Returns whether this may happen.
|
|
// This indicates that ondisarm is a veto event - any of the symptoms has a right to veto the occurrence of the disarm or pushdown.
|
|
// Think of it this way. Suppose you have a muscle disease that makes you weak. When your puny body finally hits the target...
|
|
// ...nothing actually happens because you're a weak mess and failed to even scratch him.
|
|
// Returning 0 from ANY of the symptoms' disarm events will make disarming fail.
|
|
proc/ondisarm(var/mob/target as mob, isPushDown)
|
|
var/ret = 1
|
|
for (var/effect in src.effects)
|
|
ret = min(effect:ondisarm(infected, target, isPushDown, src), ret)
|
|
suppressant.ondisarm(target, isPushDown, src)
|
|
return ret
|
|
|
|
// Act when shocked. Returns the amount of damage the shocked mob should actually take (which leaves place for both amplification and suppression)
|
|
// The return system here is more complex than for most other events. The symptoms' onshocked may not only modify the amount of shock damage, but
|
|
// also decide that the presence of the symptom makes the a muscle-event vulnerable pathogen resistant to suppression through shocking.
|
|
proc/onshocked(var/amt, var/wattage)
|
|
var/datum/shockparam/ret = new
|
|
ret.amt = amt
|
|
ret.wattage = wattage
|
|
ret.skipsupp = 0
|
|
for (var/effect in src.effects)
|
|
ret = effect:onshocked(infected, ret, src)
|
|
suppressant.onshocked(ret, src)
|
|
return ret.amt
|
|
|
|
// Act when saying something. Returns the message that should be said after the diseases make the appropriate modifications.
|
|
proc/onsay(message)
|
|
for (var/effect in src.effects)
|
|
message = effect:onsay(infected, message, src)
|
|
suppressant.onsay(message, src)
|
|
return message
|
|
|
|
// Act on emoting. Vetoing available by returning 0.
|
|
proc/onemote(act)
|
|
suppressant.onemote(infected, act, src)
|
|
for (var/effect in src.effects)
|
|
. *= effect:onemote(infected, act, src)
|
|
|
|
proc/add_new_symptom(var/list/allowed, var/allow_duplicates = 0)
|
|
for (var/i = 0, i < 10, i++)
|
|
var/T = pick(allowed)
|
|
var/datum/pathogeneffects/E = pathogen_controller.path_to_symptom[T]
|
|
if (add_symptom(E, allow_duplicates))
|
|
return 1
|
|
return 0
|
|
|
|
proc/add_symptom(var/datum/pathogeneffects/E, var/allow_duplicates = 0)
|
|
if (allow_duplicates || !(E in effects))
|
|
for (var/mutex in E.mutex)
|
|
for (var/T in typesof(mutex))
|
|
if (!(T in mutex))
|
|
mutex += T
|
|
effects += E
|
|
E.onadd(src)
|
|
return 1
|
|
return 0
|
|
|
|
proc/remove_symptom(var/datum/pathogeneffects/E, var/all = 0)
|
|
if (all)
|
|
var/rem = 0
|
|
while (E in src.effects)
|
|
src.effects -= E
|
|
rem = 1
|
|
if (rem)
|
|
rebuild_mutex()
|
|
else
|
|
if (E in src.effects)
|
|
src.effects -= E
|
|
rebuild_mutex()
|
|
|
|
proc/rebuild_mutex()
|
|
src.mutex = list()
|
|
for (var/datum/pathogeneffects/E in src.effects)
|
|
for (var/mutex in E.mutex)
|
|
for (var/T in typesof(mutex))
|
|
if (!(T in mutex))
|
|
mutex += T
|
|
|
|
proc/dig2hex(num)
|
|
switch (num)
|
|
if (0 to 9)
|
|
return num
|
|
if (10)
|
|
return "A"
|
|
if (11)
|
|
return "B"
|
|
if (12)
|
|
return "C"
|
|
if (13)
|
|
return "D"
|
|
if (14)
|
|
return "E"
|
|
if (15)
|
|
return "F"
|
|
else
|
|
return ""
|
|
|
|
// One's complement num2hex - converts numbers to their hexadecimal one's complement representation (along with the padding).
|
|
proc/num2hexoc(num, pad)
|
|
if (pad == null)
|
|
pad = 4
|
|
if (pad <= 0)
|
|
return ""
|
|
var/max = 1
|
|
|
|
var/neg = 0
|
|
if (num < 0)
|
|
num = -num
|
|
neg = 1
|
|
|
|
for (var/i = 1; i < pad; i++)
|
|
max *= 16
|
|
max *= 8
|
|
max -= 1
|
|
|
|
var/ret = ""
|
|
if (num > max)
|
|
if (neg)
|
|
for (var/i = 1; i < pad; i++)
|
|
ret = "0[ret]"
|
|
return "8[ret]"
|
|
else
|
|
for (var/i = 1; i < pad; i++)
|
|
ret = "F[ret]"
|
|
return "7[ret]"
|
|
else
|
|
var/digs = 1
|
|
var/cnum = num
|
|
while (cnum)
|
|
if (digs != pad)
|
|
var/digit = cnum % 16
|
|
if (neg)
|
|
digit = 15 - digit
|
|
ret = "[dig2hex(digit)][ret]"
|
|
cnum = round(cnum / 16)
|
|
digs++
|
|
else
|
|
var/digit = num
|
|
if (digit > 7)
|
|
logTheThing("pathology", null, null, "Num2hexoc error: overflow on [num].")
|
|
if (neg)
|
|
digit += 8
|
|
return "[dig2hex(digit)][ret]"
|
|
while (digs <= pad)
|
|
if (neg)
|
|
ret = "F[ret]"
|
|
else
|
|
ret = "0[ret]"
|
|
digs++
|
|
return ret
|
|
|
|
// One's complement reverse engineering of a hexadecimal one's complement representation to a base 10 signed number
|
|
proc/hex2numoc(var/num)
|
|
var/len = length(num)
|
|
var/max = 7
|
|
for (var/i = len - 1, i > 0, i--)
|
|
max = max * 16 + 15
|
|
var/rnum = hex2num(num)
|
|
if (rnum > max)
|
|
rnum = rnum - (16 ** len - 1)
|
|
return rnum
|
|
|
|
// generates a random 3-sequence (rand(0, 4095) is unreliable)
|
|
proc/rand3seq()
|
|
return num2hex(rand(0, 15), 1) + num2hex(rand(0, 15), 1) + num2hex(rand(0, 15), 1) |