diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index e05b93216be8..5dda2eaf4326 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -9588,15 +9588,11 @@ "atl" = ( /obj/machinery/ai_status_display, /turf/closed/wall/r_wall, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "atm" = ( /obj/machinery/status_display, /turf/closed/wall/r_wall, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "atn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ @@ -10244,9 +10240,7 @@ dir = 4 }, /turf/open/floor/plating, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "auC" = ( /obj/machinery/power/rad_collector{ anchored = 1 @@ -10256,9 +10250,7 @@ icon_state = "0-8" }, /turf/open/floor/circuit/green, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "auD" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/simple/general/visible{ @@ -10267,9 +10259,7 @@ }, /obj/structure/window/reinforced/highpressure/fulltile, /turf/open/floor/plating, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "auE" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber{ dir = 8; @@ -10277,18 +10267,14 @@ scrub_Toxins = 0 }, /turf/open/floor/engine, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "auF" = ( /obj/machinery/atmospherics/components/unary/vent_pump{ dir = 4; on = 1 }, /turf/open/floor/engine, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "auG" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/simple/general/visible{ @@ -10296,9 +10282,7 @@ }, /obj/structure/window/reinforced/highpressure/fulltile, /turf/open/floor/plating, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "auH" = ( /obj/machinery/power/rad_collector{ anchored = 1 @@ -10308,9 +10292,7 @@ d2 = 4 }, /turf/open/floor/circuit/green, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "auI" = ( /obj/structure/cable{ d1 = 4; @@ -10326,9 +10308,7 @@ dir = 8 }, /turf/open/floor/plating, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "auJ" = ( /obj/structure/cable{ d1 = 2; @@ -10878,15 +10858,11 @@ }, /obj/structure/window/reinforced/highpressure/fulltile, /turf/open/floor/plating, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "avQ" = ( /obj/machinery/power/supermatter_shard/crystal, /turf/open/floor/engine, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "avR" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/manifold/general/visible{ @@ -10895,9 +10871,7 @@ }, /obj/structure/window/reinforced/highpressure/fulltile, /turf/open/floor/plating, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "avS" = ( /obj/structure/cable{ d1 = 4; @@ -10914,9 +10888,7 @@ dir = 8 }, /turf/open/floor/plating, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "avT" = ( /obj/structure/cable{ d1 = 2; @@ -11410,9 +11382,7 @@ dir = 4 }, /turf/open/floor/plating, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "awV" = ( /obj/structure/cable{ d1 = 2; @@ -11885,18 +11855,14 @@ dir = 5 }, /turf/closed/wall/r_wall, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "axQ" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 10 }, /obj/machinery/meter, /turf/closed/wall/r_wall, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "axR" = ( /obj/machinery/door/airlock/glass_atmos{ heat_proof = 1; @@ -11905,9 +11871,7 @@ req_one_access_txt = "24;10" }, /turf/open/floor/engine, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "axS" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ icon_state = "intact"; @@ -11915,17 +11879,13 @@ }, /obj/machinery/meter, /turf/closed/wall/r_wall, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "axT" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 9 }, /turf/closed/wall/r_wall, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "axU" = ( /obj/structure/cable{ d1 = 1; @@ -12556,9 +12516,7 @@ name = "Gas to Filter" }, /turf/open/floor/engine, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "azf" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 1; @@ -12566,9 +12524,7 @@ name = "Gas to Chamber" }, /turf/open/floor/engine, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "azg" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/structure/extinguisher_cabinet{ @@ -13108,9 +13064,7 @@ "aAd" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, /turf/closed/wall/r_wall, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "aAe" = ( /obj/machinery/atmospherics/components/binary/pump, /obj/effect/turf_decal/bot, @@ -13669,9 +13623,7 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "aBe" = ( /obj/machinery/atmospherics/pipe/manifold/general/visible, /obj/machinery/meter, @@ -110595,9 +110547,7 @@ }) "ebG" = ( /turf/open/floor/engine, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "ebJ" = ( /obj/machinery/door/window/brigdoor/northleft{ name = "Captain's Desk"; @@ -112888,9 +112838,7 @@ network = list("Engine") }, /turf/open/floor/circuit/green, -/area/engine/gravity_generator{ - name = "Atmospherics Engine" - }) +/area/engine/supermatter) "ehz" = ( /obj/structure/chair/office/dark{ dir = 8 @@ -112900,6 +112848,49 @@ }, /turf/open/floor/plasteel/neutral, /area/atmos) +"ehA" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehB" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehC" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehD" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/highpressure/fulltile, +/turf/open/floor/plating, +/area/engine/supermatter) +"ehE" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehF" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehG" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehH" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehI" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehJ" = ( +/obj/structure/sign/radiation, +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehK" = ( +/obj/structure/sign/radiation, +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehL" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"ehM" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) (1,1,1) = {" aaa @@ -137907,11 +137898,11 @@ aoI apK ard asi -aiW +ehA auC auC auC -aiW +ehH azc aAc aAZ @@ -138164,13 +138155,13 @@ aoJ apL are asj -aiW +ehB auD avP avP axP -azd -aiW +ehJ +ehL aAY ark aDH @@ -138421,7 +138412,7 @@ aoK apM arf ask -aiW +ehC auE auE auE @@ -138678,7 +138669,7 @@ aoK apN arg asl -aoK +ehD ebG avQ ebG @@ -138935,7 +138926,7 @@ aoK apO arh asm -aiW +ehE auF auF auF @@ -139192,13 +139183,13 @@ aoL apP ari asn -aiW +ehF auG avR avR axT -azd -aiW +ehK +ehM aBd ark aDL @@ -139449,11 +139440,11 @@ aoI apK ebP aso -aiW +ehG ehy auH auH -aiW +ehI azg aAe aBe diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index c26ba78c62cc..00e9a2ef582a 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -20535,7 +20535,7 @@ dir = 6 }, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aJB" = ( /obj/structure/grille, /obj/structure/window/reinforced/fulltile, @@ -21087,21 +21087,21 @@ dir = 4 }, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aKH" = ( /obj/machinery/atmospherics/components/binary/pump/on{ dir = 4; name = "Gas to Chamber" }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aKI" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 9 }, /obj/machinery/meter, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aKL" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ icon_state = "intact"; @@ -21823,10 +21823,10 @@ req_access_txt = "10" }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aMk" = ( /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aMm" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, /obj/effect/turf_decal/delivery, @@ -22357,14 +22357,14 @@ name = "Gas to Filter" }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aNv" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber{ dir = 2; on = 1 }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aNw" = ( /obj/structure/window/reinforced{ dir = 4 @@ -69317,7 +69317,7 @@ req_one_access_txt = "24;10" }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "cpS" = ( /obj/structure/cable/yellow{ d1 = 1; @@ -90891,7 +90891,7 @@ }, /obj/structure/cable, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "daZ" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/manifold/general/visible{ @@ -90899,7 +90899,7 @@ }, /obj/structure/window/reinforced/highpressure/fulltile, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "dbb" = ( /obj/machinery/atmospherics/components/unary/vent_pump{ dir = 1; @@ -90908,7 +90908,7 @@ pressure_checks = 1 }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "dbd" = ( /obj/structure/sink/kitchen{ pixel_y = 28 @@ -92768,7 +92768,7 @@ "deD" = ( /obj/machinery/status_display, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "deI" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; @@ -92833,7 +92833,7 @@ }, /obj/structure/window/reinforced/highpressure/fulltile, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "deT" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; @@ -92862,7 +92862,7 @@ "deV" = ( /obj/structure/sign/fire, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "deW" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, /obj/effect/turf_decal/stripes/line{ @@ -92897,7 +92897,7 @@ "dfa" = ( /obj/machinery/power/supermatter_shard/crystal, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "dfb" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 10; @@ -92906,11 +92906,11 @@ }, /obj/machinery/meter, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "dfc" = ( /obj/structure/sign/electricshock, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "dfd" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; @@ -92969,13 +92969,13 @@ dir = 5 }, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "dfk" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/manifold/general/visible, /obj/structure/window/reinforced/highpressure/fulltile, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "dfm" = ( /obj/structure/grille, /obj/machinery/atmospherics/pipe/simple/general/visible{ @@ -92983,7 +92983,7 @@ }, /obj/structure/window/reinforced/highpressure/fulltile, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "dfp" = ( /obj/effect/turf_decal/bot{ dir = 1 @@ -93004,7 +93004,7 @@ d2 = 2 }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "dft" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; @@ -94749,7 +94749,7 @@ name = "Radiation Chamber Shutters" }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "dju" = ( /obj/structure/cable{ d1 = 1; @@ -94768,7 +94768,7 @@ name = "Radiation Chamber Shutters" }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "djw" = ( /obj/structure/cable{ d1 = 1; @@ -94793,7 +94793,7 @@ name = "Radiation Chamber Shutters" }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "djy" = ( /obj/structure/cable{ d1 = 1; @@ -95606,7 +95606,42 @@ network = list("Engine") }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) +"dlJ" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"dlK" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"dlL" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"dlM" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"dlN" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"dlO" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/highpressure/fulltile, +/turf/open/floor/plating, +/area/engine/supermatter) +"dlP" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"dlQ" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"dlR" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"dlS" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"dlT" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) (1,1,1) = {" aaa @@ -137856,11 +137891,11 @@ aEr aFC aGZ aGZ -axY +dlL aKG aMj aKG -axY +dlP aQe aRv dfD @@ -138113,11 +138148,11 @@ dej aFC deC deC -axY +dlM aKH aMk aNu -axY +dlQ dfp dfp dfE @@ -138369,13 +138404,13 @@ aCY dek der deD -axY +dlJ aJv aKI aMj dfb dfj -axY +dlS deD dfF aTN @@ -139397,13 +139432,13 @@ aCY dem aFD deD -axY -axY +dlK +dlN deV -aCZ +dlO dfc -axY -axY +dlR +dlT deD dfI dfS diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index acc7e47806a0..908db94b393b 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -22458,11 +22458,11 @@ "aJt" = ( /obj/structure/sign/radiation, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aJu" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aJv" = ( /obj/machinery/door/airlock/glass_atmos{ name = "Supermatter Chamber"; @@ -22470,7 +22470,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aJw" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 1; @@ -23178,12 +23178,12 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aKB" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aKC" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 2; @@ -23192,11 +23192,11 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aKD" = ( /obj/structure/sign/fire, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aKE" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 @@ -23883,45 +23883,45 @@ "aLO" = ( /obj/machinery/ai_status_display, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aLP" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ icon_state = "intact"; dir = 6 }, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aLQ" = ( /obj/machinery/meter, /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 9 }, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aLR" = ( /obj/machinery/door/airlock/glass_atmos{ name = "Supermatter Chamber"; req_access_txt = "24" }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aLS" = ( /obj/machinery/meter, /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 5 }, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aLT" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 10 }, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aLU" = ( /obj/machinery/status_display, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aLV" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, /obj/structure/cable{ @@ -24450,7 +24450,7 @@ dir = 4 }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "aMR" = ( /obj/machinery/power/rad_collector{ anchored = 1 @@ -24460,7 +24460,7 @@ icon_state = "0-8" }, /turf/open/floor/circuit/green, -/area/engine/engineering) +/area/engine/supermatter) "aMS" = ( /obj/structure/grille, /obj/structure/window/reinforced/fulltile, @@ -24468,7 +24468,7 @@ dir = 8 }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "aMT" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber{ dir = 8; @@ -24476,17 +24476,17 @@ scrub_Toxins = 0 }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aMU" = ( /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aMV" = ( /obj/machinery/atmospherics/components/unary/vent_pump{ dir = 4; on = 1 }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aMW" = ( /obj/structure/grille, /obj/structure/window/reinforced/fulltile, @@ -24495,7 +24495,7 @@ dir = 4 }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "aMX" = ( /obj/machinery/power/rad_collector{ anchored = 1 @@ -24505,7 +24505,7 @@ d2 = 4 }, /turf/open/floor/circuit/green, -/area/engine/engineering) +/area/engine/supermatter) "aMY" = ( /obj/structure/cable{ d1 = 4; @@ -24522,7 +24522,7 @@ dir = 8 }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "aMZ" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, /obj/structure/cable{ @@ -25191,7 +25191,7 @@ name = "supermatter crystal" }, /turf/open/floor/engine, -/area/engine/engineering) +/area/engine/supermatter) "aOb" = ( /obj/structure/cable{ d1 = 4; @@ -25209,7 +25209,7 @@ dir = 8 }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "aOc" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, /obj/structure/cable{ @@ -25502,7 +25502,7 @@ dir = 4 }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "aOC" = ( /obj/structure/grille, /obj/structure/window/reinforced/fulltile, @@ -25510,7 +25510,7 @@ dir = 5 }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "aOD" = ( /obj/structure/grille, /obj/structure/window/reinforced/fulltile, @@ -25518,7 +25518,7 @@ dir = 9 }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "aOE" = ( /obj/structure/cable{ d1 = 4; @@ -25534,7 +25534,7 @@ dir = 8 }, /turf/open/floor/plating, -/area/engine/engineering) +/area/engine/supermatter) "aOF" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, /obj/structure/cable{ @@ -26390,7 +26390,7 @@ "aPK" = ( /obj/structure/sign/electricshock, /turf/closed/wall/r_wall, -/area/engine/engineering) +/area/engine/supermatter) "aPL" = ( /obj/structure/grille, /obj/structure/window/reinforced/fulltile, @@ -41984,7 +41984,7 @@ pixel_x = 23 }, /turf/open/floor/circuit/green, -/area/engine/engineering) +/area/engine/supermatter) "buW" = ( /obj/structure/cable/white{ tag = "icon-0-2"; @@ -41995,6 +41995,32 @@ dir = 5 }, /area/bridge) +"buX" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"buY" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"buZ" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"bva" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"bvb" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"bvc" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/fulltile, +/turf/open/floor/plating, +/area/engine/supermatter) +"bvd" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) +"bve" = ( +/turf/closed/wall/r_wall, +/area/engine/supermatter) (1,1,1) = {" aaa @@ -72697,11 +72723,11 @@ aHl aIi aJs aKz -aEt +buY buV aMR aMR -aEt +bva aQL aRI aSS @@ -72953,12 +72979,12 @@ aGj aHm aIj aJt -aEt +buX aLP aMS aMS aOC -aEt +bvb aQM aRJ aST @@ -73472,7 +73498,7 @@ aLR aMU aOa aMU -aPL +bvc aQO aRL aSV @@ -73986,7 +74012,7 @@ aLT aMW aMW aOD -aEt +bvd aQQ aRN aSX @@ -74239,11 +74265,11 @@ aHr aIo aJw aKE -aEt +buZ aMX aMX aMX -aEt +bve aQR aRO aSY diff --git a/_maps/map_files/TgStation/tgstation.2.1.3.dmm b/_maps/map_files/TgStation/tgstation.2.1.3.dmm index a6c68c47dfc1..bb89658c4e42 100644 --- a/_maps/map_files/TgStation/tgstation.2.1.3.dmm +++ b/_maps/map_files/TgStation/tgstation.2.1.3.dmm @@ -4153,6 +4153,11 @@ pixel_y = 0 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23; + pixel_y = 0 + }, /turf/open/floor/plasteel/red/corner{ dir = 1 }, @@ -56049,10 +56054,6 @@ icon_state = "0-8" }, /obj/structure/grille, -/obj/machinery/door/poddoor/preopen{ - id = "Secure Gate"; - name = "brig shutters" - }, /obj/structure/window/reinforced/fulltile, /turf/open/floor/plating, /area/engine/engineering) diff --git a/_maps/shuttles/emergency_bar.dmm b/_maps/shuttles/emergency_bar.dmm index eb696067e2cd..c15d5cea7590 100644 --- a/_maps/shuttles/emergency_bar.dmm +++ b/_maps/shuttles/emergency_bar.dmm @@ -250,7 +250,7 @@ "aN" = ( /obj/structure/chair/stool/bar{ can_buckle = 1; - name = "buckable bar stool" + name = "buckleable bar stool" }, /turf/open/floor/plasteel/bar, /area/shuttle/escape) diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm index 921589d03325..9b450765dbca 100644 --- a/code/__DEFINES/robots.dm +++ b/code/__DEFINES/robots.dm @@ -34,3 +34,9 @@ #define FLOOR_BOT 4 // Floorbots #define CLEAN_BOT 8 // Cleanbots #define MED_BOT 16 // Medibots + +//AI notification defines +#define NEW_BORG 1 +#define NEW_MODULE 2 +#define RENAME 3 +#define AI_SHELL 4 \ No newline at end of file diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm new file mode 100644 index 000000000000..155f599d8994 --- /dev/null +++ b/code/__DEFINES/sound.dm @@ -0,0 +1,2 @@ +//max channel is 1024. Only go lower from here, because byond tends to pick the first availiable channel to play sounds on +#define CHANNEL_LOBBYMUSIC 1024 \ No newline at end of file diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 7f14d9d5b12a..fc8ec9f17e25 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -163,9 +163,8 @@ Proc for attack log creation, because really why not 1 argument is the actor 2 argument is the target of action 3 is the description of action(like punched, throwed, or any other verb) -4 should it make adminlog note or not -5 is the tool with which the action was made(usually item) 5 and 6 are very similar(5 have "by " before it, that it) and are separated just to keep things in a bit more in order -6 is additional information, anything that needs to be added +4 is the tool with which the action was made(usually item) 4 and 5 are very similar(5 have "by " before it, that it) and are separated just to keep things in a bit more in order +5 is additional information, anything that needs to be added */ /proc/add_logs(mob/user, mob/target, what_done, object=null, addition=null) @@ -176,19 +175,44 @@ Proc for attack log creation, because really why not var/mob/living/living_target - if(target && isliving(target)) living_target = target + + var/hp =" " + if(living_target) + hp = "(NEWHP: [living_target.health])" + + var/starget = "NON-EXISTENT SUBJECT" + if(target) + if(is_mob_target && target.ckey) + starget = "[target.name]([target.ckey])" + else + starget = "[target.name]" + + var/ssource = "NON-EXISTENT USER" //How!? + if(user) + if(is_mob_user && user.ckey) + ssource = "[user.name]([user.ckey])" + else + ssource = "[user.name]" + + var/sobject = "" + if(object) + sobject = "[object]" + + var/sattackloc = "" + if(attack_location) + sattackloc = "([attack_location.x],[attack_location.y],[attack_location.z])" if(is_mob_user) - var/message = "has [what_done] [target ? "[target.name][(is_mob_target && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]" + var/message = "has [what_done] [starget] with [sobject][addition] [hp] [sattackloc]" user.log_message(message, INDIVIDUAL_ATTACK_LOG) if(is_mob_target) - var/message = "has been [what_done] by [user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]" + var/message = "has been [what_done] by [ssource] with [sobject][addition] [hp] [sattackloc]" target.log_message(message, INDIVIDUAL_ATTACK_LOG) - log_attack("[user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(is_mob_target && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]") + log_attack("[ssource] [what_done] [starget] with [sobject][addition] [hp] [sattackloc]") /proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 9b98e7c1c107..41f5d0c56eac 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -232,7 +232,7 @@ Turf and target are seperate in case you want to teleport some distance from a t /proc/active_free_borgs() . = list() for(var/mob/living/silicon/robot/R in living_mob_list) - if(R.connected_ai) + if(R.connected_ai || R.shell) continue if(R.stat == DEAD) continue @@ -1313,7 +1313,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) else . = "" -/var/mob/dview/dview_mob = new +var/mob/dead/dview/dview_mob = new //Version of view() which ignores darkness, because BYOND doesn't have it (I actually suggested it but it was tagged redundant, BUT HEARERS IS A T- /rant). /proc/dview(var/range = world.view, var/center, var/invis_flags = 0) @@ -1327,21 +1327,24 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) . = view(range, dview_mob) dview_mob.loc = null -/mob/dview +/mob/dead/dview + name = "INTERNAL DVIEW MOB" invisibility = 101 - density = 0 + density = FALSE see_in_dark = 1e6 - anchored = 1 + anchored = TRUE + var/ready_to_die = FALSE -/mob/dview/Destroy(force=0) - stack_trace("ALRIGHT WHICH FUCKER TRIED TO DELETE *MY* DVIEW?") +/mob/dead/dview/Destroy(force = FALSE) + if(!ready_to_die) + stack_trace("ALRIGHT WHICH FUCKER TRIED TO DELETE *MY* DVIEW?") - if (!force) - return QDEL_HINT_LETMELIVE + if (!force) + return QDEL_HINT_LETMELIVE - world.log << "EVACUATE THE SHITCODE IS TRYING TO STEAL MUH JOBS" - global.dview_mob = new - return QDEL_HINT_QUEUE + log_world("EVACUATE THE SHITCODE IS TRYING TO STEAL MUH JOBS") + dview_mob = new + return ..() #define FOR_DVIEW(type, range, center, invis_flags) \ diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index a2e0e1e0b5f9..e4fdb79bb8fa 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -13,4 +13,5 @@ var/global/list/living_mob_list = list() //all alive mobs, including clientles var/global/list/dead_mob_list = list() //all dead mobs, including clientless. Excludes /mob/dead/new_player var/global/list/joined_player_list = list() //all clients that have joined the game at round-start or as a latejoin. var/global/list/silicon_mobs = list() //all silicon mobs -var/global/list/pai_list = list() \ No newline at end of file +var/global/list/pai_list = list() +var/global/list/available_ai_shells = list() \ No newline at end of file diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 636675c8ac63..5f21d372ff73 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -392,10 +392,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." textlist += "[G.required_components[i]] " textlist += "
" else - if(G.ratvar_portal) - textlist += "Seconds until Ratvar's arrival: [G.get_arrival_text(TRUE)]
" - else - textlist += "Seconds until Proselytization: [G.get_arrival_text(TRUE)]
" + textlist += "Seconds until Ratvar's arrival: [G.get_arrival_text(TRUE)]
" if(unconverted_ais_exist) if(unconverted_ais_exist > 1) textlist += "[unconverted_ais_exist] unconverted AIs exist!
" diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index 1a7450eb172c..1b510a4f76e2 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -3,6 +3,14 @@ icon_state = "blank" appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR blend_mode = BLEND_OVERLAY + var/show_alpha = 255 + var/hide_alpha = 0 + +/obj/screen/plane_master/proc/Show(override) + alpha = override || show_alpha + +/obj/screen/plane_master/proc/Hide(override) + alpha = override || hide_alpha //Why do plane masters need a backdrop sometimes? Read http://www.byond.com/forum/?post=2141928 //Trust me, you need one. Period. If you don't think you do, you're doing something extremely wrong. diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm index 204e03146df5..aa43c86f82f8 100644 --- a/code/controllers/subsystem/npcpool.dm +++ b/code/controllers/subsystem/npcpool.dm @@ -1,34 +1,31 @@ +#define PROCESSING_NPCS 0 +#define PROCESSING_DELEGATES 1 +#define PROCESSING_ASSISTANTS 2 + SUBSYSTEM_DEF(npcpool) name = "NPC Pool" - init_order = 17 - flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_NO_TICK_CHECK - priority = 25 + flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND + priority = 20 var/list/canBeUsed = list() - var/list/canBeUsed_non = list() var/list/needsDelegate = list() var/list/needsAssistant = list() - var/list/needsHelp_non = list() - var/list/botPool_l = list() //list of all npcs using the pool - var/list/botPool_l_non = list() //list of all non SNPC mobs using the pool - -/datum/controller/subsystem/npcpool/proc/insertBot(toInsert) - if(istype(toInsert,/mob/living/carbon/human/interactive)) - botPool_l |= toInsert + + var/list/processing = list() + var/list/currentrun = list() + var/stage /datum/controller/subsystem/npcpool/stat_entry() - ..("T:[botPool_l.len + botPool_l_non.len]|D:[needsDelegate.len]|A:[needsAssistant.len + needsHelp_non.len]|U:[canBeUsed.len + canBeUsed_non.len]") + ..("NPCS:[processing.len]|D:[needsDelegate.len]|A:[needsAssistant.len]|U:[canBeUsed.len]") +/datum/controller/subsystem/npcpool/proc/stop_processing(mob/living/carbon/human/interactive/I) + processing -= I + currentrun -= I + needsDelegate -= I + canBeUsed -= I + needsAssistant -= I -/datum/controller/subsystem/npcpool/proc/cleanNull() - //cleanup nulled bots - listclearnulls(botPool_l) - listclearnulls(needsDelegate) - listclearnulls(canBeUsed) - listclearnulls(needsAssistant) - - -/datum/controller/subsystem/npcpool/fire() +/datum/controller/subsystem/npcpool/fire(resumed = FALSE) //bot delegation and coordination systems //General checklist/Tasks for delegating a task or coordinating it (for SNPCs) // 1. Bot proximity to task target: if too far, delegate, if close, coordinate @@ -36,87 +33,94 @@ SUBSYSTEM_DEF(npcpool) // 3. Process delegation: if a bot (or bots) has been delegated, assign them to the task. // 4. Process coordination: if a bot(or bots) has been asked to coordinate, assign them to help. // 5. Do all assignments: goes through the delegated/coordianted bots and assigns the right variables/tasks to them. - var/npcCount = 1 - cleanNull() + if (!resumed) + src.currentrun = processing.Copy() + stage = PROCESSING_NPCS + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + var/list/canBeUsed = src.canBeUsed - //SNPC handling - for(var/mob/living/carbon/human/interactive/check in botPool_l) - if(!check) - botPool_l.Cut(npcCount,npcCount+1) - continue - var/checkInRange = view(MAX_RANGE_FIND,check) - if(!(locate(check.TARGET) in checkInRange)) - needsDelegate |= check + if(stage == PROCESSING_NPCS) + while(currentrun.len) + var/mob/living/carbon/human/interactive/thing = currentrun[currentrun.len] + --currentrun.len - else if(check.IsDeadOrIncap(FALSE)) - needsDelegate |= check + thing.InteractiveProcess() - else if(check.doing & FIGHTING) - needsAssistant |= check + var/checkInRange = view(MAX_RANGE_FIND,thing) + if(thing.IsDeadOrIncap(FALSE) || !(locate(thing.TARGET) in checkInRange)) + needsDelegate += thing + else if(thing.doing & FIGHTING) + needsAssistant += thing + else + canBeUsed += thing - else - canBeUsed |= check - npcCount++ + if (MC_TICK_CHECK) + return + stage = PROCESSING_DELEGATES + currentrun = needsDelegate //localcache + src.currentrun = currentrun - if(needsDelegate.len) + if(stage == PROCESSING_DELEGATES) + while(currentrun.len && canBeUsed.len) + var/mob/living/carbon/human/interactive/check = currentrun[currentrun.len] + var/mob/living/carbon/human/interactive/candidate = canBeUsed[canBeUsed.len] + --currentrun.len - needsDelegate -= pick(needsDelegate) // cheapo way to make sure stuff doesn't pingpong around in the pool forever. delegation runs seperately to each loop so it will work much smoother + var/helpProb = 0 + var/list/chfac = check.faction + var/list/canfac = candidate.faction + var/facCount = LAZYLEN(chfac) * LAZYLEN(canfac) - npcCount = 1 //reset the count - for(var/mob/living/carbon/human/interactive/check in needsDelegate) - if(!check) - needsDelegate.Cut(npcCount,npcCount+1) - continue - if(canBeUsed.len) - var/mob/living/carbon/human/interactive/candidate = pick(canBeUsed) - var/facCount = 0 - var/helpProb = 0 - for(var/C in check.faction) - for(var/D in candidate.faction) - if(D == C) - helpProb = min(100,helpProb + 25) - facCount++ - if(facCount == 1 && helpProb > 0) - helpProb = 100 - if(prob(helpProb)) - if(candidate.takeDelegate(check)) - needsDelegate -= check - canBeUsed -= candidate - candidate.eye_color = "red" - candidate.update_icons() - npcCount++ + for(var/C in chfac) + if(C in canfac) + helpProb = min(100,helpProb + 25) + if(helpProb >= 100) + break - if(needsAssistant.len) + if(facCount == 1 && helpProb) + helpProb = 100 - needsAssistant -= pick(needsAssistant) + if(prob(helpProb) && candidate.takeDelegate(check)) + --canBeUsed.len + candidate.eye_color = "red" + candidate.update_icons() - npcCount = 1 //reset the count - for(var/mob/living/carbon/human/interactive/check in needsAssistant) - if(!check) - needsAssistant.Cut(npcCount,npcCount+1) - continue - if(canBeUsed.len) - var/mob/living/carbon/human/interactive/candidate = pick(canBeUsed) - var/facCount = 0 - var/helpProb = 0 - for(var/C in check.faction) - for(var/D in candidate.faction) - if(D == C) - helpProb = min(100,helpProb + 25) - facCount++ - if(facCount == 1 && helpProb > 0) - helpProb = 100 - if(prob(helpProb)) - if(candidate.takeDelegate(check,FALSE)) - needsAssistant -= check - canBeUsed -= candidate - candidate.eye_color = "yellow" - candidate.update_icons() - npcCount++ + if(MC_TICK_CHECK) + return + stage = PROCESSING_ASSISTANTS + currentrun = needsAssistant //localcache + src.currentrun = currentrun + + //no need for the stage check + + while(currentrun.len && canBeUsed.len) + var/mob/living/carbon/human/interactive/check = currentrun[currentrun.len] + var/mob/living/carbon/human/interactive/candidate = canBeUsed[canBeUsed.len] + --currentrun.len + + var/helpProb = 0 + var/list/chfac = check.faction + var/list/canfac = candidate.faction + var/facCount = LAZYLEN(chfac) * LAZYLEN(canfac) + + for(var/C in chfac) + if(C in canfac) + helpProb = min(100,helpProb + 25) + if(helpProb >= 100) + break + + if(facCount == 1 && helpProb) + helpProb = 100 + + if(prob(helpProb) && candidate.takeDelegate(check,FALSE)) + --canBeUsed.len + candidate.eye_color = "yellow" + candidate.update_icons() + + if(!currentrun.len || MC_TICK_CHECK) //don't change SS state if it isn't necessary + return /datum/controller/subsystem/npcpool/Recover() - if (istype(SSnpcpool.botPool_l)) - botPool_l = SSnpcpool.botPool_l - if (istype(SSnpcpool.botPool_l_non)) - botPool_l_non = SSnpcpool.botPool_l_non \ No newline at end of file + processing = SSnpcpool.processing diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index ff916baa1efd..551a2b07ec55 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -452,6 +452,7 @@ SUBSYSTEM_DEF(shuttle) //to_chat(world, "Making transit dock at [COORD(midpoint)]") var/area/shuttle/transit/A = new() A.parallax_movedir = travel_dir + A.contents = proposed_zone var/obj/docking_port/stationary/transit/new_transit_dock = new(midpoint) new_transit_dock.assigned_turfs = proposed_zone new_transit_dock.name = "Transit for [M.id]/[M.name]" @@ -467,7 +468,6 @@ SUBSYSTEM_DEF(shuttle) var/turf/T = i T.ChangeTurf(transit_path) T.flags &= ~(UNUSED_TRANSIT_TURF) - A.contents += T M.assigned_transit = new_transit_dock return TRUE diff --git a/code/datums/antagonists/datum_clockcult.dm b/code/datums/antagonists/datum_clockcult.dm index 6bd0926fcc7c..57eb8602d2e6 100644 --- a/code/datums/antagonists/datum_clockcult.dm +++ b/code/datums/antagonists/datum_clockcult.dm @@ -18,6 +18,14 @@ . = is_eligible_servant(new_body) /datum/antagonist/clockcultist/give_to_body(mob/living/new_body) + if(iscyborg(new_body)) + var/mob/living/silicon/robot/R = new_body + if(R.deployed) + var/mob/living/silicon/ai/AI = R.mainframe + R.undeploy() + var/converted = add_servant_of_ratvar(AI, silent_update) + to_chat(AI, "Anomaly Detected. Returned to core!") //The AI needs to be in its core to properly be converted + return converted if(!silent_update) if(issilicon(new_body)) to_chat(new_body, "You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the Clockwork Justiciar, \ @@ -69,7 +77,8 @@ var/mob/living/silicon/S = owner if(iscyborg(S)) var/mob/living/silicon/robot/R = S - R.UnlinkSelf() + if(!R.shell) + R.UnlinkSelf() R.module.rebuild_modules() else if(isAI(S)) var/mob/living/silicon/ai/A = S diff --git a/code/datums/martial.dm b/code/datums/martial.dm index 803faabba6cf..a49d945fa44e 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -543,11 +543,12 @@ /datum/martial_art/cqc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) add_to_streak("D",D) + var/obj/item/I = null if(check_streak(A,D)) return 1 if(prob(65)) if(!D.stat || !D.weakened || !restraining) - var/obj/item/I = D.get_active_held_item() + I = D.get_active_held_item() D.visible_message("[A] strikes [D]'s jaw with their hand!", \ "[A] strikes your jaw, disorienting you!") playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1) @@ -560,7 +561,7 @@ D.visible_message("[A] attempted to disarm [D]!", \ "[A] attempted to disarm [D]!") playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - add_logs(A, D, "disarmed with CQC") + add_logs(A, D, "disarmed with CQC", "[I ? " grabbing \the [I]" : ""]") if(restraining && A.pulling == D) D.visible_message("[A] puts [D] into a chokehold!", \ "[A] puts you into a chokehold!") diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 5542aa2b2713..1a193db87ba2 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -132,8 +132,9 @@ /datum/martial_art/krav_maga/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(check_streak(A,D)) return 1 + var/obj/item/I = null if(prob(60)) - var/obj/item/I = D.get_active_held_item() + I = D.get_active_held_item() if(I) if(D.drop_item()) A.put_in_hands(I) @@ -144,7 +145,7 @@ D.visible_message("[A] attempted to disarm [D]!", \ "[A] attempted to disarm [D]!") playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - add_logs(A, D, "disarmed with krav maga") + add_logs(A, D, "disarmed with krav maga", "[I ? " removing \the [I]" : ""]") return 1 //Krav Maga Gloves diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index f7852d485695..75c42845ead4 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -126,7 +126,6 @@ var/area/N = V N.layer = overlay_layer N.icon = 'icons/effects/weather_effects.dmi' - N.invisibility = 0 N.color = weather_color switch(stage) if(STARTUP_STAGE) @@ -137,8 +136,7 @@ N.icon_state = end_overlay if(END_STAGE) N.color = null - N.icon_state = initial(N.icon_state) + N.icon_state = "" N.icon = 'icons/turf/areas.dmi' N.layer = AREA_LAYER //Just default back to normal area stuff since I assume setting a var is faster than initial - N.invisibility = INVISIBILITY_MAXIMUM N.set_opacity(FALSE) diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm index 474a365ed991..7da7b86e68f7 100644 --- a/code/datums/wires/robot.dm +++ b/code/datums/wires/robot.dm @@ -34,7 +34,11 @@ var/new_ai = select_active_ai(R) if(new_ai && (new_ai != R.connected_ai)) R.connected_ai = new_ai - R.notify_ai(TRUE) + if(R.shell) + R.undeploy() //If this borg is an AI shell, disconnect the controlling AI and assign ti to a new AI + R.notify_ai(AI_SHELL) + else + R.notify_ai(TRUE) if(WIRE_CAMERA) // Pulse to disable the camera. if(!isnull(R.camera) && !R.scrambledcodes) R.camera.toggle_cam(usr, 0) @@ -56,11 +60,12 @@ if(WIRE_AI) // Cut the AI wire to reset AI control. if(!mend) R.connected_ai = null + R.undeploy() //Forced disconnect of an AI should this body be a shell. if(WIRE_LAWSYNC) // Cut the law wire, and the borg will no longer receive law updates from its AI. Repair and it will re-sync. if(mend) if(!R.emagged) R.lawupdate = TRUE - else + else if(!R.deployed) //AI shells must always have the same laws as the AI R.lawupdate = FALSE if (WIRE_CAMERA) // Disable the camera. if(!isnull(R.camera) && !R.scrambledcodes) diff --git a/code/game/communications.dm b/code/game/communications.dm index d343d694a4ca..b5cb9e06fcee 100644 --- a/code/game/communications.dm +++ b/code/game/communications.dm @@ -134,7 +134,9 @@ var/list/radiochannels = list( "Syndicate" = 1213, "Supply" = 1347, "Service" = 1349, - "AI Private" = 1447 + "AI Private" = 1447, + "Red Team" = 1215, + "Blue Team" = 1217 ) var/list/radiochannelsreverse = list( @@ -148,7 +150,9 @@ var/list/radiochannelsreverse = list( "1213" = "Syndicate", "1347" = "Supply", "1349" = "Service", - "1447" = "AI Private" + "1447" = "AI Private", + "1215" = "Red Team", + "1217" = "Blue Team" ) //depenging helpers @@ -162,6 +166,8 @@ var/const/ENG_FREQ = 1357 //engineering, coloured orange in chat window var/const/SEC_FREQ = 1359 //security, coloured red in chat window var/const/CENTCOM_FREQ = 1337 //centcom frequency, coloured grey in chat window var/const/AIPRIV_FREQ = 1447 //AI private, colored magenta in chat window +var/const/REDTEAM_FREQ = 1215 // red team (CTF) frequency, coloured red +var/const/BLUETEAM_FREQ = 1217 // blue team (CTF) frequency, coloured blue #define TRANSMISSION_WIRE 0 #define TRANSMISSION_RADIO 1 diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index bb1371a85343..6247be218259 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -297,6 +297,28 @@ else holder.icon_state = "hudnobatt" +//borg-AI shell tracking +/mob/living/silicon/robot/proc/diag_hud_set_aishell() //Shows tracking beacons on the mech + var/image/holder = hud_list[DIAG_TRACK_HUD] + var/icon/I = icon(icon, icon_state, dir) + holder.pixel_y = I.Height() - world.icon_size + if(!shell) //Not an AI shell + holder.icon_state = null + else if(deployed) //AI shell in use by an AI + holder.icon_state = "hudtrackingai" + else //Empty AI shell + holder.icon_state = "hudtracking" + +//AI side tracking of AI shell control +/mob/living/silicon/ai/proc/diag_hud_set_deployed() //Shows tracking beacons on the mech + var/image/holder = hud_list[DIAG_TRACK_HUD] + var/icon/I = icon(icon, icon_state, dir) + holder.pixel_y = I.Height() - world.icon_size + if(!deployed_shell) + holder.icon_state = null + else //AI is currently controlling a shell + holder.icon_state = "hudtrackingai" + /*~~~~~~~~~~~~~~~~~~~~ BIG STOMPY MECHS ~~~~~~~~~~~~~~~~~~~~~*/ diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm index 59f0f62c25e0..bc0a05de5735 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm @@ -21,6 +21,7 @@ var/obj/effect/proc_holder/slab/slab_ability //the slab's current bound ability, for certain scripture var/list/quickbound = list(/datum/clockwork_scripture/ranged_ability/geis_prep, /datum/clockwork_scripture/create_object/replicant, \ /datum/clockwork_scripture/create_object/tinkerers_cache) //quickbound scripture, accessed by index + var/maximum_quickbound = 5 //how many quickbound scriptures we can have actions_types = list(/datum/action/item_action/clock/hierophant) /obj/item/clockwork/slab/starter @@ -51,6 +52,7 @@ nonhuman_usable = TRUE quickbound = list(/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard, \ /datum/clockwork_scripture/create_object/tinkerers_cache) + maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more actions_types = list() /obj/item/clockwork/slab/cyborg/engineer //five scriptures, plus a proselytizer @@ -81,7 +83,15 @@ quickbound = list(/datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/channeled/volt_void/cyborg) /obj/item/clockwork/slab/cyborg/access_display(mob/living/user) - to_chat(user, "Use the action buttons to recite your limited set of scripture!") + if(!ratvar_awakens) + to_chat(user, "Use the action buttons to recite your limited set of scripture!") + else + ..() + +/obj/item/clockwork/slab/cyborg/ratvar_act() + ..() + if(!ratvar_awakens) + SStgui.close_uis(src) /obj/item/clockwork/slab/New() ..() @@ -362,11 +372,12 @@ The remaining functions are several buttons in the top left while holding the slab.
From left to right, they are:
\ Hierophant Network, which allows communication to other Servants.
") if(LAZYLEN(quickbound)) - for(var/i in 1 to quickbound.len) - if(!quickbound[i]) - continue - var/datum/clockwork_scripture/quickbind_slot = quickbound[i] - textlist += "A Quickbind slot, currently set to [initial(quickbind_slot.name)].
" + for(var/i in 1 to maximum_quickbound) + if(LAZYLEN(quickbound) < i || !quickbound[i]) + textlist += "A Quickbind slot, currently set to Nothing.
" + else + var/datum/clockwork_scripture/quickbind_slot = quickbound[i] + textlist += "A Quickbind slot, currently set to [initial(quickbind_slot.name)].
" textlist += "
\ Examine the slab or swap to Recital to check the number of components it has available.

\ \ @@ -478,8 +489,8 @@ quickbound[found_index] = null //otherwise, leave it as a null so the scripture maintains position update_quickbind() else - var/target_index = input("Position of [initial(path.name)], 1 to 5?", "Input") as num|null - if(isnum(target_index) && target_index > 0 && target_index < 6 && !..()) + var/target_index = input("Position of [initial(path.name)], 1 to [maximum_quickbound]?", "Input") as num|null + if(isnum(target_index) && target_index > 0 && target_index <= maximum_quickbound && !..()) var/datum/clockwork_scripture/S if(LAZYLEN(quickbound) >= target_index) S = quickbound[target_index] @@ -492,6 +503,9 @@ return while(LAZYLEN(quickbound) < index) quickbound += null + var/datum/clockwork_scripture/quickbind_slot = all_scripture[quickbound[index]] + if(quickbind_slot && !quickbind_slot.quickbind) + return //we can't unbind things we can't normally bind quickbound[index] = scripture update_quickbind() diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_cyborg.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_cyborg.dm index 74bfbc3186c1..13d11b7d8df2 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_cyborg.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_cyborg.dm @@ -49,3 +49,4 @@ /datum/clockwork_scripture/channeled/volt_void/cyborg quickbind_desc = "Allows you to fire energy rays at target locations using your own power. Failing to fire causes backlash.
Maximum 4 chants." tier = SCRIPTURE_PERIPHERAL + quickbind = FALSE diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_judgement.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_judgement.dm index 5a03c3df28c6..b754de9e7340 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_judgement.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_judgement.dm @@ -2,12 +2,12 @@ // JUDGEMENT // /////////////// -//Ark of the Clockwork Justiciar: Creates a Gateway to the Celestial Derelict, either summoning ratvar or proselytizing everything. +//Ark of the Clockwork Justiciar: Creates a Gateway to the Celestial Derelict, summoning ratvar. /datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar descname = "Structure, Win Condition" name = "Ark of the Clockwork Justiciar" desc = "Tears apart a rift in spacetime to Reebe, the Celestial Derelict, using a massive amount of components.\n\ - This gateway will either call forth Ratvar from his exile if that is the task He has set you, or proselytize the entire station if it is not." + This gateway will, after some time, call forth Ratvar from his exile and massively empower all scriptures and tools." invocations = list("ARMORER! FRIGHT! AMPERAGE! VANGUARD! I CALL UPON YOU!!", \ "THE TIME HAS COME FOR OUR MASTER TO BREAK THE CHAINS OF EXILE!!", \ "LEND US YOUR AID! ENGINE COMES!!") diff --git a/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm index 70097c0aa44b..e53b07f95274 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm @@ -19,7 +19,6 @@ var/second_sound_played = FALSE var/third_sound_played = FALSE var/fourth_sound_played = FALSE - var/ratvar_portal = TRUE //if the gateway actually summons ratvar or just produces a hugeass conversion burst var/obj/effect/clockwork/overlay/gateway_glow/glow var/obj/effect/countdown/clockworkgate/countdown var/list/required_components = list(BELLIGERENT_EYE = 7, VANGUARD_COGWHEEL = 7, GEIS_CAPACITOR = 7, REPLICANT_ALLOY = 7, HIEROPHANT_ANSIBLE = 7) @@ -164,7 +163,7 @@ to_chat(user, "[get_component_name(i)][i != REPLICANT_ALLOY ? "s":""]: \ [required_components[i]]") else - to_chat(user, "Seconds until [ratvar_portal ? "Ratvar's arrival":"Proselytization"]: [get_arrival_text(TRUE)]") + to_chat(user, "Seconds until Ratvar's arrival: [get_arrival_text(TRUE)]") switch(progress_in_seconds) if(-INFINITY to GATEWAY_REEBE_FOUND) to_chat(user, "It's still opening.") diff --git a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm index fd482cf8f426..752119c70ca7 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm @@ -15,6 +15,7 @@ var/atom/prey //Whatever Ratvar is chasing var/clashing = FALSE //If Ratvar is FUCKING FIGHTING WITH NAR-SIE var/proselytize_range = 10 + dangerous_possession = TRUE /obj/structure/destructible/clockwork/massive/ratvar/New() ..() diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index a4dda8145f77..1e433403d518 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -336,7 +336,9 @@ var/total_borer_hosts_needed = 10 if(H!=src && Adjacent(H)) choices += H - var/mob/living/carbon/H = input(src,"Who do you wish to infest?") in null|choices + if(!choices.len) + return + var/mob/living/carbon/H = choices.len > 1 ? input(src,"Who do you wish to infest?") in null|choices : choices[1] if(!H || !src) return @@ -464,11 +466,13 @@ var/total_borer_hosts_needed = 10 for(var/mob/living/carbon/C in view(1,src)) if(C.stat == CONSCIOUS) choices += C - - var/mob/living/carbon/M = input(src,"Who do you wish to dominate?") in null|choices + + if(!choices.len) + return + var/mob/living/carbon/M = choices.len > 1 ? input(src,"Who do you wish to dominate?") in null|choices : choices[1] - if(!M || !src) + if(!M || !src || stat != CONSCIOUS || victim || (world.time - used_dominate < 150)) return if(!Adjacent(M)) return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 51575ad37816..a98d181aaabc 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -37,6 +37,9 @@ #define AIRLOCK_DAMAGE_DEFLECTION_N 20 // Normal airlock damage deflection #define AIRLOCK_DAMAGE_DEFLECTION_R 30 // Reinforced airlock damage deflection +#define NOT_ELECTRIFIED 0 +#define ELECTRIFIED_PERMANENT -1 + var/list/airlock_overlays = list() @@ -264,7 +267,7 @@ var/list/airlock_overlays = list() user.Weaken(3) /obj/machinery/door/airlock/proc/isElectrified() - if(src.secondsElectrified != 0) + if(src.secondsElectrified != NOT_ELECTRIFIED) return 1 return 0 @@ -617,10 +620,10 @@ var/list/airlock_overlays = list() if(wires.is_cut(WIRE_SHOCK)) t1 += text("Electrification wire is cut.
\n") - if(src.secondsElectrified==-1) + if(secondsElectrified==ELECTRIFIED_PERMANENT) t1 += text("Door is electrified indefinitely. Un-electrify it?
\n", src) - else if(src.secondsElectrified>0) - t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
\n", src.secondsElectrified, src) + else if(secondsElectrified>NOT_ELECTRIFIED) + t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
\n", secondsElectrified, src) else t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
\n", src, src) @@ -792,9 +795,7 @@ var/list/airlock_overlays = list() //un-electrify door if(wires.is_cut(WIRE_SHOCK)) to_chat(usr, text("Can't un-electrify the airlock - The electrification wire is cut.")) - else if(secondsElectrified==-1) - set_electrified(0) - else if(secondsElectrified>0) + else if(isElectrified()) set_electrified(0) if(8) @@ -871,33 +872,33 @@ var/list/airlock_overlays = list() //electrify door for 30 seconds if(wires.is_cut(WIRE_SHOCK)) to_chat(usr, text("The electrification wire has been cut.
\n")) - else if(src.secondsElectrified==-1) + else if(secondsElectrified==ELECTRIFIED_PERMANENT) to_chat(usr, text("The door is already indefinitely electrified. You'd have to un-electrify it before you can re-electrify it with a non-forever duration.
\n")) - else if(src.secondsElectrified!=0) + else if(isElectrified()) to_chat(usr, text("The door is already electrified. You can't re-electrify it while it's already electrified.
\n")) else shockedby += "\[[time_stamp()]\][usr](ckey:[usr.ckey])" add_logs(usr, src, "electrified") set_electrified(30) spawn(10) - while (src.secondsElectrified>0) - src.secondsElectrified-=1 - if(src.secondsElectrified<0) - set_electrified(0) - src.updateUsrDialog() + while (secondsElectrified > 0) + secondsElectrified-- + if(secondsElectrified <= 0) + set_electrified(NOT_ELECTRIFIED) + updateUsrDialog() sleep(10) if(6) //electrify door indefinitely if(wires.is_cut(WIRE_SHOCK)) to_chat(usr, text("The electrification wire has been cut.
\n")) - else if(src.secondsElectrified==-1) + else if(secondsElectrified==ELECTRIFIED_PERMANENT) to_chat(usr, text("The door is already indefinitely electrified.
\n")) - else if(src.secondsElectrified!=0) + else if(isElectrified()) to_chat(usr, text("The door is already electrified. You can't re-electrify it while it's already electrified.
\n")) else shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])") add_logs(usr, src, "electrified") - set_electrified(-1) + set_electrified(ELECTRIFIED_PERMANENT) if (8) // Not in order >.> // Safeties! Maybe we do need some stinking safeties! @@ -1465,7 +1466,7 @@ var/list/airlock_overlays = list() safe = FALSE //DOOR CRUSH close() bolt() //Bolt it! - set_electrified(-1) //Shock it! + set_electrified(ELECTRIFIED_PERMANENT) //Shock it! if(origin) shockedby += "\[[time_stamp()]\][origin](ckey:[origin.ckey])" @@ -1474,7 +1475,7 @@ var/list/airlock_overlays = list() // Must be powered and have working AI wire. if(canAIControl(src) && !stat) unbolt() - set_electrified(0) + set_electrified(NOT_ELECTRIFIED) open() safe = TRUE @@ -1546,3 +1547,26 @@ var/list/airlock_overlays = list() qdel(src) return TRUE return FALSE + +#undef AIRLOCK_CLOSED +#undef AIRLOCK_CLOSING +#undef AIRLOCK_OPEN +#undef AIRLOCK_OPENING +#undef AIRLOCK_DENY +#undef AIRLOCK_EMAG + +#undef AIRLOCK_SECURITY_NONE +#undef AIRLOCK_SECURITY_METAL +#undef AIRLOCK_SECURITY_PLASTEEL_I_S +#undef AIRLOCK_SECURITY_PLASTEEL_I +#undef AIRLOCK_SECURITY_PLASTEEL_O_S +#undef AIRLOCK_SECURITY_PLASTEEL_O +#undef AIRLOCK_SECURITY_PLASTEEL + +#undef AIRLOCK_INTEGRITY_N +#undef AIRLOCK_INTEGRITY_MULTIPLIER +#undef AIRLOCK_DAMAGE_DEFLECTION_N +#undef AIRLOCK_DAMAGE_DEFLECTION_R + +#undef NOT_ELECTRIFIED +#undef ELECTRIFIED_PERMANENT diff --git a/code/game/machinery/telecomms/broadcasting.dm b/code/game/machinery/telecomms/broadcasting.dm index 7227a393dfc2..94d17a71812f 100644 --- a/code/game/machinery/telecomms/broadcasting.dm +++ b/code/game/machinery/telecomms/broadcasting.dm @@ -107,7 +107,7 @@ else if(data == 5) for(var/obj/item/device/radio/R in all_radios["[freq]"]) - if(!R.centcom) + if(!R.independent) continue if(R.receive_range(freq, level) > -1) @@ -222,8 +222,8 @@ else if(data == 5) for(var/obj/item/device/radio/R in all_radios["[RADIO_CHAT]"]) - if(R.centcom) - receive |= R.send_hear(CENTCOM_FREQ) + if(R.independent) + receive |= R.send_hear(display_freq) // --- Broadcast to ALL radio devices --- diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index cd4cd2185c94..bcf76a7c650d 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -110,7 +110,7 @@ sleep(30) if(R) R.SetLockdown(0) - R.notify_ai(1) + R.notify_ai(NEW_BORG) /obj/machinery/transformer/conveyor/New() ..() diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 81e71a837ee6..3e2ae9adbcd0 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -36,7 +36,7 @@ var/explosionid = 1 var/list/cached_exp_block = list() if(adminlog) - message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z] - JMP)") + message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]") log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])") // Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves. diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index 3cc80ae07544..cb67eaa33512 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -1,4 +1,3 @@ - /obj/item/device/encryptionkey name = "standard encryption key" desc = "An encryption key for a radio headset. Has no special codes in it. WHY DOES IT EXIST? ASK NANOTRASEN." @@ -8,7 +7,7 @@ origin_tech = "engineering=2;bluespace=1" var/translate_binary = 0 var/syndie = 0 - var/centcom = 0 + var/independent = FALSE var/list/channels = list() /obj/item/device/encryptionkey/syndicate @@ -126,7 +125,7 @@ name = "centcom radio encryption key" desc = "An encryption key for a radio headset. To access the centcom channel, use :y." icon_state = "cent_cypherkey" - centcom = 1 + independent = TRUE channels = list("Centcom" = 1) /obj/item/device/encryptionkey/ai //ported from NT, this goes 'inside' the AI. diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index faa45a7e55fa..5beedc184924 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -291,8 +291,8 @@ if(keyslot2.syndie) src.syndie = 1 - if (keyslot2.centcom) - centcom = 1 + if (keyslot2.independent) + independent = TRUE for(var/ch_name in channels) @@ -305,4 +305,4 @@ return if (command) use_command = !use_command - to_chat(user, "You toggle high-volume mode [use_command ? "on" : "off"].") \ No newline at end of file + to_chat(user, "You toggle high-volume mode [use_command ? "on" : "off"].") diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index f1dae84113d4..a5dfc478ae6d 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -23,7 +23,7 @@ var/subspace_switchable = 0 var/subspace_transmission = 0 var/syndie = 0//Holder to see if it's a syndicate encrpyed radio - var/centcom = 0//Bleh, more dirty booleans + var/independent = FALSE // If true, bypasses any tcomms machinery. var/freqlock = 0 //Frequency lock to stop the user from untuning specialist radios. var/emped = 0 //Highjacked to track the number of consecutive EMPs on the radio, allowing consecutive EMP's to stack properly. // "Example" = FREQ_LISTENING|FREQ_BROADCASTING @@ -58,7 +58,7 @@ channels = list() translate_binary = 0 syndie = 0 - centcom = 0 + independent = FALSE if(keyslot) for(var/ch_name in keyslot.channels) @@ -73,8 +73,8 @@ if(keyslot.syndie) syndie = 1 - if(keyslot.centcom) - centcom = 1 + if(keyslot.independent) + independent = TRUE for(var/ch_name in channels) secure_radio_connections[ch_name] = add_radio(src, radiochannels[ch_name]) @@ -299,9 +299,9 @@ else jobname = "Unknown" - /* ###### Centcom channel bypasses all comms relays. ###### */ + /* ###### `independent` radios bypass all comms relays. ###### */ - if (freqnum == CENTCOM_FREQ && centcom) + if(independent) var/datum/signal/signal = new signal.transmission_method = 2 signal.data = list( @@ -478,7 +478,7 @@ if(!(src.syndie)) //Checks to see if it's allowed on that frequency, based on the encryption keys return -1 if(freq == CENTCOM_FREQ) - if (!(src.centcom)) + if(!independent) return -1 if (!on) return -1 diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 03c66d02814b..359f2f0c33db 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -206,7 +206,7 @@ lawsync = 0 O.connected_ai = null else - O.notify_ai(1) + O.notify_ai(NEW_BORG) if(forced_ai) O.connected_ai = forced_ai if(!lawsync) @@ -248,6 +248,41 @@ else to_chat(user, "The MMI must go in after everything else!") + else if(istype(W, /obj/item/borg/upgrade/ai)) + var/obj/item/borg/upgrade/ai/M = W + if(check_completion()) + if(!isturf(loc)) + to_chat(user, "You cannot install[M], the frame has to be standing on the ground to be perfectly precise!") + return + if(!user.drop_item()) + to_chat(user, "[M] is stuck to your hand!") + return + qdel(M) + var/mob/living/silicon/robot/O = new /mob/living/silicon/robot/shell(get_turf(src)) + + if(!aisync) + lawsync = FALSE + O.connected_ai = null + else + if(forced_ai) + O.connected_ai = forced_ai + O.notify_ai(AI_SHELL) + if(!lawsync) + O.lawupdate = FALSE + O.make_laws() + + + O.cell = chest.cell + chest.cell.loc = O + chest.cell = null + O.locked = panel_locked + O.job = "Cyborg" + forceMove(O) + O.robot_suit = src + if(!locomotion) + O.lockcharge = TRUE + O.update_canmove() + else if(istype(W,/obj/item/weapon/pen)) to_chat(user, "You need to use a multitool to name [src]!") else diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 156ad4ed5706..5e2495a7b9b8 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -43,7 +43,7 @@ R.custom_name = heldname R.updatename() if(oldname == R.real_name) - R.notify_ai(3, oldname, R.real_name) + R.notify_ai(RENAME, oldname, R.real_name) return 1 @@ -381,3 +381,22 @@ R.module.add_module(S, FALSE, TRUE) return 1 + +/obj/item/borg/upgrade/ai + name = "B.O.R.I.S. module" + desc = "Bluespace Optimized Remote Intelligence Synchronization. An uplink device which takes the place of an MMI in cyborg endoskeletons, creating a robotic shell controlled by an AI." + icon_state = "boris" + origin_tech = "engineering=4;magnets=4;programming=4" + +/obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/R) + if(..()) + return + if(R.shell) + to_chat(usr, "This unit is already an AI shell!") + return + if(R.key) //You cannot replace a player unless the key is completely removed. + to_chat(usr, "Intelligence patterns detected in this [R.braintype]. Aborting.") + return + + R.make_shell(src) + return TRUE \ No newline at end of file diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index a88c13415fbb..61eb42d6ca48 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -46,7 +46,7 @@ var/global/list/datum/stack_recipe/sandstone_recipes = list ( \ materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) sheettype = "sandstone" -/obj/item/stack/sheet/mineral/sandstone/New(var/loc, var/amount=null) +/obj/item/stack/sheet/mineral/sandstone/Initialize(mapload, new_amount, merge = TRUE) recipes = sandstone_recipes pixel_x = rand(0,4)-4 pixel_y = rand(0,4)-4 diff --git a/code/game/objects/items/stacks/tiles/light.dm b/code/game/objects/items/stacks/tiles/light.dm index 682060e0b6a1..3e9117cbdfb0 100644 --- a/code/game/objects/items/stacks/tiles/light.dm +++ b/code/game/objects/items/stacks/tiles/light.dm @@ -8,7 +8,7 @@ turf_type = /turf/open/floor/light var/state = 0 -/obj/item/stack/tile/light/New(var/loc, var/amount=null) +/obj/item/stack/tile/light/Initialize(mapload, new_amount, merge = TRUE) ..() if(prob(5)) state = 3 //broken diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index 0802656f8a15..47d561eb8ae3 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -19,6 +19,8 @@ qdel(src) /obj/item/weapon/grenade/flashbang/proc/bang(turf/T , mob/living/M) + if(M.stat == DEAD) //They're dead! + return M.show_message("BANG", 2) playsound(loc, 'sound/weapons/flashbang.ogg', 100, 1) var/distance = max(0,get_dist(get_turf(src),T)) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 9548e2a9920c..ec3b418a4adf 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -25,7 +25,18 @@ var/persistence_replacement = null //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset. var/unique_rename = 0 // can you customize the description/name of the thing? + + var/dangerous_possession = FALSE //Admin possession yes/no +/obj/vv_edit_var(vname, vval) + switch(vname) + if("dangerous_possession") + return FALSE + if("control_object") + var/obj/O = vval + if(istype(O) && O.dangerous_possession) + return FALSE + ..() /obj/Initialize() ..() diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 707702d9a70b..880fbec68606 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -299,6 +299,11 @@ icon = "thenet" desc = "You just seem to get caught up in it for hours." +/datum/barsign/maidcafe + name = "Maid Cafe" + icon = "maidcafe" + desc = "Welcome back, master!" + /datum/barsign/hiddensigns hidden = 1 diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index a21757828cab..e589ec167af7 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -131,6 +131,8 @@ max_integrity = 70 horizontal = TRUE delivery_icon = "deliverycrate" + material_drop = /obj/item/stack/sheet/mineral/wood + material_drop_amount = 5 /obj/structure/closet/wardrobe/red name = "security wardrobe" diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 9345367afc02..e5ba388435d0 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -207,7 +207,7 @@ playsound(src.loc, I.usesound, 50, 1) if(do_after(user, 30*I.toolspeed, target = src)) playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - new /obj/item/stack/sheet/mineral/wood(get_turf(src)) + new /obj/item/stack/sheet/mineral/wood(get_turf(src), 5) qdel(src) else if(istype(I, /obj/item/weapon/electronics/airlock)) diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index fc221ea968da..46d6c9dab13a 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -339,7 +339,7 @@ /obj/structure/flora/rock/jungle icon_state = "pile of rocks" desc = "A pile of rocks." - icon_state = "rocks" + icon_state = "rock" icon = 'icons/obj/flora/jungleflora.dmi' density = FALSE @@ -380,6 +380,6 @@ pixel_x = -16 pixel_y = -16 -/obj/structure/flora/rock/jungle/Initialize() +/obj/structure/flora/rock/pile/largejungle/Initialize() ..() icon_state = "[initial(icon_state)][rand(1,3)]" \ No newline at end of file diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 378f5030bf15..ceeb7b41a645 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -109,7 +109,7 @@ /obj/effect/mob_spawn/human/golem/New(loc, datum/species/golem/species = null, has_owner = FALSE, mob/creator = null) ..() if(species) - name += " ([initial(species.id)])" + name += " ([initial(species.prefix)])" mob_species = species var/area/A = get_area(src) if(A) @@ -120,26 +120,7 @@ owner = creator /obj/effect/mob_spawn/human/golem/special(mob/living/new_spawn) - var/golem_surname = pick(golem_names) - // 3% chance that our golem has a human surname, because - // cultural contamination - if(prob(3)) - golem_surname = pick(last_names) - var/datum/species/golem/X = mob_species - var/golem_forename = initial(X.id) - - // The id of golem species is either their material "diamond","gold", - // or just "golem" for the plain ones. So we're using it for naming. - - if(golem_forename == "golem") - golem_forename = "iron" - - new_spawn.real_name = "[capitalize(golem_forename)] [golem_surname]" - // This means golems have names like Iron Forge, or Diamond Quarry - // also a tiny chance of being called "Plasma Meme" - // which is clearly a feature - to_chat(new_spawn, "[initial(X.info_text)]") if(!owner) to_chat(new_spawn, "Build golem shells in the autolathe, and feed refined mineral sheets to the shells to bring them to life! You are generally a peaceful group unless provoked.") @@ -151,6 +132,7 @@ if(ishuman(new_spawn)) var/mob/living/carbon/human/H = new_spawn H.set_cloned_appearance() + H.real_name = H.dna.species.random_name() /obj/effect/mob_spawn/human/golem/adamantine name = "dust-caked golem shell" diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 3138c7cbcc65..7b4d3f626998 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -42,7 +42,7 @@ /obj/structure/lattice/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) - new /obj/item/stack/rods(get_turf(src), amount=number_of_rods) + new /obj/item/stack/rods(get_turf(src), number_of_rods) qdel(src) /obj/structure/lattice/singularity_pull(S, current_size) diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index a6a52ac39036..7f80a1c9b8b8 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -147,6 +147,7 @@ FLOOR SAFES if(open) if(P && in_range(src, user)) user.put_in_hands(P) + space -= P.w_class updateUsrDialog() diff --git a/code/game/say.dm b/code/game/say.dm index 172bfc0fd3c3..1366cf7435bf 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -13,7 +13,9 @@ var/list/freqtospan = list( "1353" = "comradio", "1447" = "aiprivradio", "1213" = "syndradio", - "1337" = "centcomradio" + "1337" = "centcomradio", + "1215" = "redteamradio", + "1217" = "blueteamradio" ) /atom/movable/proc/say(message) diff --git a/code/game/sound.dm b/code/game/sound.dm index 5d655b7ba4b3..793cb6d54ade 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -1,4 +1,4 @@ -/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, surround = 1, frequency = null) +/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, surround = 1, frequency = null, channel = 0) soundin = get_sfx(soundin) // same sound for everyone @@ -18,15 +18,15 @@ if(get_dist(M, turf_source) <= world.view + extrarange) var/turf/T = get_turf(M) if(T && T.z == turf_source.z) - M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, surround) + M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, surround, channel) -/atom/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, surround = 1) +/atom/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, surround = 1, channel = 0) soundin = get_sfx(soundin) var/sound/S = sound(soundin) S.wait = 0 //No queue - S.channel = 0 //Any channel + S.channel = channel S.volume = vol if (vary) @@ -79,14 +79,14 @@ return ..() -/mob/proc/stopLobbySound() - src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) +/mob/proc/stop_sound_channel(chan) + src << sound(null, repeat = 0, wait = 0, channel = chan) /client/proc/playtitlemusic() UNTIL(SSticker.login_music) //wait for SSticker init to set the login music if(prefs && (prefs.toggles & SOUND_LOBBY)) - src << sound(SSticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS + src << sound(SSticker.login_music, repeat = 0, wait = 0, volume = 85, channel = CHANNEL_LOBBYMUSIC) // MAD JAMS /proc/get_rand_frequency() return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 36be260a8ee5..98b4b733fd32 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -219,11 +219,14 @@ return if(!use_preloader && path == type) // Don't no-op if the map loader requires it to be reconstructed return src - + + var/old_baseturf = baseturf changing_turf = TRUE qdel(src) //Just get the side effects and call Destroy var/turf/W = new path(src) + W.baseturf = old_baseturf + if(!defer_change) W.AfterChange(ignore_air) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 824e0b1a8a96..6433f127aebc 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -64,7 +64,6 @@ var/list/admin_verbs_admin = list( /client/proc/toggle_AI_interact, /*toggle admin ability to interact with machines as an AI*/ /client/proc/customiseSNPC, /* Customise any interactive crewmembers in the world */ /client/proc/resetSNPC, /* Resets any interactive crewmembers in the world */ - /client/proc/toggleSNPC, /* Toggles an npc's processing mode */ /client/proc/open_shuttle_manipulator /* Opens shuttle manipulator UI */ ) var/list/admin_verbs_ban = list( @@ -239,7 +238,6 @@ var/list/admin_verbs_hideable = list( /client/proc/debug_huds, /client/proc/customiseSNPC, /client/proc/resetSNPC, - /client/proc/toggleSNPC ) /client/proc/add_admin_verbs() diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index 4f1ccafc0e07..8afc0fdca8de 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -2,10 +2,9 @@ set name = "Possess Obj" set category = "Object" - if(istype(O,/obj/singularity)) - if(config.forbid_singulo_possession) - to_chat(usr, "It is forbidden to possess singularities.") - return + if(O.dangerous_possession && config.forbid_singulo_possession) + to_chat(usr, "[O] is too powerful for you to possess.") + return var/turf/T = get_turf(O) @@ -50,4 +49,4 @@ set name = "Give Possessing Verbs" M.verbs += /proc/possess M.verbs += /proc/release - feedback_add_details("admin_verb","GPV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! \ No newline at end of file + feedback_add_details("admin_verb","GPV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm index 07b05ef565bb..dddcf3ac4806 100644 --- a/code/modules/assembly/health.dm +++ b/code/modules/assembly/health.dm @@ -11,7 +11,9 @@ var/health_scan var/alarm_health = 0 - +/obj/item/device/assembly/health/examine(mob/user) + ..() + to_chat(user, "Use a multitool to swap between \"detect death\" mode and \"detect critical state\" mode.") /obj/item/device/assembly/health/activate() if(!..()) diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 9572553f16d5..f7c3cbf93018 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -17,6 +17,10 @@ "recognizer", "voice sensor") +/obj/item/device/assembly/voice/examine(mob/user) + ..() + to_chat(user, "Use a multitool to swap between \"inclusive\", \"exclusive\", \"recognizer\", and \"voice sensor\" mode.") + /obj/item/device/assembly/voice/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) if(speaker == src) return diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 54f1c06252ae..5660ea616543 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -1,5 +1,3 @@ -#define CAN_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE * 10) -#define CAN_MIN_RELEASE_PRESSURE (ONE_ATMOSPHERE / 10) #define CAN_DEFAULT_RELEASE_PRESSURE (ONE_ATMOSPHERE) /obj/machinery/portable_atmospherics/canister @@ -16,6 +14,8 @@ var/filled = 0.5 var/gas_type = "" var/release_pressure = ONE_ATMOSPHERE + var/can_max_release_pressure = (ONE_ATMOSPHERE * 10) + var/can_min_release_pressure = (ONE_ATMOSPHERE / 10) armor = list(melee = 50, bullet = 50, laser = 50, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 80, acid = 50) obj_integrity = 250 @@ -24,6 +24,16 @@ pressure_resistance = 7 * ONE_ATMOSPHERE var/temperature_resistance = 1000 + T0C var/starter_temp + // Prototype vars + var/prototype = FALSE + var/valve_timer = null + var/timer_set = 30 + var/default_timer_set = 30 + var/minimum_timer_set = 1 + var/maximum_timer_set = 300 + var/timing = FALSE + var/restricted = FALSE + req_access = list() var/update = 0 var/static/list/label2types = list( @@ -39,6 +49,13 @@ "caution" = /obj/machinery/portable_atmospherics/canister, ) +/obj/machinery/portable_atmospherics/canister/interact(mob/user) + if(!allowed(user)) + to_chat(user, "Error - Unauthorized User") + playsound(src, 'sound/misc/compiler-failure.ogg', 50, 1) + return + ..() + /obj/machinery/portable_atmospherics/canister/nitrogen name = "n2 canister" desc = "Nitrogen gas. Reportedly useful for something." @@ -99,6 +116,46 @@ gas_type = "water_vapor" filled = 1 +/obj/machinery/portable_atmospherics/canister/proc/get_time_left() + if(timing) + . = round(max(0, valve_timer - world.time) / 10, 1) + else + . = timer_set + +/obj/machinery/portable_atmospherics/canister/proc/set_active() + timing = !timing + if(timing) + valve_timer = world.time + (timer_set * 10) + update_icon() + +/obj/machinery/portable_atmospherics/canister/proto + name = "prototype canister" + + +/obj/machinery/portable_atmospherics/canister/proto/default + name = "prototype canister" + desc = "The best way to fix an atmospheric emergency... or the best way to introduce one." + icon_state = "proto" + icon_state = "proto" + volume = 5000 + obj_integrity = 300 + max_integrity = 300 + temperature_resistance = 2000 + T0C + can_max_release_pressure = (ONE_ATMOSPHERE * 30) + can_min_release_pressure = (ONE_ATMOSPHERE / 30) + prototype = TRUE + + +/obj/machinery/portable_atmospherics/canister/proto/default/oxygen + name = "prototype canister" + desc = "A prototype canister for a prototype bike, what could go wrong?" + icon_state = "proto" + gas_type = "o2" + filled = 1 + release_pressure = ONE_ATMOSPHERE*2 + + + /obj/machinery/portable_atmospherics/canister/New(loc, datum/gas_mixture/existing_mixture) ..() if(existing_mixture) @@ -239,6 +296,9 @@ ..() if(stat & BROKEN) return PROCESS_KILL + if(timing && valve_timer < world.time) + valve_open = !valve_open + timing = FALSE if(!valve_open) pump.AIR1 = null pump.AIR2 = null @@ -267,10 +327,20 @@ data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) data["releasePressure"] = round(release_pressure ? release_pressure : 0) data["defaultReleasePressure"] = round(CAN_DEFAULT_RELEASE_PRESSURE) - data["minReleasePressure"] = round(CAN_MIN_RELEASE_PRESSURE) - data["maxReleasePressure"] = round(CAN_MAX_RELEASE_PRESSURE) + data["minReleasePressure"] = round(can_min_release_pressure) + data["maxReleasePressure"] = round(can_max_release_pressure) data["valveOpen"] = valve_open ? 1 : 0 + data["isPrototype"] = prototype ? 1 : 0 + if (prototype) + data["restricted"] = restricted + data["timing"] = timing + data["time_left"] = get_time_left() + data["timer_set"] = timer_set + data["timer_is_not_default"] = timer_set != default_timer_set + data["timer_is_not_min"] = timer_set != minimum_timer_set + data["timer_is_not_max"] = timer_set != maximum_timer_set + data["hasHoldingTank"] = holding ? 1 : 0 if (holding) data["holdingTank"] = list() @@ -287,32 +357,37 @@ if(label && !..()) var/newtype = label2types[label] if(newtype) - var/obj/machinery/portable_atmospherics/canister/replacement = new newtype(loc, air_contents) - if(connected_port) - replacement.connected_port = connected_port - replacement.connected_port.connected_device = replacement - replacement.interact(usr) - qdel(src) + var/obj/machinery/portable_atmospherics/canister/replacement = newtype + name = initial(replacement.name) + desc = initial(replacement.name) + icon_state = initial(replacement.icon_state) + if("restricted") + restricted = !restricted + if(restricted) + req_access = list(access_engine) + else + req_access = list() + . = TRUE if("pressure") var/pressure = params["pressure"] if(pressure == "reset") pressure = CAN_DEFAULT_RELEASE_PRESSURE . = TRUE else if(pressure == "min") - pressure = CAN_MIN_RELEASE_PRESSURE + pressure = can_min_release_pressure . = TRUE else if(pressure == "max") - pressure = CAN_MAX_RELEASE_PRESSURE + pressure = can_max_release_pressure . = TRUE else if(pressure == "input") - pressure = input("New release pressure ([CAN_MIN_RELEASE_PRESSURE]-[CAN_MAX_RELEASE_PRESSURE] kPa):", name, release_pressure) as num|null + pressure = input("New release pressure ([can_min_release_pressure]-[can_max_release_pressure] kPa):", name, release_pressure) as num|null if(!isnull(pressure) && !..()) . = TRUE else if(text2num(pressure) != null) pressure = text2num(pressure) . = TRUE if(.) - release_pressure = Clamp(round(pressure), CAN_MIN_RELEASE_PRESSURE, CAN_MAX_RELEASE_PRESSURE) + release_pressure = Clamp(round(pressure), can_min_release_pressure, can_max_release_pressure) investigate_log("was set to [release_pressure] kPa by [key_name(usr)].", "atmos") if("valve") var/logmsg @@ -344,11 +419,34 @@ investigate_log(logmsg, "atmos") release_log += logmsg . = TRUE + if("timer") + var/change = params["change"] + switch(change) + if("reset") + timer_set = default_timer_set + if("decrease") + timer_set = max(minimum_timer_set, timer_set - 10) + if("increase") + timer_set = min(maximum_timer_set, timer_set + 10) + if("input") + var/user_input = input(usr, "Set time to valve toggle.", name) as null|num + if(!user_input) + return + var/N = text2num(user_input) + if(!N) + return + timer_set = Clamp(N,minimum_timer_set,maximum_timer_set) + log_admin("[key_name(usr)] has activated a prototype valve timer") + . = TRUE + if("toggle_timer") + set_active() if("eject") if(holding) if(valve_open) investigate_log("[key_name(usr)] removed the [holding], leaving the valve open and transfering into the air
", "atmos") - holding.loc = get_turf(src) + holding.forceMove(get_turf(src)) holding = null . = TRUE update_icon() + + diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index 814aa2fdeb95..2a3d7a8c6121 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -145,11 +145,10 @@ var/ctf_gear = /datum/outfit/ctf var/instagib_gear = /datum/outfit/ctf/instagib - var/list/obj/effect/ctf/dead_barricade/dead_barricades = list() - var/list/obj/structure/barricade/security/ctf/living_barricades = list() + var/list/dead_barricades = list() var/static/ctf_object_typecache - var/static/arena_cleared = FALSE + var/static/arena_reset = FALSE /obj/machinery/capture_the_flag/Initialize() ..() @@ -289,7 +288,7 @@ CTF.control_points = 0 CTF.ctf_enabled = FALSE CTF.team_members = list() - CTF.arena_cleared = FALSE + CTF.arena_reset = FALSE addtimer(CALLBACK(CTF, .proc/start_ctf), 300) /obj/machinery/capture_the_flag/proc/toggle_ctf() @@ -308,25 +307,24 @@ dead_barricades.Cut() - for(var/b in living_barricades) - var/obj/structure/barricade/security/ctf/B = b - B.obj_integrity = B.max_integrity - notify_ghosts("[name] has been activated!", enter_link="(Click to join the [team] team!) or click on the controller directly!", source = src, action=NOTIFY_ATTACK) - if(!arena_cleared) - clear_the_arena() - arena_cleared = TRUE + if(!arena_reset) + reset_the_arena() + arena_reset = TRUE -/obj/machinery/capture_the_flag/proc/clear_the_arena() +/obj/machinery/capture_the_flag/proc/reset_the_arena() var/area/A = get_area(src) for(var/atm in A) if(!is_type_in_typecache(atm, ctf_object_typecache)) qdel(atm) + if(istype(atm, /obj/structure)) + var/obj/structure/S = atm + S.obj_integrity = S.max_integrity /obj/machinery/capture_the_flag/proc/stop_ctf() ctf_enabled = FALSE - arena_cleared = FALSE + arena_reset = FALSE var/area/A = get_area(src) for(var/i in mob_list) var/mob/M = i @@ -433,6 +431,7 @@ /obj/item/projectile/beam/ctf/red icon_state = "laser" + impact_effect_type = /obj/effect/overlay/temp/impact_effect/red_laser // BLUE TEAM GUNS @@ -447,6 +446,7 @@ /obj/item/projectile/beam/ctf/blue icon_state = "bluelaser" + impact_effect_type = /obj/effect/overlay/temp/impact_effect/blue_laser /datum/outfit/ctf name = "CTF" @@ -485,7 +485,6 @@ shoes = /obj/item/clothing/shoes/jackboots/fast /datum/outfit/ctf/red - ears = /obj/item/device/radio/headset/syndicate/alt suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red r_hand = /obj/item/weapon/gun/ballistic/automatic/laser/ctf/red l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/red @@ -496,7 +495,6 @@ shoes = /obj/item/clothing/shoes/jackboots/fast /datum/outfit/ctf/blue - ears = /obj/item/device/radio/headset/headset_cent/commander suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/blue r_hand = /obj/item/weapon/gun/ballistic/automatic/laser/ctf/blue l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/blue @@ -509,14 +507,16 @@ /datum/outfit/ctf/red/post_equip(mob/living/carbon/human/H) ..() var/obj/item/device/radio/R = H.ears - R.set_frequency(SYND_FREQ) - R.freqlock = 1 + R.set_frequency(REDTEAM_FREQ) + R.freqlock = TRUE + R.independent = TRUE /datum/outfit/ctf/blue/post_equip(mob/living/carbon/human/H) ..() var/obj/item/device/radio/R = H.ears - R.set_frequency(CENTCOM_FREQ) - R.freqlock = 1 + R.set_frequency(BLUETEAM_FREQ) + R.freqlock = TRUE + R.independent = TRUE @@ -552,16 +552,6 @@ deploy_time = 0 deploy_message = 0 -/obj/structure/barricade/security/ctf/Initialize(mapload) - ..() - for(var/obj/machinery/capture_the_flag/CTF in machines) - CTF.living_barricades += src - -/obj/structure/barricade/security/ctf/Destroy() - for(var/obj/machinery/capture_the_flag/CTF in machines) - CTF.living_barricades -= src - . = ..() - /obj/structure/barricade/security/ctf/make_debris() new /obj/effect/ctf/dead_barricade(get_turf(src)) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 2d27c2914157..f5b37f8601a7 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1181,10 +1181,10 @@ var/list/preferences_datums = list() if("lobby_music") toggles ^= SOUND_LOBBY - if(toggles & SOUND_LOBBY) - user << sound(SSticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1) + if((toggles & SOUND_LOBBY) && user.client) + user.client.playtitlemusic() else - user.stopLobbySound() + user.stop_sound_channel(CHANNEL_LOBBYMUSIC) if("ghost_ears") chat_toggles ^= CHAT_GHOSTEARS diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 963da2563306..8a82649d6b74 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -147,8 +147,7 @@ playtitlemusic() else to_chat(src, "You will no longer hear music in the game lobby.") - if(isnewplayer(mob)) - mob.stopLobbySound() + mob.stop_sound_channel(CHANNEL_LOBBYMUSIC) feedback_add_details("admin_verb","TLobby") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/verb/togglemidis() diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 54d158386c50..79435974149d 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -423,6 +423,7 @@ var/list/ammo_copy_vars var/list/gun_copy_vars var/badmin_mode = FALSE + var/static/list/blacklisted_vars = list("locs", "loc", "contents", "x", "y", "z") /obj/item/weapon/gun/energy/laser/chameleon/New() ..() @@ -440,6 +441,7 @@ chameleon_gun_vars = list() ammo_copy_vars = list("firing_effect_type") chameleon_ammo_vars = list() + recharge_newshot() get_chameleon_projectile(/obj/item/weapon/gun/energy/laser) /obj/item/weapon/gun/energy/laser/chameleon/emp_act(severity) @@ -449,13 +451,18 @@ chameleon_ammo_vars = list() chameleon_gun_vars = list() chameleon_projectile_vars = list() - for(var/V in chambered.vars) - chambered.vars[V] = initial(chambered.vars[V]) - qdel(chambered.BB) + if(chambered) + for(var/v in ammo_copy_vars) + if(v in blacklisted_vars) //Just in case admins go crazy. + continue + chambered.vars[v] = initial(chambered.vars[v]) + for(var/v in gun_copy_vars) + if(v in blacklisted_vars) + continue + vars[v] = initial(vars[v]) + if(chambered.BB) + qdel(chambered.BB) chambered.newshot() - for(var/V in vars) - vars[V] = initial(vars[V]) - /obj/item/weapon/gun/energy/laser/chameleon/proc/set_chameleon_ammo(obj/item/ammo_casing/AC, passthrough = TRUE, reset = FALSE) if(!istype(AC)) @@ -464,7 +471,7 @@ for(var/V in ammo_copy_vars) if(AC.vars[V]) chameleon_ammo_vars[V] = AC.vars[V] - if(chambered.vars[V]) + if(chambered && chambered.vars[V]) chambered.vars[V] = AC.vars[V] if(passthrough) var/obj/item/projectile/P = AC.BB diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index 0ec4ee43a9a1..20de61d33dea 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -99,16 +99,16 @@ insert ascii eagle on american flag background here reagents.trans_to(S, 2*(cook_time/15)) switch(cook_time) if(0 to 15) - S.color = rgb(166,103,54) + S.add_atom_colour(rgb(166,103,54), FIXED_COLOUR_PRIORITY) S.name = "lightly-fried [frying.name]" if(16 to 49) - S.color = rgb(103,63,24) + S.add_atom_colour(rgb(103,63,24), FIXED_COLOUR_PRIORITY) S.name = "fried [frying.name]" if(50 to 59) - S.color = rgb(63, 23, 4) + S.add_atom_colour(rgb(63,23,4), FIXED_COLOUR_PRIORITY) S.name = "deep-fried [frying.name]" if(60 to INFINITY) - S.color = rgb(33,19,9) + S.add_atom_colour(rgb(33,19,9), FIXED_COLOUR_PRIORITY) S.name = "the physical manifestation of the very concept of fried foods" S.desc = "A heavily fried...something. Who can tell anymore?" S.filling_color = S.color diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm index 13ee19982cac..55055f8b0c9a 100644 --- a/code/modules/holiday/holidays.dm +++ b/code/modules/holiday/holidays.dm @@ -146,7 +146,6 @@ SSticker.login_music = 'sound/ambience/clown.ogg' for(var/mob/dead/new_player/P in mob_list) if(P.client) - P.stopLobbySound() P.client.playtitlemusic() /datum/holiday/fourtwenty diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 49b5a7a77106..2928857f2bbd 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -232,7 +232,7 @@ if(!(text2path(href_list["release"]) in stack_list)) return var/obj/item/stack/sheet/inp = stack_list[text2path(href_list["release"])] - var/obj/item/stack/sheet/out = new inp.type(src,merge=FALSE) + var/obj/item/stack/sheet/out = new inp.type(src, 0, FALSE) var/desired = input("How many sheets?", "How many sheets to eject?", 1) as null|num out.amount = round(min(desired,50,inp.amount)) if(out.amount) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 62ed31816e71..1e26185d9f30 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -141,7 +141,7 @@ observer.real_name = observer.client.prefs.real_name observer.name = observer.real_name observer.update_icon() - observer.stopLobbySound() + observer.stop_sound_channel(CHANNEL_LOBBYMUSIC) qdel(mind) qdel(src) @@ -471,7 +471,7 @@ . = new_character if(.) new_character.key = key //Manually transfer the key to log them in - new_character.stopLobbySound() + new_character.stop_sound_channel(CHANNEL_LOBBYMUSIC) /mob/dead/new_player/proc/ViewManifest() var/dat = "" diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index c4584d01dd81..3f97d92e628b 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -145,8 +145,8 @@ parts -= picked if(updating_health) updatehealth() - if(update) - update_damage_overlays() + if(update) + update_damage_overlays() // damage MANY bodyparts, in random order /mob/living/carbon/take_overall_damage(brute, burn, updating_health = 1) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index edf76b61293a..7fe75dcd96cb 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -50,4 +50,4 @@ var/global/default_martial_art = new/datum/martial_art var/datum/personal_crafting/handcrafting can_buckle = TRUE buckle_lying = FALSE - can_ride_typecache = list(/mob/living/carbon/human, /mob/living/simple_animal/slime) + can_ride_typecache = list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot) diff --git a/code/modules/mob/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm similarity index 96% rename from code/modules/mob/interactive.dm rename to code/modules/mob/living/carbon/human/interactive.dm index ad76749ec84e..5e9c38562ae8 100644 --- a/code/modules/mob/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive.dm @@ -67,10 +67,7 @@ //modules var/list/functions = list("nearbyscan","combat","shitcurity","chatter") var/restrictedJob = 0 - var/shouldUseDynamicProc = 0 // switch to make the AI control it's own proccessing - var/alternateProcessing = 1 var/forceProcess = 0 - var/processTime = 8 var/lastProc = 0 var/walkdebug = 0 //causes sparks in our path target. used for debugging var/debugexamine = 0 //If we show debug info in our examine @@ -85,6 +82,7 @@ var/traitorScale = 0 // our ability as a traitor var/traitorType = 0 + var/voice_saved = FALSE /// SNPC voice handling @@ -96,6 +94,8 @@ knownStrings = list() /mob/living/carbon/human/interactive/proc/saveVoice() + if(voice_saved) + return var/savefile/S = new /savefile("data/npc_saves/snpc.sav") S["knownStrings"] << knownStrings @@ -145,8 +145,7 @@ retal_target = potentialAssault ..() - -/client/proc/resetSNPC(var/mob/A in SSnpcpool.botPool_l) +/client/proc/resetSNPC(var/mob/A in SSnpcpool.processing) set name = "Reset SNPC" set desc = "Reset the SNPC" set category = "Debug" @@ -163,24 +162,7 @@ T.retal = 0 T.doing = 0 -/client/proc/toggleSNPC(var/mob/A in SSnpcpool.botPool_l) - set name = "Toggle SNPC Proccessing Mode" - set desc = "Toggle SNPC Proccessing Mode" - set category = "Debug" - - if(!holder) - return - - if(A) - if(!istype(A,/mob/living/carbon/human/interactive)) - return - var/mob/living/carbon/human/interactive/T = A - if(T) - T.alternateProcessing = !T.alternateProcessing - T.forceProcess = 1 - to_chat(usr, "[T]'s processing has been switched to [T.alternateProcessing ? "High Profile" : "Low Profile"]") - -/client/proc/customiseSNPC(var/mob/A in SSnpcpool.botPool_l) +/client/proc/customiseSNPC(var/mob/A in SSnpcpool.processing) set name = "Customize SNPC" set desc = "Customise the SNPC" set category = "Debug" @@ -390,7 +372,7 @@ doSetup() - SSnpcpool.insertBot(src) + START_PROCESSING(SSnpcpool, src) loadVoice() @@ -400,8 +382,9 @@ attitude += rand(-10,10) slyness += rand(-10,10) - doProcess() - +/mob/living/carbon/human/interactive/Destroy() + SSnpcpool.stop_processing(src) + return ..() /mob/living/carbon/human/interactive/proc/retalTarget(var/target) var/mob/living/carbon/human/M = target @@ -533,12 +516,10 @@ /mob/living/carbon/human/interactive/proc/targetRange(towhere) return get_dist(get_turf(towhere), get_turf(src)) -/mob/living/carbon/human/interactive/Life() - ..() +/mob/living/carbon/human/interactive/proc/InteractiveProcess() if(SSticker.current_state == GAME_STATE_FINISHED) saveVoice() - if(!alternateProcessing || forceProcess || world.time > lastProc + processTime) - doProcess() + doProcess() /mob/living/carbon/human/interactive/death() saveVoice() @@ -550,22 +531,7 @@ ..() /mob/living/carbon/human/interactive/proc/doProcess() - set waitfor = 0 - forceProcess = 0 - lastProc = world.time - - if(shouldUseDynamicProc) - var/isSeen = 0 - for(var/mob/living/carbon/human/A in orange(12,src)) - if(A.client) - isSeen = 1 - alternateProcessing = isSeen - if(alternateProcessing) - forceProcess = 1 - - if(IsDeadOrIncap()) - walk(src,0) - return + set waitfor = FALSE //--------------------------- //---- interest flow control if(interest < 0 || inactivity_period < 0) @@ -587,10 +553,13 @@ if(istype(D,/obj/machinery/door/airlock)) var/obj/machinery/door/airlock/AL = D if(!AL.CanAStarPass(RPID)) // only crack open doors we can't get through + inactivity_period = 20 AL.panel_open = 1 AL.update_icon() AL.shock(src,(100 - smartness)/2) sleep(5) + if(QDELETED(AL)) + return AL.unbolt() if(!AL.wires.is_cut(WIRE_BOLTS)) AL.wires.cut(WIRE_BOLTS) @@ -599,9 +568,15 @@ if(!AL.wires.is_cut(WIRE_POWER2)) AL.wires.cut(WIRE_POWER2) sleep(5) + if(QDELETED(AL)) + return AL.panel_open = 0 AL.update_icon() - D.open() + D.open(2) //crowbar force + else + D.open() + else + D.open() if(update_hands) var/obj/item/l_hand = get_item_for_held_index(1) @@ -633,7 +608,7 @@ //proc functions for(var/Proc in functions) if(!IsDeadOrIncap()) - callfunction(Proc) + INVOKE_ASYNC(src, Proc) //target interaction stays hardcoded @@ -649,8 +624,8 @@ if(istype(TARGET, /obj/machinery/door)) var/obj/machinery/door/D = TARGET if(D.check_access(MYID) && !istype(D,/obj/machinery/door/poddoor)) + inactivity_period = 10 D.open() - //sleep(15) var/turf/T = get_step(get_step(D.loc,dir),dir) //recursion yo tryWalk(T) //THIEVING SKILLS @@ -672,15 +647,8 @@ insert_into_backpack() //---------FASHION if(istype(TARGET,/obj/item/clothing)) - var/obj/item/clothing/C = TARGET drop_item() - spawn(5) - take_to_slot(C,1) - if(!equip_to_appropriate_slot(C)) - var/obj/item/I = get_item_by_slot(C) - dropItemToGround(I) - spawn(5) - equip_to_appropriate_slot(C) + dressup(TARGET) update_hands = 1 if(MYPDA in src.loc || MYID in src.loc) if(MYPDA in src.loc) @@ -738,8 +706,19 @@ TARGET = traitorTarget tryWalk(TARGET) LAST_TARGET = TARGET - if(alternateProcessing) - addtimer(CALLBACK(src, .proc/doProcess), processTime) + +/mob/living/carbon/human/interactive/proc/dressup(obj/item/clothing/C) + set waitfor = FALSE + inactivity_period = 12 + sleep(5) + if(!QDELETED(C) && !QDELETED(src)) + take_to_slot(C,1) + if(!equip_to_appropriate_slot(C)) + var/obj/item/I = get_item_by_slot(C) + dropItemToGround(I) + sleep(5) + if(!QDELETED(src) && !QDELETED(C)) + equip_to_appropriate_slot(C) /mob/living/carbon/human/interactive/proc/favouredObjIn(var/list/inList) var/list/outList = list() @@ -751,11 +730,6 @@ outList = inList return outList -/mob/living/carbon/human/interactive/proc/callfunction(Proc) - set waitfor = 0 - spawn(0) - call(src,Proc)(src) - /mob/living/carbon/human/interactive/proc/tryWalk(turf/inTarget, override = 0) if(restrictedJob && !override) // we're a job that has to stay in our home if(!(get_turf(inTarget) in get_area_turfs(job2area(myjob)))) @@ -1143,7 +1117,8 @@ for(var/obj/item/I in allContents) if(istype(I,/obj/item/weapon/restraints)) I.attack(TARGET,src) // go go bluespace restraint launcher! - sleep(25) + inactivity_period = 25 + break /mob/living/carbon/human/interactive/proc/clowning(obj) if(shouldModulePass()) @@ -1225,7 +1200,7 @@ if(get_dist(src,C) <= 2) src.say("Wait, [C], let me heal you!") M.attack(C,src) - sleep(25) + inactivity_period = 25 else tryWalk(get_turf(C)) else if(shouldTryHeal == 2) @@ -1237,7 +1212,7 @@ if(get_dist(src,C) <= 2) src.say("Wait, [C], let me heal you!") HPS.attack(C,src) - sleep(25) + inactivity_period = 25 else tryWalk(get_turf(C)) @@ -1265,7 +1240,7 @@ tryWalk(TC) else S.afterattack(TC,src) - sleep(25) + inactivity_period = 25 /mob/living/carbon/human/interactive/proc/customEmote(var/text) visible_message("[text]") @@ -1354,7 +1329,7 @@ var/choice = pick(1,2) if(choice == 1) tryWalk(get_turf(D)) - sleep(get_dist(src,D)) + inactivity_period = get_dist(src,D) D.attackby(RP,src) else cookingwithmagic(D) @@ -1364,7 +1339,7 @@ var/choice = pick(1,2) if(choice == 1) tryWalk(get_turf(D)) - sleep(get_dist(src,D)) + inactivity_period = get_dist(src,D) FD.attackby(KK,src) else cookingwithmagic(FD) @@ -1374,7 +1349,7 @@ var/choice = pick(1,2) if(choice == 1) tryWalk(get_turf(D)) - sleep(get_dist(src,D)) + inactivity_period = get_dist(src,D) CB.attackby(RP,src) else cookingwithmagic(CB) @@ -1384,7 +1359,7 @@ var/choice = pick(1,2) if(choice == 1) tryWalk(get_turf(D)) - sleep(get_dist(src,D)) + inactivity_period = get_dist(src,D) PD.attackby(KK,src) else cookingwithmagic(PD) @@ -1533,6 +1508,7 @@ G.attack_self(src) if(prob(smartness)) npcDrop(G,1) + inactivity_period = 15 sleep(15) throw_item(TARGET) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 9c7bb600a4c5..6461045cc51e 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1073,7 +1073,6 @@ return 1 else user.do_attack_animation(target, ATTACK_EFFECT_DISARM) - add_logs(user, target, "disarmed") if(target.w_uniform) target.w_uniform.add_fingerprint(user) @@ -1085,23 +1084,23 @@ "[user] has pushed [target]!", null, COMBAT_MESSAGE_RANGE) target.apply_effect(2, WEAKEN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!")) target.forcesay(hit_appends) + add_logs(user, target, "disarmed", " pushing them to the ground") return - var/talked = 0 // BubbleWrap - if(randn <= 60) - //BubbleWrap: Disarming breaks a pull + var/obj/item/I = null if(target.pulling) to_chat(target, "[user] has broken [target]'s grip on [target.pulling]!") - talked = 1 target.stop_pulling() - //End BubbleWrap - - if(!talked) //BubbleWrap + else + I = target.get_active_held_item() if(target.drop_item()) target.visible_message("[user] has disarmed [target]!", \ "[user] has disarmed [target]!", null, COMBAT_MESSAGE_RANGE) + else + I = null playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + add_logs(user, target, "disarmed", "[I ? " removing \the [I]" : ""]") return diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 49c8e3955f8b..1fe33f1ce1dc 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -1,7 +1,7 @@ /datum/species/golem // Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck. name = "Golem" - id = "iron" + id = "iron golem" species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS) speedmod = 2 armor = 55 @@ -12,6 +12,7 @@ no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform) nojumpsuit = 1 sexes = 1 + damage_overlay_type = "" meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem // To prevent golem subtypes from overwhelming the odds when random species // changes, only the Random Golem type can be chosen @@ -21,6 +22,21 @@ fixed_mut_color = "aaa" var/info_text = "As an Iron Golem, you don't have any special traits." + var/prefix = "Iron" + var/list/special_names + +/datum/species/golem/random_name(gender,unique,lastname) + var/golem_surname = pick(golem_names) + // 3% chance that our golem has a human surname, because + // cultural contamination + if(prob(3)) + golem_surname = pick(last_names) + else if(special_names && prob(5)) + golem_surname = pick(special_names) + + var/golem_name = "[prefix] [golem_surname]" + return golem_name + /datum/species/golem/random name = "Random Golem" blacklisted = FALSE @@ -36,21 +52,24 @@ /datum/species/golem/adamantine name = "Adamantine Golem" - id = "adamantine" + id = "adamantine golem" meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine fixed_mut_color = "4ed" info_text = "As an Adamantine Golem, you don't have any special traits." + prefix = "Adamantine" //Explodes on death /datum/species/golem/plasma name = "Plasma Golem" - id = "plasma" + id = "plasma golem" fixed_mut_color = "a3d" meat = /obj/item/weapon/ore/plasma //Can burn and takes damage from heat species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS) info_text = "As a Plasma Golem, you explode on death!" burnmod = 1.5 + prefix = "Plasma" + special_names = list("Flood","Fire","Bar","Man") /datum/species/golem/plasma/spec_death(gibbed, mob/living/carbon/human/H) explosion(get_turf(H),0,1,2,flame_range = 5) @@ -60,35 +79,40 @@ //Harder to hurt /datum/species/golem/diamond name = "Diamond Golem" - id = "diamond" + id = "diamond golem" fixed_mut_color = "0ff" armor = 70 //up from 55 meat = /obj/item/weapon/ore/diamond info_text = "As a Diamond Golem, you are more resistant than the average golem." + prefix = "Diamond" + special_names = list("Back") //Faster but softer and less armoured /datum/species/golem/gold name = "Gold Golem" - id = "gold" + id = "gold golem" fixed_mut_color = "cc0" speedmod = 1 armor = 25 //down from 55 meat = /obj/item/weapon/ore/gold info_text = "As a Gold Golem, you are faster but less resistant than the average golem." + prefix = "Golden" //Heavier, thus higher chance of stunning when punching /datum/species/golem/silver name = "Silver Golem" - id = "silver" + id = "silver golem" fixed_mut_color = "ddd" punchstunthreshold = 9 //60% chance, from 40% meat = /obj/item/weapon/ore/silver info_text = "As a Silver Golem, your attacks are heavier and have a higher chance of stunning." + prefix = "Silver" + special_names = list("Surfer", "Chariot", "Lining") //Harder to stun, deals more damage, but it's even slower /datum/species/golem/plasteel name = "Plasteel Golem" - id = "plasteel" + id = "plasteel golem" fixed_mut_color = "bbb" stunmod = 0.40 punchdamagelow = 12 @@ -99,15 +123,17 @@ info_text = "As a Plasteel Golem, you are slower, but harder to stun, and hit very hard when punching." attack_verb = "smash" attack_sound = 'sound/effects/meteorimpact.ogg' //hits pretty hard + prefix = "Plasteel" //Immune to ash storms /datum/species/golem/titanium name = "Titanium Golem" - id = "titanium" + id = "titanium golem" fixed_mut_color = "fff" meat = /obj/item/weapon/ore/titanium info_text = "As a Titanium Golem, you are immune to ash storms, and slightly more resistant to burn damage." burnmod = 0.9 + prefix = "Titanium" /datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() @@ -120,11 +146,12 @@ //Immune to ash storms and lava /datum/species/golem/plastitanium name = "Plastitanium Golem" - id = "plastitanium" + id = "plastitanium golem" fixed_mut_color = "888" meat = /obj/item/weapon/ore/titanium info_text = "As a Plastitanium Golem, you are immune to both ash storms and lava, and slightly more resistant to burn damage." burnmod = 0.8 + prefix = "Plastitanium" /datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() @@ -139,12 +166,14 @@ //Fast and regenerates... but can only speak like an abductor /datum/species/golem/alloy name = "Alien Alloy Golem" - id = "alloy" + id = "alloy golem" fixed_mut_color = "333" meat = /obj/item/stack/sheet/mineral/abductor mutant_organs = list(/obj/item/organ/tongue/abductor) //abductor tongue speedmod = 1 //faster info_text = "As an Alloy Golem, you are made of advanced alien materials: you are faster and regenerate over time. You are, however, only able to be heard by other alloy golems." + prefix = "Alien" + special_names = list("Outsider", "Technology", "Watcher", "Stranger") //ominous and unknown //Regenerates because self-repairing super-advanced alien tech /datum/species/golem/alloy/spec_life(mob/living/carbon/human/H) @@ -157,7 +186,7 @@ //Since this will usually be created from a collaboration between podpeople and free golems, wood golems are a mix between the two races /datum/species/golem/wood name = "Wood Golem" - id = "wood" + id = "wood golem" fixed_mut_color = "49311c" meat = /obj/item/stack/sheet/mineral/wood //Can burn and take damage from heat @@ -166,6 +195,13 @@ burnmod = 1.25 heatmod = 1.5 info_text = "As a Wooden Golem, you have plant-like traits: you take damage from extreme temperatures, can be set on fire, and have lower armor than a normal golem. You regenerate when in the light and wither in the darkness." + prefix = "Wooden" + +/datum/species/golem/wood/random_name(gender,unique,lastname) + var/plant_name = pick("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", \ + "Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper") + var/golem_name = "[prefix] [plant_name]" + return golem_name /datum/species/golem/wood/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() @@ -204,13 +240,14 @@ //Radioactive /datum/species/golem/uranium name = "Uranium Golem" - id = "uranium" + id = "uranium golem" fixed_mut_color = "7f0" meat = /obj/item/weapon/ore/uranium info_text = "As an Uranium Golem, you emit radiation pulses every once in a while. It won't harm fellow golems, but organic lifeforms will be affected." var/last_event = 0 var/active = null + prefix = "Uranium" /datum/species/golem/uranium/spec_life(mob/living/carbon/human/H) if(!active) @@ -224,7 +261,7 @@ //Immune to physical bullets and resistant to brute, but very vulnerable to burn damage. Dusts on death. /datum/species/golem/sand name = "Sand Golem" - id = "sand" + id = "sand golem" fixed_mut_color = "ffdc8f" meat = /obj/item/weapon/ore/glass //this is sand armor = 0 @@ -232,6 +269,7 @@ brutemod = 0.25 info_text = "As a Sand Golem, you are immune to physical bullets and take very little brute damage, but are extremely vulnerable to burn damage. You will also turn to sand when dying, preventing any form of recovery." attack_sound = 'sound/effects/shovel_dig.ogg' + prefix = "Sand" /datum/species/golem/sand/spec_death(gibbed, mob/living/carbon/human/H) H.visible_message("[H] turns into a pile of sand!") @@ -253,7 +291,7 @@ //Reflects lasers and resistant to burn damage, but very vulnerable to brute damage. Shatters on death. /datum/species/golem/glass name = "Glass Golem" - id = "glass" + id = "glass golem" fixed_mut_color = "5a96b4aa" //transparent body meat = /obj/item/weapon/shard armor = 0 @@ -261,6 +299,7 @@ burnmod = 0.25 info_text = "As a Glass Golem, you reflect lasers and energy weapons, and are very resistant to burn damage, but you are extremely vulnerable to brute damage. On death, you'll shatter beyond any hope of recovery." attack_sound = 'sound/effects/Glassbr2.ogg' + prefix = "Glass" /datum/species/golem/glass/spec_death(gibbed, mob/living/carbon/human/H) playsound(H, "shatter", 70, 1) @@ -295,12 +334,14 @@ //Teleports when hit or when it wants to /datum/species/golem/bluespace name = "Bluespace Golem" - id = "bluespace" + id = "bluespace golem" fixed_mut_color = "33f" meat = /obj/item/weapon/ore/bluespace_crystal info_text = "As a Bluespace Golem, are spatially unstable: you will teleport when hit, and you can teleport manually at a long distance." attack_verb = "bluespace punch" attack_sound = 'sound/effects/phasein.ogg' + prefix = "Bluespace" + special_names = list("Crystal", "Polycrystal") var/datum/action/innate/unstable_teleport/unstable_teleport var/teleport_cooldown = 100 @@ -384,7 +425,7 @@ //honk /datum/species/golem/bananium name = "Bananium Golem" - id = "bananium" + id = "bananium golem" fixed_mut_color = "ff0" say_mod = "honks" punchdamagelow = 0 @@ -394,6 +435,7 @@ info_text = "As a Bananium Golem, you are made for pranking. Your body emits natural honks, and you cannot hurt people when punching them. Your skin also emits bananas when damaged." attack_verb = "honk" attack_sound = 'sound/items/AirHorn2.ogg' + prefix = "Bananium" var/last_honk = 0 var/honkooldown = 0 @@ -401,6 +443,11 @@ var/banana_cooldown = 100 var/active = null +/datum/species/golem/bananium/random_name(gender,unique,lastname) + var/clown_name = pick(clown_names) + var/golem_name = "[uppertext(clown_name)]" + return golem_name + /datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) ..() if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP) @@ -449,7 +496,7 @@ /datum/species/golem/runic name = "Runic Golem" - id = "runic" + id = "runic golem" limbs_id = "cultgolem" sexes = FALSE info_text = "As a Runic Golem, you possess eldritch powers granted by the Elder God Nar'Sie." @@ -459,6 +506,12 @@ var/obj/effect/proc_holder/spell/targeted/abyssal_gaze/abyssal_gaze var/obj/effect/proc_holder/spell/targeted/dominate/dominate +/datum/species/golem/runic/random_name(gender,unique,lastname) + var/edgy_first_name = pick("Razor","Blood","Dark","Evil","Cold","Pale","Black","Silent","Chaos","Deadly") + var/edgy_last_name = pick("Edge","Night","Death","Razor","Blade","Steel","Calamity","Twilight","Shadow","Nightmare") //dammit Razor Razor + var/golem_name = "[edgy_first_name] [edgy_last_name]" + return golem_name + /datum/species/golem/runic/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() C.faction |= "cult" @@ -491,7 +544,7 @@ /datum/species/golem/cloth name = "Cloth Golem" - id = "cloth" + id = "cloth golem" limbs_id = "clothgolem" sexes = FALSE info_text = "As a Cloth Golem, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable." @@ -502,6 +555,13 @@ punchdamagelow = 4 punchstunthreshold = 7 punchdamagehigh = 8 // not as heavy as stone + prefix = "Cloth" + +/datum/species/golem/cloth/random_name(gender,unique,lastname) + var/pharaoh_name = pick("Neferkare", "Hudjefa", "Khufu", "Mentuhotep", "Ahmose", "Amenhotep", "Thutmose", "Hatshepsut", "Tutankhamun", "Ramses", "Seti", \ + "Merenptah", "Djer", "Semerkhet", "Nynetjer", "Khafre", "Pepi", "Intef", "Ay") //yes, Ay was an actual pharaoh + var/golem_name = "[pharaoh_name] \Roman[rand(1,99)]" + return golem_name /datum/species/golem/cloth/spec_life(mob/living/carbon/human/H) if(H.fire_stacks < 1) diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index b9c2f68e3af8..4dc34402dd3f 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -7,6 +7,7 @@ species_traits = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,TOXINLOVER) meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime exotic_blood = "slimejelly" + damage_overlay_type = "" var/datum/action/innate/regenerate_limbs/regenerate_limbs /datum/species/jelly/on_species_loss(mob/living/carbon/C) diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index 177cfb5712a2..7665068d1f07 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -117,17 +117,23 @@ playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) visible_message("[M] has attempted to lunge at [name]!", \ "[M] has attempted to lunge at [name]!", null, COMBAT_MESSAGE_RANGE) + if (M.a_intent == INTENT_DISARM) + var/obj/item/I = null playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) if(prob(95)) Weaken(10) visible_message("[M] has tackled down [name]!", \ "[M] has tackled down [name]!", null, COMBAT_MESSAGE_RANGE) else + I = get_active_held_item() if(drop_item()) visible_message("[M] has disarmed [name]!", \ "[M] has disarmed [name]!", null, COMBAT_MESSAGE_RANGE) - add_logs(M, src, "disarmed") + else + I = null//did not manage to actually disarm the item, gross but no time to refactor + + add_logs(M, src, "disarmed", "[I ? " removing \the [I]" : ""]") updatehealth() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 5b23db9467fc..acac5cb29e6c 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -244,10 +244,6 @@ return 0 /mob/living/attack_alien(mob/living/carbon/alien/humanoid/M) - if(isturf(loc) && istype(loc.loc, /area/start)) - to_chat(M, "No attacking people at spawn, you jackass.") - return 0 - switch(M.a_intent) if ("help") visible_message("[M] caresses [src] with its scythe like arm.") diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index d1dcecca359e..41a097b6e02e 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -84,6 +84,9 @@ var/list/ai_list = list() var/obj/machinery/camera/portable/builtInCamera var/obj/structure/AIcore/deactivated/linked_core //For exosuit control + var/mob/living/silicon/robot/deployed_shell = null //For shell control + var/datum/action/innate/deploy_shell/deploy_action = new + var/datum/action/innate/deploy_last_shell/redeploy_action = new /mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai) ..() @@ -138,6 +141,8 @@ var/list/ai_list = list() radio = new /obj/item/device/radio/headset/ai(src) aicamera = new/obj/item/device/camera/siliconcam/ai_camera(src) + deploy_action.Grant(src) + if(isturf(loc)) verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \ /mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \ @@ -247,13 +252,16 @@ var/list/ai_list = list() for(var/mob/living/silicon/robot/R in connected_robots) borg_area = get_area(R) var/robot_status = "Nominal" - if(R.stat || !R.client) + if(R.shell) + robot_status = "AI SHELL" + else if(R.stat || !R.client) robot_status = "OFFLINE" else if(!R.cell || R.cell.charge <= 0) robot_status = "DEPOWERED" //Name, Health, Battery, Module, Area, and Status! Everything an AI wants to know about its borgies! stat(null, text("[R.name] | S.Integrity: [R.health]% | Cell: [R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "Empty"] | \ - Module: [R.designation] | Loc: [borg_area.name] | Status: [robot_status]")) + Module: [R.designation] | Loc: [borg_area.name] | Status: [robot_status]")) + stat(null, text("AI shell beacons detected: [LAZYLEN(available_ai_shells)]")) //Count of total AI shells else stat(null, text("Systems nonfunctional")) @@ -791,12 +799,13 @@ var/list/ai_list = list() if(!..()) return if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card. - if(!mind) - to_chat(user, "No intelligence patterns detected." ) - return if(!can_be_carded) to_chat(user, "Transfer failed.") return + disconnect_shell() //If the AI is controlling a borg, force the player back to core! + if(!mind) + to_chat(user, "No intelligence patterns detected." ) + return ShutOffDoomsdayDevice() new /obj/structure/AIcore/deactivated(loc)//Spawns a deactivated terminal at AI location. ai_restore_power()//So the AI initially has power. @@ -907,10 +916,73 @@ var/list/ai_list = list() to_chat(src, "Hack complete. \The [apc] is now under your exclusive control.") apc.update_icon() +/mob/living/silicon/ai/verb/deploy_to_shell(var/mob/living/silicon/robot/target) + set category = "AI Commands" + set name = "Deploy to Shell" + + if(stat || lacks_power() || control_disabled) + to_chat(src, "Wireless networking module is offline.") + return + + var/list/possible = list() + + for(var/borgie in available_ai_shells) + var/mob/living/silicon/robot/R = borgie + if(R.shell && !R.deployed && (R.stat != DEAD) && (!R.connected_ai ||(R.connected_ai == src))) + possible += R + + if(!LAZYLEN(possible)) + to_chat(src, "No usable AI shell beacons detected.") + + if(!target || !(target in possible)) //If the AI is looking for a new shell, or its pre-selected shell is no longer valid + target = input(src, "Which body to control?") as null|anything in possible + + if (!target || target.stat == DEAD || target.deployed || !(!target.connected_ai ||(target.connected_ai == src))) + return + + else if(mind) + soullink(/datum/soullink/sharedbody, src, target) + deployed_shell = target + target.deploy_init(src) + mind.transfer_to(target) + diag_hud_set_deployed() + +/datum/action/innate/deploy_shell + name = "Deploy to AI Shell" + desc = "Wirelessly control a specialized cyborg shell." + button_icon_state = "ai_shell" + +/datum/action/innate/deploy_shell/Trigger() + var/mob/living/silicon/ai/AI = owner + if(!AI) + return + AI.deploy_to_shell() + +/datum/action/innate/deploy_last_shell + name = "Reconnect to shell" + desc = "Reconnect to the most recently used AI shell." + button_icon_state = "ai_last_shell" + var/mob/living/silicon/robot/last_used_shell + +/datum/action/innate/deploy_last_shell/Trigger() + if(!owner) + return + if(last_used_shell) + var/mob/living/silicon/ai/AI = owner + AI.deploy_to_shell(last_used_shell) + else + Remove(owner) //If the last shell is blown, destroy it. + +/mob/living/silicon/ai/proc/disconnect_shell() + if(deployed_shell) //Forcibly call back AI in event of things such as damage, EMP or power loss. + to_chat(src, "Your remote connection has been reset!") + deployed_shell.undeploy() + diag_hud_set_deployed() + /mob/living/silicon/ai/resist() return /mob/living/silicon/ai/spawned/Initialize(mapload, datum/ai_laws/L, mob/target_ai) if(!target_ai) target_ai = src //cheat! just give... ourselves as the spawned AI, because that's technically correct - ..() + ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/ai_defense.dm b/code/modules/mob/living/silicon/ai/ai_defense.dm index 27009293938a..75ef88768f7c 100644 --- a/code/modules/mob/living/silicon/ai/ai_defense.dm +++ b/code/modules/mob/living/silicon/ai/ai_defense.dm @@ -22,6 +22,7 @@ return 0 /mob/living/silicon/ai/emp_act(severity) + disconnect_shell() if (prob(30)) switch(pick(1,2)) if(1) diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm index e0b3cf38f184..2c98c8c0aeac 100644 --- a/code/modules/mob/living/silicon/ai/examine.dm +++ b/code/modules/mob/living/silicon/ai/examine.dm @@ -1,21 +1,23 @@ /mob/living/silicon/ai/examine(mob/user) var/msg = "*---------*\nThis is \icon[src] [src]!\n" - if (src.stat == DEAD) + if (stat == DEAD) msg += "It appears to be powered-down.\n" else msg += "" - if (src.getBruteLoss()) - if (src.getBruteLoss() < 30) + if (getBruteLoss()) + if (getBruteLoss() < 30) msg += "It looks slightly dented.\n" else msg += "It looks severely dented!\n" - if (src.getFireLoss()) - if (src.getFireLoss() < 30) + if (getFireLoss()) + if (getFireLoss() < 30) msg += "It looks slightly charred.\n" else msg += "Its casing is melted and heat-warped!\n" msg += "" - if (shunted == 0 && !src.client) + if(deployed_shell) + msg += "The wireless networking light is blinking.\n" + else if (!shunted && !client) msg += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem...\n" msg += "*---------*" diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 24e4ac510a5c..329b3120cba0 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -65,6 +65,7 @@ health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss() - getFireLoss() update_stat() diag_hud_set_health() + disconnect_shell() /mob/living/silicon/ai/update_stat() if(status_flags & GODMODE) @@ -163,6 +164,7 @@ update_sight() /mob/living/silicon/ai/proc/ai_lose_power() + disconnect_shell() aiRestorePowerRoutine = POWER_RESTORATION_START blind_eyes(1) update_sight() diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 804113fb24a2..e33506ae400e 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -36,9 +36,11 @@ if(is_servant_of_ratvar(src) && user.Adjacent(src) && !stat) //To counter pseudo-stealth by using headlamps msg += "Its eyes are glowing a blazing yellow!\n" - switch(src.stat) + switch(stat) if(CONSCIOUS) - if(!src.client) + if(shell) + msg += "It appears to be an [deployed ? "active" : "empty"] AI shell.\n" + else if(!client) msg += "It appears to be in stand-by mode.\n" //afk if(UNCONSCIOUS) msg += "It doesn't seem to be responding.\n" diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm index 794f6837b31b..bd499dbdb5af 100644 --- a/code/modules/mob/living/silicon/robot/laws.dm +++ b/code/modules/mob/living/silicon/robot/laws.dm @@ -32,7 +32,9 @@ to_chat(who, "Obey these laws:") laws.show_laws(who) - if (is_special_character(src) && connected_ai) + if (shell) //AI shell + to_chat(who, "Remember, you are an AI remotely controlling your shell, other AIs can be ignored.") + else if (is_special_character(src) && connected_ai) to_chat(who, "Remember, [connected_ai.name] is technically your master, but your objective comes first.") else if (connected_ai) to_chat(who, "Remember, [connected_ai.name] is your master, other AIs can be ignored.") diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index d2f460ca2eed..06a981b9b2d2 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -16,6 +16,10 @@ var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of.. var/obj/item/device/mmi/mmi = null + var/shell = FALSE + var/deployed = FALSE + var/mob/living/silicon/ai/mainframe = null + var/datum/action/innate/undeployment/undeployment_action = new //Hud stuff @@ -73,7 +77,7 @@ var/sight_mode = 0 var/updating = 0 //portable camera camerachunk update - hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD) + hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD) var/list/upgrades = list() @@ -129,8 +133,12 @@ update_icons() ..() + //If this body is meant to be a borg controlled by the AI player + if(shell) + make_shell() + //MMI stuff. Held togheter by magic. ~Miauw - if(!mmi || !mmi.brainmob) + else if(!mmi || !mmi.brainmob) mmi = new (src) mmi.brain = new /obj/item/organ/brain(mmi) mmi.brain.name = "[real_name]'s brain" @@ -170,6 +178,8 @@ mmi = null if(connected_ai) connected_ai.connected_robots -= src + if(shell) + available_ai_shells -= src qdel(wires) qdel(module) qdel(eye_lights) @@ -204,6 +214,8 @@ /mob/living/silicon/robot/proc/updatename() + if(shell) + return var/changed_name = "" if(custom_name) changed_name = custom_name @@ -424,7 +436,9 @@ update_icons() else if(istype(W, /obj/item/weapon/screwdriver) && opened && cell) // radio - if(radio) + if(shell) + to_chat(user, "You cannot seem to open the radio compartment") //Prevent AI radio key theft + else if(radio) radio.attackby(W,user)//Push it to the radio to let it handle everything else to_chat(user, "Unable to locate a radio!") @@ -453,6 +467,9 @@ if(!cell) to_chat(user, "You need to install a power cell to do that!") return + if(shell) //AI shells always have the laws of the AI + to_chat(user, "[src] is controlled remotely! You cannot upload new laws this way!") + return if(emagged || (connected_ai && lawupdate)) //Can't be sure which, metagamers emote("buzz-[user.name]") return @@ -813,12 +830,14 @@ if(!connected_ai) return switch(notifytype) - if(1) //New Cyborg + if(NEW_BORG) //New Cyborg to_chat(connected_ai, "

NOTICE - New cyborg connection detected: [name]
") - if(2) //New Module + if(NEW_MODULE) //New Module to_chat(connected_ai, "

NOTICE - Cyborg module change detected: [name] has loaded the [designation] module.
") - if(3) //New Name + if(RENAME) //New Name to_chat(connected_ai, "

NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].
") + if(AI_SHELL) //New Shell + to_chat(connected_ai, "

NOTICE - New cyborg shell detected: [name]
") /mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close = 0) if(stat || lockcharge || low_power_mode) @@ -901,6 +920,7 @@ update_headlamp() diag_hud_set_status() diag_hud_set_health() + diag_hud_set_aishell() update_health_hud() /mob/living/silicon/robot/revive(full_heal = 0, admin_revive = 0) @@ -910,13 +930,13 @@ update_headlamp() if(admin_revive) locked = 1 - notify_ai(1) + notify_ai(NEW_BORG) . = 1 /mob/living/silicon/robot/fully_replace_character_name(oldname, newname) ..() if(oldname != real_name) - notify_ai(3, oldname, newname) + notify_ai(RENAME, oldname, newname) if(camera) camera.c_tag = real_name custom_name = newname @@ -937,6 +957,7 @@ speed = 0 ionpulse = FALSE + revert_shell() return 1 @@ -973,6 +994,97 @@ new_hat.forceMove(src) update_icons() +/mob/living/silicon/robot/proc/make_shell(var/obj/item/borg/upgrade/ai/board) + if(!board) + upgrades |= new /obj/item/borg/upgrade/ai(src) + shell = TRUE + braintype = "AI Shell" + name = "[designation] AI Shell [rand(100,999)]" + real_name = name + available_ai_shells |= src + if(camera) + camera.c_tag = real_name //update the camera name too + diag_hud_set_aishell() + notify_ai(AI_SHELL) + +/mob/living/silicon/robot/proc/revert_shell() + if(!shell) + return + undeploy() + for(var/obj/item/borg/upgrade/ai/boris in src) + //A player forced reset of a borg would drop the module before this is called, so this is for catching edge cases + qdel(boris) + shell = FALSE + available_ai_shells -= src + name = "Unformatted Cyborg [rand(100,999)]" + real_name = name + if(camera) + camera.c_tag = real_name + diag_hud_set_aishell() + +/mob/living/silicon/robot/proc/deploy_init(var/mob/living/silicon/ai/AI) + real_name = "[AI.real_name] shell [rand(100, 999)] - [designation]" //Randomizing the name so it shows up seperately in the shells list + name = real_name + if(camera) + camera.c_tag = real_name //update the camera name too + mainframe = AI + deployed = TRUE + connected_ai = mainframe + mainframe.connected_robots |= src + lawupdate = TRUE + lawsync() + if(radio && AI.radio) //AI keeps all channels, including Syndie if it is a Traitor + if(AI.radio.syndie) + radio.make_syndie() + radio.subspace_transmission = TRUE + radio.channels = AI.radio.channels + for(var/chan in radio.channels) + radio.secure_radio_connections[chan] = add_radio(radio, radiochannels[chan]) + + diag_hud_set_aishell() + undeployment_action.Grant(src) + +/datum/action/innate/undeployment + name = "Disconnect from shell" + desc = "Stop controlling your shell and resume normal core operations." + button_icon_state = "ai_core" + +/datum/action/innate/undeployment/Trigger() + if(!..()) + return FALSE + var/mob/living/silicon/robot/R = owner + + R.undeploy() + return TRUE + + +/mob/living/silicon/robot/proc/undeploy() + + if(!deployed || !mainframe) + return + mainframe.redeploy_action.Grant(mainframe) + mainframe.redeploy_action.last_used_shell = src + mind.transfer_to(mainframe) + deployed = FALSE + mainframe.deployed_shell = null + undeployment_action.Remove(src) + if(radio) //Return radio to normal + radio.recalculateChannels() + if(camera) + camera.c_tag = real_name //update the camera name too + diag_hud_set_aishell() + mainframe.diag_hud_set_deployed() + mainframe.show_laws() //Always remind the AI when switching + mainframe = null + +/mob/living/silicon/robot/attack_ai(mob/user) + if(shell && (!connected_ai || connected_ai == user)) + var/mob/living/silicon/ai/AI = user + AI.deploy_to_shell(src) + +/mob/living/silicon/robot/shell + shell = TRUE + /mob/living/silicon/robot/MouseDrop_T(mob/living/M, mob/living/user) . = ..() if(!(M in buckled_mobs) && isliving(M)) diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 3493d41caa8e..e78b12b8c59f 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -16,11 +16,12 @@ if (M.a_intent == INTENT_DISARM) if(!(lying)) M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - if(get_active_held_item()) + var/obj/item/I = get_active_held_item() + if(I) uneq_active() visible_message("[M] disarmed [src]!", \ "[M] has disabled [src]'s active module!", null, COMBAT_MESSAGE_RANGE) - add_logs(M, src, "disarmed") + add_logs(M, src, "disarmed", "[I ? " removing \the [I]" : ""]") else Stun(2) step(src,get_dir(M,src)) @@ -92,6 +93,8 @@ if(locked) to_chat(user, "You emag the cover lock.") locked = 0 + if(shell) //A warning to Traitors who may not know that emagging AI shells does not slave them. + to_chat(user, "[src] seems to be controlled remotely! Emagging the interface may not work as expected.") else to_chat(user, "The cover is already unlocked!") return @@ -125,6 +128,12 @@ log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they were slaved to traitor AI [connected_ai].") return + if(shell) //AI shells cannot be emagged, so we try to make it look like a standard reset. Smart players may see through this, however. + to_chat(user, "[src] is remotely controlled! Your emag attempt has triggered a system reset instead!") + log_game("[key_name(user)] attempted to emag an AI shell belonging to [key_name(src) ? key_name(src) : connected_ai]. The shell has been reset as a result.") + ResetModule() + return + SetEmagged(1) SetStunned(3) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown lawupdate = 0 diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 2c87cf00aaab..1ac95b26af24 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -218,7 +218,7 @@ R.SetLockdown(0) R.anchored = FALSE R.notransform = FALSE - R.notify_ai(2) + R.notify_ai(NEW_MODULE) if(R.hud_used) R.hud_used.update_robot_modules_display() if(feedback_key && !did_feedback) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index ed0016101366..de6bb7c827ec 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -21,8 +21,7 @@ var/designation = "" var/radiomod = "" //Radio character used before state laws/arrivals announce to allow department transmissions, default, or none at all. var/obj/item/device/camera/siliconcam/aicamera = null //photography - //hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD) - hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD) + hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_TRACK_HUD) var/obj/item/device/radio/borg/radio = null //AIs dont use this but this is at the silicon level to advoid copypasta in say() diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index a7e2f803f107..f3cbfd3359be 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -133,4 +133,4 @@ visual_effect_icon = ATTACK_EFFECT_PUNCH else visual_effect_icon = ATTACK_EFFECT_SMASH - ..() \ No newline at end of file + ..() diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index 6d23f54150a1..9d8631e972ac 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -67,6 +67,15 @@ var/visualAppearence = MAINTDRONE //What we appear as var/hacked = 0 //If we have laws to destroy the station var/can_be_held = TRUE //if assholes can pick us up + var/flavortext = \ + "\nDO NOT INTERFERE WITH THE ROUND AS A DRONE OR YOU WILL BE DRONE BANNED\n"+\ + "Drones are a ghost role that are allowed to fix the station and build things. Interfering with the round as a drone is against the rules.\n"+\ + "Actions that constitute interference include, but are not limited to:\n"+\ + " - Interacting with round critical objects (IDs, weapons, contraband, powersinks, bombs, etc.)\n"+\ + " - Interacting with living beings (communication, attacking, healing, etc.)\n"+\ + " - Interacting with non-living beings (dragging bodies, looting bodies, etc.)\n"+\ + "These rules are at admin discretion and will be heavily enforced.\n"+\ + "If you do not have the regular drone laws, follow your laws to the best of your ability." /mob/living/simple_animal/drone/Initialize() . = ..() @@ -121,6 +130,9 @@ ..() check_laws() + if(flavortext) + to_chat(src, "[flavortext]") + updateSeeStaticMobs() if(!picked) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm index 312a4375e0d6..abd9a7ec954d 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm @@ -29,6 +29,7 @@ default_hatmask = /obj/item/clothing/head/helmet/space/hardsuit/syndi seeStatic = 0 //Our programming is superior. hacked = TRUE + flavortext = null /mob/living/simple_animal/drone/syndrone/Initialize() ..() @@ -119,6 +120,9 @@ hacked = TRUE visualAppearence = CLOCKDRONE can_be_held = FALSE + flavortext = "You are a cogscarab, a clockwork creation of Ratvar. As a cogscarab, you have low health, an inbuilt proselytizer that can convert brass \ + to liquified alloy, a set of relatively fast tools, can communicate over the Hierophant Network with :b, and are immune to extreme \ + temperatures and pressures. \nYour goal is to serve the Justiciar and his servants by repairing and defending all they create." /mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal proselytizer default_storage = /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar @@ -138,10 +142,7 @@ /mob/living/simple_animal/drone/cogscarab/Login() ..() add_servant_of_ratvar(src, TRUE) - to_chat(src, "You are a cogscarab, a clockwork creation of Ratvar. As a cogscarab, you have low health, an inbuilt proselytizer that can convert brass \ - to liquified alloy, a set of relatively fast tools, can communicate over the Hierophant Network with :b, and are immune to extreme \ - temperatures and pressures. \nYour goal is to serve the Justiciar and his servants by repairing and defending all they create. \ - \nYou yourself are one of these servants, and will be able to utilize almost anything they can[ratvar_awakens ? "":", excluding a clockwork slab"].") + to_chat(src,"You yourself are one of these servants, and will be able to utilize almost anything they can[ratvar_awakens ? "":", excluding a clockwork slab"].") // this can't go with flavortext because i'm assuming it requires them to be ratvar'd /mob/living/simple_animal/drone/cogscarab/binarycheck() return FALSE diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index da51356ec550..943fba195291 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -308,7 +308,7 @@ /mob/proc/AIize(transfer_after = TRUE) if(client) - stopLobbySound() + stop_sound_channel(CHANNEL_LOBBYMUSIC) var/turf/loc_landmark for(var/obj/effect/landmark/start/sloc in landmarks_list) @@ -385,7 +385,7 @@ R.loc = loc R.job = "Cyborg" - R.notify_ai(1) + R.notify_ai(NEW_BORG) . = R qdel(src) diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 3cc48bb11a00..8dae7e97d970 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -27,6 +27,7 @@ var/last_warning var/consumedSupermatter = 0 //If the singularity has eaten a supermatter shard and can go to stage six resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + dangerous_possession = TRUE /obj/singularity/New(loc, var/starting_energy = 50, var/temp = 0) //CARN: admin-alert for chuckle-fuckery. diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 944d471500a9..9649e13029d1 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -122,7 +122,7 @@ var/mob/living/silicon/robot/Robot = M if(Robot.mmi) qdel(Robot.mmi) - Robot.notify_ai(1) + Robot.notify_ai(NEW_BORG) else for(var/obj/item/W in contents) if(!M.dropItemToGround(W)) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index bb6f9f7b9091..4a4cbf688b1a 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -232,7 +232,7 @@ var/const/INJECT = 5 //injection var/need_mob_update = 0 for(var/reagent in cached_reagents) var/datum/reagent/R = reagent - if(!R.holder) + if(QDELETED(R.holder)) continue if(!C) C = R.holder.my_atom diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 6e748bbc6c19..5c8d6950071a 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -37,6 +37,8 @@ /obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0), /obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), /obj/item/weapon/reagent_containers/food/snacks/grown/oat = list("flour" = -5), + /obj/item/weapon/reagent_containers/food/snacks/grown/rice = list("rice" = -5), + /obj/item/weapon/reagent_containers/food/snacks/donut/New = list("sprinkles" = -2, "sugar" = 1), /obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), /obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0), /obj/item/weapon/reagent_containers/food/snacks/egg = list("eggyolk" = -5), diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 6ce54089fea1..9267c5c7f983 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -718,6 +718,16 @@ construction_time = 120 category = list("Cyborg Upgrade Modules") +/datum/design/boris_ai_controller + name = "B.O.R.I.S. AI-Cyborg Remote Control Module" + id = "borg_ai_control" + build_type = MECHFAB + build_path = /obj/item/borg/upgrade/ai + materials = list(MAT_METAL = 1200, MAT_GLASS = 1500, MAT_GOLD = 200) + req_tech = list("programming" = 4, "magnets" = 4, "engineering" = 4) + construction_time = 50 + category = list("Misc") + //Misc /datum/design/mecha_tracking name = "Exosuit Tracking Beacon" diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index f20d9f2751dc..f1ce4d078660 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -638,7 +638,7 @@ /obj/item/weapon/relic/proc/flash(mob/user) playsound(src.loc, "sparks", rand(25,50), 1) - var/obj/item/weapon/grenade/flashbang/CB = new/obj/item/weapon/grenade/flashbang(get_turf(user)) + var/obj/item/weapon/grenade/flashbang/CB = new/obj/item/weapon/grenade/flashbang(user.loc) CB.prime() warn_admins(user, "Flash") diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index f51876459a6d..0e3daed388d9 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -523,7 +523,7 @@ var/mob/living/carbon/human/G = new /mob/living/carbon/human G.set_species(/datum/species/golem/adamantine) G.set_cloned_appearance() - G.real_name = "Adamantine Golem ([rand(1, 1000)])" + G.real_name = G.dna.species.random_name() G.name = G.real_name G.dna.unique_enzymes = G.dna.generate_unique_enzymes() G.dna.species.auto_equip(G) diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index 541f15351a08..decbfe59a921 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -320,9 +320,9 @@ I = image("icon"='icons/mob/human_parts.dmi', "icon_state"="[species_id]_[body_zone]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) else if(should_draw_gender) - I = image("icon"='icons/mob/augments.dmi', "icon_state"="[initial(icon_state)]_[icon_gender]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + I = image("icon"= icon, "icon_state"="[body_zone]_[icon_gender]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) else - I = image("icon"='icons/mob/augments.dmi', "icon_state"="[initial(icon_state)]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + I = image("icon"= icon, "icon_state"="[body_zone]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) standing += I return standing diff --git a/code/modules/surgery/bodyparts/robot_bodyparts.dm b/code/modules/surgery/bodyparts/robot_bodyparts.dm index 92df2fc50f0c..d9b51a19a50d 100644 --- a/code/modules/surgery/bodyparts/robot_bodyparts.dm +++ b/code/modules/surgery/bodyparts/robot_bodyparts.dm @@ -7,7 +7,7 @@ item_state = "buildpipe" icon = 'icons/obj/robot_parts.dmi' flags = CONDUCT - icon_state = "l_arm" + icon_state = "borg_l_arm" status = BODYPART_ROBOTIC @@ -18,7 +18,7 @@ item_state = "buildpipe" icon = 'icons/obj/robot_parts.dmi' flags = CONDUCT - icon_state = "r_arm" + icon_state = "borg_r_arm" status = BODYPART_ROBOTIC @@ -29,7 +29,7 @@ item_state = "buildpipe" icon = 'icons/obj/robot_parts.dmi' flags = CONDUCT - icon_state = "l_leg" + icon_state = "borg_l_leg" status = BODYPART_ROBOTIC @@ -40,7 +40,7 @@ item_state = "buildpipe" icon = 'icons/obj/robot_parts.dmi' flags = CONDUCT - icon_state = "r_leg" + icon_state = "borg_r_leg" status = BODYPART_ROBOTIC @@ -50,7 +50,7 @@ item_state = "buildpipe" icon = 'icons/obj/robot_parts.dmi' flags = CONDUCT - icon_state = "chest" + icon_state = "borg_chest" status = BODYPART_ROBOTIC var/wired = 0 var/obj/item/weapon/stock_parts/cell/cell = null @@ -100,7 +100,7 @@ item_state = "buildpipe" icon = 'icons/obj/robot_parts.dmi' flags = CONDUCT - icon_state = "head" + icon_state = "borg_head" status = BODYPART_ROBOTIC var/obj/item/device/assembly/flash/handheld/flash1 = null var/obj/item/device/assembly/flash/handheld/flash2 = null @@ -165,27 +165,27 @@ /obj/item/bodypart/l_arm/robot/surplus name = "surplus prosthetic left arm" desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing." - icon = 'icons/mob/augments.dmi' - icon_state = "surplus_l_arm" + icon = 'icons/mob/surplus_augments.dmi' + icon_state = "l_arm" max_damage = 20 /obj/item/bodypart/r_arm/robot/surplus name = "surplus prosthetic right arm" desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing." - icon = 'icons/mob/augments.dmi' - icon_state = "surplus_r_arm" + icon = 'icons/mob/surplus_augments.dmi' + icon_state = "r_arm" max_damage = 20 /obj/item/bodypart/l_leg/robot/surplus name = "surplus prosthetic left leg" desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing." - icon = 'icons/mob/augments.dmi' - icon_state = "surplus_l_leg" + icon = 'icons/mob/surplus_augments.dmi' + icon_state = "l_leg" max_damage = 20 /obj/item/bodypart/r_leg/robot/surplus name = "surplus prosthetic right leg" desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing." - icon = 'icons/mob/augments.dmi' + icon = 'icons/mob/surplus_augments.dmi' icon_state = "surplus_r_leg" max_damage = 20 diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index bc2f1a782746..805bdf778e2e 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -46,15 +46,17 @@ //SURGERY STEP SUCCESSES -/datum/surgery_step/add_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) +/datum/surgery_step/add_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/bodypart/tool, datum/surgery/surgery) if(L) user.visible_message("[user] successfully augments [target]'s [parse_zone(target_zone)]!", "You successfully augment [target]'s [parse_zone(target_zone)].") L.change_bodypart_status(BODYPART_ROBOTIC, 1) + L.icon = tool.icon + L.max_damage = tool.max_damage user.drop_item() qdel(tool) - target.update_damage_overlays() + target.update_body_parts() target.updatehealth() add_logs(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]") else to_chat(user, "[target] has no organic [parse_zone(target_zone)] there!") - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm index 51e5e201f80a..2b449925ee1f 100644 --- a/code/modules/zombie/organs.dm +++ b/code/modules/zombie/organs.dm @@ -3,6 +3,7 @@ desc = "A black web of pus and vicera." zone = "head" slot = "zombie_infection" + icon_state = "blacktumor" origin_tech = "biotech=5" var/datum/species/old_species var/living_transformation_time = 3 diff --git a/html/changelog.html b/html/changelog.html index 8194585f874c..ce4105eeb905 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,49 @@ -->
+

26 March 2017

+

BeeSting12 updated:

+ +

Gun Hog and Shadowlight213 updated:

+ +

Penguaro updated:

+ +

Qbopper updated:

+ +

Robustin updated:

+ +

TrustyGun updated:

+ +

XDTM updated:

+ +

coiax updated:

+ +

24 March 2017

BeeSting12 updated:

- -

22 January 2017

-

ChemicalRascal updated:

- -

Cyberboss updated:

- -

Dannno updated:

- -

Fox McCloud updated:

- -

Hyena updated:

- -

Joan updated:

- -

Shadowlight213 updated:

- -

Thunder12345 updated:

- -

Tofa01 updated:

- -

Ultimate-Chimera updated:

- -

XDTM updated:

- -

coiax updated:

-
GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 692780c99708..ee479b043855 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -10339,3 +10339,41 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. rock: - tweak: lizards are hurt slightly more by cold but less by heat. this does not mean they are more resistant to being lasered, fortunately. +2017-03-26: + BeeSting12: + - spellcheck: The bar shuttle's buckable bar stools are now buckleable bar stools. + Gun Hog and Shadowlight213: + - rscadd: The AI may now deploy to cyborgs prepared as AI shells. The module to + do this may be research in the exosuit fabricator. Simply slot the module into + a completed cyborg frame as with an MMI, or into a playerless (with no ckey) + cyborg. + - rscadd: AI shells and AIs controlling a shell can be determined through the Diagnostic + HUD. + - rscadd: AIs can deploy to a shell using the new action buttons or by simply clicking + on it. + - experiment: An AI shell will always have the laws of its controlling AI. + Penguaro: + - rscadd: Brig - Added Air Alarm + - rscdel: Engineering - Removed Brig Shutter + - tweak: Omega, Meta, & Delta Stations - The Vents and Scrubbers for the Supermatter + Air Alarm are now isolated from the rest of the Air Alarms in Engineering. + Qbopper: + - spellcheck: Drones are now given OOC guidelines to follow as well as their IC + lawset. + Robustin: + - rscadd: Added the prototype canister with expanded volume, valve pressure, and + access/timer features + TrustyGun: + - bugfix: Deconstructing display cases and coffins now drop the correct amount of + wood. + XDTM: + - tweak: Some golems now spawn with more thematic names. + - tweak: Adamantine Golems are no longer numbered, but receive a random golem name. + - bugfix: Airlocks properly remove the shock overlay when a temporary shock runs + out. + coiax: + - bugfix: Teams playing CTF have their own radio channels, rather than using the + Centcom and Syndicate channels. + - bugfix: Actually actually makes CTF barricades repair between rounds. + - bugfix: Blue CTF lasers have little blue effects when they hit things, rather + than red effects. diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 683306b96a04..c24aeccf5480 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/augments.dmi b/icons/mob/augments.dmi index a2d816c8c980..7124c35105e4 100644 Binary files a/icons/mob/augments.dmi and b/icons/mob/augments.dmi differ diff --git a/icons/mob/surplus_augments.dmi b/icons/mob/surplus_augments.dmi new file mode 100644 index 000000000000..f06ac0c94b7d Binary files /dev/null and b/icons/mob/surplus_augments.dmi differ diff --git a/icons/obj/barsigns.dmi b/icons/obj/barsigns.dmi index 94256a6b1fb0..53373c46307e 100644 Binary files a/icons/obj/barsigns.dmi and b/icons/obj/barsigns.dmi differ diff --git a/icons/obj/flora/jungleflora.dmi b/icons/obj/flora/jungleflora.dmi index ba731e438a1a..9a266e9226e8 100644 Binary files a/icons/obj/flora/jungleflora.dmi and b/icons/obj/flora/jungleflora.dmi differ diff --git a/icons/obj/module.dmi b/icons/obj/module.dmi index d2f41a303026..d2d93afac096 100644 Binary files a/icons/obj/module.dmi and b/icons/obj/module.dmi differ diff --git a/icons/obj/robot_parts.dmi b/icons/obj/robot_parts.dmi index 9461028091fc..0410cb034f3b 100644 Binary files a/icons/obj/robot_parts.dmi and b/icons/obj/robot_parts.dmi differ diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index d840841a7172..de2fcf5fbe4c 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -39,6 +39,8 @@ em {font-style: normal; font-weight: bold;} .syndradio {color: #6d3f40;} .centcomradio {color: #686868;} .aiprivradio {color: #ff00ff;} +.redteamradio {color: #ff0000;} +.blueteamradio {color: #0000ff;} .yell { font-weight: bold;} diff --git a/tgstation.dme b/tgstation.dme index 7505c6370deb..65f842e5674d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -55,6 +55,7 @@ #include "code\__DEFINES\say.dm" #include "code\__DEFINES\shuttles.dm" #include "code\__DEFINES\sight.dm" +#include "code\__DEFINES\sound.dm" #include "code\__DEFINES\stat.dm" #include "code\__DEFINES\status_effects.dm" #include "code\__DEFINES\tgui.dm" @@ -1403,7 +1404,6 @@ #include "code\modules\mining\lavaland\necropolis_chests.dm" #include "code\modules\mining\lavaland\ruins\gym.dm" #include "code\modules\mob\death.dm" -#include "code\modules\mob\interactive.dm" #include "code\modules\mob\inventory.dm" #include "code\modules\mob\login.dm" #include "code\modules\mob\logout.dm" @@ -1509,6 +1509,7 @@ #include "code\modules\mob\living\carbon\human\human_defines.dm" #include "code\modules\mob\living\carbon\human\human_helpers.dm" #include "code\modules\mob\living\carbon\human\human_movement.dm" +#include "code\modules\mob\living\carbon\human\interactive.dm" #include "code\modules\mob\living\carbon\human\inventory.dm" #include "code\modules\mob\living\carbon\human\life.dm" #include "code\modules\mob\living\carbon\human\say.dm" diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css index d52500b9d646..531fb00530b0 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;-webkit-transform:translateX(-50%);-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%;-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-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%}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-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%;-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-right:after{-webkit-transform:translateX(-8px) translateY(-50%);-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%}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-webkit-transform:translateX(8px) translateY(-50%);-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+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 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::-webkit-input-placeholder{color:#999}body.clockwork input::-moz-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;-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,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(even){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 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+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCA0MjUgMjAwIiBvcGFjaXR5PSIuMzMiPgogIDxwYXRoIGQ9Im0gMTc4LjAwMzk5LDAuMDM4NjkgLTcxLjIwMzkzLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM0LDYuMDI1NTUgbCAwLDE4Ny44NzE0NyBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgNi43NjEzNCw2LjAyNTU0IGwgNTMuMTA3MiwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTAxLjU0NDAxOCA3Mi4yMTYyOCwxMDQuNjk5Mzk4IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA1Ljc2MDE1LDIuODcwMTYgbCA3My41NTQ4NywwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzNSwtNi4wMjU1NSBsIC01NC43MTY0NCwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzMyw2LjAyNTU1IGwgMCwxMDIuNjE5MzUgTCAxODMuNzY0MTMsMi45MDg4NiBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTUuNzYwMTQsLTIuODcwMTcgeiIgLz4KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPgogIDxwYXRoIGQ9Im0gNDIwLjE1NTM1LDE3Ny44OTExOSBhIDEzLjQxMjAzOCwxMi41MDE4NDIgMCAwIDEgLTguNjMyOTUsMjIuMDY5NTEgbCAtNjYuMTE4MzIsMCBhIDUuMzY0ODE1Miw1LjAwMDczNyAwIDAgMSAtNS4zNjQ4MiwtNS4wMDA3NCBsIDAsLTc5Ljg3OTMxIHoiIC8+Cjwvc3ZnPgo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4KPCEtLSBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1zYS80LjAvIC0tPgo=") 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;-webkit-transform:translateX(-50%);-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%;-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-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%}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-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%;-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:after{-webkit-transform:translateX(-8px) translateY(-50%);-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%}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-webkit-transform:translateX(8px) translateY(-50%);-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+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 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::-webkit-input-placeholder{color:#999}body.nanotrasen input::-moz-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;-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,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(even){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 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+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCAyMDAgMjg5Ljc0MiIgb3BhY2l0eT0iLjMzIj4KICA8cGF0aCBkPSJtIDkzLjUzNzY3NywwIGMgLTE4LjExMzEyNSwwIC0zNC4yMjAxMzMsMy4xMTE2NCAtNDguMzIzNDg0LDkuMzM0MzcgLTEzLjk2NTA5Miw2LjIyMTY3IC0yNC42MTI0NDIsMTUuMDcxMTQgLTMxLjk0MDY1MSwyNi41NDcxIC03LjE4OTkzOTgsMTEuMzM3ODkgLTEwLjMwMTIyNjYsMjQuNzQ5MTEgLTEwLjMwMTIyNjYsNDAuMjM0NzggMCwxMC42NDY2MiAyLjcyNTAwMjYsMjAuNDY0NjUgOC4xNzUxMTE2LDI5LjQ1MjU4IDUuNjE1Mjc3LDguOTg2ODYgMTQuMDM4Mjc3LDE3LjM1MjA0IDI1LjI2ODgyMSwyNS4wOTQzNiAxMS4yMzA1NDQsNy42MDUzMSAyNi41MDc0MjEsMTUuNDE4MzUgNDUuODMwNTE0LDIzLjQzNzgyIDE5Ljk4Mzc0OCw4LjI5NTU3IDM0Ljg0ODg0OCwxNS41NTQ3MSA0NC41OTI5OTgsMjEuNzc2MzggOS43NDQxNCw2LjIyMjczIDE2Ljc2MTcsMTIuODU4NSAyMS4wNTU3MiwxOS45MDk1MSA0LjI5NDA0LDcuMDUyMDggNi40NDE5MywxNS43NjQwOCA2LjQ0MTkzLDI2LjEzNDU5IDAsMTYuMTc3MDIgLTUuMjAxOTYsMjguNDgyMjIgLTE1LjYwNjczLDM2LjkxNjgyIC0xMC4yMzk2LDguNDM0NyAtMjUuMDIyMDMsMTIuNjUyMyAtNDQuMzQ1MTY5LDEyLjY1MjMgLTE0LjAzODE3MSwwIC0yNS41MTUyNDcsLTEuNjU5NCAtMzQuNDMzNjE4LC00Ljk3NzcgLTguOTE4MzcsLTMuNDU2NiAtMTYuMTg1NTcyLC04LjcxMTMgLTIxLjgwMDgzOSwtMTUuNzYzMyAtNS42MTUyNzcsLTcuMDUyMSAtMTAuMDc0Nzk1LC0xNi42NjA4OCAtMTMuMzc3ODk5LC0yOC44MjgxMiBsIC0yNC43NzMxNjI2MjkzOTQ1LDAgMCw1Ni44MjYzMiBDIDMzLjg1Njc2OSwyODYuMDc2MDEgNjMuNzQ5MDQsMjg5Ljc0MjAxIDg5LjY3ODM4MywyODkuNzQyMDEgYyAxNi4wMjAwMjcsMCAzMC43MTk3ODcsLTEuMzgyNyA0NC4wOTczMzcsLTQuMTQ3OSAxMy41NDI3MiwtMi45MDQzIDI1LjEwNDEsLTcuNDY3NiAzNC42ODMwOSwtMTMuNjg5MyA5Ljc0NDEzLC02LjM1OTcgMTcuMzQwNDIsLTE0LjUxOTUgMjIuNzkwNTIsLTI0LjQ3NDggNS40NTAxLC0xMC4wOTMzMiA4LjE3NTExLC0yMi4zOTk1OSA4LjE3NTExLC0zNi45MTY4MiAwLC0xMi45OTc2NCAtMy4zMDIxLC0yNC4zMzUzOSAtOS45MDgyOSwtMzQuMDE0NiAtNi40NDEwNSwtOS44MTcyNSAtMTUuNTI1NDUsLTE4LjUyNzA3IC0yNy4yNTE0NiwtMjYuMTMxMzMgLTExLjU2MDg1LC03LjYwNDI3IC0yNy45MTA4MywtMTUuODMxNDIgLTQ5LjA1MDY2LC0yNC42ODAyMiAtMTcuNTA2NDQsLTcuMTkwMTIgLTMwLjcxOTY2OCwtMTMuNjg5NDggLTM5LjYzODAzOCwtMTkuNDk3MDEgLTguOTE4MzcxLC01LjgwNzUyIC0xOC42MDc0NzQsLTEyLjQzNDA5IC0yNC4wOTY1MjQsLTE4Ljg3NDE3IC01LjQyNjA0MywtNi4zNjYxNiAtOS42NTg4MjYsLTE1LjA3MDAzIC05LjY1ODgyNiwtMjQuODg3MjkgMCwtOS4yNjQwMSAyLjA3NTQxNCwtMTcuMjEzNDUgNi4yMjM0NTQsLTIzLjg1MDMzIDExLjA5ODI5OCwtMTQuMzk3NDggNDEuMjg2NjM4LC0xLjc5NTA3IDQ1LjA3NTYwOSwyNC4zNDc2MiA0LjgzOTM5Miw2Ljc3NDkxIDguODQ5MzUsMTYuMjQ3MjkgMTIuMDI5NTE1LDI4LjQxNTYgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTQuNDc4MjUsLTUuOTI0NDggLTkuOTU0ODgsLTEwLjYzMjIyIC0xNS45MDgzNywtMTQuMzc0MTEgMS42NDA1NSwwLjQ3OTA1IDMuMTkwMzksMS4wMjM3NiA0LjYzODY1LDEuNjQwMjQgNi40OTg2MSwyLjYyNjA3IDEyLjE2NzkzLDcuMzI3NDcgMTcuMDA3MywxNC4xMDM0NSA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNSwxNi4yNDU2NyAxMi4wMjk1MiwyOC40MTM5NyAwLDAgOC40ODEyOCwtMC4xMjg5NCA4LjQ4OTc4LC0wLjAwMiAwLjQxNzc2LDYuNDE0OTQgLTEuNzUzMzksOS40NTI4NiAtNC4xMjM0MiwxMi41NjEwNCAtMi40MTc0LDMuMTY5NzggLTUuMTQ0ODYsNi43ODk3MyAtNC4wMDI3OCwxMy4wMDI5IDEuNTA3ODYsOC4yMDMxOCAxMC4xODM1NCwxMC41OTY0MiAxNC42MjE5NCw5LjMxMTU0IC0zLjMxODQyLC0wLjQ5OTExIC01LjMxODU1LC0xLjc0OTQ4IC01LjMxODU1LC0xLjc0OTQ4IDAsMCAxLjg3NjQ2LDAuOTk4NjggNS42NTExNywtMS4zNTk4MSAtMy4yNzY5NSwwLjk1NTcxIC0xMC43MDUyOSwtMC43OTczOCAtMTEuODAxMjUsLTYuNzYzMTMgLTAuOTU3NTIsLTUuMjA4NjEgMC45NDY1NCwtNy4yOTUxNCAzLjQwMTEzLC0xMC41MTQ4MiAyLjQ1NDYyLC0zLjIxOTY4IDUuMjg0MjYsLTYuOTU4MzEgNC42ODQzLC0xNC40ODgyNCBsIDAuMDAzLDAuMDAyIDguOTI2NzYsMCAwLC01NS45OTk2NyBjIC0xNS4wNzEyNSwtMy44NzE2OCAtMjcuNjUzMTQsLTYuMzYwNDIgLTM3Ljc0NjcxLC03LjQ2NTg2IC05Ljk1NTMxLC0xLjEwNzU1IC0yMC4xODgyMywtMS42NTk4MSAtMzAuNjk2NjEzLC0xLjY1OTgxIHogbSA3MC4zMjE2MDMsMTcuMzA4OTMgMC4yMzgwNSw0MC4zMDQ5IGMgMS4zMTgwOCwxLjIyNjY2IDIuNDM5NjUsMi4yNzgxNSAzLjM0MDgxLDMuMTA2MDIgNC44MzkzOSw2Ljc3NDkxIDguODQ5MzQsMTYuMjQ1NjYgMTIuMDI5NTEsMjguNDEzOTcgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTYuNjc3MzEsLTQuNTkzODEgLTE5LjgzNjQzLC0xMC40NzMwOSAtMzYuMTQwNzEsLTE1LjgyNTIyIHogbSAtMjguMTIwNDksNS42MDU1MSA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM3LC02LjQ2Njk3IC0xMy44NDY3OCwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NzA1LDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiBtIDE1LjIyMTk1LDI0LjAwODQ4IDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzgsLTYuNDY2OTcgLTEzLjg0Njc5LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDQsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gLTk5LjExMzg0LDIuMjA3NjQgOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzODIsLTYuNDY2OTcgLTEzLjg0Njc4MiwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NTQyLDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiIgLz4KPC9zdmc+CjwhLS0gVGhpcyB3b3JrIGlzIGxpY2Vuc2VkIHVuZGVyIGEgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIC0tPgo8IS0tIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMC8gLS0+Cg==") 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;-webkit-transform:translateX(-50%);-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%;-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-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%}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-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%;-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-right:after{-webkit-transform:translateX(-8px) translateY(-50%);-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%}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-webkit-transform:translateX(8px) translateY(-50%);-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+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 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::-webkit-input-placeholder{color:#999}body.syndicate input::-moz-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;-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}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(even){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 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+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 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::-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 .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,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 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+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 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::-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 .content,body.nanotrasen section .label,body.nanotrasen section .line,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 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+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 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::-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 .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 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 diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index 606865762393..8622a82113aa 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -1,16 +1,16 @@ -require=function t(e,n,a){function r(o,s){if(!n[o]){if(!e[o]){var p="function"==typeof require&&require;if(!s&&p)return p(o,!0);if(i)return i(o,!0);var u=Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return r(n?n:t)},c,c.exports,t,e,n,a)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o=0;--a){var r=this.tryEntries[a],i=r.completion;if("root"===r.tryLoc)return e("end");if(r.tryLoc<=this.prev){var o=b.call(r,"catchLoc"),s=b.call(r,"finallyLoc");if(o&&s){if(this.prev=0;--n){var a=this.tryEntries[n];if(a.tryLoc<=this.prev&&b.call(a,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),d(n),E}},"catch":function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var a=n.completion;if("throw"===a.type){var r=a.arg;d(n)}return r}}throw Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:m(t),resultName:e,nextLoc:n},E}}}("object"==typeof n?n:"object"==typeof window?window:"object"==typeof self?self:this)}).call(this,t(190),void 0!==n?n:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{190:190}],3:[function(t,e,n){e.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},{}],4:[function(t,e,n){var a=t(84)("unscopables"),r=Array.prototype;void 0==r[a]&&t(32)(r,a,{}),e.exports=function(t){r[a][t]=!0}},{32:32,84:84}],5:[function(t,e,n){var a=t(39);e.exports=function(t){if(!a(t))throw TypeError(t+" is not an object!");return t}},{39:39}],6:[function(t,e,n){"use strict";var a=t(81),r=t(77),i=t(80);e.exports=[].copyWithin||function(t,e){var n=a(this),o=i(n.length),s=r(t,o),p=r(e,o),u=arguments,c=u.length>2?u[2]:void 0,l=Math.min((void 0===c?o:r(c,o))-p,o-s),f=1;for(s>p&&p+l>s&&(f=-1,p+=l-1,s+=l-1);l-- >0;)p in n?n[s]=n[p]:delete n[s],s+=f,p+=f;return n}},{77:77,80:80,81:81}],7:[function(t,e,n){"use strict";var a=t(81),r=t(77),i=t(80);e.exports=[].fill||function(t){for(var e=a(this),n=i(e.length),o=arguments,s=o.length,p=r(s>1?o[1]:void 0,n),u=s>2?o[2]:void 0,c=void 0===u?n:r(u,n);c>p;)e[p++]=t;return e}},{77:77,80:80,81:81}],8:[function(t,e,n){var a=t(79),r=t(80),i=t(77);e.exports=function(t){return function(e,n,o){var s,p=a(e),u=r(p.length),c=i(o,u);if(t&&n!=n){for(;u>c;)if(s=p[c++],s!=s)return!0}else for(;u>c;c++)if((t||c in p)&&p[c]===n)return t||c;return!t&&-1}}},{77:77,79:79,80:80}],9:[function(t,e,n){var a=t(18),r=t(35),i=t(81),o=t(80),s=t(10);e.exports=function(t){var e=1==t,n=2==t,p=3==t,u=4==t,c=6==t,l=5==t||c;return function(f,d,h){for(var m,v,g=i(f),b=r(g),y=a(d,h,3),_=o(b.length),x=0,w=e?s(f,_):n?s(f,0):void 0;_>x;x++)if((l||x in b)&&(m=b[x],v=y(m,x,g),t))if(e)w[x]=v;else if(v)switch(t){case 3:return!0;case 5:return m;case 6:return x;case 2:w.push(m)}else if(u)return!1;return c?-1:p||u?u:w}}},{10:10,18:18,35:35,80:80,81:81}],10:[function(t,e,n){var a=t(39),r=t(37),i=t(84)("species");e.exports=function(t,e){var n;return r(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!r(n.prototype)||(n=void 0),a(n)&&(n=n[i],null===n&&(n=void 0))),new(void 0===n?Array:n)(e)}},{37:37,39:39,84:84}],11:[function(t,e,n){var a=t(12),r=t(84)("toStringTag"),i="Arguments"==a(function(){return arguments}());e.exports=function(t){var e,n,o;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=(e=Object(t))[r])?n:i?a(e):"Object"==(o=a(e))&&"function"==typeof e.callee?"Arguments":o}},{12:12,84:84}],12:[function(t,e,n){var a={}.toString;e.exports=function(t){return a.call(t).slice(8,-1)}},{}],13:[function(t,e,n){"use strict";var a=t(47),r=t(32),i=t(61),o=t(18),s=t(70),p=t(19),u=t(28),c=t(43),l=t(45),f=t(83)("id"),d=t(31),h=t(39),m=t(66),v=t(20),g=Object.isExtensible||h,b=v?"_s":"size",y=0,_=function(t,e){if(!h(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!d(t,f)){if(!g(t))return"F";if(!e)return"E";r(t,f,++y)}return"O"+t[f]},x=function(t,e){var n,a=_(e);if("F"!==a)return t._i[a];for(n=t._f;n;n=n.n)if(n.k==e)return n};e.exports={getConstructor:function(t,e,n,r){var c=t(function(t,i){s(t,c,e),t._i=a.create(null),t._f=void 0,t._l=void 0,t[b]=0,void 0!=i&&u(i,n,t[r],t)});return i(c.prototype,{clear:function(){for(var t=this,e=t._i,n=t._f;n;n=n.n)n.r=!0,n.p&&(n.p=n.p.n=void 0),delete e[n.i];t._f=t._l=void 0,t[b]=0},"delete":function(t){var e=this,n=x(e,t);if(n){var a=n.n,r=n.p;delete e._i[n.i],n.r=!0,r&&(r.n=a),a&&(a.p=r),e._f==n&&(e._f=a),e._l==n&&(e._l=r),e[b]--}return!!n},forEach:function(t){for(var e,n=o(t,arguments.length>1?arguments[1]:void 0,3);e=e?e.n:this._f;)for(n(e.v,e.k,this);e&&e.r;)e=e.p},has:function(t){return!!x(this,t)}}),v&&a.setDesc(c.prototype,"size",{get:function(){return p(this[b])}}),c},def:function(t,e,n){var a,r,i=x(t,e);return i?i.v=n:(t._l=i={i:r=_(e,!0),k:e,v:n,p:a=t._l,n:void 0,r:!1},t._f||(t._f=i),a&&(a.n=i),t[b]++,"F"!==r&&(t._i[r]=i)),t},getEntry:x,setStrong:function(t,e,n){c(t,e,function(t,e){this._t=t,this._k=e,this._l=void 0},function(){for(var t=this,e=t._k,n=t._l;n&&n.r;)n=n.p;return t._t&&(t._l=n=n?n.n:t._t._f)?"keys"==e?l(0,n.k):"values"==e?l(0,n.v):l(0,[n.k,n.v]):(t._t=void 0,l(1))},n?"entries":"values",!n,!0),m(e)}}},{18:18,19:19,20:20,28:28,31:31,32:32,39:39,43:43,45:45,47:47,61:61,66:66,70:70,83:83}],14:[function(t,e,n){var a=t(28),r=t(11);e.exports=function(t){return function(){if(r(this)!=t)throw TypeError(t+"#toJSON isn't generic");var e=[];return a(this,!1,e.push,e),e}}},{11:11,28:28}],15:[function(t,e,n){"use strict";var a=t(32),r=t(61),i=t(5),o=t(39),s=t(70),p=t(28),u=t(9),c=t(31),l=t(83)("weak"),f=Object.isExtensible||o,d=u(5),h=u(6),m=0,v=function(t){return t._l||(t._l=new g)},g=function(){this.a=[]},b=function(t,e){return d(t.a,function(t){return t[0]===e})};g.prototype={get:function(t){var e=b(this,t);return e?e[1]:void 0},has:function(t){return!!b(this,t)},set:function(t,e){var n=b(this,t);n?n[1]=e:this.a.push([t,e])},"delete":function(t){var e=h(this.a,function(e){return e[0]===t});return~e&&this.a.splice(e,1),!!~e}},e.exports={getConstructor:function(t,e,n,a){var i=t(function(t,r){s(t,i,e),t._i=m++,t._l=void 0,void 0!=r&&p(r,n,t[a],t)});return r(i.prototype,{"delete":function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i)&&delete t[l][this._i]:v(this)["delete"](t):!1},has:function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i):v(this).has(t):!1}}),i},def:function(t,e,n){return f(i(e))?(c(e,l)||a(e,l,{}),e[l][t._i]=n):v(t).set(e,n),t},frozenStore:v,WEAK:l}},{28:28,31:31,32:32,39:39,5:5,61:61,70:70,83:83,9:9}],16:[function(t,e,n){"use strict";var a=t(30),r=t(23),i=t(62),o=t(61),s=t(28),p=t(70),u=t(39),c=t(25),l=t(44),f=t(67);e.exports=function(t,e,n,d,h,m){var v=a[t],g=v,b=h?"set":"add",y=g&&g.prototype,_={},x=function(t){var e=y[t];i(y,t,"delete"==t?function(t){return m&&!u(t)?!1:e.call(this,0===t?0:t)}:"has"==t?function(t){return m&&!u(t)?!1:e.call(this,0===t?0:t)}:"get"==t?function(t){return m&&!u(t)?void 0:e.call(this,0===t?0:t)}:"add"==t?function(t){return e.call(this,0===t?0:t),this}:function(t,n){return e.call(this,0===t?0:t,n),this})};if("function"==typeof g&&(m||y.forEach&&!c(function(){(new g).entries().next()}))){var w,k=new g,P=k[b](m?{}:-0,1)!=k,C=c(function(){k.has(1)}),E=l(function(t){new g(t)});E||(g=e(function(e,n){p(e,g,t);var a=new v;return void 0!=n&&s(n,h,a[b],a),a}),g.prototype=y,y.constructor=g),m||k.forEach(function(t,e){w=1/e===-(1/0)}),(C||w)&&(x("delete"),x("has"),h&&x("get")),(w||P)&&x(b),m&&y.clear&&delete y.clear}else g=d.getConstructor(e,t,h,b),o(g.prototype,n);return f(g,t),_[t]=g,r(r.G+r.W+r.F*(g!=v),_),m||d.setStrong(g,t,h),g}},{23:23,25:25,28:28,30:30,39:39,44:44,61:61,62:62,67:67,70:70}],17:[function(t,e,n){var a=e.exports={version:"1.2.6"};"number"==typeof __e&&(__e=a)},{}],18:[function(t,e,n){var a=t(3);e.exports=function(t,e,n){if(a(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,a){return t.call(e,n,a)};case 3:return function(n,a,r){return t.call(e,n,a,r)}}return function(){return t.apply(e,arguments)}}},{3:3}],19:[function(t,e,n){e.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},{}],20:[function(t,e,n){e.exports=!t(25)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{25:25}],21:[function(t,e,n){var a=t(39),r=t(30).document,i=a(r)&&a(r.createElement);e.exports=function(t){return i?r.createElement(t):{}}},{30:30,39:39}],22:[function(t,e,n){var a=t(47);e.exports=function(t){var e=a.getKeys(t),n=a.getSymbols;if(n)for(var r,i=n(t),o=a.isEnum,s=0;i.length>s;)o.call(t,r=i[s++])&&e.push(r);return e}},{47:47}],23:[function(t,e,n){var a=t(30),r=t(17),i=t(32),o=t(62),s=t(18),p="prototype",u=function(t,e,n){var c,l,f,d,h=t&u.F,m=t&u.G,v=t&u.S,g=t&u.P,b=t&u.B,y=m?a:v?a[e]||(a[e]={}):(a[e]||{})[p],_=m?r:r[e]||(r[e]={}),x=_[p]||(_[p]={});m&&(n=e);for(c in n)l=!h&&y&&c in y,f=(l?y:n)[c],d=b&&l?s(f,a):g&&"function"==typeof f?s(Function.call,f):f,y&&!l&&o(y,c,f),_[c]!=f&&i(_,c,d),g&&x[c]!=f&&(x[c]=f)};a.core=r,u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,e.exports=u},{17:17,18:18,30:30,32:32,62:62}],24:[function(t,e,n){var a=t(84)("match");e.exports=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[a]=!1,!"/./"[t](e)}catch(r){}}return!0}},{84:84}],25:[function(t,e,n){e.exports=function(t){try{return!!t()}catch(e){return!0}}},{}],26:[function(t,e,n){"use strict";var a=t(32),r=t(62),i=t(25),o=t(19),s=t(84);e.exports=function(t,e,n){var p=s(t),u=""[t];i(function(){var e={};return e[p]=function(){return 7},7!=""[t](e)})&&(r(String.prototype,t,n(o,p,u)),a(RegExp.prototype,p,2==e?function(t,e){return u.call(t,this,e)}:function(t){return u.call(t,this)}))}},{19:19,25:25,32:32,62:62,84:84}],27:[function(t,e,n){"use strict";var a=t(5);e.exports=function(){var t=a(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},{5:5}],28:[function(t,e,n){var a=t(18),r=t(41),i=t(36),o=t(5),s=t(80),p=t(85);e.exports=function(t,e,n,u){var c,l,f,d=p(t),h=a(n,u,e?2:1),m=0;if("function"!=typeof d)throw TypeError(t+" is not iterable!");if(i(d))for(c=s(t.length);c>m;m++)e?h(o(l=t[m])[0],l[1]):h(t[m]);else for(f=d.call(t);!(l=f.next()).done;)r(f,h,l.value,e)}},{18:18,36:36,41:41,5:5,80:80,85:85}],29:[function(t,e,n){var a=t(79),r=t(47).getNames,i={}.toString,o="object"==typeof window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(t){try{return r(t)}catch(e){return o.slice()}};e.exports.get=function(t){return o&&"[object Window]"==i.call(t)?s(t):r(a(t))}},{47:47,79:79}],30:[function(t,e,n){var a=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=a)},{}],31:[function(t,e,n){var a={}.hasOwnProperty;e.exports=function(t,e){return a.call(t,e)}},{}],32:[function(t,e,n){var a=t(47),r=t(60);e.exports=t(20)?function(t,e,n){return a.setDesc(t,e,r(1,n))}:function(t,e,n){return t[e]=n,t}},{20:20,47:47,60:60}],33:[function(t,e,n){e.exports=t(30).document&&document.documentElement},{30:30}],34:[function(t,e,n){e.exports=function(t,e,n){var a=void 0===n;switch(e.length){case 0:return a?t():t.call(n);case 1:return a?t(e[0]):t.call(n,e[0]);case 2:return a?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return a?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return a?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},{}],35:[function(t,e,n){var a=t(12);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==a(t)?t.split(""):Object(t)}},{12:12}],36:[function(t,e,n){var a=t(46),r=t(84)("iterator"),i=Array.prototype;e.exports=function(t){return void 0!==t&&(a.Array===t||i[r]===t)}},{46:46,84:84}],37:[function(t,e,n){var a=t(12);e.exports=Array.isArray||function(t){return"Array"==a(t)}},{12:12}],38:[function(t,e,n){var a=t(39),r=Math.floor;e.exports=function(t){return!a(t)&&isFinite(t)&&r(t)===t}},{39:39}],39:[function(t,e,n){e.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},{}],40:[function(t,e,n){var a=t(39),r=t(12),i=t(84)("match");e.exports=function(t){var e;return a(t)&&(void 0!==(e=t[i])?!!e:"RegExp"==r(t))}},{12:12,39:39,84:84}],41:[function(t,e,n){var a=t(5);e.exports=function(t,e,n,r){try{return r?e(a(n)[0],n[1]):e(n)}catch(i){var o=t["return"];throw void 0!==o&&a(o.call(t)),i}}},{5:5}],42:[function(t,e,n){"use strict";var a=t(47),r=t(60),i=t(67),o={};t(32)(o,t(84)("iterator"),function(){return this}),e.exports=function(t,e,n){t.prototype=a.create(o,{next:r(1,n)}),i(t,e+" Iterator")}},{32:32,47:47,60:60,67:67,84:84}],43:[function(t,e,n){"use strict";var a=t(49),r=t(23),i=t(62),o=t(32),s=t(31),p=t(46),u=t(42),c=t(67),l=t(47).getProto,f=t(84)("iterator"),d=!([].keys&&"next"in[].keys()),h="@@iterator",m="keys",v="values",g=function(){return this};e.exports=function(t,e,n,b,y,_,x){u(n,e,b);var w,k,P=function(t){if(!d&&t in A)return A[t];switch(t){case m:return function(){return new n(this,t)};case v:return function(){return new n(this,t)}}return function(){return new n(this,t)}},C=e+" Iterator",E=y==v,S=!1,A=t.prototype,O=A[f]||A[h]||y&&A[y],T=O||P(y);if(O){var M=l(T.call(new t));c(M,C,!0),!a&&s(A,h)&&o(M,f,g),E&&O.name!==v&&(S=!0,T=function(){return O.call(this)})}if(a&&!x||!d&&!S&&A[f]||o(A,f,T),p[e]=T,p[C]=g,y)if(w={values:E?T:P(v),keys:_?T:P(m),entries:E?P("entries"):T},x)for(k in w)k in A||i(A,k,w[k]);else r(r.P+r.F*(d||S),e,w);return w}},{23:23,31:31,32:32,42:42,46:46,47:47,49:49,62:62,67:67,84:84}],44:[function(t,e,n){var a=t(84)("iterator"),r=!1;try{var i=[7][a]();i["return"]=function(){r=!0},Array.from(i,function(){throw 2})}catch(o){}e.exports=function(t,e){if(!e&&!r)return!1;var n=!1;try{var i=[7],o=i[a]();o.next=function(){n=!0},i[a]=function(){return o},t(i)}catch(s){}return n}},{84:84}],45:[function(t,e,n){e.exports=function(t,e){return{value:e,done:!!t}}},{}],46:[function(t,e,n){e.exports={}},{}],47:[function(t,e,n){var a=Object;e.exports={create:a.create,getProto:a.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:a.getOwnPropertyDescriptor,setDesc:a.defineProperty,setDescs:a.defineProperties,getKeys:a.keys,getNames:a.getOwnPropertyNames,getSymbols:a.getOwnPropertySymbols,each:[].forEach}},{}],48:[function(t,e,n){var a=t(47),r=t(79);e.exports=function(t,e){for(var n,i=r(t),o=a.getKeys(i),s=o.length,p=0;s>p;)if(i[n=o[p++]]===e)return n}},{47:47,79:79}],49:[function(t,e,n){e.exports=!1},{}],50:[function(t,e,n){e.exports=Math.expm1||function(t){return 0==(t=+t)?t:t>-1e-6&&1e-6>t?t+t*t/2:Math.exp(t)-1}},{}],51:[function(t,e,n){e.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&1e-8>t?t-t*t/2:Math.log(1+t)}},{}],52:[function(t,e,n){e.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:0>t?-1:1}},{}],53:[function(t,e,n){var a,r,i,o=t(30),s=t(76).set,p=o.MutationObserver||o.WebKitMutationObserver,u=o.process,c=o.Promise,l="process"==t(12)(u),f=function(){var t,e,n;for(l&&(t=u.domain)&&(u.domain=null,t.exit());a;)e=a.domain,n=a.fn,e&&e.enter(),n(),e&&e.exit(),a=a.next;r=void 0,t&&t.enter()};if(l)i=function(){u.nextTick(f)};else if(p){var d=1,h=document.createTextNode("");new p(f).observe(h,{characterData:!0}),i=function(){h.data=d=-d}}else i=c&&c.resolve?function(){c.resolve().then(f)}:function(){s.call(o,f)};e.exports=function(t){var e={fn:t,next:void 0,domain:l&&u.domain};r&&(r.next=e),a||(a=e,i()),r=e}},{12:12,30:30,76:76}],54:[function(t,e,n){var a=t(47),r=t(81),i=t(35);e.exports=t(25)(function(){var t=Object.assign,e={},n={},a=Symbol(),r="abcdefghijklmnopqrst";return e[a]=7,r.split("").forEach(function(t){n[t]=t}),7!=t({},e)[a]||Object.keys(t({},n)).join("")!=r})?function(t,e){for(var n=r(t),o=arguments,s=o.length,p=1,u=a.getKeys,c=a.getSymbols,l=a.isEnum;s>p;)for(var f,d=i(o[p++]),h=c?u(d).concat(c(d)):u(d),m=h.length,v=0;m>v;)l.call(d,f=h[v++])&&(n[f]=d[f]);return n}:Object.assign},{25:25,35:35,47:47,81:81}],55:[function(t,e,n){var a=t(23),r=t(17),i=t(25);e.exports=function(t,e){var n=(r.Object||{})[t]||Object[t],o={};o[t]=e(n),a(a.S+a.F*i(function(){n(1)}),"Object",o)}},{17:17,23:23,25:25}],56:[function(t,e,n){var a=t(47),r=t(79),i=a.isEnum;e.exports=function(t){return function(e){for(var n,o=r(e),s=a.getKeys(o),p=s.length,u=0,c=[];p>u;)i.call(o,n=s[u++])&&c.push(t?[n,o[n]]:o[n]);return c}}},{47:47,79:79}],57:[function(t,e,n){var a=t(47),r=t(5),i=t(30).Reflect;e.exports=i&&i.ownKeys||function(t){var e=a.getNames(r(t)),n=a.getSymbols;return n?e.concat(n(t)):e}},{30:30,47:47,5:5}],58:[function(t,e,n){"use strict";var a=t(59),r=t(34),i=t(3);e.exports=function(){for(var t=i(this),e=arguments.length,n=Array(e),o=0,s=a._,p=!1;e>o;)(n[o]=arguments[o++])===s&&(p=!0);return function(){var a,i=this,o=arguments,u=o.length,c=0,l=0;if(!p&&!u)return r(t,n,i);if(a=n.slice(),p)for(;e>c;c++)a[c]===s&&(a[c]=o[l++]);for(;u>l;)a.push(o[l++]);return r(t,a,i)}}},{3:3,34:34,59:59}],59:[function(t,e,n){e.exports=t(30)},{30:30}],60:[function(t,e,n){e.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},{}],61:[function(t,e,n){var a=t(62);e.exports=function(t,e){for(var n in e)a(t,n,e[n]);return t}},{62:62}],62:[function(t,e,n){var a=t(30),r=t(32),i=t(83)("src"),o="toString",s=Function[o],p=(""+s).split(o);t(17).inspectSource=function(t){return s.call(t)},(e.exports=function(t,e,n,o){"function"==typeof n&&(n.hasOwnProperty(i)||r(n,i,t[e]?""+t[e]:p.join(e+"")),n.hasOwnProperty("name")||r(n,"name",e)),t===a?t[e]=n:(o||delete t[e],r(t,e,n))})(Function.prototype,o,function(){return"function"==typeof this&&this[i]||s.call(this)})},{17:17,30:30,32:32,83:83}],63:[function(t,e,n){e.exports=function(t,e){var n=e===Object(e)?function(t){return e[t]}:e;return function(e){return(e+"").replace(t,n)}}},{}],64:[function(t,e,n){e.exports=Object.is||function(t,e){return t===e?0!==t||1/t===1/e:t!=t&&e!=e}},{}],65:[function(t,e,n){var a=t(47).getDesc,r=t(39),i=t(5),o=function(t,e){if(i(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};e.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(e,n,r){try{r=t(18)(Function.call,a(Object.prototype,"__proto__").set,2),r(e,[]),n=!(e instanceof Array)}catch(i){n=!0}return function(t,e){return o(t,e),n?t.__proto__=e:r(t,e),t}}({},!1):void 0),check:o}},{18:18,39:39,47:47,5:5}],66:[function(t,e,n){"use strict";var a=t(30),r=t(47),i=t(20),o=t(84)("species");e.exports=function(t){var e=a[t];i&&e&&!e[o]&&r.setDesc(e,o,{configurable:!0,get:function(){return this}})}},{20:20,30:30,47:47,84:84}],67:[function(t,e,n){var a=t(47).setDesc,r=t(31),i=t(84)("toStringTag");e.exports=function(t,e,n){t&&!r(t=n?t:t.prototype,i)&&a(t,i,{configurable:!0,value:e})}},{31:31,47:47,84:84}],68:[function(t,e,n){var a=t(30),r="__core-js_shared__",i=a[r]||(a[r]={});e.exports=function(t){return i[t]||(i[t]={})}},{30:30}],69:[function(t,e,n){var a=t(5),r=t(3),i=t(84)("species");e.exports=function(t,e){var n,o=a(t).constructor;return void 0===o||void 0==(n=a(o)[i])?e:r(n)}},{3:3,5:5,84:84}],70:[function(t,e,n){e.exports=function(t,e,n){if(!(t instanceof e))throw TypeError(n+": use the 'new' operator!");return t}},{}],71:[function(t,e,n){var a=t(78),r=t(19);e.exports=function(t){return function(e,n){var i,o,s=r(e)+"",p=a(n),u=s.length;return 0>p||p>=u?t?"":void 0:(i=s.charCodeAt(p),55296>i||i>56319||p+1===u||(o=s.charCodeAt(p+1))<56320||o>57343?t?s.charAt(p):i:t?s.slice(p,p+2):(i-55296<<10)+(o-56320)+65536)}}},{19:19,78:78}],72:[function(t,e,n){var a=t(40),r=t(19);e.exports=function(t,e,n){if(a(e))throw TypeError("String#"+n+" doesn't accept regex!");return r(t)+""}},{19:19,40:40}],73:[function(t,e,n){var a=t(80),r=t(74),i=t(19);e.exports=function(t,e,n,o){var s=i(t)+"",p=s.length,u=void 0===n?" ":n+"",c=a(e);if(p>=c)return s;""==u&&(u=" ");var l=c-p,f=r.call(u,Math.ceil(l/u.length));return f.length>l&&(f=f.slice(0,l)),o?f+s:s+f}},{19:19,74:74,80:80}],74:[function(t,e,n){"use strict";var a=t(78),r=t(19);e.exports=function(t){var e=r(this)+"",n="",i=a(t);if(0>i||i==1/0)throw RangeError("Count can't be negative");for(;i>0;(i>>>=1)&&(e+=e))1&i&&(n+=e);return n}},{19:19,78:78}],75:[function(t,e,n){var a=t(23),r=t(19),i=t(25),o=" \n\x0B\f\r   ᠎              \u2028\u2029\ufeff",s="["+o+"]",p="​…",u=RegExp("^"+s+s+"*"),c=RegExp(s+s+"*$"),l=function(t,e){var n={};n[t]=e(f),a(a.P+a.F*i(function(){return!!o[t]()||p[t]()!=p}),"String",n)},f=l.trim=function(t,e){return t=r(t)+"",1&e&&(t=t.replace(u,"")),2&e&&(t=t.replace(c,"")),t};e.exports=l},{19:19,23:23,25:25}],76:[function(t,e,n){var a,r,i,o=t(18),s=t(34),p=t(33),u=t(21),c=t(30),l=c.process,f=c.setImmediate,d=c.clearImmediate,h=c.MessageChannel,m=0,v={},g="onreadystatechange",b=function(){var t=+this;if(v.hasOwnProperty(t)){var e=v[t];delete v[t],e()}},y=function(t){b.call(t.data)};f&&d||(f=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return v[++m]=function(){s("function"==typeof t?t:Function(t),e)},a(m),m},d=function(t){delete v[t]},"process"==t(12)(l)?a=function(t){l.nextTick(o(b,t,1))}:h?(r=new h,i=r.port2,r.port1.onmessage=y,a=o(i.postMessage,i,1)):c.addEventListener&&"function"==typeof postMessage&&!c.importScripts?(a=function(t){c.postMessage(t+"","*")},c.addEventListener("message",y,!1)):a=g in u("script")?function(t){p.appendChild(u("script"))[g]=function(){p.removeChild(this),b.call(t)}}:function(t){setTimeout(o(b,t,1),0)}),e.exports={set:f,clear:d}},{12:12,18:18,21:21,30:30,33:33,34:34}],77:[function(t,e,n){var a=t(78),r=Math.max,i=Math.min;e.exports=function(t,e){return t=a(t),0>t?r(t+e,0):i(t,e)}},{78:78}],78:[function(t,e,n){var a=Math.ceil,r=Math.floor;e.exports=function(t){return isNaN(t=+t)?0:(t>0?r:a)(t)}},{}],79:[function(t,e,n){var a=t(35),r=t(19);e.exports=function(t){return a(r(t))}},{19:19,35:35}],80:[function(t,e,n){var a=t(78),r=Math.min;e.exports=function(t){return t>0?r(a(t),9007199254740991):0}},{78:78}],81:[function(t,e,n){var a=t(19);e.exports=function(t){return Object(a(t))}},{19:19}],82:[function(t,e,n){var a=t(39);e.exports=function(t,e){if(!a(t))return t;var n,r;if(e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;if("function"==typeof(n=t.valueOf)&&!a(r=n.call(t)))return r;if(!e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;throw TypeError("Can't convert object to primitive value")}},{39:39}],83:[function(t,e,n){var a=0,r=Math.random();e.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++a+r).toString(36))}},{}],84:[function(t,e,n){var a=t(68)("wks"),r=t(83),i=t(30).Symbol;e.exports=function(t){return a[t]||(a[t]=i&&i[t]||(i||r)("Symbol."+t))}},{30:30,68:68,83:83}],85:[function(t,e,n){var a=t(11),r=t(84)("iterator"),i=t(46);e.exports=t(17).getIteratorMethod=function(t){return void 0!=t?t[r]||t["@@iterator"]||i[a(t)]:void 0}},{11:11,17:17,46:46,84:84}],86:[function(t,e,n){"use strict";var a,r=t(47),i=t(23),o=t(20),s=t(60),p=t(33),u=t(21),c=t(31),l=t(12),f=t(34),d=t(25),h=t(5),m=t(3),v=t(39),g=t(81),b=t(79),y=t(78),_=t(77),x=t(80),w=t(35),k=t(83)("__proto__"),P=t(9),C=t(8)(!1),E=Object.prototype,S=Array.prototype,A=S.slice,O=S.join,T=r.setDesc,M=r.getDesc,R=r.setDescs,j={};o||(a=!d(function(){return 7!=T(u("div"),"a",{get:function(){return 7}}).a}),r.setDesc=function(t,e,n){if(a)try{return T(t,e,n)}catch(r){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(h(t)[e]=n.value),t},r.getDesc=function(t,e){if(a)try{return M(t,e)}catch(n){}return c(t,e)?s(!E.propertyIsEnumerable.call(t,e),t[e]):void 0},r.setDescs=R=function(t,e){h(t);for(var n,a=r.getKeys(e),i=a.length,o=0;i>o;)r.setDesc(t,n=a[o++],e[n]);return t}),i(i.S+i.F*!o,"Object",{getOwnPropertyDescriptor:r.getDesc,defineProperty:r.setDesc,defineProperties:R});var L="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),N=L.concat("length","prototype"),D=L.length,F=function(){var t,e=u("iframe"),n=D,a=">";for(e.style.display="none",p.appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write("