mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 18:44:48 +01:00
Advanced Disease Rework (#28451)
* Reworks cures, adds strains, adds treatment chems to symptoms
* Enables coexistence of different samples of the same strain at different stages within the same container
* Adds symptom guessing. Correct guesses reduce analysis time and wrong ones increase it.
* Adds a chance for a virus to evolve into a new strain. changing the cure and adding/subtracting symptoms
* Revert "Adds a chance for a virus to evolve into a new strain. changing the cure and adding/subtracting symptoms"
This reverts commit 124dd485c7.
* Adds spontaneous virus mutations, strain tracking. Removes antibody metabolism
* change the amount of time added/reduced by each factor
* Creates a disease outbreak event that allows admins to cause an outbreak of a virus of their choosing. Allows virus creation when choosing virus to give someone or for an outbreak.
* The normal base property values are now the defaults for disease creation
* Rebuild TGUI
* Rebuild TGUI
* Rebuild TGUI
* Update tgui.bundle.js
* remove redundant lines
* improves ui some and moves to using world time for analysis time
* fixes a bug with the analysis time and updates the initial known advanced disease list
* Buffs the disease outbreak event and adds a base stat row to the PANDEMIC
* Update tgui.bundle.js
* Implements calibration
* Adds a remove from database button
* Moves the known disease global list to work per z level
* Removes treatments from most chems and makes each instance of a symptom not acting purge some of the reagent that treated it
* Update symptoms.dm
* Adds stage to unknown diseases
* Moves accumulated error to work per z level and change the location of the delete strain data button
* Adds confirmation to the delete data button and moves the disease text out of the loop in the copy constructor
* fix indentation
* Replaces pent with hydrocodone in the advanced cure list
* gives more buffs to event disease based on severity. removes longevity from possible symptoms an event disease can get. Fixes a bug with determining analysis time
* Update tgui.bundle.js
* Update pandemic.dm
* Update pandemic.dm
* Update tgui.bundle.js
* review changes
* Update tgui.bundle.js
* Update tgui.bundle.js
* Update tgui.bundle.js
* Update tgui.bundle.js
* Update tgui.bundle.js
* Update tgui.bundle.js
* Update tgui.bundle.js
* Update tgui.bundle.js
* review changes
* Update tgui.bundle.js
* Makes vaccines only add resistances and no longer cure
* improves pandemic ui and fixes calibration button not being properly disabled
* Update tgui.bundle.js
* Add the new agars to the virologist's fridge
* lowered evolution chance of viruses a bit
* further lowers evolution chance
* Update advance.dm
* Changes the scaling of analysis time and fixes stage speed presentation in the pandemic
* Scanners can now see virus strains that have been inserted in the pandemic
* Allows a mob to be infected by both an event and non event disease
* Fixes the +1 syringe of translocation stabbing your feet
* Update tgui.bundle.js
* Changes spontanous mutation to be per spread and makes disease events less likely.
* Diseases less common, mutations happen only on spread now, symptom list ordered alphabetically in the dropdown, fixed some bugs
* Update tgui.bundle.js
* changes virus alerts
* Removes numbers from the virus alert text and fixes a bug that caused excessive virus mutations
* Update tgui.bundle.js
* refactor disease spread
* Changes disease spread logic to give players options to protect themselves and others
* Blackbox things
* Increases announcement timer and fixes the infection talley
* Update disease_outbreak.dm
* Adds an incubation period to advanced viruses. bumps sneeze back to 5 range
* Adds failsafe to disease outbreaks that will infect a random crew member if none have arrived in 10 minutes
* Only record advanced disease infections
* Properly handle recording of disease infection events
* Changed resistance effect on cure
* another adjustment to res effect on cure
* Small resist buff, spontanous combustion buff and some calculation fixes
* changes spontanous combustion stat bonuses and maluses
* Update flesh_eating.dm
* Update flesh_eating.dm
* Update flesh_eating.dm
* Big trait changes and rebalance
* adds treatments to fire and necro
* Introduces viral contamination of food and reagent containers, as well as disinfection
* Fix runtime in reagent transfers
* Revert the prefs and config changes
* Slowed down diseases and made symptoms more gradual, improved disease alerts to both crew and dchat
* Sterilizine now sterilizes things contaminated with viruses. Heat reactions now take place alongside chemical reactions when adding reagents to a beaker
* Adds option to order sterile masks, goggles and biosuits in packs of 4. Makes sterile masks as good as internals for viruses
* adds logging to pandemic
* Changes symptom stats and increased disease varaiety
* Fixes some disease bugs
* Fixes some bugs and makes it behave better
* Adds shiver emote to shiver symptom
* Adds admin message/log to contracting an event disease and fixes copy behaviour when infecting
* Prefix spread defines
* Change the rest of the macros
* correct the disinfection temp macro
* Moves disease signals to their own file
* move disnifection temp back
* fix a type
* viral contaminations component review changes
* var name changes
* more style fixes
* Update tgui.bundle.js
* fixes pandemic
* Fixes disease outbreak having two carriers sometimes and changes the virus alert to the new one
* Update disease_defines.dm
* fixes samples not passing stages on properly
* actually fixes the bug
* Fixes stabilization being lost on cloning
* Finally completely and absolutely fixes the sample stages bug(please)
* Makes the pandemic a machine
* Update pandemic.dm
* removed drinks from cure requirements
* lowers chance of major viral outbreak
* fixes pandemic not processing properly
* Changes the cure system to have more options
* Makes mixing event viruses more random
* Fixes hardsuits having a 1% chance to be infected
* Increases virus protection of most clothing. medical scrubs and surgical hat buffed sunstantially
* Slow down progress of diseases
* makes spread less likely
* envirosuit is now slightly more protective from viruses, while the medical one is as good as scrubs
* Adds further protection to helmets
* Increases the number of possible cures and the scaling of required cures
* Pandemic ui improvements
* Update _disease.dm
* fix a bug with spread target in the disease outbreak event
* changes some clothing permeability
* Adds the ability to make viral DNA extracts by injecting a sample into a black slime core. It's equivalent to 2 stages
* Adds age to health analyzer, makes viral evolution toggle minor disabilities, confusion symptom now confuses more often
* Update pandemic.dm
* replace lazarus with acetic acid in the cures
* Changes the relation of the amount of cure options to required cures and the scaling of required cures with resistance
* Fixes virus renaming
* changes description and permeability of some medical jumpsuits
* Adds a list of all diseases infecting client mobs to the disease outbreak event
* uses event UID instead of ref in the disease
* Adds advanced disease carriers to admin antag menu
* Adds viral eraser which removes tracking and stabilizing. Admin spawn only for now
* Update tgui.bundle.js
* Adds the ability to create viral genetic material using radiation. it can be used in addition to that produced in xenobio
* changes alert logic, disease generation logic, adds treatments to weakness, cough and sneeze now more gradual and cough spreads at range 3
* makes disease advance a bit faster
* reduce time to announcement to 6 minutes after 3 people are infected
* Changes medibot disease detection to be the same as analyzers. Treatment chems now put the symptom on a cooldown that persists after they leave the body.
* Make sure the disease outbreak event only selects crew
* Fix abductor virus gland virus generation
* Adds sterilizine to viro locker
* Fixes null viruses appearing when merging virusless blood
* Adds oculine to hyphema treatments
* Rebalances weight loss and flesh eating
* Improvements to advanced disease carrier tab on the TGUI antag menu
* change the flag on away missions
* Update mob_spawn.dm
* Update tgui.bundle.js
* adds sterilizine recipe back
* Adds viral contamination to surgery tools and surgery steps
* small changes
* fixes pandemic ui. should work properly now(I hope)
* CI compliance
* Update flesh_eating.dm
* Update vomit.dm
* Update tgui.bundle.js
* Initial revision of analysis and fixes the UI issue with multiple stage samples
* refactors treatment and makes treatment chems more adjustable
* var correction
* symptoms and their contribution now show up on the pandemic
* Update tgui.bundle.js
* Update code/datums/diseases/advance/symptoms/cough.dm
Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com>
* change wizard disease and zombie disease macros to new ones
* Update tgui.bundle.js
* changes the part requirements on the pandemic boards to fit the actual parts
* fix misbehaviour when inserting samples without symptoms
* Some changes to difficulty scaling, reverts the level of projectile vomiting back to 4, and disallows germaphobes to avoid infection by injection
* Adds viral contamination to IV bags
---------
Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
4f77a856f0
commit
a5260456ae
@@ -1,31 +1,106 @@
|
||||
/obj/machinery/computer/pandemic
|
||||
#define ANALYSIS_DIFFICULTY_BASE 100
|
||||
#define ANALYSIS_DIFFICULTY_INCREMENT 40
|
||||
#define ANALYSIS_DURATION_BASE (0.5 MINUTES)
|
||||
#define STAGE_CONTRIBUTION 40
|
||||
#define GENE_CONTRIBUTION 60
|
||||
|
||||
/// list of known advanced disease ids. If an advanced disease isn't here it will display as unknown disease on scanners
|
||||
/// Initialized with the id of the flu and cold samples from the virologist's fridge in the pandemic's init
|
||||
GLOBAL_LIST_EMPTY(known_advanced_diseases)
|
||||
GLOBAL_LIST_EMPTY(detected_advanced_diseases)
|
||||
|
||||
/obj/machinery/pandemic
|
||||
name = "PanD.E.M.I.C 2200"
|
||||
desc = "Used to work with viruses."
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "pandemic0"
|
||||
circuit = /obj/item/circuitboard/pandemic
|
||||
idle_power_consumption = 20
|
||||
resistance_flags = ACID_PROOF
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
/// The base analysis time which is later modified by samples of uniqute stages and symptom prediction
|
||||
var/analysis_difficulty_base = ANALYSIS_DIFFICULTY_BASE
|
||||
/// How difficult the disease is to analyze. This sets the requirements for how much you need to contribute with things like stages and symptom predictions
|
||||
var/analysis_difficulty = 0
|
||||
/// The contribution of various factors towards analysis. The "max" values are only for the UI
|
||||
var/analysis_contributions = list(
|
||||
"Stage Data" = list("amount" = 0, "max" = 5 * STAGE_CONTRIBUTION),
|
||||
"Viral Gene Data" = list("amount" = 0, "max" = 2 * GENE_CONTRIBUTION),
|
||||
"Symptom Data" = list("amount" = 0, "max" = 0.5 * ANALYSIS_DIFFICULTY_BASE)
|
||||
)
|
||||
/// The time at which the analysis of a disease will be done. Calculated at the begnining of analysis using analysis_difficulty and symptoms symptom_guesses.
|
||||
var/analysis_time
|
||||
/// How much time analysis will take. Depends on components
|
||||
var/analysis_duration
|
||||
/// Whether the PANDEMIC is currently analyzing an advanced disease
|
||||
var/analyzing = FALSE
|
||||
/// Whether to keep the report screen up. This is so it can stay persistent while the UI is closed
|
||||
var/reporting = FALSE
|
||||
/// Can our sample be analyzed
|
||||
var/valid_sample = FALSE
|
||||
/// ID of the disease being analyzed
|
||||
var/analyzed_ID = ""
|
||||
/// Index of the disease being analyzed
|
||||
var/analyzed_index
|
||||
/// List of all symptoms. Gets filled in Initialize().
|
||||
var/symptom_list = list()
|
||||
var/temp_html = ""
|
||||
var/printing = null
|
||||
var/wait = null
|
||||
var/selected_strain_index = 1
|
||||
var/obj/item/reagent_containers/beaker = null
|
||||
/// The current symptom predictions
|
||||
var/list/predictions = list(
|
||||
"No Prediction",
|
||||
"No Prediction",
|
||||
"No Prediction",
|
||||
"No Prediction",
|
||||
"No Prediction",
|
||||
"No Prediction"
|
||||
)
|
||||
|
||||
/obj/machinery/computer/pandemic/Initialize(mapload)
|
||||
/obj/machinery/pandemic/Initialize(mapload)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/pandemic(null)
|
||||
component_parts += new /obj/item/stock_parts/manipulator(null)
|
||||
component_parts += new /obj/item/stock_parts/micro_laser(null)
|
||||
RefreshParts()
|
||||
|
||||
GLOB.pandemics |= src
|
||||
var/datum/symptom/S
|
||||
symptom_list += list("No Prediction")
|
||||
for(var/symptom_path in GLOB.list_symptoms)
|
||||
// I don't know a way to access the name of something with only the path without creating an instance.
|
||||
S = new symptom_path()
|
||||
symptom_list += list(S.name)
|
||||
qdel(S)
|
||||
// We init the list for the Z level here so that we can know it is loaded when we do.
|
||||
if(!(z in GLOB.known_advanced_diseases))
|
||||
GLOB.known_advanced_diseases += list("[z]" = list("4:origin", "24:origin"))
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/pandemic/Destroy()
|
||||
/obj/machinery/pandemic/RefreshParts()
|
||||
var/manip_rating = 0
|
||||
var/laser_rating = 0
|
||||
for(var/obj/item/stock_parts/manipulator/manip in component_parts)
|
||||
manip_rating += manip.rating
|
||||
for(var/obj/item/stock_parts/micro_laser/laser in component_parts)
|
||||
laser_rating += laser.rating
|
||||
|
||||
analysis_difficulty_base = ANALYSIS_DIFFICULTY_BASE * (9 / (manip_rating + 8))
|
||||
analysis_duration = ANALYSIS_DURATION_BASE * (1 / laser_rating)
|
||||
find_analysis_requirements()
|
||||
|
||||
/obj/machinery/pandemic/Destroy()
|
||||
GLOB.pandemics -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/pandemic/set_broken()
|
||||
/obj/machinery/pandemic/proc/set_broken()
|
||||
stat |= BROKEN
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/pandemic/proc/GetViruses()
|
||||
/obj/machinery/pandemic/proc/GetViruses()
|
||||
if(beaker && beaker.reagents)
|
||||
if(length(beaker.reagents.reagent_list))
|
||||
var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
|
||||
@@ -34,12 +109,12 @@
|
||||
var/list/viruses = BL.data["viruses"]
|
||||
return viruses
|
||||
|
||||
/obj/machinery/computer/pandemic/proc/GetVirusByIndex(index)
|
||||
/obj/machinery/pandemic/proc/GetVirusByIndex(index)
|
||||
var/list/viruses = GetViruses()
|
||||
if(viruses && index > 0 && index <= length(viruses))
|
||||
return viruses[index]
|
||||
|
||||
/obj/machinery/computer/pandemic/proc/GetResistances()
|
||||
/obj/machinery/pandemic/proc/GetResistances()
|
||||
if(beaker && beaker.reagents)
|
||||
if(length(beaker.reagents.reagent_list))
|
||||
var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
|
||||
@@ -48,17 +123,17 @@
|
||||
var/list/resistances = BL.data["resistances"]
|
||||
return resistances
|
||||
|
||||
/obj/machinery/computer/pandemic/proc/GetResistancesByIndex(index)
|
||||
/obj/machinery/pandemic/proc/GetResistancesByIndex(index)
|
||||
var/list/resistances = GetResistances()
|
||||
if(resistances && index > 0 && index <= length(resistances))
|
||||
return resistances[index]
|
||||
|
||||
/obj/machinery/computer/pandemic/proc/GetVirusTypeByIndex(index)
|
||||
/obj/machinery/pandemic/proc/GetVirusTypeByIndex(index)
|
||||
var/datum/disease/D = GetVirusByIndex(index)
|
||||
if(D)
|
||||
return D.GetDiseaseID()
|
||||
|
||||
/obj/machinery/computer/pandemic/proc/replicator_cooldown(waittime)
|
||||
/obj/machinery/pandemic/proc/replicator_cooldown(waittime)
|
||||
wait = 1
|
||||
update_icon()
|
||||
spawn(waittime)
|
||||
@@ -66,18 +141,18 @@
|
||||
update_icon()
|
||||
playsound(loc, 'sound/machines/ping.ogg', 30, 1)
|
||||
|
||||
/obj/machinery/computer/pandemic/update_icon_state()
|
||||
/obj/machinery/pandemic/update_icon_state()
|
||||
if(stat & BROKEN)
|
||||
icon_state = (beaker ? "pandemic1_b" : "pandemic0_b")
|
||||
return
|
||||
icon_state = "pandemic[(beaker)?"1":"0"][(has_power()) ? "" : "_nopower"]"
|
||||
|
||||
/obj/machinery/computer/pandemic/update_overlays()
|
||||
/obj/machinery/pandemic/update_overlays()
|
||||
. = list()
|
||||
if(!wait)
|
||||
. += "waitlight"
|
||||
|
||||
/obj/machinery/computer/pandemic/proc/create_culture(name, bottle_type = "culture", cooldown = 50)
|
||||
/obj/machinery/pandemic/proc/create_culture(name, bottle_type = "culture", cooldown = 50)
|
||||
var/obj/item/reagent_containers/glass/bottle/B = new/obj/item/reagent_containers/glass/bottle(loc)
|
||||
B.icon_state = "bottle"
|
||||
B.scatter_atom()
|
||||
@@ -85,7 +160,118 @@
|
||||
B.name = "[name] [bottle_type] bottle"
|
||||
return B
|
||||
|
||||
/obj/machinery/computer/pandemic/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
|
||||
/// Find the time it would take to analyze the current disease before any symptom predictions are made
|
||||
/obj/machinery/pandemic/proc/find_analysis_requirements()
|
||||
if(!beaker)
|
||||
return
|
||||
analysis_contributions["Stage Data"]["amount"] = 0
|
||||
analysis_contributions["Viral Gene Data"]["amount"] = 0
|
||||
analysis_contributions["Symptom Data"]["amount"] = 0
|
||||
analysis_contributions["Symptom Data"]["max"] = 1
|
||||
valid_sample = TRUE
|
||||
var/strains = 0
|
||||
var/list/stages = list()
|
||||
var/current_strain = ""
|
||||
var/stealth_init = FALSE
|
||||
var/stealth = 0
|
||||
var/resistance = 0
|
||||
var/max_stages = 0
|
||||
var/known_symptoms = 0
|
||||
var/num_symptoms = 0
|
||||
var/datum/reagent/blood/blood_sample = locate() in beaker.reagents.reagent_list
|
||||
var/datum/reagent/virus_genes/gene_sample = locate() in beaker.reagents.reagent_list
|
||||
if(blood_sample && blood_sample.data && blood_sample.data["viruses"])
|
||||
for(var/datum/disease/advance/to_analyze in blood_sample.data["viruses"])
|
||||
// Note down number of symptoms and number of known symptoms.
|
||||
// We only use these values if we find one strain, so no need to worry about overwriting
|
||||
known_symptoms = length(GLOB.detected_advanced_diseases["[z]"][to_analyze.GetDiseaseID()]["known_symptoms"])
|
||||
num_symptoms = length(to_analyze.symptoms)
|
||||
// Automatically analyze if the tracker stores the ID of an analyzed disease
|
||||
if(to_analyze.tracker && (to_analyze.tracker in GLOB.known_advanced_diseases["[z]"]))
|
||||
if(!(to_analyze.GetDiseaseID() in GLOB.known_advanced_diseases["[z]"]))
|
||||
GLOB.known_advanced_diseases["[z]"] += list(to_analyze.GetDiseaseID())
|
||||
// If we know this disease there's no need to keep going.
|
||||
if(to_analyze.GetDiseaseID() in GLOB.known_advanced_diseases["[z]"])
|
||||
return
|
||||
// If we somehow got multiple strains we can't do analysis.
|
||||
if(to_analyze.strain != current_strain || current_strain == "")
|
||||
strains++
|
||||
if(strains > 1)
|
||||
valid_sample = FALSE
|
||||
SStgui.update_uis(src, TRUE)
|
||||
return
|
||||
current_strain = to_analyze.strain
|
||||
// Calculate the stealth and resistance values. We only need to do this once
|
||||
if(!stealth_init)
|
||||
for(var/datum/symptom/S in to_analyze.symptoms)
|
||||
stealth += S.stealth
|
||||
resistance += S.resistance
|
||||
stealth += to_analyze.base_properties["stealth"]
|
||||
resistance += to_analyze.base_properties["resistance"]
|
||||
max_stages = to_analyze.max_stages
|
||||
stealth_init = TRUE
|
||||
// If we found a unique stage count it
|
||||
if(!(to_analyze.stage in stages))
|
||||
analysis_contributions["Stage Data"]["amount"] += STAGE_CONTRIBUTION
|
||||
stages += to_analyze.stage
|
||||
|
||||
if(gene_sample && gene_sample.data)
|
||||
for(var/key in gene_sample.data)
|
||||
for(var/strain_id in gene_sample.data[key])
|
||||
if(strain_id == current_strain)
|
||||
analysis_contributions["Viral Gene Data"]["amount"] += GENE_CONTRIBUTION
|
||||
break
|
||||
|
||||
var/power_level = (stealth + resistance)
|
||||
// Make sure we don't runtime if empty
|
||||
if(max_stages)
|
||||
analysis_difficulty = analysis_difficulty_base + ANALYSIS_DIFFICULTY_INCREMENT * (1.17 ** power_level)
|
||||
else
|
||||
analysis_difficulty = analysis_difficulty_base
|
||||
|
||||
analysis_contributions["Symptom Data"]["amount"] = num_symptoms ? analysis_difficulty * known_symptoms / (2 * num_symptoms) : 0
|
||||
analysis_contributions["Symptom Data"]["max"] = max(analysis_difficulty / 2, 1)
|
||||
|
||||
SStgui.update_uis(src, TRUE)
|
||||
|
||||
/obj/machinery/pandemic/proc/start_analysis(strain_index)
|
||||
var/datum/disease/advance/virus = GetVirusByIndex(strain_index)
|
||||
analyzing = TRUE
|
||||
analysis_time = world.time + analysis_duration
|
||||
analyzed_ID = virus.GetDiseaseID()
|
||||
analyzed_index = strain_index
|
||||
|
||||
/obj/machinery/pandemic/proc/analyze(strain_index)
|
||||
reporting = TRUE
|
||||
var/datum/disease/advance/virus = GetVirusByIndex(analyzed_index)
|
||||
var/symptom_names = list()
|
||||
for(var/datum/symptom/current_symptom in virus.symptoms)
|
||||
symptom_names += list(current_symptom.name)
|
||||
for(var/name in predictions)
|
||||
if(!name || name == "No Prediction")
|
||||
continue
|
||||
if(name in symptom_names)
|
||||
GLOB.detected_advanced_diseases["[z]"][analyzed_ID]["known_symptoms"] |= list(name)
|
||||
|
||||
var/found_symptoms = length(GLOB.detected_advanced_diseases["[z]"][analyzed_ID]["known_symptoms"])
|
||||
// Correct symptom symptom_guesses reduce the final analysis time by up to half of the base time.
|
||||
analysis_contributions["Symptom Data"]["max"] = analysis_difficulty / 2
|
||||
analysis_contributions["Symptom Data"]["amount"] = analysis_difficulty * found_symptoms / (2 * length(virus.symptoms))
|
||||
|
||||
var/total_contribution = 0
|
||||
for(var/factor in analysis_contributions)
|
||||
total_contribution += analysis_contributions[factor]["amount"]
|
||||
|
||||
return (analysis_difficulty - total_contribution) <= 0
|
||||
|
||||
/obj/machinery/pandemic/process()
|
||||
if(analyzing && analysis_time < world.time)
|
||||
if(analyze(analyzed_index))
|
||||
GLOB.known_advanced_diseases["[z]"] += analyzed_ID
|
||||
analyzing = FALSE
|
||||
SStgui.update_uis(src, TRUE)
|
||||
|
||||
/obj/machinery/pandemic/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
|
||||
if(..())
|
||||
return
|
||||
if(inoperable())
|
||||
@@ -111,9 +297,9 @@
|
||||
return
|
||||
var/type = virus.GetDiseaseID()
|
||||
if(!ispath(type))
|
||||
var/datum/disease/advance/A = GLOB.archive_diseases[type]
|
||||
if(A)
|
||||
D = new A.type(0, A)
|
||||
var/datum/disease/advance/A = virus
|
||||
if(istype(A))
|
||||
D = A.Copy()
|
||||
else if(type)
|
||||
if(type in GLOB.diseases) // Make sure this is a disease
|
||||
D = new type(0, null)
|
||||
@@ -158,6 +344,10 @@
|
||||
|
||||
var/obj/item/reagent_containers/glass/bottle/B = create_culture(vaccine_name, "vaccine", 200)
|
||||
B.reagents.add_reagent("vaccine", 15, list(vaccine_type))
|
||||
if("remove_from_database")
|
||||
if(params["strain_id"] in GLOB.known_advanced_diseases["[z]"])
|
||||
GLOB.known_advanced_diseases["[z]"] -= params["strain_id"]
|
||||
SStgui.update_uis(src, TRUE)
|
||||
if("eject_beaker")
|
||||
eject_beaker()
|
||||
update_static_data(ui.user)
|
||||
@@ -192,15 +382,16 @@
|
||||
if(!A)
|
||||
atom_say("Unable to find requested strain.")
|
||||
return
|
||||
if(A.name != "Unknown")
|
||||
atom_say("Request rejected. Strain already has a name.")
|
||||
return
|
||||
var/new_name = tgui_input_text(usr, "Name the Strain", "New Name", max_length = MAX_NAME_LEN)
|
||||
if(!new_name)
|
||||
return
|
||||
A.AssignName(new_name)
|
||||
for(var/datum/disease/advance/AD in GLOB.active_diseases)
|
||||
AD.Refresh()
|
||||
AD.Refresh(TRUE, FALSE, FALSE, FALSE)
|
||||
var/datum/reagent/blood = locate() in beaker.reagents.reagent_list
|
||||
if(blood.data && blood.data["viruses"])
|
||||
for(var/datum/disease/advance/virus in blood.data["viruses"])
|
||||
virus.AssignName(new_name)
|
||||
update_static_data(ui.user)
|
||||
if("switch_strain")
|
||||
var/strain_index = text2num(params["strain_index"])
|
||||
@@ -212,26 +403,52 @@
|
||||
atom_say("Unable to find requested strain.")
|
||||
return
|
||||
selected_strain_index = strain_index;
|
||||
if("analyze_strain")
|
||||
start_analysis(params["strain_index"])
|
||||
if("set_prediction")
|
||||
set_predictions(text2num(params["pred_index"]), params["pred_value"])
|
||||
SStgui.update_uis(src)
|
||||
if("close_report")
|
||||
reporting = FALSE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/computer/pandemic/ui_state(mob/user)
|
||||
/obj/machinery/pandemic/proc/set_predictions(index, value)
|
||||
predictions[index] = value
|
||||
|
||||
/obj/machinery/pandemic/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/pandemic/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
/obj/machinery/pandemic/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "PanDEMIC", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/pandemic/ui_data(mob/user)
|
||||
/obj/machinery/pandemic/ui_data(mob/user)
|
||||
var/datum/reagent/blood/Blood = null
|
||||
var/can_analyze = valid_sample
|
||||
var/contribution_list = list()
|
||||
var/contribution_sum = 0
|
||||
if(beaker)
|
||||
var/datum/reagents/R = beaker.reagents
|
||||
for(var/datum/reagent/blood/B in R.reagent_list)
|
||||
if(B)
|
||||
Blood = B
|
||||
break
|
||||
if(Blood)
|
||||
if(Blood.data && Blood.data["viruses"])
|
||||
for(var/datum/disease/advance/virus in Blood.data["viruses"])
|
||||
if((virus.GetDiseaseID() in GLOB.known_advanced_diseases["[z]"]))
|
||||
can_analyze = FALSE
|
||||
break
|
||||
for(var/factor in analysis_contributions)
|
||||
contribution_list += list(list(
|
||||
"factor" = factor,
|
||||
"amount" = analysis_contributions[factor]["amount"],
|
||||
"maxAmount" = analysis_contributions[factor]["max"],
|
||||
))
|
||||
contribution_sum += analysis_contributions[factor]["amount"]
|
||||
|
||||
var/list/data = list(
|
||||
"synthesisCooldown" = wait ? TRUE : FALSE,
|
||||
@@ -239,11 +456,21 @@
|
||||
"beakerContainsBlood" = Blood ? TRUE : FALSE,
|
||||
"beakerContainsVirus" = length(Blood?.data["viruses"]) != 0,
|
||||
"selectedStrainIndex" = selected_strain_index,
|
||||
"analysisTime" = analysis_time > world.time ? analysis_time - world.time : 0,
|
||||
"analysisDuration" = analysis_duration,
|
||||
"analysisDifficulty" = analysis_difficulty,
|
||||
"analysisContributions" = contribution_list,
|
||||
"totalContribution" = contribution_sum,
|
||||
"canAnalyze" = can_analyze,
|
||||
"analyzing" = analyzing,
|
||||
"reporting" = reporting,
|
||||
"symptom_names" = symptom_list,
|
||||
"predictions" = predictions,
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/pandemic/ui_static_data(mob/user)
|
||||
/obj/machinery/pandemic/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
. = data
|
||||
|
||||
@@ -256,59 +483,58 @@
|
||||
break
|
||||
|
||||
var/list/strains = list()
|
||||
for(var/datum/disease/D in GetViruses())
|
||||
if(D.visibility_flags & HIDDEN_PANDEMIC)
|
||||
for(var/datum/disease/blood_disease in GetViruses())
|
||||
if(!(blood_disease.GetDiseaseID() in GLOB.detected_advanced_diseases["[z]"]))
|
||||
GLOB.detected_advanced_diseases["[z]"] += list(blood_disease.GetDiseaseID() = list("known_symptoms" = list()))
|
||||
if(blood_disease.visibility_flags & VIRUS_HIDDEN_PANDEMIC)
|
||||
continue
|
||||
|
||||
var/list/symptoms = list()
|
||||
if(istype(D, /datum/disease/advance))
|
||||
var/datum/disease/advance/A = D
|
||||
D = GLOB.archive_diseases[A.GetDiseaseID()]
|
||||
if(!D)
|
||||
CRASH("We weren't able to get the advance disease from the archive.")
|
||||
for(var/datum/symptom/S in A.symptoms)
|
||||
symptoms += list(list(
|
||||
"name" = S.name,
|
||||
"stealth" = S.stealth,
|
||||
"resistance" = S.resistance,
|
||||
"stageSpeed" = S.stage_speed,
|
||||
"transmissibility" = S.transmittable,
|
||||
"complexity" = S.level,
|
||||
))
|
||||
|
||||
var/list/symptoms = blood_disease.get_pandemic_symptoms(z)
|
||||
var/list/base_stats = blood_disease.get_pandemic_base_stats()
|
||||
var/known = blood_disease.is_known(z)
|
||||
strains += list(list(
|
||||
"commonName" = D.name,
|
||||
"description" = D.desc,
|
||||
"commonName" = known ? blood_disease.name : "Unknown strain",
|
||||
"description" = known ? blood_disease.desc : "Unknown strain",
|
||||
"strainID" = blood_disease.get_strain_id(),
|
||||
"strainFullID" = blood_disease.get_full_strain_id(),
|
||||
"diseaseID" = blood_disease.get_ui_id(),
|
||||
"sample_stage" = blood_disease.get_stage(),
|
||||
"known" = known,
|
||||
"bloodDNA" = Blood.data["blood_DNA"],
|
||||
"bloodType" = Blood.data["blood_type"],
|
||||
"diseaseAgent" = D.agent,
|
||||
"possibleTreatments" = D.cure_text,
|
||||
"transmissionRoute" = D.spread_text,
|
||||
"diseaseAgent" = blood_disease.agent,
|
||||
"possibleCures" = known ? blood_disease.cure_text : "Unknown strain",
|
||||
"RequiredCures" = "[blood_disease.get_required_cures()]",
|
||||
"Stabilized" = blood_disease.is_stabilized(),
|
||||
"StrainTracker" = blood_disease.get_tracker(),
|
||||
"transmissionRoute" = known ? blood_disease.spread_text : "Unknown strain",
|
||||
"symptoms" = symptoms,
|
||||
"isAdvanced" = istype(D, /datum/disease/advance),
|
||||
"baseStats" = base_stats,
|
||||
"isAdvanced" = istype(blood_disease, /datum/disease/advance),
|
||||
))
|
||||
data["strains"] = strains
|
||||
|
||||
var/list/resistances = list()
|
||||
for(var/resistance in GetResistances())
|
||||
if(!ispath(resistance))
|
||||
var/datum/disease/D = GLOB.archive_diseases[resistance]
|
||||
if(D)
|
||||
resistances += list(D.name)
|
||||
var/datum/disease/resisted_disease = GLOB.archive_diseases[resistance]
|
||||
if(resisted_disease)
|
||||
resistances += list(resisted_disease.name)
|
||||
else if(resistance)
|
||||
var/datum/disease/D = new resistance(0, null)
|
||||
if(D)
|
||||
resistances += list(D.name)
|
||||
var/datum/disease/resistance_disease = new resistance(0, null)
|
||||
if(resistance_disease)
|
||||
resistances += list(resistance_disease.name)
|
||||
data["resistances"] = resistances
|
||||
data["analysis_difficulty"] = analysis_difficulty
|
||||
|
||||
/obj/machinery/computer/pandemic/proc/eject_beaker()
|
||||
/obj/machinery/pandemic/proc/eject_beaker()
|
||||
beaker.forceMove(loc)
|
||||
beaker = null
|
||||
icon_state = "pandemic0"
|
||||
selected_strain_index = 1
|
||||
|
||||
//Prints a nice virus release form. Props to Urbanliner for the layout
|
||||
/obj/machinery/computer/pandemic/proc/print_form(datum/disease/advance/D, mob/living/user)
|
||||
/obj/machinery/pandemic/proc/print_form(datum/disease/advance/D, mob/living/user)
|
||||
D = GLOB.archive_diseases[D.GetDiseaseID()]
|
||||
if(!(printing) && D)
|
||||
var/reason = tgui_input_text(user,"Enter a reason for the release", "Write", multiline = TRUE)
|
||||
@@ -350,7 +576,7 @@
|
||||
P.name = "Releasing Virus - [D.name]"
|
||||
printing = null
|
||||
|
||||
/obj/machinery/computer/pandemic/proc/print_goal_orders()
|
||||
/obj/machinery/pandemic/proc/print_goal_orders()
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
@@ -370,18 +596,18 @@
|
||||
P.info = info_text.Join("")
|
||||
P.update_icon()
|
||||
|
||||
/obj/machinery/computer/pandemic/attack_ai(mob/user)
|
||||
/obj/machinery/pandemic/attack_ai(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/pandemic/attack_hand(mob/user)
|
||||
/obj/machinery/pandemic/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/pandemic/attack_ghost(mob/user)
|
||||
/obj/machinery/pandemic/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/pandemic/item_interaction(mob/living/user, obj/item/used, list/modifiers)
|
||||
/obj/machinery/pandemic/item_interaction(mob/living/user, obj/item/used, list/modifiers)
|
||||
if(default_unfasten_wrench(user, used, time = 4 SECONDS))
|
||||
power_change()
|
||||
return
|
||||
@@ -395,17 +621,33 @@
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
beaker = used
|
||||
beaker.loc = src
|
||||
beaker.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You add the beaker to the machine.</span>")
|
||||
SStgui.update_uis(src, TRUE)
|
||||
icon_state = "pandemic1"
|
||||
|
||||
var/datum/reagent/blood/inserted = locate() in beaker.reagents.reagent_list
|
||||
if(inserted && inserted.data && inserted.data["viruses"])
|
||||
for(var/datum/disease/advance/virus in inserted.data["viruses"])
|
||||
if(!(virus.GetDiseaseID() in GLOB.detected_advanced_diseases["[z]"]))
|
||||
GLOB.detected_advanced_diseases["[z]"] += list(virus.GetDiseaseID() = list("known_symptoms" = list()))
|
||||
log_admin("[key_name(user)] inserted disease [virus] of strain [virus.strain] with the following symptoms: [english_list(virus.symptoms)] into [src] at these coords x: [x] y: [y] z: [z]")
|
||||
find_analysis_requirements()
|
||||
SStgui.update_uis(src, TRUE)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/pandemic/screwdriver_act(mob/user, obj/item/I)
|
||||
/obj/machinery/pandemic/screwdriver_act(mob/living/user, obj/item/I)
|
||||
if(!default_deconstruction_screwdriver(user, icon_state, icon_state, I))
|
||||
return FALSE
|
||||
if(beaker)
|
||||
eject_beaker()
|
||||
return TRUE
|
||||
return ..()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/pandemic/crowbar_act(mob/living/user, obj/item/I)
|
||||
return default_deconstruction_crowbar(user, I)
|
||||
|
||||
#undef ANALYSIS_DIFFICULTY_BASE
|
||||
#undef ANALYSIS_DIFFICULTY_INCREMENT
|
||||
#undef ANALYSIS_DURATION_BASE
|
||||
#undef STAGE_CONTRIBUTION
|
||||
#undef GENE_CONTRIBUTION
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
M.SetJitter(0)
|
||||
for(var/thing in M.viruses)
|
||||
var/datum/disease/D = thing
|
||||
if(D.severity == NONTHREAT)
|
||||
if(D.severity == VIRUS_NONTHREAT)
|
||||
continue
|
||||
D.cure(0)
|
||||
..()
|
||||
|
||||
@@ -155,6 +155,12 @@
|
||||
color = "#899613" // rgb: 137, 150, 19
|
||||
taste_description = "watery milk"
|
||||
|
||||
/datum/reagent/consumable/virus_food/on_mob_life(mob/living/M)
|
||||
. = ..()
|
||||
for(var/datum/disease/advance/virus in M.viruses)
|
||||
if(prob(3))
|
||||
virus.progress += 20
|
||||
|
||||
/datum/reagent/mutagen/mutagenvirusfood
|
||||
name = "Mutagenic agar"
|
||||
id = "mutagenvirusfood"
|
||||
@@ -183,3 +189,32 @@
|
||||
name = "Weakened virus plasma"
|
||||
id = "weakplasmavirusfood"
|
||||
color = "#CEC3C6" // rgb: 206,195,198
|
||||
|
||||
/datum/reagent/consumable/stable_agar
|
||||
name = "Stable agar"
|
||||
id = "stable_agar"
|
||||
color = "#50BDB0" // rgb: 80,206,192
|
||||
|
||||
/datum/reagent/consumable/tracking_agar
|
||||
name = "Tracking agar"
|
||||
id = "tracking_agar"
|
||||
color = "#2c8852" // rgb: 45,136,82
|
||||
|
||||
/datum/reagent/virus_genes
|
||||
name = "Viral Genetic Material"
|
||||
id = "virus_genes"
|
||||
color = "#e0717a"
|
||||
|
||||
/// Depth 1 copy of the lists
|
||||
/datum/reagent/virus_genes/on_merge(list/_data)
|
||||
var/list/result = list()
|
||||
for(var/key in (data + _data))
|
||||
result[key] = data[key]
|
||||
if(_data[key])
|
||||
result[key] += _data[key]
|
||||
data = result
|
||||
|
||||
/datum/reagent/viral_eraser
|
||||
name = "Viral Eraser"
|
||||
id = "viral_eraser"
|
||||
color = "#ffe600" // rgb: 45,136,82
|
||||
|
||||
@@ -29,6 +29,35 @@
|
||||
var/update_flags = STATUS_UPDATE_HEALTH
|
||||
return ..() | update_flags
|
||||
|
||||
/datum/reagent/medicine/sterilizine
|
||||
name = "Sterilizine"
|
||||
id = "sterilizine"
|
||||
description = "Sterilizes wounds in preparation for surgery."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC" // rgb: 200, 165, 220
|
||||
taste_description = "antiseptic"
|
||||
goal_difficulty = REAGENT_GOAL_EASY
|
||||
|
||||
//makes you squeaky clean
|
||||
/datum/reagent/medicine/sterilizine/reaction_mob(mob/living/M, method=REAGENT_TOUCH, volume)
|
||||
if(method == REAGENT_TOUCH)
|
||||
M.germ_level -= min(volume*20, M.germ_level)
|
||||
|
||||
/datum/reagent/medicine/sterilizine/reaction_obj(obj/O, volume)
|
||||
O.germ_level -= min(volume*20, O.germ_level)
|
||||
SEND_SIGNAL(O, COMSIG_ATOM_DISINFECTED)
|
||||
|
||||
/datum/reagent/medicine/sterilizine/reaction_turf(turf/T, volume)
|
||||
T.germ_level -= min(volume*20, T.germ_level)
|
||||
|
||||
/datum/reagent/medicine/sterilizine/reaction_temperature(exposed_temperature, exposed_volume)
|
||||
// Sterilize the container
|
||||
for(var/datum/reagent/to_disinfect in holder.reagent_list)
|
||||
if(to_disinfect.data && to_disinfect.data["viruses"])
|
||||
to_disinfect?.data["viruses"] = list()
|
||||
if(isobj(holder.my_atom))
|
||||
SEND_SIGNAL(holder.my_atom, COMSIG_ATOM_DISINFECTED)
|
||||
|
||||
/datum/reagent/medicine/synaptizine
|
||||
name = "Synaptizine"
|
||||
id = "synaptizine"
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
for(var/thing in data["viruses"])
|
||||
var/datum/disease/D = thing
|
||||
|
||||
if(D.spread_flags & SPECIAL || D.spread_flags & NON_CONTAGIOUS)
|
||||
if(D.spread_flags & SPREAD_SPECIAL || D.spread_flags & SPREAD_NON_CONTAGIOUS)
|
||||
continue
|
||||
|
||||
if(method == REAGENT_TOUCH)
|
||||
@@ -121,6 +121,13 @@
|
||||
C.blood_volume = min(C.blood_volume + round(volume, 0.1), BLOOD_VOLUME_NORMAL)
|
||||
..()
|
||||
|
||||
/datum/reagent/blood/reaction_temperature(exposed_temperature, exposed_volume)
|
||||
// If the blood goes above 60C kill all viruses
|
||||
if(exposed_temperature > VIRUS_DISINFECTION_TEMP)
|
||||
data["viruses"] = list()
|
||||
..()
|
||||
|
||||
|
||||
/datum/reagent/blood/on_new(list/data)
|
||||
if(istype(data))
|
||||
SetViruses(src, data)
|
||||
@@ -151,15 +158,38 @@
|
||||
|
||||
// Stop issues with the list changing during mixing.
|
||||
var/list/to_mix = list()
|
||||
var/list/disease_ids = list()
|
||||
var/list/stages = list()
|
||||
|
||||
for(var/datum/disease/advance/AD in mix1)
|
||||
to_mix += AD
|
||||
for(var/datum/disease/advance/AD in mix2)
|
||||
to_mix += AD
|
||||
if(!(AD.GetDiseaseID() in disease_ids))
|
||||
disease_ids += AD.GetDiseaseID()
|
||||
stages[AD.GetDiseaseID()] = list(AD.stage)
|
||||
to_mix += AD
|
||||
if(!(AD.stage in stages[AD.GetDiseaseID()]))
|
||||
stages[AD.GetDiseaseID()] += list(AD.stage)
|
||||
to_mix += AD
|
||||
|
||||
var/datum/disease/advance/AD = Advance_Mix(to_mix)
|
||||
if(AD)
|
||||
var/list/preserve = list(AD)
|
||||
for(var/datum/disease/advance/AD in mix2)
|
||||
if(!(AD.GetDiseaseID() in disease_ids))
|
||||
disease_ids += AD.GetDiseaseID()
|
||||
stages[AD.GetDiseaseID()] = list(AD.stage)
|
||||
to_mix += AD
|
||||
if(!(AD.stage in stages[AD.GetDiseaseID()]))
|
||||
stages[AD.GetDiseaseID()] += list(AD.stage)
|
||||
to_mix += AD
|
||||
|
||||
var/list/result_diseases = list()
|
||||
if(length(disease_ids) == 1)
|
||||
for(var/datum/disease/advance/AD in to_mix)
|
||||
result_diseases += AD.Copy()
|
||||
else
|
||||
var/datum/disease/advance/result_virus = Advance_Mix(to_mix)
|
||||
if(istype(result_virus))
|
||||
result_diseases = list(result_virus)
|
||||
|
||||
if(length(result_diseases))
|
||||
var/list/preserve = result_diseases
|
||||
for(var/D in data["viruses"])
|
||||
if(!istype(D, /datum/disease/advance))
|
||||
preserve += D
|
||||
@@ -187,6 +217,19 @@
|
||||
blood_prop = new(T)
|
||||
blood_prop.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*"
|
||||
|
||||
/// If irradiated by gamma radiation and there are advanced viruses in the blood become a sample of viral genetic data
|
||||
/datum/reagent/blood/reaction_radiation(amount, emission_type)
|
||||
if(emission_type == GAMMA_RAD && amount > 100)
|
||||
if(data && data["viruses"])
|
||||
var/list/strains = list("radiation" = list())
|
||||
for(var/datum/disease/advance/virus in data["viruses"])
|
||||
strains["radiation"] += virus.strain
|
||||
if(length(strains["radiation"]))
|
||||
var/blood_volume = volume
|
||||
holder.remove_reagent(id, blood_volume)
|
||||
holder.add_reagent("virus_genes", blood_volume, strains)
|
||||
|
||||
|
||||
/datum/reagent/vaccine
|
||||
//data must contain virus type
|
||||
name = "Vaccine"
|
||||
@@ -199,7 +242,7 @@
|
||||
for(var/thing in M.viruses)
|
||||
var/datum/disease/D = thing
|
||||
if(D.GetDiseaseID() in data)
|
||||
D.cure()
|
||||
D.make_resistant(M)
|
||||
M.resistances |= data
|
||||
|
||||
/datum/reagent/vaccine/on_merge(list/incoming_data)
|
||||
|
||||
@@ -62,7 +62,12 @@
|
||||
data.Cut()
|
||||
data = null
|
||||
|
||||
/datum/reagent/proc/reaction_temperature(exposed_temperature, exposed_volume) //By default we do nothing.
|
||||
/// By default do nothing
|
||||
/datum/reagent/proc/reaction_temperature(exposed_temperature, exposed_volume)
|
||||
return
|
||||
|
||||
/// By default do nothing
|
||||
/datum/reagent/proc/reaction_radiation(amount, emission_type)
|
||||
return
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
var/list/addiction_threshold_accumulated = list()
|
||||
var/flags
|
||||
|
||||
/datum/reagents/New(maximum = 100, temperature_minimum, temperature_maximum)
|
||||
/datum/reagents/New(maximum = 100, temperature_minimum, temperature_maximum, atom/_my_atom = null)
|
||||
my_atom = _my_atom
|
||||
maximum_volume = maximum
|
||||
if(temperature_minimum)
|
||||
temperature_min = temperature_minimum
|
||||
@@ -63,9 +64,10 @@
|
||||
var/datum/chemical_reaction/D = new path()
|
||||
var/list/reaction_ids = list()
|
||||
|
||||
if(D && length(D.required_reagents))
|
||||
for(var/reaction in D.required_reagents)
|
||||
reaction_ids += reaction
|
||||
if(D && (length(D.required_reagents) || length(D.required_catalysts)))
|
||||
var/list/all_requirements = D.required_reagents + D.required_catalysts
|
||||
for(var/reagent_id in all_requirements)
|
||||
reaction_ids += reagent_id
|
||||
|
||||
// Create filters based on each reagent id in the required reagents list
|
||||
for(var/id in reaction_ids)
|
||||
@@ -73,6 +75,9 @@
|
||||
GLOB.chemical_reactions_list[id] = list()
|
||||
GLOB.chemical_reactions_list[id] += D
|
||||
break // Don't bother adding ourselves to other reagent ids, it is redundant.
|
||||
if(my_atom)
|
||||
RegisterSignal(my_atom, COMSIG_ATOM_RAD_ACT, PROC_REF(radiation_react))
|
||||
ADD_TRAIT(my_atom, TRAIT_ABSORB_RADS, "reagents_holder_[UID()]")
|
||||
|
||||
/**
|
||||
* Removes reagents from the holder until the passed amount is matched.
|
||||
@@ -171,11 +176,16 @@
|
||||
if(!O.reagents)
|
||||
return
|
||||
R = O.reagents
|
||||
if(isliving(my_atom))
|
||||
var/atom/thing = target
|
||||
SEND_SIGNAL(thing, COMSIG_MOB_REAGENT_EXCHANGE, my_atom)
|
||||
else if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
if(!M.reagents)
|
||||
return
|
||||
R = M.reagents
|
||||
if(isobj(my_atom))
|
||||
SEND_SIGNAL(my_atom, COMSIG_MOB_REAGENT_EXCHANGE, target)
|
||||
else if(istype(target, /datum/reagents))
|
||||
R = target
|
||||
else
|
||||
@@ -186,7 +196,6 @@
|
||||
var/trans_data = null
|
||||
for(var/A in reagent_list)
|
||||
var/datum/reagent/current_reagent = A
|
||||
|
||||
var/current_reagent_transfer = current_reagent.volume * part
|
||||
if(preserve_data)
|
||||
trans_data = copy_data(current_reagent)
|
||||
@@ -199,6 +208,8 @@
|
||||
if(!no_react)
|
||||
R.handle_reactions()
|
||||
handle_reactions()
|
||||
R.temperature_react()
|
||||
temperature_react()
|
||||
return amount
|
||||
|
||||
/datum/reagents/proc/copy_to(obj/target, amount = 1, multiplier = 1, preserve_data = TRUE, safety = FALSE)
|
||||
@@ -215,12 +226,15 @@
|
||||
var/current_reagent_transfer = current_reagent.volume * part
|
||||
if(preserve_data)
|
||||
trans_data = copy_data(current_reagent)
|
||||
|
||||
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data)
|
||||
|
||||
update_total()
|
||||
R.update_total()
|
||||
R.handle_reactions()
|
||||
handle_reactions()
|
||||
R.temperature_react()
|
||||
temperature_react()
|
||||
return amount
|
||||
|
||||
/datum/reagents/proc/set_reagent_temp(new_temp = T0C, react = TRUE)
|
||||
@@ -230,10 +244,17 @@
|
||||
handle_reactions()
|
||||
|
||||
/datum/reagents/proc/temperature_react() //Calls the temperature reaction procs without changing the temp.
|
||||
if(chem_temp > VIRUS_DISINFECTION_TEMP && isobj(my_atom))
|
||||
SEND_SIGNAL(my_atom, COMSIG_ATOM_DISINFECTED)
|
||||
for(var/A in reagent_list)
|
||||
var/datum/reagent/current_reagent = A
|
||||
current_reagent.reaction_temperature(chem_temp, 100)
|
||||
|
||||
/datum/reagents/proc/radiation_react(atom/source, amount, emission_type)
|
||||
SIGNAL_HANDLER // COMSIG_ATOM_RAD_ACT
|
||||
for(var/datum/reagent/current_reagent in reagent_list)
|
||||
current_reagent.reaction_radiation(amount, emission_type)
|
||||
|
||||
/datum/reagents/proc/temperature_reagents(exposed_temperature, divisor = 35, change_cap = 15) //This is what you use to change the temp of a reagent holder.
|
||||
//Do not manually change the reagent unless you know what youre doing.
|
||||
var/difference = abs(chem_temp - exposed_temperature)
|
||||
@@ -275,6 +296,8 @@
|
||||
if(get_reagent_amount(reagent) < amount)
|
||||
amount = get_reagent_amount(reagent)
|
||||
amount = min(amount, R.maximum_volume - R.total_volume)
|
||||
if(isliving(my_atom))
|
||||
SEND_SIGNAL(target,COMSIG_MOB_REAGENT_EXCHANGE , my_atom)
|
||||
var/trans_data = null
|
||||
for(var/A in reagent_list)
|
||||
var/datum/reagent/current_reagent = A
|
||||
@@ -288,6 +311,7 @@
|
||||
update_total()
|
||||
R.update_total()
|
||||
R.handle_reactions()
|
||||
R.temperature_react()
|
||||
return amount
|
||||
|
||||
|
||||
@@ -492,7 +516,7 @@
|
||||
var/preserved_data = null
|
||||
for(var/B in C.required_reagents)
|
||||
if(!preserved_data)
|
||||
preserved_data = get_data(B)
|
||||
preserved_data = copy_data_by_id(B)
|
||||
remove_reagent(B, (multiplier * C.required_reagents[B]), safety = TRUE)
|
||||
|
||||
var/created_volume = C.result_amount*multiplier
|
||||
@@ -690,6 +714,9 @@
|
||||
if(total_volume + amount > maximum_volume) amount = (maximum_volume - total_volume) //Doesnt fit in. Make it disappear. Shouldnt happen. Will happen.
|
||||
if(amount <= 0)
|
||||
return FALSE
|
||||
// Contaminate the container with viruses if the reagent has any. We do this here rather than a reaction because it only depends on the data, and not necessarily the reagent.
|
||||
if(data && length(data["viruses"]) && isobj(my_atom))
|
||||
my_atom.AddComponent(/datum/component/viral_contamination, data["viruses"])
|
||||
chem_temp = clamp((chem_temp * total_volume + reagtemp * amount) / (total_volume + amount), temperature_min, temperature_max) //equalize with new chems
|
||||
|
||||
var/list/cached_reagents = reagent_list
|
||||
@@ -888,6 +915,11 @@
|
||||
if(R.id == reagent_id)
|
||||
R.data = new_data
|
||||
|
||||
/datum/reagents/proc/copy_data_by_id(reagent_id)
|
||||
for(var/datum/reagent/candidate in reagent_list)
|
||||
if(candidate.id == reagent_id)
|
||||
return(copy_data(candidate))
|
||||
|
||||
/datum/reagents/proc/copy_data(datum/reagent/current_reagent)
|
||||
if(!current_reagent || !current_reagent.data)
|
||||
return null
|
||||
@@ -966,8 +998,7 @@
|
||||
// Convenience proc to create a reagents holder for an atom
|
||||
// Max vol is maximum volume of holder
|
||||
/atom/proc/create_reagents(max_vol, temperature_minimum, temperature_maximum)
|
||||
reagents = new /datum/reagents(max_vol, temperature_minimum, temperature_maximum)
|
||||
reagents.my_atom = src
|
||||
reagents = new /datum/reagents(max_vol, temperature_minimum, temperature_maximum, src)
|
||||
|
||||
/proc/get_random_reagent_id() // Returns a random reagent ID minus blacklisted reagents
|
||||
var/static/list/random_reagents
|
||||
@@ -1012,8 +1043,11 @@
|
||||
reagent_list = null
|
||||
QDEL_LIST_CONTENTS(addiction_list)
|
||||
addiction_list = null
|
||||
if(my_atom && my_atom.reagents == src)
|
||||
my_atom.reagents = null
|
||||
if(my_atom)
|
||||
UnregisterSignal(my_atom, COMSIG_ATOM_RAD_ACT)
|
||||
REMOVE_TRAIT(my_atom, TRAIT_ABSORB_RADS, "reagents_holder_[UID()]")
|
||||
if(my_atom.reagents == src)
|
||||
my_atom.reagents = null
|
||||
my_atom = null
|
||||
|
||||
#undef ADDICTION_TIME
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
required_reagents = list("carpotoxin" = 1, "spaceacillin" = 1, "copper" = 1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/sterilizine
|
||||
name = "Sterilizine"
|
||||
id = "sterilizine"
|
||||
result = "sterilizine"
|
||||
required_reagents = list("antihol" = 2, "chlorine" = 1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/charcoal
|
||||
name = "Charcoal"
|
||||
id = "charcoal"
|
||||
|
||||
@@ -414,6 +414,20 @@
|
||||
required_reagents = list("salglu_solution" = 1, "mutagenvirusfood" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/datum/chemical_reaction/virus_food_mutadone
|
||||
name = "stable agar"
|
||||
id = "stable_agar"
|
||||
result = "stable_agar"
|
||||
required_reagents = list("mutadone" = 1, "virusfood" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/datum/chemical_reaction/virus_food_tracker
|
||||
name = "Tracking agar"
|
||||
id = "tracking_agar"
|
||||
result = "tracking_agar"
|
||||
required_reagents = list("fluorosurfactant" = 1, "virusfood" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/datum/chemical_reaction/mix_virus
|
||||
name = "Mix Virus"
|
||||
id = "mixvirus"
|
||||
@@ -499,6 +513,43 @@
|
||||
if(D)
|
||||
D.Devolve()
|
||||
|
||||
/datum/chemical_reaction/mix_virus/stabilize_virus
|
||||
name = "Stabilize Virus"
|
||||
id = "stabilize_virus"
|
||||
required_reagents = list("stable_agar" = 1)
|
||||
|
||||
/datum/chemical_reaction/mix_virus/stabilize_virus/on_reaction(datum/reagents/holder, created_volume)
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list
|
||||
if(B && B.data)
|
||||
var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"]
|
||||
if(istype(D))
|
||||
D.evolution_chance = 0
|
||||
|
||||
/datum/chemical_reaction/mix_virus/track_virus
|
||||
name = "Track Virus"
|
||||
id = "track_virus"
|
||||
required_reagents = list("tracking_agar" = 1)
|
||||
|
||||
/datum/chemical_reaction/mix_virus/track_virus/on_reaction(datum/reagents/holder, created_volume)
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list
|
||||
if(B && B.data)
|
||||
var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"]
|
||||
if(istype(D))
|
||||
D.tracker = D.GetDiseaseID()
|
||||
|
||||
/datum/chemical_reaction/mix_virus/clear_virus
|
||||
name = "Clear Virus"
|
||||
id = "clear_virus"
|
||||
required_reagents = list("viral_eraser" = 10)
|
||||
|
||||
/datum/chemical_reaction/mix_virus/clear_virus/on_reaction(datum/reagents/holder, created_volume)
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list
|
||||
if(B && B.data)
|
||||
var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"]
|
||||
if(istype(D))
|
||||
D.tracker = ""
|
||||
D.evolution_chance = VIRUS_EVOLUTION_CHANCE
|
||||
|
||||
// Someday, maybe add some version of doing science on patient zero to discover the recipees.
|
||||
/datum/chemical_reaction/zombie
|
||||
name = "Anti-Plague Sequence Alpha"
|
||||
@@ -575,7 +626,7 @@
|
||||
result = "zombiecure4"
|
||||
cure_level = 4
|
||||
amt_req_cures = 2
|
||||
required_symptom = /datum/symptom/heal/metabolism
|
||||
required_symptom = /datum/symptom/heal
|
||||
|
||||
/datum/chemical_reaction/zombie/four/get_possible_cures()
|
||||
return list("colorful_reagent", "bacchus_blessing", "pen_acid", "glyphosate", "lazarus_reagent", "omnizine", "sarin", "ants", "clf3", "sorium", "????", "aranesp")
|
||||
|
||||
@@ -512,6 +512,28 @@
|
||||
/datum/chemical_reaction/slimemutate2/on_reaction(datum/reagents/holder)
|
||||
SSblackbox.record_feedback("tally", "slime_cores_used", 1, type)
|
||||
|
||||
/datum/chemical_reaction/viral_gene_extraction
|
||||
name = "Virus Gene Extraction"
|
||||
id = "virus_gene_extraction"
|
||||
result = "virus_genes"
|
||||
required_reagents = list("blood" = 1)
|
||||
result_amount = 1
|
||||
required_other = TRUE
|
||||
required_container = /obj/item/slime_extract/black
|
||||
|
||||
/datum/chemical_reaction/viral_gene_extraction/on_reaction(datum/reagents/holder)
|
||||
SSblackbox.record_feedback("tally", "slime_cores_used", 1, type)
|
||||
var/obj/item/reagent_containers/glass/bottle/result_bottle = new(get_turf(holder.my_atom))
|
||||
holder.trans_to(result_bottle, holder.total_volume)
|
||||
var/datum/reagent/virus_genes/result_genes = locate() in result_bottle.reagents.reagent_list
|
||||
var/list/strains = list("slime" = list())
|
||||
if(result_genes.data && result_genes.data["viruses"])
|
||||
for(var/datum/disease/advance/advanced_virus in result_genes.data["viruses"])
|
||||
strains["slime"] += list(advanced_virus.strain)
|
||||
result_bottle.name = "[advanced_virus.strain] Strain Viral Genetic Matter"
|
||||
break
|
||||
result_genes.data = strains
|
||||
|
||||
//Oil
|
||||
/datum/chemical_reaction/slime_explosion
|
||||
name = "Slime Explosion"
|
||||
|
||||
@@ -302,6 +302,26 @@
|
||||
desc = "A small bottle. Contains H0NI<42 virion culture in synthblood medium."
|
||||
spawned_disease = /datum/disease/pierrot_throat
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/tracking_agar
|
||||
name = "Tracking agar bottle"
|
||||
desc = "A small bottle. Contains tracking agar which allows modifying a virus without needing to reanalyze it"
|
||||
list_reagents = list("tracking_agar" = 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/stable_agar
|
||||
name = "Stable agar bottle"
|
||||
desc = "A small bottle. Contains stable agar which stop a virus from being able to mutate on its own"
|
||||
list_reagents = list("stable_agar" = 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/sterilizine
|
||||
name = "Sterilizine bottle"
|
||||
desc = "A small bottle. Contains sterilizine, which is used to sterilize beakers and syringes"
|
||||
list_reagents = list("sterilizine" = 50)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/viral_eraser
|
||||
name = "Viral eraser bottle"
|
||||
desc = "A small bottle. Contains a small amount of viral eraser which removes all tracking and stabilizing from a virus"
|
||||
list_reagents = list("viral_eraser" = 10)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/cold
|
||||
name = "Rhinovirus culture bottle"
|
||||
desc = "A small bottle. Contains XY-rhinovirus culture in synthblood medium."
|
||||
|
||||
@@ -63,11 +63,20 @@
|
||||
add_attack_logs(user, target, "Fed with [name] containing [contained]", !!target.ckey ? null : ATKLOG_ALL)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You swallow a gulp of [src].</span>")
|
||||
|
||||
var/fraction = min(5 / reagents.total_volume, 1)
|
||||
reagents.reaction(target, REAGENT_INGEST, fraction)
|
||||
addtimer(CALLBACK(reagents, TYPE_PROC_REF(/datum/reagents, trans_to), target, 5), 5)
|
||||
playsound(target.loc,'sound/items/drink.ogg', rand(10,50), TRUE)
|
||||
// Add viruses where needed
|
||||
if(length(target.viruses))
|
||||
AddComponent(/datum/component/viral_contamination, target.viruses)
|
||||
// Infect contained blood as well for splash reactions
|
||||
var/datum/reagent/blood/blood_contained = locate() in reagents.reagent_list
|
||||
if(blood_contained?.data["viruses"])
|
||||
var/list/blood_viruses = blood_contained.data["viruses"]
|
||||
blood_viruses |= target.viruses.Copy()
|
||||
blood_contained.data["viruses"] = blood_viruses
|
||||
SEND_SIGNAL(src, COMSIG_MOB_REAGENT_EXCHANGE, target)
|
||||
|
||||
/obj/item/reagent_containers/glass/normal_act(atom/target, mob/living/user)
|
||||
if(!check_allowed_items(target, target_self = TRUE) || !is_open_container() || !reagents)
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
|
||||
/obj/item/reagent_containers/iv_bag/proc/begin_processing(mob/target)
|
||||
injection_target = target
|
||||
if(target.viruses)
|
||||
AddComponent(/datum/component/viral_contamination, target.viruses)
|
||||
RegisterSignal(injection_target, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_iv_type()
|
||||
|
||||
@@ -188,6 +188,10 @@
|
||||
var/fraction = min(amount_per_transfer_from_this / reagents.total_volume, 1)
|
||||
reagents.reaction(target, REAGENT_INGEST, fraction)
|
||||
reagents.trans_to(target, amount_per_transfer_from_this)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/carbon_target = target
|
||||
if(length(carbon_target.viruses))
|
||||
AddComponent(/datum/component/viral_contamination, carbon_target.viruses)
|
||||
to_chat(user, "<span class='notice'>You inject [amount_per_transfer_from_this] units of the solution. The syringe now contains [reagents.total_volume] units.</span>")
|
||||
if(reagents.total_volume <= 0 && mode == SYRINGE_INJECT)
|
||||
mode = SYRINGE_DRAW
|
||||
|
||||
Reference in New Issue
Block a user