diff --git a/__DEFINES/reagents.dm b/__DEFINES/reagents.dm
index 73337f8ca05..f3c29f1885c 100644
--- a/__DEFINES/reagents.dm
+++ b/__DEFINES/reagents.dm
@@ -96,7 +96,9 @@
#define CRYOXADONE "cryoxadone"
#define CLONEXADONE "clonexadone"
#define REZADONE "rezadone"
+#define PLACEBO "placebo"
#define SPACEACILLIN "spaceacillin"
+#define NANOFLOXACIN "nanofloxacin"
#define CARPOTOXIN "carpotoxin"
#define ZOMBIEPOWDER "zombiepowder"
#define MINDBREAKER "mindbreaker"
diff --git a/__DEFINES/role_datums_defines.dm b/__DEFINES/role_datums_defines.dm
index 001f76fe56e..b298e46fe54 100644
--- a/__DEFINES/role_datums_defines.dm
+++ b/__DEFINES/role_datums_defines.dm
@@ -17,6 +17,7 @@
#define VOXSHOAL "vox Shoal"
#define BLOBCONGLOMERATE "blob conglomerate"
#define CLOCKWORK "clockwork"
+#define PLAGUEMICE "plague mice invasion"
//-------
#define HIVEMIND "changeling hivemind"
#define WIZFEDERATION "wizard federation"
@@ -59,6 +60,7 @@
#define GRINCH "The Grinch"
#define CATBEAST "loose catbeast"
#define RAMBLER "soul rambler"
+#define PLAGUEMOUSE "plague mouse"
#define GREET_DEFAULT "default"
#define GREET_ROUNDSTART "roundstart"
diff --git a/__DEFINES/setup.dm b/__DEFINES/setup.dm
index ef71dc1939b..06fc65ea6cf 100644
--- a/__DEFINES/setup.dm
+++ b/__DEFINES/setup.dm
@@ -976,7 +976,40 @@ var/default_colour_matrix = list(1,0,0,0,\
#define INFECTION_LEVEL_TWO 500
#define INFECTION_LEVEL_THREE 1000
+//Diseases, Virus, Antigens
+#define SPREAD_BLOOD 1//can be extracted from the carrier's blood, all diseases have this by default.
+#define SPREAD_CONTACT 2//touching or bumping into someone may transmit the virus, virus can survive on items for a while. gloves lower the chance of transmission.
+#define SPREAD_AIRBORNE 4//carrier mobs will periodically release invisible clouds that carry the virus to adjacent mobs that can breath it.
+#define EFFECT_DANGER_HELPFUL "0"
+#define EFFECT_DANGER_FLAVOR "1"
+#define EFFECT_DANGER_ANNOYING "2"
+#define EFFECT_DANGER_HINDRANCE "3"
+#define EFFECT_DANGER_HARMFUL "4"
+#define EFFECT_DANGER_DEADLY "5"
+
+#define ANTIGEN_BLOOD "blood"
+#define ANTIGEN_COMMON "common"
+#define ANTIGEN_RARE "rare"
+#define ANTIGEN_ALIEN "alien"
+
+//blood antigens
+#define ANTIGEN_O "O"
+#define ANTIGEN_A "A"
+#define ANTIGEN_B "B"
+#define ANTIGEN_RH "Rh"
+//common antigens
+#define ANTIGEN_Q "Q"
+#define ANTIGEN_U "U"
+#define ANTIGEN_V "V"
+//rare antigens
+#define ANTIGEN_M "M"
+#define ANTIGEN_N "N"
+#define ANTIGEN_P "P"
+//alien antigens
+#define ANTIGEN_X "X"
+#define ANTIGEN_Y "Y"
+#define ANTIGEN_Z "Z"
//Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm
index 367e99dcacc..2004f62641b 100644
--- a/code/_onclick/hud/fullscreen.dm
+++ b/code/_onclick/hud/fullscreen.dm
@@ -171,3 +171,8 @@
icon_state = "white"
layer = BLIND_LAYER
alpha = 0
+
+/obj/abstract/screen/fullscreen/science
+ icon = 'icons/mob/screen1.dmi'
+ screen_loc = "WEST,SOUTH to EAST,NORTH"
+ icon_state = "science"
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index adb91b25bb6..904cd04ecc6 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -149,7 +149,8 @@
if(ismob(D))
body += {"Give Spell
- Give Disease
+ Give Old Disease
+ Give New Disease
Inflict Cancer
Toggle Godmode
Toggle Build Mode
@@ -611,7 +612,19 @@ function loadPage(list) {
return
src.give_disease(M)
- href_list["datumrefresh"] = href_list["give_spell"]
+ href_list["datumrefresh"] = href_list["give_disease"]
+
+ else if(href_list["give_disease2"])
+ if(!check_rights(R_ADMIN|R_FUN|R_DEBUG))
+ return
+
+ var/mob/living/M = locate(href_list["give_disease2"])
+ if(!M.can_be_infected())
+ to_chat(usr, "This mob cannot be infected.")
+ return
+
+ virus2_make_custom(src,M)
+ href_list["datumrefresh"] = href_list["give_disease2"]
else if(href_list["addcancer"])
if(!check_rights(R_FUN))
@@ -785,10 +798,10 @@ function loadPage(list) {
if(!istype(A))
to_chat(usr, "This can only be done to instances of movable atoms.")
return
-
+
var/turf/origin = get_turf(A)
var/turf/T = get_turf(usr)
-
+
if(istype(A,/mob))
var/mob/M = A
M.teleport_to(T)
diff --git a/code/datums/gamemode/dynamic/dynamic_rulesets_midround.dm b/code/datums/gamemode/dynamic/dynamic_rulesets_midround.dm
index ff94da08158..ab396cb6bfa 100644
--- a/code/datums/gamemode/dynamic/dynamic_rulesets_midround.dm
+++ b/code/datums/gamemode/dynamic/dynamic_rulesets_midround.dm
@@ -102,7 +102,7 @@
continue
message_admins("DEBUG: Selected [applicant] for rule.")
- var/mob/living/carbon/human/new_character = applicant
+ var/mob/new_character = applicant
if (makeBody)
new_character = generate_ruleset_body(applicant)
@@ -542,3 +542,35 @@
message_admins("Rejected catbeast ruleset. Not enough threat somehow??")
return FALSE
return TRUE
+
+//////////////////////////////////////////////
+// //
+// PLAGUE MICE ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/midround/from_ghosts/faction_based/plague_mice
+ name = "Plague Mice Invasion"
+ role_category = /datum/role/plague_mouse
+ enemy_jobs = list("Chief Medical Officer", "Medical Doctor", "Virologist")
+ required_enemies = list(2,2,2,2,2,2,2,2,2,2)
+ required_candidates = 1
+ var/max_candidates = 5
+ weight = 5
+ cost = 25
+ requirements = list(90,70,50,40,30,20,10,10,10,10)
+ high_population_requirement = 40
+ flags = MINOR_RULESET
+ my_fac = /datum/faction/plague_mice
+ logo = "plague-logo"
+
+/datum/dynamic_ruleset/midround/from_ghosts/faction_based/plague_mice/generate_ruleset_body(var/mob/applicant)
+ var/datum/faction/plague_mice/active_fac = find_active_faction_by_type(my_fac)
+ var/mob/living/simple_animal/mouse/plague/new_mouse = new (active_fac.invasion)
+ new_mouse.key = applicant.key
+ return new_mouse
+
+/datum/dynamic_ruleset/midround/from_ghosts/faction_based/plague_mice/setup_role(var/datum/role/new_role)
+ my_fac.HandleRecruitedRole(new_role)
+ new_role.Greet(GREET_DEFAULT)
+ new_role.AnnounceObjectives()
diff --git a/code/datums/gamemode/factions/bloodcult/bloodcult.dm b/code/datums/gamemode/factions/bloodcult/bloodcult.dm
index 03dcbfe44ef..629ab20db4c 100644
--- a/code/datums/gamemode/factions/bloodcult/bloodcult.dm
+++ b/code/datums/gamemode/factions/bloodcult/bloodcult.dm
@@ -134,10 +134,10 @@ var/veil_thickness = CULT_PROLOGUE
var/warning = FALSE
var/list/cult_reminders = list()
-
+
/datum/faction/bloodcult/check_win()
return cult_win
-
+
/datum/faction/bloodcult/IsSuccessful()
return cult_win
@@ -525,7 +525,7 @@ var/veil_thickness = CULT_PROLOGUE
data[BLOODCOST_LID_CONTAINER] = 1
var/mob/living/silicon/robot/robot_user = user
- if(istype(robot_user))
+ if(istype(robot_user))
var/module_items = robot_user.get_equipped_items() //This function allows robot modules to be used as blood sources. Somewhat important, considering silicons have no blood.
for(var/obj/item/weapon/gripper/G_held in module_items)
if (!istype(G_held) || !G_held.wrapped || !istype(G_held.wrapped,/obj/item/weapon/reagent_containers))
@@ -545,11 +545,11 @@ var/veil_thickness = CULT_PROLOGUE
if (amount_gathered >= amount_needed)
data[BLOODCOST_RESULT] = BLOODCOST_TARGET_HELD
return data
-
+
for(var/obj/item/weapon/reagent_containers/G_held in module_items)
if (!istype(G_held) || !round(G_held.reagents.get_reagent_amount(BLOOD)))
continue
-
+
if(istype(G_held, /obj/item/weapon/reagent_containers/blood)) //Bloodbags have their own functionality
var/obj/item/weapon/reagent_containers/blood/blood_pack = G_held
var/blood_volume = round(blood_pack.reagents.get_reagent_amount(BLOOD))
@@ -579,12 +579,12 @@ var/veil_thickness = CULT_PROLOGUE
if (amount_gathered >= amount_needed)
data[BLOODCOST_RESULT] = BLOODCOST_TARGET_HELD
return data
-
+
if (amount_gathered >= amount_needed)
data[BLOODCOST_RESULT] = BLOODCOST_TARGET_CONTAINER
return data
- //Does the user have blood? (the user can pay in blood without having to bleed first)
+ //Does the user have blood? (the user can pay in blood without having to bleed first)
if(istype(H_user) && !(H_user.species.flags & NO_BLOOD))
var/blood_volume = round(H_user.vessel.get_reagent_amount(BLOOD))
var/blood_gathered = min(amount_needed-amount_gathered,blood_volume)
@@ -594,8 +594,8 @@ var/veil_thickness = CULT_PROLOGUE
if (amount_gathered >= amount_needed)
data[BLOODCOST_RESULT] = BLOODCOST_TARGET_USER
- return data
-
+ return data
+
data[BLOODCOST_RESULT] = BLOODCOST_FAILURE
return data
diff --git a/code/datums/gamemode/factions/plague_mice.dm b/code/datums/gamemode/factions/plague_mice.dm
new file mode 100644
index 00000000000..cf0281e16d2
--- /dev/null
+++ b/code/datums/gamemode/factions/plague_mice.dm
@@ -0,0 +1,121 @@
+
+/datum/faction/plague_mice
+ name = PLAGUEMICE
+ ID = PLAGUEMICE
+ logo_state = "plague-logo"
+ hud_icons = list("plague-logo")
+
+ initroletype = /datum/role/plague_mouse
+ initial_role = PLAGUEMOUSE
+
+ roletype = /datum/role/plague_mouse
+ late_role = PLAGUEMOUSE
+
+ var/diseaseID = ""
+ var/datum/disease2/disease/bacteria/plague
+ var/turf/invasion
+
+
+/datum/faction/plague_mice/New()
+ ..()
+ SetupDisease()
+ forgeObjectives()
+
+/datum/faction/plague_mice/HandleRecruitedRole(var/datum/role/R)
+ . = ..()
+ if (!plague)
+ SetupDisease()
+
+ var/mob/living/simple_animal/mouse/plague/M = R.antag.current
+ M.infect_disease2(plague,1, "Plague Mice")
+
+/datum/faction/plague_mice/OnPostSetup()
+ if (!plague || !invasion)
+ SetupDisease()
+
+ if (invasion)
+ for(var/datum/role/plague_mouse/M in members)
+ var/datum/mind/mouse_mind = M.antag
+ mouse_mind.current.forceMove(invasion)
+
+ spawn(1 MINUTES)
+ if(members.len > 0)
+ command_alert("A horde of black mice carriers of a dangerous bacteria have invaded the station. It is not clear how they got onboard, but they need to be either captured into small cages or exterminated, and any contaminated invividual is to cooperate with the medical staff for the preparation of a cure.", "The Black Plague is upon us!",1)
+
+
+/datum/faction/plague_mice/proc/SetupDisease()
+ if (!plague)
+ plague = new
+
+ var/list/anti = list(
+ ANTIGEN_BLOOD = 0,
+ ANTIGEN_COMMON = 1,
+ ANTIGEN_RARE = 2,
+ ANTIGEN_ALIEN = 0,
+ )
+ var/list/bad = list(
+ EFFECT_DANGER_HELPFUL = 0,
+ EFFECT_DANGER_FLAVOR = 0,
+ EFFECT_DANGER_ANNOYING = 1,
+ EFFECT_DANGER_HINDRANCE = 1,
+ EFFECT_DANGER_HARMFUL = 2,
+ EFFECT_DANGER_DEADLY = 3,
+ )
+ plague.origin = "Black Plague"
+
+ plague.spread = SPREAD_BLOOD|SPREAD_CONTACT|SPREAD_AIRBORNE//gotta ensure that our mice can spread that disease
+
+ plague.color = "#ADAEAA"
+ plague.pattern = 3
+ plague.pattern_color = "#EE9A9C"
+
+ plague.makerandom(list(80,100),list(25,50),anti,bad,null)
+
+ diseaseID = "[plague.uniqueID]-[plague.subID]"
+
+ if (!invasion)
+ var/list/found_vents = list()
+ for(var/obj/machinery/atmospherics/unary/vent_pump/v in atmos_machines)
+ if(!v.welded && v.z == STATION_Z && v.canSpawnMice==1) // No more spawning in atmos. Assuming the mappers did their jobs, anyway.
+ found_vents.Add(v)
+ if(found_vents.len)
+ invasion = get_turf(pick(found_vents))
+ else
+ var/area/kitchen = locate(/area/crew_quarters/kitchen)
+ var/list/turf/simulated/floor/floors = list()
+ for(var/turf/simulated/floor/F in kitchen)
+ floors += F
+ if(!F.has_dense_content())
+ invasion = F//if by some crazy chance there's no available vent where to spawn at, let's just pick the first empty floor in the kitchen
+ return
+ invasion = pick(floors)//or any floor really. And if your station has no kitchen then you don't deserve those mice.
+
+/datum/faction/plague_mice/forgeObjectives()
+ if (!plague)
+ SetupDisease()
+
+ if (AppendObjective(/datum/objective/plague))
+ var/datum/objective/plague/O = locate() in objective_holder.objectives
+ O.diseaseID = diseaseID
+
+/datum/faction/plague_mice/update_hud_icons(var/offset = 0,var/factions_with_icons = 0)
+ //let's remove every icons
+ for(var/datum/role/R in members)
+ if(R.antag && R.antag.current && R.antag.current.client)
+ for(var/image/I in R.antag.current.client.images)
+ if(I.icon_state in hud_icons)
+ R.antag.current.client.images -= I
+
+ //then re-add them
+ for(var/datum/role/R in members)
+ if(R.antag && R.antag.current && R.antag.current.client && R.antag.GetRole(R.id))
+ for (var/mob/living/L in mob_list)//except instead of just tracking our fellow plague mice, let's track everyone that's been infected with our plague
+ if (diseaseID in L.virus2)
+ var/imageloc = L
+ if(istype(L.loc,/obj/mecha))
+ imageloc = L.loc
+ var/image/I = image('icons/role_HUD_icons.dmi', loc = imageloc, icon_state = logo_state)
+ I.pixel_x = 20 * PIXEL_MULTIPLIER
+ I.pixel_y = 20 * PIXEL_MULTIPLIER
+ I.plane = ANTAG_HUD_PLANE
+ R.antag.current.client.images += I
diff --git a/code/datums/gamemode/objectives/plague.dm b/code/datums/gamemode/objectives/plague.dm
new file mode 100644
index 00000000000..eac00851e79
--- /dev/null
+++ b/code/datums/gamemode/objectives/plague.dm
@@ -0,0 +1,25 @@
+/datum/objective/plague
+ name = "Spread your disease."
+ explanation_text = "Spread your disease among the station's inhabitants."
+ var/diseaseID = ""
+ var/total_infections = 0
+
+/datum/objective/plague/extraInfo()
+ var/current_infections = 0
+ for (var/mob/living/L in mob_list)
+ if (diseaseID in L.virus2)
+ current_infections++
+ explanation_text += " ([total_infections] infections caused in total. [current_infections] infected individuals remaining.)"
+
+/datum/objective/plague/IsFulfilled()
+ if (..())
+ return TRUE
+
+ if (total_infections > 1)
+ for (var/mob/living/L in mob_list)
+ if (L.locked_to && istype(L.locked_to, /obj/item/critter_cage))//mice in cages are "safe"
+ continue
+ if (diseaseID in L.virus2)
+ return TRUE//if we infected at least one individual, and there is still an infected individual alive, that's good enough.
+
+ return FALSE
diff --git a/code/datums/gamemode/role/catbeast.dm b/code/datums/gamemode/role/catbeast.dm
index 824f5946450..3db63a6c1b4 100644
--- a/code/datums/gamemode/role/catbeast.dm
+++ b/code/datums/gamemode/role/catbeast.dm
@@ -13,6 +13,8 @@
/datum/role/catbeast/Greet()
to_chat(antag.current, "You are a mangy catbeast! ")
to_chat(antag.current, "The longer you avoid the crew, the greater danger the station will attract! You will generate threat for each new room you enter and for being alive (up to 5 minutes).")
+ to_chat(antag.current, "The diseases you are carrying were added to your notes. ")
+
/datum/role/catbeast/OnPostSetup()
var/mob/living/carbon/human/H = antag.current
@@ -20,6 +22,7 @@
H.my_appearance.s_tone = CATBEASTBLACK
H.dna.ResetUI()
equip_catbeast(H)
+ infect_catbeast(H)
H.regenerate_icons()
var/datum/gamemode/dynamic/D = ticker.mode
if(istype(D))
@@ -34,6 +37,38 @@ var/list/catbeast_names = list("Meowth","Fluffy","Subject 246","Experiment 35a",
"Lurks-In-Shadows","Eartha Kitt","Target Practice","Fresh Meat","Ca'thulu","Furry Fury","Vore-Strikes-Back","Killing Machine","Uncle Tom",
"Nine Lives", "Bad Luck", "Siamese Sam", "Tom Tabby", "Hairball", "Throws-Dice-Poorly", "Wizard Apprentice", "Lynch Lynx", "Felix")
+/datum/role/catbeast/proc/infect_catbeast(var/mob/living/carbon/human/H)
+ var/list/anti = list(
+ ANTIGEN_BLOOD = 0,
+ ANTIGEN_COMMON = 1,
+ ANTIGEN_RARE = 2,
+ ANTIGEN_ALIEN = 0,
+ )
+ var/list/bad = list(
+ EFFECT_DANGER_HELPFUL = 0,
+ EFFECT_DANGER_FLAVOR = 1,
+ EFFECT_DANGER_ANNOYING = 2,
+ EFFECT_DANGER_HINDRANCE = 3,
+ EFFECT_DANGER_HARMFUL = 3,
+ EFFECT_DANGER_DEADLY = 1,
+ )
+
+ var/first_virus_choice = pick(subtypesof(/datum/disease2/disease))
+ var/datum/disease2/disease/D1 = new first_virus_choice
+ D1.origin = "Loose Catbeast"
+ D1.makerandom(list(60,90),list(50,90),anti,bad,null)
+ H.infect_disease2(D1,1, "Loose Catbeast")
+ var/second_virus_choice = pick(subtypesof(/datum/disease2/disease))
+ var/datum/disease2/disease/D2 = new second_virus_choice
+ D2.origin = "Loose Catbeast"
+ D2.makerandom(list(60,90),list(50,90),anti,bad,null)
+ H.infect_disease2(D2,1, "Loose Catbeast")
+ antag.store_memory("
")
+ antag.store_memory(D1.get_info())
+ antag.store_memory(" ")
+ antag.store_memory(D2.get_info())
+ antag.store_memory(" ")
+
/proc/equip_catbeast(var/mob/living/carbon/human/H)
var/list/shirts = list(/obj/item/clothing/under/overalls,/obj/item/clothing/under/schoolgirl,/obj/item/clothing/under/darkholme,/obj/item/clothing/under/maid,
/obj/item/clothing/under/rottensuit,/obj/item/clothing/under/rank/mailman,/obj/item/clothing/under/color/prisoner,/obj/item/clothing/under/psyche,
diff --git a/code/datums/gamemode/role/plague_mouse.dm b/code/datums/gamemode/role/plague_mouse.dm
new file mode 100644
index 00000000000..ca92e804cf9
--- /dev/null
+++ b/code/datums/gamemode/role/plague_mouse.dm
@@ -0,0 +1,17 @@
+
+/datum/role/plague_mouse
+ name = PLAGUEMOUSE
+ id = PLAGUEMOUSE
+ special_role = PLAGUEMOUSE
+ required_pref = ROLE_MINOR
+ wikiroute = ROLE_MINOR
+ logo_state = "plague-logo"
+ greets = list(GREET_DEFAULT)
+
+datum/role/plague_mouse/Greet(var/greeting,var/custom)
+ if(!greeting)
+ return
+
+ var/icon/logo = icon('icons/logos.dmi', logo_state)
+ to_chat(antag.current, " You are a [name]! Carrier of a dangerous Bacteria! Try and spread your contagion across the station! ")
+
diff --git a/code/datums/helper_datums/command_alerts.dm b/code/datums/helper_datums/command_alerts.dm
index ab77fc63bf0..a9afa63ff59 100644
--- a/code/datums/helper_datums/command_alerts.dm
+++ b/code/datums/helper_datums/command_alerts.dm
@@ -20,9 +20,11 @@
force_report = 1
var/level = 1
+ var/level_max = 7
+ var/level_min = 4
/datum/command_alert/biohazard_alert/announce()
- level = rand(4,7)
+ level = rand(level_min,level_max)
message = "Confirmed outbreak of level [level] biohazard aboard [station_name()]. All personnel must contain the outbreak."
..()
@@ -36,6 +38,15 @@
for(var/word in vox_sentence)
play_vox_sound(word,STATION_Z,null)
+/datum/command_alert/biohazard_alert/minor
+ level_max = 4
+ level_min = 2
+
+/datum/command_alert/biohazard_alert/major
+ level_max = 7
+ level_min = 5
+
+
///////BIOHAZARD UPDATED
/datum/command_alert/biohazard_station_lockdown
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 6bc2ec2ed66..1c5c135e4d6 100755
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -1185,7 +1185,7 @@ var/list/all_supply_groups = list("Supplies","Clothing","Security","Hospitality"
containertype = /obj/structure/largecrate
containername = "bartending equipment crate"
group = "Hospitality"
-
+
/datum/supply_packs/bar/post_creation(var/atom/movable/container)
var/obj/structure/closet/crate/flatpack/flatpack1 = locate(/obj/structure/closet/crate/flatpack/soda_dispenser/) in container
var/obj/structure/closet/crate/flatpack/flatpack2 = locate(/obj/structure/closet/crate/flatpack/booze_dispenser/) in container
@@ -1482,12 +1482,12 @@ var/list/all_supply_groups = list("Supplies","Clothing","Security","Hospitality"
containername = "Starscreen shield generator crate"
group = "Engineering"
access = list(access_engine)
-
+
/datum/supply_packs/shield_gen/post_creation(var/atom/movable/container)
var/obj/structure/closet/crate/flatpack/flatpack1 = locate(/obj/structure/closet/crate/flatpack/starscreen_generator/) in container
var/obj/structure/closet/crate/flatpack/flatpack2 = locate(/obj/structure/closet/crate/flatpack/starscreen_capacitor/) in container
flatpack1.add_stack(flatpack2)
-
+
/datum/supply_packs/shield_gen_ex
contains = list(/obj/structure/closet/crate/flatpack/starscreen_ex_generator,
/obj/structure/closet/crate/flatpack/starscreen_capacitor)
@@ -1497,7 +1497,7 @@ var/list/all_supply_groups = list("Supplies","Clothing","Security","Hospitality"
containername = "Starscreen-EX shield generator crate"
group = "Engineering"
access = list(access_engine)
-
+
/datum/supply_packs/shield_gen_ex/post_creation(var/atom/movable/container)
var/obj/structure/closet/crate/flatpack/flatpack1 = locate(/obj/structure/closet/crate/flatpack/starscreen_ex_generator/) in container
var/obj/structure/closet/crate/flatpack/flatpack2 = locate(/obj/structure/closet/crate/flatpack/starscreen_capacitor/) in container
@@ -1660,7 +1660,7 @@ var/list/all_supply_groups = list("Supplies","Clothing","Security","Hospitality"
/obj/item/weapon/virusdish/random)
cost = 25
containertype = "/obj/structure/closet/crate/secure/medsec"
- containername = "virus crate"
+ containername = "disease crate"
access = list(access_biohazard)
group = "Medical"
@@ -1777,6 +1777,17 @@ var/list/all_supply_groups = list("Supplies","Clothing","Security","Hospitality"
containername = "Regular Biosuits"
group = "Medical"
+/datum/supply_packs/mouse
+ name = "Laboratory mice and cages"
+ contains = list (
+ /obj/item/critter_cage,
+ /obj/item/critter_cage,
+ /obj/item/weapon/storage/box/monkeycubes/mousecubes,)
+ cost = 20
+ containertype = /obj/structure/closet/crate/freezer
+ containername = "lab mouse crate"
+ group = "Medical"
+
//////SCIENCE//////
/datum/supply_packs/research_parts
diff --git a/code/defines/procs/biohazard_alert.dm b/code/defines/procs/biohazard_alert.dm
index 079a509e6e7..2f988d4b69c 100644
--- a/code/defines/procs/biohazard_alert.dm
+++ b/code/defines/procs/biohazard_alert.dm
@@ -7,9 +7,15 @@ var/global/list/outbreak_level_words=list(
/* 6 */ 'sound/vox_fem/six.ogg',
/* 7 */ 'sound/vox_fem/seven.ogg',
)
-/proc/biohazard_alert(var/level=0)
+/proc/biohazard_alert()
command_alert(/datum/command_alert/biohazard_alert)
+/proc/biohazard_alert_minor()
+ command_alert(/datum/command_alert/biohazard_alert/minor)
+
+/proc/biohazard_alert_major()
+ command_alert(/datum/command_alert/biohazard_alert/major)
+
/*
#warn TELL N3X15 TO COMMENT THIS SHIT OUT
/mob/verb/test_biohazard()
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 0f96fa83ccd..7c8dec1b602 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -803,6 +803,7 @@ its easier to just keep the beam vertical.
this = new /obj/effect/decal/cleanable/vomit/active(src)
else
this = new /obj/effect/decal/cleanable/vomit(src)
+ this.virus2 += virus_copylist(M.virus2)
// Make toxins vomit look different
if(toxvomit)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 35796b6def1..44fc0b9d9b2 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -1002,9 +1002,9 @@
/atom/movable/proc/setPixelOffsetsFromParams(params, mob/user, base_pixx = 0, base_pixy = 0, clamp = TRUE)
if(anchored)
- return
+ return 0
if(user && (!Adjacent(user) || !src.Adjacent(user) || user.incapacitated() || !src.can_be_pulled(user)))
- return
+ return 0
var/list/params_list = params2list(params)
if(clamp)
pixel_x = Clamp(base_pixx + text2num(params_list["icon-x"]) - WORLD_ICON_SIZE/2, -WORLD_ICON_SIZE/2, WORLD_ICON_SIZE/2)
@@ -1012,6 +1012,7 @@
else
pixel_x = base_pixx + text2num(params_list["icon-x"]) - WORLD_ICON_SIZE/2
pixel_y = base_pixy + text2num(params_list["icon-y"]) - WORLD_ICON_SIZE/2
+ return 1
//Overwriting BYOND proc used for simple animal and NPCbot movement, Pomf help me
/atom/movable/proc/start_walk_to(Trg,Min=0,Lag=0,Speed=0)
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index ec74a2d21c2..7f2fcff635c 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -46,9 +46,37 @@ proc/process_med_hud(var/mob/M, var/mob/eye)
T = get_turf(eye)
else
T = get_turf(M)
- for(var/mob/living/carbon/human/patient in range(T))
- if(patient.head && istype(patient.head,/obj/item/clothing/head/tinfoil)) //Tinfoil hat? Move along.
+ for(var/mob/living/simple_animal/mouse/patient in range(T))
+ if(!check_HUD_visibility(patient, M))
continue
+ if(!C)
+ continue
+ holder = patient.hud_list[STATUS_HUD]
+ if(holder)
+ if(patient.isDead())
+ holder.icon_state = "huddead"
+ else if(patient.status_flags & XENO_HOST)
+ holder.icon_state = "hudxeno"
+ else if(has_any_recorded_disease(patient))
+ if (has_recorded_disease(patient))
+ holder.icon_state = "hudill_old"
+ else
+ holder.icon_state = "hudill"
+ var/dangerosity = has_recorded_virus2(patient)
+ switch (dangerosity)
+ if (2)
+ holder.icon_state = "hudill_safe"
+ if (3)
+ holder.icon_state = "hudill_danger"
+ else
+ holder.icon_state = "hudhealthy"
+ C.images += holder
+
+ for(var/mob/living/carbon/patient in range(T))
+ if (ishuman(patient))
+ var/mob/living/carbon/human/H = patient
+ if(H.head && istype(H.head,/obj/item/clothing/head/tinfoil)) //Tinfoil hat? Move along.
+ continue
if(!check_HUD_visibility(patient, M))
continue
if(!C)
@@ -70,14 +98,24 @@ proc/process_med_hud(var/mob/M, var/mob/eye)
else if(patient.status_flags & XENO_HOST)
holder.icon_state = "hudxeno"
else if(has_any_recorded_disease(patient))
- holder.icon_state = "hudill"
+ if (has_recorded_disease(patient))
+ holder.icon_state = "hudill_old"
+ else
+ holder.icon_state = "hudill"
+ var/dangerosity = has_recorded_virus2(patient)
+ switch (dangerosity)
+ if (2)
+ holder.icon_state = "hudill_safe"
+ if (3)
+ holder.icon_state = "hudill_danger"
else
holder.icon_state = "hudhealthy"
C.images += holder
holder = patient.hud_list[RECORD_HUD]
- if(holder)
- var/targetname = patient.get_identification_name(patient.get_face_name())
+ if(holder && ishuman(patient))
+ var/mob/living/carbon/human/H = patient
+ var/targetname = H.get_identification_name(H.get_face_name())
var/medical = null
var/datum/data/record/gen_record = data_core.find_general_record_by_name(targetname)
if(gen_record)
diff --git a/code/game/dna/genes/goon_disabilities.dm b/code/game/dna/genes/goon_disabilities.dm
index 2ce66fac8cb..547a16a25a7 100644
--- a/code/game/dna/genes/goon_disabilities.dm
+++ b/code/game/dna/genes/goon_disabilities.dm
@@ -390,14 +390,14 @@
H.regenerate_icons()
H.visible_message("[H.name]'s flesh melts right off! Holy shit! ")
H.drop_all()
- gibs(H.loc, H.viruses, H.dna)
+ gibs(H.loc, H.virus2, H.dna)
return
if(H.set_species("Skellington"))
H.regenerate_icons()
H.visible_message("[H.name]'s flesh melts right off! Holy shit! ")
H.drop_all()
- gibs(H.loc, H.viruses, H.dna)
+ gibs(H.loc, H.virus2, H.dna)
else
M.visible_message("[usr.name] melts into a pile of bloody viscera! ")
M.drop_all()
diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm
index 9ab48f4d3cb..020a823c25d 100644
--- a/code/game/dna/genes/monkey.dm
+++ b/code/game/dna/genes/monkey.dm
@@ -70,6 +70,9 @@
O.viruses += D
D.affected_mob = O
M.viruses -= D
+ O.virus2 = virus_copylist(M.virus2)
+ if (M.immune_system)
+ M.immune_system.transfer_to(O)
//for(var/obj/T in M)
// del(T)
diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm
index 8e9cf62991f..d3cb973195f 100644
--- a/code/game/gamemodes/blob/blobs/factory.dm
+++ b/code/game/gamemodes/blob/blobs/factory.dm
@@ -93,12 +93,14 @@
maxbodytemp = 360
plane = BLOB_PLANE
layer = BLOB_SPORE_LAYER
+ var/looks = "new"
/mob/living/simple_animal/hostile/blobspore/New(loc, var/obj/effect/blob/factory/linked_node)
if(istype(linked_node))
factory = linked_node
factory.spores += src
icon = factory.icon
+ looks = factory.looks
..()
/mob/living/simple_animal/hostile/blobspore/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
@@ -120,6 +122,32 @@
qdel(src)
/mob/living/simple_animal/hostile/blobspore/Destroy()
+ //creating a pathogenic cloud upon death
+ anim(target = loc, a_icon = icon, flick_anim = "blob_act", sleeptime = 15, direction = SOUTH, lay = BLOB_SPORE_LAYER, plane = BLOB_PLANE)
+ if (!(looks in blob_diseases))
+ CreateBlobDisease(looks)
+ var/datum/disease2/disease/D = blob_diseases[looks]
+ var/list/L = list()
+ L["[D.uniqueID]-[D.subID]"] = D
+ getFromPool(/obj/effect/effect/pathogen_cloud,get_turf(src),null,virus_copylist(L),FALSE)
if(factory)
factory.spores -= src
..()
+
+/mob/living/simple_animal/hostile/blobspore/unarmed_attack_mob(var/mob/living/target)
+ . = ..()
+
+ if (.)
+ //if we damage our target, let's try and infect them
+ if (!(looks in blob_diseases))
+ CreateBlobDisease(looks)
+ var/datum/disease2/disease/D = blob_diseases[looks]
+
+ var/chance_to_infect = 100
+ if (target.check_contact_sterility(FULL_TORSO))//For simplicity's sake (for once), let's just assume that the blob strikes the torso.
+ chance_to_infect = 10//Even with perfect protection, those spores might get to you.
+ if (target.check_bodypart_bleeding(FULL_TORSO))
+ chance_to_infect = min(100, chance_to_infect + 10)
+
+ if (prob(chance_to_infect))
+ target.infect_disease2(D, notes="(Blob, from [src])")//still 5% chance to fail infection
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index 19a1ab1b472..37e6d2fdbb1 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -485,3 +485,47 @@ var/list/blob_looks_player = list(//Options available to players
else
if(health <= 15)
icon_state = "blob_damaged"
+
+///////////////////////BLOB SPORE DISEASE//////////////////////////////////
+var/list/blob_diseases = list()
+
+/proc/CreateBlobDisease(var/looks)
+ var/datum/disease2/disease/S = new
+ S.form = "Spores"
+ S.infectionchance = 95
+ S.infectionchance_base = 95
+ S.stageprob = 0//single-stage
+ S.stage_variance = 0
+ S.max_stage = 1
+ S.can_kill = list()
+
+ var/datum/disease2/effect/blob_spores/E = new /datum/disease2/effect/blob_spores
+ E.looks = looks
+ S.effects += E
+
+ S.antigen = list(pick(antigen_family(pick(ANTIGEN_RARE,ANTIGEN_ALIEN))))
+ S.antigen |= pick(antigen_family(pick(ANTIGEN_RARE,ANTIGEN_ALIEN)))
+
+ S.spread = SPREAD_BLOOD
+ S.uniqueID = rand(0,9999)
+ S.subID = rand(0,9999)
+
+ S.strength = rand(70,100)
+ S.robustness = 100
+
+ S.color = "#99CB99"
+ S.pattern = 2
+ S.pattern_color = "#FFC977"
+
+ log_debug("Creating Spores #[S.uniqueID]-[S.subID].")
+ S.log += " [timestamp()] Created "
+
+ S.origin = "Blob ([looks])"
+
+ S.mutation_modifier = 0
+
+ S.update_global_log()
+
+ blob_diseases[looks] = S
+
+///////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index b714f8cd159..9d4d21d1473 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -399,6 +399,7 @@ var/datum/controller/gameticker/ticker
else
data_core.manifest_inject(new_character)
player.FuckUpGenes(new_character)
+ player.DiseaseCarrierCheck(new_character)
qdel(player)
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index 355b3196dd0..96b8d98646e 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -258,6 +258,7 @@
H.put_in_hand(GRASP_RIGHT_HAND, new H.species.survival_gear(H))
else
H.equip_or_collect(new H.species.survival_gear(H.back), slot_in_backpack)
+ H.put_in_hands(new /obj/item/weapon/book/manual/virology_guide(H))
return 1
/datum/job/virologist/priority_reward_equip(var/mob/living/carbon/human/H)
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index deb54fa0d08..c6bd2640d06 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -15,6 +15,7 @@
/obj/item/weapon/stock_parts/scanning_module
)
var/mob/living/carbon/occupant
+ var/obj/item/device/antibody_scanner/immune
light_color = LIGHT_COLOR_GREEN
light_range_on = 3
@@ -26,12 +27,16 @@
/obj/machinery/bodyscanner/New()
..()
+ immune = new
if(map.nameShort == "deff")
icon = 'maps/defficiency/medbay.dmi'
RefreshParts()
/obj/machinery/bodyscanner/Destroy()
go_out() //Eject everything
+ if (immune)
+ qdel(immune)
+ immune = null
..()
/obj/machinery/bodyscanner/update_icon()
@@ -313,7 +318,13 @@
return
var/obj/item/weapon/paper/R = new(loc)
R.name = "paper - 'body scan report'"
- R.info = format_occupant_data(get_occupant_data())
+ R.info = format_occupant_data(get_occupant_data(),1)
+
+ else if(href_list["immunity"])
+ if(!immune)
+ immune = new
+ if (occupant)
+ immune.attack(occupant,usr)
/obj/machinery/bodyscanner/proc/get_occupant_data()
@@ -359,7 +370,7 @@
return occupant_data
-/obj/machinery/bodyscanner/proc/format_occupant_data(var/list/occ)
+/obj/machinery/bodyscanner/proc/format_occupant_data(var/list/occ,var/print_exceptions=0)
var/dat = "Scan performed at [occ["stationtime"]] "
dat += "Occupant Statistics: "
var/aux
@@ -371,8 +382,10 @@
else
aux = "Dead"
dat += text("[]\tHealth %: [] ([]) ", (occ["health"] > 50 ? "" : ""), occ["health"], aux)
+ if (!print_exceptions)
+ dat += "View Immune System scan "
if(occ["virus_present"])
- dat += "Viral pathogen detected in blood stream. "
+ dat += "Pathogen detected in blood stream. "
dat += text("[]\t-Brute Damage %: [] ", (occ["bruteloss"] < 60 ? "" : ""), occ["bruteloss"])
dat += text("[]\t-Respiratory Damage %: [] ", (occ["oxyloss"] < 60 ? "" : ""), occ["oxyloss"])
dat += text("[]\t-Toxin Content %: [] ", (occ["toxloss"] < 60 ? "" : ""), occ["toxloss"])
@@ -561,4 +574,4 @@
say("Now outputting diagnostic.")
var/obj/item/weapon/paper/R = new(src.loc)
R.name = "paper - 'body scan report'"
- R.info = format_occupant_data(get_occupant_data())
+ R.info = format_occupant_data(get_occupant_data(),1)
diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm
index 811a0f998ab..e470e9e2ded 100644
--- a/code/game/machinery/bots/medbot.dm
+++ b/code/game/machinery/bots/medbot.dm
@@ -451,8 +451,9 @@
reagent_id = TOXIN
var/virus = 0
- for(var/datum/disease/D in C.viruses)
- virus = 1
+ for(var/ID in C.virus2)
+ if (ID in virusDB)
+ virus = 1
if (!reagent_id && (virus))
if(!C.reagents.has_reagent(treatment_virus))
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index 2075a62e1ac..187ff5eff9a 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -78,11 +78,11 @@
name = "Circuit board (Medical Records)"
desc = "A circuit board for running a computer used for viewing medical records."
build_path = /obj/machinery/computer/med_data
-/obj/item/weapon/circuitboard/pandemic
- name = "Circuit board (PanD.E.M.I.C. 2200)"
- desc = "A circuit board for running a computer used in Virology."
- build_path = /obj/machinery/computer/pandemic
- origin_tech = Tc_PROGRAMMING + "=2;" + Tc_BIOTECH + "=2"
+///obj/item/weapon/circuitboard/pandemic
+// name = "Circuit board (PanD.E.M.I.C. 2200)"
+// desc = "A circuit board for running a computer used in Virology."
+// build_path = /obj/machinery/computer/pandemic
+// origin_tech = Tc_PROGRAMMING + "=2;" + Tc_BIOTECH + "=2"
/obj/item/weapon/circuitboard/scan_consolenew
name = "Circuit board (DNA Machine)"
desc = "A circuit board for running a computer used in Genetics."
@@ -273,11 +273,10 @@
desc = "A circuit board for running a computer used to manipulate telecommunications traffic."
build_path = /obj/machinery/computer/telecomms/traffic
origin_tech = Tc_PROGRAMMING + "=3"
-
-/obj/item/weapon/circuitboard/curefab
+/*/obj/item/weapon/circuitboard/curefab
name = "Circuit board (Cure fab)"
desc = "A circuit board for running a computer used to fabricate cures for virusses."
- build_path = /obj/machinery/computer/curer
+ build_path = /obj/machinery/computer/curer*/
/obj/item/weapon/circuitboard/splicer
name = "Circuit board (Disease Splicer)"
desc = "A circuit board for running a computer used to splice DNA strands in virusses."
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index 6953ab8f674..47c3d9fcb7c 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -18,28 +18,30 @@
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/med_data/attack_ai(user as mob)
- src.add_hiddenprint(user)
- return src.attack_hand(user)
+ add_hiddenprint(user)
+ return attack_hand(user)
/obj/machinery/computer/med_data/attack_paw(user as mob)
- return src.attack_hand(user)
+ return attack_hand(user)
-/obj/machinery/computer/med_data/attack_hand(mob/user as mob)
- if(..())
+/obj/machinery/computer/med_data/attack_hand(var/mob/user)
+ . = ..()
+
+ if(.)
return
var/dat
- if (src.temp)
- dat = text("[src.temp] Clear Screen ")
+ if (temp)
+ dat = text("[temp] Clear Screen ")
else
- dat = text("Confirm Identity: [] ", src, (src.scan ? text("[]", src.scan.name) : "----------"))
- if (src.authenticated)
- switch(src.screen)
+ dat = text("Confirm Identity: [] ", src, (scan ? text("[]", scan.name) : "----------"))
+ if (authenticated)
+ switch(screen)
if(1.0)
dat += {"
Search Records
List Records
-Virus Database
+Pathogen Database
Medbot Tracking
Record Maintenance
@@ -60,7 +62,7 @@
user << browse_rsc(front, "front.png")
user << browse_rsc(side, "side.png")
dat += " Medical Record "
- if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1)))
+ if ((istype(active1, /datum/data/record) && data_core.general.Find(active1)))
dat += "Name: [active1.fields["name"]] \
ID: [active1.fields["id"]] \n \
Sex: [active1.fields["sex"]] \n \
@@ -71,11 +73,11 @@
Photo:
"
else
dat += "General Record Lost! "
- if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2)))
- dat += text(" \nMedical Data \nBlood Type: [] \nDNA: [] \n \nMinor Disabilities: [] \nDetails: [] \n \nMajor Disabilities: [] \nDetails: [] \n \nAllergies: [] \nDetails: [] \n \nCurrent Diseases: [] (per disease info placed in log/comment section) \nDetails: [] \n \nImportant Notes: \n\t[] \n \nComments/Log ", src, src.active2.fields["b_type"], src, src.active2.fields["b_dna"], src, src.active2.fields["mi_dis"], src, src.active2.fields["mi_dis_d"], src, src.active2.fields["ma_dis"], src, src.active2.fields["ma_dis_d"], src, src.active2.fields["alg"], src, src.active2.fields["alg_d"], src, src.active2.fields["cdi"], src, src.active2.fields["cdi_d"], src, src.active2.fields["notes"])
+ if ((istype(active2, /datum/data/record) && data_core.medical.Find(active2)))
+ dat += text(" \nMedical Data \nBlood Type: [] \nDNA: [] \n \nMinor Disabilities: [] \nDetails: [] \n \nMajor Disabilities: [] \nDetails: [] \n \nAllergies: [] \nDetails: [] \n \nCurrent Diseases: [] (per disease info placed in log/comment section) \nDetails: [] \n \nImportant Notes: \n\t[] \n \nComments/Log ", src, active2.fields["b_type"], src, active2.fields["b_dna"], src, active2.fields["mi_dis"], src, active2.fields["mi_dis_d"], src, active2.fields["ma_dis"], src, active2.fields["ma_dis_d"], src, active2.fields["alg"], src, active2.fields["alg_d"], src, active2.fields["cdi"], src, active2.fields["cdi_d"], src, active2.fields["notes"])
var/counter = 1
- while(src.active2.fields[text("com_[]", counter)])
- dat += text("[]Delete Entry ", src.active2.fields[text("com_[]", counter)], src, counter)
+ while(active2.fields[text("com_[]", counter)])
+ dat += text("[]Delete Entry ", active2.fields[text("com_[]", counter)], src, counter)
counter++
dat += text("Add Entry ", src)
dat += text("Delete Record (Medical Only) ", src)
@@ -84,7 +86,7 @@
dat += text("New Record ")
dat += text("\nPrint Record \nBack ", src, src)
if(5.0)
- dat += "Virus Database "
+ dat += "Pathogen Database "
/* Advanced diseases is weak! Feeble! Glory to virus2!
for(var/Dt in typesof(/datum/disease/))
var/datum/disease/Dis = new Dt(0)
@@ -96,7 +98,7 @@
*/
for (var/ID in virusDB)
var/datum/data/record/v = virusDB[ID]
- dat += "[v.fields["name"]] "
+ dat += "[v.fields["name"]][v.fields["nickname"] ? " \"[v.fields["nickname"]]\"" : ""] "
dat += "Back "
if(6.0)
@@ -107,7 +109,7 @@
var/bdat = null
for(var/obj/machinery/bot/medbot/M in machines)
- if(M.z != src.z)
+ if(M.z != z)
continue //only find medibots on the same z-level as the computer
var/turf/bl = get_turf(M)
if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up
@@ -128,19 +130,30 @@
onclose(user, "med_rec")
return
+/obj/machinery/computer/med_data/proc/pathogen_dat(var/datum/data/record/v)
+ var/dat = "GNAv2 [v.fields["name"]][v.fields["nickname"] ? " \"[v.fields["nickname"]]\"" : ""] "
+ //temp += "Name: [v.fields["name"]] "
+ dat += "Nickname: [v.fields["nickname"] ? "[v.fields["nickname"]]" : "(input)"] "
+ dat += "Dangerousness: [v.fields["danger"]] "
+ dat += "Antigen: [v.fields["antigen"]]"
+ dat += "Spread: [v.fields["spread type"]] "
+ dat += "Details: [v.fields["description"]] "
+ dat += "Management: Delete "
+ return dat
+
/obj/machinery/computer/med_data/Topic(href, href_list)
if(..())
return
- if (!( data_core.general.Find(src.active1) ))
- src.active1 = null
- if (!( data_core.medical.Find(src.active2) ))
- src.active2 = null
- if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || isAdminGhost(usr) || (istype(usr, /mob/living/silicon)))
+ if (!( data_core.general.Find(active1) ))
+ active1 = null
+ if (!( data_core.medical.Find(active2) ))
+ active2 = null
+ if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || isAdminGhost(usr) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
if (href_list["temp"])
- src.temp = null
+ temp = null
if (href_list["scan"])
- if (src.scan)
+ if (scan)
if(ishuman(usr))
scan.forceMove(usr.loc)
@@ -151,19 +164,19 @@
scan = null
else
- src.scan.forceMove(src.loc)
- src.scan = null
+ scan.forceMove(loc)
+ scan = null
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
if(usr.drop_item(I, src))
- src.scan = I
+ scan = I
else if (href_list["logout"])
- src.authenticated = null
- src.screen = null
- src.active1 = null
- src.active2 = null
+ authenticated = null
+ screen = null
+ active1 = null
+ active2 = null
else if (href_list["login"])
if(isAdminGhost(usr))
@@ -174,247 +187,268 @@
screen = 1
if (istype(usr, /mob/living/silicon/ai))
- src.active1 = null
- src.active2 = null
- src.authenticated = usr.name
- src.rank = "AI"
- src.screen = 1
+ active1 = null
+ active2 = null
+ authenticated = usr.name
+ rank = "AI"
+ screen = 1
else if (istype(usr, /mob/living/silicon/robot))
- src.active1 = null
- src.active2 = null
- src.authenticated = usr.name
+ active1 = null
+ active2 = null
+ authenticated = usr.name
var/mob/living/silicon/robot/R = usr
- src.rank = "[R.modtype] [R.braintype]"
- src.screen = 1
+ rank = "[R.modtype] [R.braintype]"
+ screen = 1
- else if (istype(src.scan, /obj/item/weapon/card/id))
- src.active1 = null
- src.active2 = null
- if (src.check_access(src.scan))
- src.authenticated = src.scan.registered_name
- src.rank = src.scan.assignment
- src.screen = 1
- if (src.authenticated)
+ else if (istype(scan, /obj/item/weapon/card/id))
+ active1 = null
+ active2 = null
+ if (check_access(scan))
+ authenticated = scan.registered_name
+ rank = scan.assignment
+ screen = 1
+ if (authenticated)
if(href_list["screen"])
- src.screen = text2num(href_list["screen"])
- if(src.screen < 1)
- src.screen = 1
+ screen = text2num(href_list["screen"])
+ if(screen < 1)
+ screen = 1
- src.active1 = null
- src.active2 = null
+ active1 = null
+ active2 = null
if(href_list["vir"])
var/datum/data/record/v = locate(href_list["vir"])
- src.temp = "GNAv2 [v.fields["form"]] V-[v.fields["id"]] "
- src.temp += "Name: [v.fields["name"]] "
- src.temp += "Antigen: [v.fields["antigen"]]"
- src.temp += "Spread: [v.fields["spread type"]] "
- src.temp += "Details: [v.fields["description"]] "
- temp += "Management: Delete "
+ temp = pathogen_dat(v)
if (href_list["del_all"])
- src.temp = text("Are you sure you wish to delete all records? \n\tYes \n\tNo ", src, src)
+ temp = text("Are you sure you wish to delete all records? \n\tYes \n\tNo ", src, src)
if (href_list["del_all2"])
for(var/datum/data/record/R in data_core.medical)
qdel(R)
R = null
//Foreach goto(494)
- src.temp = "All records deleted."
+ temp = "All records deleted."
if (href_list["field"])
- var/a1 = src.active1
- var/a2 = src.active2
+ var/a1 = active1
+ var/a2 = active2
switch(href_list["field"])
if("fingerprint")
- if (istype(src.active1, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1))
+ if (istype(active1, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please input fingerprint hash:", "Med. records", active1.fields["fingerprint"], null) as text),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1))
return
- src.active1.fields["fingerprint"] = t1
+ active1.fields["fingerprint"] = t1
if("sex")
- if (istype(src.active1, /datum/data/record))
- if (src.active1.fields["sex"] == "Male")
- src.active1.fields["sex"] = "Female"
+ if (istype(active1, /datum/data/record))
+ if (active1.fields["sex"] == "Male")
+ active1.fields["sex"] = "Female"
else
- src.active1.fields["sex"] = "Male"
+ active1.fields["sex"] = "Male"
if("age")
- if (istype(src.active1, /datum/data/record))
- var/t1 = input("Please input age:", "Med. records", src.active1.fields["age"], null) as num
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1))
+ if (istype(active1, /datum/data/record))
+ var/t1 = input("Please input age:", "Med. records", active1.fields["age"], null) as num
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1))
return
- src.active1.fields["age"] = t1
+ active1.fields["age"] = t1
if("mi_dis")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please input minor disabilities list:", "Med. records", active2.fields["mi_dis"], null) as text),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
return
- src.active2.fields["mi_dis"] = t1
+ active2.fields["mi_dis"] = t1
if("mi_dis_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please summarize minor dis.:", "Med. records", active2.fields["mi_dis_d"], null) as message),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
return
- src.active2.fields["mi_dis_d"] = t1
+ active2.fields["mi_dis_d"] = t1
if("ma_dis")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please input major diabilities list:", "Med. records", active2.fields["ma_dis"], null) as text),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
return
- src.active2.fields["ma_dis"] = t1
+ active2.fields["ma_dis"] = t1
if("ma_dis_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please summarize major dis.:", "Med. records", active2.fields["ma_dis_d"], null) as message),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
return
- src.active2.fields["ma_dis_d"] = t1
+ active2.fields["ma_dis_d"] = t1
if("alg")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please state allergies:", "Med. records", active2.fields["alg"], null) as text),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
return
- src.active2.fields["alg"] = t1
+ active2.fields["alg"] = t1
if("alg_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please summarize allergies:", "Med. records", active2.fields["alg_d"], null) as message),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
return
- src.active2.fields["alg_d"] = t1
+ active2.fields["alg_d"] = t1
if("cdi")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please state diseases:", "Med. records", active2.fields["cdi"], null) as text),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
return
- src.active2.fields["cdi"] = t1
+ active2.fields["cdi"] = t1
if("cdi_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please summarize diseases:", "Med. records", active2.fields["cdi_d"], null) as message),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
return
- src.active2.fields["cdi_d"] = t1
+ active2.fields["cdi_d"] = t1
if("notes")
- if (istype(src.active2, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please summarize notes:", "Med. records", src.active2.fields["notes"], null) as message),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
+ if (istype(active2, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please summarize notes:", "Med. records", active2.fields["notes"], null) as message),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
return
- src.active2.fields["notes"] = t1
+ active2.fields["notes"] = t1
if("p_stat")
- if (istype(src.active1, /datum/data/record))
- src.temp = text("Physical Condition: \n\t*SSD* \n\t*Deceased* \n\t*Unconscious* \n\tActive \n\tPhysically Unfit ", src, src, src, src, src)
+ if (istype(active1, /datum/data/record))
+ temp = text("Physical Condition: \n\t*SSD* \n\t*Deceased* \n\t*Unconscious* \n\tActive \n\tPhysically Unfit ", src, src, src, src, src)
if("m_stat")
- if (istype(src.active1, /datum/data/record))
- src.temp = text("Mental Condition: \n\t*Insane* \n\t*Unstable* \n\t*Watch* \n\tStable ", src, src, src, src)
+ if (istype(active1, /datum/data/record))
+ temp = text("Mental Condition: \n\t*Insane* \n\t*Unstable* \n\t*Watch* \n\tStable ", src, src, src, src)
if("b_type")
- if (istype(src.active2, /datum/data/record))
- src.temp = text("Blood Type: \n\tA- A+ \n\tB- B+ \n\tAB- AB+ \n\tO- O+ ", src, src, src, src, src, src, src, src)
+ if (istype(active2, /datum/data/record))
+ temp = text("Blood Type: \n\tA- A+ \n\tB- B+ \n\tAB- AB+ \n\tO- O+ ", src, src, src, src, src, src, src, src)
if("b_dna")
- if (istype(src.active1, /datum/data/record))
- var/t1 = copytext(sanitize(input("Please input DNA hash:", "Med. records", src.active1.fields["dna"], null) as text),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1))
+ if (istype(active1, /datum/data/record))
+ var/t1 = copytext(sanitize(input("Please input DNA hash:", "Med. records", active1.fields["dna"], null) as text),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1))
return
- src.active1.fields["dna"] = t1
+ active1.fields["dna"] = t1
+ /*
if("vir_name")
var/datum/data/record/v = locate(href_list["edit_vir"])
if (v)
var/t1 = copytext(sanitize(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1))
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1))
return
v.fields["name"] = t1
+ */
+ if("vir_nickname")
+ var/datum/data/record/v = locate(href_list["edit_vir"])
+ if (v)
+ var/t1 = copytext(sanitize(input("Please input pathogen nickname:", "VirusDB", v.fields["nickname"], null) as text),1,MAX_MESSAGE_LEN)
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1))
+ return
+ v.fields["nickname"] = t1
+ temp = pathogen_dat(v)
if("vir_desc")
var/datum/data/record/v = locate(href_list["edit_vir"])
if (v)
var/t1 = copytext(sanitize(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1))
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1))
return
v.fields["description"] = t1
+ temp = pathogen_dat(v)
+ if("danger_vir")
+ var/datum/data/record/v = locate(href_list["edit_vir"])
+ if (v)
+ temp = text("Pathogen Dangerousness: \n\t*DANGEROUS* \n\tUndetermined \n\tSafe ", src, src, src)
if("del_vir")
var/datum/data/record/V = locate(href_list["del_vir"])
if(V)
- virusDB.Remove("[V.fields["id"]]")
+ virusDB.Remove("[V.fields["id"]]-[V.fields["sub"]]")
qdel(V)
- src.temp = "Record Deleted."
+ temp = "Record Deleted."
screen = 5
if (href_list["p_stat"])
- if (src.active1)
+ if (active1)
switch(href_list["p_stat"])
if("deceased")
- src.active1.fields["p_stat"] = "*Deceased*"
+ active1.fields["p_stat"] = "*Deceased*"
if("ssd")
- src.active1.fields["p_stat"] = "*SSD*"
+ active1.fields["p_stat"] = "*SSD*"
if("active")
- src.active1.fields["p_stat"] = "Active"
+ active1.fields["p_stat"] = "Active"
if("unfit")
- src.active1.fields["p_stat"] = "Physically Unfit"
+ active1.fields["p_stat"] = "Physically Unfit"
if("disabled")
- src.active1.fields["p_stat"] = "Disabled"
+ active1.fields["p_stat"] = "Disabled"
if (href_list["m_stat"])
- if (src.active1)
+ if (active1)
switch(href_list["m_stat"])
if("insane")
- src.active1.fields["m_stat"] = "*Insane*"
+ active1.fields["m_stat"] = "*Insane*"
if("unstable")
- src.active1.fields["m_stat"] = "*Unstable*"
+ active1.fields["m_stat"] = "*Unstable*"
if("watch")
- src.active1.fields["m_stat"] = "*Watch*"
+ active1.fields["m_stat"] = "*Watch*"
if("stable")
- src.active1.fields["m_stat"] = "Stable"
+ active1.fields["m_stat"] = "Stable"
if (href_list["b_type"])
- if (src.active2)
+ if (active2)
switch(href_list["b_type"])
if("an")
- src.active2.fields["b_type"] = "A-"
+ active2.fields["b_type"] = "A-"
if("bn")
- src.active2.fields["b_type"] = "B-"
+ active2.fields["b_type"] = "B-"
if("abn")
- src.active2.fields["b_type"] = "AB-"
+ active2.fields["b_type"] = "AB-"
if("on")
- src.active2.fields["b_type"] = "O-"
+ active2.fields["b_type"] = "O-"
if("ap")
- src.active2.fields["b_type"] = "A+"
+ active2.fields["b_type"] = "A+"
if("bp")
- src.active2.fields["b_type"] = "B+"
+ active2.fields["b_type"] = "B+"
if("abp")
- src.active2.fields["b_type"] = "AB+"
+ active2.fields["b_type"] = "AB+"
if("op")
- src.active2.fields["b_type"] = "O+"
+ active2.fields["b_type"] = "O+"
+ if (href_list["danger_vir"])
+ var/datum/data/record/v = locate(href_list["edit_vir"])
+ if (v)
+ switch(href_list["danger_vir"])
+ if("dangerous")
+ v.fields["danger"] = "*DANGEROUS*"
+ if("undetermined")
+ v.fields["danger"] = "Undetermined"
+ if("safe")
+ v.fields["danger"] = "Safe"
+ temp = pathogen_dat(v)
if (href_list["del_r"])
- if (src.active2)
- src.temp = text("Are you sure you wish to delete the record (Medical Portion Only)? \n\tYes \n\tNo ", src, src)
+ if (active2)
+ temp = text("Are you sure you wish to delete the record (Medical Portion Only)? \n\tYes \n\tNo ", src, src)
if (href_list["del_r2"])
- if (src.active2)
- qdel(src.active2)
- src.active2 = null
+ if (active2)
+ qdel(active2)
+ active2 = null
if (href_list["d_rec"])
var/datum/data/record/R = locate(href_list["d_rec"])
var/datum/data/record/M = locate(href_list["d_rec"])
if (!( data_core.general.Find(R) ))
- src.temp = "Record Not Found!"
+ temp = "Record Not Found!"
return
for(var/datum/data/record/E in data_core.medical)
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
M = E
else
//Foreach continue //goto(2540)
- src.active1 = R
- src.active2 = M
- src.screen = 4
+ active1 = R
+ active2 = M
+ screen = 4
if (href_list["new"])
- if ((istype(src.active1, /datum/data/record) && !( istype(src.active2, /datum/data/record) )))
+ if ((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) )))
var/datum/data/record/R = new /datum/data/record( )
- R.fields["name"] = src.active1.fields["name"]
- R.fields["id"] = src.active1.fields["id"]
+ R.fields["name"] = active1.fields["name"]
+ R.fields["id"] = active1.fields["id"]
R.name = text("Medical Record #[]", R.fields["id"])
R.fields["b_type"] = "Unknown"
R.fields["b_dna"] = "Unknown"
@@ -428,72 +462,72 @@
R.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
R.fields["notes"] = "No notes."
data_core.medical += R
- src.active2 = R
- src.screen = 4
+ active2 = R
+ screen = 4
if (href_list["add_c"])
- if (!( istype(src.active2, /datum/data/record) ))
+ if (!( istype(active2, /datum/data/record) ))
return
- var/a2 = src.active2
+ var/a2 = active2
var/t1 = copytext(sanitize(input("Add Comment:", "Med. records", null, null) as message),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
+ if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2))
return
var/counter = 1
- while(src.active2.fields[text("com_[]", counter)])
+ while(active2.fields[text("com_[]", counter)])
counter++
- src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [worldtime2text(give_seconds = TRUE)], [game_year] [t1]")
+ active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [worldtime2text(give_seconds = TRUE)], [game_year] [t1]")
if (href_list["del_c"])
- if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])]))
- src.active2.fields[text("com_[]", href_list["del_c"])] = "Deleted "
+ if ((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])]))
+ active2.fields[text("com_[]", href_list["del_c"])] = "Deleted "
if (href_list["search"])
var/norange = (usr.mutations && usr.mutations.len && (M_TK in usr.mutations))
var/t1 = copytext(sanitize(input("Search String: (Name, DNA, or ID)", "Med. records", null, null) as text),1,MAX_MESSAGE_LEN)
- if ((!( t1 ) || usr.stat || !( src.authenticated ) || usr.restrained() || ((!in_range(src, usr)) && (!istype(usr, /mob/living/silicon)) && !norange)))
+ if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || ((!in_range(src, usr)) && (!istype(usr, /mob/living/silicon)) && !norange)))
return
- src.active1 = null
- src.active2 = null
+ active1 = null
+ active2 = null
t1 = lowertext(t1)
for(var/datum/data/record/R in data_core.medical)
if ((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"])))
- src.active2 = R
+ active2 = R
else
//Foreach continue //goto(3229)
- if (!( src.active2 ))
- src.temp = text("Could not locate record [].", sanitize(t1))
+ if (!( active2 ))
+ temp = text("Could not locate record [].", sanitize(t1))
else
for(var/datum/data/record/E in data_core.general)
- if ((E.fields["name"] == src.active2.fields["name"] || E.fields["id"] == src.active2.fields["id"]))
- src.active1 = E
+ if ((E.fields["name"] == active2.fields["name"] || E.fields["id"] == active2.fields["id"]))
+ active1 = E
else
//Foreach continue //goto(3334)
- src.screen = 4
+ screen = 4
if (href_list["print_p"])
- if (!( src.printing ))
- src.printing = 1
+ if (!( printing ))
+ printing = 1
sleep(50)
- var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( src.loc )
+ var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc )
P.info = "Medical Record "
- if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1)))
- P.info += text("Name: [] ID: [] \nSex: [] \nAge: [] \nFingerprint: [] \nPhysical Status: [] \nMental Status: [] ", src.active1.fields["name"], src.active1.fields["id"], src.active1.fields["sex"], src.active1.fields["age"], src.active1.fields["fingerprint"], src.active1.fields["p_stat"], src.active1.fields["m_stat"])
+ if ((istype(active1, /datum/data/record) && data_core.general.Find(active1)))
+ P.info += text("Name: [] ID: [] \nSex: [] \nAge: [] \nFingerprint: [] \nPhysical Status: [] \nMental Status: [] ", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"], active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"])
else
P.info += "General Record Lost! "
- if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2)))
- P.info += text(" \nMedical Data \nBlood Type: [] \nDNA: [] \n \nMinor Disabilities: [] \nDetails: [] \n \nMajor Disabilities: [] \nDetails: [] \n \nAllergies: [] \nDetails: [] \n \nCurrent Diseases: [] (per disease info placed in log/comment section) \nDetails: [] \n \nImportant Notes: \n\t[] \n \nComments/Log ", src.active2.fields["b_type"], src.active2.fields["b_dna"], src.active2.fields["mi_dis"], src.active2.fields["mi_dis_d"], src.active2.fields["ma_dis"], src.active2.fields["ma_dis_d"], src.active2.fields["alg"], src.active2.fields["alg_d"], src.active2.fields["cdi"], src.active2.fields["cdi_d"], src.active2.fields["notes"])
+ if ((istype(active2, /datum/data/record) && data_core.medical.Find(active2)))
+ P.info += text(" \nMedical Data \nBlood Type: [] \nDNA: [] \n \nMinor Disabilities: [] \nDetails: [] \n \nMajor Disabilities: [] \nDetails: [] \n \nAllergies: [] \nDetails: [] \n \nCurrent Diseases: [] (per disease info placed in log/comment section) \nDetails: [] \n \nImportant Notes: \n\t[] \n \nComments/Log ", active2.fields["b_type"], active2.fields["b_dna"], active2.fields["mi_dis"], active2.fields["mi_dis_d"], active2.fields["ma_dis"], active2.fields["ma_dis_d"], active2.fields["alg"], active2.fields["alg_d"], active2.fields["cdi"], active2.fields["cdi_d"], active2.fields["notes"])
var/counter = 1
- while(src.active2.fields[text("com_[]", counter)])
- P.info += text("[] ", src.active2.fields[text("com_[]", counter)])
+ while(active2.fields[text("com_[]", counter)])
+ P.info += text("[] ", active2.fields[text("com_[]", counter)])
counter++
else
P.info += "Medical Record Lost! "
P.info += ""
P.name = "paper- 'Medical Record'"
- src.printing = null
+ printing = null
- src.add_fingerprint(usr)
- src.updateUsrDialog()
+ add_fingerprint(usr)
+ updateUsrDialog()
return
/obj/machinery/computer/med_data/emp_act(severity)
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index 8387c5482d9..6da172c5869 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -1180,7 +1180,7 @@ obj/item/weapon/circuitboard/rdserver
/obj/item/weapon/circuitboard/centrifuge
name = "Circuit Board (Isolation Centrifuge)"
desc = "A circuit board used to run a machine that isolates pathogens and antibodies."
- build_path = /obj/machinery/centrifuge
+ build_path = /obj/machinery/disease2/centrifuge
board_type = MACHINE
origin_tech = Tc_BIOTECH + "=3"
req_components = list(
diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm
index 593ef35e9f1..adb2506152a 100644
--- a/code/game/machinery/kitchen/gibber.dm
+++ b/code/game/machinery/kitchen/gibber.dm
@@ -217,6 +217,12 @@ obj/machinery/gibber/New()
if(src.occupant.reagents)
src.occupant.reagents.trans_to (newmeat, round (sourcetotalreagents / totalslabs, 1)) // Transfer all the reagents from the
+ if (occupant.virus2?.len)
+ for (var/ID in occupant.virus2)
+ var/datum/disease2/disease/D = occupant.virus2[ID]
+ if (D.spread & SPREAD_BLOOD)
+ newmeat.infect_disease2(D,1,"(Gibber, from [occupant], and activated by [user])")
+
allmeat[i] = newmeat
src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [key_name(user)] " //One shall not simply gib a mob unnoticed!
diff --git a/code/game/machinery/kitchen/processor.dm b/code/game/machinery/kitchen/processor.dm
index e349961408b..6a90d1ce2e6 100644
--- a/code/game/machinery/kitchen/processor.dm
+++ b/code/game/machinery/kitchen/processor.dm
@@ -158,7 +158,7 @@
for(var/obj/I in target.contents)
I.forceMove(loc)
I.throw_at(pick(throwzone),rand(2,5),0)
- hgibs(loc, target.viruses, target.dna, target.species.flesh_color, target.species.blood_color)
+ hgibs(loc, target.virus2, target.dna, target.species.flesh_color, target.species.blood_color)
qdel(target)
target = null
for(var/i = 1;i<=6;i++)
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 14704aefff2..8dccab7338c 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -1579,6 +1579,7 @@ var/global/num_vending_terminals = 1
/obj/item/weapon/reagent_containers/syringe/antiviral = 4,
/obj/item/weapon/reagent_containers/syringe = 12,
/obj/item/device/healthanalyzer = 5,
+ /obj/item/device/antibody_scanner = 5,
/obj/item/weapon/reagent_containers/glass/beaker = 4,
/obj/item/weapon/reagent_containers/dropper = 2,
/obj/item/stack/medical/splint = 4,
@@ -1642,6 +1643,7 @@ var/global/num_vending_terminals = 1
/obj/item/stack/medical/ointment = 2,
/obj/item/weapon/reagent_containers/syringe/inaprovaline = 4,
/obj/item/device/healthanalyzer = 1,
+ /obj/item/device/antibody_scanner = 1,
/obj/item/stack/medical/splint = 1,
)
contraband = list(
@@ -1666,6 +1668,7 @@ var/global/num_vending_terminals = 1
/obj/item/stack/medical/bruise_pack = 3,
/obj/item/stack/medical/ointment =3,
/obj/item/device/healthanalyzer = 3,
+ /obj/item/device/antibody_scanner = 3,
)
contraband = list(
/obj/item/weapon/reagent_containers/pill/tox = 3,
@@ -2119,7 +2122,8 @@ var/global/num_vending_terminals = 1
/obj/item/clothing/back/magiccape = 1,
)
- pack = /obj/structure/vendomatpack/magivend //Who's laughing now? wizarditis doesn't do shit anyway. - Deity Link
+ pack = /obj/structure/vendomatpack/magivend //Who's laughing now? wizarditis doesn't do shit anyway. - Deity Link of 2014
+ //How about I make a foul of myself 5 years later? Wizarditis is now a proper symptom. - Deity Link of 2019
/obj/machinery/vending/dinnerware
name = "\improper Dinnerware"
diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm
index 2e426398fd6..f2cd689d6ca 100644
--- a/code/game/objects/effects/decals/Cleanable/misc.dm
+++ b/code/game/objects/effects/decals/Cleanable/misc.dm
@@ -264,4 +264,38 @@
name = "smashed butter"
desc = "Looks like some one has butter fingers."
icon = 'icons/effects/tomatodecal.dmi'
- icon_state = "smashed_butter"
\ No newline at end of file
+ icon_state = "smashed_butter"
+
+/obj/effect/decal/cleanable/virusdish
+ name = "broken virus containment dish"
+ icon = 'icons/obj/virology.dmi'
+ icon_state = "brokendish-outline"
+ density = 0
+ anchored = 1
+ mouse_opacity = 1
+ layer = OBJ_LAYER
+ plane = OBJ_PLANE
+ var/last_openner
+ var/datum/disease2/disease/contained_virus
+
+/obj/effect/decal/cleanable/virusdish/Crossed(var/mob/living/perp)
+ ..()
+ FeetStab(perp,damage = 10,knockdown = 0)
+ infection_attempt(perp)
+
+/obj/effect/decal/cleanable/virusdish/proc/infection_attempt(var/mob/living/perp)
+ //Now if your feet aren't well protected, or are bleeding, you might get infected.
+ var/block = 0
+ var/bleeding = 0
+ if (perp.lying)
+ block = perp.check_contact_sterility(FULL_TORSO)
+ bleeding = perp.check_bodypart_bleeding(FULL_TORSO)
+ else
+ block = perp.check_contact_sterility(FEET)
+ bleeding = perp.check_bodypart_bleeding(FEET)
+
+ if (!block)
+ if (contained_virus.spread & SPREAD_CONTACT)
+ perp.infect_disease2(contained_virus, notes="(Contact, from [perp.lying?"lying":"standing"] over a broken virus dish[last_openner ? " broken by [last_openner]" : ""])")
+ else if (bleeding && (contained_virus.spread & SPREAD_BLOOD))
+ perp.infect_disease2(contained_virus, notes="(Blood, from [perp.lying?"lying":"standing"] over a broken virus dish[last_openner ? " broken by [last_openner]" : ""])")
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 96ec1d94959..86d8f315105 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -1,3 +1,5 @@
+var/list/infected_cleanables = list()
+
/obj/effect/decal/cleanable
var/list/random_icon_states = list()
var/targeted_by = null //Used so cleanbots can claim a mess.
@@ -16,6 +18,7 @@
var/list/absorbs_types = list() // Types to aggregate.
var/on_wall = 0 //Wall on which this decal is placed on
+ var/image/pathogen
var/persistence_type = SS_CLEANABLE
var/age = 1 //For map persistence. +1 per round that this item has survived. After a certain amount, it will not carry on to the next round anymore.
@@ -67,6 +70,17 @@
blood_DNA |= C.blood_DNA.Copy()
amount += C.amount
returnToPool(C)
+ spawn(1)//cleanables can get infected in many different ways when they spawn so it's much easier to handle the pathogen overlay here after a delay
+ if (virus2 && virus2.len > 0)
+ infected_cleanables += src
+ if (!pathogen)
+ pathogen = image('icons/effects/effects.dmi',src,"pathogen_blood")
+ pathogen.plane = HUD_PLANE
+ pathogen.layer = UNDER_HUD_LAYER
+ pathogen.appearance_flags = RESET_COLOR|RESET_ALPHA
+ for (var/mob/living/L in science_goggles_wearers)
+ if (L.client)
+ L.client.images |= pathogen
/obj/effect/decal/cleanable/initialize()
..()
@@ -90,12 +104,20 @@
if(persistent_type_replacement)
.["type"] = persistent_type_replacement
+
/obj/effect/decal/cleanable/attackby(obj/item/O as obj, mob/user as mob)
if(istype(O,/obj/item/weapon/mop))
return ..()
return 0 //No more "X HITS THE BLOOD WITH AN RCD"
/obj/effect/decal/cleanable/Destroy()
+ infected_cleanables -= src
+ if (pathogen)
+ for (var/mob/living/L in science_goggles_wearers)
+ if (L.client)
+ L.client.images -= pathogen
+ pathogen = null
+
blood_list -= src
for(var/datum/disease/D in viruses)
D.cure(0)
diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibs.dm
index 1d9a66db245..c7b65c5e1bf 100644
--- a/code/game/objects/effects/gibs.dm
+++ b/code/game/objects/effects/gibs.dm
@@ -1,14 +1,14 @@
-/proc/gibs(atom/location, var/list/viruses, var/datum/dna/MobDNA) //CARN MARKER
- new /obj/effect/gibspawner/generic(get_turf(location),viruses,MobDNA)
+/proc/gibs(atom/location, var/list/virus2, var/datum/dna/MobDNA) //CARN MARKER
+ new /obj/effect/gibspawner/generic(get_turf(location),virus2,MobDNA)
-/proc/hgibs(atom/location, var/list/viruses, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor, spread_radius)
- new /obj/effect/gibspawner/human(get_turf(location),viruses,MobDNA,fleshcolor,bloodcolor, spread_radius)
+/proc/hgibs(atom/location, var/list/virus2, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor, spread_radius)
+ new /obj/effect/gibspawner/human(get_turf(location),virus2,MobDNA,fleshcolor,bloodcolor, spread_radius)
-/proc/xgibs(atom/location, var/list/viruses)
- new /obj/effect/gibspawner/xeno(get_turf(location),viruses)
+/proc/xgibs(atom/location, var/list/virus2)
+ new /obj/effect/gibspawner/xeno(get_turf(location),virus2)
-/proc/robogibs(atom/location, var/list/viruses)
- new /obj/effect/gibspawner/robot(get_turf(location),viruses)
+/proc/robogibs(atom/location, var/list/virus2)
+ new /obj/effect/gibspawner/robot(get_turf(location),virus2)
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//The following procs were thought to be used in correlation with the amount of blood available, example:
//a loop in [bloodpack.dm] that spawns _______________________________________
@@ -17,22 +17,21 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//Apparently no one has ever needed to do a blood mess, so I didn't bother making a generic proc.
////////////////////////////////////////////////////////////////////////////////////////////////////////
-/proc/bloodmess_splatter(atom/location, var/list/viruses, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor, spread_radius)
- new /obj/effect/gibspawner/blood(get_turf(location), viruses, MobDNA, fleshcolor, bloodcolor, spread_radius)
+/proc/bloodmess_splatter(atom/location, var/list/virus2, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor, spread_radius)
+ new /obj/effect/gibspawner/blood(get_turf(location), virus2, MobDNA, fleshcolor, bloodcolor, spread_radius)
-/proc/bloodmess_drip(atom/location, var/list/viruses, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor, spread_radius)
- new /obj/effect/gibspawner/blood_drip(get_turf(location), viruses, MobDNA, fleshcolor, bloodcolor, spread_radius)
+/proc/bloodmess_drip(atom/location, var/list/virus2, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor, spread_radius)
+ new /obj/effect/gibspawner/blood_drip(get_turf(location), virus2, MobDNA, fleshcolor, bloodcolor, spread_radius)
/obj/effect/gibspawner
var/sparks = 0 //whether sparks spread on Gib()
- var/virusProb = 20 //the chance for viruses to spread on the gibs
var/list/gibtypes = list()
var/list/gibamounts = list()
var/list/gibdirections = list() //of lists
var/fleshcolor //Used for gibbed humans.
var/bloodcolor //Used for gibbed humans.
-/obj/effect/gibspawner/New(location, var/list/viruses, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor, spread_radius)
+/obj/effect/gibspawner/New(location, var/list/virus2, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor, spread_radius)
..()
if(fleshcolor)
@@ -41,9 +40,9 @@
src.bloodcolor = bloodcolor
if(istype(loc,/turf)) //basically if a badmin spawns it
- Gib(loc,viruses,MobDNA,spread_radius)
+ Gib(loc,virus2,MobDNA,spread_radius)
-/obj/effect/gibspawner/proc/Gib(atom/location, var/list/viruses = list(), var/datum/dna/MobDNA = null, spread_radius)
+/obj/effect/gibspawner/proc/Gib(atom/location, var/list/virus2 = list(), var/datum/dna/MobDNA = null, spread_radius)
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
to_chat(world, "Gib list length mismatch! ")
return
@@ -68,8 +67,8 @@
gib.update_icon()
- if(viruses)
- gib.virus2 |= virus_copylist(viruses)
+ if(virus2)
+ gib.virus2 = filter_disease_by_spread(virus_copylist(virus2),required = SPREAD_BLOOD)
gib.blood_DNA = list()
if(MobDNA)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 07cb0168333..eaec2dd387f 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -66,6 +66,10 @@
var/hides_identity = HIDES_IDENTITY_DEFAULT
var/datum/daemon/daemon
+ var/list/datum/disease2/disease/virus2 = list()
+ var/sterility = 0// 0 to 100. increase chances of preventing disease spread.
+ var/image/pathogen
+
/obj/item/proc/return_thermal_protection()
return return_cover_protection(body_parts_covered) * (1 - heat_conductivity)
@@ -75,6 +79,13 @@
new path(src)
/obj/item/Destroy()
+ infected_items -= src
+ if (pathogen)
+ for (var/mob/living/L in science_goggles_wearers)
+ if (L.client)
+ L.client.images -= pathogen
+ pathogen = null
+
if(istype(loc, /mob))
var/mob/H = loc
H.drop_from_inventory(src) // items at the very least get unequipped from their mob before being deleted
@@ -214,7 +225,7 @@
R.activate_module(src)
R.hud_used.update_robot_modules_display()
-/obj/item/attack_hand(mob/user as mob)
+/obj/item/attack_hand(var/mob/user)
if (!user)
return
@@ -244,7 +255,8 @@
if(can_pickup(user) && !user.put_in_active_hand(src))
forceMove(get_turf(user))
- return
+ //transfers diseases between the mob and the item
+ disease_contact(user)
/obj/item/requires_dexterity(mob/user)
return TRUE
@@ -1026,16 +1038,17 @@
/obj/item/clean_blood()
. = ..()
- if(blood_overlay)
+ remove_disease2()
+ if (blood_overlay)
overlays.Remove(blood_overlay)
- if(had_blood)
+ if (had_blood)
clear_luminol()
- if(istype(src, /obj/item/clothing/gloves))
+ if (istype(src, /obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = src
G.transfer_blood = 0
-/obj/item/add_blood(mob/living/carbon/human/M as mob)
+/obj/item/add_blood(var/mob/living/carbon/human/M)
if (!..())
return FALSE
if(istype(src, /obj/item/weapon/melee/energy))
@@ -1056,6 +1069,17 @@
//if this blood isn't already in the list, add it
if(!M)
return
+
+ if (M.virus2?.len)
+ var/list/blood_diseases = filter_disease_by_spread(M.virus2,required = SPREAD_BLOOD)
+ if (blood_diseases?.len)
+ for (var/ID in blood_diseases)
+ var/datum/disease2/disease/D = blood_diseases[ID]
+ infect_disease2(D, notes="(Blood, coming from [M])")
+ if (isliving(loc))
+ var/mob/living/L = loc
+ infection_attempt(L,D)//Wear gloves when doing surgery or beating that catbeast to death!
+
if(blood_DNA[M.dna.unique_enzymes])
return FALSE //already bloodied with this blood. Cannot add more.
blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
@@ -1383,3 +1407,40 @@ var/global/list/image/blood_overlays = list()
//This proc will be called when the person holding or equipping it talks.
/obj/item/proc/affect_speech(var/datum/speech/speech, var/mob/living/L)
return
+
+/////// DISEASE STUFF //////////////////////////////////////////////////////////////////////////
+//Called by attack_hand(), transfers diseases between the mob and the item
+/obj/item/proc/disease_contact(var/mob/living/M,var/bodypart = null)
+ //first let's try to infect them with our viruses
+ for (var/ID in virus2)
+ var/datum/disease2/disease/D = virus2[ID]
+ infection_attempt(M,D,bodypart)
+
+ if (!bodypart)//no bodypart specified? that should mean we're being held.
+ bodypart = HANDS
+ //secondly, do they happen to carry contact-spreading viruses themselves?
+ var/list/contact_diseases = filter_disease_by_spread(M.virus2,required = SPREAD_CONTACT)
+ if (contact_diseases?.len)
+ //if so are their hands protected?
+ if (!M.check_contact_sterility(bodypart))
+ for (var/ID in contact_diseases)
+ var/datum/disease2/disease/D = contact_diseases[ID]
+ infect_disease2(D, notes="(Contact, from being touched by [M])")
+
+
+ //spreading of blood-spreading diseases to items is handled by add_blood()
+
+//Called by disease_contact(), trying to infect people who pick us up
+/obj/item/proc/infection_attempt(var/mob/living/perp,var/datum/disease2/disease/D,var/bodypart = null)
+ if (!istype(D))
+ return
+ if (src in perp.held_items)
+ bodypart = HANDS
+ if (bodypart)
+ var/block = perp.check_contact_sterility(bodypart)
+ var/bleeding = perp.check_bodypart_bleeding(bodypart)
+ if (!block)
+ if (D.spread & SPREAD_CONTACT)
+ perp.infect_disease2(D, notes="(Contact, from picking up \a [src])")
+ else if (bleeding && (D.spread & SPREAD_BLOOD))//if we're covered with a blood-spreading disease, we may infect people with bleeding hands.
+ perp.infect_disease2(D, notes="(Blood, from picking up \a [src])")
diff --git a/code/game/objects/items/devices/deskbell.dm b/code/game/objects/items/devices/deskbell.dm
index 90f3772efef..e49952b0104 100644
--- a/code/game/objects/items/devices/deskbell.dm
+++ b/code/game/objects/items/devices/deskbell.dm
@@ -79,6 +79,7 @@
/obj/item/device/deskbell/attack_hand(var/mob/user)
if(anchored)
+ disease_contact(user,HANDS)
ring()
add_fingerprint(user)
return
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 2ea78df9fa7..4af722c1bb2 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -110,6 +110,27 @@ BREATHALYZER
to_chat(user, "\The [src] glows [pick("red", "green", "blue", "pink")]! You wonder what that would mean. ")
src.add_fingerprint(user)
+
+/obj/item/device/healthanalyzer/afterattack(var/atom/A, var/mob/user)
+ . = ..()
+ if(.)
+ return
+
+ if (A.Adjacent(user) && isitem(A))
+ var/obj/item/I = A
+ if(I.virus2 && I.virus2.len > 0)
+ playsound(user, 'sound/items/healthanalyzer.ogg', 50, 1)
+ for(var/ID in I.virus2)
+ var/datum/disease2/disease/D = I.virus2[ID]
+ if(ID in virusDB)
+ var/datum/data/record/V = virusDB[ID]
+ to_chat(user,"Warning: [V.fields["name"]][V.fields["nickname"] ? " \"[V.fields["nickname"]]\"" : ""] detected on \the [src]. Antigen: [D.get_antigen_string()] ")
+ else
+ to_chat(user,"Warning: Unknown [D.form] detected on \the [src]. ")
+ else
+ to_chat(user,"No pathogen detected on \the [src]. ")
+
+
/obj/item/device/healthanalyzer/attack_self(mob/living/user as mob)
. = ..()
if(.)
@@ -185,13 +206,16 @@ Subject's pulse: ??? BPM"})
if(H.nutrition < STARVATION_MIN)
message += "Warning: Subject starving. "
- if(iscarbon(M))
- var/mob/living/carbon/C = M
- if(C.virus2.len)
- for(var/ID in C.virus2)
- if(ID in virusDB)
- var/datum/data/record/V = virusDB[ID]
- message += "Warning: [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]] "
+ if(M.virus2.len)
+ for(var/ID in M.virus2)
+ var/datum/disease2/disease/D = M.virus2[ID]
+ if(ID in virusDB)
+ var/datum/data/record/V = virusDB[ID]
+ message += "[V.fields["name"]][V.fields["nickname"] ? " \"[V.fields["nickname"]]\"" : ""] detected in subject's blood. Strength: [D.strength]. Antigen: [D.get_antigen_string()] "
+ else
+ message += "Unknown [D.form] detected in subject's blood. Strength: [D.strength] "
+ else
+ message += "No pathogen detected in subject's blood. "
for(var/datum/disease/D in M.viruses)
if(!D.hidden[SCANNER])
diff --git a/code/game/objects/items/stacks/stack_recipes.dm b/code/game/objects/items/stacks/stack_recipes.dm
index e48cec73c04..c1428fc4a6d 100644
--- a/code/game/objects/items/stacks/stack_recipes.dm
+++ b/code/game/objects/items/stacks/stack_recipes.dm
@@ -333,6 +333,7 @@ var/list/datum/stack_recipe/metal_recipes = list (
var/list/datum/stack_recipe/plasteel_recipes = list (
new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = 1 ),
new/datum/stack_recipe("Cage", /obj/structure/cage, 6, time = 100, one_per_turf = 1 ),
+ new/datum/stack_recipe("Small Cage", /obj/item/critter_cage, 2, time = 50, one_per_turf = 0 ),
new/datum/stack_recipe("RUST fuel assembly port frame", /obj/item/mounted/frame/rust_fuel_assembly_port, 12, time = 50, one_per_turf = 1 ),
new/datum/stack_recipe("RUST fuel compressor frame", /obj/item/mounted/frame/rust_fuel_compressor, 12, time = 50, one_per_turf = 1 ),
new/datum/stack_recipe("Mass Driver frame", /obj/machinery/mass_driver_frame, 3, time = 50, one_per_turf = 1 ),
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 0dbbc06094b..fda96f12284 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -502,8 +502,8 @@
/obj/item/toy/snappop/virus
name = "unstable goo"
desc = "Your palm is oozing this stuff!"
- icon = 'icons/mob/slimes.dmi'
- icon_state = "red slime extract"
+ icon = 'icons/obj/virology.dmi'
+ icon_state = "unstable_goo"
throwforce = 30.0
throw_speed = 10
throw_range = 30
@@ -1113,17 +1113,17 @@
name = "fingerbox"
desc = "A high quality fingerbox."
icon_state = "fingerbox"
-
+
/obj/item/toy/gasha/bangerboy
name = "toy Bangerboy"
icon_state = "bangerboy"
desc = "BANG "
-
+
/obj/item/toy/gasha/femsec
name = "toy femsec"
icon_state = "femsec"
desc = "bodybag accessory not included"
-
+
/obj/item/toy/gasha/hoptard
name = "toy HoPtard"
icon_state = "hoptard"
@@ -1783,4 +1783,3 @@ var/list/living_balloons = list()
name = "\improper Trader action figure"
icon_state = "trader"
toysay = "Shiny rock for nuke, good trade yes?"
-
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm
index 554d61fc373..bd85a407ca2 100644
--- a/code/game/objects/items/weapons/manuals.dm
+++ b/code/game/objects/items/weapons/manuals.dm
@@ -601,4 +601,309 @@