@@ -340,7 +340,7 @@ nanoui is used to open and update nano browser uis
winset(user, "mapwindow.map", "focus=true") // return keyboard focus to map
on_close_winset()
//onclose(user, window_id)
- nanomanager.ui_opened(src)
+ SSnano.ui_opened(src)
/**
* Close this UI
@@ -349,7 +349,7 @@ nanoui is used to open and update nano browser uis
*/
/datum/nanoui/proc/close()
is_auto_updating = 0
- nanomanager.ui_closed(src)
+ SSnano.ui_closed(src)
user << browse(null, "window=[window_id]")
/**
@@ -392,7 +392,7 @@ nanoui is used to open and update nano browser uis
return
if (src_object && src_object.Topic(href, href_list))
- nanomanager.update_uis(src_object) // update all UIs attached to src_object
+ SSnano.update_uis(src_object) // update all UIs attached to src_object
/**
* Process this UI, updating the entire UI or just the status (aka visibility)
@@ -406,7 +406,7 @@ nanoui is used to open and update nano browser uis
if (!src_object || !user)
close()
return
-
+
if (status && (update || is_auto_updating))
src_object.ui_interact(user, ui_key, src) // Update the UI (update_status() is called whenever a UI is updated)
else
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index df41e44c61f..2d5ead77aff 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -84,7 +84,7 @@
/obj/item/weapon/paper/attack_self(mob/user)
user.examinate(src)
- if(rigged && (events.holiday == "April Fool's Day"))
+ if(rigged && (SSevent.holiday == "April Fool's Day"))
if(spam_flag == 0)
spam_flag = 1
playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index a85940d0f81..e4e8a72694d 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -47,7 +47,7 @@
papers.Remove(P)
else
P = new /obj/item/weapon/paper
- if(events.holiday == "April Fool's Day")
+ if(SSevent.holiday == "April Fool's Day")
if(prob(30))
P.info = "
HONK HONK HONK HONK HONK HONK HONK
HOOOOOOOOOOOOOOOOOOOOOONK
APRIL FOOLS"
P.rigged = 1
diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm
index 0cec896235e..e30567795c0 100644
--- a/code/modules/power/antimatter/shielding.dm
+++ b/code/modules/power/antimatter/shielding.dm
@@ -155,7 +155,8 @@ proc/cardinalrange(var/center)
/obj/machinery/am_shielding/proc/setup_core()
processing = 1
- machines.Add(src)
+ machines |= src
+ SSmachine.processing |= src
if(!control_unit) return
control_unit.linked_cores.Add(src)
control_unit.reported_core_efficiency += efficiency
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 7f933f37e06..7014dec8cc4 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -714,7 +714,7 @@
)
// update the ui if it exists, returns null if no ui is passed/found
- ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+ ui = SSnano.try_update_ui(user, src, ui_key, ui, data)
if (!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index a9f1c3a0611..3ee6979100f 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -217,7 +217,7 @@
// rebuild all power networks from scratch - only called at world creation or by the admin verb
-/proc/makepowernets()
+/datum/subsystem/power/proc/makepowernets()
for(var/datum/powernet/PN in powernets)
del(PN)
powernets.Cut()
@@ -356,10 +356,10 @@
////////////////////////////////////////////
/datum/powernet/New()
- powernets += src
+ SSpower.powernets += src
/datum/powernet/Destroy()
- powernets -= src
+ SSpower.powernets -= src
/datum/powernet/proc/is_empty()
return !cables.len && !nodes.len
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 1ed275131b6..c502e814eff 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -34,8 +34,7 @@
narsie_spawn_animation()
sleep(70)
- if(emergency_shuttle)
- emergency_shuttle.incall(0.3) // Cannot recall
+ SSshuttle.emergency.request(null, 0.3) // Cannot recall
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)
diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm
index 8f1443cb6c3..78998bac96e 100644
--- a/code/modules/power/singularity/singularity.dm
+++ b/code/modules/power/singularity/singularity.dm
@@ -32,7 +32,7 @@
src.energy = starting_energy
..()
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
for(var/obj/machinery/power/singularity_beacon/singubeacon in world)
if(singubeacon.active)
target = singubeacon
@@ -40,7 +40,7 @@
return
/obj/singularity/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
/obj/singularity/Move(atom/newloc, direct)
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index 64d0ac7bbd4..3ee6f487554 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -315,7 +315,7 @@
)
// update the ui if it exists, returns null if no ui is passed/found
- ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+ ui = SSnano.try_update_ui(user, src, ui_key, ui, data)
if (!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm
index 7c70cb2c484..c0341f3eb52 100644
--- a/code/modules/power/solar.dm
+++ b/code/modules/power/solar.dm
@@ -1,8 +1,6 @@
#define SOLAR_MAX_DIST 40
#define SOLARGENRATE 1500
-var/list/solars_list = list()
-
/obj/machinery/power/solar
name = "solar panel"
desc = "A solar electrical generator."
@@ -108,14 +106,12 @@ var/list/solars_list = list()
//calculates the fraction of the sunlight that the panel recieves
/obj/machinery/power/solar/proc/update_solar_exposure()
- if(!sun)
- return
if(obscured)
sunfrac = 0
return
//find the smaller angle between the direction the panel is facing and the direction of the sun (the sign is not important here)
- var/p_angle = min(abs(adir - sun.angle), 360 - abs(adir - sun.angle))
+ var/p_angle = min(abs(adir - SSsun.angle), 360 - abs(adir - SSsun.angle))
if(p_angle > 90) // if facing more than 90deg from sun, zero output
sunfrac = 0
@@ -127,7 +123,7 @@ var/list/solars_list = list()
/obj/machinery/power/solar/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY
if(stat & BROKEN)
return
- if(!sun || !control) //if there's no sun or the panel is not linked to a solar control computer, no need to proceed
+ if(!control) //if there's no sun or the panel is not linked to a solar control computer, no need to proceed
return
if(powernet)
@@ -178,10 +174,12 @@ var/list/solars_list = list()
var/ax = x // start at the solar panel
var/ay = y
var/turf/T = null
+ var/dx = SSsun.dx
+ var/dy = SSsun.dy
for(var/i = 1 to 20) // 20 steps is enough
- ax += sun.dx // do step
- ay += sun.dy
+ ax += dx // do step
+ ay += dy
T = locate( round(ax,0.5),round(ay,0.5),z)
@@ -308,12 +306,12 @@ var/list/solars_list = list()
/obj/machinery/power/solar_control/disconnect_from_network()
..()
- solars_list.Remove(src)
+ SSsun.solars.Remove(src)
/obj/machinery/power/solar_control/connect_to_network()
var/to_return = ..()
if(powernet) //if connected and not already in solar_list...
- solars_list |= src //... add it
+ SSsun.solars |= src //... add it
return to_return
//search for unconnected panels and trackers in the computer powernet and connect them
@@ -341,7 +339,7 @@ var/list/solars_list = list()
cdir = targetdir //...the current direction is the targetted one (and rotates panels to it)
if(2) // auto-tracking
if(connected_tracker)
- connected_tracker.set_angle(sun.angle)
+ connected_tracker.set_angle(SSsun.angle)
set_panels(cdir)
updateDialog()
@@ -475,7 +473,7 @@ var/list/solars_list = list()
track = text2num(href_list["track"])
if(track == 2)
if(connected_tracker)
- connected_tracker.set_angle(sun.angle)
+ connected_tracker.set_angle(SSsun.angle)
set_panels(cdir)
else if (track == 1) //begin manual tracking
src.targetdir = src.cdir
@@ -485,7 +483,7 @@ var/list/solars_list = list()
if(href_list["search_connected"])
search_for_connected()
if(connected_tracker && track == 2)
- connected_tracker.set_angle(sun.angle)
+ connected_tracker.set_angle(SSsun.angle)
set_panels(cdir)
src.updateUsrDialog()
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index 75d5a076186..f30ce4493de 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -30,11 +30,11 @@ obj/item/weapon/gun/energy/laser/retro
/obj/item/weapon/gun/energy/laser/captain/New()
..()
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
/obj/item/weapon/gun/energy/laser/captain/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
@@ -115,11 +115,11 @@ obj/item/weapon/gun/energy/laser/retro
/obj/item/weapon/gun/energy/laser/bluetag/New()
..()
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
/obj/item/weapon/gun/energy/laser/bluetag/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
@@ -154,11 +154,11 @@ obj/item/weapon/gun/energy/laser/retro
/obj/item/weapon/gun/energy/laser/redtag/New()
..()
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
/obj/item/weapon/gun/energy/laser/redtag/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm
index 0a4f961eb78..6737f748e4d 100644
--- a/code/modules/projectiles/guns/energy/nuclear.dm
+++ b/code/modules/projectiles/guns/energy/nuclear.dm
@@ -24,11 +24,11 @@
/obj/item/weapon/gun/energy/gun/nuclear/New()
..()
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
/obj/item/weapon/gun/energy/gun/nuclear/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
@@ -62,7 +62,7 @@
M << "
You feel a wave of heat wash over you."
M.apply_effect(300, IRRADIATE)
crit_fail = 1 //break the gun so it stops recharging
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
update_icon()
return 0
@@ -109,4 +109,4 @@
/obj/item/weapon/gun/energy/gun/turret
name = "hybrid turret gun"
desc = "A basic hybrid energy gun with two settings: Stun and kill."
- ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
\ No newline at end of file
+ ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 4db3e4a9ffb..561e8a15f5e 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -33,11 +33,11 @@
/obj/item/weapon/gun/energy/floragun/New()
..()
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
/obj/item/weapon/gun/energy/floragun/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
@@ -69,11 +69,11 @@
/obj/item/weapon/gun/energy/meteorgun/New()
..()
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
/obj/item/weapon/gun/energy/meteorgun/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
/obj/item/weapon/gun/energy/meteorgun/process()
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 8f28a53effc..f79e0b24d0c 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -32,11 +32,11 @@
/obj/item/weapon/gun/energy/gun/advtaser/cyborg/New()
..()
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
/obj/item/weapon/gun/energy/gun/advtaser/cyborg/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
/obj/item/weapon/gun/energy/gun/advtaser/cyborg/process() //Every [recharge_time] ticks, recharge a shot for the cyborg
@@ -72,11 +72,11 @@
/obj/item/weapon/gun/energy/crossbow/New()
..()
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
/obj/item/weapon/gun/energy/crossbow/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm
index c575632c498..063e135516a 100644
--- a/code/modules/projectiles/guns/magic.dm
+++ b/code/modules/projectiles/guns/magic.dm
@@ -46,11 +46,11 @@
..()
charges = max_charges
chambered = new ammo_type(src)
- if(can_charge) processing_objects.Add(src)
+ if(can_charge) SSobj.processing.Add(src)
/obj/item/weapon/gun/magic/Destroy()
- if(can_charge) processing_objects.Remove(src)
+ if(can_charge) SSobj.processing.Remove(src)
..()
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index 2e3672c2866..0022664d00f 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -28,7 +28,7 @@
energy = min(energy + addenergy, max_energy)
if(energy != oldenergy)
use_power(1500) // This thing uses up alot of power (this is still low as shit for creating reagents from thin air)
- nanomanager.update_uis(src) // update all UIs attached to src
+ SSnano.update_uis(src) // update all UIs attached to src
/obj/machinery/chem_dispenser/power_change()
if(powered())
@@ -36,7 +36,7 @@
else
spawn(rand(0, 15))
stat |= NOPOWER
- nanomanager.update_uis(src) // update all UIs attached to src
+ SSnano.update_uis(src) // update all UIs attached to src
/obj/machinery/chem_dispenser/process()
@@ -103,7 +103,7 @@
data["chemicals"] = chemicals
// update the ui if it exists, returns null if no ui is passed/found
- ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+ ui = SSnano.try_update_ui(user, src, ui_key, ui, data)
if (!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
@@ -158,7 +158,7 @@
user.drop_item()
B.loc = src
user << "You add the beaker to the machine!"
- nanomanager.update_uis(src) // update all UIs attached to src
+ SSnano.update_uis(src) // update all UIs attached to src
overlays += "disp_beaker"
/obj/machinery/chem_dispenser/attack_ai(mob/user as mob)
@@ -668,7 +668,7 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime)
if(archive_diseases[id])
var/datum/disease/advance/A = archive_diseases[id]
A.AssignName(new_name)
- for(var/datum/disease/advance/AD in active_diseases)
+ for(var/datum/disease/advance/AD in SSdisease.processing)
AD.Refresh()
src.updateUsrDialog()
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents.dm
index 2151bbec53f..02983913ee8 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents.dm
@@ -650,6 +650,10 @@ datum/reagent/space_cleaner/reaction_turf(var/turf/T, var/volume)
for(var/mob/living/carbon/slime/M in T)
M.adjustToxLoss(rand(5,10))
+ if(istype(T, /turf/simulated/floor))
+ var/turf/simulated/floor/F = T
+ if(volume >= 1)
+ F.dirt = 0
datum/reagent/space_cleaner/reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
if(iscarbon(M))
@@ -689,6 +693,7 @@ datum/reagent/cryptobiolin/on_mob_life(var/mob/living/M as mob)
if(!M.confused)
M.confused = 1
M.confused = max(M.confused, 20)
+ ..()
return
datum/reagent/impedrezene
@@ -854,4 +859,4 @@ datum/reagent/plantnutriment/robustharvestnutriment
// Undefine the alias for REAGENTS_EFFECT_MULTIPLER
-#undef REM
\ No newline at end of file
+#undef REM
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index 6fe8b06f328..b4a3825e249 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -38,11 +38,11 @@ Borg Hypospray
modes[R] = iteration
iteration++
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
/obj/item/weapon/reagent_containers/borghypo/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
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/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm
index e807beeaedb..ea9fda485e7 100644
--- a/code/modules/scripting/Implementations/Telecomms.dm
+++ b/code/modules/scripting/Implementations/Telecomms.dm
@@ -190,6 +190,11 @@
interpreter.SetProc("randseed", /proc/n_randseed)
interpreter.SetProc("min", /proc/n_min)
interpreter.SetProc("max", /proc/n_max)
+ interpreter.SetProc("sin", /proc/n_sin)
+ interpreter.SetProc("cos", /proc/n_cos)
+ interpreter.SetProc("asin", /proc/n_asin)
+ interpreter.SetProc("acos", /proc/n_acos)
+ interpreter.SetProc("log", /proc/n_log)
// Time
interpreter.SetProc("time", /proc/n_time)
diff --git a/code/modules/scripting/Implementations/_Logic.dm b/code/modules/scripting/Implementations/_Logic.dm
index 343adf34d43..6fd47acf7c8 100644
--- a/code/modules/scripting/Implementations/_Logic.dm
+++ b/code/modules/scripting/Implementations/_Logic.dm
@@ -262,6 +262,31 @@
if(isnum(num)&&isnum(min)&&isnum(max))
return ((min <= num) && (num <= max))
+// Returns the sine of num
+/proc/n_sin(var/num)
+ if(isnum(num))
+ return sin(num)
+
+// Returns the cosine of num
+/proc/n_cos(var/num)
+ if(isnum(num))
+ return cos(num)
+
+// Returns the arcsine of num
+/proc/n_asin(var/num)
+ if(isnum(num)&&-1<=num&&num<=1)
+ return arcsin(num)
+
+// Returns the arccosine of num
+/proc/n_acos(var/num)
+ if(isnum(num)&&-1<=num&&num<=1)
+ return arccos(num)
+
+// Returns the natural log of num
+/proc/n_log(var/num)
+ if(isnum(num)&&0
S.dwidth)
+ return 2
+ if(width-dwidth > S.width-S.dwidth)
+ return 3
+ if(dheight > S.dheight)
+ return 4
+ if(height-dheight > S.height-S.dheight)
+ return 5
+ //check the dock isn't occupied
+ if(S.get_docked())
+ return 6
+ return 0 //0 means we can dock
+
+ //call the shuttle to destination S
+ proc/request(obj/docking_port/stationary/S)
+ if(canDock(S))
+ ERROR("[type](\"[name]\") cannot dock at [S]\")")
+ return 1 //we can't dock at S
+
+ switch(mode)
+ if(SHUTTLE_CALL)
+ if(S == destination)
+ if(world.time <= timer)
+ timer = world.time
+ else
+ destination = S
+ timer = world.time
+ if(SHUTTLE_RECALL)
+ if(S == destination)
+ timer = world.time - timeLeft(1)
+ else
+ destination = S
+ timer = world.time
+ mode = SHUTTLE_CALL
+ else
+ destination = S
+ mode = SHUTTLE_CALL
+ timer = world.time
+ enterTransit() //hyperspace
+
+ //recall the shuttle to where it was previously
+ proc/cancel()
+ if(mode != SHUTTLE_CALL)
+ return
+
+ timer = world.time - timeLeft(1)
+ mode = SHUTTLE_RECALL
+
+ proc/enterTransit()
+ previous = null
+// if(!destination)
+// return
+ var/obj/docking_port/stationary/S0 = get_docked()
+ var/obj/docking_port/stationary/S1 = findTransitDock()
+ if(S1)
+ if(dock(S1))
+ WARNING("shuttle \"[id]\" could not enter transit space. Docked at [S0 ? S0.id : "null"]. Transit dock [S1 ? S1.id : "null"].")
+ else
+ previous = S0
+ else
+ WARNING("shuttle \"[id]\" could not enter transit space. S0=[S0 ? S0.id : "null"] S1=[S1 ? S1.id : "null"]")
+
+ //this is the main proc. It instantly moves our mobile port to stationary port S1
+ //it handles all the generic behaviour, such as sanity checks, closing doors on the shuttle, stunning mobs, etc
+ proc/dock(obj/docking_port/stationary/S1)
+ . = canDock(S1)
+ if(.)
+ ERROR("[type](\"[name]\") cannot dock at [S1]")
+ return .
+
+ if(canMove())
+ return -1
+
+ closePortDoors()
+
+// //rotate transit docking ports, so we don't need zillions of variants
+// if(istype(S1, /obj/docking_port/stationary/transit))
+// S1.dir = turn(NORTH, -travelDir)
+
+ var/obj/docking_port/stationary/S0 = get_docked()
+ var/turf_type = /turf/space
+ var/area_type = /area/space
+ if(S0)
+ if(S0.turf_type)
+ turf_type = S0.turf_type
+ if(S0.area_type)
+ area_type = S0.area_type
+
+ var/list/L0 = return_ordered_turfs()
+ var/list/L1 = return_ordered_turfs(S1.x, S1.y, S1.z, S1.dir)
+
+ //remove area surrounding docking port
+ if(areaInstance.contents.len)
+ var/area/A0 = locate("[area_type]")
+ if(!A0)
+ A0 = new area_type(null)
+ for(var/turf/T0 in L0)
+ A0.contents += T0
+
+ //move or squish anything in the way ship at destination
+ roadkill(L1, S1.dir)
+
+ for(var/i=1, i<=L0.len, ++i)
+ var/turf/T0 = L0[i]
+ if(!istype(T0, /turf/simulated/shuttle)) //only move shuttle turfs!
+ continue
+
+ var/turf/T1 = L1[i]
+ if(!T1)
+ continue
+
+ T0.copyTurf(T1)
+ areaInstance.contents += T1
+
+ //copy over air
+ if(istype(T1, /turf/simulated))
+ var/turf/simulated/Ts1 = T1
+ Ts1.copy_air_with_tile(T0)
+
+ //move mobile to new location
+ loc = S1.loc
+ dir = S1.dir
+
+ //move all objects
+ for(var/obj/O in T0)
+ if(O.invisibility >= 101)
+ continue
+ O.loc = T1
+
+ //close open doors
+ if(istype(O, /obj/machinery/door))
+ var/obj/machinery/door/Door = O
+ spawn(-1)
+ if(Door)
+ Door.close()
+
+ for(var/mob/M in T0)
+ if(!M.move_on_shuttle)
+ continue
+ M.loc = T1
+
+ //docking turbulence
+ if(M.client)
+ spawn(0)
+ if(M.buckled)
+ shake_camera(M, 2, 1) // turn it down a bit come on
+ else
+ shake_camera(M, 7, 1)
+ if(istype(M, /mob/living/carbon))
+ if(!M.buckled)
+ M.Weaken(3)
+
+ T0.ChangeTurf(turf_type)
+
+ //air system updates
+ for(var/turf/T1 in L1)
+ T1.shift_to_subarea()
+ SSair.remove_from_active(T1)
+ T1.CalculateAdjacentTurfs()
+ SSair.add_to_active(T1,1)
+
+ for(var/turf/T0 in L0)
+ T0.shift_to_subarea()
+ SSair.remove_from_active(T0)
+ T0.CalculateAdjacentTurfs()
+ SSair.add_to_active(T0,1)
+
+/*
+ if(istype(S1, /obj/docking_port/stationary/transit))
+ var/d = turn(dir, 180 + travelDir)
+ for(var/turf/space/transit/T in S1.return_ordered_turfs())
+ T.pushdirection = d
+ T.update_icon()
+*/
+
+ proc/findTransitDock()
+ var/obj/docking_port/stationary/transit/T = SSshuttle.getDock("[id]_transit")
+ if(T && !canDock(T))
+ return T
+ /* commented out due to issues with rotation
+ for(var/obj/docking_port/stationary/transit/S in SSshuttle.transit)
+ if(S.id)
+ continue
+ if(!canDock(S))
+ return S
+ */
+
+
+ //shuttle-door closing is handled in the dock() proc whilst looping through turfs
+ //this one closes the door where we are docked at, if there is one there.
+ proc/closePortDoors()
+ var/turf/T = get_step(loc, turn(dir,180))
+ if(T)
+ var/obj/machinery/door/Door = locate() in T
+ if(Door)
+ spawn(-1)
+ Door.close()
+
+ proc/roadkill(list/L, dir, x, y)
+ for(var/turf/T in L)
+ for(var/atom/movable/AM in T)
+ if(ismob(AM))
+ if(istype(AM, /mob/living))
+ var/mob/living/M = AM
+ M.Paralyse(10)
+ M.take_organ_damage(80)
+ M.anchored = 0
else
- shake_camera(M, 7, 1)
- if(istype(M, /mob/living/carbon))
- if(!M.buckled)
- M.Weaken(3)
+ continue
- moving = 0
- return 1
+ if(!AM.anchored)
+ step(AM, dir)
+ else
+ qdel(AM)
+/*
+ //used to check if atom/A is within the shuttle's bounding box
+ proc/onShuttleCheck(atom/A)
+ var/turf/T = get_turf(A)
+ if(!T)
+ return 0
+ var/list/L = return_coords()
+ if(L[1] > L[3])
+ L.Swap(1,3)
+ if(L[2] > L[4])
+ L.Swap(2,4)
+
+ if(L[1] <= T.x && T.x <= L[3])
+ if(L[2] <= T.y && T.y <= L[4])
+ return 1
+ return 0
+*/
+ //used by shuttle subsystem to check timers
+ proc/check()
+ var/timeLeft = timeLeft(1)
+ if(timeLeft <= 0)
+ switch(mode)
+ if(SHUTTLE_CALL)
+ if(dock(destination))
+ setTimer(20) //can't dock for some reason, try again in 2 seconds
+ return
+ if(SHUTTLE_RECALL)
+ if(dock(previous))
+ setTimer(20) //can't dock for some reason, try again in 2 seconds
+ return
+ mode = SHUTTLE_IDLE
+ timer = 0
+ destination = null
+
+
+ proc/setTimer(wait)
+ if(timer <= 0)
+ timer = world.time
+ timer += wait - timeLeft(1)
+
+ //returns timeLeft
+ proc/timeLeft(divisor)
+ if(divisor <= 0)
+ divisor = 10
+ if(!timer)
+ return round(callTime/divisor, 1)
+ return max( round((timer+callTime-world.time)/divisor,1), 0 )
+
+ proc/getStatusText()
+ var/obj/docking_port/stationary/dockedAt = get_docked()
+ . = (dockedAt && dockedAt.name) ? dockedAt.name : "unknown"
+ if(istype(dockedAt, /obj/docking_port/stationary/transit))
+ var/obj/docking_port/stationary/dst
+ if(mode == SHUTTLE_RECALL)
+ dst = previous
+ else
+ dst = destination
+ . += " towards [dst ? dst.name : "unknown location"] ([timeLeft(600)]mins)"
/obj/machinery/computer/shuttle
name = "Shuttle Console"
@@ -54,17 +474,34 @@ datum/shuttle_manager/proc/move_shuttle(var/override_delay)
icon_state = "shuttle"
req_access = list( )
circuit = /obj/item/weapon/circuitboard/shuttle
- var/id
+ var/shuttleId
+ var/possible_destinations = ""
+
+/obj/machinery/computer/shuttle/New(location, obj/item/weapon/circuitboard/shuttle/C)
+ ..()
+ if(istype(C))
+ possible_destinations = C.possible_destinations
+ shuttleId = C.shuttleId
/obj/machinery/computer/shuttle/attack_hand(user as mob)
if(..(user))
return
src.add_fingerprint(usr)
- var/dat
- dat = text("Send Shuttle")
- //user << browse("[dat]", "window=miningshuttle;size=200x100")
- var/datum/browser/popup = new(user, "miningshuttle", name, 200, 140)
- popup.set_content(dat)
+
+ var/list/options = params2list(possible_destinations)
+ var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
+ var/dat = "Status: [M ? M.getStatusText() : "*Missing*"]
"
+ if(M)
+ for(var/obj/docking_port/stationary/S in SSshuttle.stationary)
+ if(!options.Find(S.id))
+ continue
+ if(M.canDock(S))
+ continue
+ dat += "Send to [S.name]
"
+ dat += "Close"
+
+ var/datum/browser/popup = new(user, "computer", M ? M.name : "shuttle", 300, 200)
+ popup.set_content("[dat]")
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
@@ -76,15 +513,12 @@ datum/shuttle_manager/proc/move_shuttle(var/override_delay)
if(!allowed(usr))
usr << "Access denied."
return
+
if(href_list["move"])
- if(id in shuttles)
- var/datum/shuttle_manager/s = shuttles[id]
- if (s.move_shuttle())
- usr << "Shuttle recieved message and will be sent shortly."
- else
- usr << "Shuttle is already moving."
- else
- usr << "Invalid shuttle requested."
+ switch(SSshuttle.moveShuttle(shuttleId, href_list["move"], 1))
+ if(0) usr << "Shuttle recieved message and will be sent shortly."
+ if(1) usr << "Invalid shuttle requested."
+ else usr << "Unable to comply."
/obj/machinery/computer/shuttle/emag_act(mob/user as mob)
if(!emagged)
@@ -95,20 +529,30 @@ datum/shuttle_manager/proc/move_shuttle(var/override_delay)
/obj/machinery/computer/shuttle/ferry
name = "transport ferry console"
circuit = /obj/item/weapon/circuitboard/ferry
- id = "ferry"
+ shuttleId = "ferry"
+ possible_destinations = "ferry_home;ferry_away"
+
/obj/machinery/computer/shuttle/ferry/request
name = "ferry console"
circuit = /obj/item/weapon/circuitboard/ferry/request
var/cooldown //prevents spamming admins
+ possible_destinations = "ferry_home"
-/obj/machinery/computer/shuttle/ferry/request/Topic(href, href_list)
- if(href_list["move"])
- if(cooldown)
- return
- cooldown = 1
- usr << "Docking locks are engaged. Requesting authorization..."
- var/datum/shuttle_manager/s = shuttles["ferry"]
- admins << "FERRY: [key_name(usr)] (?) (JMP) (Move) is requesting to move the transport ferry to [s.location == /area/shuttle/transport1/centcom ? "the station" : "Centcom"]."
- spawn(600) //One minute cooldown
- cooldown = 0
\ No newline at end of file
+
+
+#undef DOCKING_PORT_HIGHLIGHT
+
+
+/turf/proc/copyTurf(turf/T)
+ if(T.type != type)
+ T = new type(T)
+ if(T.icon_state != icon_state)
+ T.icon_state = icon_state
+ if(T.icon != icon)
+ T.icon = icon
+ if(T.color != color)
+ T.color = color
+ if(T.dir != dir)
+ T.dir = dir
+ return T
\ No newline at end of file
diff --git a/code/modules/surgery/generic_steps.dm b/code/modules/surgery/generic_steps.dm
index 700d2b87e59..7683c9444ff 100644
--- a/code/modules/surgery/generic_steps.dm
+++ b/code/modules/surgery/generic_steps.dm
@@ -58,7 +58,7 @@
//saw bone
/datum/surgery_step/saw
- implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/melee/arm_blade = 75, /obj/item/weapon/hatchet = 35, /obj/item/weapon/butch = 25)
+ implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/melee/arm_blade = 75, /obj/item/weapon/hatchet = 35, /obj/item/weapon/kitchenknife/butcher = 25)
time = 64
/datum/surgery_step/saw/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm
index 8652fc2978e..ae8b5147e91 100644
--- a/code/modules/surgery/lipoplasty.dm
+++ b/code/modules/surgery/lipoplasty.dm
@@ -9,7 +9,7 @@
//cut fat
/datum/surgery_step/cut_fat
- implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/hatchet = 35, /obj/item/weapon/butch = 25)
+ implements = list(/obj/item/weapon/circular_saw = 100, /obj/item/weapon/hatchet = 35, /obj/item/weapon/kitchenknife/butcher = 25)
time = 64
/datum/surgery_step/cut_fat/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm
index e0eccaff92b..98c42e57f46 100644
--- a/code/modules/telesci/telepad.dm
+++ b/code/modules/telesci/telepad.dm
@@ -119,14 +119,14 @@
/obj/item/weapon/rcs/New()
..()
- processing_objects.Add(src)
+ SSobj.processing.Add(src)
/obj/item/weapon/rcs/examine(mob/user)
..()
user << "There are [rcharges] charge\s left."
/obj/item/weapon/rcs/Destroy()
- processing_objects.Remove(src)
+ SSobj.processing.Remove(src)
..()
/obj/item/weapon/rcs/process()
if(rcharges > 10)
@@ -154,4 +154,4 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
- user << " You emag the RCS. Click on it to toggle between modes."
\ No newline at end of file
+ user << " You emag the RCS. Click on it to toggle between modes."
diff --git a/code/world.dm b/code/world.dm
index c31d225da1d..55f7260d0d9 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -3,11 +3,11 @@
turf = /turf/space
area = /area/space
view = "15x15"
- cache_lifespan = 1
-
-#define RECOMMENDED_VERSION 495
+ cache_lifespan = 7
/world/New()
+ map_ready = 1
+
#if (PRELOAD_RSC == 0)
external_rsc_urls = file2list("config/external_rsc_urls.txt","\n")
var/i=1
@@ -30,9 +30,6 @@
diaryofmeanpeople << "\n\nStarting up. [time2text(world.timeofday, "hh:mm.ss")]\n---------------------"
changelog_hash = md5('html/changelog.html') //used for telling if the changelog has changed recently
- if(byond_version < RECOMMENDED_VERSION)
- world.log << "Your server's BYOND version does not meet the recommended requirements for /tg/station code. Please update BYOND."
-
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
load_configuration()
@@ -54,48 +51,21 @@
timezoneOffset = text2num(time2text(0,"hh")) * 36000
- sun = new /datum/sun()
- radio_controller = new /datum/controller/radio()
- data_core = new /obj/effect/datacore()
- paiController = new /datum/paiController()
-
if(config.sql_enabled)
if(!setup_database_connection())
world.log << "Your server failed to establish a connection with the database."
else
world.log << "Database connection established."
- plmaster = new /obj/effect/overlay()
- plmaster.icon = 'icons/effects/tile_effects.dmi'
- plmaster.icon_state = "plasma"
- plmaster.layer = FLY_LAYER
- plmaster.mouse_opacity = 0
- slmaster = new /obj/effect/overlay()
- slmaster.icon = 'icons/effects/tile_effects.dmi'
- slmaster.icon_state = "sleeping_agent"
- slmaster.layer = FLY_LAYER
- slmaster.mouse_opacity = 0
+ data_core = new /obj/effect/datacore()
- setup_map_transitions()
- for(var/i=0, iYou have been inactive for more than 10 minutes and have been disconnected."
- del(C)
-#undef INACTIVITY_KICK
-
-
/world/proc/load_mode()
var/list/Lines = file2list("data/mode.txt")
if(Lines.len)
diff --git a/config/tips.txt b/config/tips.txt
new file mode 100644
index 00000000000..4738b3c6780
--- /dev/null
+++ b/config/tips.txt
@@ -0,0 +1,79 @@
+You can drag yourself to a chair or a bed to buckle yourself to it.
+You can drag yourself onto a photocopier to copy your ass.
+Space transitions change every round, but are consistent within a round.
+People can be ejected from the cloner before they are done by cutting power to the clone pod.
+If you've been feeding some slimes for at least two generations, you can order them around, and even have them follow you if they like you enough.
+Almost all slime cores have two or more different effects.
+With the right slime cores, you can get up to nine uses of a single slime's effects.
+Touching a supermatter shard is akin to hugging a singularity.
+To catch thrown items, toggle throw mode on and make sure you have an open hand.
+Updating sec records regularly helps avoid confusion in the brig!
+You can drag the icon of an equipped headset or PDA onto your screen to interact with them.
+The mime's invisible wall will block electrodes and other projectiles, but beams pass straight through it like windows.
+The Librarian system is much more robust than most people think! Mess around with it, see if you can log who takes out the books for radio-reading.
+Use a pair of handcuffs on a pair of orange shoes (standard prisoner issue) to chain them together.
+Revolutionaries brainwashed by Rev leaders can have their opinions swayed back to nanotrasen loyalty by enough heavy objects to the head.
+Husked corpses that have been drained of their genomes by a changeling also lack blood in their veins, unlike burned or space frozen corpses.
+The stethoscope's utility extends beyond lung and heart checkups. They can also be used to crack certain safes.
+Chloral Hydrate can be counteracted by having coffee in your system!
+The AI system integrity restorer in both the RD's office and on the bridge can revive a dead AI loaded onto an intellicard.
+If an anomaly appears, scan it with an analyzer and then ping the frequency it gives you with a remote signaling device.
+Various creatures can crawl through air vents by holding alt while left clicking them.
+Nuclear operatives can be extremely powerful, but only if they work together. Communication is key!
+A rogue AI can be an extremely powerful tool for traitors, but be wary of the laws you use to slave it to you, as it may try to find loopholes to get back at you.
+You can drag yourself onto tables to climb on them. This takes a moment and requires two free hands.
+You can drag other players onto yourself to open the strip menu, letting you remove their equipment or force them to equip something.
+Aliens are by far the most powerful close-quarters combat menace. Fight them at a distance to gain the upper hand!
+Aliens take double damage from all burn sources, such as lasers and fires. Flamethrowers are extremely effective against them.
+As an alien, your most powerful weapon is the facehugger. It can instantly win any fight, but can be completely blocked by certain headgear. Strip downed victims before applying one.
+Monkeys can still wear some human items, such as masks and backpacks, but they cannot bring anything with them when vent crawling.
+Nuclear operatives are very effective in a blitzkrieg tactic: attacking almost as soon as the round starts and well before the crew is prepared.
+You can use a fire extinguisher as a ghetto jetpack by spraying in the opposite direction of where you want to go. This also works with any gun.
+Coffee can keep you very warm. Drink a lot before running around through exposed space.
+Both cargo and the HoP can make you fill out a form for their services.
+You can destroy a blob by shooting emitters at its core.
+You can electrify a grille by having an exposed wire node underneath it.
+If you press the tab key, you can toggle hotkey mode, which allows you to move using WASD and perform other actions using hotkeys.
+You can hack MULE bots to let you ride them.
+You can hack most vending machines to obtain contraband items.
+You can use a multitool on the Cargo Ordering Console circuitboards to get contraband crates.
+The cryptographic sequencer (emag) has an enormous amount of functions beyond breaking open locks and hacking cyborgs, experiment!
+Touching anything without black, insulated, or brown gloves will leave fingerprints, which can be analyzed by detectives to find the suspect. Be careful of what you leave prints on!
+Blobs are extremely powerful and are impossible to defeat alone. Communicate with the crew and rally them against the threat!
+You can fight blob pieces diagonally, as they can only expand onto adjacent tiles in cardinal directions.
+Security huds and secglass huds can tell you if someone is implanted with a loyalty implant. Use this to your advantage in a revolution.
+Loyalty implants can only prevent someone from being turned into a cultist: unlike revolutionaries, it will not de-cult them if they have already been converted.
+Don't neglect upgrading your machines with the machine parts produced by research! These can seriously improve the efficiency of your equipment.
+Cyborgs are impervious to fires and temperature, and can walk in a blazing inferno without worry. Don't shy away from setting the whole station on fire as a malfunctioning or rogue AI!
+The heads of staff, especially the Head of Security and the Captain, are usually extremely difficult to kill. If one of them is your target as a traitor, plan carefully.
+The Steal DNA sting from changelings counts for your genome absorb objective, but does not let you change your powers.
+Chemists are among the most powerful people on the station. They can survive almost anything thanks to all the chemicals in them that have basically replaced their blood.
+The station is capable of being entirely powered by the solar arrays, and is a much safer form of power over the singularity engine.
+The singularity engine is extremely dangerous if containment fails. Check back on it very frequently and call the shuttle immediately when, not if, it breaks free.
+Firesuits and winter coats offer mild protection from the cold, allowing you to spend longer periods of time near breaches and space than if wearing nothing at all.
+Vendors provide a very poor source of food riddled with sugar. This can affect your metabolism quite severely and it comes with many negative effects. Eat from the kitchen to stay healthy and even profit from a happy gut!
+Emergency internals tanks can be used from your hands, your pockets, your belt, or your suit storage slot (assuming you're wearing a valid exosuit).
+When walking through halls, stay on the Help intent to pass through people rather than bumping into them.
+Trying to do surgery but you keep cutting your patient? Remember to be on the help intent and to target the right limb!
+Glass shards can be welded to make glass, and metal rods can be welded to make metal. Ores can be welded, too, but this takes a lot of fuel.
+Many monsters won't attack you if you're unconscious. If you see a space bear, go to sleep, quick!
+Many monsters won't attack you if you're unconscious, but a medibot will still heal you. Keep one around when you're mining and never worry about dying again.
+Two people are critical and need your help, but you don't have time for two trips? Pull one and use the grab intent to grab the other. This will make you slower, but you will be able to take them both.
+When using the grab intent, grab someone by clicking on them then upgrade your grab by clicking on your hand slot. Holding them by the hands lets you throw them or table them.
+Can't seem to get a patient into the cryo tube or sleepers? Just drag their sprite to it to put them in it instantly. No more needing to shuffle around pulling them into it awkwardly.
+EMP blasts have a chance to make machines explode!
+Targeting your opponent's mouth in a fistfight will give you a greater chance of knocking them unconscious.
+As a security officer, examining a crew member with a secHUD allows you to set their status to arrest. You can even give a reason for the arrest warrant, as well.
+Clowns are extremely clumsy and will often misfire weapons.
+Hulks can't fire weapons because of their meaty fingers.
+The mime's crayon is edible.
+Shooting lasers at a computer console will destroy it.
+Using ethanol on a piece of paper will remove any writing on it.
+Using an emag on the gibber will allow you to throw people into it!
+Using the comms console with captain level access will allow you to broadcast announcements in BIG, RED LETTERS!
+You can repair cracked windows with a welding tool on help intent.
+Alt-click on an adjacent tile to see its contents in the top right pane.
+While observing or as a ghost, double click on people, bots, or the singularity to follow them.
+Ghosts can click on active teleporters, portals, wormholes, or the gateway to jump to its destination!
+Ghosts can double-click their corpse, or the object containing their corpse (such as the cloning scanner), to re-enter it.
+Ghosts can see inside storage items that have been left on the ground.
\ No newline at end of file
diff --git a/html/changelog.html b/html/changelog.html
index 092b4c9d99f..5d8ce1986bc 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,14 @@
-->
+
+
06 January 2015
+
JJRcop, Nienhaus updated:
+
+ - Adds emoji to OOC chat.
+
+
+
27 December 2014
Dorsidwarf updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index c68eb21a486..efcd2c9516c 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -2229,3 +2229,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
item has been made available to the Space Station 13 cargo team for the cost
of a hundred supply points, as a reward for all your hard work. Good luck, and
stay safe.
+2015-01-06:
+ JJRcop, Nienhaus:
+ - rscadd: Adds emoji to OOC chat.
diff --git a/html/changelogs/JJRcop-OOCemoji.yml b/html/changelogs/JJRcop-OOCemoji.yml
deleted file mode 100644
index fa65b93fb7e..00000000000
--- a/html/changelogs/JJRcop-OOCemoji.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: JJRcop, Nienhaus
-delete-after: True
-changes:
- - rscadd: "Adds emoji to OOC chat."
\ No newline at end of file
diff --git a/html/changelogs/Studley.yml b/html/changelogs/Studley.yml
new file mode 100644
index 00000000000..03f2481434c
--- /dev/null
+++ b/html/changelogs/Studley.yml
@@ -0,0 +1,5 @@
+author: Studley
+delete-after: True
+changes:
+ - bugfix: "Fixed NTSL division."
+ - rscadd: "Added new NTSL math functions, including 'sin,' 'cos,' 'asin,' 'acos,' and 'log.'"
diff --git a/icons/effects/crayondecal.dmi b/icons/effects/crayondecal.dmi
index 6cede450e75..dc3f8f82996 100644
Binary files a/icons/effects/crayondecal.dmi and b/icons/effects/crayondecal.dmi differ
diff --git a/icons/effects/ss13_dark_alpha6.dmi b/icons/effects/ss13_dark_alpha6.dmi
index 742337358da..44f84ec33ad 100644
Binary files a/icons/effects/ss13_dark_alpha6.dmi and b/icons/effects/ss13_dark_alpha6.dmi differ
diff --git a/icons/emoji.dmi b/icons/emoji.dmi
index a78a7e3df79..8da34d9a468 100644
Binary files a/icons/emoji.dmi and b/icons/emoji.dmi differ
diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi
index 25580035f9e..43dcda058a5 100644
Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ
diff --git a/icons/obj/crayons.dmi b/icons/obj/crayons.dmi
index 7ebabd5a81e..cb4df277f6e 100644
Binary files a/icons/obj/crayons.dmi and b/icons/obj/crayons.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/icons/obj/objects.dmi b/icons/obj/objects.dmi
index e0bbc6ea25a..51b57125584 100644
Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ
diff --git a/icons/obj/pda.dmi b/icons/obj/pda.dmi
index 848647eae2d..8bc456a4787 100644
Binary files a/icons/obj/pda.dmi and b/icons/obj/pda.dmi differ
diff --git a/icons/turf/space.dmi b/icons/turf/space.dmi
index 9f15fbbe63a..2bd62851550 100644
Binary files a/icons/turf/space.dmi and b/icons/turf/space.dmi differ
diff --git a/sound/misc/leavingtg.ogg b/sound/misc/leavingtg.ogg
new file mode 100644
index 00000000000..455dc9fb119
Binary files /dev/null and b/sound/misc/leavingtg.ogg differ
diff --git a/strings/npc_chatter.txt b/strings/npc_chatter.txt
new file mode 100644
index 00000000000..2178cdb2df2
--- /dev/null
+++ b/strings/npc_chatter.txt
@@ -0,0 +1,11 @@
+verbs_use@=touch@,hold@,poke@,punch@,smash@,assault@,wrench@,tickle@,modify@,whack@,beat@,tackle@,destroy
+verbs_touch@=pat@,mess with@,absorb@,sneeze on@,inject@,rip@,slap@,grab@,choke
+verbs_move@=run@,jog@,leg it@,slide@,cheese it@,walk@,stroll@,fly@,scoot@,yakkety@,speed@,fuck off@,escape
+nouns_insult@=gaylord@,shitcurity@,noob@,comdom@,greyshirt@,tator@,lingbin@,bitch@,whorelord@,cluwne@,monkey@,cheesemonger@,milkdrinker
+nouns_generic@=you@,you there@,guy@,person@,dude@,jerk@,officer
+nouns_objects@=thing@,tool@,whatever@,potential murder weapon@,object@,toy@,device@,whatever
+nouns_body@=ass@,head@,face@,arms@,fingers@,toes@,chest@,eyes@,nails@,groin@,stomach@,intestines@,head
+adjective_insult@=ugly@,repulsive@,dumb@,asian@,mongoloid@,childish@,captain-like@,monkey-like@,whoreish@,dimwit@,jerk-face@,vomit-inducer
+adjective_objects@=big@,small@,tiny@,round@,square@,oblong@,colorful@,dull@,shiny@,sparkling@,blinking@,awful
+adjective_generic@=nice@,pretty@,ugly@,bad@,okay@,stupid
+curse_words@=damn@,shit@,arse@,ass@,wank@,jerk@,bitch
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index 232ef06ce5e..c08bebbd9c9 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -59,7 +59,6 @@
#include "code\_globalvars\logging.dm"
#include "code\_globalvars\misc.dm"
#include "code\_globalvars\station.dm"
-#include "code\_globalvars\unused.dm"
#include "code\_globalvars\lists\flavor_misc.dm"
#include "code\_globalvars\lists\mapping.dm"
#include "code\_globalvars\lists\mobs.dm"
@@ -119,13 +118,30 @@
#include "code\controllers\_DynamicAreaLighting_TG.dm"
#include "code\controllers\configuration.dm"
#include "code\controllers\failsafe.dm"
-#include "code\controllers\garbage.dm"
-#include "code\controllers\lighting_controller.dm"
#include "code\controllers\master_controller.dm"
-#include "code\controllers\shuttle_controller.dm"
-#include "code\controllers\supply_shuttle.dm"
+#include "code\controllers\subsystems.dm"
#include "code\controllers\verbs.dm"
-#include "code\controllers\voting.dm"
+#include "code\controllers\subsystem\air.dm"
+#include "code\controllers\subsystem\bots.dm"
+#include "code\controllers\subsystem\diseases.dm"
+#include "code\controllers\subsystem\events.dm"
+#include "code\controllers\subsystem\garbage.dm"
+#include "code\controllers\subsystem\jobs.dm"
+#include "code\controllers\subsystem\lighting.dm"
+#include "code\controllers\subsystem\machines.dm"
+#include "code\controllers\subsystem\mobs.dm"
+#include "code\controllers\subsystem\nanoUI.dm"
+#include "code\controllers\subsystem\objects.dm"
+#include "code\controllers\subsystem\pipenets.dm"
+#include "code\controllers\subsystem\power.dm"
+#include "code\controllers\subsystem\radio.dm"
+#include "code\controllers\subsystem\server_maintenance.dm"
+#include "code\controllers\subsystem\shuttles.dm"
+#include "code\controllers\subsystem\sun.dm"
+#include "code\controllers\subsystem\ticker.dm"
+#include "code\controllers\subsystem\voting.dm"
+#include "code\controllers\subsystem\shuttles\emergency.dm"
+#include "code\controllers\subsystem\shuttles\supply.dm"
#include "code\datums\ai_laws.dm"
#include "code\datums\browser.dm"
#include "code\datums\computerfiles.dm"
@@ -139,7 +155,6 @@
#include "code\datums\mutations.dm"
#include "code\datums\recipe.dm"
#include "code\datums\spell.dm"
-#include "code\datums\sun.dm"
#include "code\datums\supplypacks.dm"
#include "code\datums\uplink_item.dm"
#include "code\datums\diseases\_disease.dm"
@@ -253,7 +268,6 @@
#include "code\game\gamemodes\events.dm"
#include "code\game\gamemodes\factions.dm"
#include "code\game\gamemodes\game_mode.dm"
-#include "code\game\gamemodes\gameticker.dm"
#include "code\game\gamemodes\intercept_report.dm"
#include "code\game\gamemodes\objective.dm"
#include "code\game\gamemodes\objective_items.dm"
@@ -320,7 +334,6 @@
#include "code\game\gamemodes\wizard\spellbook.dm"
#include "code\game\gamemodes\wizard\wizard.dm"
#include "code\game\jobs\access.dm"
-#include "code\game\jobs\job_controller.dm"
#include "code\game\jobs\jobs.dm"
#include "code\game\jobs\whitelist.dm"
#include "code\game\jobs\job\assistant.dm"
@@ -755,6 +768,7 @@
#include "code\modules\admin\verbs\deadsay.dm"
#include "code\modules\admin\verbs\debug.dm"
#include "code\modules\admin\verbs\diagnostics.dm"
+#include "code\modules\admin\verbs\fps.dm"
#include "code\modules\admin\verbs\getlogs.dm"
#include "code\modules\admin\verbs\mapping.dm"
#include "code\modules\admin\verbs\massmodvar.dm"
@@ -766,7 +780,6 @@
#include "code\modules\admin\verbs\pray.dm"
#include "code\modules\admin\verbs\randomverbs.dm"
#include "code\modules\admin\verbs\reestablish_db_connection.dm"
-#include "code\modules\admin\verbs\ticklag.dm"
#include "code\modules\admin\verbs\tripAI.dm"
#include "code\modules\admin\verbs\SDQL2\SDQL_2.dm"
#include "code\modules\admin\verbs\SDQL2\SDQL_2_parser.dm"
@@ -872,7 +885,6 @@
#include "code\modules\events\dust.dm"
#include "code\modules\events\electrical_storm.dm"
#include "code\modules\events\event.dm"
-#include "code\modules\events\event_manager.dm"
#include "code\modules\events\false_alarm.dm"
#include "code\modules\events\immovable_rod.dm"
#include "code\modules\events\ion_storm.dm"
@@ -978,6 +990,7 @@
#include "code\modules\mining\laborcamp\laborshuttle.dm"
#include "code\modules\mining\laborcamp\laborstacker.dm"
#include "code\modules\mob\death.dm"
+#include "code\modules\mob\interactive.dm"
#include "code\modules\mob\inventory.dm"
#include "code\modules\mob\login.dm"
#include "code\modules\mob\logout.dm"
@@ -1282,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"
diff --git a/tools/mapmerge/clean_map.bat b/tools/mapmerge/clean_map.bat
index 01cf441ee32..8e1c9273d53 100644
--- a/tools/mapmerge/clean_map.bat
+++ b/tools/mapmerge/clean_map.bat
@@ -1,5 +1,7 @@
-set MAPFILE=tgstation.2.1.3.dmm
+@echo off
+cd ../../_maps/map_files/
+set /P MAPFILE=Please enter mapfile (relative to map_files folder):
-java -jar MapPatcher.jar -clean ../../_maps/map_files/TgStation/%MAPFILE%.backup ../../_maps/map_files/TgStation/%MAPFILE% ../../_maps/map_files/TgStation/%MAPFILE%
+java -jar ../../tools/mapmerge/MapPatcher.jar -clean "%MAPFILE%.backup" "%MAPFILE%" "%MAPFILE%"
-pause
+pause
\ No newline at end of file
diff --git a/tools/mapmerge/prepare_map.bat b/tools/mapmerge/prepare_map.bat
index 4132fbbc2a7..bfe1e6560e9 100644
--- a/tools/mapmerge/prepare_map.bat
+++ b/tools/mapmerge/prepare_map.bat
@@ -1,6 +1,12 @@
-set MAPFILE=tgstation.2.1.3.dmm
+@echo off
+cd ../../_maps/map_files/
-cd ../../_maps/map_files/TgStation/
-copy %MAPFILE% %MAPFILE%.backup
+for /R %%f in (*.dmm) do copy %%f "%%f.backup"
+cls
+echo All dmm files in map_files directories have been backed up
+echo Now you can make your changes...
+echo ---
+echo Remember to run clean_map.bat just before you commit your changes!
+echo ---
pause