diff --git a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
index cfc78c0dbf..7613265273 100644
--- a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
+++ b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
@@ -3305,7 +3305,7 @@
"ga" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "o2";
+ filter_type = /datum/gas/oxygen;
on = 1
},
/turf/open/floor/plasteel/floorgrime{
@@ -3719,7 +3719,7 @@
"gO" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "n2o";
+ filter_type = /datum/gas/nitrous_oxide;
on = 1
},
/turf/open/floor/plasteel/floorgrime{
diff --git a/_maps/RandomZLevels/undergroundoutpost45.dmm b/_maps/RandomZLevels/undergroundoutpost45.dmm
index 0f8c2e70bb..8911016cac 100644
--- a/_maps/RandomZLevels/undergroundoutpost45.dmm
+++ b/_maps/RandomZLevels/undergroundoutpost45.dmm
@@ -14187,7 +14187,7 @@
"um" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 4;
- filter_type = "n2";
+ filter_type = /datum/gas/nitrogen;
on = 1
},
/turf/open/floor/plasteel/red/side{
@@ -14236,7 +14236,7 @@
"up" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 4;
- filter_type = "o2";
+ filter_type = /datum/gas/oxygen;
on = 1
},
/turf/open/floor/plasteel/blue/side{
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 1db3e9697d..c1fe8ff733 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -27778,7 +27778,6 @@
/obj/structure/table,
/obj/item/folder/white,
/obj/item/device/radio/headset/headset_med,
-/obj/item/circuitboard/machine/smoke_machine,
/turf/open/floor/plasteel/white,
/area/medical/chemistry)
"boe" = (
@@ -37450,6 +37449,7 @@
/obj/item/circuitboard/machine/clonescanner,
/obj/item/circuitboard/machine/clonepod,
/obj/item/circuitboard/computer/scan_consolenew,
+/obj/item/circuitboard/machine/smoke_machine,
/turf/open/floor/plating,
/area/storage/tech)
"bJl" = (
@@ -43123,7 +43123,7 @@
"bWb" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "n2o";
+ filter_type = /datum/gas/nitrous_oxide;
on = 1
},
/turf/open/floor/plasteel,
@@ -44684,7 +44684,7 @@
"bZJ" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "plasma";
+ filter_type = /datum/gas/plasma;
on = 1
},
/turf/open/floor/plasteel,
@@ -46475,7 +46475,7 @@
"cdB" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "co2";
+ filter_type = /datum/gas/carbon_dioxide;
on = 1
},
/turf/open/floor/plasteel,
@@ -47103,7 +47103,7 @@
"cfi" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 2;
- filter_type = "n2";
+ filter_type = /datum/gas/nitrogen;
on = 1
},
/turf/open/floor/plasteel,
@@ -47355,7 +47355,7 @@
"cfR" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 4;
- filter_type = "o2";
+ filter_type = /datum/gas/oxygen;
on = 1
},
/turf/open/floor/plasteel,
@@ -57434,7 +57434,7 @@
"cGf" = (
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{
dir = 8;
- filter_type = "n2"
+ filter_type = /datum/gas/nitrogen
},
/turf/open/floor/engine,
/area/engine/engineering)
@@ -58550,7 +58550,7 @@
"cSJ" = (
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{
dir = 8;
- filter_type = "freon";
+ filter_type = /datum/gas/freon;
name = "gas filter (freon)"
},
/turf/open/floor/engine,
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 95256fae4c..442d34746b 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -6987,7 +6987,7 @@
},
/obj/machinery/atmospherics/components/trinary/filter/critical{
dir = 4;
- filter_type = "n2"
+ filter_type = /datum/gas/nitrogen
},
/turf/open/floor/plasteel/neutral,
/area/engine/atmospherics_engine)
@@ -10811,7 +10811,7 @@
/area/shuttle/supply)
"aza" = (
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{
- filter_type = "n2";
+ filter_type = /datum/gas/nitrogen;
name = "nitrogen filter"
},
/turf/open/floor/plasteel/yellow,
@@ -23007,7 +23007,7 @@
/obj/structure/window/reinforced,
/obj/machinery/atmospherics/components/trinary/filter{
dir = 2;
- filter_type = "co2";
+ filter_type = /datum/gas/carbon_dioxide;
name = "co2 filter";
on = 1
},
@@ -24580,7 +24580,7 @@
/obj/structure/window/reinforced,
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "o2";
+ filter_type = /datum/gas/oxygen;
name = "oxygen filter";
on = 1
},
@@ -25841,7 +25841,7 @@
/obj/structure/window/reinforced,
/obj/machinery/atmospherics/components/trinary/filter{
dir = 2;
- filter_type = "plasma";
+ filter_type = /datum/gas/plasma;
name = "waste filter";
on = 1
},
@@ -27484,7 +27484,7 @@
/obj/structure/window/reinforced,
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "n2";
+ filter_type = /datum/gas/nitrogen;
name = "nitrogen filter";
on = 1
},
@@ -29207,7 +29207,7 @@
/obj/structure/window/reinforced,
/obj/machinery/atmospherics/components/trinary/filter{
dir = 2;
- filter_type = "n2o";
+ filter_type = /datum/gas/nitrous_oxide;
name = "n2o filter";
on = 1
},
@@ -39367,6 +39367,7 @@
pixel_y = -3
},
/obj/effect/turf_decal/bot,
+/obj/item/circuitboard/machine/smoke_machine,
/turf/open/floor/plasteel,
/area/storage/tech)
"bAP" = (
@@ -77224,7 +77225,6 @@
/obj/structure/table/glass,
/obj/item/clipboard,
/obj/item/toy/figure/chemist,
-/obj/item/circuitboard/machine/smoke_machine,
/turf/open/floor/plasteel/whiteyellow/corner{
dir = 1
},
@@ -105710,7 +105710,7 @@
},
/obj/machinery/atmospherics/components/trinary/filter/critical{
dir = 4;
- filter_type = "freon";
+ filter_type = /datum/gas/freon;
name = "gas filter (freon)"
},
/turf/open/floor/plasteel/neutral,
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 26bc13dde1..78b39c756a 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -27681,6 +27681,7 @@
/obj/item/circuitboard/machine/clonescanner,
/obj/item/circuitboard/machine/clonepod,
/obj/item/circuitboard/computer/scan_consolenew,
+/obj/item/circuitboard/machine/smoke_machine,
/turf/open/floor/plasteel/black,
/area/storage/tech)
"bbo" = (
@@ -46859,7 +46860,7 @@
"bMk" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "n2o";
+ filter_type = /datum/gas/nitrous_oxide;
on = 1
},
/obj/structure/window/reinforced{
@@ -49916,7 +49917,7 @@
"bSj" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "plasma";
+ filter_type = /datum/gas/plasma;
on = 1
},
/obj/structure/window/reinforced{
@@ -52635,7 +52636,7 @@
"bXq" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "co2";
+ filter_type = /datum/gas/carbon_dioxide;
on = 1
},
/obj/structure/window/reinforced{
@@ -54519,7 +54520,7 @@
"cbd" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 4;
- filter_type = "n2";
+ filter_type = /datum/gas/nitrogen;
on = 1
},
/obj/structure/window/reinforced,
@@ -54574,7 +54575,7 @@
/obj/structure/window/reinforced,
/obj/machinery/atmospherics/components/trinary/filter{
dir = 4;
- filter_type = "o2";
+ filter_type = /datum/gas/oxygen;
on = 1
},
/turf/open/floor/plasteel/blue,
@@ -59764,7 +59765,6 @@
dir = 1;
pixel_y = -24
},
-/obj/item/circuitboard/machine/smoke_machine,
/turf/open/floor/plasteel/whiteyellow{
dir = 4
},
@@ -82679,7 +82679,7 @@
dir = 4
},
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{
- filter_type = "freon";
+ filter_type = /datum/gas/freon;
name = "gas filter (freon)"
},
/turf/open/floor/engine,
@@ -82879,7 +82879,7 @@
dir = 4
},
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{
- filter_type = "n2"
+ filter_type = /datum/gas/nitrogen
},
/turf/open/floor/engine,
/area/engine/engineering)
diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm
index 620f34dfb3..3e9d0e5f64 100644
--- a/_maps/map_files/OmegaStation/OmegaStation.dmm
+++ b/_maps/map_files/OmegaStation/OmegaStation.dmm
@@ -11009,7 +11009,7 @@
"asz" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 2;
- filter_type = "n2";
+ filter_type = /datum/gas/nitrogen;
name = "nitrogen filter";
on = 1
},
@@ -13296,7 +13296,7 @@
"awD" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 2;
- filter_type = "o2";
+ filter_type = /datum/gas/oxygen;
name = "oxygen filter";
on = 1
},
@@ -14109,7 +14109,7 @@
"ayf" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "plasma";
+ filter_type = /datum/gas/plasma;
name = "waste filter";
on = 1
},
@@ -21607,7 +21607,7 @@
},
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{
dir = 1;
- filter_type = "n2"
+ filter_type = /datum/gas/nitrogen
},
/turf/open/floor/plasteel,
/area/engine/engineering)
@@ -23873,7 +23873,7 @@
},
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{
dir = 1;
- filter_type = "freon";
+ filter_type = /datum/gas/freon;
name = "gas filter (freon)"
},
/turf/open/floor/plasteel,
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index 154df34231..a63a533f30 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -32785,7 +32785,6 @@
/obj/item/hand_labeler,
/obj/item/device/radio/headset/headset_med,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
-/obj/item/circuitboard/machine/smoke_machine,
/turf/open/floor/plasteel/white,
/area/medical/chemistry)
"bwW" = (
@@ -41751,6 +41750,7 @@
/obj/structure/sign/poster/official/random{
pixel_y = 32
},
+/obj/item/circuitboard/machine/smoke_machine,
/turf/open/floor/plasteel/darkgreen,
/area/storage/tech)
"bQw" = (
@@ -41924,7 +41924,7 @@
"bQN" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "n2o";
+ filter_type = /datum/gas/nitrous_oxide;
on = 1
},
/turf/open/floor/plasteel,
@@ -43351,7 +43351,7 @@
"bTU" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "plasma";
+ filter_type = /datum/gas/plasma;
on = 1
},
/turf/open/floor/plasteel,
@@ -44738,7 +44738,7 @@
"bWK" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 4;
- filter_type = "o2";
+ filter_type = /datum/gas/oxygen;
on = 1
},
/turf/open/floor/plasteel,
@@ -44777,7 +44777,7 @@
"bWQ" = (
/obj/machinery/atmospherics/components/trinary/filter{
dir = 1;
- filter_type = "co2";
+ filter_type = /datum/gas/carbon_dioxide;
on = 1
},
/turf/open/floor/plasteel,
diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm
index 98448336e1..d3d1445c7d 100644
--- a/code/__DEFINES/atmospherics.dm
+++ b/code/__DEFINES/atmospherics.dm
@@ -17,6 +17,7 @@
#define META_GAS_MOLES_VISIBLE 3
#define META_GAS_OVERLAY 4
#define META_GAS_DANGER 5
+#define META_GAS_ID 6
//stuff you should probably leave well alone!
//ATMOS
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index bdb9ad35a9..b83fc3dd39 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -466,3 +466,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
//Dummy mob reserve slots
#define DUMMY_HUMAN_SLOT_PREFERENCES "dummy_preference_preview"
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
+
+#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
+ //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
\ No newline at end of file
diff --git a/code/_compile_options.dm b/code/_compile_options.dm
index 829a55150f..1c1ad2e692 100644
--- a/code/_compile_options.dm
+++ b/code/_compile_options.dm
@@ -1,75 +1,76 @@
-#define DEBUG //Enables byond profiling and full runtime logs - note, this may also be defined in your .dme file
- //Enables in-depth debug messages to runtime log (used for debugging)
-//#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this
- //uncommented, but not visible in the release version)
-
-#ifdef TESTING
-//#define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing.
- //Also allows for recursive reference searching of datums.
- //Sets world.loop_checks to false and prevents find references from sleeping
-
-//#define VISUALIZE_ACTIVE_TURFS //Highlights atmos active turfs in green
-#endif
-
-#define PRELOAD_RSC 1 /*set to:
- 0 to allow using external resources or on-demand behaviour;
- 1 to use the default behaviour;
- 2 for preloading absolutely everything;
- */
-
-#define BACKGROUND_ENABLED 0 // The default value for all uses of set background. Set background can cause gradual lag and is recommended you only turn this on if necessary.
- // 1 will enable set background. 0 will disable set background.
-
-//ADMIN STUFF
-#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued.
-
-#define SPAM_TRIGGER_WARNING 5 //Number of identical messages required before the spam-prevention will warn you to stfu
-#define SPAM_TRIGGER_AUTOMUTE 10 //Number of identical messages required before the spam-prevention will automute you
-
-//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam
-#define MAX_MESSAGE_LEN 1024
-#define MAX_NAME_LEN 42
-#define MAX_BROADCAST_LEN 512
-#define MAX_CHARTER_LEN 80
-
-//MINOR TWEAKS/MISC
-#define AGE_MIN 18 //youngest a character can be
-#define AGE_MAX 85 //oldest a character can be
-#define WIZARD_AGE_MIN 30 //youngest a wizard can be
-#define SHOES_SLOWDOWN 0 //How much shoes slow you down by default. Negative values speed you up
-#define POCKET_STRIP_DELAY 40 //time taken (in deciseconds) to search somebody's pockets
-#define DOOR_CRUSH_DAMAGE 15 //the amount of damage that airlocks deal when they crush you
-
-#define HUNGER_FACTOR 0.1 //factor at which mob nutrition decreases
-#define REAGENTS_METABOLISM 0.4 //How many units of reagent are consumed per tick, by default.
-#define REAGENTS_EFFECT_MULTIPLIER (REAGENTS_METABOLISM / 0.4) // By defining the effect multiplier this way, it'll exactly adjust all effects according to how they originally were with the 0.4 metabolism
-
-#define MAX_STACK_AMOUNT_METAL 50
-#define MAX_STACK_AMOUNT_GLASS 50
-#define MAX_STACK_AMOUNT_RODS 60
-
-// AI Toggles
-#define AI_CAMERA_LUMINOSITY 5
-#define AI_VOX 1 // Comment out if you don't want VOX to be enabled and have players download the voice sounds.
-
-//Additional code for the above flags_1.
-#ifdef TESTING
-#warn compiling in TESTING mode. testing() debug messages will be visible.
-#endif
-
-#ifdef TRAVISTESTING
-#define TESTING
-#endif
-
-//Update this whenever you need to take advantage of more recent byond features
-#define MIN_COMPILER_VERSION 511
-#if DM_VERSION < MIN_COMPILER_VERSION
-//Don't forget to update this part
-#error Your version of BYOND is too out-of-date to compile this project. Go to byond.com/download and update.
-#error You need version 511 or higher
-#endif
-
-//Update this whenever the db schema changes
-//make sure you add an update to the schema_version stable in the db changelog
-#define DB_MAJOR_VERSION 3
-#define DB_MINOR_VERSION 3
+#define DEBUG //Enables byond profiling and full runtime logs - note, this may also be defined in your .dme file
+ //Enables in-depth debug messages to runtime log (used for debugging)
+//#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this
+ //uncommented, but not visible in the release version)
+
+#ifdef TESTING
+//#define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing.
+ //Also allows for recursive reference searching of datums.
+ //Sets world.loop_checks to false and prevents find references from sleeping
+
+//#define VISUALIZE_ACTIVE_TURFS //Highlights atmos active turfs in green
+#endif
+
+#define PRELOAD_RSC 1 /*set to:
+ 0 to allow using external resources or on-demand behaviour;
+ 1 to use the default behaviour;
+ 2 for preloading absolutely everything;
+ */
+
+#define BACKGROUND_ENABLED 0 // The default value for all uses of set background. Set background can cause gradual lag and is recommended you only turn this on if necessary.
+ // 1 will enable set background. 0 will disable set background.
+
+//ADMIN STUFF
+#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued.
+
+#define SPAM_TRIGGER_WARNING 5 //Number of identical messages required before the spam-prevention will warn you to stfu
+#define SPAM_TRIGGER_AUTOMUTE 10 //Number of identical messages required before the spam-prevention will automute you
+
+//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam
+#define MAX_MESSAGE_LEN 1024
+#define MAX_NAME_LEN 42
+#define MAX_BROADCAST_LEN 512
+#define MAX_CHARTER_LEN 80
+
+//MINOR TWEAKS/MISC
+#define AGE_MIN 17 //youngest a character can be
+#define AGE_MAX 85 //oldest a character can be
+#define WIZARD_AGE_MIN 30 //youngest a wizard can be
+#define APPRENTICE_AGE_MIN 29 //youngest an apprentice can be
+#define SHOES_SLOWDOWN 0 //How much shoes slow you down by default. Negative values speed you up
+#define POCKET_STRIP_DELAY 40 //time taken (in deciseconds) to search somebody's pockets
+#define DOOR_CRUSH_DAMAGE 15 //the amount of damage that airlocks deal when they crush you
+
+#define HUNGER_FACTOR 0.1 //factor at which mob nutrition decreases
+#define REAGENTS_METABOLISM 0.4 //How many units of reagent are consumed per tick, by default.
+#define REAGENTS_EFFECT_MULTIPLIER (REAGENTS_METABOLISM / 0.4) // By defining the effect multiplier this way, it'll exactly adjust all effects according to how they originally were with the 0.4 metabolism
+
+#define MAX_STACK_AMOUNT_METAL 50
+#define MAX_STACK_AMOUNT_GLASS 50
+#define MAX_STACK_AMOUNT_RODS 60
+
+// AI Toggles
+#define AI_CAMERA_LUMINOSITY 5
+#define AI_VOX 1 // Comment out if you don't want VOX to be enabled and have players download the voice sounds.
+
+//Additional code for the above flags.
+#ifdef TESTING
+#warn compiling in TESTING mode. testing() debug messages will be visible.
+#endif
+
+#ifdef TRAVISTESTING
+#define TESTING
+#endif
+
+//Update this whenever you need to take advantage of more recent byond features
+#define MIN_COMPILER_VERSION 511
+#if DM_VERSION < MIN_COMPILER_VERSION
+//Don't forget to update this part
+#error Your version of BYOND is too out-of-date to compile this project. Go to byond.com/download and update.
+#error You need version 511 or higher
+#endif
+
+//Update this whenever the db schema changes
+//make sure you add an update to the schema_version stable in the db changelog
+#define DB_MAJOR_VERSION 3
+#define DB_MINOR_VERSION 4
diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm
index d855c7f141..c6cc5d7330 100644
--- a/code/_globalvars/lists/names.dm
+++ b/code/_globalvars/lists/names.dm
@@ -16,6 +16,8 @@ GLOBAL_LIST_INIT(golem_names, world.file2list("strings/names/golem.txt"))
GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt"))
GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt"))
GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt"))
+GLOBAL_LIST_INIT(megacarp_first_names, world.file2list("strings/names/megacarp1.txt"))
+GLOBAL_LIST_INIT(megacarp_last_names, world.file2list("strings/names/megacarp2.txt"))
GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt"))
diff --git a/code/citadel/cit_crewobjectives.dm b/code/citadel/cit_crewobjectives.dm
index 90a655b622..6afa92af65 100644
--- a/code/citadel/cit_crewobjectives.dm
+++ b/code/citadel/cit_crewobjectives.dm
@@ -1,6 +1,6 @@
/datum/controller/subsystem/ticker/proc/generate_crew_objectives()
for(var/datum/mind/crewMind in SSticker.minds)
- if(prob(2) && !issilicon(crewMind.current) && !jobban_isbanned(crewMind, "Syndicate") && GLOB.miscreants_allowed && ROLE_MISCREANT in crewMind.current.client.prefs.be_special)
+ if(prob(5) && !issilicon(crewMind.current) && !jobban_isbanned(crewMind, "Syndicate") && GLOB.miscreants_allowed && ROLE_MISCREANT in crewMind.current.client.prefs.be_special)
generate_miscreant_objectives(crewMind)
else
if(CONFIG_GET(flag/allow_crew_objectives))
@@ -16,7 +16,7 @@
return
if(!crewMind.assigned_role)
return
- var/list/validobjs = get_valid_crew_objs(ckey(crewMind.assigned_role))
+ var/list/validobjs = crewobjjobs["[ckey(crewMind.assigned_role)]"]
if(!validobjs || !validobjs.len)
return
var/selectedObj = pick(validobjs)
@@ -28,16 +28,6 @@
to_chat(crewMind, "As a part of Nanotrasen's anti-tide efforts, you have been assigned an optional objective. It will be checked at the end of the shift. Performing traitorous acts in pursuit of your objective may result in termination of your employment.")
to_chat(crewMind, "Your optional objective: [newObjective.explanation_text]")
-/datum/controller/subsystem/ticker/proc/get_valid_crew_objs(var/job = "")//taken from old hippie with adjustments
- var/list/objpaths = typesof(/datum/objective/crew)
- var/list/objlist = list()
- for(var/hoorayhackyshit in objpaths)
- var/datum/objective/crew/obj = hoorayhackyshit //dm is not a sane language in any way, shape, or form.
- var/list/availableto = splittext(initial(obj.jobs),",")
- if(job in availableto)
- objlist += obj
- return objlist
-
/datum/objective/crew/
var/jobs = ""
explanation_text = "Yell on the development discussion channel on Citadels discord if this ever shows up. Something just broke here, dude"
diff --git a/code/citadel/cit_miscreants.dm b/code/citadel/cit_miscreants.dm
index e658fad097..ec5ff0156f 100644
--- a/code/citadel/cit_miscreants.dm
+++ b/code/citadel/cit_miscreants.dm
@@ -11,7 +11,7 @@
return
if(jobban_isbanned(crewMind, "Syndicate"))
return
- var/list/objectiveTypes = typesof(/datum/objective/miscreant) - /datum/objective/miscreant
+ var/list/objectiveTypes = miscreantobjlist
if(!objectiveTypes.len)
return
var/selectedType = pick(objectiveTypes)
diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm
index 0b8fa750b6..43585a5896 100644
--- a/code/controllers/subsystem/server_maint.dm
+++ b/code/controllers/subsystem/server_maint.dm
@@ -16,6 +16,8 @@ SUBSYSTEM_DEF(server_maint)
/datum/controller/subsystem/server_maint/fire(resumed = FALSE)
if(!resumed)
+ if(listclearnulls(GLOB.clients))
+ log_world("Found a null in clients list!")
src.currentrun = GLOB.clients.Copy()
var/list/currentrun = src.currentrun
diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm
index 52fd286eed..a9b307bc0d 100644
--- a/code/controllers/subsystem/tgui.dm
+++ b/code/controllers/subsystem/tgui.dm
@@ -11,7 +11,7 @@ SUBSYSTEM_DEF(tgui)
var/basehtml // The HTML base used for all UIs.
/datum/controller/subsystem/tgui/PreInit()
- basehtml = file2text('tgui/tgui.html') // Read the HTML from disk.
+ basehtml = file2text("tgui/tgui.html")
/datum/controller/subsystem/tgui/Shutdown()
close_all_uis()
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 50e3dab667..8f36661ca4 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -66,6 +66,11 @@ SUBSYSTEM_DEF(ticker)
var/modevoted = FALSE //Have we sent a vote for the gamemode?
+ //Crew Objective/Miscreant stuff
+ var/list/crewobjlist = list()
+ var/list/crewobjjobs = list()
+ var/list/miscreantobjlist = list()
+
/datum/controller/subsystem/ticker/Initialize(timeofday)
load_mode()
@@ -87,7 +92,7 @@ SUBSYSTEM_DEF(ticker)
var/list/provisional_title_music = flist("config/title_music/sounds/")
var/list/music = list()
var/use_rare_music = prob(1)
-
+
for(var/S in provisional_title_music)
var/lower = lowertext(S)
var/list/L = splittext(lower,"+")
@@ -115,7 +120,7 @@ SUBSYSTEM_DEF(ticker)
if(byond_sound_formats[ext])
continue
music -= S
-
+
if(isemptylist(music))
music = world.file2list(ROUND_START_MUSIC_LIST, "\n")
login_music = pick(music)
@@ -123,6 +128,14 @@ SUBSYSTEM_DEF(ticker)
login_music = "config/title_music/sounds/[pick(music)]"
+ crewobjlist = typesof(/datum/objective/crew)
+ miscreantobjlist = (typesof(/datum/objective/miscreant) - /datum/objective/miscreant)
+ for(var/hoorayhackyshit in crewobjlist) //taken from old Hippie's "job2obj" proc with adjustments.
+ var/datum/objective/crew/obj = hoorayhackyshit //dm is not a sane language in any way, shape, or form.
+ var/list/availableto = splittext(initial(obj.jobs),",")
+ for(var/job in availableto)
+ crewobjjobs["[job]"] += list(obj)
+
if(!GLOB.syndicate_code_phrase)
GLOB.syndicate_code_phrase = generate_code_phrase()
if(!GLOB.syndicate_code_response)
@@ -521,11 +534,11 @@ SUBSYSTEM_DEF(ticker)
if(!crewMind.current || !crewMind.objectives.len)
continue
for(var/datum/objective/miscreant/MO in crewMind.objectives)
- miscreants += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [MO.explanation_text] (Optional)
"
+ miscreants += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [MO.explanation_text] (Optional)"
for(var/datum/objective/crew/CO in crewMind.objectives)
if(CO.check_completion())
to_chat(crewMind.current, "
Your optional objective: [CO.explanation_text] Success!")
- successfulCrew += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [CO.explanation_text] Success! (Optional)
"
+ successfulCrew += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [CO.explanation_text] Success! (Optional)"
else
to_chat(crewMind.current, "
Your optional objective: [CO.explanation_text] Failed.")
diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm
index ad5a9d9e18..7e500c2e4a 100644
--- a/code/datums/antagonists/antag_datum.dm
+++ b/code/datums/antagonists/antag_datum.dm
@@ -1,20 +1,21 @@
+GLOBAL_LIST_EMPTY(antagonists)
+
/datum/antagonist
var/name = "Antagonist"
-
var/datum/mind/owner //Mind that owns this datum
-
var/silent = FALSE //Silent will prevent the gain/lose texts to show
-
var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum
var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with
- var/delete_on_death = TRUE
+ var/delete_on_mind_deletion = TRUE
/datum/antagonist/New(datum/mind/new_owner)
+ GLOB.antagonists += src
typecache_datum_blacklist = typecacheof(typecache_datum_blacklist)
if(new_owner)
owner = new_owner
/datum/antagonist/Destroy()
+ GLOB.antagonists -= src
if(owner)
LAZYREMOVE(owner.antag_datums, src)
owner = null
diff --git a/code/datums/antagonists/datum_cult.dm b/code/datums/antagonists/datum_cult.dm
index 8c05c54b21..37dce88691 100644
--- a/code/datums/antagonists/datum_cult.dm
+++ b/code/datums/antagonists/datum_cult.dm
@@ -131,7 +131,7 @@
/datum/antagonist/cult/master/on_gain()
. = ..()
var/mob/living/current = owner.current
- SSticker.mode.set_antag_hud(current, "cultmaster")
+ set_antag_hud(current, "cultmaster")
/datum/antagonist/cult/master/greet()
to_chat(owner.current, "You are the cult's Master. As the cult's Master, you have a unique title and loud voice when communicating, are capable of marking \
diff --git a/code/datums/antagonists/devil.dm b/code/datums/antagonists/devil.dm
index f66fc5a3b2..76a9e022c6 100644
--- a/code/datums/antagonists/devil.dm
+++ b/code/datums/antagonists/devil.dm
@@ -86,7 +86,7 @@ GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon",
GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr."))
/datum/antagonist/devil
//Don't delete upon mind destruction, otherwise soul re-selling will break.
- delete_on_death = FALSE
+ delete_on_mind_deletion = FALSE
var/obligation
var/ban
var/bane
diff --git a/code/datums/antagonists/wizard.dm b/code/datums/antagonists/wizard.dm
new file mode 100644
index 0000000000..627b3e88d7
--- /dev/null
+++ b/code/datums/antagonists/wizard.dm
@@ -0,0 +1,273 @@
+#define APPRENTICE_DESTRUCTION "destruction"
+#define APPRENTICE_BLUESPACE "bluespace"
+#define APPRENTICE_ROBELESS "robeless"
+#define APPRENTICE_HEALING "healing"
+
+/datum/antagonist/wizard
+ name = "Space Wizard"
+ var/give_objectives = TRUE
+ var/strip = TRUE //strip before equipping
+ var/allow_rename = TRUE
+ var/hud_version = "wizard"
+ var/datum/objective_team/wizard/wiz_team //Only created if wizard summons apprentices
+ var/list/objectives = list() //this should be base datum antag proc and list, todo make lazy
+ var/move_to_lair = TRUE
+ var/outfit_type = /datum/outfit/wizard
+ var/wiz_age = WIZARD_AGE_MIN /* Wizards by nature cannot be too young. */
+
+/datum/antagonist/wizard/on_gain()
+ register()
+ if(give_objectives)
+ create_objectives()
+ equip_wizard()
+ if(move_to_lair)
+ send_to_lair()
+ . = ..()
+ if(allow_rename)
+ rename_wizard()
+
+/datum/antagonist/wizard/proc/register()
+ SSticker.mode.wizards |= owner
+
+/datum/antagonist/wizard/proc/unregister()
+ SSticker.mode.wizards -= src
+
+/datum/objective_team/wizard
+ name = "wizard team"
+
+/datum/antagonist/wizard/proc/create_wiz_team()
+ wiz_team = new(owner)
+ wiz_team.name = "[owner.current.real_name] team"
+ update_wiz_icons_added(owner.current)
+
+/datum/antagonist/wizard/proc/send_to_lair()
+ if(!owner || !owner.current)
+ return
+ if(!GLOB.wizardstart.len)
+ SSjob.SendToLateJoin(owner.current)
+ to_chat(owner, "HOT INSERTION, GO GO GO")
+ owner.current.forceMove(pick(GLOB.wizardstart))
+
+/datum/antagonist/wizard/proc/create_objectives()
+ switch(rand(1,100))
+ if(1 to 30)
+ var/datum/objective/assassinate/kill_objective = new
+ kill_objective.owner = owner
+ kill_objective.find_target()
+ objectives += kill_objective
+
+ if (!(locate(/datum/objective/escape) in owner.objectives))
+ var/datum/objective/escape/escape_objective = new
+ escape_objective.owner = owner
+ objectives += escape_objective
+
+ if(31 to 60)
+ var/datum/objective/steal/steal_objective = new
+ steal_objective.owner = owner
+ steal_objective.find_target()
+ objectives += steal_objective
+
+ if (!(locate(/datum/objective/escape) in owner.objectives))
+ var/datum/objective/escape/escape_objective = new
+ escape_objective.owner = owner
+ objectives += escape_objective
+
+ if(61 to 85)
+ var/datum/objective/assassinate/kill_objective = new
+ kill_objective.owner = owner
+ kill_objective.find_target()
+ objectives += kill_objective
+
+ var/datum/objective/steal/steal_objective = new
+ steal_objective.owner = owner
+ steal_objective.find_target()
+ objectives += steal_objective
+
+ if (!(locate(/datum/objective/survive) in owner.objectives))
+ var/datum/objective/survive/survive_objective = new
+ survive_objective.owner = owner
+ objectives += survive_objective
+
+ else
+ if (!(locate(/datum/objective/hijack) in owner.objectives))
+ var/datum/objective/hijack/hijack_objective = new
+ hijack_objective.owner = owner
+ objectives += hijack_objective
+
+ for(var/datum/objective/O in objectives)
+ owner.objectives += O
+
+/datum/antagonist/wizard/on_removal()
+ unregister()
+ owner.RemoveAllSpells() // TODO keep track which spells are wizard spells which innate stuff
+ return ..()
+
+/datum/antagonist/wizard/proc/equip_wizard()
+ if(!owner)
+ return
+ var/mob/living/carbon/human/H = owner.current
+ if(!istype(H))
+ return
+ if(strip)
+ H.delete_equipment()
+ //Wizards are human by default. Use the mirror if you want something else.
+ H.set_species(/datum/species/human)
+ if(H.age < wiz_age)
+ H.age = wiz_age
+ H.equipOutfit(outfit_type)
+
+/datum/antagonist/wizard/greet()
+ to_chat(owner, "You are the Space Wizard!")
+ to_chat(owner, "The Space Wizards Federation has given you the following tasks:")
+ owner.announce_objectives()
+ to_chat(owner, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.")
+ to_chat(owner, "The spellbook is bound to you, and others cannot use it.")
+ to_chat(owner, "In your pockets you will find a teleport scroll. Use it as needed.")
+ to_chat(owner,"Remember: do not forget to prepare your spells.")
+
+/datum/antagonist/wizard/farewell()
+ to_chat(owner, "You have been brainwashed! You are no longer a wizard!")
+
+/datum/antagonist/wizard/proc/rename_wizard()
+ set waitfor = FALSE
+
+ var/wizard_name_first = pick(GLOB.wizard_first)
+ var/wizard_name_second = pick(GLOB.wizard_second)
+ var/randomname = "[wizard_name_first] [wizard_name_second]"
+ var/mob/living/wiz_mob = owner.current
+ var/newname = copytext(sanitize(input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN)
+
+ if (!newname)
+ newname = randomname
+
+ wiz_mob.fully_replace_character_name(wiz_mob.real_name, newname)
+
+/datum/antagonist/wizard/apply_innate_effects(mob/living/mob_override)
+ var/mob/living/M = mob_override || owner.current
+ if(wiz_team) //Don't bother with the icon if you're solo wizard
+ update_wiz_icons_added(M)
+ M.faction |= "wizard"
+
+/datum/antagonist/wizard/remove_innate_effects(mob/living/mob_override)
+ var/mob/living/M = mob_override || owner.current
+ update_wiz_icons_removed(M)
+ M.faction -= "wizard"
+
+/datum/antagonist/wizard/apprentice
+ name = "Wizard Apprentice"
+ hud_version = "apprentice"
+ var/datum/mind/master
+ var/school = APPRENTICE_DESTRUCTION
+ outfit_type = /datum/outfit/wizard/apprentice
+ wiz_age = APPRENTICE_AGE_MIN
+
+/datum/antagonist/wizard/apprentice/greet()
+ to_chat(owner, "You are [master.current.real_name]'s apprentice! You are bound by magic contract to follow their orders and help them in accomplishing their goals.")
+ owner.announce_objectives()
+
+/datum/antagonist/wizard/apprentice/register()
+ SSticker.mode.apprentices |= src
+
+/datum/antagonist/wizard/apprentice/unregister()
+ SSticker.mode.apprentices -= src
+
+/datum/antagonist/wizard/apprentice/equip_wizard()
+ . = ..()
+ if(!owner)
+ return
+ var/mob/living/carbon/human/H = owner.current
+ if(!istype(H))
+ return
+ switch(school)
+ if(APPRENTICE_DESTRUCTION)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null))
+ owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null))
+ to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.")
+ if(APPRENTICE_BLUESPACE)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
+ to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.")
+ if(APPRENTICE_HEALING)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null))
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null))
+ H.put_in_hands(new /obj/item/gun/magic/staff/healing(H))
+ to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.")
+ if(APPRENTICE_HEALING)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null))
+ to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.")
+
+/datum/antagonist/wizard/apprentice/create_objectives()
+ var/datum/objective/protect/new_objective = new /datum/objective/protect
+ new_objective.owner = owner
+ new_objective.target = master
+ new_objective.explanation_text = "Protect [master.current.real_name], the wizard."
+ owner.objectives += new_objective
+ objectives += new_objective
+
+//Random event wizard
+/datum/antagonist/wizard/apprentice/imposter
+ name = "Wizard Imposter"
+ allow_rename = FALSE
+
+/datum/antagonist/wizard/apprentice/imposter/greet()
+ to_chat(owner, "You are an imposter! Trick and confuse the crew to misdirect malice from your handsome original!")
+ owner.announce_objectives()
+
+/datum/antagonist/wizard/apprentice/imposter/equip_wizard()
+ var/mob/living/carbon/human/master_mob = master.current
+ var/mob/living/carbon/human/H = owner.current
+ if(!istype(master_mob) || !istype(H))
+ return
+ if(master_mob.ears)
+ H.equip_to_slot_or_del(new master_mob.ears.type, slot_ears)
+ if(master_mob.w_uniform)
+ H.equip_to_slot_or_del(new master_mob.w_uniform.type, slot_w_uniform)
+ if(master_mob.shoes)
+ H.equip_to_slot_or_del(new master_mob.shoes.type, slot_shoes)
+ if(master_mob.wear_suit)
+ H.equip_to_slot_or_del(new master_mob.wear_suit.type, slot_wear_suit)
+ if(master_mob.head)
+ H.equip_to_slot_or_del(new master_mob.head.type, slot_head)
+ if(master_mob.back)
+ H.equip_to_slot_or_del(new master_mob.back.type, slot_back)
+
+ //Operation: Fuck off and scare people
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null))
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
+
+/datum/antagonist/wizard/proc/update_wiz_icons_added(mob/living/wiz)
+ var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ]
+ wizhud.join_hud(wiz)
+ set_antag_hud(wiz, hud_version)
+
+/datum/antagonist/wizard/proc/update_wiz_icons_removed(mob/living/wiz)
+ var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ]
+ wizhud.leave_hud(wiz)
+ set_antag_hud(wiz, null)
+
+
+/datum/antagonist/wizard/academy
+ name = "Academy Teacher"
+ outfit_type = /datum/outfit/wizard/academy
+
+/datum/antagonist/wizard/academy/equip_wizard()
+ . = ..()
+
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball)
+
+ var/mob/living/M = owner.current
+ if(!istype(M))
+ return
+
+ var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(M)
+ Implant.implant(M)
+
+/datum/antagonist/wizard/academy/create_objectives()
+ var/datum/objective/new_objective = new("Protect Wizard Academy from the intruders")
+ new_objective.owner = owner
+ owner.objectives += new_objective
+ objectives += new_objective
\ No newline at end of file
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 0eb76388ae..b5436f0313 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -191,11 +191,11 @@
// Can most things breathe?
if(trace_gases)
continue
- if(!(A_gases["o2"] && A_gases["o2"][MOLES] >= 16))
+ if(!(A_gases[/datum/gas/oxygen] && A_gases[/datum/gas/oxygen][MOLES] >= 16))
continue
- if(A_gases["plasma"])
+ if(A_gases[/datum/gas/plasma])
continue
- if(A_gases["co2"] && A_gases["co2"][MOLES] >= 10)
+ if(A_gases[/datum/gas/carbon_dioxide] && A_gases[/datum/gas/carbon_dioxide][MOLES] >= 10)
continue
// Aim for goldilocks temperatures and pressure
diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm
index 8fe8fcd366..ed46910148 100644
--- a/code/datums/martial/sleeping_carp.dm
+++ b/code/datums/martial/sleeping_carp.dm
@@ -112,6 +112,8 @@
D.stop_pulling()
if(A.a_intent == INTENT_GRAB)
add_logs(A, D, "grabbed", addition="aggressively")
+ D.visible_message("[A] violently grabs [D]!", \
+ "[A] violently grabs you!")
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
else
add_logs(A, D, "grabbed", addition="passively")
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 3116be2ea1..2f45067b0c 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -75,7 +75,7 @@
if(islist(antag_datums))
for(var/i in antag_datums)
var/datum/antagonist/antag_datum = i
- if(antag_datum.delete_on_death)
+ if(antag_datum.delete_on_mind_deletion)
qdel(i)
antag_datums = null
return ..()
@@ -133,10 +133,16 @@
memory = null
// Datum antag mind procs
-/datum/mind/proc/add_antag_datum(datum_type, team)
- if(!datum_type)
+/datum/mind/proc/add_antag_datum(datum_type_or_instance, team)
+ if(!datum_type_or_instance)
return
- var/datum/antagonist/A = new datum_type(src, team)
+ var/datum/antagonist/A
+ if(!ispath(datum_type_or_instance))
+ A = datum_type_or_instance
+ if(!istype(A))
+ return
+ else
+ A = new datum_type_or_instance(src, team)
if(!A.can_be_owned(src))
qdel(A)
return
@@ -193,12 +199,12 @@
/datum/mind/proc/remove_traitor()
if(src in SSticker.mode.traitors)
- src.remove_antag_datum(ANTAG_DATUM_TRAITOR)
+ remove_antag_datum(ANTAG_DATUM_TRAITOR)
SSticker.mode.update_traitor_icons_removed(src)
/datum/mind/proc/remove_brother()
if(src in SSticker.mode.brothers)
- src.remove_antag_datum(ANTAG_DATUM_BROTHER)
+ remove_antag_datum(ANTAG_DATUM_BROTHER)
SSticker.mode.update_brother_icons_removed(src)
/datum/mind/proc/remove_nukeop()
@@ -210,11 +216,8 @@
remove_antag_equip()
/datum/mind/proc/remove_wizard()
- if(src in SSticker.mode.wizards)
- SSticker.mode.wizards -= src
- RemoveAllSpells()
+ remove_antag_datum(/datum/antagonist/wizard)
special_role = null
- remove_antag_equip()
/datum/mind/proc/remove_cultist()
if(src in SSticker.mode.cult)
@@ -254,7 +257,6 @@
remove_rev()
SSticker.mode.update_changeling_icons_removed(src)
SSticker.mode.update_traitor_icons_removed(src)
- SSticker.mode.update_wiz_icons_removed(src)
SSticker.mode.update_cult_icons_removed(src)
SSticker.mode.update_rev_icons_removed(src)
@@ -526,11 +528,9 @@
if (SSticker.mode.config_tag=="wizard")
text = uppertext(text)
text = "[text]: "
- if ((src in SSticker.mode.wizards) || (src in SSticker.mode.apprentices))
+ if (has_antag_datum(/datum/antagonist/wizard))
text += "YES | no"
- text += "
To lair, undress, dress up, let choose name."
- if (objectives.len==0)
- text += "
Objectives are empty! Randomize!"
+ text += "
To lair, undress"
else
text += "yes | NO"
@@ -1049,27 +1049,15 @@
switch(href_list["wizard"])
if("clear")
remove_wizard()
- to_chat(current, "You have been brainwashed! You are no longer a wizard!")
log_admin("[key_name(usr)] has de-wizard'ed [current].")
- SSticker.mode.update_wiz_icons_removed(src)
if("wizard")
- if(!(src in SSticker.mode.wizards))
- SSticker.mode.wizards += src
+ if(has_antag_datum(/datum/antagonist/wizard))
special_role = "Wizard"
- //SSticker.mode.learn_basic_spells(current)
- to_chat(current, "You are the Space Wizard!")
+ add_antag_datum(/datum/antagonist/wizard)
message_admins("[key_name_admin(usr)] has wizard'ed [current].")
log_admin("[key_name(usr)] has wizard'ed [current].")
- SSticker.mode.update_wiz_icons_added(src)
if("lair")
current.forceMove(pick(GLOB.wizardstart))
- if("dressup")
- SSticker.mode.equip_wizard(current)
- if("name")
- SSticker.mode.name_wizard(current)
- if("autoobjectives")
- SSticker.mode.forge_wizard_objectives(src)
- to_chat(usr, "The objectives for wizard [key] have been generated. You can edit them and anounce manually.")
else if (href_list["changeling"])
switch(href_list["changeling"])
@@ -1440,20 +1428,10 @@
SSticker.mode.update_changeling_icons_added(src)
/datum/mind/proc/make_Wizard()
- if(!(src in SSticker.mode.wizards))
- SSticker.mode.wizards += src
+ if(!has_antag_datum(/datum/antagonist/wizard))
special_role = "Wizard"
assigned_role = "Wizard"
- if(!GLOB.wizardstart.len)
- SSjob.SendToLateJoin(current)
- to_chat(current, "HOT INSERTION, GO GO GO")
- else
- current.forceMove(pick(GLOB.wizardstart))
-
- SSticker.mode.equip_wizard(current)
- SSticker.mode.name_wizard(current)
- SSticker.mode.forge_wizard_objectives(src)
- SSticker.mode.greet_wizard(src)
+ add_antag_datum(/datum/antagonist/wizard)
/datum/mind/proc/make_Cultist()
diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm
new file mode 100644
index 0000000000..02cb4e0c31
--- /dev/null
+++ b/code/datums/world_topic.dm
@@ -0,0 +1,168 @@
+// SETUP
+
+/proc/TopicHandlers()
+ . = list()
+ var/list/all_handlers = subtypesof(/datum/world_topic)
+ for(var/I in all_handlers)
+ var/datum/world_topic/WT = I
+ var/keyword = initial(WT.keyword)
+ if(!keyword)
+ warning("[WT] has no keyword! Ignoring...")
+ continue
+ var/existing_path = .[keyword]
+ if(existing_path)
+ warning("[existing_path] and [WT] have the same keyword! Ignoring [WT]...")
+ else if(keyword == "key")
+ warning("[WT] has keyword 'key'! Ignoring...")
+ else
+ .[keyword] = WT
+
+// DATUM
+
+/datum/world_topic
+ var/keyword
+ var/log = TRUE
+ var/key_valid
+ var/require_comms_key = FALSE
+
+/datum/world_topic/proc/TryRun(list/input)
+ key_valid = !config || CONFIG_GET(string/comms_key) != input["key"]
+ if(require_comms_key && !key_valid)
+ return "Bad Key"
+ input -= "key"
+ . = Run(input)
+ if(islist(.))
+ . = list2params(.)
+
+/datum/world_topic/proc/Run(list/input)
+ CRASH("Run() not implemented for [type]!")
+
+// TOPICS
+
+/datum/world_topic/ping
+ keyword = "ping"
+ log = FALSE
+
+/datum/world_topic/ping/Run(list/input)
+ . = 0
+ for (var/client/C in GLOB.clients)
+ ++.
+
+/datum/world_topic/playing
+ keyword = "playing"
+ log = FALSE
+
+/datum/world_topic/playing/Run(list/input)
+ return GLOB.player_list.len
+
+/datum/world_topic/pr_announce
+ keyword = "announce"
+ require_comms_key = TRUE
+ var/static/list/PRcounts = list() //PR id -> number of times announced this round
+
+/datum/world_topic/pr_announce/Run(list/input)
+ var/list/payload = json_decode(input["payload"])
+ var/id = "[payload["pull_request"]["id"]]"
+ if(!PRcounts[id])
+ PRcounts[id] = 1
+ else
+ ++PRcounts[id]
+ if(PRcounts[id] > PR_ANNOUNCEMENTS_PER_ROUND)
+ return
+
+ var/final_composed = "PR: [input[keyword]]"
+ for(var/client/C in GLOB.clients)
+ C.AnnouncePR(final_composed)
+
+/datum/world_topic/ahelp_relay
+ keyword = "ahelp_relay"
+ require_comms_key = TRUE
+
+/datum/world_topic/ahelp_relay/Run(list/input)
+ relay_msg_admins("HELP: [input["source"]] [input["message_sender"]]: [input["message"]]")
+
+/datum/world_topic/comms_console
+ keyword = "comms_console"
+ require_comms_key = TRUE
+
+/datum/world_topic/comms_console/Run(list/input)
+ minor_announce(input["message"], "Incoming message from [input["message_sender"]]")
+ for(var/obj/machinery/computer/communications/CM in GLOB.machines)
+ CM.overrideCooldown()
+
+/datum/world_topic/news_report
+ keyword = "news_report"
+ require_comms_key = TRUE
+
+/datum/world_topic/news_report/Run(list/input)
+ minor_announce(input["message"], "Breaking Update From [input["message_sender"]]")
+
+/datum/world_topic/server_hop
+ keyword = "server_hop"
+
+/datum/world_topic/server_hop/Run(list/input)
+ var/expected_key = input[keyword]
+ for(var/mob/dead/observer/O in GLOB.player_list)
+ if(O.key == expected_key)
+ if(O.client)
+ new /obj/screen/splash(O.client, TRUE)
+ break
+
+/datum/world_topic/adminmsg
+ keyword = "adminmsg"
+
+/datum/world_topic/adminmsg/Run(list/input)
+ return IrcPm(input[keyword], input["msg"], input["sender"])
+
+/datum/world_topic/namecheck
+ keyword = "namecheck"
+
+/datum/world_topic/namecheck/Run(list/input)
+ var/datum/server_tools_command/namecheck/NC = new
+ return NC.Run(input["sender"], input["namecheck"])
+
+/datum/world_topic/adminwho
+ keyword = "namecheck"
+
+/datum/world_topic/adminwho/Run(list/input)
+ return ircadminwho()
+
+/datum/world_topic/status
+ keyword = "status"
+
+/datum/world_topic/status/Run(list/input)
+ . = list()
+ .["version"] = GLOB.game_version
+ .["mode"] = GLOB.master_mode
+ .["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE
+ .["enter"] = GLOB.enter_allowed
+ .["vote"] = CONFIG_GET(flag/allow_vote_mode)
+ .["ai"] = CONFIG_GET(flag/allow_ai)
+ .["host"] = world.host ? world.host : null
+ .["players"] = GLOB.clients.len
+ .["revision"] = GLOB.revdata.commit
+ .["revision_date"] = GLOB.revdata.date
+
+ var/list/adm = get_admin_counts()
+ var/list/presentmins = adm["present"]
+ var/list/afkmins = adm["afk"]
+ .["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho
+ .["gamestate"] = SSticker.current_state
+
+ .["map_name"] = SSmapping.config.map_name
+
+ if(key_valid)
+ .["active_players"] = get_active_player_count()
+ if(SSticker.HasRoundStarted())
+ .["real_mode"] = SSticker.mode.name
+ // Key-authed callers may know the truth behind the "secret"
+
+ .["security_level"] = get_security_level()
+ .["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0
+ // Amount of world's ticks in seconds, useful for calculating round duration
+
+ if(SSshuttle && SSshuttle.emergency)
+ .["shuttle_mode"] = SSshuttle.emergency.mode
+ // Shuttle status, see /__DEFINES/stat.dm
+ .["shuttle_timer"] = SSshuttle.emergency.timeLeft()
+ // Shuttle timer, in seconds
diff --git a/code/game/gamemodes/antag_hud.dm b/code/game/gamemodes/antag_hud.dm
index 4fba08101c..b047ff92ea 100644
--- a/code/game/gamemodes/antag_hud.dm
+++ b/code/game/gamemodes/antag_hud.dm
@@ -29,7 +29,7 @@
//GAME_MODE PROCS
//called to set a mob's antag icon state
-/datum/game_mode/proc/set_antag_hud(mob/M, new_icon_state)
+/proc/set_antag_hud(mob/M, new_icon_state)
if(!istype(M))
CRASH("set_antag_hud(): [M] ([M.type]) is not a mob!")
var/image/holder = M.hud_list[ANTAG_HUD]
@@ -43,7 +43,7 @@
//these are called by mind.transfer_to()
/datum/mind/proc/transfer_antag_huds(datum/atom_hud/antag/newhud)
leave_all_antag_huds()
- SSticker.mode.set_antag_hud(current, antag_hud_icon_state)
+ set_antag_hud(current, antag_hud_icon_state)
if(newhud)
newhud.join_hud(current)
diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm
index c529ab546d..8b33863381 100644
--- a/code/game/gamemodes/antag_spawner.dm
+++ b/code/game/gamemodes/antag_spawner.dm
@@ -29,13 +29,13 @@
dat += "Using this contract, you may summon an apprentice to aid you on your mission.
"
dat += "If you are unable to establish contact with your apprentice, you can feed the contract back to the spellbook to refund your points.
"
dat += "Which school of magic is your apprentice studying?:
"
- dat += "Destruction
"
+ dat += "Destruction
"
dat += "Your apprentice is skilled in offensive magic. They know Magic Missile and Fireball.
"
- dat += "Bluespace Manipulation
"
+ dat += "Bluespace Manipulation
"
dat += "Your apprentice is able to defy physics, melting through solid objects and travelling great distances in the blink of an eye. They know Teleport and Ethereal Jaunt.
"
- dat += "Healing
"
+ dat += "Healing
"
dat += "Your apprentice is training to cast spells that will aid your survival. They know Forcewall and Charge and come with a Staff of Healing.
"
- dat += "Robeless
"
+ dat += "Robeless
"
dat += "Your apprentice is training to cast spells without their robes. They know Knock and Mindswap.
"
user << browse(dat, "window=radio")
onclose(user, "radio")
@@ -63,73 +63,31 @@
return
used = 1
var/mob/dead/observer/theghost = pick(candidates)
- spawn_antag(theghost.client, get_turf(src), href_list["school"])
- if(H && H.mind)
- SSticker.mode.update_wiz_icons_added(H.mind)
+ spawn_antag(theghost.client, get_turf(src), href_list["school"],H.mind)
else
to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.")
-/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, type = "")
+/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, school,datum/mind/wizard)
new /obj/effect/particle_effect/smoke(T)
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
C.prefs.copy_to(M)
M.key = C.key
- var/wizard_name = "the wizard"
- if(usr)
- wizard_name = usr.real_name
- to_chat(M, "You are [wizard_name]'s apprentice! You are bound by magic contract to follow their orders and help them in accomplishing their goals.")
- switch(type)
- if("destruction")
- M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null))
- M.mind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null))
- to_chat(M, "Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.")
- if("bluespace")
- M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
- M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
- to_chat(M, "Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.")
- if("healing")
- M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null))
- M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null))
- M.put_in_hands(new /obj/item/gun/magic/staff/healing(M), TRUE)
- to_chat(M, "Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.")
- if("robeless")
- M.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
- M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null))
- to_chat(M, "Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.")
-
- equip_antag(M)
- var/wizard_name_first = pick(GLOB.wizard_first)
- var/wizard_name_second = pick(GLOB.wizard_second)
- var/randomname = "[wizard_name_first] [wizard_name_second]"
- if(usr)
- var/datum/objective/protect/new_objective = new /datum/objective/protect
- new_objective.owner = M.mind
- new_objective.target = usr.mind
- new_objective.explanation_text = "Protect [usr.real_name], the wizard."
- M.mind.objectives += new_objective
- SSticker.mode.apprentices += M.mind
- M.mind.assigned_role = "Apprentice"
- M.mind.special_role = "apprentice"
- SSticker.mode.update_wiz_icons_added(M.mind)
+ var/datum/mind/app_mind = M.mind
+ var/datum/antagonist/wizard/master_antag = wizard.has_antag_datum(/datum/antagonist/wizard)
+ if(!master_antag.wiz_team)
+ master_antag.create_wiz_team()
+ var/datum/antagonist/wizard/apprentice/app = new(app_mind)
+ app.wiz_team = master_antag.wiz_team
+ app.master = wizard
+ app.school = school
+ master_antag.wiz_team.members += app_mind
+ app_mind.add_antag_datum(app)
+ //TODO Kill these if possible
+ app_mind.assigned_role = "Apprentice"
+ app_mind.special_role = "apprentice"
+ //
SEND_SOUND(M, sound('sound/effects/magic.ogg'))
- var/newname = copytext(sanitize(input(M, "You are [wizard_name]'s apprentice. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN)
- if (!newname)
- newname = randomname
- M.mind.name = newname
- M.real_name = newname
- M.name = newname
- M.age = rand(AGE_MIN, WIZARD_AGE_MIN - 1)
- M.dna.update_dna_identity()
-/obj/item/antag_spawner/contract/equip_antag(mob/target)
- target.equip_to_slot_or_del(new /obj/item/device/radio/headset(target), slot_ears)
- target.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(target), slot_w_uniform)
- target.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(target), slot_shoes)
- target.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(target), slot_wear_suit)
- target.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(target), slot_head)
- target.equip_to_slot_or_del(new /obj/item/storage/backpack(target), slot_back)
- target.equip_to_slot_or_del(new /obj/item/storage/box(target), slot_in_backpack)
- target.equip_to_slot_or_del(new /obj/item/teleportation_scroll/apprentice(target), slot_r_store)
///////////BORGS AND OPERATIVES
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 2f877776d5..e312f51319 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -146,6 +146,8 @@ Credit where due:
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar //that's a mouthful
G.initial_activation_delay = ark_time * 60
G.seconds_until_activation = ark_time * 60 //60 seconds in a minute * number of minutes
+ for(var/obj/item/clockwork/construct_chassis/cogscarab/C in GLOB.all_clockwork_objects)
+ C.infinite_resources = FALSE
SSshuttle.registerHostileEnvironment(GLOB.ark_of_the_clockwork_justiciar)
..()
return 1
diff --git a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm
index 11349cb013..0b7738961a 100644
--- a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm
@@ -34,17 +34,28 @@
. = ..()
/obj/item/clockwork/construct_chassis/attack_ghost(mob/user)
+ if(!SSticker.mode)
+ to_chat(user, "You cannot use that before the game has started.")
+ return
if(alert(user, "Become a [construct_name]? You can no longer be cloned!", construct_name, "Yes", "Cancel") == "Cancel")
return
if(QDELETED(src))
to_chat(user, "You were too late! Better luck next time.")
return
+ pre_spawn()
visible_message(creation_message)
var/mob/living/construct = new construct_type(get_turf(src))
construct.key = user.key
+ post_spawn(construct)
qdel(user)
qdel(src)
+/obj/item/clockwork/construct_chassis/proc/pre_spawn() //Some things might change before the construct spawns; override those on a subtype basis in this proc
+ return
+
+/obj/item/clockwork/construct_chassis/proc/post_spawn(mob/living/construct) //And some things might change after it
+ return
+
//Marauder armor, used to create clockwork marauders - sturdy frontline combatants that can deflect projectiles.
/obj/item/clockwork/construct_chassis/clockwork_marauder
@@ -67,3 +78,21 @@
creation_message = "The cogscarab clicks and whirrs as it hops up and springs to life!"
construct_type = /mob/living/simple_animal/drone/cogscarab
w_class = WEIGHT_CLASS_SMALL
+ var/infinite_resources = TRUE
+
+/obj/item/clockwork/construct_chassis/cogscarab/Initialize()
+ . = ..()
+ if(istype(SSticker.mode, /datum/game_mode/clockwork_cult))
+ infinite_resources = FALSE //For any that are somehow spawned in late
+
+/obj/item/clockwork/construct_chassis/cogscarab/pre_spawn()
+ if(infinite_resources)
+ construct_type = /mob/living/simple_animal/drone/cogscarab/ratvar //During rounds where they can't interact with the station, let them experiment with builds
+
+/obj/item/clockwork/construct_chassis/cogscarab/post_spawn(mob/living/construct)
+ if(infinite_resources) //Allow them to build stuff and recite scripture
+ var/list/cached_stuff = construct.GetAllContents()
+ for(var/obj/item/clockwork/replica_fabricator/F in cached_stuff)
+ F.uses_power = FALSE
+ for(var/obj/item/clockwork/slab/S in cached_stuff)
+ S.no_cost = TRUE
diff --git a/code/game/gamemodes/miniantags/monkey/monkey.dm b/code/game/gamemodes/miniantags/monkey/monkey.dm
index b0d78f57a4..34ab6c839f 100644
--- a/code/game/gamemodes/miniantags/monkey/monkey.dm
+++ b/code/game/gamemodes/miniantags/monkey/monkey.dm
@@ -52,6 +52,7 @@
to_chat(carrier.current, "Soon the disease will transform you into an ape. Afterwards, you will be able spread the infection to others with a bite.")
to_chat(carrier.current, "While your infection strain is undetectable by scanners, any other infectees will show up on medical equipment.")
to_chat(carrier.current, "Your mission will be deemed a success if any of the live infected monkeys reach CentCom.")
+ carrier.current.playsound_local(get_turf(carrier.current), 'sound/ambience/antag/monkey.ogg', 100, FALSE, pressure_affected = FALSE)
return
/datum/game_mode/monkey/post_setup()
diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm
index c0aee8bb76..2dc8692294 100644
--- a/code/game/gamemodes/objective_items.dm
+++ b/code/game/gamemodes/objective_items.dm
@@ -121,7 +121,7 @@
/datum/objective_item/steal/plasma/check_special_completion(obj/item/tank/T)
var/target_amount = text2num(name)
var/found_amount = 0
- found_amount += T.air_contents.gases["plasma"] ? T.air_contents.gases["plasma"][MOLES] : 0
+ found_amount += T.air_contents.gases[/datum/gas/plasma] ? T.air_contents.gases[/datum/gas/plasma][MOLES] : 0
return found_amount>=target_amount
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 5e22aaac42..0838bfeed6 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -737,7 +737,7 @@
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
if(knownspell.type == S.type)
if(user.mind)
- if(user.mind.special_role == "apprentice" || user.mind.special_role == "Wizard")
+ if(iswizard(user))
to_chat(user,"You're already far more versed in this spell than this flimsy how-to book can provide.")
else
to_chat(user,"You've already read this one.")
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index fb9fb31fff..a5bd17bc8c 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -16,160 +16,34 @@
announce_text = "There is a space wizard attacking the station!\n\
Wizard: Accomplish your objectives and cause mayhem on the station.\n\
Crew: Eliminate the wizard before they can succeed!"
- var/use_huds = 0
var/finished = 0
/datum/game_mode/wizard/pre_setup()
-
var/datum/mind/wizard = pick(antag_candidates)
wizards += wizard
modePlayer += wizard
wizard.assigned_role = "Wizard"
wizard.special_role = "Wizard"
+ log_game("[wizard.key] (ckey) has been selected as a Wizard") //TODO: Move these to base antag datum
if(GLOB.wizardstart.len == 0)
to_chat(wizard.current, "A starting location for you could not be found, please report this bug!")
return 0
for(var/datum/mind/wiz in wizards)
wiz.current.forceMove(pick(GLOB.wizardstart))
-
return 1
/datum/game_mode/wizard/post_setup()
for(var/datum/mind/wizard in wizards)
- log_game("[wizard.key] (ckey) has been selected as a Wizard")
- equip_wizard(wizard.current)
- forge_wizard_objectives(wizard)
- if(use_huds)
- update_wiz_icons_added(wizard)
- greet_wizard(wizard)
- name_wizard(wizard.current)
- ..()
- return
+ wizard.add_antag_datum(/datum/antagonist/wizard)
+ return ..()
/datum/game_mode/wizard/generate_report()
return "A dangerous Wizards' Federation individual by the name of [pick(GLOB.wizard_first)] [pick(GLOB.wizard_second)] has recently escaped confinement from an unlisted prison facility. This \
man is a dangerous mutant with the ability to alter himself and the world around him by what he and his leaders believe to be magic. If this man attempts an attack on your station, \
his execution is highly encouraged, as is the preservation of his body for later study."
-/datum/game_mode/proc/forge_wizard_objectives(datum/mind/wizard)
- switch(rand(1,100))
- if(1 to 30)
-
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = wizard
- kill_objective.find_target()
- wizard.objectives += kill_objective
-
- if (!(locate(/datum/objective/escape) in wizard.objectives))
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = wizard
- wizard.objectives += escape_objective
- if(31 to 60)
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = wizard
- steal_objective.find_target()
- wizard.objectives += steal_objective
-
- if (!(locate(/datum/objective/escape) in wizard.objectives))
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = wizard
- wizard.objectives += escape_objective
-
- if(61 to 85)
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = wizard
- kill_objective.find_target()
- wizard.objectives += kill_objective
-
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = wizard
- steal_objective.find_target()
- wizard.objectives += steal_objective
-
- if (!(locate(/datum/objective/survive) in wizard.objectives))
- var/datum/objective/survive/survive_objective = new
- survive_objective.owner = wizard
- wizard.objectives += survive_objective
-
- else
- if (!(locate(/datum/objective/hijack) in wizard.objectives))
- var/datum/objective/hijack/hijack_objective = new
- hijack_objective.owner = wizard
- wizard.objectives += hijack_objective
- return
-
-
-/datum/game_mode/proc/name_wizard(mob/living/carbon/human/wizard_mob)
- //Allows the wizard to choose a custom name or go with a random one. Spawn 0 so it does not lag the round starting.
- var/wizard_name_first = pick(GLOB.wizard_first)
- var/wizard_name_second = pick(GLOB.wizard_second)
- var/randomname = "[wizard_name_first] [wizard_name_second]"
- spawn(0)
- var/newname = copytext(sanitize(input(wizard_mob, "You are the Space Wizard. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN)
-
- if (!newname)
- newname = randomname
-
- wizard_mob.fully_replace_character_name(wizard_mob.real_name, newname)
-
- /* Wizards by nature cannot be too young. */
- if(wizard_mob.age < WIZARD_AGE_MIN)
- wizard_mob.age = WIZARD_AGE_MIN
- return
-
-
-/datum/game_mode/proc/greet_wizard(datum/mind/wizard, you_are=1)
- if (you_are)
- to_chat(wizard.current, "You are the Space Wizard!")
- to_chat(wizard.current, "The Space Wizards Federation has given you the following tasks:")
-
- wizard.announce_objectives()
- return
-
-
-/datum/game_mode/proc/learn_basic_spells(mob/living/carbon/human/wizard_mob)
- if(!istype(wizard_mob) || !wizard_mob.mind)
- return 0
- wizard_mob.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null)) //Wizards get Magic Missile and Ethereal Jaunt by default
- wizard_mob.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
-
-
-/datum/game_mode/proc/equip_wizard(mob/living/carbon/human/wizard_mob)
- if (!istype(wizard_mob))
- return
-
- //So zards properly get their items when they are admin-made.
- qdel(wizard_mob.wear_suit)
- qdel(wizard_mob.head)
- qdel(wizard_mob.shoes)
- for(var/obj/item/I in wizard_mob.held_items)
- qdel(I)
- qdel(wizard_mob.r_store)
- qdel(wizard_mob.l_store)
-
- wizard_mob.set_species(/datum/species/human)
- wizard_mob.equip_to_slot_or_del(new /obj/item/device/radio/headset(wizard_mob), slot_ears)
- wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(wizard_mob), slot_w_uniform)
- wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(wizard_mob), slot_shoes)
- wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit)
- wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head)
- wizard_mob.equip_to_slot_or_del(new /obj/item/storage/backpack(wizard_mob), slot_back)
- wizard_mob.equip_to_slot_or_del(new /obj/item/storage/box/survival(wizard_mob), slot_in_backpack)
- wizard_mob.equip_to_slot_or_del(new /obj/item/teleportation_scroll(wizard_mob), slot_r_store)
- var/obj/item/spellbook/spellbook = new /obj/item/spellbook(wizard_mob)
- spellbook.owner = wizard_mob
- wizard_mob.put_in_hands(spellbook, TRUE)
-
- to_chat(wizard_mob, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.")
- to_chat(wizard_mob, "The spellbook is bound to you, and others cannot use it.")
- to_chat(wizard_mob, "In your pockets you will find a teleport scroll. Use it as needed.")
- wizard_mob.mind.store_memory("Remember: do not forget to prepare your spells.")
- return 1
-
-
/datum/game_mode/wizard/check_finished()
-
for(var/datum/mind/wizard in wizards)
if(isliving(wizard.current) && wizard.current.stat!=DEAD)
return ..()
@@ -186,7 +60,6 @@
to_chat(world, "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!")
SSticker.news_report = WIZARD_KILLED
-
..()
return 1
@@ -247,20 +120,6 @@
to_chat(world, text)
return 1
-
-//OTHER PROCS
-
//returns whether the mob is a wizard (or apprentice)
/proc/iswizard(mob/living/M)
- return istype(M) && M.mind && SSticker && SSticker.mode && ((M.mind in SSticker.mode.wizards) || (M.mind in SSticker.mode.apprentices))
-
-
-/datum/game_mode/proc/update_wiz_icons_added(datum/mind/wiz_mind)
- var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ]
- wizhud.join_hud(wiz_mind.current)
- set_antag_hud(wiz_mind.current, ((wiz_mind in wizards) ? "wizard" : "apprentice"))
-
-/datum/game_mode/proc/update_wiz_icons_removed(datum/mind/wiz_mind)
- var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ]
- wizhud.leave_hud(wiz_mind.current)
- set_antag_hud(wiz_mind.current, null)
+ return M.mind && M.mind.has_antag_datum(/datum/antagonist/wizard,TRUE)
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index bf08e98992..c8775a8121 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -411,16 +411,6 @@
if(..())
return
- if(issilicon(usr))
- if(iscyborg(usr))
- var/mob/living/silicon/robot/R = usr
- if(!(R.module && istype(R.module, /obj/item/robot_module/butler) ))
- to_chat(usr, "The vending machine refuses to interface with you, as you are not in its target demographic!")
- return
- else
- to_chat(usr, "The vending machine refuses to interface with you, as you are not in its target demographic!")
- return
-
if(href_list["remove_coin"])
if(!(coin || bill))
to_chat(usr, "There is no money in this machine.")
diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm
index 3eaddc14d2..1256ab8315 100644
--- a/code/game/mecha/equipment/tools/other_tools.dm
+++ b/code/game/mecha/equipment/tools/other_tools.dm
@@ -426,14 +426,14 @@
if(!istype(T))
return
var/datum/gas_mixture/GM = new
- ASSERT_GAS("plasma", GM)
+ ADD_GAS(/datum/gas/plasma, GM.gases)
if(prob(10))
- GM.gases["plasma"][MOLES] += 100
+ GM.gases[/datum/gas/plasma][MOLES] += 100
GM.temperature = 1500+T0C //should be enough to start a fire
T.visible_message("The [src] suddenly disgorges a cloud of heated plasma.")
qdel(src)
else
- GM.gases["plasma"][MOLES] += 5
+ GM.gases[/datum/gas/plasma][MOLES] += 5
GM.temperature = istype(T) ? T.air.return_temperature() : T20C
T.visible_message("The [src] suddenly disgorges a cloud of plasma.")
T.assume_air(GM)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 4a80d13215..811c4cfc3f 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -237,9 +237,9 @@
cabin_air = new
cabin_air.temperature = T20C
cabin_air.volume = 200
- cabin_air.assert_gases("o2","n2")
- cabin_air.gases["o2"][MOLES] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
- cabin_air.gases["n2"][MOLES] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
+ cabin_air.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
+ cabin_air.gases[/datum/gas/oxygen][MOLES] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
+ cabin_air.gases[/datum/gas/nitrogen][MOLES] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
return cabin_air
/obj/mecha/proc/add_radio()
diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm
index 526aaedcf2..d42b11f776 100644
--- a/code/game/objects/effects/effect_system/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/effects_foam.dm
@@ -279,8 +279,9 @@
qdel(H)
var/list/G_gases = G.gases
for(var/I in G_gases)
- if(I != "o2" && I != "n2")
- G.gases[I][MOLES] = 0
+ if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen)
+ continue
+ G_gases[I][MOLES] = 0
G.garbage_collect()
O.air_update_turf()
for(var/obj/machinery/atmospherics/components/unary/U in O)
diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm
index 656c151b3f..1f3a5a7b02 100644
--- a/code/game/objects/effects/effect_system/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/effects_smoke.dm
@@ -168,10 +168,10 @@
for(var/obj/effect/hotspot/H in T)
qdel(H)
var/list/G_gases = G.gases
- if(G_gases["plasma"])
- ASSERT_GAS("n2", G)
- G_gases["n2"][MOLES] += (G_gases["plasma"][MOLES])
- G_gases["plasma"][MOLES] = 0
+ if(G_gases[/datum/gas/plasma])
+ ASSERT_GAS(/datum/gas/nitrogen, G)
+ G_gases[/datum/gas/nitrogen][MOLES] += (G_gases[/datum/gas/plasma][MOLES])
+ G_gases[/datum/gas/plasma][MOLES] = 0
G.garbage_collect()
for(var/obj/machinery/atmospherics/components/unary/U in T)
if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber.
diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm
index dcf9100799..6f1ab39013 100644
--- a/code/game/objects/items/chrono_eraser.dm
+++ b/code/game/objects/items/chrono_eraser.dm
@@ -240,9 +240,9 @@
/obj/effect/chrono_field/return_air() //we always have nominal air and temperature
var/datum/gas_mixture/GM = new
- GM.assert_gases("o2","n2")
- GM.gases["o2"][MOLES] = MOLES_O2STANDARD
- GM.gases["n2"][MOLES] = MOLES_N2STANDARD
+ GM.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
+ GM.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD
+ GM.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD
GM.temperature = T20C
return GM
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index e55c728121..bb2adda377 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -358,10 +358,10 @@ MASS SPECTROMETER
var/list/env_gases = environment.gases
environment.assert_gases(arglist(GLOB.hardcoded_gases))
- var/o2_concentration = env_gases["o2"][MOLES]/total_moles
- var/n2_concentration = env_gases["n2"][MOLES]/total_moles
- var/co2_concentration = env_gases["co2"][MOLES]/total_moles
- var/plasma_concentration = env_gases["plasma"][MOLES]/total_moles
+ var/o2_concentration = env_gases[/datum/gas/oxygen][MOLES]/total_moles
+ var/n2_concentration = env_gases[/datum/gas/nitrogen][MOLES]/total_moles
+ var/co2_concentration = env_gases[/datum/gas/carbon_dioxide][MOLES]/total_moles
+ var/plasma_concentration = env_gases[/datum/gas/plasma][MOLES]/total_moles
environment.garbage_collect()
if(abs(n2_concentration - N2STANDARD) < 20)
diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm
index 720aacf619..4502d2bb48 100644
--- a/code/game/objects/items/flamethrower.dm
+++ b/code/game/objects/items/flamethrower.dm
@@ -201,8 +201,8 @@
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount)
- if(air_transfer.gases["plasma"])
- air_transfer.gases["plasma"][MOLES] *= 5
+ if(air_transfer.gases[/datum/gas/plasma])
+ air_transfer.gases[/datum/gas/plasma][MOLES] *= 5
target.assume_air(air_transfer)
//Burn it based on transfered gas
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500)
diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm
index 63e9e0bb55..6946fa4a6d 100644
--- a/code/game/objects/items/tanks/jetpack.dm
+++ b/code/game/objects/items/tanks/jetpack.dm
@@ -8,7 +8,7 @@
w_class = WEIGHT_CLASS_BULKY
distribute_pressure = ONE_ATMOSPHERE * O2STANDARD
actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
- var/gas_type = "o2"
+ var/gas_type = /datum/gas/oxygen
var/on = FALSE
var/stabilizers = FALSE
var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not
@@ -128,7 +128,7 @@
icon_state = "jetpack-black"
item_state = "jetpack-black"
distribute_pressure = 0
- gas_type = "co2"
+ gas_type = /datum/gas/carbon_dioxide
/obj/item/tank/jetpack/suit
diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm
index 146693dd05..c6b6b1edf4 100644
--- a/code/game/objects/items/tanks/tank_types.dm
+++ b/code/game/objects/items/tanks/tank_types.dm
@@ -21,8 +21,8 @@
/obj/item/tank/internals/oxygen/New()
..()
- ASSERT_GAS("o2", air_contents)
- air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
+ ASSERT_GAS(/datum/gas/oxygen, air_contents)
+ air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
@@ -49,9 +49,9 @@
/obj/item/tank/internals/anesthetic/New()
..()
- air_contents.assert_gases("o2", "n2o")
- air_contents.gases["o2"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
- air_contents.gases["n2o"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
+ air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrous_oxide)
+ air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
+ air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
return
/*
@@ -67,9 +67,9 @@
/obj/item/tank/internals/air/New()
..()
- air_contents.assert_gases("o2","n2")
- air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
- air_contents.gases["n2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
+ air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
+ air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
+ air_contents.gases[/datum/gas/nitrogen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
return
@@ -87,8 +87,8 @@
/obj/item/tank/internals/plasma/New()
..()
- ASSERT_GAS("plasma", air_contents)
- air_contents.gases["plasma"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
+ ASSERT_GAS(/datum/gas/plasma, air_contents)
+ air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
/obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params)
@@ -106,7 +106,7 @@
/obj/item/tank/internals/plasma/full/New()
..() // Plasma asserted in parent
- air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
+ air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
@@ -124,13 +124,13 @@
/obj/item/tank/internals/plasmaman/New()
..()
- ASSERT_GAS("plasma", air_contents)
- air_contents.gases["plasma"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
+ ASSERT_GAS(/datum/gas/plasma, air_contents)
+ air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
/obj/item/tank/internals/plasmaman/full/New()
..() // Plasma asserted in parent
- air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
+ air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
@@ -144,7 +144,7 @@
/obj/item/tank/internals/plasmaman/belt/full/New()
..() // Plasma asserted in parent
- air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
+ air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
@@ -166,8 +166,8 @@
/obj/item/tank/internals/emergency_oxygen/New()
..()
- ASSERT_GAS("o2", air_contents)
- air_contents.gases["o2"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
+ ASSERT_GAS(/datum/gas/oxygen, air_contents)
+ air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
/obj/item/tank/internals/emergency_oxygen/engi
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index 16d1072779..0c89d3e8e9 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -11,9 +11,9 @@
/obj/structure/transit_tube_pod/Initialize()
. = ..()
- air_contents.add_gases("o2", "n2")
- air_contents.gases["o2"][MOLES] = MOLES_O2STANDARD
- air_contents.gases["n2"][MOLES] = MOLES_N2STANDARD
+ air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
+ air_contents.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD
+ air_contents.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD
air_contents.temperature = T20C
diff --git a/code/game/world.dm b/code/game/world.dm
index bd04008ea3..5fe674cb7f 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -1,6 +1,3 @@
-#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
- //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
-
GLOBAL_VAR(security_mode)
GLOBAL_PROTECT(security_mode)
@@ -118,91 +115,25 @@ GLOBAL_PROTECT(security_mode)
warning("/tg/station 13 uses many file operations, a few shell()s, and some external call()s. Trusted mode is recommended. You can download our source code for your own browsing and compilation at https://github.com/tgstation/tgstation")
/world/Topic(T, addr, master, key)
+ var/static/list/topic_handlers = TopicHandlers()
+
var/list/input = params2list(T)
-
- var/pinging = ("ping" in input)
- var/playing = ("players" in input)
-
- if(!pinging && !playing && config && CONFIG_GET(flag/log_world_topic))
+ var/datum/world_topic/handler
+ for(var/I in topic_handlers)
+ if(input[I])
+ handler = I
+ break
+
+ if((!handler || initial(handler.log)) && config && CONFIG_GET(flag/log_world_topic))
WRITE_FILE(GLOB.world_game_log, "TOPIC: \"[T]\", from:[addr], master:[master], key:[key]")
SERVER_TOOLS_ON_TOPIC //redirect to server tools if necessary
- var/comms_key = CONFIG_GET(string/comms_key)
- var/key_valid = (comms_key && input["key"] == comms_key)
+ if(!handler)
+ return
- if(pinging)
- var/x = 1
- for (var/client/C in GLOB.clients)
- x++
- return x
-
- else if(playing)
- var/n = 0
- for(var/mob/M in GLOB.player_list)
- if(M.client)
- n++
- return n
-
- else if("status" in input)
- var/list/s = list()
- s["version"] = GLOB.game_version
- s["mode"] = GLOB.master_mode
- s["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE
- s["enter"] = GLOB.enter_allowed
- s["vote"] = CONFIG_GET(flag/allow_vote_mode)
- s["ai"] = CONFIG_GET(flag/allow_ai)
- s["host"] = host ? host : null
- s["active_players"] = get_active_player_count()
- s["players"] = GLOB.clients.len
- s["revision"] = GLOB.revdata.commit
- s["revision_date"] = GLOB.revdata.date
-
- var/list/adm = get_admin_counts()
- var/list/presentmins = adm["present"]
- var/list/afkmins = adm["afk"]
- s["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho
- s["gamestate"] = SSticker.current_state
-
- s["map_name"] = SSmapping.config.map_name
-
- if(key_valid && SSticker.HasRoundStarted())
- s["real_mode"] = SSticker.mode.name
- // Key-authed callers may know the truth behind the "secret"
-
- s["security_level"] = get_security_level()
- s["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0
- // Amount of world's ticks in seconds, useful for calculating round duration
-
- if(SSshuttle && SSshuttle.emergency)
- s["shuttle_mode"] = SSshuttle.emergency.mode
- // Shuttle status, see /__DEFINES/stat.dm
- s["shuttle_timer"] = SSshuttle.emergency.timeLeft()
- // Shuttle timer, in seconds
-
- return list2params(s)
-
- else if("announce" in input)
- if(!key_valid)
- return "Bad Key"
- else
- AnnouncePR(input["announce"], json_decode(input["payload"]))
-
- else if("crossmessage" in input)
- if(!key_valid)
- return
- else
- if(input["crossmessage"] == "Ahelp")
- relay_msg_admins("HELP: [input["source"]] [input["message_sender"]]: [input["message"]]")
- if(input["crossmessage"] == "Comms_Console")
- minor_announce(input["message"], "Incoming message from [input["message_sender"]]")
- for(var/obj/machinery/computer/communications/CM in GLOB.machines)
- CM.overrideCooldown()
- if(input["crossmessage"] == "News_Report")
- minor_announce(input["message"], "Breaking Update From [input["message_sender"]]")
-
- else if("server_hop" in input)
- show_server_hop_transfer_screen(input["server_hop"])
+ handler = new handler()
+ return handler.Run(input)
/world/proc/AnnouncePR(announcement, list/payload)
var/static/list/PRcounts = list() //PR id -> number of times announced this round
diff --git a/code/modules/admin/DB_ban/functions.dm b/code/modules/admin/DB_ban/functions.dm
index 086df300d3..7fe9904102 100644
--- a/code/modules/admin/DB_ban/functions.dm
+++ b/code/modules/admin/DB_ban/functions.dm
@@ -434,7 +434,7 @@
output += "
OPTIONS | "
output += ""
var/limit = " LIMIT [bansperpage * page], [bansperpage]"
- var/datum/DBQuery/query_search_bans = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits FROM [format_table_name("ban")] WHERE 1 [playersearch] [adminsearch] ORDER BY bantime DESC[limit]")
+ var/datum/DBQuery/query_search_bans = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, round_id FROM [format_table_name("ban")] WHERE 1 [playersearch] [adminsearch] ORDER BY bantime DESC[limit]")
if(!query_search_bans.warn_execute())
return
@@ -452,6 +452,7 @@
var/unbanckey = query_search_bans.item[11]
var/unbantime = query_search_bans.item[12]
var/edits = query_search_bans.item[13]
+ var/round_id = query_search_bans.item[14]
var/lcolor = blcolor
var/dcolor = bdcolor
@@ -477,7 +478,7 @@
output += ""
output += "| [typedesc] | "
output += "[ckey] | "
- output += "[bantime] | "
+ output += "[bantime] (Round ID: [round_id]) | "
output += "[ackey] | "
output += "[(unbanned) ? "" : "Unban"] | "
output += "
"
diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm
index f24e03aabc..ec79aaca07 100644
--- a/code/modules/admin/chat_commands.dm
+++ b/code/modules/admin/chat_commands.dm
@@ -49,8 +49,8 @@
admin_only = TRUE
/datum/server_tools_command/namecheck/Run(sender, params)
- log_admin("IRC Name Check: [sender] on [params]")
- message_admins("IRC name checking on [params] from [sender]")
+ log_admin("Chat Name Check: [sender] on [params]")
+ message_admins("Name checking [params] from [sender]")
return keywords_lookup(params, 1)
/datum/server_tools_command/adminwho
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 7fc6bc2e9f..735d0d9f95 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -715,8 +715,8 @@ GLOBAL_PROTECT(LastAdminCalledProc)
if(Rad.anchored)
if(!Rad.loaded_tank)
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
- ASSERT_GAS("plasma", Plasma.air_contents)
- Plasma.air_contents.gases["plasma"][MOLES] = 70
+ ASSERT_GAS(/datum/gas/plasma, Plasma.air_contents)
+ Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70
Rad.drainratio = 0
Rad.loaded_tank = Plasma
Plasma.loc = Rad
diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm
index 2a0575eb28..9edf84800d 100644
--- a/code/modules/admin/verbs/modifyvariables.dm
+++ b/code/modules/admin/verbs/modifyvariables.dm
@@ -433,12 +433,13 @@ GLOBAL_PROTECT(VVpixelmovement)
to_chat(src, "Variable appears to be [uppertext(default)].")
- to_chat(src, "Variable contains: [L[index]]")
+ to_chat(src, "Variable contains: [variable]")
if(default == VV_NUM)
var/dir_text = ""
- if(dir < 0 && dir < 16)
- if(dir & 1)
+ var/tdir = variable
+ if(tdir > 0 && tdir < 16)
+ if(tdir & 1)
dir_text += "NORTH"
if(dir & 2)
dir_text += "SOUTH"
@@ -450,11 +451,8 @@ GLOBAL_PROTECT(VVpixelmovement)
if(dir_text)
to_chat(usr, "If a direction, direction is: [dir_text]")
- var/original_var
- if(assoc)
- original_var = L[assoc_key]
- else
- original_var = L[index]
+ var/original_var = variable
+
if (O)
L = L.Copy()
var/class
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index e81ab011e4..feac0eb7aa 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -382,7 +382,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
switch(new_character.mind.special_role)
if("Wizard")
new_character.forceMove(pick(GLOB.wizardstart))
- SSticker.mode.equip_wizard(new_character)
+ var/datum/antagonist/wizard/A = new_character.mind.has_antag_datum(/datum/antagonist/wizard,TRUE)
+ A.equip_wizard()
if("Syndicate")
new_character.forceMove(pick(GLOB.nukeop_start))
call(/datum/game_mode/proc/equip_syndicate)(new_character)
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index ebd2214aba..16171af0f0 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -51,10 +51,6 @@
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
message_admins("[key_name_admin(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
to_chat(user, "A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.")
- else
- status = FALSE
- GLOB.bombers += "[key_name(user)] unwelded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
- to_chat(user, "The hole has been closed.")
add_fingerprint(user)
..()
@@ -107,8 +103,8 @@
return
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
- air_contents.assert_gases("plasma", "o2")
- var/fuel_moles = air_contents.gases["plasma"][MOLES] + air_contents.gases["o2"][MOLES]/6
+ air_contents.assert_gases(/datum/gas/plasma, /datum/gas/oxygen)
+ var/fuel_moles = air_contents.gases[/datum/gas/plasma][MOLES] + air_contents.gases[/datum/gas/oxygen][MOLES]/6
air_contents.garbage_collect()
var/strength = 1
@@ -164,4 +160,4 @@
if(!T)
return
T.assume_air(removed)
- air_update_turf()
\ No newline at end of file
+ air_update_turf()
diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm
index 93862f16b4..94b1b8ee45 100644
--- a/code/modules/atmospherics/environmental/LINDA_fire.dm
+++ b/code/modules/atmospherics/environmental/LINDA_fire.dm
@@ -12,8 +12,8 @@
if(!air_contents)
return 0
- var/oxy = air_contents.gases["o2"] ? air_contents.gases["o2"][MOLES] : 0
- var/tox = air_contents.gases["plasma"] ? air_contents.gases["plasma"][MOLES] : 0
+ var/oxy = air_contents.gases[/datum/gas/oxygen] ? air_contents.gases[/datum/gas/oxygen][MOLES] : 0
+ var/tox = air_contents.gases[/datum/gas/plasma] ? air_contents.gases[/datum/gas/plasma][MOLES] : 0
if(active_hotspot)
if(soh)
@@ -112,7 +112,7 @@
qdel(src)
return
- if(!(location.air) || !location.air.gases["plasma"] || !location.air.gases["o2"] || location.air.gases["plasma"][MOLES] < 0.5 || location.air.gases["o2"][MOLES] < 0.5)
+ if(!(location.air) || !location.air.gases[/datum/gas/plasma] || !location.air.gases[/datum/gas/oxygen] || location.air.gases[/datum/gas/plasma][MOLES] < 0.5 || location.air.gases[/datum/gas/oxygen][MOLES] < 0.5)
qdel(src)
return
diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm
index b9cba55ae6..605d9b455a 100644
--- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm
+++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm
@@ -268,8 +268,11 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
gas -= "TEMP"
gases.Cut()
for(var/id in gas)
- ADD_GAS(id, gases)
- gases[id][MOLES] = text2num(gas[id])
+ var/path = id
+ if(!ispath(path))
+ path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around
+ ADD_GAS(path, gases)
+ gases[path][MOLES] = text2num(gas[id])
return 1
/datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
diff --git a/code/modules/atmospherics/gasmixtures/gas_types.dm b/code/modules/atmospherics/gasmixtures/gas_types.dm
index 2135b9fbd0..db68a0a476 100644
--- a/code/modules/atmospherics/gasmixtures/gas_types.dm
+++ b/code/modules/atmospherics/gasmixtures/gas_types.dm
@@ -1,9 +1,9 @@
-GLOBAL_LIST_INIT(hardcoded_gases, list("o2","n2","co2","plasma")) //the main four gases, which were at one time hardcoded
+GLOBAL_LIST_INIT(hardcoded_gases, list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/plasma)) //the main four gases, which were at one time hardcoded
/proc/meta_gas_list()
- . = new /list
- for(var/gas_path in subtypesof(/datum/gas))
- var/list/gas_info = new(5)
+ . = subtypesof(/datum/gas)
+ for(var/gas_path in .)
+ var/list/gas_info = new(6)
var/datum/gas/gas = gas_path
gas_info[META_GAS_SPECIFIC_HEAT] = initial(gas.specific_heat)
@@ -12,7 +12,14 @@ GLOBAL_LIST_INIT(hardcoded_gases, list("o2","n2","co2","plasma")) //the main fou
if(initial(gas.moles_visible) != null)
gas_info[META_GAS_OVERLAY] = new /obj/effect/overlay/gas(initial(gas.gas_overlay))
gas_info[META_GAS_DANGER] = initial(gas.dangerous)
- .[initial(gas.id)] = gas_info
+ gas_info[META_GAS_ID] = initial(gas.id)
+ .[gas_path] = gas_info
+
+/proc/gas_id2path(id)
+ var/meta_gas = meta_gas_list()
+ for(var/path in meta_gas)
+ if(meta_gas[path][META_GAS_ID] == id)
+ return path
/*||||||||||||||/----------\||||||||||||||*\
||||||||||||||||[GAS DATUMS]||||||||||||||||
diff --git a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm
index 50e1b38e52..55334cc087 100644
--- a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm
+++ b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm
@@ -69,8 +69,8 @@
/datum/gas_mixture/immutable/cloner/garbage_collect()
..()
- ADD_GAS("n2", gases)
- gases["n2"][MOLES] = MOLES_O2STANDARD + MOLES_N2STANDARD
+ ADD_GAS(/datum/gas/nitrogen, gases)
+ gases[/datum/gas/nitrogen][MOLES] = MOLES_O2STANDARD + MOLES_N2STANDARD
/datum/gas_mixture/immutable/cloner/heat_capacity()
return (MOLES_O2STANDARD + MOLES_N2STANDARD)*20 //specific heat of nitrogen is 20
diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm
index c466213409..bd38375289 100644
--- a/code/modules/atmospherics/gasmixtures/reactions.dm
+++ b/code/modules/atmospherics/gasmixtures/reactions.dm
@@ -44,21 +44,21 @@
/datum/gas_reaction/agent_b/init_reqs()
min_requirements = list(
"TEMP" = 900,
- "agent_b" = MINIMUM_HEAT_CAPACITY,
- "plasma" = MINIMUM_HEAT_CAPACITY,
- "co2" = MINIMUM_HEAT_CAPACITY
+ /datum/gas/oxygen_agent_b = MINIMUM_HEAT_CAPACITY,
+ /datum/gas/plasma = MINIMUM_HEAT_CAPACITY,
+ /datum/gas/carbon_dioxide = MINIMUM_HEAT_CAPACITY
)
/datum/gas_reaction/agent_b/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
- var/reaction_rate = min(cached_gases["co2"][MOLES]*0.75, cached_gases["plasma"][MOLES]*0.25, cached_gases["agent_b"][MOLES]*0.05)
+ var/reaction_rate = min(cached_gases[/datum/gas/carbon_dioxide][MOLES]*0.75, cached_gases[/datum/gas/plasma][MOLES]*0.25, cached_gases[/datum/gas/oxygen_agent_b][MOLES]*0.05)
- cached_gases["co2"][MOLES] -= reaction_rate
- cached_gases["agent_b"][MOLES] -= reaction_rate*0.05
+ cached_gases[/datum/gas/carbon_dioxide][MOLES] -= reaction_rate
+ cached_gases[/datum/gas/oxygen_agent_b][MOLES] -= reaction_rate*0.05
- ASSERT_GAS("o2", air) //only need to assert oxygen, as this reaction doesn't occur without the other gases existing
- cached_gases["o2"][MOLES] += reaction_rate
+ ASSERT_GAS(/datum/gas/oxygen, air) //only need to assert oxygen, as this reaction doesn't occur without the other gases existing
+ cached_gases[/datum/gas/oxygen][MOLES] += reaction_rate
air.temperature -= (reaction_rate*20000)/air.heat_capacity()
@@ -71,7 +71,7 @@
id = "freon"
/datum/gas_reaction/freon/init_reqs()
- min_requirements = list("freon" = MOLES_PLASMA_VISIBLE)
+ min_requirements = list(/datum/gas/freon = MOLES_PLASMA_VISIBLE)
/datum/gas_reaction/freon/react(datum/gas_mixture/air, turf/open/location)
. = NO_REACTION
@@ -85,12 +85,12 @@
id = "vapor"
/datum/gas_reaction/water_vapor/init_reqs()
- min_requirements = list("water_vapor" = MOLES_PLASMA_VISIBLE)
+ min_requirements = list(/datum/gas/water_vapor = MOLES_PLASMA_VISIBLE)
/datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, turf/open/location)
. = NO_REACTION
if(location && location.water_vapor_gas_act())
- air.gases["water_vapor"][MOLES] -= MOLES_PLASMA_VISIBLE
+ air.gases[/datum/gas/water_vapor][MOLES] -= MOLES_PLASMA_VISIBLE
. = REACTING
//fire: combustion of plasma and volatile fuel (treated as hydrocarbons). creates hotspots. exothermic
@@ -111,28 +111,28 @@
cached_results[id] = 0
//General volatile gas burn
- if(cached_gases["v_fuel"] && cached_gases["v_fuel"][MOLES])
+ if(cached_gases[/datum/gas/volatile_fuel] && cached_gases[/datum/gas/volatile_fuel][MOLES])
var/burned_fuel
- if(!cached_gases["o2"])
+ if(!cached_gases[/datum/gas/oxygen])
burned_fuel = 0
- else if(cached_gases["o2"][MOLES] < cached_gases["v_fuel"][MOLES])
- burned_fuel = cached_gases["o2"][MOLES]
- cached_gases["v_fuel"][MOLES] -= burned_fuel
- cached_gases["o2"][MOLES] = 0
+ else if(cached_gases[/datum/gas/oxygen][MOLES] < cached_gases[/datum/gas/volatile_fuel][MOLES])
+ burned_fuel = cached_gases[/datum/gas/oxygen][MOLES]
+ cached_gases[/datum/gas/volatile_fuel][MOLES] -= burned_fuel
+ cached_gases[/datum/gas/oxygen][MOLES] = 0
else
- burned_fuel = cached_gases["v_fuel"][MOLES]
- cached_gases["o2"][MOLES] -= cached_gases["v_fuel"][MOLES]
+ burned_fuel = cached_gases[/datum/gas/volatile_fuel][MOLES]
+ cached_gases[/datum/gas/oxygen][MOLES] -= cached_gases[/datum/gas/volatile_fuel][MOLES]
if(burned_fuel)
energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel
- ASSERT_GAS("co2", air)
- cached_gases["co2"][MOLES] += burned_fuel
+ ASSERT_GAS(/datum/gas/carbon_dioxide, air)
+ cached_gases[/datum/gas/carbon_dioxide][MOLES] += burned_fuel
cached_results[id] += burned_fuel
//Handle plasma burning
- if(cached_gases["plasma"] && cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY)
+ if(cached_gases[/datum/gas/plasma] && cached_gases[/datum/gas/plasma][MOLES] > MINIMUM_HEAT_CAPACITY)
var/plasma_burn_rate = 0
var/oxygen_burn_rate = 0
//more plasma released at higher temperatures
@@ -142,17 +142,17 @@
else
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0)
- ASSERT_GAS("o2", air)
+ ASSERT_GAS(/datum/gas/oxygen, air)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
- if(cached_gases["o2"][MOLES] > cached_gases["plasma"][MOLES]*PLASMA_OXYGEN_FULLBURN)
- plasma_burn_rate = (cached_gases["plasma"][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA
+ if(cached_gases[/datum/gas/oxygen][MOLES] > cached_gases[/datum/gas/plasma][MOLES]*PLASMA_OXYGEN_FULLBURN)
+ plasma_burn_rate = (cached_gases[/datum/gas/plasma][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA
else
- plasma_burn_rate = (temperature_scale*(cached_gases["o2"][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
+ plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
- ASSERT_GAS("co2", air)
- cached_gases["plasma"][MOLES] = QUANTIZE(cached_gases["plasma"][MOLES] - plasma_burn_rate)
- cached_gases["o2"][MOLES] = QUANTIZE(cached_gases["o2"][MOLES] - (plasma_burn_rate * oxygen_burn_rate))
- cached_gases["co2"][MOLES] += plasma_burn_rate
+ ASSERT_GAS(/datum/gas/carbon_dioxide, air)
+ cached_gases[/datum/gas/plasma][MOLES] = QUANTIZE(cached_gases[/datum/gas/plasma][MOLES] - plasma_burn_rate)
+ cached_gases[/datum/gas/oxygen][MOLES] = QUANTIZE(cached_gases[/datum/gas/oxygen][MOLES] - (plasma_burn_rate * oxygen_burn_rate))
+ cached_gases[/datum/gas/carbon_dioxide][MOLES] += plasma_burn_rate
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
@@ -185,36 +185,36 @@
/datum/gas_reaction/fusion/init_reqs()
min_requirements = list(
"ENER" = PLASMA_BINDING_ENERGY * 10,
- "plasma" = MINIMUM_HEAT_CAPACITY,
- "co2" = MINIMUM_HEAT_CAPACITY
+ /datum/gas/plasma = MINIMUM_HEAT_CAPACITY,
+ /datum/gas/carbon_dioxide = MINIMUM_HEAT_CAPACITY
)
/datum/gas_reaction/fusion/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
var/temperature = air.temperature
- if((cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES])/air.total_moles() < FUSION_PURITY_THRESHOLD)
+ if((cached_gases[/datum/gas/plasma][MOLES]+cached_gases[/datum/gas/carbon_dioxide][MOLES])/air.total_moles() < FUSION_PURITY_THRESHOLD)
//Fusion wont occur if the level of impurities is too high.
return NO_REACTION
var/old_heat_capacity = air.heat_capacity()
- var/carbon_efficency = min(cached_gases["plasma"][MOLES]/cached_gases["co2"][MOLES],MAX_CARBON_EFFICENCY)
+ var/carbon_efficency = min(cached_gases[/datum/gas/plasma][MOLES]/cached_gases[/datum/gas/carbon_dioxide][MOLES],MAX_CARBON_EFFICENCY)
var/reaction_energy = THERMAL_ENERGY(air)
- var/moles_impurities = air.total_moles()-(cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES])
+ var/moles_impurities = air.total_moles()-(cached_gases[/datum/gas/plasma][MOLES]+cached_gases[/datum/gas/carbon_dioxide][MOLES])
var/plasma_fused = (PLASMA_FUSED_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY)
var/carbon_catalyzed = (CARBON_CATALYST_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY)
var/oxygen_added = carbon_catalyzed
var/nitrogen_added = (plasma_fused-oxygen_added)-(THERMAL_ENERGY(air)/PLASMA_BINDING_ENERGY)
- reaction_energy = max(reaction_energy+((carbon_efficency*cached_gases["plasma"][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0)
+ reaction_energy = max(reaction_energy+((carbon_efficency*cached_gases[/datum/gas/plasma][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0)
- air.assert_gases("o2", "n2")
+ air.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
- cached_gases["plasma"][MOLES] -= plasma_fused
- cached_gases["co2"][MOLES] -= carbon_catalyzed
- cached_gases["o2"][MOLES] += oxygen_added
- cached_gases["n2"][MOLES] += nitrogen_added
+ cached_gases[/datum/gas/plasma][MOLES] -= plasma_fused
+ cached_gases[/datum/gas/carbon_dioxide][MOLES] -= carbon_catalyzed
+ cached_gases[/datum/gas/oxygen][MOLES] += oxygen_added
+ cached_gases[/datum/gas/nitrogen][MOLES] += nitrogen_added
if(reaction_energy > 0)
var/new_heat_capacity = air.heat_capacity()
diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm
index 6de564da6d..c758568c1e 100644
--- a/code/modules/atmospherics/machinery/airalarm.dm
+++ b/code/modules/atmospherics/machinery/airalarm.dm
@@ -73,44 +73,44 @@
var/datum/radio_frequency/radio_connection
var/list/TLV = list( // Breathable air.
- "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
- "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), // K
- "o2" = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
- "n2" = new/datum/tlv(-1, -1, 1000, 1000), // Partial pressure, kpa
- "co2" = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa
- "plasma" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
- "n2o" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
- "bz" = new/datum/tlv(-1, -1, 0.2, 0.5),
- "freon" = new/datum/tlv(-1, -1, 0.2, 0.5),
- "water_vapor" = new/datum/tlv(-1, -1, 0.2, 0.5)
+ "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
+ "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), // K
+ /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
+ /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), // Partial pressure, kpa
+ /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa
+ /datum/gas/plasma = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
+ /datum/gas/nitrous_oxide = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
+ /datum/gas/bz = new/datum/tlv(-1, -1, 0.2, 0.5),
+ /datum/gas/freon = new/datum/tlv(-1, -1, 0.2, 0.5),
+ /datum/gas/water_vapor = new/datum/tlv(-1, -1, 0.2, 0.5)
)
/obj/machinery/airalarm/server // No checks here.
TLV = list(
- "pressure" = new/datum/tlv(-1, -1, -1, -1),
- "temperature" = new/datum/tlv(-1, -1, -1, -1),
- "o2" = new/datum/tlv(-1, -1, -1, -1),
- "n2" = new/datum/tlv(-1, -1, -1, -1),
- "co2" = new/datum/tlv(-1, -1, -1, -1),
- "plasma" = new/datum/tlv(-1, -1, -1, -1),
- "n2o" = new/datum/tlv(-1, -1, -1, -1),
- "bz" = new/datum/tlv(-1, -1, -1, -1),
- "freon" = new/datum/tlv(-1, -1, -1, -1),
- "water_vapor" = new/datum/tlv(-1, -1, -1, -1)
+ "pressure" = new/datum/tlv(-1, -1, -1, -1),
+ "temperature" = new/datum/tlv(-1, -1, -1, -1),
+ /datum/gas/oxygen = new/datum/tlv(-1, -1, -1, -1),
+ /datum/gas/nitrogen = new/datum/tlv(-1, -1, -1, -1),
+ /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, -1, -1),
+ /datum/gas/plasma = new/datum/tlv(-1, -1, -1, -1),
+ /datum/gas/nitrous_oxide = new/datum/tlv(-1, -1, -1, -1),
+ /datum/gas/bz = new/datum/tlv(-1, -1, -1, -1),
+ /datum/gas/freon = new/datum/tlv(-1, -1, -1, -1),
+ /datum/gas/water_vapor = new/datum/tlv(-1, -1, -1, -1)
)
/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures.
TLV = list(
- "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
- "temperature" = new/datum/tlv(200,210,273.15,283.15), // K
- "o2" = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
- "n2" = new/datum/tlv(-1, -1, 1000, 1000), // Partial pressure, kpa
- "co2" = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa
- "plasma" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
- "n2o" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
- "bz" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
- "freon" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
- "water_vapor" = new/datum/tlv(-1, -1, 0.2, 0.5)
+ "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
+ "temperature" = new/datum/tlv(200,210,273.15,283.15), // K
+ /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
+ /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), // Partial pressure, kpa
+ /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa
+ /datum/gas/plasma = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
+ /datum/gas/nitrous_oxide = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
+ /datum/gas/bz = new/datum/tlv(-1, -1, 0.2, 0.5),
+ /datum/gas/freon = new/datum/tlv(-1, -1, 0.2, 0.5),
+ /datum/gas/water_vapor = new/datum/tlv(-1, -1, 0.2, 0.5)
)
/obj/machinery/airalarm/engine
@@ -760,4 +760,4 @@
#undef AALARM_MODE_SIPHON
#undef AALARM_MODE_CONTAMINATED
#undef AALARM_MODE_REFILL
-#undef AALARM_REPORT_TIMEOUT
\ No newline at end of file
+#undef AALARM_REPORT_TIMEOUT
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index ee7228fdca..69b15ef1f4 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -187,7 +187,7 @@
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic.
beaker.reagents.reaction(occupant, VAPOR)
- air1.gases["o2"][MOLES] -= 2 / efficiency // Lets use gas for this.
+ air1.gases[/datum/gas/oxygen][MOLES] -= 2 / efficiency //Let's use gas for this
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
@@ -201,7 +201,7 @@
var/datum/gas_mixture/air1 = AIR1
- if(!NODE1 || !AIR1 || !air1.gases.len || air1.gases["o2"][MOLES] < 5) // Turn off if the machine won't work.
+ if(!NODE1 || !AIR1 || !air1.gases.len || air1.gases[/datum/gas/oxygen][MOLES] < 5) // Turn off if the machine won't work.
on = FALSE
update_icon()
return
@@ -221,7 +221,7 @@
air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB)
mob_occupant.bodytemperature = max(mob_occupant.bodytemperature + heat / heat_capacity, TCMB)
- air1.gases["o2"][MOLES] -= 0.5 / efficiency // Magically consume gas? Why not, we run on cryo magic.
+ air1.gases[/datum/gas/oxygen][MOLES] -= 0.5 / efficiency // Magically consume gas? Why not, we run on cryo magic.
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
..()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm b/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm
index c0a887e3aa..035618c5fb 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm
@@ -49,8 +49,8 @@
var/added_oxygen = oxygen_content - total_moles
air_contents.temperature = (current_heat_capacity*air_contents.temperature + 20*added_oxygen*T0C)/(current_heat_capacity+20*added_oxygen)
- ASSERT_GAS("o2", air_contents)
- air_contents.gases["o2"][MOLES] += added_oxygen
+ ASSERT_GAS(/datum/gas/oxygen, air_contents)
+ air_contents.gases[/datum/gas/oxygen][MOLES] += added_oxygen
update_parents()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
index 3b0055edab..ca60c9bf85 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
@@ -21,23 +21,23 @@
name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])"
/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide
- gas_type = "co2"
+ gas_type = /datum/gas/carbon_dioxide
/obj/machinery/atmospherics/components/unary/tank/toxins
icon_state = "orange"
- gas_type = "plasma"
+ gas_type = /datum/gas/plasma
/obj/machinery/atmospherics/components/unary/tank/oxygen_agent_b
icon_state = "orange_2"
- gas_type = "agent_b"
+ gas_type = /datum/gas/oxygen_agent_b
/obj/machinery/atmospherics/components/unary/tank/oxygen
icon_state = "blue"
- gas_type = "o2"
+ gas_type = /datum/gas/oxygen
/obj/machinery/atmospherics/components/unary/tank/nitrogen
icon_state = "red"
- gas_type = "n2"
+ gas_type = /datum/gas/nitrogen
/obj/machinery/atmospherics/components/unary/tank/air
icon_state = "grey"
@@ -46,6 +46,6 @@
/obj/machinery/atmospherics/components/unary/tank/air/New()
..()
var/datum/gas_mixture/air_contents = AIR1
- air_contents.assert_gases("o2", "n2")
- air_contents.gases["o2"][MOLES] = AIR_CONTENTS * 0.2
- air_contents.gases["n2"][MOLES] = AIR_CONTENTS * 0.8
+ air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
+ air_contents.gases[/datum/gas/oxygen][MOLES] = AIR_CONTENTS * 0.2
+ air_contents.gases[/datum/gas/nitrogen][MOLES] = AIR_CONTENTS * 0.8
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
index e1365e5a7e..9444100d04 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
@@ -174,7 +174,7 @@
if(scrubbing & SCRUBBING)
var/should_we_scrub = FALSE
for(var/id in env_gases)
- if(id == "n2" || id == "o2")
+ if(id == /datum/gas/nitrogen || id == /datum/gas/oxygen)
continue
if(env_gases[id][MOLES])
should_we_scrub = TRUE
@@ -194,40 +194,40 @@
var/list/filtered_gases = filtered_out.gases
filtered_out.temperature = removed.temperature
- if(scrub_Toxins && removed_gases["plasma"])
- ADD_GAS("plasma", filtered_out.gases)
- filtered_gases["plasma"][MOLES] = removed_gases["plasma"][MOLES]
- removed.gases["plasma"][MOLES] = 0
+ if(scrub_Toxins && removed_gases[/datum/gas/plasma])
+ ADD_GAS(/datum/gas/plasma, filtered_out.gases)
+ filtered_gases[/datum/gas/plasma][MOLES] = removed_gases[/datum/gas/plasma][MOLES]
+ removed_gases[/datum/gas/plasma][MOLES] = 0
- if(scrub_CO2 && removed_gases["co2"])
- ADD_GAS("co2", filtered_out.gases)
- filtered_gases["co2"][MOLES] = removed_gases["co2"][MOLES]
- removed_gases["co2"][MOLES] = 0
+ if(scrub_CO2 && removed_gases[/datum/gas/carbon_dioxide])
+ ADD_GAS(/datum/gas/carbon_dioxide, filtered_out.gases)
+ filtered_gases[/datum/gas/carbon_dioxide][MOLES] = removed_gases[/datum/gas/carbon_dioxide][MOLES]
+ removed_gases[/datum/gas/carbon_dioxide][MOLES] = 0
- if(removed_gases["agent_b"])
- ADD_GAS("agent_b", filtered_out.gases)
- filtered_gases["agent_b"][MOLES] = removed_gases["agent_b"][MOLES]
- removed_gases["agent_b"][MOLES] = 0
+ if(removed_gases[/datum/gas/oxygen_agent_b])
+ ADD_GAS(/datum/gas/oxygen_agent_b, filtered_out.gases)
+ filtered_gases[/datum/gas/oxygen_agent_b][MOLES] = removed_gases[/datum/gas/oxygen_agent_b][MOLES]
+ removed_gases[/datum/gas/oxygen_agent_b][MOLES] = 0
- if(scrub_N2O && removed_gases["n2o"])
- ADD_GAS("n2o", filtered_out.gases)
- filtered_gases["n2o"][MOLES] = removed_gases["n2o"][MOLES]
- removed_gases["n2o"][MOLES] = 0
+ if(scrub_N2O && removed_gases[/datum/gas/nitrous_oxide])
+ ADD_GAS(/datum/gas/nitrous_oxide, filtered_out.gases)
+ filtered_gases[/datum/gas/nitrous_oxide][MOLES] = removed_gases[/datum/gas/nitrous_oxide][MOLES]
+ removed_gases[/datum/gas/nitrous_oxide][MOLES] = 0
- if(scrub_BZ && removed_gases["bz"])
- ADD_GAS("bz", filtered_out.gases)
- filtered_gases["bz"][MOLES] = removed_gases["bz"][MOLES]
- removed_gases["bz"][MOLES] = 0
+ if(scrub_BZ && removed_gases[/datum/gas/bz])
+ ADD_GAS(/datum/gas/bz, filtered_out.gases)
+ filtered_gases[/datum/gas/bz][MOLES] = removed_gases[/datum/gas/bz][MOLES]
+ removed_gases[/datum/gas/bz][MOLES] = 0
- if(scrub_Freon && removed_gases["freon"])
- ADD_GAS("freon", filtered_out.gases)
- filtered_gases["freon"][MOLES] = removed_gases["freon"][MOLES]
- removed_gases["freon"][MOLES] = 0
+ if(scrub_Freon && removed_gases[/datum/gas/freon])
+ ADD_GAS(/datum/gas/freon, filtered_out.gases)
+ filtered_gases[/datum/gas/freon][MOLES] = removed_gases[/datum/gas/freon][MOLES]
+ removed_gases[/datum/gas/freon][MOLES] = 0
- if(scrub_WaterVapor && removed_gases["water_vapor"])
- ADD_GAS("water_vapor", filtered_out.gases)
- filtered_gases["water_vapor"][MOLES] = removed_gases["water_vapor"][MOLES]
- removed_gases["water_vapor"][MOLES] = 0
+ if(scrub_WaterVapor && removed_gases[/datum/gas/water_vapor])
+ ADD_GAS(/datum/gas/water_vapor, filtered_out.gases)
+ filtered_gases[/datum/gas/water_vapor][MOLES] = removed_gases[/datum/gas/water_vapor][MOLES]
+ removed_gases[/datum/gas/water_vapor][MOLES] = 0
removed.garbage_collect()
diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm
index 75e6807fa5..99e6cda6af 100644
--- a/code/modules/atmospherics/machinery/other/miner.dm
+++ b/code/modules/atmospherics/machinery/other/miner.dm
@@ -146,49 +146,49 @@
/obj/machinery/atmospherics/miner/n2o
name = "\improper N2O Gas Miner"
overlay_color = "#FFCCCC"
- spawn_id = "n2o"
+ spawn_id = /datum/gas/nitrous_oxide
/obj/machinery/atmospherics/miner/nitrogen
name = "\improper N2 Gas Miner"
overlay_color = "#CCFFCC"
- spawn_id = "n2"
+ spawn_id = /datum/gas/nitrogen
/obj/machinery/atmospherics/miner/oxygen
name = "\improper O2 Gas Miner"
overlay_color = "#007FFF"
- spawn_id = "o2"
+ spawn_id = /datum/gas/oxygen
/obj/machinery/atmospherics/miner/toxins
name = "\improper Plasma Gas Miner"
overlay_color = "#FF0000"
- spawn_id = "plasma"
+ spawn_id = /datum/gas/plasma
/obj/machinery/atmospherics/miner/carbon_dioxide
name = "\improper CO2 Gas Miner"
overlay_color = "#CDCDCD"
- spawn_id = "co2"
+ spawn_id = /datum/gas/carbon_dioxide
/obj/machinery/atmospherics/miner/bz
name = "\improper BZ Gas Miner"
overlay_color = "#FAFF00"
- spawn_id = "bz"
+ spawn_id = /datum/gas/bz
/obj/machinery/atmospherics/miner/freon
name = "\improper Freon Gas Miner"
overlay_color = "#00FFE5"
- spawn_id = "freon"
+ spawn_id = /datum/gas/freon
/obj/machinery/atmospherics/miner/volatile_fuel
name = "\improper Volatile Fuel Gas Miner"
overlay_color = "#564040"
- spawn_id = "v_fuel"
+ spawn_id = /datum/gas/volatile_fuel
/obj/machinery/atmospherics/miner/agent_b
name = "\improper Agent B Gas Miner"
overlay_color = "#E81E24"
- spawn_id = "agent_b"
+ spawn_id = /datum/gas/oxygen_agent_b
/obj/machinery/atmospherics/miner/water_vapor
name = "\improper Water Vapor Gas Miner"
overlay_color = "#99928E"
- spawn_id = "water_vapor"
+ spawn_id = /datum/gas/water_vapor
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index c08ef25b61..fa2a6fbcbf 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -12,7 +12,7 @@
volume = 1000
var/filled = 0.5
- var/gas_type = ""
+ var/gas_type
var/release_pressure = ONE_ATMOSPHERE
var/can_max_release_pressure = (ONE_ATMOSPHERE * 10)
var/can_min_release_pressure = (ONE_ATMOSPHERE / 10)
@@ -59,42 +59,42 @@
name = "n2 canister"
desc = "Nitrogen gas. Reportedly useful for something."
icon_state = "red"
- gas_type = "n2"
+ gas_type = /datum/gas/nitrogen
/obj/machinery/portable_atmospherics/canister/oxygen
name = "o2 canister"
desc = "Oxygen. Necessary for human life."
icon_state = "blue"
- gas_type = "o2"
+ gas_type = /datum/gas/oxygen
/obj/machinery/portable_atmospherics/canister/carbon_dioxide
name = "co2 canister"
desc = "Carbon dioxide. What the fuck is carbon dioxide?"
icon_state = "black"
- gas_type = "co2"
+ gas_type = /datum/gas/carbon_dioxide
/obj/machinery/portable_atmospherics/canister/toxins
name = "plasma canister"
desc = "Plasma gas. The reason YOU are here. Highly toxic."
icon_state = "orange"
- gas_type = "plasma"
+ gas_type = /datum/gas/plasma
/obj/machinery/portable_atmospherics/canister/agent_b
name = "agent b canister"
desc = "Oxygen Agent B. You're not quite sure what it does."
- gas_type = "agent_b"
+ gas_type = /datum/gas/oxygen_agent_b
/obj/machinery/portable_atmospherics/canister/bz
name = "BZ canister"
desc = "BZ, a powerful hallucinogenic nerve agent."
icon_state = "purple"
- gas_type = "bz"
+ gas_type = /datum/gas/bz
/obj/machinery/portable_atmospherics/canister/nitrous_oxide
name = "n2o canister"
desc = "Nitrous oxide gas. Known to cause drowsiness."
icon_state = "redws"
- gas_type = "n2o"
+ gas_type = /datum/gas/nitrous_oxide
/obj/machinery/portable_atmospherics/canister/air
name = "air canister"
@@ -105,14 +105,14 @@
name = "freon canister"
desc = "Freon. Great for the atmosphere!"
icon_state = "freon"
- gas_type = "freon"
+ gas_type = /datum/gas/freon
starter_temp = 120
/obj/machinery/portable_atmospherics/canister/water_vapor
name = "water vapor canister"
desc = "Water Vapor. We get it, you vape."
icon_state = "water_vapor"
- gas_type = "water_vapor"
+ gas_type = /datum/gas/water_vapor
filled = 1
/obj/machinery/portable_atmospherics/canister/proc/get_time_left()
@@ -148,7 +148,7 @@
name = "prototype canister"
desc = "A prototype canister for a prototype bike, what could go wrong?"
icon_state = "proto"
- gas_type = "o2"
+ gas_type = /datum/gas/oxygen
filled = 1
release_pressure = ONE_ATMOSPHERE*2
@@ -181,9 +181,9 @@
if(starter_temp)
air_contents.temperature = starter_temp
/obj/machinery/portable_atmospherics/canister/air/create_gas()
- air_contents.add_gases("o2","n2")
- air_contents.gases["o2"][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
- air_contents.gases["n2"][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
+ air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
+ air_contents.gases[/datum/gas/oxygen][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
+ air_contents.gases[/datum/gas/nitrogen][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
#define HOLDING 1
#define CONNECTED 2
diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm
index cca108757a..0cddd5cb4f 100644
--- a/code/modules/atmospherics/machinery/portable/pump.dm
+++ b/code/modules/atmospherics/machinery/portable/pump.dm
@@ -99,8 +99,8 @@
if("power")
on = !on
if(on && !holding)
- var/plasma = air_contents.gases["plasma"]
- var/n2o = air_contents.gases["n2o"]
+ var/plasma = air_contents.gases[/datum/gas/plasma]
+ var/n2o = air_contents.gases[/datum/gas/nitrous_oxide]
if(n2o || plasma)
var/area/A = get_area(src)
message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [A][ADMIN_JMP(src)]")
@@ -138,4 +138,4 @@
holding.loc = get_turf(src)
holding = null
. = TRUE
- update_icon()
\ No newline at end of file
+ update_icon()
diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm
index 7a76405a90..cd857d19a1 100644
--- a/code/modules/atmospherics/machinery/portable/scrubber.dm
+++ b/code/modules/atmospherics/machinery/portable/scrubber.dm
@@ -7,7 +7,7 @@
var/volume_rate = 1000
volume = 1000
- var/list/scrubbing = list("plasma", "co2", "n2o", "agent_b", "bz", "freon", "water_vapor")
+ var/list/scrubbing = list(/datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/oxygen_agent_b, /datum/gas/bz, /datum/gas/freon, /datum/gas/water_vapor)
/obj/machinery/portable_atmospherics/scrubber/Destroy()
var/turf/T = get_turf(src)
diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm
index 87583ebea1..d01a0757ba 100644
--- a/code/modules/awaymissions/mission_code/Academy.dm
+++ b/code/modules/awaymissions/mission_code/Academy.dm
@@ -108,27 +108,12 @@
/obj/structure/academy_wizard_spawner/proc/summon_wizard()
var/turf/T = src.loc
-
var/mob/living/carbon/human/wizbody = new(T)
- wizbody.equipOutfit(/datum/outfit/wizard/academy)
- var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(wizbody)
- Implant.implant(wizbody)
- wizbody.faction |= "wizard"
- wizbody.real_name = "Academy Teacher"
- wizbody.name = "Academy Teacher"
-
- var/datum/mind/wizmind = new /datum/mind()
- wizmind.name = "Wizard Defender"
+ wizbody.fully_replace_character_name("Academy Teacher")
+ wizbody.mind_initialize()
+ var/datum/mind/wizmind = wizbody.mind
wizmind.special_role = "Academy Defender"
- var/datum/objective/O = new("Protect Wizard Academy from the intruders")
- wizmind.objectives += O
- wizmind.transfer_to(wizbody)
- SSticker.mode.wizards |= wizmind
-
- wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt)
- wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile)
- wizmind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball)
-
+ wizmind.add_antag_datum(/datum/antagonist/wizard/academy)
current_wizard = wizbody
give_control()
diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm
index b021259d5c..0552c1b4b3 100644
--- a/code/modules/clothing/outfits/standard.dm
+++ b/code/modules/clothing/outfits/standard.dm
@@ -265,6 +265,20 @@
back = /obj/item/storage/backpack
backpack_contents = list(/obj/item/storage/box=1)
+/datum/outfit/wizard/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ if(visualsOnly)
+ return
+
+ var/obj/item/spellbook/S = locate() in H.held_items
+ if(S)
+ S.owner = H
+
+/datum/outfit/wizard/apprentice
+ name = "Wizard Apprentice"
+ r_hand = null
+ l_hand = null
+ r_pocket = /obj/item/teleportation_scroll/apprentice
+
/datum/outfit/wizard/red
name = "Red Wizard"
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index 287635742f..db7028411c 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -167,9 +167,9 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
- if(!GM.gases["o2"])
+ if(!GM.gases[/datum/gas/oxygen])
return
- GM.gases["o2"][MOLES] -= severity * holder.energy
+ GM.gases[/datum/gas/oxygen][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/nitro_eater
@@ -182,9 +182,9 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
- if(!GM.gases["n2"])
+ if(!GM.gases[/datum/gas/nitrogen])
return
- GM.gases["n2"][MOLES] -= severity * holder.energy
+ GM.gases[/datum/gas/nitrogen][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/carbondioxide_eater
@@ -197,9 +197,9 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
- if(!GM.gases["co2"])
+ if(!GM.gases[/datum/gas/carbon_dioxide])
return
- GM.gases["co2"][MOLES] -= severity * holder.energy
+ GM.gases[/datum/gas/carbon_dioxide][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/plasma_eater
@@ -212,9 +212,9 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
- if(!GM.gases["plasma"])
+ if(!GM.gases[/datum/gas/plasma])
return
- GM.gases["plasma"][MOLES] -= severity * holder.energy
+ GM.gases[/datum/gas/plasma][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/thorns
diff --git a/code/modules/events/wizard/curseditems.dm b/code/modules/events/wizard/curseditems.dm
index f5b6ae1cc1..30a4377839 100644
--- a/code/modules/events/wizard/curseditems.dm
+++ b/code/modules/events/wizard/curseditems.dm
@@ -40,7 +40,7 @@
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
if(ruins_spaceworthiness && !(H.z in GLOB.station_z_levels) || isspaceturf(H.loc) || isplasmaman(H))
continue //#savetheminers
- if(ruins_wizard_loadout && H.mind && ((H.mind in SSticker.mode.wizards) || (H.mind in SSticker.mode.apprentices)))
+ if(ruins_wizard_loadout && iswizard(H))
continue
if(item_set == "catgirls2015") //Wizard code means never having to say you're sorry
H.gender = FEMALE
diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm
index 1ba052c4c0..54d3d8ed41 100644
--- a/code/modules/events/wizard/imposter.dm
+++ b/code/modules/events/wizard/imposter.dm
@@ -24,35 +24,18 @@
I.name = I.dna.real_name
I.updateappearance(mutcolor_update=1)
I.domutcheck()
- if(W.ears)
- I.equip_to_slot_or_del(new W.ears.type, slot_ears)
- if(W.w_uniform)
- I.equip_to_slot_or_del(new W.w_uniform.type , slot_w_uniform)
- if(W.shoes)
- I.equip_to_slot_or_del(new W.shoes.type, slot_shoes)
- if(W.wear_suit)
- I.equip_to_slot_or_del(new W.wear_suit.type, slot_wear_suit)
- if(W.head)
- I.equip_to_slot_or_del(new W.head.type, slot_head)
- if(W.back)
- I.equip_to_slot_or_del(new W.back.type, slot_back)
I.key = C.key
-
- //Operation: Fuck off and scare people
- I.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
- I.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null))
- I.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
-
+ var/datum/antagonist/wizard/master = M.has_antag_datum(/datum/antagonist/wizard)
+ if(!master.wiz_team)
+ master.create_wiz_team()
+ var/datum/antagonist/wizard/apprentice/imposter = new(I.mind)
+ imposter.master = M
+ imposter.wiz_team = master.wiz_team
+ master.wiz_team += imposter
+ I.mind.add_antag_datum(imposter)
+ //Remove if possible
SSticker.mode.apprentices += I.mind
I.mind.special_role = "imposter"
-
- var/datum/objective/protect/protect_objective = new /datum/objective/protect
- protect_objective.owner = I.mind
- protect_objective.target = W.mind
- protect_objective.explanation_text = "Protect [W.real_name], the wizard."
- I.mind.objectives += protect_objective
- SSticker.mode.update_wiz_icons_added(I.mind)
-
- I.log_message("Is an imposter!", INDIVIDUAL_ATTACK_LOG)
- to_chat(I, "You are an imposter! Trick and confuse the crew to misdirect malice from your handsome original!")
+ //
+ I.log_message("Is an imposter!", INDIVIDUAL_ATTACK_LOG) //?
SEND_SOUND(I, sound('sound/effects/magic.ogg'))
diff --git a/code/modules/events/wizard/shuffle.dm b/code/modules/events/wizard/shuffle.dm
index 568a8fbc72..2f525d2098 100644
--- a/code/modules/events/wizard/shuffle.dm
+++ b/code/modules/events/wizard/shuffle.dm
@@ -82,7 +82,7 @@
var/list/mobs = list()
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- if(H.stat || !H.mind || (H.mind in SSticker.mode.wizards) || (H.mind in SSticker.mode.apprentices))
+ if(H.stat || !H.mind || iswizard(H))
continue //the wizard(s) are spared on this one
mobs += H
diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm
index 7183cac451..a78416b6cc 100644
--- a/code/modules/hydroponics/grown/banana.dm
+++ b/code/modules/hydroponics/grown/banana.dm
@@ -38,10 +38,13 @@
user.visible_message("[user] laughs so hard they begin to suffocate!")
return (OXYLOSS)
+//Banana Peel
/obj/item/grown/bananapeel
seed = /obj/item/seeds/banana
name = "banana peel"
desc = "A peel from a banana."
+ lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
icon_state = "banana_peel"
item_state = "banana_peel"
w_class = WEIGHT_CLASS_TINY
@@ -81,6 +84,7 @@
name = "mimana peel"
desc = "A mimana peel."
icon_state = "mimana_peel"
+ item_state = "mimana_peel"
// Bluespace Banana
/obj/item/seeds/banana/bluespace
@@ -100,6 +104,7 @@
seed = /obj/item/seeds/banana/bluespace
name = "bluespace banana"
icon_state = "banana_blue"
+ item_state = "bluespace_peel"
trash = /obj/item/grown/bananapeel/bluespace
filling_color = "#0000FF"
origin_tech = "biotech=3;bluespace=5"
diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm
index 3a9e75fdaa..f11d6e0772 100644
--- a/code/modules/hydroponics/grown/towercap.dm
+++ b/code/modules/hydroponics/grown/towercap.dm
@@ -181,8 +181,8 @@
if(isopenturf(loc))
var/turf/open/O = loc
if(O.air)
- var/G = O.air.gases
- if(G["o2"][MOLES] > 13)
+ var/loc_gases = O.air.gases
+ if(loc_gases[/datum/gas/oxygen][MOLES] > 13)
return 1
return 0
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index b692ab2d32..1eb4ced083 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -375,7 +375,7 @@
if(GLOB.highlander)
to_chat(humanc, "THERE CAN BE ONLY ONE!!!")
humanc.make_scottish()
- if(prob(2) && !issilicon(humanc) && !jobban_isbanned(humanc.mind, "Syndicate") && GLOB.miscreants_allowed && ROLE_MISCREANT in humanc.client.prefs.be_special)
+ if(prob(5) && !issilicon(humanc) && !jobban_isbanned(humanc.mind, "Syndicate") && GLOB.miscreants_allowed && ROLE_MISCREANT in humanc.client.prefs.be_special)
SSticker.generate_miscreant_objectives(humanc.mind)
else
if(CONFIG_GET(flag/allow_crew_objectives))
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 1022719805..4c6628a53b 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -597,14 +597,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
target.faction = list("neutral")
return 1
-/proc/show_server_hop_transfer_screen(expected_key)
- //only show it to incoming ghosts
- for(var/mob/dead/observer/O in GLOB.player_list)
- if(O.key == expected_key)
- if(O.client)
- new /obj/screen/splash(O.client, TRUE)
- break
-
//this is a mob verb instead of atom for performance reasons
//see /mob/verb/examinate() in mob.dm for more info
//overriden here and in /mob/living for different point span classes and sanity checks
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index 0bfd788846..1543d6b716 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -1,54 +1,54 @@
-/mob/living/carbon/alien/Life()
- findQueen()
- return..()
-
-/mob/living/carbon/alien/check_breath(datum/gas_mixture/breath)
- if(status_flags & GODMODE)
- return
-
- if(!breath || (breath.total_moles() == 0))
- //Aliens breathe in vaccuum
- return 0
-
- var/toxins_used = 0
- var/tox_detect_threshold = 0.02
- var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
- var/list/breath_gases = breath.gases
-
- breath.assert_gases("plasma", "o2")
-
- //Partial pressure of the toxins in our breath
- var/Toxins_pp = (breath_gases["plasma"][MOLES]/breath.total_moles())*breath_pressure
-
- if(Toxins_pp > tox_detect_threshold) // Detect toxins in air
- adjustPlasma(breath_gases["plasma"][MOLES]*250)
- throw_alert("alien_tox", /obj/screen/alert/alien_tox)
-
- toxins_used = breath_gases["plasma"][MOLES]
-
- else
- clear_alert("alien_tox")
-
- //Breathe in toxins and out oxygen
- breath_gases["plasma"][MOLES] -= toxins_used
- breath_gases["o2"][MOLES] += toxins_used
-
- breath.garbage_collect()
-
- //BREATH TEMPERATURE
- handle_breath_temperature(breath)
-
-/mob/living/carbon/alien/handle_status_effects()
- ..()
- //natural reduction of movement delay due to stun.
- if(move_delay_add > 0)
- move_delay_add = max(0, move_delay_add - rand(1, 2))
-
-/mob/living/carbon/alien/handle_changeling()
- return
-
-/mob/living/carbon/alien/handle_fire()//Aliens on fire code
- if(..())
- return
- bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up!
- return
\ No newline at end of file
+/mob/living/carbon/alien/Life()
+ findQueen()
+ return..()
+
+/mob/living/carbon/alien/check_breath(datum/gas_mixture/breath)
+ if(status_flags & GODMODE)
+ return
+
+ if(!breath || (breath.total_moles() == 0))
+ //Aliens breathe in vaccuum
+ return 0
+
+ var/toxins_used = 0
+ var/tox_detect_threshold = 0.02
+ var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
+ var/list/breath_gases = breath.gases
+
+ breath.assert_gases(/datum/gas/plasma, /datum/gas/oxygen)
+
+ //Partial pressure of the toxins in our breath
+ var/Toxins_pp = (breath_gases[/datum/gas/plasma][MOLES]/breath.total_moles())*breath_pressure
+
+ if(Toxins_pp > tox_detect_threshold) // Detect toxins in air
+ adjustPlasma(breath_gases[/datum/gas/plasma][MOLES]*250)
+ throw_alert("alien_tox", /obj/screen/alert/alien_tox)
+
+ toxins_used = breath_gases[/datum/gas/plasma][MOLES]
+
+ else
+ clear_alert("alien_tox")
+
+ //Breathe in toxins and out oxygen
+ breath_gases[/datum/gas/plasma][MOLES] -= toxins_used
+ breath_gases[/datum/gas/oxygen][MOLES] += toxins_used
+
+ breath.garbage_collect()
+
+ //BREATH TEMPERATURE
+ handle_breath_temperature(breath)
+
+/mob/living/carbon/alien/handle_status_effects()
+ ..()
+ //natural reduction of movement delay due to stun.
+ if(move_delay_add > 0)
+ move_delay_add = max(0, move_delay_add - rand(1, 2))
+
+/mob/living/carbon/alien/handle_changeling()
+ return
+
+/mob/living/carbon/alien/handle_fire()//Aliens on fire code
+ if(..())
+ return
+ bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up!
+ return
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index c216052cea..817e22163a 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -26,7 +26,7 @@
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
if(environment)
if(environment.total_moles())
- if(environment.gases["o2"] && (environment.gases["o2"][MOLES]) >= 1) //Same threshhold that extinguishes fire
+ if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen][MOLES]) >= 1) //Same threshhold that extinguishes fire
H.adjust_fire_stacks(0.5)
if(!H.on_fire && H.fire_stacks > 0)
H.visible_message("[H]'s body reacts with the atmosphere and bursts into flames!","Your body reacts with the atmosphere and bursts into flame!")
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 2bf605de9c..979bc2d89c 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -132,11 +132,10 @@
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/list/breath_gases = breath.gases
- breath.assert_gases("o2","plasma","co2","n2o", "bz")
-
- var/O2_partialpressure = (breath_gases["o2"][MOLES]/breath.total_moles())*breath_pressure
- var/Toxins_partialpressure = (breath_gases["plasma"][MOLES]/breath.total_moles())*breath_pressure
- var/CO2_partialpressure = (breath_gases["co2"][MOLES]/breath.total_moles())*breath_pressure
+ breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz)
+ var/O2_partialpressure = (breath_gases[/datum/gas/oxygen][MOLES]/breath.total_moles())*breath_pressure
+ var/Toxins_partialpressure = (breath_gases[/datum/gas/plasma][MOLES]/breath.total_moles())*breath_pressure
+ var/CO2_partialpressure = (breath_gases[/datum/gas/carbon_dioxide][MOLES]/breath.total_moles())*breath_pressure
//OXYGEN
@@ -147,7 +146,7 @@
var/ratio = 1 - O2_partialpressure/safe_oxy_min
adjustOxyLoss(min(5*ratio, 3))
failed_last_breath = 1
- oxygen_used = breath_gases["o2"][MOLES]*ratio
+ oxygen_used = breath_gases[/datum/gas/oxygen][MOLES]*ratio
else
adjustOxyLoss(3)
failed_last_breath = 1
@@ -157,11 +156,11 @@
failed_last_breath = 0
if(health >= HEALTH_THRESHOLD_CRIT)
adjustOxyLoss(-5)
- oxygen_used = breath_gases["o2"][MOLES]
+ oxygen_used = breath_gases[/datum/gas/oxygen][MOLES]
clear_alert("not_enough_oxy")
- breath_gases["o2"][MOLES] -= oxygen_used
- breath_gases["co2"][MOLES] += oxygen_used
+ breath_gases[/datum/gas/oxygen][MOLES] -= oxygen_used
+ breath_gases[/datum/gas/carbon_dioxide][MOLES] += oxygen_used
//CARBON DIOXIDE
if(CO2_partialpressure > safe_co2_max)
@@ -180,15 +179,15 @@
//TOXINS/PLASMA
if(Toxins_partialpressure > safe_tox_max)
- var/ratio = (breath_gases["plasma"][MOLES]/safe_tox_max) * 10
+ var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_tox_max) * 10
adjustToxLoss(Clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
clear_alert("too_much_tox")
//NITROUS OXIDE
- if(breath_gases["n2o"])
- var/SA_partialpressure = (breath_gases["n2o"][MOLES]/breath.total_moles())*breath_pressure
+ if(breath_gases[/datum/gas/nitrous_oxide])
+ var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide][MOLES]/breath.total_moles())*breath_pressure
if(SA_partialpressure > SA_para_min)
Unconscious(60)
if(SA_partialpressure > SA_sleep_min)
@@ -198,8 +197,8 @@
emote(pick("giggle","laugh"))
//BZ (Facepunch port of their Agent B)
- if(breath_gases["bz"])
- var/bz_partialpressure = (breath_gases["bz"][MOLES]/breath.total_moles())*breath_pressure
+ if(breath_gases[/datum/gas/bz])
+ var/bz_partialpressure = (breath_gases[/datum/gas/bz][MOLES]/breath.total_moles())*breath_pressure
if(bz_partialpressure > 1)
hallucination += 20
else if(bz_partialpressure > 0.01)
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 66ca8bf8e2..acbdea29c1 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -92,7 +92,7 @@
ExtinguishMob()
return
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
- if(!G.gases["o2"] || G.gases["o2"][MOLES] < 1)
+ if(!G.gases[/datum/gas/oxygen] || G.gases[/datum/gas/oxygen][MOLES] < 1)
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return
var/turf/location = get_turf(src)
@@ -123,5 +123,3 @@
/mob/living/proc/update_damage_hud()
return
-
-
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index 28de1f16e8..af4d8736b6 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -206,7 +206,8 @@
if(A && isturf(A.loc))
var/atom/movable/AM = A
if(istype(AM, /obj/effect/decal/cleanable))
- qdel(AM)
+ for(var/obj/effect/decal/cleanable/C in A.loc)
+ qdel(C)
anchored = FALSE
target = null
diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm
index fde10031d1..806a916421 100644
--- a/code/modules/mob/living/simple_animal/hostile/carp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/carp.dm
@@ -1,81 +1,101 @@
-/mob/living/simple_animal/hostile/carp
- name = "space carp"
- desc = "A ferocious, fang-bearing creature that resembles a fish."
- icon_state = "carp"
- icon_living = "carp"
- icon_dead = "carp_dead"
- icon_gib = "carp_gib"
- speak_chance = 0
- turns_per_move = 5
- butcher_results = list(/obj/item/reagent_containers/food/snacks/carpmeat = 2)
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "hits"
- emote_taunt = list("gnashes")
- taunt_chance = 30
- speed = 0
- maxHealth = 25
- health = 25
- devourable = TRUE
- no_vore = FALSE
-
- harm_intent_damage = 8
- obj_damage = 50
- melee_damage_lower = 15
- melee_damage_upper = 15
- attacktext = "bites"
- attack_sound = 'sound/weapons/bite.ogg'
- speak_emote = list("gnashes")
-
- //Space carp aren't affected by cold.
- atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- minbodytemp = 0
- maxbodytemp = 1500
-
- faction = list("carp")
- movement_type = FLYING
- pressure_resistance = 200
- gold_core_spawnable = 1
-
-/mob/living/simple_animal/hostile/carp/Process_Spacemove(movement_dir = 0)
- return 1 //No drifting in space for space carp! //original comments do not steal
-
-/mob/living/simple_animal/hostile/carp/AttackingTarget()
- . = ..()
- if(. && ishuman(target))
- var/mob/living/carbon/human/H = target
- H.adjustStaminaLoss(8)
-
-/mob/living/simple_animal/hostile/carp/holocarp
- icon_state = "holocarp"
- icon_living = "holocarp"
- maxbodytemp = INFINITY
- gold_core_spawnable = 0
- del_on_death = 1
-
-/mob/living/simple_animal/hostile/carp/megacarp
- icon = 'icons/mob/broadMobs.dmi'
- name = "Mega Space Carp"
- desc = "A ferocious, fang bearing creature that resembles a shark. This one seems especially ticked off."
- icon_state = "megacarp"
- icon_living = "megacarp"
- icon_dead = "megacarp_dead"
- icon_gib = "megacarp_gib"
- maxHealth = 65
- health = 65
- pixel_x = -16
- mob_size = MOB_SIZE_LARGE
-
- obj_damage = 80
- melee_damage_lower = 20
- melee_damage_upper = 20
-
-
-/mob/living/simple_animal/hostile/carp/cayenne
- name = "Cayenne"
- desc = "A failed Syndicate experiment in weaponized space carp technology, it now serves as a lovable mascot."
- gender = FEMALE
- speak_emote = list("squeaks")
- gold_core_spawnable = 0
- faction = list("syndicate")
- AIStatus = AI_OFF
\ No newline at end of file
+#define REGENERATION_DELAY 60 // After taking damage, how long it takes for automatic regeneration to begin for megacarps (ty robustin!)
+
+/mob/living/simple_animal/hostile/carp
+ name = "space carp"
+ desc = "A ferocious, fang-bearing creature that resembles a fish."
+ icon_state = "carp"
+ icon_living = "carp"
+ icon_dead = "carp_dead"
+ icon_gib = "carp_gib"
+ speak_chance = 0
+ turns_per_move = 5
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/carpmeat = 2)
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "hits"
+ emote_taunt = list("gnashes")
+ taunt_chance = 30
+ speed = 0
+ maxHealth = 25
+ health = 25
+
+ harm_intent_damage = 8
+ obj_damage = 50
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ attacktext = "bites"
+ attack_sound = 'sound/weapons/bite.ogg'
+ speak_emote = list("gnashes")
+
+ //Space carp aren't affected by cold.
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 0
+ maxbodytemp = 1500
+ faction = list("carp")
+ movement_type = FLYING
+ pressure_resistance = 200
+ gold_core_spawnable = 1
+
+/mob/living/simple_animal/hostile/carp/Process_Spacemove(movement_dir = 0)
+ return 1 //No drifting in space for space carp! //original comments do not steal
+
+/mob/living/simple_animal/hostile/carp/AttackingTarget()
+ . = ..()
+ if(. && ishuman(target))
+ var/mob/living/carbon/human/H = target
+ H.adjustStaminaLoss(8)
+
+/mob/living/simple_animal/hostile/carp/holocarp
+ icon_state = "holocarp"
+ icon_living = "holocarp"
+ maxbodytemp = INFINITY
+ gold_core_spawnable = 0
+ del_on_death = 1
+
+/mob/living/simple_animal/hostile/carp/megacarp
+ icon = 'icons/mob/broadMobs.dmi'
+ name = "Mega Space Carp"
+ desc = "A ferocious, fang bearing creature that resembles a shark. This one seems especially ticked off."
+ icon_state = "megacarp"
+ icon_living = "megacarp"
+ icon_dead = "megacarp_dead"
+ icon_gib = "megacarp_gib"
+ maxHealth = 20
+ health = 20
+ pixel_x = -16
+ mob_size = MOB_SIZE_LARGE
+
+ obj_damage = 80
+ melee_damage_lower = 20
+ melee_damage_upper = 20
+
+ var/regen_cooldown = 0
+
+/mob/living/simple_animal/hostile/carp/megacarp/Initialize()
+ . = ..()
+ name = "[pick(GLOB.megacarp_first_names)] [pick(GLOB.megacarp_last_names)]"
+ melee_damage_lower += rand(2, 10)
+ melee_damage_upper += rand(10,20)
+ maxHealth += rand(30,60)
+ move_to_delay = rand(3,7)
+
+/mob/living/simple_animal/hostile/carp/megacarp/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
+ . = ..()
+ if(.)
+ regen_cooldown = world.time + REGENERATION_DELAY
+
+/mob/living/simple_animal/hostile/carp/megacarp/Life()
+ . = ..()
+ if(regen_cooldown < world.time)
+ heal_overall_damage(4)
+
+/mob/living/simple_animal/hostile/carp/cayenne
+ name = "Cayenne"
+ desc = "A failed Syndicate experiment in weaponized space carp technology, it now serves as a lovable mascot."
+ gender = FEMALE
+ speak_emote = list("squeaks")
+ gold_core_spawnable = 0
+ faction = list("syndicate")
+ AIStatus = AI_OFF
+
+#undef REGENERATION_DELAY
diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm
index 47fa2a8010..aa51fb4e17 100644
--- a/code/modules/mob/living/simple_animal/hostile/tree.dm
+++ b/code/modules/mob/living/simple_animal/hostile/tree.dm
@@ -43,12 +43,12 @@
..()
if(isopenturf(loc))
var/turf/open/T = src.loc
- if(T.air && T.air.gases["co2"])
- var/co2 = T.air.gases["co2"][MOLES]
+ if(T.air && T.air.gases[/datum/gas/carbon_dioxide])
+ var/co2 = T.air.gases[/datum/gas/carbon_dioxide][MOLES]
if(co2 > 0)
if(prob(25))
var/amt = min(co2, 9)
- T.air.gases["co2"][MOLES] -= amt
+ T.air.gases[/datum/gas/carbon_dioxide][MOLES] -= amt
T.atmos_spawn_air("o2=[amt]")
/mob/living/simple_animal/hostile/tree/AttackingTarget()
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index d4b2c8f7c6..56ba972d6b 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -186,10 +186,10 @@
var/ST_gases = ST.air.gases
ST.air.assert_gases(arglist(GLOB.hardcoded_gases))
- var/tox = ST_gases["plasma"][MOLES]
- var/oxy = ST_gases["o2"][MOLES]
- var/n2 = ST_gases["n2"][MOLES]
- var/co2 = ST_gases["co2"][MOLES]
+ var/tox = ST_gases[/datum/gas/plasma][MOLES]
+ var/oxy = ST_gases[/datum/gas/oxygen][MOLES]
+ var/n2 = ST_gases[/datum/gas/nitrogen][MOLES]
+ var/co2 = ST_gases[/datum/gas/carbon_dioxide][MOLES]
ST.air.garbage_collect()
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
index a3c37e9889..0ec41119dc 100644
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -134,8 +134,8 @@
if(stat != DEAD)
var/bz_percentage =0
- if("bz" in environment.gases)
- bz_percentage = environment.gases["bz"][MOLES] / environment.total_moles()
+ if(environment.gases[/datum/gas/bz])
+ bz_percentage = environment.gases[/datum/gas/bz][MOLES] / environment.total_moles()
var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis
if(stat == CONSCIOUS && stasis)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 457376990e..cb086b7115 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -363,7 +363,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
if(M.mind in SSticker.mode.changelings)
return 2
if("wizard")
- if(M.mind in SSticker.mode.wizards)
+ if(iswizard(M))
return 2
if("apprentice")
if(M.mind in SSticker.mode.apprentices)
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index 9b5592af3b..b73285570a 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -31,11 +31,11 @@ GLOBAL_LIST_EMPTY(rad_collectors)
/obj/machinery/power/rad_collector/process()
if(loaded_tank)
- if(!loaded_tank.air_contents.gases["plasma"])
+ if(!loaded_tank.air_contents.gases[/datum/gas/plasma])
investigate_log("out of fuel.", INVESTIGATE_SINGULO)
eject()
else
- loaded_tank.air_contents.gases["plasma"][MOLES] -= 0.001*drainratio
+ loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] -= 0.001*drainratio
loaded_tank.air_contents.garbage_collect()
return
@@ -50,7 +50,7 @@ GLOBAL_LIST_EMPTY(rad_collectors)
"You turn the [src.name] [active? "on":"off"].")
var/fuel
if(loaded_tank)
- fuel = loaded_tank.air_contents.gases["plasma"]
+ fuel = loaded_tank.air_contents.gases[/datum/gas/plasma]
fuel = fuel ? fuel[MOLES] : 0
investigate_log("turned [active?"on":"off"] by [user.key]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"It is empty"].", INVESTIGATE_SINGULO)
return
@@ -139,7 +139,7 @@ GLOBAL_LIST_EMPTY(rad_collectors)
/obj/machinery/power/rad_collector/proc/receive_pulse(pulse_strength)
if(loaded_tank && active)
- var/power_produced = loaded_tank.air_contents.gases["plasma"] ? loaded_tank.air_contents.gases["plasma"][MOLES] : 0
+ var/power_produced = loaded_tank.air_contents.gases[/datum/gas/plasma] ? loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] : 0
power_produced *= pulse_strength*10
add_avail(power_produced)
last_power = power_produced
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index b6f7d20fbc..1dc36f9097 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -284,17 +284,17 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
if(damage > damage_archived && prob(10))
playsound(get_turf(src), 'sound/effects/empulse.ogg', 50, 1)
- removed.assert_gases("o2", "plasma", "co2", "n2o", "n2", "freon")
+ removed.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/nitrogen, /datum/gas/freon)
//calculating gas related values
combined_gas = max(removed.total_moles(), 0)
- plasmacomp = max(removed.gases["plasma"][MOLES]/combined_gas, 0)
- o2comp = max(removed.gases["o2"][MOLES]/combined_gas, 0)
- co2comp = max(removed.gases["co2"][MOLES]/combined_gas, 0)
+ plasmacomp = max(removed.gases[/datum/gas/plasma][MOLES]/combined_gas, 0)
+ o2comp = max(removed.gases[/datum/gas/oxygen][MOLES]/combined_gas, 0)
+ co2comp = max(removed.gases[/datum/gas/carbon_dioxide][MOLES]/combined_gas, 0)
- n2ocomp = max(removed.gases["n2o"][MOLES]/combined_gas, 0)
- n2comp = max(removed.gases["n2"][MOLES]/combined_gas, 0)
- freoncomp = max(removed.gases["freon"][MOLES]/combined_gas, 0)
+ n2ocomp = max(removed.gases[/datum/gas/nitrous_oxide][MOLES]/combined_gas, 0)
+ n2comp = max(removed.gases[/datum/gas/nitrogen][MOLES]/combined_gas, 0)
+ freoncomp = max(removed.gases[/datum/gas/freon][MOLES]/combined_gas, 0)
gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp - n2comp - freoncomp, 0), 1)
@@ -348,12 +348,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
removed.temperature = max(0, min(removed.temperature, 2500 * dynamic_heat_modifier))
//Calculate how much gas to release
- removed.gases["plasma"][MOLES] += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0)
+ removed.gases[/datum/gas/plasma][MOLES] += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0)
- removed.gases["o2"][MOLES] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)
+ removed.gases[/datum/gas/oxygen][MOLES] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)
if(combined_gas < 50)
- removed.gases["freon"][MOLES] = max((removed.gases["freon"][MOLES] + device_energy) * freoncomp / FREON_BREEDING_MODIFIER, 0)
+ removed.gases[/datum/gas/freon][MOLES] = max((removed.gases[/datum/gas/freon][MOLES] + device_energy) * freoncomp / FREON_BREEDING_MODIFIER, 0)
if(produces_gas)
env.merge(removed)
diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm
index 1d657117c3..0cb7e6c47d 100644
--- a/code/modules/spells/spell_types/rightandwrong.dm
+++ b/code/modules/spells/spell_types/rightandwrong.dm
@@ -1,219 +1,221 @@
-//In this file: Summon Magic/Summon Guns/Summon Events
-
-/proc/rightandwrong(summon_type, mob/user, survivor_probability) //0 = Summon Guns, 1 = Summon Magic
- var/list/gunslist = list("taser","gravgun","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","speargun","arg","uzi","alienpistol","dragnet","turret","pulsecarbine","decloner","mindflayer","hyperkinetic","advplasmacutter","wormhole","wt550","bulldog","grenadelauncher","goldenrevolver","sniper","medibeam","scatterbeam")
- var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffchange", "staffhealing", "armor", "scrying","staffdoor","voodoo", "whistle", "battlemage", "immortality", "ghostsword", "special")
- var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos", "necromantic", "bloodcontract")
-
- if(user) //in this case either someone holding a spellbook or a badmin
- to_chat(user, "You summoned [summon_type ? "magic" : "guns"]!")
- message_admins("[key_name_admin(user, 1)] summoned [summon_type ? "magic" : "guns"]!")
- log_game("[key_name(user)] summoned [summon_type ? "magic" : "guns"]!")
- for(var/mob/living/carbon/human/H in GLOB.player_list)
- if(H.stat == DEAD || !(H.client)) continue
- if(H.mind)
- if(H.mind.special_role == "Wizard" || H.mind.special_role == "apprentice" || H.mind.special_role == "survivalist") continue
- if(prob(survivor_probability) && !(H.mind in SSticker.mode.traitors))
- SSticker.mode.traitors += H.mind
- if(!summon_type)
- var/datum/objective/steal_five_of_type/summon_guns/guns = new
- guns.owner = H.mind
- H.mind.objectives += guns
- H.mind.special_role = "survivalist"
- to_chat(H, "You are the survivalist! Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, by any means necessary. Kill anyone who gets in your way.")
- else
- var/datum/objective/steal_five_of_type/summon_magic/magic = new
- magic.owner = H.mind
- H.mind.objectives += magic
- H.mind.special_role = "amateur magician"
- to_chat(H, "You are the amateur magician! Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way.")
- var/datum/objective/survive/survive = new
- survive.owner = H.mind
- H.mind.objectives += survive
- H.log_message("Was made into a survivalist, and trusts no one!", INDIVIDUAL_ATTACK_LOG)
- H.mind.announce_objectives()
- var/randomizeguns = pick(gunslist)
- var/randomizemagic = pick(magiclist)
- var/randomizemagicspecial = pick(magicspeciallist)
- if(!summon_type)
- var/obj/item/gun/G
- switch (randomizeguns)
- if("taser")
- G = new /obj/item/gun/energy/e_gun/advtaser(get_turf(H))
- if("egun")
- G = new /obj/item/gun/energy/e_gun(get_turf(H))
- if("laser")
- G = new /obj/item/gun/energy/laser(get_turf(H))
- if("revolver")
- G = new /obj/item/gun/ballistic/revolver(get_turf(H))
- if("detective")
- G = new /obj/item/gun/ballistic/revolver/detective(get_turf(H))
- if("deagle")
- G = new /obj/item/gun/ballistic/automatic/pistol/deagle/camo(get_turf(H))
- if("gyrojet")
- G = new /obj/item/gun/ballistic/automatic/gyropistol(get_turf(H))
- if("pulse")
- G = new /obj/item/gun/energy/pulse(get_turf(H))
- if("suppressed")
- G = new /obj/item/gun/ballistic/automatic/pistol(get_turf(H))
- new /obj/item/suppressor(get_turf(H))
- if("doublebarrel")
- G = new /obj/item/gun/ballistic/revolver/doublebarrel(get_turf(H))
- if("shotgun")
- G = new /obj/item/gun/ballistic/shotgun(get_turf(H))
- if("combatshotgun")
- G = new /obj/item/gun/ballistic/shotgun/automatic/combat(get_turf(H))
- if("arg")
- G = new /obj/item/gun/ballistic/automatic/ar(get_turf(H))
- if("mateba")
- G = new /obj/item/gun/ballistic/revolver/mateba(get_turf(H))
- if("boltaction")
- G = new /obj/item/gun/ballistic/shotgun/boltaction(get_turf(H))
- if("speargun")
- G = new /obj/item/gun/ballistic/automatic/speargun(get_turf(H))
- if("uzi")
- G = new /obj/item/gun/ballistic/automatic/mini_uzi(get_turf(H))
- if("cannon")
- G = new /obj/item/gun/energy/lasercannon(get_turf(H))
- if("crossbow")
- G = new /obj/item/gun/energy/kinetic_accelerator/crossbow/large(get_turf(H))
- if("nuclear")
- G = new /obj/item/gun/energy/e_gun/nuclear(get_turf(H))
- if("sabr")
- G = new /obj/item/gun/ballistic/automatic/proto(get_turf(H))
- if("bulldog")
- G = new /obj/item/gun/ballistic/automatic/shotgun/bulldog(get_turf(H))
- if("c20r")
- G = new /obj/item/gun/ballistic/automatic/c20r(get_turf(H))
- if("saw")
- G = new /obj/item/gun/ballistic/automatic/l6_saw(get_turf(H))
- if("car")
- G = new /obj/item/gun/ballistic/automatic/m90(get_turf(H))
- if("alienpistol")
- G = new /obj/item/gun/energy/alien(get_turf(H))
- if("dragnet")
- G = new /obj/item/gun/energy/e_gun/dragnet(get_turf(H))
- if("turret")
- G = new /obj/item/gun/energy/e_gun/turret(get_turf(H))
- if("pulsecarbine")
- G = new /obj/item/gun/energy/pulse/carbine(get_turf(H))
- if("decloner")
- G = new /obj/item/gun/energy/decloner(get_turf(H))
- if("mindflayer")
- G = new /obj/item/gun/energy/mindflayer(get_turf(H))
- if("hyperkinetic")
- G = new /obj/item/gun/energy/kinetic_accelerator(get_turf(H))
- if("advplasmacutter")
- G = new /obj/item/gun/energy/plasmacutter/adv(get_turf(H))
- if("wormhole")
- G = new /obj/item/gun/energy/wormhole_projector(get_turf(H))
- if("wt550")
- G = new /obj/item/gun/ballistic/automatic/wt550(get_turf(H))
- if("bulldog")
- G = new /obj/item/gun/ballistic/automatic/shotgun(get_turf(H))
- if("grenadelauncher")
- G = new /obj/item/gun/ballistic/revolver/grenadelauncher(get_turf(H))
- if("goldenrevolver")
- G = new /obj/item/gun/ballistic/revolver/golden(get_turf(H))
- if("sniper")
- G = new /obj/item/gun/ballistic/automatic/sniper_rifle(get_turf(H))
- if("medibeam")
- G = new /obj/item/gun/medbeam(get_turf(H))
- if("scatterbeam")
- G = new /obj/item/gun/energy/laser/scatter(get_turf(H))
- if("gravgun")
- G = new /obj/item/gun/energy/gravity_gun(get_turf(H))
- G.unlock()
- playsound(get_turf(H),'sound/magic/summon_guns.ogg', 50, 1)
-
- else
- switch (randomizemagic)
- if("fireball")
- new /obj/item/spellbook/oneuse/fireball(get_turf(H))
- if("smoke")
- new /obj/item/spellbook/oneuse/smoke(get_turf(H))
- if("blind")
- new /obj/item/spellbook/oneuse/blind(get_turf(H))
- if("mindswap")
- new /obj/item/spellbook/oneuse/mindswap(get_turf(H))
- if("forcewall")
- new /obj/item/spellbook/oneuse/forcewall(get_turf(H))
- if("knock")
- new /obj/item/spellbook/oneuse/knock(get_turf(H))
- if("horsemask")
- new /obj/item/spellbook/oneuse/barnyard(get_turf(H))
- if("charge")
- new /obj/item/spellbook/oneuse/charge(get_turf(H))
- if("summonitem")
- new /obj/item/spellbook/oneuse/summonitem(get_turf(H))
- if("wandnothing")
- new /obj/item/gun/magic/wand(get_turf(H))
- if("wanddeath")
- new /obj/item/gun/magic/wand/death(get_turf(H))
- if("wandresurrection")
- new /obj/item/gun/magic/wand/resurrection(get_turf(H))
- if("wandpolymorph")
- new /obj/item/gun/magic/wand/polymorph(get_turf(H))
- if("wandteleport")
- new /obj/item/gun/magic/wand/teleport(get_turf(H))
- if("wanddoor")
- new /obj/item/gun/magic/wand/door(get_turf(H))
- if("wandfireball")
- new /obj/item/gun/magic/wand/fireball(get_turf(H))
- if("staffhealing")
- new /obj/item/gun/magic/staff/healing(get_turf(H))
- if("staffdoor")
- new /obj/item/gun/magic/staff/door(get_turf(H))
- if("armor")
- new /obj/item/clothing/suit/space/hardsuit/wizard(get_turf(H))
- if("scrying")
- new /obj/item/scrying(get_turf(H))
- if (!(H.dna.check_mutation(XRAY)))
- H.dna.add_mutation(XRAY)
- to_chat(H, "The walls suddenly disappear.")
- if("voodoo")
- new /obj/item/voodoo(get_turf(H))
- if("whistle")
- new /obj/item/warpwhistle(get_turf(H))
- if("battlemage")
- new /obj/item/clothing/suit/space/hardsuit/shielded/wizard(get_turf(H))
- if("immortality")
- new /obj/item/device/immortality_talisman(get_turf(H))
- if("ghostsword")
- new /obj/item/melee/ghost_sword(get_turf(H))
- if("special")
- magiclist -= "special" //only one super OP item per summoning max
- switch (randomizemagicspecial)
- if("staffchange")
- new /obj/item/gun/magic/staff/change(get_turf(H))
- if("staffanimation")
- new /obj/item/gun/magic/staff/animate(get_turf(H))
- if("wandbelt")
- new /obj/item/storage/belt/wands/full(get_turf(H))
- if("contract")
- new /obj/item/antag_spawner/contract(get_turf(H))
- if("staffchaos")
- new /obj/item/gun/magic/staff/chaos(get_turf(H))
- if("necromantic")
- new /obj/item/device/necromantic_stone(get_turf(H))
- if("bloodcontract")
- new /obj/item/blood_contract(get_turf(H))
- to_chat(H, "You suddenly feel lucky.")
- playsound(get_turf(H),'sound/magic/summon_magic.ogg', 50, 1)
-
-
-/proc/summonevents()
- if(!SSevents.wizardmode)
- SSevents.frequency_lower = 600 //1 minute lower bound
- SSevents.frequency_upper = 3000 //5 minutes upper bound
- SSevents.toggleWizardmode()
- SSevents.reschedule()
-
- else //Speed it up
- SSevents.frequency_upper -= 600 //The upper bound falls a minute each time, making the AVERAGE time between events lessen
- if(SSevents.frequency_upper < SSevents.frequency_lower) //Sanity
- SSevents.frequency_upper = SSevents.frequency_lower
-
- SSevents.reschedule()
- message_admins("Summon Events intensifies, events will now occur every [SSevents.frequency_lower / 600] to [SSevents.frequency_upper / 600] minutes.")
- log_game("Summon Events was increased!")
+//In this file: Summon Magic/Summon Guns/Summon Events
+
+/proc/rightandwrong(summon_type, mob/user, survivor_probability) //0 = Summon Guns, 1 = Summon Magic
+ var/list/gunslist = list("taser","gravgun","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","speargun","arg","uzi","alienpistol","dragnet","turret","pulsecarbine","decloner","mindflayer","hyperkinetic","advplasmacutter","wormhole","wt550","bulldog","grenadelauncher","goldenrevolver","sniper","medibeam","scatterbeam")
+ var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffchange", "staffhealing", "armor", "scrying","staffdoor","voodoo", "whistle", "battlemage", "immortality", "ghostsword", "special")
+ var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos", "necromantic", "bloodcontract")
+
+ if(user) //in this case either someone holding a spellbook or a badmin
+ to_chat(user, "You summoned [summon_type ? "magic" : "guns"]!")
+ message_admins("[key_name_admin(user, 1)] summoned [summon_type ? "magic" : "guns"]!")
+ log_game("[key_name(user)] summoned [summon_type ? "magic" : "guns"]!")
+ for(var/mob/living/carbon/human/H in GLOB.player_list)
+ if(H.stat == DEAD || !(H.client))
+ continue
+ if(H.mind)
+ if(iswizard(H) || H.mind.special_role == "survivalist")
+ continue
+ if(prob(survivor_probability) && !(H.mind in SSticker.mode.traitors))
+ SSticker.mode.traitors += H.mind
+ if(!summon_type)
+ var/datum/objective/steal_five_of_type/summon_guns/guns = new
+ guns.owner = H.mind
+ H.mind.objectives += guns
+ H.mind.special_role = "survivalist"
+ to_chat(H, "You are the survivalist! Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, by any means necessary. Kill anyone who gets in your way.")
+ else
+ var/datum/objective/steal_five_of_type/summon_magic/magic = new
+ magic.owner = H.mind
+ H.mind.objectives += magic
+ H.mind.special_role = "amateur magician"
+ to_chat(H, "You are the amateur magician! Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way.")
+ var/datum/objective/survive/survive = new
+ survive.owner = H.mind
+ H.mind.objectives += survive
+ H.log_message("Was made into a survivalist, and trusts no one!", INDIVIDUAL_ATTACK_LOG)
+ H.mind.announce_objectives()
+ var/randomizeguns = pick(gunslist)
+ var/randomizemagic = pick(magiclist)
+ var/randomizemagicspecial = pick(magicspeciallist)
+ if(!summon_type)
+ var/obj/item/gun/G
+ switch (randomizeguns)
+ if("taser")
+ G = new /obj/item/gun/energy/e_gun/advtaser(get_turf(H))
+ if("egun")
+ G = new /obj/item/gun/energy/e_gun(get_turf(H))
+ if("laser")
+ G = new /obj/item/gun/energy/laser(get_turf(H))
+ if("revolver")
+ G = new /obj/item/gun/ballistic/revolver(get_turf(H))
+ if("detective")
+ G = new /obj/item/gun/ballistic/revolver/detective(get_turf(H))
+ if("deagle")
+ G = new /obj/item/gun/ballistic/automatic/pistol/deagle/camo(get_turf(H))
+ if("gyrojet")
+ G = new /obj/item/gun/ballistic/automatic/gyropistol(get_turf(H))
+ if("pulse")
+ G = new /obj/item/gun/energy/pulse(get_turf(H))
+ if("suppressed")
+ G = new /obj/item/gun/ballistic/automatic/pistol(get_turf(H))
+ new /obj/item/suppressor(get_turf(H))
+ if("doublebarrel")
+ G = new /obj/item/gun/ballistic/revolver/doublebarrel(get_turf(H))
+ if("shotgun")
+ G = new /obj/item/gun/ballistic/shotgun(get_turf(H))
+ if("combatshotgun")
+ G = new /obj/item/gun/ballistic/shotgun/automatic/combat(get_turf(H))
+ if("arg")
+ G = new /obj/item/gun/ballistic/automatic/ar(get_turf(H))
+ if("mateba")
+ G = new /obj/item/gun/ballistic/revolver/mateba(get_turf(H))
+ if("boltaction")
+ G = new /obj/item/gun/ballistic/shotgun/boltaction(get_turf(H))
+ if("speargun")
+ G = new /obj/item/gun/ballistic/automatic/speargun(get_turf(H))
+ if("uzi")
+ G = new /obj/item/gun/ballistic/automatic/mini_uzi(get_turf(H))
+ if("cannon")
+ G = new /obj/item/gun/energy/lasercannon(get_turf(H))
+ if("crossbow")
+ G = new /obj/item/gun/energy/kinetic_accelerator/crossbow/large(get_turf(H))
+ if("nuclear")
+ G = new /obj/item/gun/energy/e_gun/nuclear(get_turf(H))
+ if("sabr")
+ G = new /obj/item/gun/ballistic/automatic/proto(get_turf(H))
+ if("bulldog")
+ G = new /obj/item/gun/ballistic/automatic/shotgun/bulldog(get_turf(H))
+ if("c20r")
+ G = new /obj/item/gun/ballistic/automatic/c20r(get_turf(H))
+ if("saw")
+ G = new /obj/item/gun/ballistic/automatic/l6_saw(get_turf(H))
+ if("car")
+ G = new /obj/item/gun/ballistic/automatic/m90(get_turf(H))
+ if("alienpistol")
+ G = new /obj/item/gun/energy/alien(get_turf(H))
+ if("dragnet")
+ G = new /obj/item/gun/energy/e_gun/dragnet(get_turf(H))
+ if("turret")
+ G = new /obj/item/gun/energy/e_gun/turret(get_turf(H))
+ if("pulsecarbine")
+ G = new /obj/item/gun/energy/pulse/carbine(get_turf(H))
+ if("decloner")
+ G = new /obj/item/gun/energy/decloner(get_turf(H))
+ if("mindflayer")
+ G = new /obj/item/gun/energy/mindflayer(get_turf(H))
+ if("hyperkinetic")
+ G = new /obj/item/gun/energy/kinetic_accelerator(get_turf(H))
+ if("advplasmacutter")
+ G = new /obj/item/gun/energy/plasmacutter/adv(get_turf(H))
+ if("wormhole")
+ G = new /obj/item/gun/energy/wormhole_projector(get_turf(H))
+ if("wt550")
+ G = new /obj/item/gun/ballistic/automatic/wt550(get_turf(H))
+ if("bulldog")
+ G = new /obj/item/gun/ballistic/automatic/shotgun(get_turf(H))
+ if("grenadelauncher")
+ G = new /obj/item/gun/ballistic/revolver/grenadelauncher(get_turf(H))
+ if("goldenrevolver")
+ G = new /obj/item/gun/ballistic/revolver/golden(get_turf(H))
+ if("sniper")
+ G = new /obj/item/gun/ballistic/automatic/sniper_rifle(get_turf(H))
+ if("medibeam")
+ G = new /obj/item/gun/medbeam(get_turf(H))
+ if("scatterbeam")
+ G = new /obj/item/gun/energy/laser/scatter(get_turf(H))
+ if("gravgun")
+ G = new /obj/item/gun/energy/gravity_gun(get_turf(H))
+ G.unlock()
+ playsound(get_turf(H),'sound/magic/summon_guns.ogg', 50, 1)
+
+ else
+ switch (randomizemagic)
+ if("fireball")
+ new /obj/item/spellbook/oneuse/fireball(get_turf(H))
+ if("smoke")
+ new /obj/item/spellbook/oneuse/smoke(get_turf(H))
+ if("blind")
+ new /obj/item/spellbook/oneuse/blind(get_turf(H))
+ if("mindswap")
+ new /obj/item/spellbook/oneuse/mindswap(get_turf(H))
+ if("forcewall")
+ new /obj/item/spellbook/oneuse/forcewall(get_turf(H))
+ if("knock")
+ new /obj/item/spellbook/oneuse/knock(get_turf(H))
+ if("horsemask")
+ new /obj/item/spellbook/oneuse/barnyard(get_turf(H))
+ if("charge")
+ new /obj/item/spellbook/oneuse/charge(get_turf(H))
+ if("summonitem")
+ new /obj/item/spellbook/oneuse/summonitem(get_turf(H))
+ if("wandnothing")
+ new /obj/item/gun/magic/wand(get_turf(H))
+ if("wanddeath")
+ new /obj/item/gun/magic/wand/death(get_turf(H))
+ if("wandresurrection")
+ new /obj/item/gun/magic/wand/resurrection(get_turf(H))
+ if("wandpolymorph")
+ new /obj/item/gun/magic/wand/polymorph(get_turf(H))
+ if("wandteleport")
+ new /obj/item/gun/magic/wand/teleport(get_turf(H))
+ if("wanddoor")
+ new /obj/item/gun/magic/wand/door(get_turf(H))
+ if("wandfireball")
+ new /obj/item/gun/magic/wand/fireball(get_turf(H))
+ if("staffhealing")
+ new /obj/item/gun/magic/staff/healing(get_turf(H))
+ if("staffdoor")
+ new /obj/item/gun/magic/staff/door(get_turf(H))
+ if("armor")
+ new /obj/item/clothing/suit/space/hardsuit/wizard(get_turf(H))
+ if("scrying")
+ new /obj/item/scrying(get_turf(H))
+ if (!(H.dna.check_mutation(XRAY)))
+ H.dna.add_mutation(XRAY)
+ to_chat(H, "The walls suddenly disappear.")
+ if("voodoo")
+ new /obj/item/voodoo(get_turf(H))
+ if("whistle")
+ new /obj/item/warpwhistle(get_turf(H))
+ if("battlemage")
+ new /obj/item/clothing/suit/space/hardsuit/shielded/wizard(get_turf(H))
+ if("immortality")
+ new /obj/item/device/immortality_talisman(get_turf(H))
+ if("ghostsword")
+ new /obj/item/melee/ghost_sword(get_turf(H))
+ if("special")
+ magiclist -= "special" //only one super OP item per summoning max
+ switch (randomizemagicspecial)
+ if("staffchange")
+ new /obj/item/gun/magic/staff/change(get_turf(H))
+ if("staffanimation")
+ new /obj/item/gun/magic/staff/animate(get_turf(H))
+ if("wandbelt")
+ new /obj/item/storage/belt/wands/full(get_turf(H))
+ if("contract")
+ new /obj/item/antag_spawner/contract(get_turf(H))
+ if("staffchaos")
+ new /obj/item/gun/magic/staff/chaos(get_turf(H))
+ if("necromantic")
+ new /obj/item/device/necromantic_stone(get_turf(H))
+ if("bloodcontract")
+ new /obj/item/blood_contract(get_turf(H))
+ to_chat(H, "You suddenly feel lucky.")
+ playsound(get_turf(H),'sound/magic/summon_magic.ogg', 50, 1)
+
+
+/proc/summonevents()
+ if(!SSevents.wizardmode)
+ SSevents.frequency_lower = 600 //1 minute lower bound
+ SSevents.frequency_upper = 3000 //5 minutes upper bound
+ SSevents.toggleWizardmode()
+ SSevents.reschedule()
+
+ else //Speed it up
+ SSevents.frequency_upper -= 600 //The upper bound falls a minute each time, making the AVERAGE time between events lessen
+ if(SSevents.frequency_upper < SSevents.frequency_lower) //Sanity
+ SSevents.frequency_upper = SSevents.frequency_lower
+
+ SSevents.reschedule()
+ message_admins("Summon Events intensifies, events will now occur every [SSevents.frequency_lower / 600] to [SSevents.frequency_upper / 600] minutes.")
+ log_game("Summon Events was increased!")
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index 834a99d1ec..12ab61aaec 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -95,13 +95,13 @@
var/list/breath_gases = breath.gases
- breath.assert_gases("o2", "n2", "plasma", "co2", "n2o", "bz")
+ breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitrogen)
//Partial pressures in our breath
- var/O2_pp = breath.get_breath_partial_pressure(breath_gases["o2"][MOLES])
- var/N2_pp = breath.get_breath_partial_pressure(breath_gases["n2"][MOLES])
- var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases["plasma"][MOLES])
- var/CO2_pp = breath.get_breath_partial_pressure(breath_gases["co2"][MOLES])
+ var/O2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/oxygen][MOLES])
+ var/N2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrogen][MOLES])
+ var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/plasma][MOLES])
+ var/CO2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/carbon_dioxide][MOLES])
//-- OXY --//
@@ -109,7 +109,7 @@
//Too much oxygen! //Yes, some species may not like it.
if(safe_oxygen_max)
if(O2_pp > safe_oxygen_max)
- var/ratio = (breath_gases["o2"][MOLES]/safe_oxygen_max) * 10
+ var/ratio = (breath_gases[/datum/gas/oxygen][MOLES]/safe_oxygen_max) * 10
H.apply_damage_type(Clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type)
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
else
@@ -118,18 +118,18 @@
//Too little oxygen!
if(safe_oxygen_min)
if(O2_pp < safe_oxygen_min)
- gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath_gases["o2"][MOLES])
+ gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath_gases[/datum/gas/oxygen][MOLES])
H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
else
H.failed_last_breath = FALSE
if(H.health >= HEALTH_THRESHOLD_CRIT)
H.adjustOxyLoss(-5)
- gas_breathed = breath_gases["o2"][MOLES]
+ gas_breathed = breath_gases[/datum/gas/oxygen][MOLES]
H.clear_alert("not_enough_oxy")
//Exhale
- breath_gases["o2"][MOLES] -= gas_breathed
- breath_gases["co2"][MOLES] += gas_breathed
+ breath_gases[/datum/gas/oxygen][MOLES] -= gas_breathed
+ breath_gases[/datum/gas/carbon_dioxide][MOLES] += gas_breathed
gas_breathed = 0
//-- Nitrogen --//
@@ -137,7 +137,7 @@
//Too much nitrogen!
if(safe_nitro_max)
if(N2_pp > safe_nitro_max)
- var/ratio = (breath_gases["n2"][MOLES]/safe_nitro_max) * 10
+ var/ratio = (breath_gases[/datum/gas/nitrogen][MOLES]/safe_nitro_max) * 10
H.apply_damage_type(Clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type)
H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro)
else
@@ -146,18 +146,18 @@
//Too little nitrogen!
if(safe_nitro_min)
if(N2_pp < safe_nitro_min)
- gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath_gases["n2"][MOLES])
+ gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath_gases[/datum/gas/nitrogen][MOLES])
H.throw_alert("nitro", /obj/screen/alert/not_enough_nitro)
else
H.failed_last_breath = FALSE
if(H.health >= HEALTH_THRESHOLD_CRIT)
H.adjustOxyLoss(-5)
- gas_breathed = breath_gases["n2"][MOLES]
+ gas_breathed = breath_gases[/datum/gas/nitrogen][MOLES]
H.clear_alert("nitro")
//Exhale
- breath_gases["n2"][MOLES] -= gas_breathed
- breath_gases["co2"][MOLES] += gas_breathed
+ breath_gases[/datum/gas/nitrogen][MOLES] -= gas_breathed
+ breath_gases[/datum/gas/carbon_dioxide][MOLES] += gas_breathed
gas_breathed = 0
//-- CO2 --//
@@ -183,18 +183,18 @@
//Too little CO2!
if(safe_co2_min)
if(CO2_pp < safe_co2_min)
- gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath_gases["co2"][MOLES])
+ gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath_gases[/datum/gas/carbon_dioxide][MOLES])
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
else
H.failed_last_breath = FALSE
if(H.health >= HEALTH_THRESHOLD_CRIT)
H.adjustOxyLoss(-5)
- gas_breathed = breath_gases["co2"][MOLES]
+ gas_breathed = breath_gases[/datum/gas/carbon_dioxide][MOLES]
H.clear_alert("not_enough_co2")
//Exhale
- breath_gases["co2"][MOLES] -= gas_breathed
- breath_gases["o2"][MOLES] += gas_breathed
+ breath_gases[/datum/gas/carbon_dioxide][MOLES] -= gas_breathed
+ breath_gases[/datum/gas/oxygen][MOLES] += gas_breathed
gas_breathed = 0
@@ -203,7 +203,7 @@
//Too much toxins!
if(safe_toxins_max)
if(Toxins_pp > safe_toxins_max)
- var/ratio = (breath_gases["plasma"][MOLES]/safe_toxins_max) * 10
+ var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_toxins_max) * 10
H.apply_damage_type(Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type)
H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
@@ -213,18 +213,18 @@
//Too little toxins!
if(safe_toxins_min)
if(Toxins_pp < safe_toxins_min)
- gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath_gases["plasma"][MOLES])
+ gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath_gases[/datum/gas/plasma][MOLES])
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else
H.failed_last_breath = FALSE
if(H.health >= HEALTH_THRESHOLD_CRIT)
H.adjustOxyLoss(-5)
- gas_breathed = breath_gases["plasma"][MOLES]
+ gas_breathed = breath_gases[/datum/gas/plasma][MOLES]
H.clear_alert("not_enough_tox")
//Exhale
- breath_gases["plasma"][MOLES] -= gas_breathed
- breath_gases["co2"][MOLES] += gas_breathed
+ breath_gases[/datum/gas/plasma][MOLES] -= gas_breathed
+ breath_gases[/datum/gas/carbon_dioxide][MOLES] += gas_breathed
gas_breathed = 0
@@ -234,7 +234,7 @@
// N2O
- var/SA_pp = breath.get_breath_partial_pressure(breath_gases["n2o"][MOLES])
+ var/SA_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrous_oxide][MOLES])
if(SA_pp > SA_para_min) // Enough to make us stunned for a bit
H.Unconscious(60) // 60 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
@@ -245,7 +245,7 @@
// BZ
- var/bz_pp = breath.get_breath_partial_pressure(breath_gases["bz"][MOLES])
+ var/bz_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/bz][MOLES])
if(bz_pp > BZ_trip_balls_min)
H.hallucination += 20
if(prob(33))
diff --git a/html/changelogs/AutoChangeLog-pr-3304.yml b/html/changelogs/AutoChangeLog-pr-3304.yml
new file mode 100644
index 0000000000..b5247599de
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3304.yml
@@ -0,0 +1,4 @@
+author: "More Robust Than You"
+delete-after: True
+changes:
+ - tweak: "Jungle Fever carriers now hear the proper antag sound"
diff --git a/html/changelogs/AutoChangeLog-pr-3307.yml b/html/changelogs/AutoChangeLog-pr-3307.yml
new file mode 100644
index 0000000000..e69277f1e9
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3307.yml
@@ -0,0 +1,6 @@
+author: "deathride58"
+delete-after: True
+changes:
+ - tweak: "The game will no longer take 2-3 minutes to start up during highpop. Hooray optimization!"
+ - tweak: "Miscreants now have a 5% chance of being generated instead of a 2% chance."
+ - tweak: "Crew objective display at the end of the round is now a lot more compact."
diff --git a/html/changelogs/AutoChangeLog-pr-3310.yml b/html/changelogs/AutoChangeLog-pr-3310.yml
new file mode 100644
index 0000000000..8fddec701f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3310.yml
@@ -0,0 +1,4 @@
+author: "Xhuis"
+delete-after: True
+changes:
+ - tweak: "Cogscarabs can now experiment more freely with base design during non-clockcult rounds with infinite power and the ability to recite scripture!"
diff --git a/html/changelogs/AutoChangeLog-pr-3314.yml b/html/changelogs/AutoChangeLog-pr-3314.yml
new file mode 100644
index 0000000000..dbf4d48f28
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3314.yml
@@ -0,0 +1,4 @@
+author: "Mercenaryblue"
+delete-after: True
+changes:
+ - imageadd: "added some in_hands for banana peels."
diff --git a/html/changelogs/AutoChangeLog-pr-3321.yml b/html/changelogs/AutoChangeLog-pr-3321.yml
new file mode 100644
index 0000000000..094d5f7df8
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3321.yml
@@ -0,0 +1,4 @@
+author: "DaxDupont"
+delete-after: True
+changes:
+ - tweak: "After lobbying by Robust Softdrinks and Getmore Chocolate Corp all vendor firmware has been changed to add sillicons to their target demographic."
diff --git a/html/changelogs/Bawhoppen Forgot to add a Changelog.yml b/html/changelogs/Bawhoppen Forgot to add a Changelog.yml
new file mode 100644
index 0000000000..9c9895e895
--- /dev/null
+++ b/html/changelogs/Bawhoppen Forgot to add a Changelog.yml
@@ -0,0 +1,35 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: "Bawhoppen"
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
+# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "Smoke machine board has been moved to tech storage."
diff --git a/icons/mob/inhands/misc/food_lefthand.dmi b/icons/mob/inhands/misc/food_lefthand.dmi
index 770172cb5b..bdcccfc08b 100644
Binary files a/icons/mob/inhands/misc/food_lefthand.dmi and b/icons/mob/inhands/misc/food_lefthand.dmi differ
diff --git a/icons/mob/inhands/misc/food_righthand.dmi b/icons/mob/inhands/misc/food_righthand.dmi
index 17d2dde33f..b35ae67239 100644
Binary files a/icons/mob/inhands/misc/food_righthand.dmi and b/icons/mob/inhands/misc/food_righthand.dmi differ
diff --git a/strings/names/megacarp1.txt b/strings/names/megacarp1.txt
new file mode 100644
index 0000000000..e214c4cc01
--- /dev/null
+++ b/strings/names/megacarp1.txt
@@ -0,0 +1,79 @@
+Legendary
+Epic
+Rare
+Common
+Elusive
+Lackluster
+Bloody
+Strange
+Unremarkable
+Scarcely Lethal
+Mildly Menacing
+Truly Feared
+Wicked
+Nasty
+Normal
+Unique
+Vintage
+Genuine
+Unusual
+Haunted
+Big
+Small
+The
+Savage
+Hungry
+Sated
+Despicable
+Nice
+Helpful
+Rogue
+Spotted
+Deep Blue
+Quick
+Slow
+Beloved
+Agressive
+Angry
+Bewildered
+Clumsy
+Defeated
+Grumpy
+Itchy
+Scratchy
+Lazy
+Mysterious
+Repulsive
+Thoughtless
+Broad
+Chubby
+Crooked
+Curved
+Deep
+Flat
+High
+Hollow
+Low
+Narrow
+Round
+Shallow
+Robust
+Skinny
+Square Nose
+Steep Nose
+Renegade
+Ancient
+Old
+Fast
+Brief
+Short
+Frustratingly Elusive
+Curvy
+Fitted
+Forked
+Rugged
+Sinuous
+Slimy
+Sweeping
+Twisted
+Crooked
\ No newline at end of file
diff --git a/strings/names/megacarp2.txt b/strings/names/megacarp2.txt
new file mode 100644
index 0000000000..f00ec8bb2c
--- /dev/null
+++ b/strings/names/megacarp2.txt
@@ -0,0 +1,54 @@
+Laser Shark
+Hammerhead Shark
+Wobbegong Shark
+Smooth-Hound Shark
+Thresher Shark
+Sand Shark
+Mackerel Shark
+Sawshark
+Angel Shark
+Cat Shark
+Space Shark
+Cow Shark
+Goblin Shark
+Ghast Shark
+Ghost Shark
+Nightmare Shark
+Sharkling
+Sharknado
+Megalodon
+Minilodon
+Dog Shark
+Moby Dick
+Flipper Shark
+Space Kraken
+Great White Shark
+Asteroid Shark
+Meteor Shark
+Derelict Shark
+Lava Shark
+Whale Shark
+Traitor Shark
+Magishark
+Chaos Shark
+Incinerator Shark
+Shredder Shark
+Shawshark
+Judicator Shark
+Snapjaw Shark
+Bloodhound Shark
+Vermin Shark
+Chomper Shark
+Megalomaniac Shark
+Frog Shark
+Buffalo Shark
+Lizard Shark
+Pulse Shark
+Baby Gargantuan Shark
+Flying Shark
+Spacetime Shark
+Freon Shark
+Plasma Shark
+Guru Shark
+Toxic Shark
+Spider Shark
diff --git a/tgstation.dme b/tgstation.dme
index c63b893b69..e93c702505 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -291,6 +291,7 @@
#include "code\datums\soullink.dm"
#include "code\datums\spawners_menu.dm"
#include "code\datums\verbs.dm"
+#include "code\datums\world_topic.dm"
#include "code\datums\antagonists\antag_datum.dm"
#include "code\datums\antagonists\datum_abductor.dm"
#include "code\datums\antagonists\datum_brother.dm"
@@ -300,6 +301,7 @@
#include "code\datums\antagonists\datum_traitor.dm"
#include "code\datums\antagonists\devil.dm"
#include "code\datums\antagonists\ninja.dm"
+#include "code\datums\antagonists\wizard.dm"
#include "code\datums\components\_component.dm"
#include "code\datums\components\archaeology.dm"
#include "code\datums\components\infective.dm"
diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css
index ffe61666b9..256b53c106 100644
--- a/tgui/assets/tgui.css
+++ b/tgui/assets/tgui.css
@@ -1 +1 @@
-@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input::-webkit-input-placeholder{color:#999}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"}
\ No newline at end of file
+@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"}
\ No newline at end of file