diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql
index 043a47a02ad..c6045cd835e 100644
--- a/SQL/paradise_schema.sql
+++ b/SQL/paradise_schema.sql
@@ -446,10 +446,13 @@ DROP TABLE IF EXISTS `erro_watch`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `erro_watch` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) NOT NULL,
`reason` text NOT NULL,
- PRIMARY KEY (`id`)
+ `timestamp` datetime NOT NULL,
+ `adminckey` varchar(32) NOT NULL,
+ `last_editor` varchar(32),
+ `edits` text,
+ PRIMARY KEY (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index 678e2ca9a95..180bf9b4d4b 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -2782,7 +2782,7 @@
"bbz" = (/obj/structure/closet/wardrobe/xenos,/turf/simulated/floor,/area/crew_quarters/locker)
"bbA" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/crew_quarters/locker)
"bbB" = (/turf/simulated/floor,/area/crew_quarters/locker)
-"bbC" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/vending/cola,/turf/simulated/floor,/area/crew_quarters/locker)
+"bbC" = (/obj/machinery/vending/cola,/turf/simulated/floor,/area/crew_quarters/locker)
"bbD" = (/obj/machinery/vending/artvend,/turf/simulated/floor,/area/crew_quarters/locker)
"bbE" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/crew_quarters/locker)
"bbF" = (/obj/machinery/vending/clothing,/turf/simulated/floor,/area/crew_quarters/locker)
@@ -3821,7 +3821,7 @@
"bvy" = (/obj/structure/morgue,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office)
"bvz" = (/obj/structure/morgue,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor,/area/medical/morgue)
"bvA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/asmaint)
-"bvB" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor,/area/assembly/chargebay)
+"bvB" = (/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor,/area/crew_quarters/locker)
"bvC" = (/turf/simulated/floor,/area/assembly/chargebay)
"bvD" = (/obj/machinery/door_control{dir = 2; id = "mechbay"; name = "Mech Bay Door Control"; pixel_x = 6; pixel_y = 24; req_access_txt = "29"},/turf/simulated/floor{tag = "icon-warningcorner (WEST)"; icon_state = "warningcorner"; dir = 8},/area/assembly/chargebay)
"bvE" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/assembly/chargebay)
@@ -3917,7 +3917,7 @@
"bxq" = (/obj/structure/morgue{tag = "icon-morgue1 (WEST)"; icon_state = "morgue1"; dir = 8},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor,/area/medical/morgue)
"bxr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 12},/turf/simulated/floor/plating,/area/maintenance/asmaint)
"bxs" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/assembly/chargebay)
-"bxt" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/bluegrid,/area/assembly/chargebay)
+"bxt" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor,/area/assembly/chargebay)
"bxu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/bluegrid,/area/assembly/chargebay)
"bxv" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/assembly/chargebay)
"bxw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/assembly/chargebay)
@@ -4286,14 +4286,14 @@
"bEv" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
"bEw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
"bEx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
-"bEy" = (/obj/machinery/camera{c_tag = "Medbay Fore Starboard"; network = list("SS13")},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/power/apc{dir = 1; name = "Medbay APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
-"bEz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/closet/walllocker/emerglocker/north,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
-"bEA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2)
+"bEy" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/bluegrid,/area/assembly/chargebay)
+"bEz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/closet/walllocker/emerglocker/north,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
+"bEA" = (/obj/machinery/camera{c_tag = "Medbay Fore Starboard"; network = list("SS13")},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
"bEB" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
"bEC" = (/turf/simulated/floor{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/medbay2)
"bED" = (/turf/simulated/wall/r_wall,/area/medical/medbay2)
-"bEE" = (/obj/machinery/power/apc{dir = 1; name = "Starboard Emergency Storage APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint)
-"bEF" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint)
+"bEE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2)
+"bEF" = (/obj/machinery/power/apc{dir = 1; name = "Starboard Emergency Storage APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/maintenance/asmaint)
"bEG" = (/obj/structure/table,/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/asmaint2)
"bEH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/asmaint)
"bEI" = (/obj/structure/extinguisher_cabinet{pixel_x = -27},/obj/machinery/light{dir = 8},/turf/simulated/floor/bluegrid,/area/assembly/chargebay)
@@ -4383,7 +4383,7 @@
"bGo" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/assembly/chargebay)
"bGp" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor,/area/assembly/chargebay)
"bGq" = (/obj/machinery/power/apc{dir = 4; name = "Mech Bay APC"; pixel_x = 26; pixel_y = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/assembly/chargebay)
-"bGr" = (/obj/structure/table,/obj/item/weapon/circular_saw,/obj/item/weapon/scalpel{pixel_y = 12},/obj/structure/sign/poster/legit{pixel_x = -32},/turf/simulated/floor{dir = 2; icon_state = "whitecorner"},/area/assembly/robotics)
+"bGr" = (/obj/structure/table,/obj/item/weapon/circular_saw,/obj/item/weapon/scalpel{pixel_y = 12},/turf/simulated/floor{dir = 2; icon_state = "whitecorner"},/area/assembly/robotics)
"bGs" = (/obj/structure/table,/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"; tag = ""},/obj/item/device/mmi/posibrain,/obj/item/device/robotanalyzer,/turf/simulated/floor{dir = 8; icon_state = "whitecorner"},/area/assembly/robotics)
"bGt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics)
"bGu" = (/obj/machinery/door_control{id = "robotics2"; name = "Robotics Lab Shutters Control"; pixel_x = 24; pixel_y = -24; req_access_txt = "29"},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics)
@@ -4470,7 +4470,7 @@
"bHX" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor,/area/assembly/chargebay)
"bHY" = (/obj/structure/reagent_dispensers/fueltank,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/assembly/chargebay)
"bHZ" = (/obj/machinery/recharge_station,/turf/simulated/floor{icon_state = "bot"},/area/assembly/chargebay)
-"bIa" = (/obj/structure/table,/obj/item/weapon/storage/box/bodybags{pixel_x = -1; pixel_y = -2},/obj/item/weapon/pen,/turf/simulated/floor{icon_state = "whitehall"; dir = 4},/area/assembly/robotics)
+"bIa" = (/obj/structure/table,/obj/item/weapon/storage/box/bodybags{pixel_x = -1; pixel_y = -2},/obj/item/weapon/pen,/obj/structure/sign/poster/legit{pixel_x = -32},/turf/simulated/floor{icon_state = "whitehall"; dir = 4},/area/assembly/robotics)
"bIb" = (/obj/machinery/optable{name = "Robotics Operating Table"},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics)
"bIc" = (/obj/machinery/computer/operating{name = "Robotics Operating Computer"},/obj/machinery/light,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics)
"bId" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics)
@@ -4988,7 +4988,7 @@
"bRV" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/quartermaster/qm)
"bRW" = (/obj/machinery/light,/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/sw)
"bRX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor,/area/hallway/primary/central/sw)
-"bRY" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -35},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/hallway/primary/central/sw)
+"bRY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -28},/turf/simulated/floor,/area/hallway/primary/central/sw)
"bRZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/hallway/primary/central/sw)
"bSa" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor,/area/hallway/primary/central/sw)
"bSb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/hallway/primary/central/sw)
@@ -5485,7 +5485,7 @@
"cby" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/obj/item/weapon/pen/blue,/obj/item/weapon/folder/blue{pixel_x = 4; pixel_y = 6},/obj/item/weapon/paper/blueshield,/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield)
"cbz" = (/obj/structure/sign/poster/legit{pixel_x = 32},/obj/machinery/photocopier,/turf/simulated/floor/wood,/area/blueshield)
"cbA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/wall,/area/ntrep)
-"cbB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/sign/poster/legit{pixel_x = -32},/obj/machinery/photocopier,/turf/simulated/floor/wood,/area/ntrep)
+"cbB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/photocopier,/turf/simulated/floor/wood,/area/ntrep)
"cbC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/carpet,/area/ntrep)
"cbD" = (/obj/structure/table/woodentable,/obj/machinery/computer/skills{req_access_txt = "57"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/carpet,/area/ntrep)
"cbE" = (/obj/structure/table/woodentable,/obj/item/weapon/folder,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/weapon/stamp/centcom,/obj/item/weapon/pen/fluff/fountainpen,/turf/simulated/floor/carpet,/area/ntrep)
@@ -5570,7 +5570,7 @@
"cdf" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield)
"cdg" = (/obj/item/flag/nt,/turf/simulated/floor/wood,/area/blueshield)
"cdh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/ntrep)
-"cdi" = (/obj/item/flag/nt,/turf/simulated/floor/wood,/area/ntrep)
+"cdi" = (/obj/item/flag/nt,/obj/structure/sign/poster/legit{pixel_x = -32},/turf/simulated/floor/wood,/area/ntrep)
"cdj" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/carpet,/area/ntrep)
"cdk" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/obj/machinery/camera{c_tag = "Blueshield's Office"; dir = 1; network = list("SS13")},/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = -32},/turf/simulated/floor/wood,/area/blueshield)
"cdl" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Nanotrasen Representative"},/turf/simulated/floor/carpet,/area/ntrep)
@@ -5695,7 +5695,7 @@
"cfA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
"cfB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
"cfC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/junction{dir = 8},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
-"cfD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
+"cfD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
"cfE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
"cfF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/medbay2)
"cfG" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/light{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci)
@@ -5753,7 +5753,7 @@
"cgG" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2)
"cgH" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2)
"cgI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2)
-"cgJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/power/apc{dir = 2; name = "Medbay APC"; pixel_y = -24},/obj/structure/cable,/obj/machinery/camera{c_tag = "Medbay Psych Office Corridor East"; dir = 1; network = list("SS13")},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2)
+"cgJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/camera{c_tag = "Medbay Psych Office Corridor East"; dir = 1; network = list("SS13")},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2)
"cgK" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2)
"cgL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light/small{dir = 4},/obj/machinery/vending/medical,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2)
"cgM" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci)
@@ -6114,14 +6114,14 @@
"cnD" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/toxins/xenobiology)
"cnE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Xenobiology Research"; req_access_txt = "47"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology)
"cnF" = (/obj/structure/sign/securearea,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/toxins/xenobiology)
-"cnG" = (/obj/structure/closet/bombcloset,/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
+"cnG" = (/obj/structure/closet/bombcloset,/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cnH" = (/obj/structure/closet/secure_closet/scientist,/obj/machinery/light{dir = 1; on = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cnI" = (/obj/structure/closet/secure_closet/scientist,/obj/machinery/camera{c_tag = "Research Test Lab West"; dir = 2; network = list("Research","SS13"); pixel_x = 0},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cnJ" = (/obj/machinery/alarm{pixel_y = 22},/obj/structure/table,/obj/item/device/radio/electropack,/obj/item/device/assembly/signaler,/obj/item/device/healthanalyzer,/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cnK" = (/obj/machinery/power/apc{dir = 1; name = "Testing Lab APC"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cnL" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/obj/item/clothing/ears/earmuffs,/obj/item/device/multitool,/obj/item/clothing/ears/earmuffs,/obj/structure/sign/poster/legit{pixel_y = 32},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cnM" = (/obj/structure/table,/obj/item/clothing/glasses/science,/obj/item/clothing/glasses/science,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; name = "Chemistry Cleaner"},/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; name = "Chemistry Cleaner"},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
-"cnN" = (/obj/structure/reagent_dispensers/watertank,/obj/effect/decal/warning_stripes/yellow,/obj/machinery/light{dir = 1; on = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
+"cnN" = (/obj/structure/reagent_dispensers/watertank,/obj/effect/decal/warning_stripes/yellow,/obj/machinery/light{dir = 1; on = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cnO" = (/obj/structure/reagent_dispensers/fueltank,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cnP" = (/obj/machinery/chem_dispenser,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/structure/sign/nosmoking_2{pixel_y = 32},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/toxins/misc_lab)
"cnQ" = (/obj/machinery/chem_heater,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/toxins/misc_lab)
@@ -6292,7 +6292,7 @@
"cqZ" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology)
"cra" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/stool/bed/chair/wood/wings{tag = "icon-wooden_chair_wings (EAST)"; icon_state = "wooden_chair_wings"; dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/wood,/area/crew_quarters/bar)
"crb" = (/obj/structure/window/reinforced,/obj/structure/table/reinforced,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/toxins/misc_lab)
-"crc" = (/obj/structure/rack,/obj/item/clothing/mask/gas{pixel_x = 2; pixel_y = 2},/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas{pixel_x = -2; pixel_y = -2},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
+"crc" = (/obj/structure/rack,/obj/item/clothing/mask/gas{pixel_x = 2; pixel_y = 2},/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas{pixel_x = -2; pixel_y = -2},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -28},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"crd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/closet/l3closet/scientist,/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cre" = (/obj/structure/closet/l3closet/scientist,/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"crf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
@@ -6487,7 +6487,7 @@
"cuM" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/engine,/area/toxins/test_chamber)
"cuN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/stool{pixel_y = 8},/turf/simulated/floor,/area/crew_quarters/fitness)
"cuO" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/engine,/area/toxins/test_chamber)
-"cuP" = (/obj/machinery/light{dir = 8},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/engine,/area/toxins/test_chamber)
+"cuP" = (/obj/machinery/light{dir = 8},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -28},/turf/simulated/floor/engine,/area/toxins/test_chamber)
"cuQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = 0; pixel_y = -30},/obj/structure/table,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cuR" = (/obj/structure/table/reinforced,/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/item/clothing/mask/gas,/turf/simulated/floor/engine,/area/toxins/test_chamber)
"cuS" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/machinery/power/apc{dir = 2; name = "Test Chamber APC"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor/engine,/area/toxins/test_chamber)
@@ -6557,7 +6557,7 @@
"cwe" = (/turf/simulated/wall/r_wall,/area/toxins/test_chamber)
"cwf" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 8},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/fpmaint2)
"cwg" = (/obj/effect/decal/cleanable/fungus,/turf/simulated/wall,/area/maintenance/fpmaint2)
-"cwh" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "white"},/area/space)
+"cwh" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/camera{c_tag = "Xenobiology Module North-East"; dir = 8; network = list("Research","SS13"); pixel_y = -22},/turf/simulated/floor{icon_state = "white"},/area/space)
"cwi" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating/airless/catwalk,/area/maintenance/fpmaint)
"cwj" = (/obj/item/weapon/wrench,/turf/simulated/floor/plating,/area/maintenance/fpmaint2)
"cwk" = (/obj/machinery/optable,/turf/simulated/floor/plating,/area/maintenance/fpmaint2)
@@ -8117,7 +8117,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAvaWraBmaBmaBmaBmaBmaBmaWraAvaJnazEaWuaWvaAvaWxaWyaWzaWzaWAaAyaWBaUCaWCaWDaYgcZRaWFaWGaWHaWHaWIaWJaWJaWJaWKaWLaWLaWMaWNaWOaWHaWHaWPaWQaWRaWSaWTaWTaWUbdkaWVaWQaWQaWQaWWaUWaUXaUYaUZaUZaUZaUZaWXaUZaUZaUZaUZaUZaUZaWYaWZaXaaXbaXcaXdaXeaXfaXgaXhaXiaXiaXiaXjaXkaXkaXkaXlaVyaVyaVyaXmaXnaVyaINaXoaXpaVDaVDaXqaVDaXraXsaVGaXtaSdaXuaXvaXwaXxaXyaSdaXzaXAaXBaXCaXDaXEaSlaFSaXGaFSaSlaSlaSlaSoaSlaSlaSqaLHaOQaXHaQFaQFaQFaXIaQFaXJaOVaOVaOVaOVaOVaOVaOVaXKaOVaPfaPfaPeaPfaXLaXMaNqaXNaXOaXPaXQaXRaXSaXTaXUaFTaaaaaaaaaaaaaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaIfazEaAvaCzaBmaXWaXXaXYaXZaBmaCzaAvaAvazEaYcaSPaAvaYdaYeaWzaWzaWAaAyaYfaUCaFzaWDaYgaUGaYhaYiaUGaUGaYjaYkaYlaUGaYmaYnaYoaYnaYpaYqaYnaYnaYraYnaYnclqaYtaYnaYuaYsaYvaVTaUGaUGaYwaYxaYyaYzaYAaYBaYAaYCaYDaYCaYCaYCaYCaYCaYCaYEaYFaYGaYGaYGaYGaYHaYGaYIaYJaYGaYGaYKaYLaYMaYMaYMaYMaYMaYMaYMaYNaVyaVyaINaYOaYPaYQaYRaYRaYSaYTaXsaVGaYUaSdaSdaSdaSdaSdaYVaSdaYWaYXaYYaYZaTQaZaaSlaZbaZcaZdaZeaZfaZgaZhaZiaSlaSqaWaaOQaZjaZkaQFaZlaZmaQFaZnaZnaOQaZoaZpbeKaNqaZraZsaZtaPfaPfaZuaZvaNqaZwaNqaZxaXOaZyaZzaZAaXOaXOaZBaFTaaaaaaaaaaaaaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaAyaAvaWraBmaGTaFzaFzaGUaBmaWraBmaZDaZEaZFaZGaAvaZHaZHaUzaZHaUAaAyaZIaUCaFzaAyaSUaSUaZJaZKaZKaZKaZKaZKaZKaZLaZMaZKaZKaZKaZKaZKaZKaZNaZOaZPaZPaZQaZPaJaaGCaKiaJaaJaaZUaZVaZWaSUaZXaZXaZYaZYaZYaGEaGEaGEaGEaGEaGEaGEaGEbacaGFaGFaGGaGFaGRaGRaGRaGRaHeaGZaGRbacaHgaHgaHgaHgaHgaHgaHgaHgbaobaobaoaINbapbaqbarbarbarbarbasbatbaubavbawbaxbcjbazbaAbaBaSdaSdbaCaHhaHoaHhaHhaSlbaHbaIbaJbaJbaJbaJbaKbaLaSlbaMdcjaOQbaNaQFaZlaZlaZmaZlaQFbaOaOQbaPbaQbaRaNqaPfbaSbaTbaUbaUbaVbaWbaXbaYbaZbbabbbbbcbbdaXQaXOaXObbeaFTaaaaaaaaaaaaaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtdcdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHvbbfaFzbbgbbhbbibbjbbkbblbbjbbmbbnbbjbbjbbobbpbbqbbrbbsbbsbbsbbtbbsbbubbvaAybbwbbxbbyaZKbbzbbAbbBbbCbbDbbBbbEbbFbbGbbHbbIbbJaZKbbKbbLaZPbdjbdgbdiaJabdhbbObbNaJabbQaHEbbSbbQbbQbbQbbTaUZaVeaGEaaaaaaaaaaaaaaaaaaaaabacbbVbbWbbXbWEbbZbcabcbbccbcdbcebcfbacaaaaaaaaaaaaaaaaaaaaaaHgbchaVybciaINcrgbaqbavbavbavbavbavbckbclbavbavbavbaybcmbcmbcnbcpbcrbcqbcobcubctbcsaSlbcvbcwbcxbcybcybcxbczbcAaSlaSqaLHaOQbcCbcDaQFaZlaZmaQFbcEbcEaOQaOQbcFaOQaNqbcGaZsaZvbcHbcHbcIaZvaNqaNqaNqbcJaXObcKbcKbcLbcKaXObcMaFTaabaaaaaabcNaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHvbbfaFzbbgbbhbbibbjbbkbblbbjbbmbbnbbjbbjbbobbpbbqbbrbbsbbsbbsbbtbbsbbubbvaAybbwbbxbbyaZKbbzbbAbvBbbCbbDbbBbbEbbFbbGbbHbbIbbJaZKbbKbbLaZPbdjbdgbdiaJabdhbbObbNaJabbQaHEbbSbbQbbQbbQbbTaUZaVeaGEaaaaaaaaaaaaaaaaaaaaabacbbVbbWbbXbWEbbZbcabcbbccbcdbcebcfbacaaaaaaaaaaaaaaaaaaaaaaHgbchaVybciaINcrgbaqbavbavbavbavbavbckbclbavbavbavbaybcmbcmbcnbcpbcrbcqbcobcubctbcsaSlbcvbcwbcxbcybcybcxbczbcAaSlaSqaLHaOQbcCbcDaQFaZlaZmaQFbcEbcEaOQaOQbcFaOQaNqbcGaZsaZvbcHbcHbcIaZvaNqaNqaNqbcJaXObcKbcKbcLbcKaXObcMaFTaabaaaaaabcNaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHvbcObcPbcObcObcObcObcObcObcPbcObcObcQaFzbcRbcSbcTaFzbcUaFzbcVbcWbcXbcYbcZaAybbxbbxbdaaZKbdbbbBbbBbbBbbBbbBbbEbdcbbBbbBbbBbddaZKbbKbdeaZPbdfbbMbeFaJaaZTaZSaZRaJabdlbdmbdnbdobdpaHEbbTaUZaVeaGEaaaaaaaaaaaabacbacbacbacbdrbdsbdtbdubdvbdwbdxbdybdzbdAbdBbacbacbacbacaaaaaaaaaaaaaHgbchaVybdHbdGbeTbdIcpZbjUbeTcqocqWcqqcrabdJbdKbavbaybdLbcmbdMbdNbcmbdObdPbdQbdRbcmbdSbdTbdUbcxbcybcybcxbdVbdWaSlaSqdauaOQbaNaQFaZlaZlaZmaZlaQFaQFbdYbdZaQFbeaaNqbebbecbedbcHbcHbeebedbefaNqbegbehaXObeibeibejbeiaXObbeaFTaHPaFTaFTaFTaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazEazEaAvaAvaAvaAvaAvaAvaAvaAvaAvazEaAybeqberbesbesbesbesbesbesbetbesbesbesaAybbxbbKbeuaZKbevbbBbbBbewbexbeybezbewbbBbbBbbBbeAaZKbbKbbLaZPbeBbqwbbPaJabeEcePcZXaJabeGbeHbeIbeJbnEaHEbeMbeNaVeaGEaGEbeQbacbacbacbeRbeScrlbeUbeVbeVbeWbeXbeVbeYbeVbeZbfabfbbfcbfdbfebacbacbacbeQaHgaHgbchaVyaVyaINbfgbdDbdJbdFbavbfhbfibavbfjbfkbdKbavbaybcmbcmbflbfmbfnbfobfpbfqbfrbcmbfsbdTbftbcxbcybcybfubfvbdWaSlaSqaLHaOQbfxbfybfzaZlaZmbfAaQFaQFbfBaQFbfCbfDaNqbfEbfFbfGbcHbcHbfHbfGbfIaNqbfJbehaXOaXOaXOaXQaXOaXObfKbfLbfMbfNbfObfPaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfQbfQbfQbfQbfQbfQbfQbfQbfQbfQbfQbfQaabaAvaIiaFBbfSbesbfTbfUbfVbfWbfXbfYbfZbgabesbjjbgcbgdbgeaZKbgfbbBbbBbewbeybggbghbewbbBbbBbgibgjaZKbbKbbLaZPaZPbgkaZPaJabeEbeDbhSaJabglbeJbgmbeJbgnaHEbbTbgoaVeaVfaVfbgpaHQbgrbacbgsbdtbgtbeVbeVbgubgvbgwbgxbgwbgybgzbgAbgBbgCbgDbgEbacbgFaHQbgGbgHbgIbchaVyaVyaHFbavbgJbavbavbavbgKbgLbavbfjbgMbdKbavbaybcmbcmbgNbgObgPbgQbgRbgSbfrbgTaSlbgUbftbcxbcybcybcxbfvbgVaSlbgWbgXaOQbgYaOQaOQbgZaZmbhabhbaQFbhcbhdaUgbhebaZbhfbhgbhhbhibhibhjbhkbhlbaZbhmbhnaXObhoaXOaXQaXOaXObhpaFTaHPaFTaFTaHPaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -8130,13 +8130,13 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboPboPboPboPboPboPboPboPboPboPboPaHRaAvaAvbpQbpRbpSbpSbpSbpTbpSbpSbpUbpVbpWaZOaZOaZObpXbjlbkFbpYbpZbntbjlbqabsubqaaZKaZKaZKaZKbqcaZKbqdbkQbkRbqebqfbnzbqgbqhbkRbmobkXbqibnCbnCbnCbqjbkXbqkbnHbmuaHVbqmbpqbprbqnbqobpubnNbqpbjPbqqbqrblgbqsbqtbqubmEbqvdavbqxbqybqzbqAbqBbqCbqDbnVbqEbllbqFbqGbocbodboebofbohbqHbohbohbohbohbqIbqJbqJbqJbqJbqKbohbohbohbohbqLbohbqHbqMbohbqNbqObqPbohbqQbqRbqRbqSbqTbqUbqVbkobkobkobkobkobkobkobqWbqXbqYbkobkobkobkobkobkobkobkobkobkobqZbrabrabrbbrcbrdbrebrfbrfbrfbrfbrgbrhaFTaabaaaaaaaabaNtaNtaNtaNtaNtaNtaaaaNtaNtaNtaNtdcdaNtaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboPboPboPboPboPboPboPboPboPboPboPbrjbrkbrlbrmbrnbpSbrobrpbrqbrqbrrbrsbrtbrubrvbrvbrwbrxbjlbjlbjlbmdbrybmcaZOaZOaZOaZObrzbbKbbKbrAbjybrBbrCbrDbrEbrFbrGbrHbrIbkRbrJbkXbrKbnCbnCbnCbrLaIgbrNbnHbrOblbbrPbrQbnLbnLbnLbnLbnNbrRbjPbrSbrTbjPbjPbjPbjPbjPbjPbjPblkbllbrUbrVbrWbrXbrYbrZbsabllbsbbscbscbsdbsdbsdbsdbsdbsdbsdbsebsebsfbsgbshbshbsgbsfbsebsebsibsibsibsibsibsibsjbsjbskbsjbsjbsjbsjbsjbslbsmbsnbsobkobkobspbspbsqbsqbsqbsqbsqbsrbrabrabqZbrabkobrabrabrabrabssbstbstbstbstbsFbsvbsvbsvbsvbsvbsvbsvbsvbsvaaaaaaaaaaaaaNtaNtaNtaNtaNtaNtaaaaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboPboPboPboPboPboPboPboPboPboPboPaAvaAvaAvbpQbswbpSbsxbpSaIhaIhbpSbpUbpUbdabsAbsBbsBbsCbjlbkFbsDbmdbsEbmcbsHbsGbujbsIbsJbsKbsKbsLbsKbsMbsNbkRbsObsPbsQbsRbsSbrDbsTbkXbsUbnCbnCbsVbsWbsXbrNbnHbsYblbbsZbtabtbbtcbtdbtebtfblbblbbtgbthbtibtjbtkbtjbtlbthaaabtmbllbtnbtobtpbtqbrYbnVbtrbllbtsbttbtubsdbtvbtwbtxbtybtzbtAbtBbtCbtDbtEbtFbtFbtEbtGbtHbtIbsibtJbtLbtKbtMbsibtNbtObtPbtQbtRbtSbtSbtTbslbtUbtVbtWbtXbtWbtYbtYbsqbtZbuabubbsqaImbudaImbsqbuebrabssbstaInbugaInbstbuhbuibstbuwbukbulbumaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaNtaNtaNtaNtaNtaNtaaaaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboPboPboPboPboPboPboPboPboPboPaaabunaAvbuoblUbupbpSbuqbpSburbusbutbuubpSbuvbwHbuxbuybsCbjlbjlbjlbjlbjlbjlbuzbuAbuBbuCbuDbkRbkRbkRbkRbkRbkRbkRbuEbkRbkRbkRbuFbkRbuGbuHbuIbnCbnCbnCbuJaIgbuKbnHbuLblbbuMbtablcblcblcblbbuNblbbuObuPbuQbuRbuSbuTbuUbuVbuWbuXbuYbllbuZbnVbvbbvabrYbvcbnVbllbvdbvebvfbsdbvgbvhbvibvjbvkbvlbvmbtFbtFbtFbtFbtFbtFbtFbtFbvobvpbvqbvrbvsbvtbsibvubvvbvwbvxbxqbvzbvvbEbbslbvAbtVbvBbvCbvDbvEbvEbvFbvGbvHbvIbvJbvKbvLbvMbsqbvNbvObvPbstbvQbvRbvSbvTbvTbvUbstbvVbvWbvXbumaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaNtaNtaNtaNtaNtaNtaaaaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIfazEaBmaBmaAvaAvaAvaAvaAvaAvaAvaGTbwabwbbpSbwcbwdbwebwfbwgbwhbwibgebbKbbKbbKbwjbrvbrvbrvbrvbrvbrvbwkbwlbwlbwmbwnbkRbwobDsbwqbwrbwsbwtbwubwvbkRbwwbwxbwybsTaIgbuIbnCbnCbwzbkXbkXbwAbwBbwCbwDbwEbwFbwGbzDbwIbwJbwKbwLbwMbwNbuWbwObwPbwObwPbwQbuWbuXbwRbwSbwTbwUbwVbwWbwXbwYbwZbwSbxabttbttbsdbxbbxcbxdbxebxfbsdbvmbtFbtFbtFbtFbtFbtFbtFbvnbxhbxibxjbxkbvqbxlbsibxmbxnbxobvxbEbbvzbxpbTrbslbxrbxsbxtbxubxubxvbxwbxxbxybxzbxzbxzbxAbxzbxBbxCbxDbxEbxFbxGbxHbxIbxJbxJbxJbxKbstbxLbvWbxMbumaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaNtaNtaNtaNtaNtaaaaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboPboPboPboPboPboPboPboPboPboPaaabunaAvbuoblUbupbpSbuqbpSburbusbutbuubpSbuvbwHbuxbuybsCbjlbjlbjlbjlbjlbjlbuzbuAbuBbuCbuDbkRbkRbkRbkRbkRbkRbkRbuEbkRbkRbkRbuFbkRbuGbuHbuIbnCbnCbnCbuJaIgbuKbnHbuLblbbuMbtablcblcblcblbbuNblbbuObuPbuQbuRbuSbuTbuUbuVbuWbuXbuYbllbuZbnVbvbbvabrYbvcbnVbllbvdbvebvfbsdbvgbvhbvibvjbvkbvlbvmbtFbtFbtFbtFbtFbtFbtFbtFbvobvpbvqbvrbvsbvtbsibvubvvbvwbvxbxqbvzbvvbEbbslbvAbtVbxtbvCbvDbvEbvEbvFbvGbvHbvIbvJbvKbvLbvMbsqbvNbvObvPbstbvQbvRbvSbvTbvTbvUbstbvVbvWbvXbumaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaNtaNtaNtaNtaNtaNtaaaaNtaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIfazEaBmaBmaAvaAvaAvaAvaAvaAvaAvaGTbwabwbbpSbwcbwdbwebwfbwgbwhbwibgebbKbbKbbKbwjbrvbrvbrvbrvbrvbrvbwkbwlbwlbwmbwnbkRbwobDsbwqbwrbwsbwtbwubwvbkRbwwbwxbwybsTaIgbuIbnCbnCbwzbkXbkXbwAbwBbwCbwDbwEbwFbwGbzDbwIbwJbwKbwLbwMbwNbuWbwObwPbwObwPbwQbuWbuXbwRbwSbwTbwUbwVbwWbwXbwYbwZbwSbxabttbttbsdbxbbxcbxdbxebxfbsdbvmbtFbtFbtFbtFbtFbtFbtFbvnbxhbxibxjbxkbvqbxlbsibxmbxnbxobvxbEbbvzbxpbTrbslbxrbxsbEybxubxubxvbxwbxxbxybxzbxzbxzbxAbxzbxBbxCbxDbxEbxFbxGbxHbxIbxJbxJbxJbxKbstbxLbvWbxMbumaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaNtaNtaNtaNtaNtaaaaNtaNtaNtaNtaNtaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAvbxObxPbxQbxRbxSbxSbxTbxUaFzbpSbxVaIhbwfbxXbpSbpSbpSaZOaJkaJkbyabybbyabyabyabybbyaaZOaZObkRbkRbkRbycbkRbydbydbydbydbydbydbwubyeaJlbygbyhbyibyjbykbylbymbynbyobypbyqbyrbysbytbyubyvbyvbywbyxbyybyzbyAbyBbyCbyDbthbyEbuUbyFbuSbyGbthaaabyHbyIbyJbyKbyIbyIbyIbyIbyLbllbyMbttbyNbyObyPbyQbyRbySbyTbsdbyUbyVbyWbyXbyYbyZbzabzbbtFbzcbsibzdbxkbzebzfbsibzgbzhbvwbvxbEbbvzbvvbEbbslbvAbtVbzibzjbzkbzlbzmaJmbzobzpbzqbzrbzsbztbzubsqbzvbzwbzxbstbzybzzbzAbvTbzBbzCbstbxLbvWbAhbumaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAvbzEbzFbzGaFyaFybzHbzIaFybzJbpSbzKaJMaKbbzNbpSaaaaaaaaaaabaabbzObzObzObzObzObzObzOaaaaaaaKcbzQbzRbzSbzTbydbydbydbydbydbydbzUbzVbzWbzXbzYbzZbAaaKdbkXbkXbAcbBWbkXbkXbAdbAebAfbAgbBubAibAibAjbAibAkbAlbAmbAnbyDbthbAobtjbtjbtjbApbthaaabyHbyIbAqbArbAsbAtbAubAvbAwbAxbAybttbAzbsdbtvbAAbABbACbADbAEbAFbAGbAHbAIbAJbAKbALbAMbANbAObAPbAQbxkbARbASbsibATbAUbAVbAWbAXbAYbAZbtTbslbBabBbbBcbBdbBdbBebBfaKjbBhbBibBjbBkbBlbBmbBnbsqbBobzwbBpbstbBqbBrbBsbvTbvTbBtbstbvVbvWbEGbumaaaaaaaaaaaaaabbBvbBwbBxbBwbBxbBwbByaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBzaAvbBAbBAaMWaAvaAvaIfazEbBDbBCbpSbBEbBFaKbaKbbpSaaaaaaaaaaaaaaabzObzObzObzObzObzObzOaaaaaaaKcbBJbydbBKbBLbBLbBLbBLbBLbBMbBNbBLbBObBPbBQbBRbBSbBTbBUbkXbBVbnCbKebBXaIgbBZbCabCbbAgbAgbAmbCcbCdbCebCfbCgbAmbtgbyDbthaNIaPwbCjaRvaPAbthaaabCmbyIbCnbCobCpbCqbCrbCqbCsbCtbCubttbCvbsdaSVaSOaSObCzbCAbCBbCCbCDbCEbCFbCGbCGbCHbCIbCJbCKbsibAQbCLaSXbsibsibsjbCNbCObCPbsjbslbslbslbCQbCRbtVbCSbzjbzkbCTbBdaKjbCVbCWbCWbCXbvIbCYbCZbDabDbbvObDcbstbDdbDebvTbDfbDgbDhbstbxLbDibumbumaaaaaaaaaaaaaabbDjbDkbDlbDmbDnbDobDjaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabDpbDpbDpbDpbDpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabzObzObzObzObzObzObzOaSZaKcaKcbDubDvbDwbDxbDxbDxbDvbydbwubyebydbydaJlbDybDzbDAbDBbDCbDDbDEbnCbnCbDFaIgbBZbCabDHbDIbDJbDKbDLbDMbDNbDObDPbAmbDQbDRbuQbDSbDTbDUbDVbDWbuWbuXbDXbyIbDYbDZbEabCqbTFbCqbEcbCtbEdbttbEebsdbEfbEgbEhbEibEjbEkbElbEmbEnbEnaTabEpbEnbEnbEqbErbEsbEtbEubEvbEwbExbEybEzbEAbEBbECbEDbEEbEFbEYbEHbtVbEIbEJbEKbELbEMbvFbENbCWbCWbEObEPbCYbEQbsqbERbERbESbstbETbEUcHibEWbvTbEXbstbxLbHVbumaaaaaaaaaaaaaaaaabbEZbFabDlbDnbDlbFbbBxaabaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabDpbDpbDpbDpbDpbDpbDpaaaaaaaaaaaaaaaaaaaaaaaaaaabDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabzObzObzObzObzObzObzObFcbFdbFcbFebFfbFgbFfbFfbFfbFfbFhbwubyebFibkRbkRbFjbnCbyhbDBbFkaIgbFmbFnbFnbFobFpbFqbFrbFsaTbbFuaTcbFwbFxbFybFzbFAbAmbAnbyDbthbFBbFCbFDbFEbFFbthaaabCmbFGbFHbFGbFGbFGbFGbFGbFIbFGbFJbttbEebsdbFKbFLbFLbFMbFNbCBbFObFPaTebFRbFSbFTbFUaTebFVbFWbFXbFYbFZbGabGbbGbbGcbGdbGebGfbGgbGhbGibGjbGkbGlbGmbGnbGnbGobGpbGqbvFbGrbvIbvIbGsbGtbCYbGubGvbGwbGxbGybGzbGAaTnaTfbGDaTfbstbstbGFbDbbDbaToaToaToaToaTobDbbDjbDnbDlbDnbDnbGJbDjaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabDpbDpbDpbDpbDpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabzObzObzObzObzObzObzOaSZaKcaKcbDubDvbDwbDxbDxbDxbDvbydbwubyebydbydaJlbDybDzbDAbDBbDCbDDbDEbnCbnCbDFaIgbBZbCabDHbDIbDJbDKbDLbDMbDNbDObDPbAmbDQbDRbuQbDSbDTbDUbDVbDWbuWbuXbDXbyIbDYbDZbEabCqbTFbCqbEcbCtbEdbttbEebsdbEfbEgbEhbEibEjbEkbElbEmbEnbEnaTabEpbEnbEnbEqbErbEsbEtbEubEvbEwbExbEAbEzbEEbEBbECbEDbEFbHTbEYbEHbtVbEIbEJbEKbELbEMbvFbENbCWbCWbEObEPbCYbEQbsqbERbERbESbstbETbEUcHibEWbvTbEXbstbxLbHVbumaaaaaaaaaaaaaaaaabbEZbFabDlbDnbDlbFbbBxaabaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabDpbDpbDpbDpbDpbDpbDpaaaaaaaaaaaaaaaaaaaaaaaaaaabDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabzObzObzObzObzObzObzObFcbFdbFcbFebFfbFgbFfbFfbFfbFfbFhbwubyebFibkRbkRbFjbnCbyhbDBbFkaIgbFmbFnbFnbFobFpbFqbFrbFsaTbbFuaTcbFwbFxbFybFzbFAbAmbAnbyDbthbFBbFCbFDbFEbFFbthaaabCmbFGbFHbFGbFGbFGbFGbFGbFIbFGbFJbttbEebsdbFKbFLbFLbFMbFNbCBbFObFPaTebFRbFSbFTbFUaTebFVbFWbFXbFYbFZbGabGbbGbbGcbGdbGebGfbGgbGhbGjbGibGkbGlbGmbGnbGnbGobGpbGqbvFbGrbvIbvIbGsbGtbCYbGubGvbGwbGxbGybGzbGAaTnaTfbGDaTfbstbstbGFbDbbDbaToaToaToaToaTobDbbDjbDnbDlbDnbDnbGJbDjaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabDpbDpbDpbDpbDpbDpbDpbDpbDpaaaaaaaaaaaaaaaaaaaaabDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabzObzObzObzObzObzObzObGKbGLbGKbGMbydbDwbDxbDxbDxbydbydbwubyebGNbGObkRbEVbnCbyhbDBbGQaIgbGSbnCbplbnCbGTbBZbttbGUaTbbFuaTqbGXbGYbGZbHabHbbHcbHdbHebHfbHfbHgbHhbHibthbthaaabCmbFGbHjbHkbHlbHmbHnbHobHpbHqbHrbttbEebAEbHsbHtbHubHvbHwbCBbHxbHybHzbHAbHBbHCbHDbHEbHFbHGbHHbHIbHJbHKbHLbHMbHNbHObHPbHQbHRbEDbHSbHTbHUbZMbtWbHWbHXbHYbHZbHZbvFbIabIbbIcbvFbIdbCYbIebvFbIfbIgbIhbIibIjbIkbIlbImbInbIobIpbIqbIrbIsbItbItbIubIvbIwaTrbIybBwbBxbIzbBxbBwbIAaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabDpbDpbDpbDpbDpbDpbDpbDpbDpaaaaaaaaaaaaaaaaaabDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabzObzObzObzObzObzObzOaSZaKcaKcbIDbydbDwbydbydbydbydbydbwubyebGNbIEbkRbIFbnCbIGbIHbnCbIIbnBbnCbnCbIJaIgbBZbttbGUaTbbFubAmbIKbILbIMbINbIObIPbIQbIRbISbITbuWbIUbIVbuWbuXbuXbIWbFGbIXbIYbIZbJabJbbJbbJcbJdbJebttbJfbsdbCBbJgaSVbJibJjbCBbHxbJkbJlbJmbJnbJobJpbJlbHxbJqbJrbJsbJsbJsbJtbJsbJubJubJvbJwbJxbJybJybJzbJxbJxbJybJybJAbJBbJAbJAbvFbvFbvFbvFbvFaTsbJDaJmbvFbJFbJGbJHbJIbJIbJJbJKbJLbJMbJNbJObJPbJQbJRbJSbJSbJTbIjbJUbDbaTTaTTaTTbJYbDbbJZaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkxbkxbkxbkxbkxbkxbkxbkxbkxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabDpbDpbDpbDpbDpbDpbDpbDpbDpaaaaaaaaaaaaaaaaaabDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqbDqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabzObzObzObzObzObzObzObGKbGLbGKbDubKabKbbydbydbydbKabydbwubyebGNbKcbkRbKdbnCbyhbDBbnCbkXbYmbnCbnCbKfaIgbBZbttbKgaTbbKibAmbKjbKkbKlbKmbKnbIPbKobKpbKqbKrbKsbKtbKubKvaaaaaaaaabFGbKwbKxbKybKybKzbKAbKBbFGbKCbKDbEebKEbKFbKGbKHbKIbKJbKKbKLbHyaWsbKNbKObKPbKQaWsbHxbJqbKRbKSbKTbKUbKVbKWbJubKXbKYbKZbJxbLabLbbLcbLdbLebLfbLgbIobLhbJIbJIbLibLjbJIbLkbLlbLmbLnbLobJIbLpbLqbLraWwaWtaXFbLvbLwbLvbLvbLvbGFbDbbDbaToaTobDbbLxbLybLzbLAbLBbLCbLDaTTaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm
index 4b8f65601af..dd5ce7b52c6 100644
--- a/code/__DEFINES/genetics.dm
+++ b/code/__DEFINES/genetics.dm
@@ -7,6 +7,8 @@
#define DISABILITY_FLAG_FAT 2
#define DISABILITY_FLAG_EPILEPTIC 4
#define DISABILITY_FLAG_DEAF 8
+#define DISABILITY_FLAG_BLIND 16
+#define DISABILITY_FLAG_MUTE 32
///////////////////////////////////////
// MUTATIONS
@@ -93,4 +95,4 @@
//sdisabilities
#define BLIND 1
#define MUTE 2
-#define DEAF 4
\ No newline at end of file
+#define DEAF 4
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index 66f412bdfa8..d7dcc2287a6 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -3,7 +3,7 @@
icon = 'icons/obj/wizard.dmi'
icon_state = "soulstone"
item_state = "electronic"
- desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artefacts power."
+ desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artifact's power."
w_class = 1.0
slot_flags = SLOT_BELT
origin_tech = "bluespace=4;materials=4"
@@ -16,16 +16,20 @@
if(!istype(M, /mob/living/carbon/human))//If target is not a human.
return ..()
if(istype(M, /mob/living/carbon/human/dummy))
- return..()
+ return ..()
if(M.has_brain_worms()) //Borer stuff - RR
user << "This being is corrupted by an alien intelligence and cannot be soul trapped."
- return..()
+ return ..()
+
+ if(jobban_isbanned(M, "cultist") || jobban_isbanned(M, "Syndicate"))
+ user << "A mysterious force prevents you from trapping this being's soul."
+ return ..()
- M.attack_log += text("\[[time_stamp()]\] Has had their soul captured with [src.name] by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to capture the soul of [M.name] ([M.ckey])")
+ M.attack_log += text("\[[time_stamp()]\] Has had their soul captured with [src.name] by [key_name(user)]")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to capture the soul of [key_name(M)]")
- log_attack("[user.name] ([user.ckey]) used the [src.name] to capture the soul of [M.name] ([M.ckey])")
+ log_attack("[key_name(user)] used the [src.name] to capture the soul of [key_name(M)]")
transfer_soul("VICTIM", M, user)
@@ -221,6 +225,8 @@
return
/proc/makeNewConstruct(var/mob/living/simple_animal/construct/ctype, var/mob/target, var/mob/stoner = null, cultoverride = 0)
+ if(jobban_isbanned(target, "cultist") || jobban_isbanned(target, "Syndicate"))
+ return
var/mob/living/simple_animal/construct/newstruct = new ctype(get_turf(target))
newstruct.faction |= "\ref[stoner]"
newstruct.key = target.key
diff --git a/code/game/machinery/Freezer.dm b/code/game/machinery/Freezer.dm
index 86ec3c9d9bc..220ceb12df7 100644
--- a/code/game/machinery/Freezer.dm
+++ b/code/game/machinery/Freezer.dm
@@ -80,12 +80,16 @@
return
/obj/machinery/atmospherics/unary/cold_sink/freezer/attack_ai(mob/user as mob)
- src.attack_hand(user)
+ attack_hand(user)
+
+/obj/machinery/atmospherics/unary/cold_sink/freezer/attack_ghost(mob/user as mob)
+ attack_hand(user)
/obj/machinery/atmospherics/unary/cold_sink/freezer/attack_hand(mob/user as mob)
if(panel_open)
user << "Close the maintenance panel first."
return
+
src.ui_interact(user)
/obj/machinery/atmospherics/unary/cold_sink/freezer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
@@ -137,9 +141,6 @@
src.add_fingerprint(usr)
return 1
-/obj/machinery/atmospherics/unary/cold_sink/freezer/process()
- ..()
-
/obj/machinery/atmospherics/unary/cold_sink/freezer/power_change()
..()
if(stat & NOPOWER)
@@ -234,7 +235,10 @@
return
/obj/machinery/atmospherics/unary/heat_reservoir/heater/attack_ai(mob/user as mob)
- src.attack_hand(user)
+ attack_hand(user)
+
+/obj/machinery/atmospherics/unary/heat_reservoir/heater/attack_ghost(mob/user as mob)
+ src.attack_hand(user)
/obj/machinery/atmospherics/unary/heat_reservoir/heater/attack_hand(mob/user as mob)
if(panel_open)
@@ -275,6 +279,8 @@
ui.set_auto_update(1)
/obj/machinery/atmospherics/unary/heat_reservoir/heater/Topic(href, href_list)
+ if(..())
+ return 1
if (href_list["toggleStatus"])
src.on = !src.on
update_icon()
@@ -287,9 +293,6 @@
src.add_fingerprint(usr)
return 1
-/obj/machinery/atmospherics/unary/heat_reservoir/heater/process()
- ..()
-
/obj/machinery/atmospherics/unary/heat_reservoir/heater/power_change()
..()
if(stat & NOPOWER)
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 0c250f3d1cd..7509a79639b 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -99,18 +99,22 @@
default_deconstruction_crowbar(G)
/obj/machinery/sleep_console/attack_ai(mob/user as mob)
- return src.attack_hand(user)
+ return attack_hand(user)
+
+/obj/machinery/sleep_console/attack_ghost(mob/user as mob)
+ return attack_hand(user)
/obj/machinery/sleep_console/attack_hand(mob/user as mob)
- if(..())
- return
if(stat & (NOPOWER|BROKEN))
return
+
if (panel_open)
user << "Close the maintenance panel first."
return
+
if (!src.connected)
findsleeper()
+
if (src.connected)
var/mob/living/occupant = src.connected.occupant
var/dat = "Occupant Statistics:
"
@@ -163,10 +167,12 @@
/obj/machinery/sleep_console/Topic(href, href_list)
if(..())
- return
+ return 1
+
if(panel_open)
usr << "Close the maintenance panel first."
- return
+ return 1
+
if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
usr.set_machine(src)
if (href_list["chemical"])
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index a02e47faa8d..4ffe2a33052 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -39,8 +39,6 @@
component_parts += new /obj/item/stack/cable_coil(null, 2)
RefreshParts()
-/obj/machinery/bodyscanner/RefreshParts()
-
/obj/machinery/bodyscanner/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob)
if (istype(G, /obj/item/weapon/screwdriver))
if(src.occupant)
@@ -278,8 +276,6 @@
RefreshParts()
findscanner()
-/obj/machinery/body_scanconsole/RefreshParts()
-
/obj/machinery/body_scanconsole/ex_act(severity)
switch(severity)
if(1.0)
@@ -352,20 +348,23 @@
default_deconstruction_crowbar(G)
-
/obj/machinery/body_scanconsole/attack_ai(user as mob)
- return src.attack_hand(user)
+ return attack_hand(user)
+
+/obj/machinery/body_scanconsole/attack_ghost(user as mob)
+ return attack_hand(user)
/obj/machinery/body_scanconsole/attack_hand(user as mob)
- if(..())
- return
if(stat & (NOPOWER|BROKEN))
return
+
if (panel_open)
user << "Close the maintenance panel first."
return
+
if(!src.connected)
findscanner()
+
if (src.connected)
if(!connected.occupant)
user << "The scanner is empty."
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 5d6c2ff7730..d181367d6b9 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -434,11 +434,9 @@
for(var/device_id in alarm_area.air_scrub_names)
send_signal(device_id, list(
"power"= 1,
- "co2_scrub"= 1,
"o2_scrub" = (preset==AALARM_PRESET_VOX),
- "tox_scrub"= 0,
- "n2_scrub"= 1,
- "n2o_scrub"= 0,
+ "n2_scrub" = 0,
+ "co2_scrub"= 1,
"scrubbing"= 1,
"widenet"= 0,
))
@@ -454,7 +452,6 @@
"power"= 1,
"co2_scrub"= 1,
"tox_scrub"= 1,
- "n2_scrub"= 1,
"n2o_scrub"= 1,
"scrubbing"= 1,
"widenet"= 1,
@@ -484,7 +481,6 @@
"power"= 1,
"co2_scrub"= 1,
"tox_scrub"= 0,
- "n2_scrub"= 0,
"n2o_scrub"= 0,
"scrubbing"= 1,
"widenet"= 0,
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index 4fda7a334d3..4f6957afe22 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -22,6 +22,13 @@
return
ui_interact(user)
+
+/obj/machinery/computer/robotics/proc/is_authenticated(var/mob/user as mob)
+ if(isobserver(user) && check_rights(R_ADMIN, 0, user))
+ return 1
+ else if(allowed(user))
+ return 1
+ return 0
/obj/machinery/computer/robotics/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
@@ -31,7 +38,7 @@
data["safety"] = safety
// Also applies for cyborgs. Hides the manual self-destruct button.
data["is_ai"] = issilicon(user)
- data["allowed"] = src.allowed(user)
+ data["allowed"] = is_authenticated(user)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
@@ -43,10 +50,11 @@
/obj/machinery/computer/robotics/Topic(href, href_list)
if(..())
- return
+ return 1
+
var/mob/user = usr
- if(!src.allowed(user))
- user << "Access Denied."
+ if(!is_authenticated(user))
+ user << "Access denied."
return
// Destroys the cyborg
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index 126cfd70a70..638887b0fbe 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -153,6 +153,9 @@
go_out()
return
+/obj/machinery/atmospherics/unary/cryo_cell/attack_ghost(mob/user)
+ return attack_hand(user)
+
/obj/machinery/atmospherics/unary/cryo_cell/attack_hand(mob/user)
if(panel_open)
usr << "\blue Close the maintenance panel first."
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 37220d43956..7ff7cc466d8 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -241,8 +241,15 @@
else if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/H = user
- if(!isnull(H.internal_organs_by_name["cell"]))
- can_accept_user = 1
+
+ if(H.stat == DEAD)
+ return
+ if(occupant)
+ H << "The cell is already occupied!"
+ return
+ if(isnull(H.internal_organs_by_name["cell"]))
+ return
+ can_accept_user = 1
if(!can_accept_user)
user << "Only non-organics may enter the recharger!"
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index 1727a4f25fa..18d5a433990 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -167,8 +167,8 @@
chassis.use_power(energy_drain)
log_message("Honked from [src.name]. HONK!")
var/turf/T = get_turf(src)
- message_admins("[key_name_admin(chassis.occupant, chassis.occupant.client)](?) (FLW) used a Mecha Honker in ([T.x],[T.y],[T.z] - JMP)",0,1)
- log_game("[chassis.occupant.ckey]([chassis.occupant]) used a Mecha Honker in ([T.x],[T.y],[T.z])")
+ msg_admin_attack("[key_name_admin(chassis.occupant)] used a Mecha Honker in ([T.x], [T.y], [T.z] - JMP)")
+ log_game("[key_name(chassis.occupant)] used a Mecha Honker in [T.x], [T.y], [T.z]")
do_after_cooldown()
return
@@ -242,8 +242,8 @@
set_ready_state(0)
log_message("Fired from [src.name], targeting [target].")
var/turf/T = get_turf(src)
- message_admins("[key_name(chassis.occupant, chassis.occupant.client)](?) fired a [src] in ([T.x],[T.y],[T.z] - JMP)",0,1)
- log_game("[key_name(chassis.occupant)] fired a [src] ([T.x],[T.y],[T.z])")
+ msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - JMP)")
+ log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]")
do_after_cooldown()
return
@@ -358,8 +358,8 @@
projectiles--
log_message("Fired from [src.name], targeting [target].")
var/turf/T = get_turf(src)
- message_admins("[key_name(chassis.occupant, chassis.occupant.client)](?) (FLW) fired a [src] in ([T.x],[T.y],[T.z] - JMP)",0,1)
- log_game("[key_name(chassis.occupant)] fired a [src] ([T.x],[T.y],[T.z])")
+ msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - JMP)")
+ log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]")
do_after_cooldown()
return
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index af8ac8cc04f..5c50910f303 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -13,6 +13,7 @@
var/global/list/datum/stack_recipe/metal_recipes = list ( \
new/datum/stack_recipe("stool", /obj/structure/stool, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("chair", /obj/structure/stool/bed/chair, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("wheelchair", /obj/structure/stool/bed/chair/wheelchair, 15, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("bed", /obj/structure/stool/bed, 2, one_per_turf = 1, on_floor = 1), \
null, \
new/datum/stack_recipe_list("office chairs",list( \
diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm
index 7e49a4465b9..87bd6a78d5d 100644
--- a/code/game/objects/items/weapons/dna_injector.dm
+++ b/code/game/objects/items/weapons/dna_injector.dm
@@ -62,7 +62,7 @@
/obj/item/weapon/dnainjector/proc/inject(mob/living/M as mob, mob/user as mob)
if(istype(M,/mob/living))
- M.apply_effect(rand(10,25),IRRADIATE,0)
+ M.apply_effect(rand(10,25),IRRADIATE,0,1)
if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed
// UI in syringe.
@@ -97,6 +97,7 @@
var/mob/living/carbon/human/H = M
if(H.species.flags & NO_DNA_RAD)
return
+
if (!usr.IsAdvancedToolUser())
return
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index 2d62be62449..e04289a4479 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -42,7 +42,7 @@ var/global/normal_ooc_colour = "#002eb8"
display_colour = "#0099cc" //light blue
if(check_rights(R_MOD,0) && !check_rights(R_ADMIN,0))
display_colour = "#184880" //dark blue
- else if(holder.rights & R_ADMIN)
+ else if(check_rights(R_ADMIN,0))
if(config.allow_admin_ooccolor)
display_colour = src.prefs.ooccolor
else
@@ -124,7 +124,7 @@ var/global/normal_ooc_colour = "#002eb8"
if(!M.client)
continue
var/client/C = M.client
- if(check_rights(R_MOD,0))
+ if(check_rights(R_MOD,0,M))
continue //they are handled after that
if(C.prefs.toggles & CHAT_LOOC)
@@ -142,7 +142,7 @@ var/global/normal_ooc_colour = "#002eb8"
display_name = "[S.name]/([S.key])"
for(var/client/C in admins)
- if(check_rights(R_MOD,0))
+ if(check_rights(R_MOD,0,C.mob))
if(C.prefs.toggles & CHAT_LOOC)
var/prefix = "(R)LOOC"
if (C.mob in heard)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 060518108a1..df5db483430 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -51,22 +51,26 @@ var/global/nologevent = 0
else
body += " \[Heal\] "
- body += {"
-
\[
- VV -
- TP -
- PM -
- SM -
- [admin_jump_link(M, src)]\]
- Mob type = [M.type]
- Kick |
- Warn |
- Ban |
- Jobban |
- Appearance Ban |
- Notes |
- Watchlist Flag
- "}
+ body += "
\[ "
+ body += "VV - "
+ body += "TP -"
+ body += "PM -"
+ body += "SM -"
+ body += "[admin_jump_link(M, src)]\]
"
+
+ body += "Mob type = [M.type]
"
+
+ body += "Kick | "
+ body += "Warn | "
+ body += "Ban | "
+ body += "Jobban | "
+ body += "Appearance Ban | "
+ body += "Notes | "
+ if(M.client.check_watchlist(M.client.ckey))
+ body += "Remove from Watchlist | "
+ body += "Edit Watchlist Reason "
+ else
+ body += "Add to Watchlist "
if(M.client)
body += "| Prison | "
diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm
index aea9f51f715..0fc31b8848a 100644
--- a/code/modules/admin/admin_investigate.dm
+++ b/code/modules/admin/admin_investigate.dm
@@ -26,7 +26,7 @@
F << "[time_stamp()] \ref[src] ([x],[y],[z]) || [src] [message]
"
//ADMINVERBS
-/client/proc/investigate_show( subject in list("hrefs","pda","singulo","atmos","ntsl","gold core","cult") )
+/client/proc/investigate_show( subject in list("hrefs","pda","singulo","atmos","watchlist","ntsl","gold core","cult") )
set name = "Investigate"
set category = "Admin"
if(!holder) return
@@ -75,4 +75,7 @@
if(!F)
src << "Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed."
return
- src << browse(F,"window=investigate[subject];size=800x300")
\ No newline at end of file
+ src << browse(F,"window=investigate[subject];size=800x300")
+
+ if("watchlist")
+ watchlist_show()
\ No newline at end of file
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index dc66fdd713d..0ac5b340400 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -386,12 +386,12 @@
mins = min(525599,mins)
minutes = CMinutes + mins
duration = GetExp(minutes)
- reason = input(usr,"Reason?","reason",reason2) as text|null
+ reason = input(usr,"Please state the reason","Reason",reason2) as message|null
if(!reason) return
if("No")
temp = 0
duration = "Perma"
- reason = input(usr,"Reason?","reason",reason2) as text|null
+ reason = input(usr,"Please state the reason","Reason",reason2) as message|null
if(!reason) return
log_admin("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]")
@@ -437,7 +437,7 @@
else switch(alert("Appearance ban [M.ckey]?",,"Yes","No", "Cancel"))
if("Yes")
- var/reason = input(usr,"Reason?","reason","Metafriender") as text|null
+ var/reason = input(usr,"Please state the reason","Reason") as message|null
if(!reason)
return
ban_unban_log_save("[key_name(usr)] appearance banned [key_name(M)]. reason: [reason]")
@@ -870,7 +870,7 @@
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(!mins)
return
- var/reason = input(usr,"Reason?","Please State Reason","") as text|null
+ var/reason = input(usr,"Please state the reason","Reason","") as message|null
if(!reason)
return
@@ -894,7 +894,7 @@
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
if("No")
- var/reason = input(usr,"Reason?","Please State Reason","") as text|null
+ var/reason = input(usr,"Please state the reason","Reason","") as message|null
if(reason)
var/msg
for(var/job in notbannedlist)
@@ -1004,7 +1004,7 @@
if(!mins)
return
if(mins >= 525600) mins = 525599
- var/reason = input(usr,"Reason?","reason","Griefer") as text|null
+ var/reason = input(usr,"Please state the reason","Reason") as message|null
if(!reason)
return
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
@@ -1024,7 +1024,7 @@
del(M.client)
//del(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends.
if("No")
- var/reason = input(usr,"Reason?","reason","Griefer") as text|null
+ var/reason = input(usr,"Please state the reason","Reason") as message|null
if(!reason)
return
switch(alert(usr,"IP ban?",,"Yes","No","Cancel"))
@@ -1050,62 +1050,50 @@
if("Cancel")
return
+
//Watchlist
- else if(href_list["watchlist"])
- if(!check_rights(R_ADMIN)) return
- var/mob/M = locate(href_list["watchlist"])
- if(!dbcon.IsConnected())
- usr << "Failed to establish database connection."
+ else if(href_list["watchadd"])
+ var/target_ckey = locate(href_list["watchadd"])
+ usr.client.watchlist_add(target_ckey)
+
+ else if(href_list["watchremove"])
+ var/target_ckey = href_list["watchremove"]
+ var/confirm = alert("Are you sure you want to remove [target_ckey] from the watchlist?", "Confirm Watchlist Removal", "Yes", "No")
+ if(confirm == "Yes")
+ usr.client.watchlist_remove(target_ckey)
+
+ else if(href_list["watchedit"])
+ var/target_ckey = href_list["watchedit"]
+ usr.client.watchlist_edit(target_ckey)
+
+ else if(href_list["watchaddbrowse"])
+ usr.client.watchlist_add(null, 1)
+
+ else if(href_list["watchremovebrowse"])
+ var/target_ckey = href_list["watchremovebrowse"]
+ usr.client.watchlist_remove(target_ckey, 1)
+
+ else if(href_list["watcheditbrowse"])
+ var/target_ckey = href_list["watcheditbrowse"]
+ usr.client.watchlist_edit(target_ckey, 1)
+
+ else if(href_list["watchsearch"])
+ var/target_ckey = href_list["watchsearch"]
+ usr.client.watchlist_show(target_ckey)
+
+ else if(href_list["watchshow"])
+ usr.client.watchlist_show()
+
+ else if(href_list["watcheditlog"])
+ var/target_ckey = sanitizeSQL("[href_list["watcheditlog"]]")
+ var/DBQuery/query_watchedits = dbcon.NewQuery("SELECT edits FROM [format_table_name("watch")] WHERE ckey = '[target_ckey]'")
+ if(!query_watchedits.Execute())
+ var/err = query_watchedits.ErrorMsg()
+ log_game("SQL ERROR obtaining edits from watch table. Error : \[[err]\]\n")
return
- if(!ismob(M))
- usr << "This can only be used on instances of type /mob"
- return
- if(!M.ckey)
- usr << "This mob has no ckey"
- return
- var/sql_ckey = sanitizeSQL(M.ckey)
- var/DBQuery/query = dbcon.NewQuery("SELECT ckey FROM [format_table_name("watch")] WHERE (ckey = '[sql_ckey]')")
- query.Execute()
- if(query.NextRow())
- switch(alert(usr, "Ckey already flagged", "[sql_ckey] is already on the watchlist, do you want to:", "Remove", "Edit reason", "Cancel"))
- if("Cancel")
- return
- if("Remove")
- var/DBQuery/query_watchdel = dbcon.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey = '[sql_ckey]'")
- if(!query_watchdel.Execute())
- var/err = query_watchdel.ErrorMsg()
- log_game("SQL ERROR during removing watch entry. Error : \[[err]\]\n")
- return
- log_admin("[key_name_admin(usr)] has removed [key_name_admin(M)] from the watchlist")
- message_admins("[key_name_admin(usr)] has removed [key_name_admin(M)] from the watchlist", 1)
- if("Edit reason")
- var/DBQuery/query_reason = dbcon.NewQuery("SELECT ckey, reason FROM [format_table_name("watch")] WHERE (ckey = '[sql_ckey]')")
- query_reason.Execute()
- if(query_reason.NextRow())
- var/watch_reason = query_reason.item[2]
- var/new_reason = input("Insert new reason", "New Reason", "[watch_reason]", null) as null|text
- new_reason = sanitizeSQL(new_reason)
- if(!new_reason)
- return
- var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("watch")] SET reason = '[new_reason]' WHERE (ckey = '[sql_ckey]')")
- if(!update_query.Execute())
- var/err = update_query.ErrorMsg()
- log_game("SQL ERROR during edit watch entry reason. Error : \[[err]\]\n")
- return
- log_admin("[key_name_admin(usr)] has edited [sql_ckey]'s reason from [watch_reason] to [new_reason]",1)
- message_admins("[key_name_admin(usr)] has edited [sql_ckey]'s reason from [watch_reason] to [new_reason]",1)
- else
- var/reason = input(usr,"Reason?","reason","Metagaming") as text|null
- if(!reason)
- return
- reason = sanitizeSQL(reason)
- var/DBQuery/query_watchadd = dbcon.NewQuery("INSERT INTO [format_table_name("watch")] (ckey, reason) VALUES ('[sql_ckey]', '[reason]')")
- if(!query_watchadd.Execute())
- var/err = query_watchadd.ErrorMsg()
- log_game("SQL ERROR during adding new watch entry. Error : \[[err]\]\n")
- return
- log_admin("[key_name_admin(usr)] has added [key_name_admin(M)] to the watchlist - Reason: [reason]")
- message_admins("[key_name_admin(usr)] has added [key_name_admin(M)] to the watchlist - Reason: [reason]", 1)
+ if(query_watchedits.NextRow())
+ var/edit_log = query_watchedits.item[1]
+ usr << browse(edit_log,"window=watchedits")
else if(href_list["mute"])
if(!check_rights(R_MOD))
diff --git a/code/modules/admin/verbs/massmodvar.dm b/code/modules/admin/verbs/massmodvar.dm
index 7a3ef8deb2b..aa05d810810 100644
--- a/code/modules/admin/verbs/massmodvar.dm
+++ b/code/modules/admin/verbs/massmodvar.dm
@@ -168,7 +168,7 @@
return .(O.vars[variable])
if("text")
- var/new_value = input("Enter new text:","Text",O.vars[variable]) as text|null
+ var/new_value = input("Enter new text:","Text",O.vars[variable]) as message|null
if(new_value == null) return
O.vars[variable] = new_value
diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm
index b49a0fe609a..f0532fbd254 100644
--- a/code/modules/admin/verbs/modifyvariables.dm
+++ b/code/modules/admin/verbs/modifyvariables.dm
@@ -44,7 +44,7 @@ var/list/forbidden_varedit_object_types = list(
switch(class)
if("text")
- var_value = input("Enter new text:","Text") as null|text
+ var_value = input("Enter new text:","Text") as null|message
if("num")
var_value = input("Enter new number:","Num") as null|num
@@ -93,7 +93,7 @@ var/list/forbidden_varedit_object_types = list(
switch(class)
if("text")
- var_value = input("Enter new text:","Text") as text
+ var_value = input("Enter new text:","Text") as message|null
if("num")
var_value = input("Enter new number:","Num") as num
@@ -494,7 +494,7 @@ var/list/forbidden_varedit_object_types = list(
return .(O.vars[variable])
if("text")
- var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text
+ var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|message
if(var_new==null) return
O.vars[variable] = var_new
diff --git a/code/modules/admin/watchlist.dm b/code/modules/admin/watchlist.dm
new file mode 100644
index 00000000000..4ef6ce0b404
--- /dev/null
+++ b/code/modules/admin/watchlist.dm
@@ -0,0 +1,118 @@
+client/proc/watchlist_add(target_ckey, browse = 0)
+ if(!target_ckey)
+ var/new_ckey = ckey(input(usr,"Who would you like to add to the watchlist?","Enter a ckey",null) as text)
+ if(!new_ckey)
+ return
+ new_ckey = sanitizeSQL(new_ckey)
+ var/DBQuery/query_watchfind = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
+ if(!query_watchfind.Execute())
+ var/err = query_watchfind.ErrorMsg()
+ log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
+ return
+ if(!query_watchfind.NextRow())
+ usr << "[new_ckey] has not been seen before, you can only add known players."
+ return
+ else
+ target_ckey = new_ckey
+ var/target_sql_ckey = sanitizeSQL(target_ckey)
+ if(check_watchlist(target_sql_ckey))
+ usr << "[target_sql_ckey] is already on the watchlist."
+ return
+ var/reason = input(usr,"Please state the reason","Reason") as message|null
+ if(!reason)
+ return
+ reason = sanitizeSQL(reason)
+ var/timestamp = SQLtime()
+ var/adminckey = usr.ckey
+ if(!adminckey)
+ return
+ var/admin_sql_ckey = sanitizeSQL(adminckey)
+ var/DBQuery/query_watchadd = dbcon.NewQuery("INSERT INTO [format_table_name("watch")] (ckey, reason, adminckey, timestamp) VALUES ('[target_sql_ckey]', '[reason]', '[admin_sql_ckey]', '[timestamp]')")
+ if(!query_watchadd.Execute())
+ var/err = query_watchadd.ErrorMsg()
+ log_game("SQL ERROR during adding new watch entry. Error : \[[err]\]\n")
+ return
+ log_admin("[key_name(usr)] has added [target_ckey] to the watchlist - Reason: [reason]")
+ message_admins("[key_name_admin(usr)] has added [target_ckey] to the watchlist - Reason: [reason]", 1)
+ if(browse)
+ watchlist_show(target_sql_ckey)
+
+client/proc/watchlist_remove(target_ckey, browse = 0)
+ var/target_sql_ckey = sanitizeSQL(target_ckey)
+ var/DBQuery/query_watchdel = dbcon.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
+ if(!query_watchdel.Execute())
+ var/err = query_watchdel.ErrorMsg()
+ log_game("SQL ERROR during removing watch entry. Error : \[[err]\]\n")
+ return
+ log_admin("[key_name(usr)] has removed [target_ckey] from the watchlist")
+ message_admins("[key_name_admin(usr)] has removed [target_ckey] from the watchlist", 1)
+ if(browse)
+ watchlist_show()
+
+client/proc/watchlist_edit(target_ckey, browse = 0)
+ var/target_sql_ckey = sanitizeSQL(target_ckey)
+ var/DBQuery/query_watchreason = dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
+ if(!query_watchreason.Execute())
+ var/err = query_watchreason.ErrorMsg()
+ log_game("SQL ERROR obtaining reason from watch table. Error : \[[err]\]\n")
+ return
+ if(query_watchreason.NextRow())
+ var/watch_reason = query_watchreason.item[1]
+ var/new_reason = input("Input the new reason", "New Reason", "[watch_reason]") as message|null
+ new_reason = sanitizeSQL(new_reason)
+ if(!new_reason || new_reason == watch_reason)
+ return
+ var/sql_ckey = sanitizeSQL(usr.ckey)
+ var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from \"[watch_reason]\" to \"[new_reason]\""
+ edit_text = sanitizeSQL(edit_text)
+ var/DBQuery/query_watchupdate = dbcon.NewQuery("UPDATE [format_table_name("watch")] SET reason = '[new_reason]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE ckey = '[target_sql_ckey]'")
+ if(!query_watchupdate.Execute())
+ var/err = query_watchupdate.ErrorMsg()
+ log_game("SQL ERROR editing watchlist reason. Error : \[[err]\]\n")
+ return
+ log_admin("[key_name(usr)] has edited [target_ckey]'s watchlist reason from \"[watch_reason]\" to \"[new_reason]\"")
+ message_admins("[key_name_admin(usr)] has edited [target_ckey]'s watchlist reason from \"[watch_reason]\" to \"[new_reason]\"")
+ if(browse)
+ watchlist_show(target_sql_ckey)
+
+client/proc/watchlist_show(search)
+ var/output
+ output += "