diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index 8441647f791..2259b631491 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -382,6 +382,17 @@ to destroy them and players will be able to make replacements.
/obj/item/weapon/stock_parts/console_screen = 1,
/obj/item/weapon/stock_parts/cell = 1)
+//Almost the same recipe as destructive analyzer to give people choices.
+/obj/item/weapon/circuitboard/experimentor
+ name = "circuit board (E.X.P.E.R.I-MENTOR)"
+ build_path = /obj/machinery/r_n_d/experimentor
+ board_type = "machine"
+ origin_tech = "magnets=1;engineering=1;programming=1;biotech=1;bluespace=2"
+ req_components = list(
+ /obj/item/weapon/stock_parts/scanning_module = 1,
+ /obj/item/weapon/stock_parts/manipulator = 2,
+ /obj/item/weapon/stock_parts/micro_laser = 2)
+
/obj/item/weapon/circuitboard/destructive_analyzer
name = "circuit board (Destructive Analyzer)"
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index cf6f48f456c..3c347b9dae7 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -76,7 +76,6 @@
new /obj/item/clothing/under/hosparademale(src)
new /obj/item/clothing/suit/armor/hos(src)
new /obj/item/clothing/head/HoS(src)
- new /obj/item/clothing/head/HoS/formal(src)
new /obj/item/clothing/glasses/hud/security/eyepatch(src)
new /obj/item/weapon/storage/lockbox/loyalty(src)
new /obj/item/weapon/storage/box/flashbangs(src)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index bbe55e693c4..7f2d0ee9a1e 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -578,10 +578,8 @@ var/global/floorIsLava = 0
set category = "Server"
set desc="Start the round RIGHT NOW"
set name="Start Now"
- if(!ticker)
- alert("Unable to start the game as it is not set up.")
- return
if(ticker.current_state == GAME_STATE_PREGAME)
+ ticker.can_fire = 1
ticker.current_state = GAME_STATE_SETTING_UP
log_admin("[usr.key] has started the game.")
message_admins("[usr.key] has started the game.")
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index 408e205c679..256138f8beb 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -66,11 +66,6 @@
desc = "A robust beret for the Head of Security, for looking stylish while not sacrificing protection."
icon_state = "hosberetblack"
-/obj/item/clothing/head/HoS/formal
- name = "formal head of security cap"
- desc = "A robust formal cap for special occasions."
- icon_state = "hosformal"
-
/obj/item/clothing/head/warden
name = "warden's police hat"
desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts."
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index aed63e5e5f9..88cc52f77bd 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -40,7 +40,7 @@
/obj/item/clothing/under/rank/prisoner
name = "prison jumpsuit"
- desc = "It's standardised Nanotrasen prisoner wear. Its suit sensors are stuck in the \"Fully On\" position."
+ desc = "It's standardised Nanotrasen prisoner-wear. Its suit sensors are stuck in the \"Fully On\" position."
icon_state = "prisoner"
item_state = "o_suit"
item_color = "prisoner"
@@ -336,7 +336,7 @@
/obj/item/clothing/under/captainparade
name = "captain's parade uniform"
- desc = "A captain's luxury wear, for special occasions."
+ desc = "A captain's luxury-wear, for special occasions."
icon_state = "captain_parade"
item_state = "by_suit"
item_color = "captain_parade"
@@ -344,20 +344,15 @@
/obj/item/clothing/under/hosparademale
name = "head of security's parade uniform"
- desc = "A male head of security's luxury wear, for special occasions."
+ desc = "A male head of security's luxury-wear, for special occasions."
icon_state = "hos_parade_male"
item_state = "r_suit"
item_color = "hos_parade_male"
can_adjust = 0
- fitted = 0
-
-/obj/item/clothing/under/hosparademale/New()
- ..()
- attachTie(new /obj/item/clothing/tie/red(src))
/obj/item/clothing/under/hosparadefem
name = "head of security's parade uniform"
- desc = "A female head of security's luxury wear, for special occasions."
+ desc = "A female head of security's luxury-wear, for special occasions."
icon_state = "hos_parade_fem"
item_state = "r_suit"
item_color = "hos_parade_fem"
@@ -366,7 +361,7 @@
/obj/item/clothing/under/assistantformal
name = "assistant's formal uniform"
- desc = "An assistant's formal wear. Why an assistant needs formal wear is still unknown."
+ desc = "An assistant's formal-wear. Why an assistant needs formal-wear is still unknown."
icon_state = "assistant_formal"
item_state = "gy_suit"
item_color = "assistant_formal"
diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm
index bcd39b203e3..f984e47c32c 100644
--- a/code/modules/research/designs/machine_designs.dm
+++ b/code/modules/research/designs/machine_designs.dm
@@ -142,6 +142,16 @@
build_path = /obj/item/weapon/circuitboard/destructive_analyzer
category = list("Research Machinery")
+/datum/design/experimentor
+ name = "Machine Design (E.X.P.E.R.I-MENTOR Board)"
+ desc = "The circuit board for an E.X.P.E.R.I-MENTOR."
+ id = "experimentor"
+ req_tech = list("programming" = 2, "magnets" = 2, "engineering" = 2, "bluespace" = 2)
+ build_type = IMPRINTER
+ materials = list("$glass" = 1000, "sacid" = 20)
+ build_path = /obj/item/weapon/circuitboard/experimentor
+ category = list("Research Machinery")
+
/datum/design/protolathe
name = "Machine Design (Protolathe Board)"
desc = "The circuit board for a protolathe."
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
new file mode 100644
index 00000000000..2bafbeb8472
--- /dev/null
+++ b/code/modules/research/experimentor.dm
@@ -0,0 +1,392 @@
+//this is designed to replace the destructive analyzer
+
+#define SCANTYPE_POKE 1
+#define SCANTYPE_IRRADIATE 2
+#define SCANTYPE_GAS 3
+#define SCANTYPE_HEAT 4
+#define SCANTYPE_COLD 5
+#define SCANTYPE_OBLITERATE 6
+
+#define EFFECT_PROB_VERYLOW 10
+#define EFFECT_PROB_LOW 20
+#define EFFECT_PROB_MEDIUM 45
+#define EFFECT_PROB_HIGH 65
+#define EFFECT_PROB_VERYHIGH 85
+
+#define FAIL 7
+/obj/machinery/r_n_d/experimentor
+ name = "E.X.P.E.R.I-MENTOR"
+ icon = 'icons/obj/machines/heavy_lathe.dmi'
+ icon_state = "h_lathe"
+ density = 1
+ anchored = 1
+ use_power = 1
+ var/obj/item/loaded_item = null
+ ///
+ var/badThingCoeff = 0
+ var/resetTime = 15
+ var/list/item_reactions = list()
+ var/list/valid_items = list()
+
+/obj/machinery/r_n_d/experimentor/proc/ConvertReqString2List(var/list/source_list)
+ var/list/temp_list = params2list(source_list)
+ for(var/O in temp_list)
+ temp_list[O] = text2num(temp_list[O])
+ return temp_list
+
+/obj/machinery/r_n_d/experimentor/proc/SetTypeReactions()
+ for(var/I in typesof(/obj/item))
+ item_reactions["[I]"] = pick(SCANTYPE_POKE,SCANTYPE_IRRADIATE,SCANTYPE_GAS,SCANTYPE_HEAT,SCANTYPE_COLD,SCANTYPE_OBLITERATE)
+ if(ispath(I,/obj/item/weapon/reagent_containers/food) || ispath(I,/obj/item/weapon/stock_parts) || ispath(I,/obj/item/weapon/grenade/chem_grenade) || ispath(I,/obj/item/weapon/kitchen))
+ var/obj/item/tempCheck = new I()
+ if(tempCheck.icon_state != null) //check it's an actual usable item, in a hacky way
+ valid_items += I
+ qdel(tempCheck)
+
+
+/obj/machinery/r_n_d/experimentor/New()
+ ..()
+ component_parts = list()
+ component_parts += new /obj/item/weapon/circuitboard/experimentor(src)
+ component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
+ component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
+ component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
+ SetTypeReactions()
+ RefreshParts()
+
+/obj/machinery/r_n_d/experimentor/RefreshParts()
+ for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
+ if(resetTime > 0 && (resetTime - M.rating) >= 1)
+ resetTime -= M.rating
+ for(var/obj/item/weapon/stock_parts/scanning_module/M in component_parts)
+ badThingCoeff += M.rating*2
+ for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts)
+ badThingCoeff += M.rating
+
+/obj/machinery/r_n_d/experimentor/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if (shocked)
+ shock(user,50)
+ if (istype(O, /obj/item/weapon/screwdriver))
+ if (!panel_open)
+ panel_open = 1
+ if(linked_console)
+ linked_console.linked_destroy = null
+ linked_console = null
+ icon_state = "h_lathe_maint"
+ user << "You open the maintenance hatch of [src]."
+ else
+ panel_open = 0
+ icon_state = "h_lathe"
+ user << "You close the maintenance hatch of [src]."
+ return
+ if (panel_open)
+ if(istype(O, /obj/item/weapon/crowbar))
+ playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
+ var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc)
+ M.state = 2
+ M.icon_state = "box_1"
+ for(var/obj/I in component_parts)
+ I.loc = src.loc
+ del(src)
+ return 1
+ else
+ user << "You can't load the [src.name] while it's opened."
+ return 1
+ if (disabled)
+ return
+ if (!linked_console)
+ user << "The [src] must be linked to an R&D console first!"
+ return
+ if (busy)
+ user << "The [src] is busy right now."
+ return
+ if (istype(O, /obj/item) && !loaded_item)
+ if(!O.origin_tech)
+ user << "This doesn't seem to have a tech origin!"
+ return
+ var/list/temp_tech = ConvertReqString2List(O.origin_tech)
+ if (temp_tech.len == 0)
+ user << "You cannot experiment on this item!"
+ return
+ if(O.reliability < 90 && O.crit_fail == 0)
+ usr << "Item is neither reliable enough or broken enough to learn from."
+ return
+ busy = 1
+ loaded_item = O
+ user.drop_item()
+ O.loc = src
+ user << "You add the [O.name] to the machine!"
+ flick("h_lathe_load", src)
+ spawn(15)
+ icon_state = "h_lathe_wloop"
+ return
+
+
+/obj/machinery/r_n_d/experimentor/attack_hand(mob/user as mob)
+ user.set_machine(src)
+ var/dat = "
"
+ if(!linked_console)
+ dat += "Scan for R&D Console
"
+ if(loaded_item)
+ dat += "Loaded Item: [loaded_item]
"
+ dat += "Technology:
"
+ var/list/D = ConvertReqString2List(loaded_item.origin_tech)
+ for(var/T in D)
+ dat += "[T]
"
+ dat += "
Available tests:"
+ dat += "
Poke"
+ dat += "
Irradiate"
+ dat += "
Gas"
+ dat += "
Burn"
+ dat += "
Freeze"
+ dat += "
Destroy
"
+ dat += "
Eject"
+ else
+ dat += "Nothing loaded."
+ dat += "
Close
"
+ var/datum/browser/popup = new(user, "experimentor","Experimentor", 700, 400, src)
+ popup.set_content(dat)
+ popup.open()
+ onclose(user, "experimentor")
+
+
+/obj/machinery/r_n_d/experimentor/proc/matchReaction(var/matching,var/reaction)
+ var/obj/item/D = matching
+ if(D)
+ if(item_reactions.Find("[D.type]"))
+ var/tor = item_reactions["[D.type]"]
+ if(tor == text2num(reaction))
+ return tor
+ else
+ return FAIL
+ else
+ return FAIL
+ else
+ return FAIL
+
+/obj/machinery/r_n_d/experimentor/proc/ejectItem(var/delete=FALSE)
+ loaded_item.loc = src.loc
+ if(delete)
+ qdel(loaded_item)
+ loaded_item = null
+
+/*
+#define EFFECT_PROB_VERYLOW 10
+#define EFFECT_PROB_LOW 20
+#define EFFECT_PROB_MEDIUM 45
+#define EFFECT_PROB_HIGH 65
+#define EFFECT_PROB_VERYHIGH 85
+*/
+/obj/machinery/r_n_d/experimentor/proc/experiment(var/exp,var/obj/item/exp_on)
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ if(exp == SCANTYPE_POKE)
+ visible_message("[src] prods at [exp_on] with mechanical arms.")
+ if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
+ visible_message("[src] malfunctions and destroys [exp_on], lashing it's arms out at nearby people!.")
+ for(var/mob/living/m in oview(1))
+ m.apply_damage(15,"brute",pick("head","chest","groin"))
+ ejectItem(TRUE)
+ else if(prob(EFFECT_PROB_LOW-badThingCoeff))
+ visible_message("[src] malfunctions!.")
+ exp = SCANTYPE_OBLITERATE
+ else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
+ visible_message("[src] malfunctions, throwing the [exp_on]!.")
+ var/mob/living/target = locate(/mob/living) in oview(7,src)
+ if(target)
+ var/obj/item/throwing = loaded_item
+ ejectItem()
+ throwing.throw_at(target, 10, 1)
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ if(exp == SCANTYPE_IRRADIATE)
+ visible_message("[src] reflects radioactive rays at [exp_on]!")
+ if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
+ visible_message("[src] malfunctions, melting [exp_on] and leaking radiation!.")
+ for(var/mob/living/m in oview(1))
+ m.apply_effect(25,IRRADIATE)
+ ejectItem(TRUE)
+ else if(prob(EFFECT_PROB_LOW-badThingCoeff))
+ visible_message("[src] malfunctions, spewing toxic waste!.")
+ for(var/turf/T in oview(1))
+ if(!T.density)
+ if(prob(EFFECT_PROB_VERYHIGH))
+ new /obj/effect/decal/cleanable/greenglow(T)
+ else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
+ visible_message("[src] malfunctions, transforming the [exp_on]!.")
+ ejectItem(TRUE)
+ var/newPath = pick(valid_items)
+ loaded_item = new newPath(src)
+ if(istype(loaded_item,/obj/item/weapon/grenade/chem_grenade))
+ var/obj/item/weapon/grenade/chem_grenade/CG = loaded_item
+ CG.prime()
+ ejectItem()
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ if(exp == SCANTYPE_GAS)
+ visible_message("[src] fills it's chamber with gas, [exp_on] included.")
+ if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
+ visible_message("[src] destroys [exp_on], leaking dangerous gas!.")
+ var/list/chems = list("carbon","radium","toxin","condensedcapsaicin","mushroomhallucinogen","space_drugs","ethanol","beepskysmash")
+ var/datum/reagents/R = new/datum/reagents(50)
+ R.my_atom = src
+ R.add_reagent(pick(chems), 50)
+ var/datum/effect/effect/system/chem_smoke_spread/smoke = new
+ smoke.set_up(R, 1, 0, src, 0, silent = 1)
+ playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
+ smoke.start()
+ R.delete()
+ ejectItem(TRUE)
+ else if(prob(EFFECT_PROB_LOW-badThingCoeff))
+ visible_message("[src] malfunctions, spewing harmless gas!.")
+ var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
+ smoke.set_up(1,0, src.loc, 0)
+ smoke.start()
+ else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
+ visible_message("[src] melts [exp_on], ionizing the air around it!.")
+ empulse(src.loc, 8, 10)
+ ejectItem(TRUE)
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ if(exp == SCANTYPE_HEAT)
+ visible_message("[src] raises [exp_on]'s temperature.")
+ if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
+ visible_message("[src] malfunctions, melting [exp_on] and releasing a burst of flame!.")
+ explosion(src.loc, -1, 0, 0, 0, 0, flame_range = 2)
+ ejectItem(TRUE)
+ else if(prob(EFFECT_PROB_LOW-badThingCoeff))
+ visible_message("[src] malfunctions, melting [exp_on] and leaking hot air!.")
+ var/datum/gas_mixture/env = src.loc.return_air()
+ var/transfer_moles = 0.25 * env.total_moles()
+ var/datum/gas_mixture/removed = env.remove(transfer_moles)
+ if(removed)
+ var/heat_capacity = removed.heat_capacity()
+ if(heat_capacity == 0 || heat_capacity == null)
+ heat_capacity = 1
+ removed.temperature = min((removed.temperature*heat_capacity + 100000)/heat_capacity, 1000)
+ env.merge(removed)
+ air_update_turf()
+ ejectItem(TRUE)
+ else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
+ visible_message("[src] malfunctions, activating it's emergency coolant systems!.")
+ var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
+ smoke.set_up(1,0, src.loc, 0)
+ smoke.start()
+ for(var/mob/living/m in oview(1))
+ m.apply_damage(5,"burn",pick("head","chest","groin"))
+ ejectItem()
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ if(exp == SCANTYPE_COLD)
+ visible_message("[src] lowers [exp_on]'s temperature.")
+ if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
+ visible_message("[src] malfunctions, shattering [exp_on] and releasing a dangerous cloud of coolant!")
+ var/datum/reagents/R = new/datum/reagents(50)
+ R.my_atom = src
+ R.add_reagent("frostoil", 50)
+ var/datum/effect/effect/system/chem_smoke_spread/smoke = new
+ smoke.set_up(R, 1, 0, src, 0, silent = 1)
+ playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
+ smoke.start()
+ R.delete()
+ ejectItem(TRUE)
+ else if(prob(EFFECT_PROB_LOW-badThingCoeff))
+ visible_message("[src] malfunctions, shattering [exp_on] and leaking cold air!.")
+ var/datum/gas_mixture/env = src.loc.return_air()
+ var/transfer_moles = 0.25 * env.total_moles()
+ var/datum/gas_mixture/removed = env.remove(transfer_moles)
+ if(removed)
+ var/heat_capacity = removed.heat_capacity()
+ if(heat_capacity == 0 || heat_capacity == null)
+ heat_capacity = 1
+ removed.temperature = (removed.temperature*heat_capacity - 75000)/heat_capacity
+ env.merge(removed)
+ air_update_turf()
+ ejectItem(TRUE)
+ else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
+ visible_message("[src] malfunctions, releasing a flurry of chilly air as [exp_on] pops out!.")
+ var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
+ smoke.set_up(1,0, src.loc, 0)
+ smoke.start()
+ ejectItem()
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ if(exp == SCANTYPE_OBLITERATE)
+ visible_message("[exp_on] activates the crushing mechanism, [exp_on] is destroyed!")
+ if(linked_console.linked_lathe)
+ linked_console.linked_lathe.m_amount += min((linked_console.linked_lathe.max_material_storage - linked_console.linked_lathe.TotalMaterials()), (exp_on.m_amt))
+ linked_console.linked_lathe.g_amount += min((linked_console.linked_lathe.max_material_storage - linked_console.linked_lathe.TotalMaterials()), (exp_on.g_amt))
+ if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
+ visible_message("[src]'s crusher goes way too many levels too high, crushing right through space-time!")
+ playsound(src.loc, 'sound/effects/supermatter.ogg', 50, 1, -3)
+ var/list/throwAt = list()
+ for(var/i in oview(7,src))
+ if(istype(i,/obj/item) || istype(i,/mob/living))
+ throwAt.Add(i)
+ var/counter
+ for(counter = 1, counter < throwAt.len, ++counter)
+ var/cast = throwAt[counter]
+ cast:throw_at(src,10,1)
+ else if(prob(EFFECT_PROB_LOW-badThingCoeff))
+ visible_message("[src]'s crusher goes one level too high, crushing right into space-time!.")
+ playsound(src.loc, 'sound/effects/supermatter.ogg', 50, 1, -3)
+ var/list/oViewStuff = oview(7,src)
+ var/list/throwAt = list()
+ for(var/i in oViewStuff)
+ if(istype(i,/obj/item) || istype(i,/mob/living))
+ throwAt.Add(i)
+ var/counter
+ for(counter = 1, counter < throwAt.len, ++counter)
+ var/cast = throwAt[counter]
+ cast:throw_at(pick(throwAt),10,1)
+ ejectItem(TRUE)
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ if(exp == FAIL)
+ var/a = pick("rumbles","shakes","vibrates","shudders")
+ var/b = pick("crushes","spins","viscerates","smashes","insults")
+ visible_message("[exp_on] [a], and [b], the experiment was a failiure!")
+
+ spawn(resetTime)
+ icon_state = "h_lathe"
+ busy = 0
+
+/obj/machinery/r_n_d/experimentor/Topic(href, href_list)
+ if(..())
+ return
+ usr.set_machine(src)
+
+ var/scantype = href_list["function"]
+ var/obj/item/process = locate(href_list["item"]) in src
+
+ if(scantype == "close")
+ usr << browse(null, "window=experimentor")
+ else if(scantype == "search")
+ var/obj/machinery/computer/rdconsole/D = locate(/obj/machinery/computer/rdconsole) in oview(3,src)
+ if(D)
+ linked_console = D
+ else if(scantype == "eject")
+ ejectItem()
+ else
+ var/dotype = matchReaction(process,scantype)
+ experiment(dotype,process)
+ use_power(750)
+ if(dotype != FAIL)
+ if(process.origin_tech)
+ var/list/temp_tech = ConvertReqString2List(process.origin_tech)
+ for(var/T in temp_tech)
+ linked_console.files.UpdateTech(T, temp_tech[T])
+ linked_console.files.UpdateDesigns(process,process.type)
+ if(scantype != "close")
+ src.updateUsrDialog()
+ return
+
+#undef SCANTYPE_POKE
+#undef SCANTYPE_IRRADIATE
+#undef SCANTYPE_GAS
+#undef SCANTYPE_HEAT
+#undef SCANTYPE_COLD
+#undef SCANTYPE_OBLITERATE
+
+#undef EFFECT_PROB_VERYLOW
+#undef EFFECT_PROB_LOW
+#undef EFFECT_PROB_MEDIUM
+#undef EFFECT_PROB_HIGH
+#undef EFFECT_PROB_VERYHIGH
+
+#undef FAIL
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 550d1eaa80a..b10bcfce92b 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi
index fc3d36fd310..43dcda058a5 100644
Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index cc946cfab32..24f9048fc45 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi
index cbec4b7a7e5..9cee4e8a3bb 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/icons/obj/machines/heavy_lathe.dmi b/icons/obj/machines/heavy_lathe.dmi
index 1189687d861..68557159eb4 100644
Binary files a/icons/obj/machines/heavy_lathe.dmi and b/icons/obj/machines/heavy_lathe.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index b104e9f60f2..c08bebbd9c9 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1295,6 +1295,7 @@
#include "code\modules\research\circuitprinter.dm"
#include "code\modules\research\designs.dm"
#include "code\modules\research\destructive_analyzer.dm"
+#include "code\modules\research\experimentor.dm"
#include "code\modules\research\message_server.dm"
#include "code\modules\research\protolathe.dm"
#include "code\modules\research\rd-readme.dm"