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