diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql
index c05e74a467a..043a47a02ad 100644
--- a/SQL/paradise_schema.sql
+++ b/SQL/paradise_schema.sql
@@ -50,8 +50,8 @@ CREATE TABLE `characters` (
`eyes_red` smallint(4) NOT NULL,
`eyes_green` smallint(4) NOT NULL,
`eyes_blue` smallint(4) NOT NULL,
- `underwear` smallint(4) NOT NULL,
- `undershirt` smallint(4) NOT NULL,
+ `underwear` mediumtext NOT NULL,
+ `undershirt` mediumtext NOT NULL,
`backbag` smallint(4) NOT NULL,
`b_type` varchar(45) NOT NULL,
`alternate_option` smallint(4) NOT NULL,
@@ -438,4 +438,21 @@ CREATE TABLE `whitelist` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+--
+-- Table structure for table `watch`
+--
+
+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`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+-- Dump completed on 2013-03-24 18:02:35
+
-- Dump completed on 2015-05-28 19:57:44
diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index 422689148ee..e24dc3825bc 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -663,7 +663,7 @@
"amM" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Office"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/security/main)
"amN" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Office"; req_access_txt = "63"},/turf/simulated/floor,/area/security/main)
"amO" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; dir = 1; freq = 1400; location = "Security"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
-"amP" = (/obj/machinery/light/small{dir = 1},/obj/structure/closet/emcloset,/obj/machinery/camera/xray{c_tag = "Brig Escape Pod"; network = list("SS13")},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
+"amP" = (/obj/machinery/light/small{dir = 1},/obj/structure/closet/emcloset,/obj/machinery/camera{c_tag = "Security Pod"; dir = 2; network = list("SS13")},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
"amQ" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/escape_pod3/station)
"amR" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/shuttle/escape_pod3/station)
"amS" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s10"; icon_state = "swall_s10"; dir = 2},/area/shuttle/escape_pod3/station)
@@ -1353,7 +1353,7 @@
"aAa" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor{icon_state = "neutral"; dir = 9},/area/crew_quarters/fitness)
"aAb" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor{icon_state = "neutral"; dir = 5},/area/crew_quarters/fitness)
"aAc" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness)
-"aAd" = (/obj/machinery/requests_console{department = "Crew Quarters"; name = "Crew Quarters Requests Console"; pixel_y = 30},/obj/machinery/camera/xray{c_tag = "Dormitories North"; network = list("SS13")},/obj/machinery/vending/cigarette,/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness)
+"aAd" = (/obj/machinery/requests_console{department = "Crew Quarters"; name = "Crew Quarters Requests Console"; pixel_y = 30},/obj/machinery/vending/cigarette,/obj/machinery/camera{c_tag = "Dormitories North"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness)
"aAe" = (/obj/machinery/vending/cola,/obj/machinery/light{dir = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness)
"aAf" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness)
"aAg" = (/obj/machinery/vending/coffee,/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness)
@@ -1369,7 +1369,7 @@
"aAq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/security/prison/cell_block/C)
"aAr" = (/obj/structure/rack,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
"aAs" = (/obj/effect/decal/cleanable/fungus,/turf/simulated/wall,/area/maintenance/fsmaint2)
-"aAt" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 8; name = "Fore Starboard Solar APC"; pixel_x = -25; pixel_y = 3},/turf/simulated/floor/plating,/area/solar/auxstarboard)
+"aAt" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 8; name = "Fore Starboard Solar APC"; pixel_x = -25; pixel_y = 3},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard)
"aAu" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/fpmaint)
"aAv" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry)
"aAw" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint)
@@ -1464,7 +1464,7 @@
"aCh" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1450; master_tag = "bar_maint"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/turf/simulated/floor/plating/airless/catwalk,/area/space)
"aCi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/crew_quarters/fitness)
"aCj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/fitness)
-"aCk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10; initialize_directions = 10; level = 1},/obj/machinery/camera/xray{c_tag = "Fitness Rooms North"; network = list("SS13")},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/fitness)
+"aCk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10; initialize_directions = 10; level = 1},/obj/machinery/camera{c_tag = "Fitness Rooms North"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/fitness)
"aCl" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/fitness)
"aCm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/crew_quarters/fitness)
"aCn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/fitness)
@@ -1582,7 +1582,7 @@
"aEv" = (/obj/effect/spawner/window,/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"})
"aEw" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry)
"aEx" = (/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth{frequency = 1380; id_tag = "escape_pod_1_berth"; pixel_x = -25; pixel_y = 30; tag_door = "escape_pod_1_berth_hatch"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry)
-"aEy" = (/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/obj/machinery/light{dir = 1},/obj/machinery/camera/xray{c_tag = "Arrivals Escape Pods"},/turf/simulated/floor,/area/hallway/secondary/entry)
+"aEy" = (/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/obj/machinery/light{dir = 1},/obj/machinery/camera{c_tag = "Arrivals Escape Pods"; dir = 2},/turf/simulated/floor,/area/hallway/secondary/entry)
"aEz" = (/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth{frequency = 1380; id_tag = "escape_pod_2_berth"; pixel_x = -25; pixel_y = 30; tag_door = "escape_pod_2_berth_hatch"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry)
"aEA" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/turf/simulated/floor{dir = 1; icon_state = "arrival"},/area/hallway/secondary/entry)
"aEB" = (/obj/machinery/light{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "arrival"},/area/hallway/secondary/entry)
@@ -1661,13 +1661,13 @@
"aFW" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
"aFX" = (/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
"aFY" = (/obj/machinery/door/airlock/glass_command{name = "Softsuits"; req_access_txt = "18"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
-"aFZ" = (/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/ai_monitored/storage/eva)
+"aFZ" = (/obj/machinery/camera/motion{c_tag = "EVA Northwest"; dir = 2; network = list("SS13")},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/ai_monitored/storage/eva)
"aGa" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/ai_monitored/storage/eva)
"aGb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/vending/eva,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/ai_monitored/storage/eva)
"aGc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/ai_monitored/storage/eva)
"aGd" = (/obj/machinery/power/apc{dir = 1; name = "EVA APC"; pixel_x = 3; pixel_y = 23},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/ai_monitored/storage/eva)
"aGe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/ai_monitored/storage/eva)
-"aGf" = (/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/ai_monitored/storage/eva)
+"aGf" = (/obj/machinery/camera{c_tag = "EVA Northeast"; dir = 2; network = list("SS13")},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/ai_monitored/storage/eva)
"aGg" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Softsuits"; req_access_txt = "18"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
"aGh" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
"aGi" = (/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/fore)
@@ -2198,7 +2198,7 @@
"aQn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
"aQo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/wall,/area/crew_quarters/kitchen)
"aQp" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/wall,/area/crew_quarters/kitchen)
-"aQq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Kitchen Maintenance"; req_access_txt = "28"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/crew_quarters/kitchen)
+"aQq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Kitchen Maintenance"; req_access_txt = "28"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
"aQr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Kitchen"},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/maintenance/fsmaint2)
"aQs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
"aQt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/fitness)
@@ -2265,9 +2265,9 @@
"aRC" = (/obj/item/clothing/suit/space/eva/mime,/obj/item/clothing/head/helmet/space/eva/mime,/obj/structure/rack{dir = 8; layer = 2.9},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
"aRD" = (/obj/item/clothing/suit/space/eva/clown,/obj/item/clothing/head/helmet/space/eva/clown,/obj/structure/rack{dir = 8; layer = 2.9},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
"aRE" = (/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 = ""},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/ai_monitored/storage/eva)
-"aRF" = (/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 = ""},/turf/simulated/floor,/area/ai_monitored/storage/eva)
+"aRF" = (/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/machinery/camera{c_tag = "EVA Soutwest"; dir = 1; network = list("SS13")},/turf/simulated/floor,/area/ai_monitored/storage/eva)
"aRG" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
-"aRH" = (/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/machinery/camera{c_tag = "EVA South"; dir = 1; network = list("SS13")},/turf/simulated/floor,/area/ai_monitored/storage/eva)
+"aRH" = (/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/machinery/camera{c_tag = "EVA Southeast"; dir = 1; network = list("SS13")},/turf/simulated/floor,/area/ai_monitored/storage/eva)
"aRI" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/ai_monitored/storage/eva)
"aRJ" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/machinery/light_switch{pixel_y = -25},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
"aRK" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/flora/kirbyplants,/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/hallway/primary/central/north)
@@ -2299,7 +2299,7 @@
"aSk" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/hydroponics)
"aSl" = (/turf/simulated/wall,/area/hydroponics)
"aSm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall,/area/hydroponics)
-"aSn" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Hydroponics Maintenance"; req_access_txt = "35"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plating,/area/hydroponics)
+"aSn" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Hydroponics Maintenance"; req_access_txt = "35"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
"aSo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/hydroponics)
"aSp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/maintenance/electrical)
"aSq" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
@@ -3662,7 +3662,7 @@
"bsv" = (/turf/simulated/wall/r_wall,/area/hallway/secondary/exit)
"bsw" = (/obj/machinery/light{dir = 4},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/secondary/entry)
"bsx" = (/obj/machinery/conveyor{dir = 1; id = "garbage"},/turf/simulated/floor/plating,/area/maintenance/disposal)
-"bsy" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/solar/starboard)
+"bsy" = (/turf/simulated/wall/r_wall,/area/maintenance/starboardsolar)
"bsz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/table,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft)
"bsA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/port)
"bsB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/port)
@@ -3881,7 +3881,7 @@
"bwG" = (/obj/machinery/power/apc{dir = 1; name = "Bridge Maintenance APC"; pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/maintenance/maintcentral)
"bwH" = (/obj/effect/decal/cleanable/generic,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/port)
"bwI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/bridge/meeting_room)
-"bwJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/account_database{anchored = 1},/obj/machinery/camera{c_tag = "Head of Personnel's Office Back Room"; dir = 2; network = list("SS13")},/turf/simulated/floor,/area/bridge/meeting_room)
+"bwJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/computer/account_database{anchored = 1},/turf/simulated/floor,/area/bridge/meeting_room)
"bwK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/bridge/meeting_room)
"bwL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/bridge/meeting_room)
"bwM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/lattice,/turf/space,/area/space)
@@ -3976,7 +3976,7 @@
"byx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/closet/wardrobe/black,/turf/simulated/floor/plating,/area/maintenance/maintcentral)
"byy" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/bridge/meeting_room)
"byz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor,/area/bridge/meeting_room)
-"byA" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/bridge/meeting_room)
+"byA" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Gravity Generator Room South"; dir = 8; network = list("SS13")},/turf/simulated/floor,/area/bridge/meeting_room)
"byB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/bridge/meeting_room)
"byC" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/lattice,/turf/space,/area/space)
"byD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/turf/space,/area/space)
@@ -4306,7 +4306,7 @@
"bEP" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics)
"bEQ" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/device/healthanalyzer,/obj/item/device/healthanalyzer,/obj/item/device/healthanalyzer,/obj/machinery/newscaster{pixel_x = 26; pixel_y = 1},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics)
"bER" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{icon_state = "bot"},/area/medical/research{name = "Research Division"})
-"bES" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "bot"},/area/medical/research{name = "Research Division"})
+"bES" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/camera{c_tag = "Research Hallway Entrance"; dir = 2; network = list("Research","SS13")},/turf/simulated/floor{icon_state = "bot"},/area/medical/research{name = "Research Division"})
"bET" = (/obj/machinery/door_control{id = "rdlab2"; name = "Research and Development Lab Shutters Control"; pixel_x = -24; pixel_y = -24; req_access_txt = "47"},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab)
"bEU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab)
"bEV" = (/obj/structure/table,/obj/machinery/requests_console{department = "Cargo Bay"; name = "Cargo Requests Console"; departmentType = 2; pixel_x = -30; pixel_y = 0},/obj/machinery/camera{c_tag = "Cargo Office"; dir = 4; network = list("SS13")},/obj/item/stack/sheet/glass{amount = 50; pixel_x = 3; pixel_y = 3},/obj/item/stack/sheet/metal{amount = 50},/obj/item/device/multitool,/turf/simulated/floor,/area/quartermaster/office)
@@ -5307,7 +5307,7 @@
"bYc" = (/obj/machinery/door/airlock/external{name = "Toxins Test Chamber"; req_access_txt = "0"},/turf/simulated/floor/plating/airless,/area/toxins/test_area)
"bYd" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating/airless,/area/toxins/test_area)
"bYe" = (/obj/machinery/camera{c_tag = "Research Toxins Test Chamber North"; network = list("Toxins","Research","SS13")},/obj/machinery/light{dir = 1},/turf/simulated/floor/airless,/area/toxins/test_area)
-"bYf" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/solar/starboard)
+"bYf" = (/obj/machinery/door/airlock/engineering{name = "Aft Starboard Solar Access"; req_access_txt = "10"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
"bYg" = (/obj/item/weapon/ore/silver,/obj/item/weapon/ore/silver,/obj/structure/closet/crate,/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "mining_dock_pump"},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/quartermaster/miningdock)
"bYh" = (/obj/machinery/camera{c_tag = "Mining Dock External"; dir = 8},/obj/structure/closet/emcloset,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/turf/simulated/floor{icon_state = "warning"},/area/quartermaster/miningdock)
"bYi" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/turf/simulated/wall,/area/quartermaster/miningdock)
@@ -5928,7 +5928,7 @@
"cjZ" = (/obj/machinery/atmospherics/pipe/tank/toxins{volume = 3200},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
"cka" = (/obj/machinery/atmospherics/pipe/tank/oxygen{volume = 3200},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
"ckb" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
-"ckc" = (/obj/effect/decal/cleanable/fungus,/turf/simulated/wall,/area/maintenance/incinerator)
+"ckc" = (/obj/effect/decal/remains/human{desc = "This guy seemed to have died in terrible way! Half his remains are dust."; icon_state = "remains"; name = "Human remains"},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
"ckd" = (/obj/structure/closet,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/asmaint)
"cke" = (/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/clothing/glasses/hud/health,/obj/machinery/light{dir = 8},/obj/machinery/camera{c_tag = "Virology Lab West"; dir = 4; network = list("SS13")},/obj/item/weapon/reagent_containers/spray/cleaner,/obj/structure/table/glass,/obj/machinery/light_switch{pixel_x = -27},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab)
"ckf" = (/obj/machinery/power/smes{charge = 5e+006; input_attempt = 1},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/obj/machinery/light{dir = 1; on = 1},/turf/simulated/floor,/area/aisat/maintenance)
@@ -6003,7 +6003,6 @@
"clw" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
"clx" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
"cly" = (/obj/machinery/power/apc{dir = 4; name = "Incinerator APC"; pixel_x = 24; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
-"clz" = (/turf/simulated/wall,/area/maintenance/incinerator)
"clA" = (/obj/machinery/light/small{dir = 8},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/apmaint)
"clB" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/crew{pixel_x = -1; pixel_y = 1},/obj/item/weapon/circuitboard/card{pixel_x = 2; pixel_y = -2},/obj/item/weapon/circuitboard/communications{pixel_x = 5; pixel_y = -5},/obj/machinery/light/small{dir = 8},/turf/simulated/floor,/area/storage/tech)
"clC" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/storage/tech)
@@ -6195,9 +6194,9 @@
"cpg" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cph" = (/obj/machinery/chem_dispenser,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/toxins/misc_lab)
"cpi" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitepurple"},/area/toxins/misc_lab)
-"cpj" = (/turf/simulated/wall/r_wall,/area/solar/starboard)
-"cpk" = (/obj/machinery/door/airlock/engineering{name = "Aft Starboard Solar Access"; req_access_txt = "10"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/solar/starboard)
-"cpl" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/solar/starboard)
+"cpj" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/starboardsolar)
+"cpk" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
+"cpl" = (/obj/machinery/power/apc{dir = 8; name = "Aft Starboard Solar APC"; pixel_x = -26; pixel_y = 3},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
"cpm" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/toxins/test_area)
"cpn" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating/airless,/area/toxins/test_area)
"cpo" = (/obj/machinery/power/apc{dir = 4; name = "Explosives Testing APC"; pixel_x = 25},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/toxins/test_area)
@@ -6251,9 +6250,9 @@
"cqk" = (/obj/structure/window/reinforced,/obj/structure/table/reinforced,/obj/machinery/reagentgrinder,/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/toxins/misc_lab)
"cql" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitepurplecorner"},/area/toxins/misc_lab)
"cqm" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
-"cqn" = (/obj/machinery/power/apc{dir = 8; name = "Aft Starboard Solar APC"; pixel_x = -26; pixel_y = 3},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/solar/starboard)
+"cqn" = (/obj/machinery/power/smes{charge = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
"cqo" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/stool/bed/chair/wood/wings,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/wood,/area/crew_quarters/bar)
-"cqp" = (/obj/machinery/power/smes{charge = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/solar/starboard)
+"cqp" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
"cqq" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/wood,/area/crew_quarters/bar)
"cqr" = (/obj/item/clothing/mask/cigarette,/turf/simulated/floor/plating/airless,/area/toxins/test_area)
"cqs" = (/obj/machinery/light/small,/turf/simulated/floor/plating/airless,/area/toxins/test_area)
@@ -6284,6 +6283,7 @@
"cqR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/wall/r_wall,/area/medical/medbay2)
"cqS" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology)
"cqT" = (/obj/machinery/light{dir = 4},/obj/machinery/hologram/holopad,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology)
+"cqU" = (/obj/structure/stool,/obj/machinery/camera{c_tag = "Aft Starboard Solar Control"; dir = 4; network = list("SS13")},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
"cqV" = (/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/asmaint)
"cqW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/stool/bed/chair/wood/wings,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/wood,/area/crew_quarters/bar)
"cqX" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/light,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology)
@@ -6297,9 +6297,9 @@
"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)
"crg" = (/obj/structure/piano,/obj/machinery/light{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar)
"crh" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/closet/secure_closet/research_reagents,/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/toxins/misc_lab)
-"cri" = (/obj/structure/stool,/obj/machinery/camera{c_tag = "Aft Starboard Solar Control"; dir = 4; network = list("SS13")},/turf/simulated/floor/plating,/area/solar/starboard)
-"crj" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/solar/starboard)
-"crk" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/solar/starboard)
+"cri" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
+"crj" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "solar_xeno_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "10;13"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
+"crk" = (/obj/machinery/power/solar_control{id = "starboardsolar"; name = "Aft Starboard Solar Control"; track = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
"crl" = (/obj/machinery/computer/secure_data,/obj/machinery/alarm{pixel_y = 26},/turf/simulated/floor{dir = 6; icon_state = "red"},/area/bridge)
"crm" = (/obj/effect/decal/warning_stripes/west,/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"crn" = (/obj/structure/spacepoddoor,/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
@@ -6364,9 +6364,9 @@
"csu" = (/obj/structure/window/reinforced,/obj/structure/table/reinforced,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/mineral/plasma{amount = 5; layer = 2.9},/obj/item/stack/sheet/glass{amount = 50; pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/monkeycubes,/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/toxins/misc_lab)
"csv" = (/obj/structure/window/reinforced,/obj/structure/table/reinforced,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/dropper/precision,/obj/item/weapon/reagent_containers/dropper/precision,/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/toxins/misc_lab)
"csw" = (/obj/structure/table/reinforced,/obj/machinery/atmospherics/pipe/simple/insulated,/obj/machinery/ignition_switch{id = "testigniter"; pixel_x = 3; pixel_y = -3},/obj/machinery/door_control{id = "RnDChem"; name = "Chamber Blast Doors"; pixel_x = 3; pixel_y = 5},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
-"csx" = (/obj/machinery/power/solar_control{id = "starboardsolar"; name = "Aft Starboard Solar Control"; track = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/solar/starboard)
-"csy" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "solar_xeno_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "10;13"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/solar/starboard)
-"csz" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/solar/starboard)
+"csx" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
+"csy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_xeno_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
+"csz" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
"csA" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"csB" = (/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"csC" = (/obj/machinery/atmospherics/unary/vent_pump{on = 0},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
@@ -6404,15 +6404,22 @@
"cti" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery)
"ctj" = (/obj/machinery/computer/operating,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery)
"ctk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft)
+"ctl" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_xeno_pump"; tag_exterior_door = "solar_xeno_outer"; frequency = 1379; id_tag = "solar_xeno_airlock"; tag_interior_door = "solar_xeno_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "solar_xeno_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_xeno_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "solar_xeno_pump"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
+"ctm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_xeno_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar)
+"ctn" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"},/obj/machinery/power/smes{charge = 0},/turf/simulated/floor/plating,/area/maintenance/portsolar)
"cto" = (/obj/structure/closet/crate/freezer,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery)
"ctp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/asmaint)
"ctq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/medical/virology)
"ctr" = (/obj/structure/sign/biohazard{pixel_x = -32},/obj/effect/decal/warning_stripes/yellow,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_viro"; name = "Virology Quarantine Lockdown"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology)
"cts" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/effect/decal/warning_stripes/yellow,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_viro"; name = "Virology Quarantine Lockdown"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology)
"ctt" = (/obj/structure/sign/biohazard{pixel_x = 32},/obj/effect/decal/warning_stripes/yellow,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_viro"; name = "Virology Quarantine Lockdown"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology)
+"ctu" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft)
+"ctv" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/portsolar)
+"ctw" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/portsolar)
+"ctx" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/camera{c_tag = "Xenobiology Access"; dir = 2; network = list("Research","SS13"); pixel_x = 0},/turf/simulated/floor{tag = "icon-warnwhite (NORTHEAST)"; icon_state = "warnwhite"; dir = 5},/area/toxins/xenobiology)
"cty" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor{dir = 9; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/toxins/xenobiology)
"ctz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology)
-"ctA" = (/obj/structure/closet/emcloset,/obj/machinery/camera/xray{c_tag = "Xenobiology Access"; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-warnwhite (NORTHEAST)"; icon_state = "warnwhite"; dir = 5},/area/toxins/xenobiology)
+"ctA" = (/obj/machinery/light{dir = 8},/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/warning_stripes/blue/hollow,/turf/simulated/floor{icon_state = "dark"},/area/atmos)
"ctB" = (/obj/structure/table/reinforced,/obj/item/device/taperecorder,/obj/item/device/tape/random{pixel_x = 3; pixel_y = -3},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"ctC" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"ctD" = (/obj/machinery/atmospherics/pipe/simple/hidden/green{dir = 4; level = 2},/turf/simulated/wall/r_wall,/area/toxins/test_chamber)
@@ -6423,7 +6430,8 @@
"ctI" = (/obj/machinery/light,/obj/structure/clownstatue,/turf/simulated/floor/wood,/area/clownoffice)
"ctJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/engine{icon_state = "stage_stairs"; name = "reinforced stairs"},/area/toxins/test_chamber)
"ctK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/sparker{id = "testigniter"; name = "Test Igniter"; pixel_x = -25},/turf/simulated/floor/engine,/area/toxins/test_chamber)
-"ctM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_xeno_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/solar/starboard)
+"ctL" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/effect/decal/warning_stripes/red/hollow,/obj/machinery/camera{c_tag = "Atmospherics North-West"; dir = 4; network = list("SS13")},/turf/simulated/floor{icon_state = "dark"},/area/atmos)
+"ctM" = (/obj/machinery/requests_console{department = "Engineering"; departmentType = 3; name = "Engineering Requests Console"; pixel_y = 30},/obj/structure/table,/obj/item/weapon/book/manual/engineering_guide,/obj/item/weapon/book/manual/engineering_particle_accelerator{pixel_y = 6},/obj/item/weapon/book/manual/engineering_singularity_safety,/obj/machinery/camera{c_tag = "Engineering Northwest"; network = list("SS13")},/turf/simulated/floor,/area/engine/engineering)
"ctP" = (/obj/structure/spacepoddoor,/obj/machinery/door/poddoor/three_tile_ver{id_tag = "mechpodbay"; layer = 3.1; req_access_txt = "70"},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"ctQ" = (/obj/machinery/door_control{desc = "A remote control-switch for the pod doors."; id = "mechpodbay"; name = "Pod Door Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "70"},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
"ctR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/engine,/area/engine/mechanic_workshop)
@@ -6478,7 +6486,6 @@
"cuU" = (/obj/machinery/light,/obj/machinery/computer/security/telescreen{desc = "Used for watching the horrors within the test chamber."; name = "Research Monitor"; network = list("TestChamber"); pixel_x = 0; pixel_y = -32},/turf/simulated/floor{icon_state = "white"},/area/toxins/misc_lab)
"cuV" = (/obj/machinery/camera{c_tag = "Research Test Chamber"; dir = 2; network = list("TestChamber","SS13","Research"); pixel_x = 0},/turf/simulated/floor/engine,/area/toxins/test_chamber)
"cuW" = (/mob/living/carbon/human/monkey,/turf/simulated/floor/engine,/area/toxins/test_chamber)
-"cuY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_xeno_pump"; tag_exterior_door = "solar_xeno_outer"; frequency = 1379; id_tag = "solar_xeno_airlock"; tag_interior_door = "solar_xeno_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "solar_xeno_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_xeno_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "solar_xeno_pump"},/turf/simulated/floor/plating,/area/solar/starboard)
"cuZ" = (/obj/structure/rack{dir = 1},/obj/item/weapon/extinguisher,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/toolbox/electrical,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/device/radio{pixel_y = 6},/turf/simulated/floor,/area/engine/mechanic_workshop)
"cva" = (/turf/simulated/floor,/area/engine/mechanic_workshop)
"cvb" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/flora/kirbyplants,/turf/simulated/floor{icon_state = "dark"},/area/engine/mechanic_workshop)
@@ -6538,7 +6545,6 @@
"cwk" = (/obj/machinery/optable,/turf/simulated/floor/plating,/area/maintenance/fpmaint2)
"cwl" = (/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/fitness)
"cwm" = (/turf/simulated/floor/airless{icon_state = "damaged5"},/area/space)
-"cwo" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_xeno_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/solar/starboard)
"cwp" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/space)
"cwq" = (/obj/structure/table,/obj/item/pod_parts/core,/obj/item/weapon/circuitboard/mecha/pod,/obj/item/clothing/glasses/welding{pixel_y = 12},/turf/simulated/floor,/area/engine/mechanic_workshop)
"cwr" = (/obj/machinery/door_control{id = "mechpod"; name = "Mechanic's Inner Door Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "70"},/obj/structure/table,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/rods{amount = 50},/obj/item/stack/sheet/mineral/plasma{amount = 30},/turf/simulated/floor,/area/engine/mechanic_workshop)
@@ -6814,7 +6820,6 @@
"cCf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/hallway/primary/aft)
"cCh" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Engineering"; name = "Engineering Security Doors"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = "0"},/turf/simulated/floor,/area/engine/equipmentstorage)
"cCm" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Engineering"; name = "Engineering Security Doors"; opacity = 0},/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = "0"},/turf/simulated/floor,/area/engine/equipmentstorage)
-"cCo" = (/obj/machinery/camera{c_tag = "Atmospherics North-West"; dir = 4; network = list("SS13")},/obj/machinery/light{dir = 8},/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/warning_stripes/blue/hollow,/turf/simulated/floor{icon_state = "dark"},/area/atmos)
"cCp" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/warning_stripes/blue/hollow,/turf/simulated/floor{icon_state = "dark"},/area/atmos)
"cCq" = (/turf/simulated/floor,/turf/simulated/floor{tag = "icon-siding8 (NORTH)"; icon_state = "siding8"; dir = 1},/area/atmos)
"cCr" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor,/area/atmos)
@@ -6871,7 +6876,6 @@
"cDu" = (/turf/simulated/floor,/area/engine/equipmentstorage)
"cDv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor,/area/engine/equipmentstorage)
"cDw" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/atmos)
-"cDx" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor{icon_state = "dark"},/area/atmos)
"cDy" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor{icon_state = "dark"},/area/atmos)
"cDz" = (/turf/simulated/floor,/obj/item/device/radio/beacon,/turf/simulated/floor{tag = "icon-siding8 (NORTH)"; icon_state = "siding8"; dir = 1},/area/atmos)
"cDA" = (/turf/simulated/floor,/area/atmos)
@@ -6915,9 +6919,6 @@
"cEq" = (/turf/simulated/floor/plating/airless,/obj/structure/cable,/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk3"; icon_state = "catwalk3"},/area/solar/port)
"cEu" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = -32; pixel_y = 0},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/maintenance/portsolar)
"cEv" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/portsolar)
-"cEw" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/smes{charge = 0},/turf/simulated/floor/plating,/area/maintenance/portsolar)
-"cEx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/portsolar)
-"cEy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft)
"cEz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft)
"cEA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft)
"cEB" = (/obj/machinery/optable{name = "Robotics Operating Table"},/obj/machinery/light,/turf/simulated/floor{icon_state = "white"},/area/assembly/assembly_line)
@@ -6975,13 +6976,11 @@
"cFE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/portsolar)
"cFF" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "robotics_solar_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/portsolar)
"cFG" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/portsolar)
-"cFH" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/portsolar)
"cFI" = (/obj/machinery/door/airlock/engineering{name = "Aft Port Solar Access"; req_access_txt = "10"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/portsolar)
"cFJ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft)
"cFK" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating,/area/maintenance/aft)
"cFL" = (/obj/structure/stool/bed/chair,/obj/item/weapon/storage/fancy/cigarettes,/turf/simulated/floor/plating,/area/maintenance/asmaint)
"cFM" = (/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/obj/structure/table,/obj/item/weapon/book/manual/engineering_hacking{pixel_x = 3; pixel_y = 3},/obj/item/weapon/book/manual/engineering_construction,/obj/item/weapon/book/manual/supermatter_engine,/turf/simulated/floor,/area/engine/engineering)
-"cFN" = (/obj/machinery/requests_console{department = "Engineering"; departmentType = 3; name = "Engineering Requests Console"; pixel_y = 30},/obj/structure/table,/obj/item/weapon/book/manual/engineering_guide,/obj/item/weapon/book/manual/engineering_particle_accelerator{pixel_y = 6},/obj/item/weapon/book/manual/engineering_singularity_safety,/turf/simulated/floor,/area/engine/engineering)
"cFO" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/machinery/light{dir = 1},/obj/item/weapon/cartridge/engineering{pixel_x = 3},/obj/item/weapon/cartridge/engineering{pixel_x = -3; pixel_y = 2},/obj/item/weapon/cartridge/engineering{pixel_x = 4; pixel_y = 5},/turf/simulated/floor,/area/engine/engineering)
"cFP" = (/obj/machinery/power/apc{cell_type = 15000; dir = 1; name = "Engineering APC"; pixel_x = 0; pixel_y = 25},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor,/area/engine/engineering)
"cFR" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/rig,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/rig,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/power/apc{dir = 1; name = "Engineering Hardsuit Storage APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor,/area/engine/hardsuitstorage)
@@ -8142,25 +8141,25 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaccZcgfcgecggbTCceIcghcghcghcghcghcghbTIbTIbTIbTIbTIbTIbTIcgicgjcgkcglcgmcgncgocgocgpcgqcfbbHTbHTcgrcgscgtbHTbHTbHTcgucgvcgwcdEcgxcgycgzcfucgAcgBcgCbQWcgBcgDcdTcdTcdTcdTcdTcdTcgBcdTcdTcdTbQWcgEcgFcgGcgHcgIcgJcgKcgLcaAcgMcgNcehcgOcehcgPcgQcgRcgScgTcgUcgVbzwcgWceobXVcgXbDbbDicgYcgZchabumbvWbvWbThchbchcchdchechfchgchhchichjchkchlbThchmchnchochpaacaacaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaachqbWFbWFbWFbWFbWFbWFbWFchrchsbWHbWHbWHbWHchtbdqbUNaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaccZccZccZccZbTCceIccZaaaaaaaaaaaachuchvchwchxchychzchAchBchCchDchEbhrchGchHchIchIchJchKchLchMchMchMchMchNchMbHTbHTbNRchOchPchQchRchSchTcgIchUchVchWchXchYchZciacdTcdTcibcicbhsciebhscicbEDcifcigcigcihciicijcakcikcilcaAcimcinciocipciqcirciscaAcaAbDbcitbDbbDbbDbciucivciwbDbbvWcgYcixciybumbumbumbThbThbThbThbThbThbThbThbThbThbThbThbThbThbThbThbThaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaabUNcbicbicbicbicbicbicizbWHcbhcbiciAbWHbWHbWHbWHbUNaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciBaaaaabaabciCciCciCciCciCciCciDciCbTCcdbbhtaaabhubjJbhYbjYciJciKciLciMciNciOciPciQciRciSciTciUciVciWciXciYciZchLcjacjbcjbcjbcjcchMbHTbHTcjdcjdcjdcjdcjecjdcjfcjfcjgcjdcjdcjhcjdcjicjjbkycjlbkycjmcjncjocjpcjqbuXbuXcjrcjscjtcjucjvcjwcjxcbScaAcaAcjycaAcjzcaAcjAcjBcjCcfdcjDcjFcjGcjHcjIcjJcjKcjLcjIbvWcgYcjMbvWcjNcjOcjPcjQcfQbvWbvWbvWbvWbvWbvWbvWcjRcjEaZCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabUNbWHbWHbWHbWHbWHbWHceDbWHciAbWHbWHbWHbWHbWHbUNbUNaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjTcjUcjUcjUbkzcjWcjXcjYcjZckackbckccjScdbbhtaaabmZckgckhckickjciKckkbURckmcknchBckoceTbZUbhrckpcgockqcgockrcksbneckuckvckvckvckwchMbHTbHTcjdckxckyckzckAckBckCckCckDckEckFckGckHckIckJckKcdXcdXckLckMckNckOckPaaaaaacjvckQckRckScjrckdckUckVckWckWckXbGickYckZclaclbckZckZckZclcckZckZcldcleclfclgclhclicljclkbWycllclmbWybWybWybWyclnclobWybWybWybWyclpbvWaZCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabUNbUNccYbWHbWHbWHbWHbWHbWHbWHbWHbWHbWHbWHbUNbUNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaclrclsclsclsclscltcluclvclwclxclxclyclzclAceIbhtaaabmZclBclCclDclEclFclGclHclEclEclIclJclKclLclMclMclNclOcgoclPclQbneckvckvckvckvclSchMbHTbHTcjdclTclUclVclWclXclYclYclZcmacmbcmccmdcmecjdcmfcdTcmgbEDcmhckNcmickPaaaaaacjvcmjcmkcmlcjvbHUcmmcmncmncmncmncmncmnckTcmpcmqcmocmscmsbnfbnfcmscmvcmwcmxcmycmzcmAcmBcmCcmAcmAcmAcmAcmAcmAcmAcmAcmAcmAcmAcmAbvWcmDcmraZCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabZEbUNbUNcgbcgbbWHbWHbWHbWHbWHbWHbWHbWHbUNbUNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacmEcmFcmGcmHcmGcmIcmJcmKcmLbRSbGWclzcmNcdbbhtaaabmZcmOcmPcmQcmRciKcmScmTcmUcmVchBckoceTcmWcmXceVcmYcmZbhrbhrbhrcndcneckvckvcnfcngchMbHTcnhcjdcnicnjcnkcnlcnlcnlcnmcnncnlcnlcnocnkcnpcnqcnrcdTcnsbEDcntckNcnuckPaaaaaacjvcnvcnwcnxcjvcnybHTcnhcnzcnzcnzcnzcnzbngbnkbnjcnzcnzaaaaaaaaaaaacjIcnDcnEcnFcmAcnGcnIcnHcnKcnJcnMcnLcnOcnNcnQcnPcoXcnRcpacmAcnScnTcnUcnVcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnXcnYbUNbYcbUNbWHbWHbWHbWHbWHbWHbWHbUNbUNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaacmEcnZcoacobcocclwcodclwcoeclwcofbxgcohcoibhtaaabnlbjJbnIbjYcomciKciKconcoocopcoqcorcoscotcouceVcovcowcoxcoycozchLcoAckvckvckvcoBchMbHTbHTcoCcoCcoDcoEboQboQboQcoCbpobpobpocoLcoMcoDcoNcmfcdTcmgbEDcoOckNckOckPaaaaaacjvcoPcoQcoRcjvbHTbHTbHTcnzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpPcoTcoUcoVbqlcpbcoYcoYcoZcoYcoYcoYcoYcoYcpdcpccpfcpecphcpjcpjcpkcplcpjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabUNcpmcpncpobUNbUNbWHbWHcppbWHbWHbUNbUNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacmEcpqcmGcprcmGcpsbSzbSHbSEcmKcpwclzcpxcdbccZaaaaaaaaaaaachucpycpzcpAcpAchBcpBchBcpCceTbZUcpDcpEcpFcpGcpHcpHcpHcpIcpJckvcpKckvcpLchMbHTbHTcoCcpMcpNcpOcpPcpQcpRcoCcpQcpRcpPcpScpTcpUcoNcnrcpVcnsbEDcpWckNcpXckPcnzcnzcjvcjvcjvcjvcjvcpYbHTbHTcnzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpPcqacqbcqccqdcpicqfcqhcpgcoYcoYcqjcoYcoYcpdcpfcpfcpfcoXcpjcqnbYfcqpcpjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcgcqrcqsbYdbUMbUNbUNbWHbdqbWHbUNbUNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUabCcqtcqtcqtcqtcqtcqtcqtcqtcqucqucqucqucquciCclzclzclzclzclzclzcqvcqwcqxcqxcqxcqxcqxchuchBchBchBchBchBchBchBcqyceTbZUcqzcqAcqBcqCcqDcqEcqFcqGcqHcqIcqJcqKcqLchMbHTbHTcoCcqMcqNcpOcpPcpPcqOcoCcqPcpPcpPcpScpOcqQcoNbEDbEDbEDcqRcqSckNcqTckPczvbHTbHTbHTbHTcqVbHTbHTbHTbHTcnzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpPcqXcqYcqZbricqlcqgcqecqicoYcoYcoYcoYcqmcrhcrbcsvcsucqkcpjcricrjcrkcpjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcgbcgbcgbcgbUMbUMbUNbUNbUNbUNbUOaabaabaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrmcrncrocrpcrqcrqcrrcrscrtcrucrvcrwcrxbrMcrzcrzcrzcrAcrBcrCcrDcrDcrEcrFcrGcrHcrIcrHcrHcrHcrGcrHcrHcrJcrKcrLcrMceTbZUcrNcrPcrOcrQceVcrRclMcrScrTcrUcrVcrWcrXcrYbHTbHTcoCcrZcsacsbcsccsdcoHcoCcoIcsdcsgcshcsbcsicoNbHTbHTbHTcsjcoOckNcoOcskbHTbHTcFLbHTbHTbHTbHTbHTcfccGOcnzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacslcjIcsmcjLcslcrccrecrdcuQcrfcsocsncoYcoYcsqcspcsscsrcstcpjcsxcsycszcpjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrmcrncsAcsBcsCcsBcsDcsEcsFcsGcsHcsIcsHcsJcsKcsKcsecsKceTcsfbZVbZVcsKcsLcsKcsKcsKcsKcsKcsKcsKcsKcsKcsKcsMcsNcsOcsPcsQcsRcsScsTcsUcsVcsWcsXcsYcsZctactbctcctdctecmnctfctgcthctictjcoJcoScoKcoCcoWcpPcoJcptcpOctocoNctpcmscmsctqctrctscttckPbnjbnjbnjbnjcnzcnzcnzbnjbnjbnjcnzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjIctyctzctAcjIcmAcmAcmAcmAcmAcmAcuTcsncuUctBcswctCcmAcmAcpjbsyctMbsybsyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrmctPcsBctQctRctSctTctUctVctWctXctYctZcuacubcucctkcudcuecdqcufcdqcubcugcubcubcubcubcubcubcubcubcubcubcuhcsKcuicujcukbszbuccuncuocupcuqcurcuscutbufcuvcuwcuxcrVcdzcuycuzcuAcpPcpOcpPcpPcpucoCcpvcpPcpPcpScpOcuEcoNcuFcnzaaacuGckPcuHckPckPaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjIcjIcjIcjIcjIcjIcjIcjIcjIcuIcuJcuKcjIaabaabaaaaaaaabcmAcmActEcmActGctFctHcmAaaaaaabsycuYbsyaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUabCcqtcqtcqtcqtcqtcqtcuZcvacvacvbcsHcvccqtcqxcvdcvecvecvfcvecvgcvecvebvYbvZcvecvebvZbvZbvZcvecvecvecvecvlcvmcvncvocvpcvqcvrcvscvtcvscvscvucvscvvbxNcvxcvycvzcrYbHTcuFcvAcvBcvCcvDcvEcvFcvGcoCcvHcvFcvIcpScvJcvKcoNcuFcnzaaacuGcvLcvMcvNckPaaaaaaaaaaaacvOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjIcvPcvQcvRbxWcvTcvUcvVcvWcvXcvYcvZcjIaabaaaaaaaaaaabaabcwectJcuVcxCcxBcwacweaaaaaabsycwobsyaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjTcjUcjUcjUbkzcjWcjXcjYcjZckackbciDcjScdbbhtaaabmZckgckhckickjciKckkbURckmcknchBckoceTbZUbhrckpcgockqcgockrcksbneckuckvckvckvckwchMbHTbHTcjdckxckyckzckAckBckCckCckDckEckFckGckHckIckJckKcdXcdXckLckMckNckOckPaaaaaacjvckQckRckScjrckdckUckVckWckWckXbGickYckZclaclbckZckZckZclcckZckZcldcleclfclgclhclicljclkbWycllclmbWybWybWybWyclnclobWybWybWybWyclpbvWaZCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabUNbUNccYbWHbWHbWHbWHbWHbWHbWHbWHbWHbWHbWHbUNbUNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaclrclsclsclsclscltcluclvclwclxclxclyciCclAceIbhtaaabmZclBclCclDclEclFclGclHclEclEclIclJclKclLclMclMclNclOcgoclPclQbneckvckvckvckvclSchMbHTbHTcjdclTclUclVclWclXclYclYclZcmacmbcmccmdcmecjdcmfcdTcmgbEDcmhckNcmickPaaaaaacjvcmjcmkcmlcjvbHUcmmcmncmncmncmncmncmnckTcmpcmqcmocmscmsbnfbnfcmscmvcmwcmxcmycmzcmAcmBcmCcmAcmAcmAcmAcmAcmAcmAcmAcmAcmAcmAcmAbvWcmDcmraZCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabZEbUNbUNcgbcgbbWHbWHbWHbWHbWHbWHbWHbWHbUNbUNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacmEcmFcmGcmHcmGcmIcmJcmKcmLbRSbGWciCcmNcdbbhtaaabmZcmOcmPcmQcmRciKcmScmTcmUcmVchBckoceTcmWcmXceVcmYcmZbhrbhrbhrcndcneckvckvcnfcngchMbHTcnhcjdcnicnjcnkcnlcnlcnlcnmcnncnlcnlcnocnkcnpcnqcnrcdTcnsbEDcntckNcnuckPaaaaaacjvcnvcnwcnxcjvcnybHTcnhcnzcnzcnzcnzcnzbngbnkbnjcnzcnzaaaaaaaaaaaacjIcnDcnEcnFcmAcnGcnIcnHcnKcnJcnMcnLcnOcnNcnQcnPcoXcnRcpacmAcnScnTcnUcnVcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnWcnXcnYbUNbYcbUNbWHbWHbWHbWHbWHbWHbWHbUNbUNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaacmEcnZcoacobcocclwcodckccoeclwcofbxgcohcoibhtaaabnlbjJbnIbjYcomciKciKconcoocopcoqcorcoscotcouceVcovcowcoxcoycozchLcoAckvckvckvcoBchMbHTbHTcoCcoCcoDcoEboQboQboQcoCbpobpobpocoLcoMcoDcoNcmfcdTcmgbEDcoOckNckOckPaaaaaacjvcoPcoQcoRcjvbHTbHTbHTcnzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpPcoTcoUcoVbqlcpbcoYcoYcoZcoYcoYcoYcoYcoYcpdcpccpfcpecphbsybsybYfcpjbsyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabUNcpmcpncpobUNbUNbWHbWHcppbWHbWHbUNbUNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacmEcpqcmGcprcmGcpsbSzbSHbSEcmKcpwciCcpxcdbccZaaaaaaaaaaaachucpycpzcpAcpAchBcpBchBcpCceTbZUcpDcpEcpFcpGcpHcpHcpHcpIcpJckvcpKckvcpLchMbHTbHTcoCcpMcpNcpOcpPcpQcpRcoCcpQcpRcpPcpScpTcpUcoNcnrcpVcnsbEDcpWckNcpXckPcnzcnzcjvcjvcjvcjvcjvcpYbHTbHTcnzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpPcqacqbcqccqdcpicqfcqhcpgcoYcoYcqjcoYcoYcpdcpfcpfcpfcoXbsycplcpkcqnbsyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcgcqrcqsbYdbUMbUNbUNbWHbdqbWHbUNbUNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUabCcqtcqtcqtcqtcqtcqtcqtcqtcqucqucqucqucquciCciCciCciCciCciCciCcqvcqwcqxcqxcqxcqxcqxchuchBchBchBchBchBchBchBcqyceTbZUcqzcqAcqBcqCcqDcqEcqFcqGcqHcqIcqJcqKcqLchMbHTbHTcoCcqMcqNcpOcpPcpPcqOcoCcqPcpPcpPcpScpOcqQcoNbEDbEDbEDcqRcqSckNcqTckPczvbHTbHTbHTbHTcqVbHTbHTbHTbHTcnzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpPcqXcqYcqZbricqlcqgcqecqicoYcoYcoYcoYcqmcrhcrbcsvcsucqkbsycqUcqpcribsyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcgbcgbcgbcgbUMbUMbUNbUNbUNbUNbUOaabaabaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrmcrncrocrpcrqcrqcrrcrscrtcrucrvcrwcrxbrMcrzcrzcrzcrAcrBcrCcrDcrDcrEcrFcrGcrHcrIcrHcrHcrHcrGcrHcrHcrJcrKcrLcrMceTbZUcrNcrPcrOcrQceVcrRclMcrScrTcrUcrVcrWcrXcrYbHTbHTcoCcrZcsacsbcsccsdcoHcoCcoIcsdcsgcshcsbcsicoNbHTbHTbHTcsjcoOckNcoOcskbHTbHTcFLbHTbHTbHTbHTbHTcfccGOcnzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacslcjIcsmcjLcslcrccrecrdcuQcrfcsocsncoYcoYcsqcspcsscsrcstbsycrkcrjcsxbsyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrmcrncsAcsBcsCcsBcsDcsEcsFcsGcsHcsIcsHcsJcsKcsKcsecsKceTcsfbZVbZVcsKcsLcsKcsKcsKcsKcsKcsKcsKcsKcsKcsKcsMcsNcsOcsPcsQcsRcsScsTcsUcsVcsWcsXcsYcsZctactbctcctdctecmnctfctgcthctictjcoJcoScoKcoCcoWcpPcoJcptcpOctocoNctpcmscmsctqctrctscttckPbnjbnjbnjbnjcnzcnzcnzbnjbnjbnjcnzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjIctyctzctxcjIcmAcmAcmAcmAcmAcmAcuTcsncuUctBcswctCcmAcmAbsycszcsycszcszaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrmctPcsBctQctRctSctTctUctVctWctXctYctZcuacubcucctkcudcuecdqcufcdqcubcugcubcubcubcubcubcubcubcubcubcubcuhcsKcuicujcukbszbuccuncuocupcuqcurcuscutbufcuvcuwcuxcrVcdzcuycuzcuAcpPcpOcpPcpPcpucoCcpvcpPcpPcpScpOcuEcoNcuFcnzaaacuGckPcuHckPckPaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjIcjIcjIcjIcjIcjIcjIcjIcjIcuIcuJcuKcjIaabaabaaaaaaaabcmAcmActEcmActGctFctHcmAaaaaaacszctlcszaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUabCcqtcqtcqtcqtcqtcqtcuZcvacvacvbcsHcvccqtcqxcvdcvecvecvfcvecvgcvecvebvYbvZcvecvebvZbvZbvZcvecvecvecvecvlcvmcvncvocvpcvqcvrcvscvtcvscvscvucvscvvbxNcvxcvycvzcrYbHTcuFcvAcvBcvCcvDcvEcvFcvGcoCcvHcvFcvIcpScvJcvKcoNcuFcnzaaacuGcvLcvMcvNckPaaaaaaaaaaaacvOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjIcvPcvQcvRbxWcvTcvUcvVcvWcvXcvYcvZcjIaabaaaaaaaaaaabaabcwectJcuVcxCcxBcwacweaaaaaacszctmcszaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaczaczaczakSakSaczakSakSakSalwakSakSaabalwawTaaaaabaabcwpcwpcwpcqtcwqcwrcwscwtcwucwvcwwcogcwybxZcwAcwBcwCcwDcwEcwFcwGcwHcwIcvecwHcwJcwKcwLcwLcwMcvecwNcwOcwPcwQbZUcwRbyfcwTcwUcwVcwWcwVcwXcwYbzncxacxbcnBcrYcrYcuFcvAcoNcoNcxdcoNcoNcxecxfcxgcxgcxgcxhcxgcxicxgcxjcnzaaacuGcxkcvMcxlckPbhsbhsbhsbhsckPckPcxpcxqcxqcxrcxqcxqcxrcxsaaaaaacjIcxtbTHcxtcxvcxwcqacxxcvWcxycxzcxycjIaaaaaaaaaaaaaaaaaacwecwbcuWcxCcxCcwccweaaaaaaaaacxJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKaaaaaaaaaaaaaaaaaaaaaaaaaczaaaaaaaabaabaaaaabaabaaaaaaaabaabaabaaaawTaaaaaaaaaaabaabcwpcqtcqtcqtcqtcqtcqtcqtcqtcxLcwybxZcxNcxOcxPcxQcxQcxQcxQcxRcxScxTcwLcxUcwLcwLcxVcwLcxWcxXcxYcxZcwQbZUcyacybcyccwUcydcyecyfcwUcygcyhcyicyjcykcnCcymcyncyocypcypcyqcyrcyscytcyucdzcdzcdzcyvbHTbHTcbRbHTcnzaaacuGcywcvMcyxcyycyzcyAcyBcyCbzLcyEbTJbzLcyEbTLbzLcyHcyIcyJaaaaaacjIcxtcxtcxtbzMcyLcyMcyNcyOcyPcyQcyRcjIaaaaaaaaaaaaaaaaaacwectKcxCczMcxCcuLcweaaaaaaaaacyXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaaaaaaaaaaaaaczaaacyYcyZczaaaacyYcyZczaaaacyYcyZczaaabczbaabaaaaaaaaaaaaaabaabaabaaaaaaaaaaaaaaaaaabxYcwybxZczdcwLcxVczecwLcwLcwLczfcwLczdczdcwLcwLcwLcwLczgbzPcxXczicsKczjbZUcybcybczkcwUczlczmczncwUczoctaczpczqczrczscztcHZbHTczucbSczubHTbHTbHTcuFcZScnzbnjbnjbnjbnjbnjcnzcnzaaaczwczxczycjqczzczAcoOcoOczBbAbczDczEbAbczDczEbAbczDczEcyJaaaaabcjIcvWcvWcvWcvWczFcqaczGczHczIczJczKcjIaabaaaaaaaaaaaaaaacwecuPcuMcxCcxCcuOctDcEpaaaaaacyXaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaaaaaaaaaaczaaacyYczVczaaaacyYczVczaaaacyYczVczaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabbxYcwybxZczdczYcwLczZcAacAbcAbcxUcwLczdcAccwLcwLcwLcwLcAdcAecAfcAgbYxcAhcAicAjcAkcAlcwUczlcAmcAncwUcAoctacrYcApcrVcAqcArcAscAtcAucAvcAwcAtcAtcAtcAxcAtcnzaaaaaaaaaaaaaaaaaaaabaaacuGcAycvMcAzcAAcABcoOcoOczBbAbcADbAbbAbcADbAbbAbcADbAbcyJaabaabcjIcvPcvQcvRbBBcAIcyMcAJcAKcALcAMcANcjIaabaabaabaabaabaaacwecwecuScuRcwdcwecweaaaaaaaaacyXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaagaaaaaaaaaakSaabcyYczVczaaaacyYczVczaaabcyYczVczaaabaaaaaaaabaabaabaabaabaaaaaaaaaaaaaaaaabaaaaaabxYcwycvecAWcwLcAXcAYcAZcBacBbcBacBccBacBdcBecwHcBfczdczdbzPcBgcBhcBicBjcBkcBlcBmcBncBocBpcBqcBrcBscBtcBucBvcBvcBwcBxcBycBzbBGcBBcBCcBDcBEcBFcBGcBHbBHaabaaaaaaaaaaaaaaaaaaaabaabczwcBJcBKcBLcBMcBNcoOcoOcoOcBOcoOcoOcoOcoOcoOcoOcoOcBPbBIaaaaaacjIcxtbTXcxtcBRcxwcqacBScBTcBUcBVcBWcjIcjIcjIcjIcjIaabaaaaaacwecwecwecwecweaaaaaaaaaaaacyXaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaaaaaaaaaaabaaacyYczVczaaabcyYczVczaaaacyYczVczaaaaaaaaaaaaaaaaaaaaabaabaabaaaaabaaaaabaabaaaaaacxLcBZcvecCacCbcCbcCccvecvecvecvecvecvecvecvecvecvecvecvecvecCdcCecCdcCfcCdcqxbBYcChbCibChbChbCkcCmbClcBucCocCpcCqcCrcCscCtbBGcCvcCwcCxcCycCzcCAcCBbCwaabcCDcCDcCDcCDcCDaaaaaaaabcuGcCEcvMcCFcCGcCHcCIcoOcoOcCJcoOcoOcoOcoOcoOcCKcoOcCLbBIaaaaaacjIcxtcxtcxtbBBcCNcyMcCOcCPcCQcCRcCScCTcCUcCVcCWcjIaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyXaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaczaczakSaabaaacyYczVczaaabcyYczVczaaaacyYczVczaaabaaaaaaaaaaaaaaaaaaaaaaaaaabbCxcCYcCYcCYcCYcxLcCZcwycDacDbcDccDccDdcDecDfcDgcDgcDgcDgcDhcDicDjcDicDicDkcDkcDicDlcDmcDncDocDocDpcDqcDrcDscDtcDucDucDvcDwcDxcDycDzcDAcCscDBbBGcDCcDDcDEcDFcDGcDHcDIbCycDKcDLcDMcDNcDOcCDaaaaaacDPcDQcDRcDScDTcDRcDUcDVcDWcDXcDYcDZbzLcDYcEbcEccEdcEebCMcyJaaaaaacjIcvWcvWcvWcvWcEgcqacBScEhcEicBVcEjcEkcElcEmcEnbSIcEpaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyXaabaaaaaaaaaaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaczaaaaabaaaaabaabcEqaabaabaabcEqaabaaaaabcEqaabaaaaaaaaaaaaaaaaaaaaaaaabCxbCxbCxcEucEvcEwcExcEycEzcEAcDacDacEBcECcvecvecEDcEEcEEcEEcEEcEFcEGcEHcEGcEGcEGcDocDocEIcEJcEKcELcEMcDucENcDrcDucDucDucDucEOcBucEPcEQcCqcDAcCscDAbBGcDCcDDcEScETcEUcEVcEWbCUaabcEYcEZcDOcFacCDaaaaaaaaacDQcFbcFccFdcDRcFecFfcFgcFhcFiczEczDcFicFjcFkcFlczEczDcyJaaaaaacjIcvPcvQcvRbDrcAIcyMcFncFocFpcEmcFqcFrcFscFtcFucjIaabaabaagaaaaaaaaaaaaaaaaaaaaaaaaaaacyXaabaaaaaaaaaaabaabaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaakSaabcFvcFwcFwcFxcFycFzcFzcFzcFycFzcFzcFzcFycFzcFzcFAcFwcFwcFwcFwcFwcFBcFCcFDcFEcFFcFGcFHcFIcFJceHcwycFKcDacvecvecvecZTcEDcEEcFMcFNcFOcFPbGIcFRcFScFTcFUbDtcFWcFXcFYcFZcGabDtcGccGdcDrcGecDucDucDucGfcBucGgcGgcDAcGhcGicGjcGkcGlcGmcGncGocGpcGqcGrbCycGscDLcGtcDOcDOcCDaaaaaaaabcDQcGucFccGvcDRcGwcGxcCIcGycFicGzcGAcFicGBcGCcFlcGzcGDcyJaaaaaacjIcxtbTHcxtcGEcxwcqacGFcFocGGcqacqacGHcvWcvWcvWcjIaaaaaaaaaaaaamjamjamjawTaabaabaabaabcGIaabaabaabaabaabalwamjamjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaaaaaaaaaaabaaacyYczVczaaabcyYczVczaaaacyYczVczaaaaaaaaaaaaaaaaaaaaabaabaabaaaaabaaaaabaabaaaaaacxLcBZcvecCacCbcCbcCccvecvecvecvecvecvecvecvecvecvecvecvecvecCdcCecCdcCfcCdcqxbBYcChbCibChbChbCkcCmbClcBuctAcCpcCqcCrcCscCtbBGcCvcCwcCxcCycCzcCAcCBbCwaabcCDcCDcCDcCDcCDaaaaaaaabcuGcCEcvMcCFcCGcCHcCIcoOcoOcCJcoOcoOcoOcoOcoOcCKcoOcCLbBIaaaaaacjIcxtcxtcxtbBBcCNcyMcCOcCPcCQcCRcCScCTcCUcCVcCWcjIaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyXaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaczaczakSaabaaacyYczVczaaabcyYczVczaaaacyYczVczaaabaaaaaaaaaaaaaaaaaaaaaaaaaabbCxcCYcCYcCYcCYcxLcCZcwycDacDbcDccDccDdcDecDfcDgcDgcDgcDgcDhcDicDjcDicDicDkcDkcDicDlcDmcDncDocDocDpcDqcDrcDscDtcDucDucDvcDwctLcDycDzcDAcCscDBbBGcDCcDDcDEcDFcDGcDHcDIbCycDKcDLcDMcDNcDOcCDaaaaaacDPcDQcDRcDScDTcDRcDUcDVcDWcDXcDYcDZbzLcDYcEbcEccEdcEebCMcyJaaaaaacjIcvWcvWcvWcvWcEgcqacBScEhcEicBVcEjcEkcElcEmcEnbSIcEpaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyXaabaaaaaaaaaaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaczaaaaabaaaaabaabcEqaabaabaabcEqaabaaaaabcEqaabaaaaaaaaaaaaaaaaaaaaaaaabCxbCxbCxcEucEvctnctvctucEzcEAcDacDacEBcECcvecvecEDcEEcEEcEEcEEcEFcEGcEHcEGcEGcEGcDocDocEIcEJcEKcELcEMcDucENcDrcDucDucDucDucEOcBucEPcEQcCqcDAcCscDAbBGcDCcDDcEScETcEUcEVcEWbCUaabcEYcEZcDOcFacCDaaaaaaaaacDQcFbcFccFdcDRcFecFfcFgcFhcFiczEczDcFicFjcFkcFlczEczDcyJaaaaaacjIcvPcvQcvRbDrcAIcyMcFncFocFpcEmcFqcFrcFscFtcFucjIaabaabaagaaaaaaaaaaaaaaaaaaaaaaaaaaacyXaabaaaaaaaaaaabaabaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaakSaabcFvcFwcFwcFxcFycFzcFzcFzcFycFzcFzcFzcFycFzcFzcFAcFwcFwcFwcFwcFwcFBcFCcFDcFEcFFcFGctwcFIcFJceHcwycFKcDacvecvecvecZTcEDcEEcFMctMcFOcFPbGIcFRcFScFTcFUbDtcFWcFXcFYcFZcGabDtcGccGdcDrcGecDucDucDucGfcBucGgcGgcDAcGhcGicGjcGkcGlcGmcGncGocGpcGqcGrbCycGscDLcGtcDOcDOcCDaaaaaaaabcDQcGucFccGvcDRcGwcGxcCIcGycFicGzcGAcFicGBcGCcFlcGzcGDcyJaaaaaacjIcxtbTHcxtcGEcxwcqacGFcFocGGcqacqacGHcvWcvWcvWcjIaaaaaaaaaaaaamjamjamjawTaabaabaabaabcGIaabaabaabaabaabalwamjamjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaczaaaaabaaaaabaabcGJaabaaaaabcGJaabaaaaabcGJaabaaaaaaaaaaaaaaaaaaaaaaaabCxbCxbCxcGLcGMcGNcCYcZUceHcGPcEzcEzcEzcEzcGQcEzcFJcEEcGRcGScGTcGUbDGcGWcGXcGYcGZbEocHbcHccHdbFlcktbGPcGccENcDrcZicHjcDucDucHkcBucHlcHmcDAcHncCscHocHpbFvbFtbGBbFQbGEbGCbGEbGGaabcCDcCDcCDcCDcCDaabaabaabcHxcHycFccGvcDRcHzcHAcHBcHCcHDcHEcHFcHFcHGcHFcHHcHIcDRcHJaaaaaacjIcxtcxtcxtbDrcHKcHLcHMcHNcHOcCTcCTcCTcHPcHQcHRbGHaaaaaaaaaaaaamjaaaaabaaaaabaaaaaaaaacHTaaaaabaabaaaaaaaaaaaaamjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaczaczakSaabaabcyYcHUczaaaacyYcHUczaaaacyYcHUczaaabaaaaaaaaaaaaaaaaaaaaaaabaabbCxcCYcCYcCYcCYcHWcHXcHYceHcZVceHceHcEDcIaceHcEEbYRcaecGTcajbGIcamcIhcIicIjbGRcIlcImcIncIocIpbGRcIrcIscItcIucIvcIwcIxcIycIzcIAcGjcIBcICcIDcIEcIFcIGcIHcIIcIJcIKcILcIMbGVcDKcDLcIPcIOcIOcCDaaaaaaaabcDQcIQcFccIRcDRbIxbIxbIxbIxcDRcIVcIWcIXcIYcIZcJacJbcIYbIBaaacDPcjIcjIcjIcjIcjIcJdcqacJecyMcJfcyMcJgcyMcJhcyMcJibGHaaaaaaaaaaaaamjaaacJkcJkcJkcJkcJkaabcJlaabcJkcJkcJkcJkcJkaaaamjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJmaaaaaaaaacJmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxKcxKcxKcxKcxKcxKcxKcxKcxKaaaaaaaaaaaaaaaaaaaaaaaacyYcHUczaaabcyYcHUczaaaacyYcHUczaaaaaaaaaaaabaaaaaaaaaaaaaabaabaabaaaaaaaabaabcJncJncJncJncJncJncJncJocJncJncEEcJpcJqcGTcajbGIbICbGIbJhcJvcDocJwcJxcFZcJycJzcDocJAcDucDrcJBcJCcJDcIxcJEcJFcJGcJHcJIcJJcJKcJHcJLcJMcJNcJOcDAcJPcJQcJRbJCaabcEYcJUcJTcJVcCDaaaaaaaaacDQcDRcJWcJXcDRcJYcJZcKacKbciIcFccKdcKecIYbJEcKgcKhcKibIBaabaaaaaaaaaaaaaaacjIcKkcKlcKmcKncKocKpcKqcKrcKocKpcKscjIaaaaaaaaaaaaamjaabcKtcKucKucKucKucKvcKwcKxcKycKycKycKycKzaabamjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJmcJmcJmcJmcJmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm
index 31fbcc1fb0b..571e5e81d99 100644
--- a/_maps/map_files/cyberiad/z2.dmm
+++ b/_maps/map_files/cyberiad/z2.dmm
@@ -119,8 +119,8 @@
"co" = (/turf/unsimulated/wall,/area/prison/solitary)
"cp" = (/turf/simulated/wall/mineral/alien,/area/xenos_station/start)
"cq" = (/obj/structure/grille,/obj/structure/window/plasmareinforced,/obj/structure/window/plasmareinforced{dir = 8},/obj/structure/window/plasmareinforced{dir = 1},/obj/machinery/door/poddoor/shutters{color = "purple"; density = 0; dir = 2; icon_state = "shutter0"; id_tag = "alienshutters"; name = "Alien Blast Shutters"; opacity = 0},/turf/simulated/floor/plating/airless,/area/xenos_station/start)
-"cr" = (/obj/structure/grille,/obj/structure/window/plasmareinforced,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 1},/obj/machinery/door/poddoor/shutters{color = "purple"; density = 0; dir = 2; icon_state = "shutter0"; id_tag = "alienshutters"; name = "Alien Blast Shutters"; opacity = 0},/turf/simulated/floor/plating/airless,/area/xenos_station/start)
-"cs" = (/obj/structure/grille,/obj/structure/window/plasmareinforced,/obj/structure/window/plasmareinforced{dir = 1},/obj/machinery/door/poddoor/shutters{color = "purple"; density = 0; dir = 2; icon_state = "shutter0"; id_tag = "alienshutters"; name = "Alien Blast Shutters"; opacity = 0},/turf/simulated/floor/plating/airless,/area/xenos_station/start)
+"cr" = (/obj/structure/grille,/obj/structure/window/plasmareinforced,/obj/structure/window/plasmareinforced{dir = 1},/obj/machinery/door/poddoor/shutters{color = "purple"; density = 0; dir = 2; icon_state = "shutter0"; id_tag = "alienshutters"; name = "Alien Blast Shutters"; opacity = 0},/turf/simulated/floor/plating/airless,/area/xenos_station/start)
+"cs" = (/obj/structure/grille,/obj/structure/window/plasmareinforced,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 1},/obj/machinery/door/poddoor/shutters{color = "purple"; density = 0; dir = 2; icon_state = "shutter0"; id_tag = "alienshutters"; name = "Alien Blast Shutters"; opacity = 0},/turf/simulated/floor/plating/airless,/area/xenos_station/start)
"ct" = (/turf/simulated/floor/holofloor{tag = "icon-asteroid5"; icon_state = "asteroid5"; dir = 2},/area/holodeck/source_desert)
"cu" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/grassybush,/turf/simulated/floor/holofloor{tag = "icon-wood_siding6"; icon_state = "wood_siding6"; dir = 2},/area/holodeck/source_picnicarea)
"cv" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/grassybush,/turf/simulated/floor/holofloor{tag = "icon-wood_siding10"; icon_state = "wood_siding10"; dir = 2},/area/holodeck/source_picnicarea)
@@ -1128,7 +1128,7 @@
"vJ" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_centcom_dock"; pixel_y = -25; req_access_txt = "109"; tag_door = "specops_centcom_dock_inner"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops)
"vK" = (/obj/structure/table/woodentable{dir = 10},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "SPECOPS"; name = "Ready Room"; pixel_y = 16; req_access_txt = "114"},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "ASSAULT"; name = "Assault Armor"; pixel_y = -4; req_access_txt = "114"},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "specopsoffice"; name = "Privacy Shutters"; pixel_y = 6; req_access_txt = "114"},/turf/unsimulated/floor{dir = 8; icon_state = "carpetside"},/area/centcom/specops)
"vL" = (/obj/structure/stool/bed/chair/comfy/black{dir = 1},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/specops)
-"vM" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; name = "Spec Ops Intercom"; pixel_y = 28},/obj/machinery/artillerycontrol{luminosity = 255},/turf/unsimulated/floor{dir = 4; icon_state = "carpetside"},/area/centcom/specops)
+"vM" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; name = "Spec Ops Intercom"; pixel_y = 28},/obj/machinery/computer/artillerycontrol{luminosity = 255},/turf/unsimulated/floor{dir = 4; icon_state = "carpetside"},/area/centcom/specops)
"vN" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops)
"vO" = (/obj/machinery/telecomms/processor/preset_cent,/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control)
"vP" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_centcom_dock_inner"; locked = 1; name = "Shuttle Hatch"; req_access = null; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops)
@@ -1370,7 +1370,7 @@
"Ar" = (/obj/machinery/door/unpowered/shuttle{req_access_txt = "106"},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom)
"As" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "106"},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom)
"At" = (/obj/machinery/door/airlock/external{name = "Transport Shuttle"; opacity = 0; req_access_txt = "106"},/turf/unsimulated/floor{name = "plating"},/area/space)
-"Au" = (/obj/machinery/computer/shuttle_control{req_access = null; req_access_txt = "106"; shuttle_tag = "Centcom"},/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_shuttle_bay"; name = "shuttle bay controller"; pixel_x = 25; pixel_y = 0; req_access_txt = "106"; req_one_access_txt = "0"; tag_door = "centcom_shuttle_bay_door"},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac)
+"Au" = (/obj/machinery/computer/shuttle_control{req_access = null; req_access_txt = "106"; shuttle_tag = "Centcom"},/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_shuttle"; pixel_x = 25; pixel_y = 0; req_access_txt = "106"; req_one_access_txt = "0"; tag_door = "centcom_shuttle_hatch"},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac)
"Av" = (/obj/structure/shuttle/engine/propulsion,/turf/space,/area/shuttle/escape/centcom)
"Aw" = (/obj/structure/table,/turf/simulated/shuttle/floor,/area/centcom/evac)
"Ax" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/turf/simulated/shuttle/floor,/area/centcom/evac)
@@ -1389,7 +1389,7 @@
"AK" = (/turf/simulated/shuttle/wall{icon_state = "swall13"; dir = 2},/area/shuttle/transport1/centcom)
"AL" = (/obj/machinery/computer/crew,/turf/simulated/shuttle/floor,/area/centcom/evac)
"AM" = (/obj/machinery/computer/communications,/turf/simulated/shuttle/floor,/area/centcom/evac)
-"AN" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "admin_shuttle_bay"; name = "shuttle bay controller"; pixel_x = 25; pixel_y = 0; req_access_txt = "106"; req_one_access_txt = "0"; tag_door = "admin_shuttle_bay_door"},/obj/machinery/computer/shuttle_control{req_access_txt = "106"; req_one_access_txt = "0"; shuttle_tag = "Administration"},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac)
+"AN" = (/obj/machinery/computer/shuttle_control{req_access_txt = "106"; req_one_access_txt = "0"; shuttle_tag = "Administration"},/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "admin_shuttle_port"; pixel_x = 25; pixel_y = 0; req_one_access_txt = "106"; tag_door = "admin_shuttle_hatch_port"},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac)
"AO" = (/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor,/area/centcom/evac)
"AP" = (/obj/structure/table,/obj/item/device/radio,/turf/simulated/shuttle/floor,/area/centcom/evac)
"AQ" = (/obj/machinery/door/airlock/external{name = "Administration Shuttle"; opacity = 0; req_access_txt = "106"},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac)
@@ -1666,7 +1666,7 @@
"Gb" = (/obj/structure/table/woodentable,/obj/item/toy/cards/deck/syndicate,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/admin)
"Gc" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/devilskiss,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/admin)
"Gd" = (/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/turf/unsimulated/wall{desc = "This window appears to be reinforced, it looks nearly impossible to break."; dir = 8; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; name = "window"; opacity = 0; tag = "icon-window5_end (WEST)"},/area/admin)
-"Ge" = (/obj/machinery/artillerycontrol{luminosity = 255},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
+"Ge" = (/obj/machinery/computer/artillerycontrol{luminosity = 255},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
"Gf" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
"Gg" = (/obj/item/weapon/stool,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/admin)
"Gh" = (/obj/structure/table/woodentable,/obj/item/weapon/lighter/zippo/fluff/naples_1,/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/admin)
@@ -1678,7 +1678,7 @@
"Gn" = (/obj/machinery/computer/message_monitor,/obj/item/weapon/paper/monitorkey,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
"Go" = (/obj/machinery/computer/atmos_alert,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
"Gp" = (/obj/machinery/computer/secure_data,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
-"Gq" = (/obj/machinery/account_database{name = "Admin Accounts Database"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
+"Gq" = (/obj/machinery/computer/account_database{name = "Admin Accounts Database"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
"Gr" = (/obj/structure/table,/obj/item/weapon/gun/projectile/automatic/pistol,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
"Gs" = (/obj/structure/table,/obj/machinery/door_control{desc = "A remote control switch to lock down external access to the admin room."; icon_state = "doorctrl0"; id = "ADMINLOCKDOWN"; name = "Lockdown"; pixel_y = 0; req_access_txt = "0"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
"Gt" = (/obj/structure/table,/obj/item/weapon/storage/fancy/cigarettes/syndicate,/obj/item/weapon/reagent_containers/food/drinks/cans/adminbooze,/obj/item/weapon/reagent_containers/food/drinks/cans/badminbrew,/obj/item/weapon/reagent_containers/food/drinks/cans/madminmalt,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
@@ -1805,7 +1805,7 @@ amaVbabdaYbfaTaXbbaWbeaZbgaUbcaSaTbfbebabdaXaZaYaUaWaeaqarasatauavbhaxbjbkboblbm
adaYaWbgaXbcbaaTbebfaUbbaSbdaZaVbabcaUaWbgaTbbaXbdbfahbhbibjbkboblbmaDapaqarasatauavbhbiavbhbibjbmbnapaqarasatauavbhaxaLaMaYaWbgaXbcbaaTbebfaUbbaSbdaZaVbabcaUaWbgaTaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqbObqbqbqbsbPbQbPbQbPbsbIbIbIbIbIbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsbLbMbMbMbNbD
alaXbfaSaTaZaWbaaUbcbdbeaVbgbbaYaWaZbdbfaSbabeaTbgbcagbmbnapaqarasataJavbhbibjbkboblbmbnasatauavatauavbhbibjbkboblbmaDaLaMaXbfaSaTaZaWbaaUbcbdbeaVbgbbaYaWaZbdbfaSbaaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqbqbRbSbqbsbTbTbTbTbTbsbUbUbUbUbVbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsbLbMbMbMbNbD
aoaTbcaVbabbbfaWbdaZbgbWbXbYbWbWbfbbbgbcaVaWaUbaaSaZacbhbibjbkboblbmaDapaqarasatauavbhbibjbkboblbmbnapaqarasatauavbhaxaLaMaTbcaVbabbbfaWbdaZbgaUaYaSbeaXbfbbbgbcaVaWaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpcabqbqbqbqbscbcccdcccebscfcgchcicfbsbxbxbJbxbxbsbybybybybybsbzbzbzbzbzbsbLbMbMbMbNbD
-abbaaZaYaWbebcbfbgbbcjbXckclcmcnbWbeaSaZaYbfbdaWaVbbaiarasatauavbhbiaybkboblbmbnapaqarasapaqarasbibjbkboblbmbnapaqaraHaLaMbaaZaYaWbebcbfbgbbaSbdaXaVaUaYbcbeaSaZaYbfaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcocococococococococococococococoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZbZcpcqcscrcpbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqcabqbqctbscucccdcccvbscfcwcxcycfbsbxbxbJbxbxbsbybybybybybsbzbzbzbzbzbsczbMbMbMcAbD
+abbaaZaYaWbebcbfbgbbcjbXckclcmcnbWbeaSaZaYbfbdaWaVbbaiarasatauavbhbiaybkboblbmbnapaqarasapaqarasbibjbkboblbmbnapaqaraHaLaMbaaZaYaWbebcbfbgbbaSbdaXaVaUaYbcbeaSaZaYbfaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcocococococococococococococococoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZbZcpcqcrcscpbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqcabqbqctbscucccdcccvbscfcwcxcycfbsbxbxbJbxbxbsbybybybybybsbzbzbzbzbzbsczbMbMbMcAbD
aeaWbbaXbfaUaZbcaScBcCckclcmcDcDcEcFaVbbaXbcbgbfaYbeafboblbmbnapaqaraHatauavbhbibjbkbocGcHcIcJcKcLasatauavbhbibjbkboaBaLaMaWbbaXbfaUaZbccjcBcMcNcOcPcQbaaZaUaVbbaXbcaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcRcScTcocScUcocScVcocWcXcocScUcoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZbZcpcpcYcZdacpcpbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqbEcabqbRbsbTbTbTbTbTbsdbcwcxcydbbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsczbMbMbMcAbD
ahbfbeaTbcbdbbaZaVdcdddddedfckdgdgcFaYbeaTaZaSbcaXaUanbnapaqarasatauaKbhbibjbkboblbmbncIdhdidjdkdlavbhbibjbkboblbmbnaEaLaMbfbeaTbcbdbbcEcFdmdmdmdmdmcNdnbbbdaYbeaTaZaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcododpcodocXcododqcodocUcodocTcoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZcpcpdadadrdadacpcpbZaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqbqbqcabqbsdsdtdsdtdsbsducwcxcydubsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsczbMbMbMcAbD
agbcaUbaaZbgbebbaYdvdededwdxdyclcldzaXaUbabbaVaZaTbdakbjbkboblbmbnapaFarasatauavbhbibjdAdBdCdDdhdEaqarasatauavbhbibjazaLaMbcaUbaaZbgcBcFdmdmdmdmdmdmdmdFcBbfaXaUbabbaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcocococococococococococococococoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZcpdadadadadadadacpbZaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqdGbqbqcabsbGbHbGbHbGbsducwcxcydubsbxbJbxbJbxbsbybybybybybsbzbKbzbKbzbsczbMbMbMcAbD
@@ -2055,4 +2055,3 @@ aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
"}
-
diff --git a/_maps/map_files/cyberiad/z3.dmm b/_maps/map_files/cyberiad/z3.dmm
index afd45e79a66..bea6ad97392 100644
--- a/_maps/map_files/cyberiad/z3.dmm
+++ b/_maps/map_files/cyberiad/z3.dmm
@@ -341,7 +341,7 @@
"gC" = (/obj/machinery/turretid/stun{ailock = 1; check_synth = 1; control_area = "\improper Telecoms Foyer"; desc = "A firewall prevents AI's from interacting with this device."; name = "Telecoms Foyer Turret Control"; pixel_y = 30; req_access = list(61)},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor,/area/tcommsat/entrance)
"gD" = (/obj/structure/sign/electricshock,/turf/simulated/wall/r_wall,/area/tcommsat/entrance)
"gE" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/tcommsat/entrance)
-"gF" = (/obj/structure/closet/crate,/obj/item/clothing/glasses/night,/obj/machinery/light_switch{pixel_y = -28},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/tcommsat/entrance)
+"gF" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/camera{c_tag = "Telecomms Foyer"; dir = 2; network = list("Telecomms")},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"gG" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/space)
"gH" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/tcommsat/entrance)
"gI" = (/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/tcommsat/entrance)
@@ -360,7 +360,7 @@
"gV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/turf/simulated/floor{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/tcommsat/entrance)
"gW" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/tcommsat/entrance)
"gX" = (/turf/simulated/floor{tag = "icon-warningcorner (WEST)"; icon_state = "warningcorner"; dir = 8},/area/tcommsat/entrance)
-"gY" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; layer = 2.4; on = 1},/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/tcommsat/entrance)
+"gY" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"gZ" = (/turf/simulated/wall/r_wall,/area/tcommsat/powercontrol)
"ha" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor,/area/tcommsat/entrance)
"hb" = (/obj/machinery/power/apc{dir = 1; name = "Telecoms Sat. Teleporter APC"; pixel_x = 1; pixel_y = 26},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/tcommsat/entrance)
@@ -372,7 +372,7 @@
"hh" = (/obj/machinery/camera/xray{c_tag = "Telecomms Airlock"; network = list("Telecomms")},/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"hi" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"hj" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1381; master_tag = "telecoms_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
-"hk" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/camera{c_tag = "Telecomms Foyer"; dir = 2; network = list("Telecomms")},/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
+"hk" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; layer = 2.4; on = 1},/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/obj/structure/table,/obj/machinery/recharger,/turf/simulated/floor,/area/tcommsat/entrance)
"hl" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"hm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/space)
"hn" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_x = 29; pixel_y = 0},/turf/simulated/floor,/area/tcommsat/entrance)
@@ -442,7 +442,7 @@
"iz" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/tcommsat/entrance)
"iA" = (/obj/machinery/door/airlock/external{frequency = 1381; icon_state = "door_locked"; id_tag = "telecoms_outer"; locked = 1; name = "External Access"; req_access = null; req_access_txt = "10;13"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"iB" = (/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
-"iC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
+"iC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/closet/crate,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"iD" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"iE" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 4; name = "Telecoms Sat. Power Control APC"; pixel_x = 25},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"iF" = (/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/tcommsat/entrance)
@@ -451,9 +451,9 @@
"iI" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1381; master_tag = "telecoms_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "13"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/tcommsat/powercontrol)
"iJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/light{dir = 1},/turf/simulated/floor/plating/airless,/area/tcommsat/powercontrol)
"iK" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/plating/airless,/area/tcommsat/powercontrol)
-"iL" = (/obj/machinery/light{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
+"iL" = (/obj/machinery/light{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; layer = 2.4; on = 1},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"iM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
-"iN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
+"iN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/table,/obj/machinery/cell_charger,/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"iO" = (/obj/machinery/door/airlock/hatch{name = "Telecoms Power Control"; req_access_txt = "61"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"iP" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"iQ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor,/area/tcommsat/entrance)
@@ -462,10 +462,9 @@
"iT" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor,/area/tcommsat/entrance)
"iU" = (/obj/machinery/power/smes{charge = 2.5e+006; input_attempt = 1; input_level = 250000; inputting = 1; output_level = 250000},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"iV" = (/obj/structure/cable,/obj/machinery/power/terminal{dir = 4},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
-"iW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/table,/obj/machinery/recharger,/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
-"iX" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 140; on = 1; pressure_checks = 0},/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
+"iW" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/light_switch{pixel_y = -28},/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
+"iX" = (/obj/structure/closet/crate,/obj/machinery/light_switch{pixel_y = -28},/obj/item/clothing/glasses/night,/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/tcommsat/entrance)
"iY" = (/obj/structure/sign/electricshock,/turf/simulated/wall/r_wall,/area/tcommsat/powercontrol)
-"iZ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/table,/obj/machinery/cell_charger,/obj/machinery/light_switch{pixel_y = -28},/turf/simulated/floor/plating,/area/tcommsat/powercontrol)
"ja" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/tracker,/turf/simulated/floor/plating/airless,/area/space)
"jb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/space)
"jc" = (/obj/structure/lattice,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/space)
@@ -609,11 +608,11 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiecccccdcfcgcgcgcgcgcdgthagMgwgKgLgMgNgMgOgtcdcgcgcgcgcgcfcdccccieaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaidibcccccdcdcdcdcdcdcdgtgtgtgtgPgQgRgtgtgtgtcdcdcdcdcdcdcdcccchHicaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaidibgZgZgZgZgZgZgZgZgZgZgtgtgSgTgUgtcccccccccccccccccccccchHicaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiegZhchhhdhjhihkhihlgZgtgtgVgWgXgtgtbWhHhZhZhZhZhZhZhZhZicaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahmgZhoiqgZiwivivivixgZgtgYiziygMhbgtgtiebWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiegZhchhhdhjhigYgFhlgZgtgtgVgWgXgtgtbWhHhZhZhZhZhZhZhZhZicaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahmgZhoiqgZiwivivivixgZgthkiziygMhbgtgtiebWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahmgZiAgZgZiCiBiDiBiEgZiFheiHiGhfhfhggtieaUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagGiJiIiKgZiLiBiNiMiPiOiRiQiTiShfhfhngtieaUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYbYhGbYgZiViUiXiWiZiYgFhqhfhfhfhfhggtiebWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagGiJiIiKgZiLiMiMiMiPiOiRiQiTiShfhfhngtieaUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYbYhGbYgZiViUiviNiWiYiXhqhfhfhfhfhggtiebWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYbYhGbYgZgZgZgZgZgZgZgthrhshshshtgtgtiebWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajaeRiueRjbhZhZhZhZhZibgtgthuhvhwgtgthHicbWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWbWidibgtgtgtgtgthHicbWbWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/code/__DEFINES/btime.dm b/code/__DEFINES/btime.dm
index a80446d441c..33d5def1deb 100644
--- a/code/__DEFINES/btime.dm
+++ b/code/__DEFINES/btime.dm
@@ -10,8 +10,8 @@ var/global/__btime__libName = "btime.[world.system_type==MS_WINDOWS?"dll":"so"]"
// This will always return 1 unless the btime library cannot be accessed
if(TimeOfHour || 1) return 1
catch(var/exception/e)
- world.log << "PRECISE_TIMER_AVAILABLE is defined in btime.dm, but calling the btime library failed: [e]"
- world.log << "This is a fatal error. The world will now shut down."
+ log_to_dd("PRECISE_TIMER_AVAILABLE is defined in btime.dm, but calling the btime library failed: [e]")
+ log_to_dd("This is a fatal error. The world will now shut down.")
del(world)
#else
#define TimeOfHour (world.timeofday % 36000)
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index ff2ac44ffe2..49d3e68c031 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -137,7 +137,7 @@
if(sight_check && !isInSight(A, O))
continue
L |= M
- //world.log << "[recursion_limit] = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])"
+ //log_to_dd("[recursion_limit] = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])")
else if(include_radio && istype(A, /obj/item/device/radio))
if(sight_check && !isInSight(A, O))
@@ -167,7 +167,7 @@
var/mob/M = A
if(M.client)
hear += M
- //world.log << "Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])"
+ //log_to_dd("Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])")
else if(istype(A, /obj/item/device/radio))
hear += A
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 210e5ed891e..c69742b94c8 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -4,32 +4,16 @@
//////////////////////////
/proc/makeDatumRefLists()
+ //hair
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, hair_styles_list, hair_styles_male_list, hair_styles_female_list)
+ //facial hair
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, facial_hair_styles_list, facial_hair_styles_male_list, facial_hair_styles_female_list)
+ //underwear
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, underwear_list, underwear_m, underwear_f)
+ //undershirt
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, undershirt_list, undershirt_m, undershirt_f)
+
var/list/paths
-
- //Hair - Initialise all /datum/sprite_accessory/hair into an list indexed by hair-style name
- paths = subtypesof(/datum/sprite_accessory/hair)
- for(var/path in paths)
- var/datum/sprite_accessory/hair/H = new path()
- hair_styles_list[H.name] = H
- switch(H.gender)
- if(MALE) hair_styles_male_list += H.name
- if(FEMALE) hair_styles_female_list += H.name
- else
- hair_styles_male_list += H.name
- hair_styles_female_list += H.name
-
- //Facial Hair - Initialise all /datum/sprite_accessory/facial_hair into an list indexed by facialhair-style name
- paths = subtypesof(/datum/sprite_accessory/facial_hair)
- for(var/path in paths)
- var/datum/sprite_accessory/facial_hair/H = new path()
- facial_hair_styles_list[H.name] = H
- switch(H.gender)
- if(MALE) facial_hair_styles_male_list += H.name
- if(FEMALE) facial_hair_styles_female_list += H.name
- else
- facial_hair_styles_male_list += H.name
- facial_hair_styles_female_list += H.name
-
//Surgery Steps - Initialize all /datum/surgery_step into a list
paths = subtypesof(/datum/surgery_step)
for(var/T in paths)
diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm
index c0b2d3af292..5f4be64c9db 100644
--- a/code/__HELPERS/lists.dm
+++ b/code/__HELPERS/lists.dm
@@ -370,7 +370,7 @@
//Don't use this on lists larger than half a dozen or so
/proc/insertion_sort_numeric_list_ascending(var/list/L)
- //world.log << "ascending len input: [L.len]"
+ //log_to_dd("ascending len input: [L.len]")
var/list/out = list(pop(L))
for(var/entry in L)
if(isnum(entry))
@@ -383,13 +383,13 @@
if(!success)
out.Add(entry)
- //world.log << " output: [out.len]"
+ //log_to_dd(" output: [out.len]")
return out
/proc/insertion_sort_numeric_list_descending(var/list/L)
- //world.log << "descending len input: [L.len]"
+ //log_to_dd("descending len input: [L.len]")
var/list/out = insertion_sort_numeric_list_ascending(L)
- //world.log << " output: [out.len]"
+ //log_to_dd(" output: [out.len]")
return reverselist(out)
/proc/dd_sortedObjectList(var/list/L, var/cache=list())
@@ -583,4 +583,3 @@ proc/dd_sortedObjectList(list/incoming)
/datum/alarm/dd_SortValue()
return "[sanitize(last_name)]"
-
\ No newline at end of file
diff --git a/code/__HELPERS/logging.dm b/code/__HELPERS/logging.dm
index ac569991aa7..fd07b20e641 100644
--- a/code/__HELPERS/logging.dm
+++ b/code/__HELPERS/logging.dm
@@ -8,16 +8,16 @@
/proc/error(msg)
- world.log << "## ERROR: [msg]"
+ log_to_dd("## ERROR: [msg]")
#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].")
//print a warning message to world.log
/proc/warning(msg)
- world.log << "## WARNING: [msg]"
+ log_to_dd("## WARNING: [msg]")
//print a testing-mode debug message to world.log
/proc/testing(msg)
- world.log << "## TESTING: [msg]"
+ log_to_dd("## TESTING: [msg]")
/proc/log_admin(text)
admin_log.Add(text)
@@ -80,3 +80,8 @@
/proc/log_misc(text)
diary << "\[[time_stamp()]]MISC: [text][log_end]"
+
+/proc/log_to_dd(text)
+ world.log << text //this comes before the config check because it can't possibly runtime
+ if(config.log_world_output)
+ diary << "\[[time_stamp()]]DD_OUTPUT: [text][log_end]"
\ No newline at end of file
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 4658e6691ea..619716363f9 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -1,4 +1,16 @@
-proc/random_hair_style(gender, species = "Human")
+/proc/random_underwear(var/gender)
+ switch(gender)
+ if(MALE) return pick(underwear_m)
+ if(FEMALE) return pick(underwear_f)
+ else return pick(underwear_list)
+
+/proc/random_undershirt(var/gender)
+ switch(gender)
+ if(MALE) return pick(undershirt_m)
+ if(FEMALE) return pick(undershirt_f)
+ else return pick(undershirt_list)
+
+proc/random_hair_style(var/gender, species = "Human")
var/h_style = "Bald"
var/list/valid_hairstyles = list()
@@ -29,7 +41,7 @@ proc/random_hair_style(gender, species = "Human")
if(SOUTHEAST) return NORTHWEST
return 0
-proc/random_facial_hair_style(gender, species = "Human")
+proc/random_facial_hair_style(var/gender, species = "Human")
var/f_style = "Shaved"
var/list/valid_facialhairstyles = list()
@@ -136,14 +148,14 @@ proc/add_logs(mob/target, mob/user, what_done, var/object=null, var/addition=nul
if(!user)
return
if(ismob(user))
- user.attack_log += text("\[[time_stamp()]\] Has [what_done] [target.name][ismob(target) ? "([target.ckey])" : ""][object ? " with [object]" : " "][addition]")
+ user.attack_log += text("\[[time_stamp()]\] Has [what_done] [key_name(target)][object ? " with [object]" : " "][addition]")
if(ismob(target))
- target.attack_log += text("\[[time_stamp()]\] Has been [what_done] by [user.name][ismob(user) ? "([user.ckey])" : ""][object ? " with [object]" : " "][addition]")
+ target.attack_log += text("\[[time_stamp()]\] Has been [what_done] by [key_name(user)][object ? " with [object]" : " "][addition]")
if(admin)
- log_attack("[user.name][ismob(user) ? "([user.ckey])" : ""] [what_done] [target.name][ismob(target) ? "([target.ckey])" : ""][object ? " with [object]" : " "][addition]")
+ log_attack("[key_name(user)] [what_done] [key_name(target)][object ? " with [object]" : " "][addition]")
if(target.client)
if(what_done in ignore) return
if(target == user)return
if(!admin) return
- msg_admin_attack("[user.name][ismob(user) ? "([user.ckey])" : ""][isAntag(user) ? "(ANTAG)" : ""] [what_done] [target.name][ismob(target) ? "([target.ckey])" : ""][object ? " with [object]" : " "][addition](JMP)")
+ msg_admin_attack("[key_name_admin(user)] [what_done] [key_name_admin(target)][object ? " with [object]" : " "][addition]")
diff --git a/code/__HELPERS/sanitize_values.dm b/code/__HELPERS/sanitize_values.dm
index 4b521f9bfbb..1be69032cf1 100644
--- a/code/__HELPERS/sanitize_values.dm
+++ b/code/__HELPERS/sanitize_values.dm
@@ -14,7 +14,7 @@
/proc/sanitize_inlist(value, list/List, default)
if(value in List) return value
if(default) return default
- if(List && List.len)return List[1]
+ if(List && List.len)return pick(List)
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 2b840e6759c..bdeac1a9565 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -18,6 +18,9 @@
var/sqltext = dbcon.Quote(t);
return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that
+/proc/format_table_name(table as text)
+ return sqlfdbktableprefix + table
+
/*
* Text sanitization
*/
@@ -339,4 +342,19 @@ proc/checkhtml(var/t)
/proc/trim_strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN)
return trim(strip_html_properly(input, max_length))
+
+//Used in preferences' SetFlavorText and human's set_flavor verb
+//Previews a string of len or less length
+/proc/TextPreview(var/string,var/len=40)
+ if(lentext(string) <= len)
+ if(!lentext(string))
+ return "\[...\]"
+ else
+ return string
+ else
+ return "[copytext_preserve_html(string, 1, 37)]..."
+
+//alternative copytext() for encoded text, doesn't break html entities (" and other)
+/proc/copytext_preserve_html(var/text, var/first, var/last)
+ return html_encode(copytext(html_decode(text), first, last))
\ No newline at end of file
diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm
index cbc7fd08920..af4de68fd7a 100644
--- a/code/__HELPERS/time.dm
+++ b/code/__HELPERS/time.dm
@@ -4,25 +4,14 @@
#define HOURS *36000
//Returns the world time in english
-proc/worldtime2text(time = world.time)
+/proc/worldtime2text(time = world.time)
return "[round(time / 36000)+12]:[(time / 600 % 60) < 10 ? add_zero(time / 600 % 60, 1) : time / 600 % 60]"
-proc/time_stamp()
+/proc/time_stamp()
return time2text(world.timeofday, "hh:mm:ss")
-
-/* Preserving this so future generations can see how fucking retarded some people are
-proc/time_stamp()
- var/hh = text2num(time2text(world.timeofday, "hh")) // Set the hour
- var/mm = text2num(time2text(world.timeofday, "mm")) // Set the minute
- var/ss = text2num(time2text(world.timeofday, "ss")) // Set the second
- var/ph
- var/pm
- var/ps
- if(hh < 10) ph = "0"
- if(mm < 10) pm = "0"
- if(ss < 10) ps = "0"
- return"[ph][hh]:[pm][mm]:[ps][ss]"
-*/
+
+/proc/gameTimestamp(format = "hh:mm:ss") // Get the game time in text
+ return time2text(world.time - timezoneOffset + 432000, format)
/* Returns 1 if it is the selected month and day */
proc/isDay(var/month, var/day)
@@ -35,3 +24,8 @@ proc/isDay(var/month, var/day)
// Uncomment this out when debugging!
//else
//return 1
+
+//returns timestamp in a sql and ISO 8601 friendly format
+/proc/SQLtime()
+ return time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
+
\ No newline at end of file
diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm
index bac5959d630..1ef5f60488e 100644
--- a/code/__HELPERS/type2type.dm
+++ b/code/__HELPERS/type2type.dm
@@ -248,7 +248,7 @@ proc/tg_text2list(text, glue=",", assocglue=";")
if(4.0) return EAST
if(8.0) return WEST
else
- world.log << "UNKNOWN DIRECTION: [direction]"
+ log_to_dd("UNKNOWN DIRECTION: [direction]")
/proc/dir2text(direction)
switch(direction)
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index e5219516f27..3612c4d8c4d 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -653,7 +653,15 @@ Turf and target are seperate in case you want to teleport some distance from a t
return .
/proc/key_name_admin(var/whom, var/include_name = 1)
- return key_name(whom, 1, include_name)
+ var/message = "[key_name(whom, 1, include_name)](?)[isAntag(whom) ? " (ANTAG)" : ""] ([admin_jump_link(whom, "holder")])"
+ return message
+
+/proc/get_mob_by_ckey(key)
+ if(!key)
+ return
+ for(var/mob/M in mob_list)
+ if(M.ckey == key)
+ return M
// Returns the atom sitting on the turf.
// For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf.
diff --git a/code/_globalvars/database.dm b/code/_globalvars/database.dm
index 437f479f99c..987b31b9ff7 100644
--- a/code/_globalvars/database.dm
+++ b/code/_globalvars/database.dm
@@ -9,6 +9,7 @@ var/sqlpass = "example"
var/sqlfdbkdb = "paradise"
var/sqlfdbklogin = "root"
var/sqlfdbkpass = "example"
+var/sqlfdbktableprefix = "erro_" //backwords compatibility with downstream server hosts
var/sqllogging = 0 // Should we log deaths, population stats, etc?
diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm
index 8ec230cc13b..882331d21de 100644
--- a/code/_globalvars/lists/flavor_misc.dm
+++ b/code/_globalvars/lists/flavor_misc.dm
@@ -8,12 +8,13 @@ var/global/list/facial_hair_styles_male_list = list()
var/global/list/facial_hair_styles_female_list = list()
var/global/list/skin_styles_female_list = list() //unused
//Underwear
-var/global/list/underwear_m = list("White", "Grey", "Green", "Blue", "Black", "Mankini", "None")
-var/global/list/underwear_f = list("Red", "White", "Yellow", "Blue", "Black", "Thong", "None")
-var/global/list/underwear_list = underwear_m + underwear_f
- //undershirt
-var/global/list/undershirt_t = list("White Shirt", "White Tank top", "Black shirt", "Black Tank top", "Grey Shirt", "Grey tank top", "Lover Shirt", "Blue Ian Shirt", "UK Shirt","I Love NT Shirt", "Peace Shirt", "Band Shirt", "PogoMan Shirt", "Matroska Shirt", "White Short-sleeved shirt", "Purple Short-sleeved shirt", "Blue Short-sleeved shirt", "Green Short-sleeved shirt", "Black Short-Sleeved shirt", "Blue T-Shirt", "Red T-Shirt", "Yellow T-Shirt", "Green T-Shirt", "Blue Polo Shirt", "Red Polo Shirt", "White Polo Shirt", "Gray-Yellow Polo Shirt", "Green Sports Shirt", "Red Sports Shirt", "Blue Sports Shirt", "SS13 Shirt", "Fire Tank Top", "Question Shirt", "Skull Shirt", "Commie Shirt", "Nanotrasen Shirt", "Striped Shirt", "Blue Shirt", "Red Shirt", "Green Shirt", "Meat Shirt", "Tie-Dye Shirt", "Red Jersey", "Blue Jersey", "None")
-var/global/list/undershirt_list = undershirt_t
+var/global/list/underwear_list = list() //stores /datum/sprite_accessory/underwear indexed by name
+var/global/list/underwear_m = list() //stores only underwear name
+var/global/list/underwear_f = list() //stores only underwear name
+ //Undershirts
+var/global/list/undershirt_list = list() //stores /datum/sprite_accessory/undershirt indexed by name
+var/global/list/undershirt_m = list() //stores only undershirt name
+var/global/list/undershirt_f = list() //stores only undershirt name
//Backpacks
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt")
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index b2ddadd7404..9d2e9fc5c89 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -8,6 +8,7 @@ var/global/list/whitelisted_species = list()
var/list/clients = list() //list of all clients
var/list/admins = list() //list of all clients whom are admins
+var/list/deadmins = list() //list of all clients who have used the de-admin verb.
var/list/directory = list() //list of all ckeys with associated client
//Since it didn't really belong in any other category, I'm putting this here
diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm
index cd38e6e34d8..00a878bf27f 100644
--- a/code/_globalvars/misc.dm
+++ b/code/_globalvars/misc.dm
@@ -64,4 +64,6 @@ var/score_dmgestjob = null
var/score_dmgestdamage = 0
var/score_dmgestkey = null
-var/TAB = " "
\ No newline at end of file
+var/TAB = " "
+
+var/timezoneOffset = 0 // The difference betwen midnight (of the host computer) and 0 world.ticks.
\ No newline at end of file
diff --git a/code/_hooks/hooks.dm b/code/_hooks/hooks.dm
index 07f4bfd0618..b78526bfc2b 100644
--- a/code/_hooks/hooks.dm
+++ b/code/_hooks/hooks.dm
@@ -32,21 +32,21 @@ var/global/list/hooks = list()
for (var/hook_path in typesof(/hook))
var/hook/hook = new hook_path
hooks[hook.name] = hook
-// world.log << "Found hook: " + hook.name
+// log_to_dd("Found hook: " + hook.name)
for (var/hook_path in typesof(/hook_handler))
var/hook_handler/hook_handler = new hook_path
for (var/name in hooks)
if (hascall(hook_handler, "On" + name))
var/hook/hook = hooks[name]
hook.handlers += hook_handler
-// world.log << "Found hook handler for: " + name
+// log_to_dd("Found hook handler for: " + name)
for (var/hook/hook in hooks)
hook.Setup()
/proc/CallHook(var/name as text, var/list/args)
var/hook/hook = hooks[name]
if (!hook)
- //world.log << "WARNING: Hook with name " + name + " does not exist"
+ //log_to_dd("WARNING: Hook with name " + name + " does not exist")
return
if (hook.Called(args))
return
diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm
index 9c586c3873e..745f747684f 100644
--- a/code/_onclick/hud/robot.dm
+++ b/code/_onclick/hud/robot.dm
@@ -191,6 +191,8 @@
var/mob/living/silicon/robot/r = mymob
+ if(!r.client) return
+
if(r.shown_robot_modules)
//Modules display is shown
r.client.screen += r.throw_icon //"store" icon
diff --git a/code/controllers/ProcessScheduler/core/process.dm b/code/controllers/ProcessScheduler/core/process.dm
index c09b5730b69..eb6350a73b6 100644
--- a/code/controllers/ProcessScheduler/core/process.dm
+++ b/code/controllers/ProcessScheduler/core/process.dm
@@ -360,9 +360,9 @@
if(istype(thrower, /atom))
var/atom/A = thrower
ptext += " ([A]) ([A.x],[A.y],[A.z])"
- world.log << "\[[time_stamp()]\] Process [name] caught exception[ptext]: [etext]"
+ log_to_dd("\[[time_stamp()]\] Process [name] caught exception[ptext]: [etext]")
if(exceptions[eid] >= 10)
- world.log << "This exception will now be ignored for ten minutes."
+ log_to_dd("This exception will now be ignored for ten minutes.")
spawn(6000)
exceptions[eid] = 0
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index c727a275a0b..a958c3b4eec 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -17,6 +17,7 @@
var/log_adminchat = 0 // log admin chat messages
var/log_adminwarn = 0 // log warnings admins get about bomb construction and such
var/log_pda = 0 // log pda messages
+ var/log_world_output = 0 // log world.log << messages
var/log_runtimes = 0 // Logs all runtimes.
var/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits
var/log_runtime = 0 // logs world.log to a file
@@ -159,7 +160,7 @@
var/allow_holidays = 0
var/player_overflow_cap = 0 //number of players before the server starts rerouting
var/list/overflow_whitelist = list() //whitelist for overflow
-
+
var/disable_away_missions = 0 // disable away missions
/datum/configuration/New()
@@ -267,6 +268,9 @@
if ("log_pda")
config.log_pda = 1
+ if ("log_world_output")
+ config.log_world_output = 1
+
if ("log_hrefs")
config.log_hrefs = 1
@@ -518,7 +522,7 @@
if("overflow_server_url")
config.overflow_server_url = value
-
+
if("disable_away_missions")
config.disable_away_missions = 1
@@ -630,6 +634,8 @@
sqlfdbklogin = value
if ("feedback_password")
sqlfdbkpass = value
+ if("feedback_tableprefix")
+ sqlfdbktableprefix = value
if ("enable_stat_tracking")
sqllogging = 1
else
diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm
index 4194567ae10..7bdbb664724 100644
--- a/code/controllers/emergency_shuttle_controller.dm
+++ b/code/controllers/emergency_shuttle_controller.dm
@@ -70,8 +70,9 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
wait_for_launch = 0
//calls the shuttle for an emergency evacuation
-/datum/emergency_shuttle_controller/proc/call_evac()
- if(!can_call()) return 0
+/datum/emergency_shuttle_controller/proc/call_evac(var/reason)
+ if(!can_call())
+ return 0
//set the launch timer
autopilot = 1
@@ -82,7 +83,10 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
shuttle.move_time = SHUTTLE_TRANSIT_DURATION
evac = 1
- emergency_shuttle_called.Announce("An emergency evacuation shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.")
+ var/emergencytext = "An emergency evacuation shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes."
+ if(reason)
+ emergencytext += "\n\nReason: [reason]"
+ emergency_shuttle_called.Announce(emergencytext)
for(var/area/A in world)
if(istype(A, /area/hallway))
A.readyalert()
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 48cc625ab47..0553e65edfb 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -274,7 +274,7 @@ client
body += ""
body += ""
body += ""
- body += ""
+ body += ""
body += ""
body += ""
if(isobj(D))
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 864a0f0d6b0..8f74d67cc62 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -71,7 +71,7 @@ datum/mind
proc/transfer_to(mob/living/new_character)
if(!istype(new_character))
- world.log << "## DEBUG: transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn"
+ log_to_dd("## DEBUG: transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn")
if(current) //remove ourself from our old body's mind variable
current.mind = null
@@ -142,7 +142,7 @@ datum/mind
var/mob/living/carbon/human/H = current
if (istype(current, /mob/living/carbon/human))
/** Impanted**/
- if(H.is_loyalty_implanted(H))
+ if(H.is_loyalty_implanted())
text = "Loyalty Implant:Remove|Implanted"
else
text = "Loyalty Implant:No Implant|Implant him!"
@@ -152,7 +152,7 @@ datum/mind
if (ticker.mode.config_tag=="revolution")
text += uppertext(text)
text = "[text]: "
- if (H.is_loyalty_implanted(H))
+ if (H.is_loyalty_implanted())
text += "LOYAL EMPLOYEE|headrev|rev"
else if (src in ticker.mode.head_revolutionaries)
text = "employee|HEADREV|rev"
@@ -188,7 +188,7 @@ datum/mind
if (ticker.mode.config_tag=="cult")
text = uppertext(text)
text = "[text]: "
- if (H.is_loyalty_implanted(H))
+ if (H.is_loyalty_implanted())
text += "LOYAL EMPLOYEE|cultist"
else if (src in ticker.mode.cult)
text += "employee|CULTIST"
@@ -302,7 +302,7 @@ datum/mind
if (ticker.mode.config_tag=="traitor" || ticker.mode.config_tag=="traitorchan")
text = uppertext(text)
text = "[text]: "
- if (H.is_loyalty_implanted(H))
+ if (H.is_loyalty_implanted())
text +="traitor|LOYAL EMPLOYEE"
else
if (src in ticker.mode.traitors)
diff --git a/code/defines/procs/statistics.dm b/code/defines/procs/statistics.dm
index 91d065e5279..52c0af1af82 100644
--- a/code/defines/procs/statistics.dm
+++ b/code/defines/procs/statistics.dm
@@ -140,7 +140,7 @@ proc/sql_commit_feedback()
log_game("SQL ERROR during feedback reporting. Failed to connect.")
else
- var/DBQuery/max_query = dbcon.NewQuery("SELECT MAX(roundid) AS max_round_id FROM erro_feedback")
+ var/DBQuery/max_query = dbcon.NewQuery("SELECT MAX(roundid) AS max_round_id FROM [format_table_name("feedback")]")
max_query.Execute()
var/newroundid
@@ -160,7 +160,7 @@ proc/sql_commit_feedback()
var/variable = item.get_variable()
var/value = item.get_value()
- var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_feedback (id, roundid, time, variable, value) VALUES (null, [newroundid], Now(), '[variable]', '[value]')")
+ var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("feedback")] (id, roundid, time, variable, value) VALUES (null, [newroundid], Now(), '[variable]', '[value]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
\ No newline at end of file
diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm
index 4fa3a5358cd..88ff95833ad 100644
--- a/code/game/asteroid.dm
+++ b/code/game/asteroid.dm
@@ -203,6 +203,6 @@ var/global/max_secret_rooms = 6
new garbage(T)
areapoints -= 5
emptyturfs -= T
- //world.log << "The [theme] themed [T.loc] has been created!"
+ //log_to_dd("The [theme] themed [T.loc] has been created!")
return 1
\ No newline at end of file
diff --git a/code/game/dna/dna.dm b/code/game/dna/dna.dm
index 2835a1614ed..716d563a6e7 100644
--- a/code/game/dna/dna.dm
+++ b/code/game/dna/dna.dm
@@ -74,7 +74,7 @@
//Hair
var/hair = 0
if(!character.h_style)
- character.h_style = "Bald"
+ character.h_style = random_hair_style(character.gender)
var/hrange = round(4095 / hair_styles_list.len)
var/index = hair_styles_list.Find(character.h_style)
@@ -84,7 +84,7 @@
//Facial Hair
var/beard = 0
if(!character.f_style)
- character.f_style = "Shaved"
+ character.f_style = random_facial_hair_style(character.gender)
var/f_hrange = round(4095 / facial_hair_styles_list.len)
index = facial_hair_styles_list.Find(character.f_style)
diff --git a/code/game/dna/genes/goon_disabilities.dm b/code/game/dna/genes/goon_disabilities.dm
index db34ccbdbbb..7ea73a79ddd 100644
--- a/code/game/dna/genes/goon_disabilities.dm
+++ b/code/game/dna/genes/goon_disabilities.dm
@@ -335,8 +335,8 @@
var/mob/living/carbon/L = usr
if(L)
- usr.attack_log += text("\[[time_stamp()]\] [usr.real_name] ([usr.ckey]) cast the spell [name] on [L.real_name] ([L.ckey]).")
- msg_admin_attack("[usr.real_name] ([usr.ckey])[isAntag(usr) ? "(ANTAG)" : ""] has cast the spell [name] on [L.real_name] ([L.ckey]) (JMP)")
+ usr.attack_log += text("\[[time_stamp()]\] [key_name(usr)] cast the spell [name] on [key_name(L)]")
+ msg_admin_attack("[key_name_admin(usr)] has cast the spell [name] on [key_name_admin(L)]")
L.adjust_fire_stacks(0.5)
L.visible_message("\red [L.name] suddenly bursts into flames!")
diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm
index 452a8cd6c8d..06a16390fa7 100644
--- a/code/game/dna/genes/goon_powers.dm
+++ b/code/game/dna/genes/goon_powers.dm
@@ -169,13 +169,13 @@
if(H.internal)
H.visible_message("\red [usr] sprays a cloud of fine ice crystals, engulfing [H]!",
"[usr] sprays a cloud of fine ice crystals over your [H.head]'s visor.")
- log_admin("[ckey(usr.key)] has used cryokinesis on [ckey(C.key)], internals yes, suit yes")
- msg_admin_attack("[usr.real_name] ([usr.ckey])[isAntag(usr) ? "(ANTAG)" : ""] has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)")
+ log_admin("[key_name(usr)] has used cryokinesis on [key_name(C)] while wearing internals and a suit")
+ msg_admin_attack("[key_name_admin(usr)] has cast cryokinesis on [key_name_admin(C)]")
else
H.visible_message("\red [usr] sprays a cloud of fine ice crystals engulfing, [H]!",
"[usr] sprays a cloud of fine ice crystals cover your [H.head]'s visor and make it into your air vents!.")
- log_admin("[usr.real_name] ([ckey(usr.key)]) has used cryokinesis on [C.real_name] ([ckey(C.key)]), ()")
- msg_admin_attack("[usr.real_name] ([usr.ckey])[isAntag(usr) ? "(ANTAG)" : ""] has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)")
+ log_admin("[key_name(usr)] has used cryokinesis on [key_name(C)]")
+ msg_admin_attack("[key_name_admin(usr)] has cast cryokinesis on [key_name_admin(C)]")
H.bodytemperature = max(0, H.bodytemperature - 50)
H.adjustFireLoss(5)
if(!handle_suit)
@@ -184,8 +184,8 @@
C.ExtinguishMob()
C.visible_message("\red [usr] sprays a cloud of fine ice crystals, engulfing [C]!")
- log_admin("[ckey(usr.key)] has used cryokinesis on [ckey(C.key)], internals no, suit no")
- msg_admin_attack("[usr.real_name] ([usr.ckey])[isAntag(usr) ? "(ANTAG)" : ""] has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)")
+ log_admin("[key_name(usr)] has used cryokinesis on [key_name(C)] without internals or a suit")
+ msg_admin_attack("[key_name_admin(usr)] has cast cryokinesis on [key_name_admin(C)]")
//playsound(usr.loc, 'bamf.ogg', 50, 0)
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 93f2c468aa6..50819be8c1d 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -16,6 +16,8 @@
return 0
if(iscultist(mind.current))
return 1 //If they're already in the cult, assume they are convertable
+ if(jobban_isbanned(mind.current, "cultist") || jobban_isbanned(mind.current, "Syndicate"))
+ return 0
if(ishuman(mind.current) && (mind.assigned_role in list("Captain", "Chaplain")))
return 0
if(ishuman(mind.current))
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 98451fe2ee7..f58a93b931f 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -330,9 +330,9 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
attack(mob/living/M as mob, mob/living/user as mob)
- M.attack_log += text("\[[time_stamp()]\] Has had the [name] used on him by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used [name] on [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] used [name] on [M.name] ([M.ckey]) (JMP)")
+ M.attack_log += text("\[[time_stamp()]\] Has had the [name] used on him by [key_name(user)]")
+ user.attack_log += text("\[[time_stamp()]\] Used [name] on [key_name(M)]")
+ msg_admin_attack("[key_name_admin(user)] used [name] on [key_name_admin(M)]")
if(!iscarbon(M))
M.LAssailant = null
else
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index d6343e88142..c42c9cec293 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -111,7 +111,7 @@ var/list/sacrificed = list()
"\red AAAAAAHHHH!.", \
"\red You hear an anguished scream.")
cult_log("[key_name_admin(usr)] tried to convert [key_name_admin(M)]")
- if(is_convertable_to_cult(M.mind) && !jobban_isbanned(M, "cultist") && !jobban_isbanned(M,"Syndicate"))//putting jobban check here because is_convertable uses mind as argument
+ if(is_convertable_to_cult(M.mind))
ticker.mode.add_cultist(M.mind)
M.mind.special_role = "Cultist"
M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root."
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index c72cf729bee..87d8e4e083c 100644
--- a/code/game/gamemodes/events.dm
+++ b/code/game/gamemodes/events.dm
@@ -96,7 +96,7 @@
sleep(150)
command_announcement.Announce("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")
else
- world.log << "ERROR: Could not initate grey-tide virus. Unable find prison or brig area."
+ log_to_dd("ERROR: Could not initate grey-tide virus. Unable find prison or brig area.")
/proc/carp_migration() // -- Darem
for(var/obj/effect/landmark/C in landmarks_list)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index fb2168181e3..7438d5c7978 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -129,17 +129,12 @@
msg += "You have been sent the $[pay], as agreed."
else
msg += "However, we were unable to send you the $[pay] you're entitled."
- if(useMS)
+ if(useMS && P)
// THIS SHOULD HAVE DONE EVERYTHING FOR ME
useMS.send_pda_message("[P.owner]", "[command_name()] Payroll", msg)
// BUT NOPE, NEED TO DO THIS BULLSHIT.
- P.tnote += "← From [command_name()] (Payroll):
[msg]
"
-
- if (!P.silent)
- playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1)
- for (var/mob/O in hearers(3, P.loc))
- if(!P.silent) O.show_message(text("\icon[P] *[P.ttone]*"))
+ P.play_ringtone()
//Search for holder of the PDA.
var/mob/living/L = null
if(P.loc && isliving(P.loc))
@@ -562,4 +557,11 @@ proc/get_nt_opposed()
if(BE_ALIEN) roletext="alien"
if(BE_MUTINEER) roletext="mutineer"
if(BE_BLOB) roletext="blob"
- return roletext
\ No newline at end of file
+ return roletext
+
+/proc/get_nuke_code()
+ var/nukecode = "ERROR"
+ for(var/obj/machinery/nuclearbomb/bomb in world)
+ if(bomb && bomb.r_code && bomb.z == ZLEVEL_STATION)
+ nukecode = bomb.r_code
+ return nukecode
\ No newline at end of file
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
index 164ff065758..5f4d14740a2 100644
--- a/code/game/gamemodes/heist/heist.dm
+++ b/code/game/gamemodes/heist/heist.dm
@@ -261,7 +261,7 @@ datum/game_mode/proc/auto_declare_completion_heist()
text += "
[vox.key] was [vox.name] ("
if(check_return)
var/obj/stack = raiders[vox]
- if(get_area(stack) != locate(/area/shuttle/vox/station))
+ if(get_area(stack.loc) != locate(/area/shuttle/vox/station))
text += "left behind)"
continue
if(vox.current)
diff --git a/code/game/gamemodes/mutiny/mutiny.dm b/code/game/gamemodes/mutiny/mutiny.dm
index 150ff09f5fe..ad4513e6709 100644
--- a/code/game/gamemodes/mutiny/mutiny.dm
+++ b/code/game/gamemodes/mutiny/mutiny.dm
@@ -105,10 +105,7 @@ datum/game_mode/mutiny
if (!pda)
return 0
- if (!pda.silent)
- playsound(pda.loc, 'sound/machines/twobeep.ogg', 50, 1)
- for (var/mob/O in hearers(3, pda.loc))
- O.show_message(text("\icon[pda] *[pda.ttone]*"))
+ pda.play_ringtone()
head_mutineer.current << fluff.get_pda_body()
return 1
diff --git a/code/game/gamemodes/mutiny/mutiny_hooks.dm b/code/game/gamemodes/mutiny/mutiny_hooks.dm
index 14766e520ec..f87ab7c1919 100644
--- a/code/game/gamemodes/mutiny/mutiny_hooks.dm
+++ b/code/game/gamemodes/mutiny/mutiny_hooks.dm
@@ -12,7 +12,7 @@
mode.update_icon(H.mind)
return 1
-/hook/harvest_podman/proc/update_icon(mob/living/carbon/primitive/diona/D)
+/hook/harvest_podman/proc/update_icon(mob/living/simple_animal/diona/D)
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if (!mode) return 1
diff --git a/code/game/gamemodes/nations/nations.dm b/code/game/gamemodes/nations/nations.dm
index 52df698a96f..f0cc2f28cbe 100644
--- a/code/game/gamemodes/nations/nations.dm
+++ b/code/game/gamemodes/nations/nations.dm
@@ -293,8 +293,7 @@ datum/game_mode/nations
else
new_character.gender = pick(MALE,FEMALE)
var/datum/preferences/A = new()
- A.randomize_appearance_for(new_character)
- new_character.real_name = real_name
+ A.copy_to(new_character)
if(!new_character.real_name)
if(new_character.gender == MALE)
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index e9752e1e65b..faf3f353c16 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -10,7 +10,7 @@ var/bomb_set
var/extended = 0.0
var/lighthack = 0
var/opened = 0.0
- var/timeleft = 60.0
+ var/timeleft = 120.0
var/timing = 0.0
var/r_code = "ADMIN"
var/code = ""
@@ -51,12 +51,11 @@ var/bomb_set
/obj/machinery/nuclearbomb/process()
if (src.timing)
bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed.
- src.timeleft--
- if (src.timeleft <= 0)
- explode()
- for(var/mob/M in viewers(1, src))
- if ((M.client && M.machine == src))
- nanomanager.update_uis(src)
+ timeleft = max(timeleft - 2, 0) // 2 seconds per process()
+ if (timeleft <= 0)
+ spawn
+ explode()
+ nanomanager.update_uis(src)
return
/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob, params)
@@ -163,13 +162,13 @@ var/bomb_set
return
..()
-
+/obj/machinery/nuclearbomb/attack_ghost(mob/user as mob)
+ ui_interact(user)
+
/obj/machinery/nuclearbomb/attack_hand(mob/user as mob)
if (src.extended)
if (src.opened)
- nukehack_win(user,50)
- user.set_machine(src)
- ui_interact(user)
+ ui_interact(user)
else if (src.deployable)
if(removal_stage < 5)
src.anchored = 1
@@ -182,9 +181,6 @@ var/bomb_set
src.extended = 1
return
-obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob)
- ui_interact(user)
-
/obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
var/uiwidth
@@ -193,8 +189,8 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob)
data["is_syndicate"] = is_syndicate
if(!src.opened)
data["hacking"] = 0
- data["auth"] = src.auth
- if (src.auth)
+ data["auth"] = is_auth(user)
+ if (is_auth(user))
if (src.yes_code)
data["authstatus"] = src.timing ? "Functional/Set" : "Functional"
else
@@ -211,7 +207,7 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob)
data["anchored"] = src.anchored
data["yescode"] = src.yes_code
data["message"] = "AUTH"
- if (src.auth)
+ if (is_auth(user))
data["message"] = src.code
if (src.yes_code)
data["message"] = "*****"
@@ -230,11 +226,13 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob)
uiwidth = 420
uiheight = 440
uititle = "Nuclear Bomb Defusion"
+
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "nuclear_bomb.tmpl", uititle, uiwidth, uiheight)
ui.set_initial_data(data)
ui.open()
+ ui.set_auto_update(1)
/obj/machinery/nuclearbomb/verb/make_deployable()
set category = "Object"
@@ -252,137 +250,139 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob)
src.deployable = 1
return
+/obj/machinery/nuclearbomb/proc/is_auth(user as mob)
+ if(auth)
+ return 1
+ if(isobserver(user) && check_rights(R_ADMIN, 0, user))
+ return 1
+ else
+ return 0
+
/obj/machinery/nuclearbomb/Topic(href, href_list)
if(..())
- return
- if (!usr.canmove || usr.stat || usr.restrained())
- return
- if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
- usr.set_machine(src)
- if(href_list["act"])
- var/temp_wire = href_list["wire"]
- if(href_list["act"] == "pulse")
- if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
- usr << "You need a multitool!"
+ return 1
+
+ if(href_list["act"])
+ var/temp_wire = href_list["wire"]
+ if(href_list["act"] == "pulse")
+ if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
+ usr << "You need a multitool!"
+ else
+ if(src.wires[temp_wire])
+ usr << "You can't pulse a cut wire."
else
- if(src.wires[temp_wire])
- usr << "You can't pulse a cut wire."
- else
- if(src.light_wire == temp_wire)
- src.lighthack = !src.lighthack
- spawn(100) src.lighthack = !src.lighthack
- if(src.timing_wire == temp_wire)
- if(src.timing)
- explode()
- if(src.safety_wire == temp_wire)
- src.safety = !src.safety
- spawn(100) src.safety = !src.safety
- if(src.safety == 1)
- visible_message("\blue The [src] quiets down.")
- if(!src.lighthack)
- if (src.icon_state == "nuclearbomb2")
- src.icon_state = "nuclearbomb1"
- else
- visible_message("\blue The [src] emits a quiet whirling noise!")
- if(href_list["act"] == "wire")
- if (!istype(usr.get_active_hand(), /obj/item/weapon/wirecutters))
- usr << "You need wirecutters!"
- else
- wires[temp_wire] = !wires[temp_wire]
- if(src.safety_wire == temp_wire)
- if(src.timing)
- explode()
- if(src.timing_wire == temp_wire)
- if(!src.lighthack)
- if (src.icon_state == "nuclearbomb2")
- src.icon_state = "nuclearbomb1"
- src.timing = 0
- bomb_set = 0
if(src.light_wire == temp_wire)
src.lighthack = !src.lighthack
-
- if (href_list["auth"])
- if (src.auth)
- src.auth.loc = src.loc
- src.yes_code = 0
- src.auth = null
+ spawn(100) src.lighthack = !src.lighthack
+ if(src.timing_wire == temp_wire)
+ if(src.timing)
+ spawn
+ explode()
+ if(src.safety_wire == temp_wire)
+ src.safety = !src.safety
+ spawn(100) src.safety = !src.safety
+ if(src.safety == 1)
+ visible_message("\blue The [src] quiets down.")
+ if(!src.lighthack)
+ if (src.icon_state == "nuclearbomb2")
+ src.icon_state = "nuclearbomb1"
+ else
+ visible_message("\blue The [src] emits a quiet whirling noise!")
+ if(href_list["act"] == "wire")
+ if (!istype(usr.get_active_hand(), /obj/item/weapon/wirecutters))
+ usr << "You need wirecutters!"
else
- var/obj/item/I = usr.get_active_hand()
- if (istype(I, /obj/item/weapon/disk/nuclear))
- usr.drop_item()
- I.loc = src
- src.auth = I
- if (src.auth)
- if (href_list["type"])
- if (href_list["type"] == "E")
- if (src.code == src.r_code)
- src.yes_code = 1
- src.code = null
- else
- src.code = "ERROR"
- else
- if (href_list["type"] == "R")
- src.yes_code = 0
- src.code = null
- else
- lastentered = text("[]", href_list["type"])
- if (text2num(lastentered) == null)
- var/turf/LOC = get_turf(usr)
- message_admins("[key_name_admin(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]! ([LOC ? "JMP" : "null"])", 0)
- log_admin("EXPLOIT: [key_name(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]!")
- else
- src.code += lastentered
- if (length(src.code) > 5)
- src.code = "ERROR"
- if (src.yes_code)
- if (href_list["time"])
- var/time = text2num(href_list["time"])
- src.timeleft += time
- src.timeleft = min(max(round(src.timeleft), 60), 600)
- if (href_list["timer"])
- if (src.timing == -1.0)
- return
- if (src.safety)
- usr << "\red The safety is still on."
- nanomanager.update_uis(src)
- return
- src.timing = !( src.timing )
- if (src.timing)
- if(!src.lighthack)
- src.icon_state = "nuclearbomb2"
- if(!src.safety)
- bomb_set = 1//There can still be issues with this reseting when there are multiple bombs. Not a big deal tho for Nuke/N
- else
- bomb_set = 0
- else
- bomb_set = 0
- if(!src.lighthack)
+ wires[temp_wire] = !wires[temp_wire]
+ if(src.safety_wire == temp_wire)
+ if(src.timing)
+ spawn
+ explode()
+ if(src.timing_wire == temp_wire)
+ if(!src.lighthack)
+ if (src.icon_state == "nuclearbomb2")
src.icon_state = "nuclearbomb1"
- if (href_list["safety"])
- src.safety = !( src.safety )
- if(safety)
- src.timing = 0
- bomb_set = 0
- if (href_list["anchor"])
- if(removal_stage == 5)
- src.anchored = 0
- visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
- return
+ src.timing = 0
+ bomb_set = 0
+ if(src.light_wire == temp_wire)
+ src.lighthack = !src.lighthack
- src.anchored = !( src.anchored )
- if(src.anchored)
- visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.")
+ if (href_list["auth"])
+ if (src.auth)
+ src.auth.loc = src.loc
+ src.yes_code = 0
+ src.auth = null
+ else
+ var/obj/item/I = usr.get_active_hand()
+ if (istype(I, /obj/item/weapon/disk/nuclear))
+ usr.drop_item()
+ I.loc = src
+ src.auth = I
+ if (is_auth(usr))
+ if (href_list["type"])
+ if (href_list["type"] == "E")
+ if (src.code == src.r_code)
+ src.yes_code = 1
+ src.code = null
+ else
+ src.code = "ERROR"
+ else
+ if (href_list["type"] == "R")
+ src.yes_code = 0
+ src.code = null
+ else
+ lastentered = text("[]", href_list["type"])
+ if (text2num(lastentered) == null)
+ var/turf/LOC = get_turf(usr)
+ message_admins("[key_name_admin(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]! ([LOC ? "JMP" : "null"])", 0)
+ log_admin("EXPLOIT: [key_name(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]!")
else
- visible_message("\red The anchoring bolts slide back into the depths of [src].")
+ src.code += lastentered
+ if (length(src.code) > 5)
+ src.code = "ERROR"
+ if (src.yes_code)
+ if (href_list["time"])
+ var/time = text2num(href_list["time"])
+ src.timeleft += time
+ src.timeleft = min(max(round(src.timeleft), 120), 600)
+ if (href_list["timer"])
+ if (src.timing == -1.0)
+ nanomanager.update_uis(src)
+ return
+ if (src.safety)
+ usr << "\red The safety is still on."
+ nanomanager.update_uis(src)
+ return
+ src.timing = !( src.timing )
+ if (src.timing)
+ if(!src.lighthack)
+ src.icon_state = "nuclearbomb2"
+ if(!src.safety)
+ bomb_set = 1//There can still be issues with this reseting when there are multiple bombs. Not a big deal tho for Nuke/N
+ else
+ bomb_set = 0
+ else
+ bomb_set = 0
+ if(!src.lighthack)
+ src.icon_state = "nuclearbomb1"
+ if (href_list["safety"])
+ src.safety = !( src.safety )
+ if(safety)
+ src.timing = 0
+ bomb_set = 0
+ if (href_list["anchor"])
+ if(removal_stage == 5)
+ src.anchored = 0
+ visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
+ nanomanager.update_uis(src)
+ return
- src.add_fingerprint(usr)
- for(var/mob/M in viewers(1, src))
- if ((M.client && M.machine == src))
- nanomanager.update_uis(src)
- else
- return
- return
+ src.anchored = !( src.anchored )
+ if(src.anchored)
+ visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.")
+ else
+ visible_message("\red The anchoring bolts slide back into the depths of [src].")
+ nanomanager.update_uis(src)
/obj/machinery/nuclearbomb/ex_act(severity)
return
@@ -394,7 +394,6 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob)
return ..()
return
-
#define NUKERANGE 80
/obj/machinery/nuclearbomb/proc/explode()
if (src.safety)
@@ -479,8 +478,8 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob)
var/obj/item/weapon/disk/nuclear/NEWDISK = new(pick(blobstart))
transfer_fingerprints_to(NEWDISK)
var/turf/diskturf = get_turf(src)
- message_admins("[src] has been destroyed in ([diskturf.x], [diskturf.y] ,[diskturf.z] - JMP). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z] - JMP).")
- log_game("[src] has been destroyed in ([diskturf.x], [diskturf.y] ,[diskturf.z]). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z]).")
+ message_admins("[src] has been destroyed at ([diskturf.x], [diskturf.y], [diskturf.z] - JMP). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z] - JMP).")
+ log_game("[src] has been destroyed in ([diskturf.x], [diskturf.y], [diskturf.z]). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z]).")
return QDEL_HINT_HARDDEL_NOW
else
error("[src] was supposed to be destroyed, but we were unable to locate a blobstart landmark to spawn a new one.")
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index 591d5f8f5ba..099a8e61bad 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -250,7 +250,7 @@
if(beingborged)
rev_mind.current << "\red The frame's firmware detects and deletes your neural reprogramming! You remember nothing from the moment you were flashed until now."
-
+ message_admins("[key_name_admin(rev_mind.current)] has been borged while being a member of the revolution.")
else
rev_mind.current << "\red You have been brainwashed! You are no longer a revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you..."
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index ae4e41babed..11dbb239be3 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -374,15 +374,15 @@
if(t_mind.current.client)
for(var/image/I in t_mind.current.client.images)
if((I.icon_state == "greytide" || I.icon_state == "greytide_head") && I.loc == traitor_mind.current)
- //world.log << "deleting [traitor_mind] overlay"
+ //log_to_dd("deleting [traitor_mind] overlay")
qdel(I)
if(head)
- //world.log << "found [head.name]"
+ //log_to_dd("found [head.name]")
if(head.current)
if(head.current.client)
for(var/image/I in head.current.client.images)
if((I.icon_state == "greytide" || I.icon_state == "greytide_head") && I.loc == traitor_mind.current)
- //world.log << "deleting [traitor_mind] overlay"
+ //log_to_dd("deleting [traitor_mind] overlay")
qdel(I)
if(traitor_mind.current)
if(traitor_mind.current.client)
diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm
index 921f50dce9d..13507d847cb 100644
--- a/code/game/gamemodes/vampire/vampire.dm
+++ b/code/game/gamemodes/vampire/vampire.dm
@@ -416,15 +416,15 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
if(t_mind.current.client)
for(var/image/I in t_mind.current.client.images)
if((I.icon_state == "vampthrall" || I.icon_state == "vampire") && I.loc == vampire_mind.current)
- //world.log << "deleting [vampire_mind] overlay"
+ //log_to_dd("deleting [vampire_mind] overlay")
qdel(I)
if(head)
- //world.log << "found [head.name]"
+ //log_to_dd("found [head.name]")
if(head.current)
if(head.current.client)
for(var/image/I in head.current.client.images)
if((I.icon_state == "vampthrall" || I.icon_state == "vampire") && I.loc == vampire_mind.current)
- //world.log << "deleting [vampire_mind] overlay"
+ //log_to_dd("deleting [vampire_mind] overlay")
qdel(I)
if(vampire_mind.current)
if(vampire_mind.current.client)
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index eff70300720..b25aa1b6ae8 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -11,7 +11,7 @@
var/datum/vampire/vampire = src.mind.vampire
if(!vampire)
- world.log << "[src] has vampire verbs but isn't a vampire."
+ log_to_dd("[src] has vampire verbs but isn't a vampire.")
return 0
var/fullpower = (VAMP_FULL in vampire.powers)
@@ -198,7 +198,8 @@
if(M.current.vampire_power(50, 0))
M.current.visible_message("[M.current.name] transforms!")
M.current.client.prefs.real_name = M.current.generate_name() //random_name(M.current.gender)
- M.current.client.prefs.randomize_appearance_for(M.current)
+ M.current.client.prefs.random_character()
+ M.current.client.prefs.copy_to(M.current)
M.current.regenerate_icons()
M.current.remove_vampire_blood(50)
M.current.verbs -= /client/vampire/proc/vampire_shapeshift
@@ -300,7 +301,7 @@
enthrall_safe = 1
break
if(!C)
- world.log << "something bad happened on enthralling a mob src is [src] [src.key] \ref[src]"
+ log_to_dd("something bad happened on enthralling a mob src is [src] [src.key] \ref[src]")
return 0
if(!C.mind)
src << "\red [C.name]'s mind is not there for you to enthrall."
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 148a4b41a25..6ccb27d2c2b 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -65,17 +65,11 @@
/datum/game_mode/proc/forge_wizard_objectives(var/datum/mind/wizard)
switch(rand(1,100))
if(1 to 30)
-
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = wizard
kill_objective.find_target()
wizard.objectives += kill_objective
-
- if (!(locate(/datum/objective/escape) in wizard.objectives))
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = wizard
- wizard.objectives += escape_objective
- if(31 to 60)
+
var/datum/objective/steal/steal_objective = new
steal_objective.owner = wizard
steal_objective.find_target()
@@ -85,8 +79,7 @@
var/datum/objective/escape/escape_objective = new
escape_objective.owner = wizard
wizard.objectives += escape_objective
-
- if(61 to 85)
+ if(31 to 60)
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = wizard
kill_objective.find_target()
@@ -102,7 +95,23 @@
survive_objective.owner = wizard
wizard.objectives += survive_objective
+ if(61 to 85)
+ var/datum/objective/assassinate/kill_objective = new
+ kill_objective.owner = wizard
+ kill_objective.find_target()
+ wizard.objectives += kill_objective
+
+ if (!(locate(/datum/objective/hijack) in wizard.objectives))
+ var/datum/objective/hijack/hijack_objective = new
+ hijack_objective.owner = wizard
+ wizard.objectives += hijack_objective
+
else
+ var/datum/objective/steal/steal_objective = new
+ steal_objective.owner = wizard
+ steal_objective.find_target()
+ wizard.objectives += steal_objective
+
if (!(locate(/datum/objective/hijack) in wizard.objectives))
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = wizard
@@ -302,4 +311,4 @@ Made a proc so this is not repeated 14 (or more) times.*/
return 1
/proc/iswizard(mob/living/M as mob)
- return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.wizards)
\ No newline at end of file
+ return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.wizards)
diff --git a/code/game/gamemodes/xenos/xenos.dm b/code/game/gamemodes/xenos/xenos.dm
index 74b4bea15cd..fa6390a1935 100644
--- a/code/game/gamemodes/xenos/xenos.dm
+++ b/code/game/gamemodes/xenos/xenos.dm
@@ -150,13 +150,6 @@
else
return 0
-/datum/game_mode/xenos/proc/get_nuke_code()
- var/nukecode = "ERROR"
- for(var/obj/machinery/nuclearbomb/bomb in world)
- if(bomb && bomb.r_code && bomb.z == ZLEVEL_STATION)
- nukecode = bomb.r_code
- return nukecode
-
/datum/game_mode/xenos/proc/xenos_alive()
var/list/livingxenos = list()
for(var/datum/mind/xeno in xenos)
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 5667a13a40d..b11edd5ae8d 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -695,7 +695,7 @@
data["danger"] = danger
return data
-/obj/machinery/alarm/proc/get_nano_data(mob/user)
+/obj/machinery/alarm/proc/get_nano_data(mob/user, href_list)
var/data[0]
data["name"] = sanitize(name)
data["air"] = ui_air_status()
@@ -705,7 +705,7 @@
// Locked when:
// Not sent from atmos console AND
// Not silicon AND locked.
- data["locked"] = (!(istype(user, /mob/living/silicon)) && locked)
+ data["locked"] = is_locked(user,href_list)
data["rcon"] = rcon_setting
data["target_temp"] = target_temperature - T0C
data["atmos_alarm"] = alarm_area.atmosalm
@@ -805,15 +805,15 @@
return thresholds
/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
- var/list/data = get_nano_data(user)
-
+ var/list/href = state.href_list(user)
var/remote_connection = 0
var/remote_access = 0
- if(state)
- var/list/href = state.href_list(user)
+ if(href)
remote_connection = href["remote_connection"] // Remote connection means we're non-adjacent/connecting from another computer
remote_access = href["remote_access"] // Remote access means we also have the privilege to alter the air alarm.
+ var/list/data = get_nano_data(user, href)
+
data["remote_connection"] = remote_connection
data["remote_access"] = remote_access
@@ -825,13 +825,25 @@
ui.set_auto_update(1)
/obj/machinery/alarm/proc/is_authenticated(mob/user as mob, href_list)
- if(isAI(user) || isrobot(user) || emagged || is_auth_rcon(href_list))
+ if(isobserver(user) && check_rights(R_ADMIN, 0, user))
+ return 1
+ else if(isAI(user) || isrobot(user) || emagged || is_auth_rcon(href_list))
return 1
else
return !locked
+/obj/machinery/alarm/proc/is_locked(mob/user as mob, href_list)
+ if(isobserver(user) && check_rights(R_ADMIN, 0, user))
+ return 0
+ else if(is_auth_rcon(href_list))
+ return 0
+ else if(isAI(user) || isrobot(user))
+ return 0
+ else
+ return locked
+
/obj/machinery/alarm/proc/is_auth_rcon(href_list)
- if(href_list["remote_connection"] && href_list["remote_access"])
+ if(href_list && href_list["remote_connection"] && href_list["remote_access"])
return 1
else
return 0
@@ -840,7 +852,7 @@
if(buildstage != 2)
return STATUS_CLOSE
- if(aidisabled && isAI(user))
+ if(aidisabled && (isAI(user) || isrobot(user)))
user << "AI control for \the [src] interface has been disabled."
return STATUS_CLOSE
diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm
index 27a825e2d5c..702f7512535 100644
--- a/code/game/machinery/atmoalter/canister.dm
+++ b/code/game/machinery/atmoalter/canister.dm
@@ -438,16 +438,26 @@ update_flag
menu = text2num(href_list["mode_target"])
if(href_list["toggle"])
+ var/logmsg
if (valve_open)
if (holding)
- release_log += "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the [holding]
"
+ logmsg = "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the [holding]
"
else
- release_log += "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the air
"
+ logmsg = "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the air
"
else
if (holding)
- release_log += "Valve was opened by [usr] ([usr.ckey]), starting the transfer into the [holding]
"
+ logmsg = "Valve was opened by [usr] ([usr.ckey]), starting the transfer into the [holding]
"
else
- release_log += "Valve was opened by [usr] ([usr.ckey]), starting the transfer into the air
"
+ logmsg = "Valve was opened by [usr] ([usr.ckey]), starting the transfer into the air
"
+ if(air_contents.toxins > 0)
+ message_admins("[key_name_admin(usr)] opened a canister that contains plasma! (JMP)")
+ log_admin("[key_name(usr)] opened a canister that contains plasma at [x], [y], [z]")
+ var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air_contents.trace_gases
+ if(sleeping_agent && (sleeping_agent.moles > 1))
+ message_admins("[key_name_admin(usr)] opened a canister that contains N2O! (JMP)")
+ log_admin("[key_name(usr)] opened a canister that contains N2O at [x], [y], [z]")
+ investigate_log(logmsg, "atmos")
+ release_log += logmsg
valve_open = !valve_open
if (href_list["remove_tank"])
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 5ed58c833ca..c08ae986c6d 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -43,7 +43,7 @@
for(var/obj/machinery/camera/C in cameranet.cameras)
var/list/tempnetwork = C.network&src.network
if(C != src && C.c_tag == src.c_tag && tempnetwork.len)
- world.log << "[src.c_tag] [src.x] [src.y] [src.z] conflicts with [C.c_tag] [C.x] [C.y] [C.z]"
+ log_to_dd("[src.c_tag] [src.x] [src.y] [src.z] conflicts with [C.c_tag] [C.x] [C.y] [C.z]")
*/
..()
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index 62629ca59ec..f8e177a32d8 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -50,8 +50,12 @@ var/time_last_changed_position = 0
/obj/machinery/computer/card/proc/is_centcom()
return istype(src, /obj/machinery/computer/card/centcom)
-/obj/machinery/computer/card/proc/is_authenticated()
- return scan ? check_access(scan) : 0
+/obj/machinery/computer/card/proc/is_authenticated(user as mob)
+ if(isobserver(user) && check_rights(R_ADMIN, 0, user))
+ return 1
+ if(scan)
+ return check_access(scan)
+ return 0
/obj/machinery/computer/card/proc/get_target_rank()
return modify && modify.assignment ? modify.assignment : "Unassigned"
@@ -180,7 +184,7 @@ var/time_last_changed_position = 0
data["target_owner"] = modify && modify.registered_name ? modify.registered_name : "-----"
data["target_rank"] = get_target_rank()
data["scan_name"] = scan ? scan.name : "-----"
- data["authenticated"] = is_authenticated()
+ data["authenticated"] = is_authenticated(user)
data["has_modify"] = !!modify
data["account_number"] = modify ? modify.associated_account_number : null
data["centcom_access"] = is_centcom()
@@ -285,7 +289,7 @@ var/time_last_changed_position = 0
if("access")
if(href_list["allowed"])
- if(is_authenticated())
+ if(is_authenticated(usr))
var/access_type = text2num(href_list["access_target"])
var/access_allowed = text2num(href_list["allowed"])
if(access_type in (is_centcom() ? get_all_centcom_access() : get_all_accesses()))
@@ -295,11 +299,11 @@ var/time_last_changed_position = 0
if("skin")
var/skin = href_list["skin_target"]
- if(is_authenticated() && modify && ((skin in get_station_card_skins()) || ((skin in get_centcom_card_skins()) && is_centcom())))
+ if(is_authenticated(usr) && modify && ((skin in get_station_card_skins()) || ((skin in get_centcom_card_skins()) && is_centcom())))
modify.icon_state = href_list["skin_target"]
if ("assign")
- if (is_authenticated() && modify)
+ if (is_authenticated(usr) && modify)
var/t1 = href_list["assign_target"]
if(t1 == "Custom")
var/temp_t = sanitize(copytext(input("Enter a custom job assignment.","Assignment"),1,MAX_MESSAGE_LEN))
@@ -330,7 +334,7 @@ var/time_last_changed_position = 0
callHook("reassign_employee", list(modify))
if ("reg")
- if (is_authenticated())
+ if (is_authenticated(usr))
var/t2 = modify
if ((modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf)))
var/temp_name = reject_bad_name(href_list["reg"])
@@ -341,7 +345,7 @@ var/time_last_changed_position = 0
nanomanager.update_uis(src)
if ("account")
- if (is_authenticated())
+ if (is_authenticated(usr))
var/t2 = modify
if ((modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf)))
var/account_num = text2num(href_list["account"])
@@ -381,7 +385,7 @@ var/time_last_changed_position = 0
P.info += " [get_access_desc(A)]"
if ("terminate")
- if (is_authenticated())
+ if (is_authenticated(usr))
modify.assignment = "Terminated"
modify.access = list()
@@ -389,7 +393,7 @@ var/time_last_changed_position = 0
if("make_job_available")
// MAKE ANOTHER JOB POSITION AVAILABLE FOR LATE JOINERS
- if(is_authenticated())
+ if(is_authenticated(usr))
var/edit_job_target = href_list["job"]
var/datum/job/j = job_master.GetJob(edit_job_target)
if(!j)
@@ -404,7 +408,7 @@ var/time_last_changed_position = 0
if("make_job_unavailable")
// MAKE JOB POSITION UNAVAILABLE FOR LATE JOINERS
- if(is_authenticated())
+ if(is_authenticated(usr))
var/edit_job_target = href_list["job"]
var/datum/job/j = job_master.GetJob(edit_job_target)
if(!j)
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index fff7bcecb9a..189338e14e9 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -64,50 +64,69 @@ var/shuttle_call/shuttle_calls[0]
/obj/machinery/computer/communications/New()
..()
crew_announcement.newscast = 1
+
+/obj/machinery/computer/communications/proc/is_authenticated(user as mob, var/message = 1)
+ if(authenticated == 2)
+ return 2
+ else if(isobserver(user) && check_rights(R_ADMIN, 0, user))
+ return 2
+ else if(authenticated)
+ return 1
+ else
+ if(message)
+ user << "Access denied."
+ return 0
/obj/machinery/computer/communications/Topic(href, href_list)
if(..(href, href_list))
return 1
if ((!(src.z in config.station_levels) && !(src.z in config.admin_levels)))
- usr << "\red Unable to establish a connection: \black You're too far away from the station!"
+ usr << "Unable to establish a connection: You're too far away from the station!"
+ return 1
+
+ if(href_list["login"])
+ var/mob/living/carbon/human/M = usr
+ var/obj/item/card = M.get_active_hand()
+ var/obj/item/weapon/card/id/I = (card && card.GetID())||M.wear_id||M.wear_pda
+ if (istype(I, /obj/item/device/pda))
+ var/obj/item/device/pda/pda = I
+ I = pda.id
+ if (I && istype(I))
+ if(src.check_access(I))
+ authenticated = 1
+ if(access_captain in I.access)
+ authenticated = 2
+ crew_announcement.announcer = GetNameAndAssignmentFromId(I)
+ nanomanager.update_uis(src)
+ return
+
+ if(href_list["logout"])
+ authenticated = 0
+ crew_announcement.announcer = ""
+ setMenuState(usr,COMM_SCREEN_MAIN)
+ nanomanager.update_uis(src)
return
- usr.set_machine(src)
+ if(!is_authenticated(usr))
+ return 1
- if(!href_list["operation"])
- return
switch(href_list["operation"])
- // main interface
if("main")
setMenuState(usr,COMM_SCREEN_MAIN)
- if("login")
- var/mob/M = usr
- var/obj/item/weapon/card/id/I = M.get_active_hand()
- if (istype(I, /obj/item/device/pda))
- var/obj/item/device/pda/pda = I
- I = pda.id
- if (I && istype(I))
- if(src.check_access(I))
- authenticated = 1
- if(access_captain in I.access)
- authenticated = 2
- crew_announcement.announcer = GetNameAndAssignmentFromId(I)
- if("logout")
- authenticated = 0
- crew_announcement.announcer = ""
- setMenuState(usr,COMM_SCREEN_MAIN)
-
- // ALART LAVUL
+
if("changeseclevel")
setMenuState(usr,COMM_SCREEN_SECLEVEL)
if("newalertlevel")
- if(issilicon(usr))
- return
+ if(isAI(usr) || isrobot(usr))
+ usr << "Firewalls prevent you from changing the alert level."
+ nanomanager.update_uis(src)
+ return 1
tmp_alertlevel = text2num(href_list["level"])
- var/mob/M = usr
- var/obj/item/weapon/card/id/I = M.get_active_hand()
+ var/mob/living/carbon/human/L = usr
+ var/obj/item/card = L.get_active_hand()
+ var/obj/item/weapon/card/id/I = (card && card.GetID())||L.wear_id||L.wear_pda
if (istype(I, /obj/item/device/pda))
var/obj/item/device/pda/pda = I
I = pda.id
@@ -128,20 +147,22 @@ var/shuttle_call/shuttle_calls[0]
if(SEC_LEVEL_BLUE)
feedback_inc("alert_comms_blue",1)
tmp_alertlevel = 0
- else:
- usr << "You are not authorized to do this."
+ else
+ usr << "You are not authorized to do this."
tmp_alertlevel = 0
setMenuState(usr,COMM_SCREEN_MAIN)
else
- usr << "You need to swipe your ID."
+ usr << "You need to swipe your ID."
if("announce")
- if(src.authenticated==2)
+ if(is_authenticated(usr) == 2)
if(message_cooldown)
- usr << "Please allow at least one minute to pass between announcements"
+ usr << "Please allow at least one minute to pass between announcements."
+ nanomanager.update_uis(src)
return
var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement")
- if(!input || !(usr in view(1,src)))
+ if(!input || ..() || !(is_authenticated(usr) == 2))
+ nanomanager.update_uis(src)
return
crew_announcement.Announce(input)
message_cooldown = 1
@@ -149,27 +170,34 @@ var/shuttle_call/shuttle_calls[0]
message_cooldown = 0
if("callshuttle")
- if(src.authenticated)
- var/response = alert("Are you sure you wish to call the shuttle?", "Confirm", "Yes", "No")
- if(response == "Yes")
- call_shuttle_proc(usr)
- if(emergency_shuttle.online())
- post_status("shuttle")
+ var/input = input(usr, "Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","") as text|null
+ if(!input || ..() || !is_authenticated(usr))
+ nanomanager.update_uis(src)
+ return
+
+ call_shuttle_proc(usr, input)
+ if(emergency_shuttle.online())
+ post_status("shuttle")
setMenuState(usr,COMM_SCREEN_MAIN)
+
if("cancelshuttle")
- if(issilicon(usr)) return
- if(src.authenticated)
- var/response = alert("Are you sure you wish to recall the shuttle?", "Confirm", "Yes", "No")
- if(response == "Yes")
- cancel_call_proc(usr)
- if(emergency_shuttle.online())
- post_status("shuttle")
+ if(isAI(usr) || isrobot(usr))
+ usr << "Firewalls prevent you from recalling the shuttle."
+ nanomanager.update_uis(src)
+ return 1
+ var/response = alert("Are you sure you wish to recall the shuttle?", "Confirm", "Yes", "No")
+ if(response == "Yes")
+ cancel_call_proc(usr)
+ if(emergency_shuttle.online())
+ post_status("shuttle")
setMenuState(usr,COMM_SCREEN_MAIN)
+
if("messagelist")
src.currmsg = 0
if(href_list["msgid"])
setCurrentMessage(usr, text2num(href_list["msgid"]))
setMenuState(usr,COMM_SCREEN_MESSAGES)
+
if("delmessage")
if(href_list["msgid"])
src.currmsg = text2num(href_list["msgid"])
@@ -203,18 +231,39 @@ var/shuttle_call/shuttle_calls[0]
if("setmsg1")
stat_msg1 = input("Line 1", "Enter Message Text", stat_msg1) as text|null
setMenuState(usr,COMM_SCREEN_STAT)
+
if("setmsg2")
stat_msg2 = input("Line 2", "Enter Message Text", stat_msg2) as text|null
setMenuState(usr,COMM_SCREEN_STAT)
- // OMG CENTCOMM LETTERHEAD
- if("MessageCentcomm")
- if(src.authenticated==2)
+ if("nukerequest")
+ if(is_authenticated(usr) == 2)
if(centcomm_message_cooldown)
- usr << "Arrays recycling. Please stand by."
+ usr << "Arrays recycling. Please stand by."
+ nanomanager.update_uis(src)
return
- var/input = input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "")
- if(!input || !(usr in view(1,src)))
+ var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response.", "Self Destruct Code Request.","") as text|null
+ if(!input || ..() || !(is_authenticated(usr) == 2))
+ nanomanager.update_uis(src)
+ return
+ Nuke_request(input, usr)
+ usr << "Request sent."
+ log_say("[key_name(usr)] has requested the nuclear codes from Centcomm")
+ priority_announcement.Announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested",'sound/AI/commandreport.ogg')
+ centcomm_message_cooldown = 1
+ spawn(6000)//10 minute cooldown
+ centcomm_message_cooldown = 0
+ setMenuState(usr,COMM_SCREEN_MAIN)
+
+ if("MessageCentcomm")
+ if(is_authenticated(usr) == 2)
+ if(centcomm_message_cooldown)
+ usr << "Arrays recycling. Please stand by."
+ nanomanager.update_uis(src)
+ return
+ var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") as text|null
+ if(!input || ..() || !(is_authenticated(usr) == 2))
+ nanomanager.update_uis(src)
return
Centcomm_announce(input, usr)
usr << "Message transmitted."
@@ -224,15 +273,16 @@ var/shuttle_call/shuttle_calls[0]
centcomm_message_cooldown = 0
setMenuState(usr,COMM_SCREEN_MAIN)
-
// OMG SYNDICATE ...LETTERHEAD
if("MessageSyndicate")
- if((src.authenticated==2) && (src.emagged))
+ if((is_authenticated(usr) == 2) && (src.emagged))
if(centcomm_message_cooldown)
usr << "Arrays recycling. Please stand by."
+ nanomanager.update_uis(src)
return
- var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "")
- if(!input || !(usr in view(1,src)))
+ var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") as text|null
+ if(!input || ..() || !(is_authenticated(usr) == 2))
+ nanomanager.update_uis(src)
return
Syndicate_announce(input, usr)
usr << "Message transmitted."
@@ -247,17 +297,18 @@ var/shuttle_call/shuttle_calls[0]
src.emagged = 0
setMenuState(usr,COMM_SCREEN_MAIN)
+ nanomanager.update_uis(src)
return 1
/obj/machinery/computer/communications/emag_act(user as mob)
if(!emagged)
src.emagged = 1
- user << "You scramble the communication routing circuits!"
+ user << "You scramble the communication routing circuits!"
+ nanomanager.update_uis(src)
/obj/machinery/computer/communications/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
-
/obj/machinery/computer/communications/attack_hand(var/mob/user as mob)
if(..(user))
return
@@ -266,7 +317,7 @@ var/shuttle_call/shuttle_calls[0]
return
if (!(src.z in list(ZLEVEL_STATION, ZLEVEL_CENTCOMM)))
- user << "\red Unable to establish a connection: \black You're too far away from the station!"
+ user << "Unable to establish a connection: You're too far away from the station!"
return
ui_interact(user)
@@ -274,10 +325,10 @@ var/shuttle_call/shuttle_calls[0]
/obj/machinery/computer/communications/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
// this is the data which will be sent to the ui
var/data[0]
- data["is_ai"] = issilicon(user)
+ data["is_ai"] = isAI(user)||isrobot(user)
data["menu_state"] = data["is_ai"] ? ai_menu_state : menu_state
data["emagged"] = emagged
- data["authenticated"] = authenticated
+ data["authenticated"] = is_authenticated(user, 0)
data["screen"] = getMenuState(usr)
data["stat_display"] = list(
@@ -297,7 +348,7 @@ var/shuttle_call/shuttle_calls[0]
)
)
data["security_level"] = security_level
- data["str_security_level"] = get_security_level()
+ data["str_security_level"] = capitalize(get_security_level())
data["levels"] = list(
list("id"=SEC_LEVEL_GREEN, "name"="Green"),
list("id"=SEC_LEVEL_BLUE, "name"="Blue"),
@@ -333,29 +384,27 @@ var/shuttle_call/shuttle_calls[0]
ui.set_initial_data(data)
// open the new ui window
ui.open()
- // auto update every Master Controller tick
- ui.set_auto_update(1)
/obj/machinery/computer/communications/proc/setCurrentMessage(var/mob/user,var/value)
- if(issilicon(user))
+ if(isAI(user) || isrobot(user))
aicurrmsg=value
else
currmsg=value
/obj/machinery/computer/communications/proc/getCurrentMessage(var/mob/user)
- if(issilicon(user))
+ if(isAI(user) || isrobot(user))
return aicurrmsg
else
return currmsg
/obj/machinery/computer/communications/proc/setMenuState(var/mob/user,var/value)
- if(issilicon(user))
+ if(isAI(user) || isrobot(user))
ai_menu_state=value
else
menu_state=value
/obj/machinery/computer/communications/proc/getMenuState(var/mob/user)
- if(issilicon(user))
+ if(isAI(user) || isrobot(user))
return ai_menu_state
else
return menu_state
@@ -364,39 +413,38 @@ var/shuttle_call/shuttle_calls[0]
for(var/obj/machinery/computer/prison_shuttle/PS in world)
PS.allowedtocall = !(PS.allowedtocall)
-/proc/call_shuttle_proc(var/mob/user)
+/proc/call_shuttle_proc(var/mob/user, var/reason)
if ((!( ticker ) || !emergency_shuttle.location()))
return
if(sent_strike_team == 1)
- user << "Centcom will not allow the shuttle to be called. Consider all contracts terminated."
+ user << "Central Command will not allow the shuttle to be called. Consider all contracts terminated."
return
if(emergency_shuttle.deny_shuttle)
- user << "The emergency shuttle may not be sent at this time. Please try again later."
+ user << "The emergency shuttle may not be sent at this time. Please try again later."
return
if(world.time < 6000) // Ten minute grace period to let the game get going without lolmetagaming. -- TLE
- user << "The emergency shuttle is refueling. Please wait another [round((6000-world.time)/60)] minutes before trying again."
+ user << "The emergency shuttle is refueling. Please wait another [round((6000-world.time)/600)] minutes before trying again."
return
if(emergency_shuttle.going_to_centcom())
- user << "The emergency shuttle may not be called while returning to CentCom."
+ user << "The emergency shuttle may not be called while returning to Central Command."
return
if(emergency_shuttle.online())
- user << "The emergency shuttle is already on its way."
+ user << "The emergency shuttle is already on its way."
return
if(ticker.mode.name == "blob")
- user << "Under directive 7-10, [station_name()] is quarantined until further notice."
+ user << "Under directive 7-10, [station_name()] is quarantined until further notice."
return
- emergency_shuttle.call_evac()
+ emergency_shuttle.call_evac(reason)
log_game("[key_name(user)] has called the shuttle.")
message_admins("[key_name_admin(user)] has called the shuttle.", 1)
-
return
/proc/init_shift_change(var/mob/user, var/force = 0)
@@ -422,7 +470,7 @@ var/shuttle_call/shuttle_calls[0]
return
if(world.time < 54000) // 30 minute grace period to let the game get going
- user << "The shuttle is refueling. Please wait another [round((54000-world.time)/60)] minutes before trying again."
+ user << "The shuttle is refueling. Please wait another [round((54000-world.time)/600)] minutes before trying again."
return
if(ticker.mode.name == "epidemic")
diff --git a/code/game/machinery/computer/hologram.dm b/code/game/machinery/computer/hologram.dm
index c21e3cf8b4f..bfd95d46457 100644
--- a/code/game/machinery/computer/hologram.dm
+++ b/code/game/machinery/computer/hologram.dm
@@ -36,7 +36,7 @@
I.Blend(rgb(- src.lumens, -src.lumens, -src.lumens), ICON_SUBTRACT)
I.Blend(new /icon('icons/mob/human.dmi', "mouth_m_s"), ICON_OVERLAY)
- I.Blend(new /icon('icons/mob/human.dmi', "underwear1_m_s"), ICON_OVERLAY)
+ I.Blend(new /icon('icons/mob/underwear.dmi', "Mens White"), ICON_OVERLAY)
var/icon/U = new /icon('icons/mob/human_face.dmi', "hair_a_s")
U.Blend(rgb(src.h_r, src.h_g, src.h_b), ICON_ADD)
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index 8a7d4d170a8..3099d738a70 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -446,16 +446,13 @@
//Sender isn't faking as someone who exists
if(isnull(PDARec))
src.linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]")
- if (!customrecepient.silent)
- playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
- for (var/mob/O in hearers(3, customrecepient.loc))
- O.show_message(text("\icon[customrecepient] *[customrecepient.ttone]*"))
- if( customrecepient.loc && ishuman(customrecepient.loc) )
- var/mob/living/carbon/human/H = customrecepient.loc
- H << "\icon[customrecepient] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)"
- log_pda("[usr] (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]")
- customrecepient.overlays.Cut()
- customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r")
+ customrecepient.play_ringtone()
+ if( customrecepient.loc && ishuman(customrecepient.loc) )
+ var/mob/living/carbon/human/H = customrecepient.loc
+ H << "\icon[customrecepient] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)"
+ log_pda("[usr] (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]")
+ customrecepient.overlays.Cut()
+ customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r")
//Sender is faking as someone who exists
else
src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]")
@@ -464,16 +461,13 @@
if(!customrecepient.conversations.Find("\ref[PDARec]"))
customrecepient.conversations.Add("\ref[PDARec]")
- if (!customrecepient.silent)
- playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
- for (var/mob/O in hearers(3, customrecepient.loc))
- O.show_message(text("\icon[customrecepient] *[customrecepient.ttone]*"))
- if( customrecepient.loc && ishuman(customrecepient.loc) )
- var/mob/living/carbon/human/H = customrecepient.loc
- H << "\icon[customrecepient] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)"
- log_pda("[usr] (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]")
- customrecepient.overlays.Cut()
- customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r")
+ customrecepient.play_ringtone()
+ if( customrecepient.loc && ishuman(customrecepient.loc) )
+ var/mob/living/carbon/human/H = customrecepient.loc
+ H << "\icon[customrecepient] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)"
+ log_pda("[usr] (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]")
+ customrecepient.overlays.Cut()
+ customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r")
//Finally..
ResetMessage()
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index ba3727ee30b..4fda7a334d3 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -72,14 +72,14 @@
target << "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered."
target.ResetSecurityCodes()
else
- message_admins("\blue [key_name_admin(usr)] detonated [target.name]!")
- log_game("\blue [key_name_admin(usr)] detonated [target.name]!")
+ message_admins("[key_name_admin(usr)] detonated [key_name_admin(target)] (JMP)!")
+ log_game("\[key_name(usr)] detonated [key_name(target)]!")
target << "Self-destruct command received."
+ if(target.connected_ai)
+ target.connected_ai << "
ALERT - Cyborg detonation detected: [target.name]
"
spawn(10)
target.self_destruct()
-
-
// Locks or unlocks the cyborg
else if (href_list["lockdown"])
var/mob/living/silicon/robot/target = get_cyborg_by_name(href_list["lockdown"])
@@ -101,15 +101,13 @@
if(!target || !istype(target))
return
- message_admins("\blue [key_name_admin(usr)] [target.canmove ? "locked down" : "released"] [target.name]!")
- log_game("[key_name(usr)] [target.canmove ? "locked down" : "released"] [target.name]!")
+ message_admins("[key_name_admin(usr)] [target.canmove ? "locked down" : "released"] [key_name_admin(target)]!")
+ log_game("[key_name(usr)] [target.canmove ? "locked down" : "released"] [key_name(target)]!")
target.canmove = !target.canmove
- if (target.lockcharge)
- target.lockcharge = !target.lockcharge
- target << "Your lockdown has been lifted!"
- else
- target.lockcharge = !target.lockcharge
- target << "You have been locked down!"
+ target.lockcharge = !target.lockcharge
+ target << "[!target.lockcharge ? "Your lockdown has been lifted!" : "You have been locked down!"]"
+ if(target.connected_ai)
+ target.connected_ai << "[!target.lockcharge ? "NOTICE - Cyborg lockdown lifted" : "ALERT - Cyborg lockdown detected"]: [target.name]
"
// Remotely hacks the cyborg. Only antag AIs can do this and only to linked cyborgs.
else if (href_list["hack"])
@@ -137,8 +135,8 @@
if(!target || !istype(target))
return
- message_admins("\blue [key_name_admin(usr)] emagged [target.name] using robotic console!")
- log_game("[key_name(usr)] emagged [target.name] using robotic console!")
+ message_admins("\blue [key_name_admin(usr)] emagged [key_name_admin(target)] using robotic console!")
+ log_game("[key_name(usr)] emagged [key_name(target)] using robotic console!")
target.emagged = 1
target << "Failsafe protocols overriden. New tools available."
@@ -160,9 +158,9 @@
user << "Self-destruct aborted - safety active"
return
- message_admins("\blue [key_name_admin(usr)] detonated all cyborgs!")
- log_game("[key_name(usr)] detonated all cyborgs!")
-
+ message_admins("[key_name_admin(usr)] detonated all cyborgs!")
+ log_game("\[key_name(usr)] detonated all cyborgs!")
+
for(var/mob/living/silicon/robot/R in mob_list)
if(istype(R, /mob/living/silicon/robot/drone))
continue
@@ -170,6 +168,8 @@
if(R.scrambledcodes)
continue
R << "Self-destruct command received."
+ if(R.connected_ai)
+ R.connected_ai << "
ALERT - Cyborg detonation detected: [R.name]
"
spawn(10)
R.self_destruct()
diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm
index d9f3dcd996e..28125a24c96 100644
--- a/code/game/machinery/computer/shuttle.dm
+++ b/code/game/machinery/computer/shuttle.dm
@@ -37,12 +37,12 @@
src.authorized -= W:registered_name
src.authorized += W:registered_name
if (src.auth_need - src.authorized.len > 0)
- message_admins("[key_name_admin(user)] has authorized early shuttle launch")
- log_game("[user.ckey] has authorized early shuttle launch")
+ message_admins("[key_name_admin(user.client)] has authorized early shuttle launch ",0,1)
+ log_game("[key_name(user)] has authorized early shuttle launch in ([x],[y],[z])")
world << text("\blue Alert: [] authorizations needed until shuttle is launched early", src.auth_need - src.authorized.len)
else
- message_admins("[key_name_admin(user)] has launched the shuttle")
- log_game("[user.ckey] has launched the shuttle early")
+ message_admins("[key_name_admin(user.client)] has launched the emergency shuttle before launch.",0,1)
+ log_game("[key_name(user)] has launched the emergency shuttle before launch in ([x],[y],[z]).")
world << "\blue Alert: Shuttle launch time shortened to 10 seconds!"
emergency_shuttle.set_launch_countdown(10)
//src.authorized = null
@@ -59,13 +59,15 @@
src.authorized = list( )
return
- emag_act(user as mob)
+ emag_act(mob/user as mob)
if (!emagged)
var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel")
if(!emagged && !emergency_shuttle.location())
switch(choice)
if("Launch")
+ message_admins("[key_name_admin(user.client)] has emagged the emergency shuttle before launch.",0,1)
+ log_game("[key_name(user)] has emagged the emergency shuttle in ([x],[y],[z]) before launch.")
world << "\blue Alert: Shuttle launch time shortened to 10 seconds!"
emergency_shuttle.set_launch_countdown(10)
emagged = 1
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index d52c6d2adf7..c28edd89e55 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -488,9 +488,8 @@
Gh << "Warning: Your body has entered cryostorage."
// Book keeping!
- var/turf/location = get_turf(src)
- log_admin("[key_name_admin(M)] has entered a stasis pod. (JMP)")
- message_admins("[key_name_admin(M)] has entered a stasis pod.")
+ log_admin("[key_name(M)] has entered a stasis pod.")
+ message_admins("[key_name_admin(user)] has entered a stasis pod. (JMP)")
//Despawning occurs when process() is called with an occupant without a client.
src.add_fingerprint(M)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 6eaa50bc1f1..abc14227433 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -851,7 +851,9 @@ About the new airlock wires panel:
return
/obj/machinery/door/airlock/plasma/attackby(C as obj, mob/user as mob, params)
- if(C)
+ if(is_hot(C) > 300)
+ message_admins("Plasma airlock ignited by [key_name_admin(user)] in ([x],[y],[z] - JMP)")
+ log_game("Plasma wall ignited by [key_name(user)] in ([x],[y],[z])")
ignite(is_hot(C))
..()
diff --git a/code/game/machinery/embedded_controller/airlock_controllers.dm b/code/game/machinery/embedded_controller/airlock_controllers.dm
index fb909dee555..bf6fe4f0fe7 100644
--- a/code/game/machinery/embedded_controller/airlock_controllers.dm
+++ b/code/game/machinery/embedded_controller/airlock_controllers.dm
@@ -45,7 +45,7 @@
/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/Topic(href, href_list)
if(..())
- return
+ return 1
usr.set_machine(src)
src.add_fingerprint(usr)
diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm
index b0e0a52d948..06a5266d17e 100644
--- a/code/game/machinery/embedded_controller/embedded_controller_base.dm
+++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm
@@ -26,6 +26,9 @@
update_icon()
src.updateDialog()
+/obj/machinery/embedded_controller/attack_ghost(mob/user as mob)
+ src.ui_interact(user)
+
/obj/machinery/embedded_controller/attack_ai(mob/user as mob)
src.ui_interact(user)
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index 5322c3da301..e32146ff69f 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -82,7 +82,7 @@
if (istype(O, /mob/living/carbon/human))
var/mob/living/carbon/human/H = O
var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"]
- if ((E.damage > E.min_bruised_damage && prob(E.damage + 50)))
+ if (E && (E.damage > E.min_bruised_damage && prob(E.damage + 50)))
flick("e_flash", O:flash)
E.damage += rand(1, 2)
else
diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm
index df6727ce3f8..db49facd824 100644
--- a/code/game/machinery/kitchen/gibber.dm
+++ b/code/game/machinery/kitchen/gibber.dm
@@ -339,7 +339,7 @@
return
if(UserOverride)
- msg_admin_attack("[occupant] ([occupant.ckey]) was gibbed by an autogibber (\the [src]) at (JMP)")
+ msg_admin_attack("[key_name_admin(occupant)] was gibbed by an autogibber (\the [src]) (JMP)")
if(src.operating)
return
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index eaa0fa170b4..14c72f6ee9c 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -224,7 +224,7 @@ Class Procs:
var/re_init=0
if("set_tag" in href_list)
if(!(href_list["set_tag"] in settagwhitelist))//I see you're trying Href exploits, I see you're failing, I SEE ADMIN WARNING. (seriously though, this is a powerfull HREF, I originally found this loophole, I'm not leaving it in on my PR)
- message_admins("set_tag HREF (var attempted to edit: [href_list["set_tag"]]) exploit attempted by [key_name(user, user.client)] (?) on [src] ([x],[y],[z] - JMP)")
+ message_admins("set_tag HREF (var attempted to edit: [href_list["set_tag"]]) exploit attempted by [key_name_admin(user)] on [src] (JMP)")
return 1
if(!(href_list["set_tag"] in vars))
usr << "Something went wrong: Unable to find [href_list["set_tag"]] in vars!"
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 5ebcb512d72..7bb074e03f4 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -174,7 +174,7 @@ var/list/turret_icons
user << "There seems to be a firewall preventing you from accessing this device."
return 1
- if(locked && !(isrobot(user) || isAI(user)))
+ if(locked && !(isrobot(user) || isAI(user) || isobserver(user)))
user << "Access denied."
return 1
@@ -185,6 +185,9 @@ var/list/turret_icons
return
ui_interact(user)
+
+/obj/machinery/porta_turret/attack_ghost(mob/user)
+ ui_interact(user)
/obj/machinery/porta_turret/attack_hand(mob/user)
if(isLocked(user))
diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm
index 915def6bdda..11ec8837c87 100644
--- a/code/game/machinery/syndicatebeacon.dm
+++ b/code/game/machinery/syndicatebeacon.dm
@@ -87,7 +87,7 @@
M << "You have joined the ranks of the Syndicate and become a traitor to the station!"
- message_admins("[N]/([N.ckey]) has accepted a traitor objective from a syndicate beacon.")
+ message_admins("[key_name_admin(N)] has accepted a traitor objective from a syndicate beacon.")
var/obj_count = 1
for(var/datum/objective/OBJ in M.mind.objectives)
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 7ad9f121d06..04a5d3e45dd 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -138,7 +138,7 @@
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
if(payload && !istype(payload, /obj/item/weapon/bombcore/training))
- msg_admin_attack("[key_name(user)][isAntag(user) ? "(ANTAG)" : ""]? has primed a [name] ([payload]) for detonation at [A.name] (JMP).")
+ msg_admin_attack("[key_name_admin(user)] has primed a [name] ([payload]) for detonation at [A.name] (JMP).")
log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])")
payload.adminlog = "The [src.name] that [key_name(user)] had primed detonated!"
@@ -311,10 +311,9 @@
var/turf/T = get_turf(src)
var/area/A = get_area(T)
detonated--
- var/log_str = "[key_name(user)]? has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] (JMP)."
- bombers += log_str
- message_admins(log_str)
- log_game("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name]([T.x],[T.y],[T.z])")
+ message_admins("[key_name_admin(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] (JMP).")
+ bombers += "[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])"
+ log_game("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])")
detonated = 0
existant = 0
cooldown = 1
diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index 7823dabea92..85ec4928a0c 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -637,7 +637,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
if(do_sleep)
sleep(rand(10,25))
- //world.log << "Level: [signal.data["level"]] - Done: [signal.data["done"]]"
+ //log_to_dd("Level: [signal.data["level"]] - Done: [signal.data["done"]]")
return signal
diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm
index 3657410b400..f3b84e75f89 100644
--- a/code/game/machinery/telecomms/telecomunications.dm
+++ b/code/game/machinery/telecomms/telecomunications.dm
@@ -604,8 +604,9 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
if(istext(t))
rawcode = t
-/obj/machinery/telecomms/server/proc/compile()
+/obj/machinery/telecomms/server/proc/compile(mob/user as mob)
if(Compiler)
+ admin_log(user)
return Compiler.Compile(rawcode)
/obj/machinery/telecomms/server/proc/update_logs()
@@ -627,8 +628,13 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
log_entries.Add(log)
update_logs()
-
-
+/obj/machinery/telecomms/server/proc/admin_log(var/mob/mob)
+ var/msg="[key_name(mob)] has compiled a script to server [src]:"
+ diary << msg
+ diary << rawcode
+ src.investigate_log("[msg]
[rawcode]", "ntsl")
+ if(length(rawcode)) // Let's not bother the admins for empty code.
+ message_admins("[key_name_admin(mob)] has compiled and uploaded a NTSL script to [src.id] (JMP)")
// Simple log entry datum
diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm
index 90db7efaec9..458c8a369cb 100644
--- a/code/game/mecha/equipment/tools/tools.dm
+++ b/code/game/mecha/equipment/tools/tools.dm
@@ -443,6 +443,8 @@
P.failchance = 0
P.icon_state = "anom"
P.name = "wormhole"
+ message_admins("[key_name_admin(chassis.occupant, chassis.occupant.client)](?) (FLW) used a Wormhole Generator in ([T.x],[T.y],[T.z] - JMP)",0,1)
+ log_game("[key_name(chassis.occupant)] used a Wormhole Generator in ([T.x],[T.y],[T.z])")
do_after_cooldown()
src = null
spawn(rand(150,300))
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index 1aec90c414f..1727a4f25fa 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -166,6 +166,9 @@
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])")
do_after_cooldown()
return
@@ -238,6 +241,9 @@
sleep(2)
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])")
do_after_cooldown()
return
@@ -351,6 +357,9 @@
M.throw_at(target, missile_range, missile_speed, chassis)
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])")
do_after_cooldown()
return
diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm
index 3f6b92c98ce..42837d06aba 100644
--- a/code/game/mecha/mech_bay.dm
+++ b/code/game/mecha/mech_bay.dm
@@ -13,8 +13,13 @@
temperature = TCMB
/turf/simulated/floor/mech_bay_recharge_floor/Destroy()
- recharge_console.recharge_floor = null
- recharge_port.recharge_floor = null
+ if(recharge_console && recharge_console.recharge_floor == src)
+ recharge_console.recharge_floor = null
+ recharge_console = null
+ if(recharge_port && recharge_port.recharge_floor == src)
+ recharge_port.recharge_floor = null
+ recharge_port = null
+ recharging_mecha = null
..()
/turf/simulated/floor/mech_bay_recharge_floor/Entered(var/obj/mecha/mecha)
@@ -285,4 +290,4 @@
// open the new ui window
ui.open()
// auto update every Master Controller tick
- ui.set_auto_update(1)
+ ui.set_auto_update(1)
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index 1d25b822d9b..329cbe8c152 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -483,7 +483,7 @@ steam.start() -- spawns the effect
var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast)
var/more = ""
if(M)
- more = "(?)"
+ more = " "
msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", 0, 1)
log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].")
else
@@ -1226,7 +1226,7 @@ steam.start() -- spawns the effect
var/r = rand(0,255)
var/g = rand(0,255)
var/b = rand(0,255)
- world.log << "Colour , [r],[g],[b]"
+ log_to_dd("Colour , [r],[g],[b]")
I.Blend(rgb(r,g,b),ICON_MULTIPLY)
src.icon = I
playsound(src.loc, "sparks", 100, 1)
diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm
index 735b006d75e..74919873a29 100644
--- a/code/game/objects/explosion.dm
+++ b/code/game/objects/explosion.dm
@@ -144,7 +144,7 @@
var/timeofhour = TimeOfHour
var/took = round((start <= timeofhour) ? ((timeofhour-start)/10) : ((timeofhour-(start-36000))/10), 0.01)
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
- if(Debug2) world.log << "## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds."
+ if(Debug2) log_to_dd("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
//Machines which report explosions.
for(var/i,i<=doppler_arrays.len,i++)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 6e8df50c0e7..842fa1edb45 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -599,10 +599,10 @@
user << "\red You cannot locate any eyes on this creature!"
return
- user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
- M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
+ user.attack_log += "\[[time_stamp()]\] Attacked [key_name(M)] with [src.name] (INTENT: [uppertext(user.a_intent)])"
+ M.attack_log += "\[[time_stamp()]\] Attacked by [key_name(user)] with [src.name] (INTENT: [uppertext(user.a_intent)])"
if(M.ckey)
- msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") //BS12 EDIT ALG
+ msg_admin_attack("[key_name_admin(user)] attacked [key_name_admin(M)] with [src.name] (INTENT: [uppertext(user.a_intent)])") //BS12 EDIT ALG
if(!iscarbon(user))
M.LAssailant = null
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 6f743230357..74c1f2f51ff 100755
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -921,14 +921,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
ai.show_message("Intercepted message from [who]: [t]")
*/
- if (!P.silent)
- var/sound/S = sound('sound/machines/twobeep.ogg')
-
- if(P.ttone in ttone_sound)
- S = ttone_sound[P.ttone]
- playsound(P.loc, S, 50, 1)
- for (var/mob/O in hearers(3, P.loc))
- if(!P.silent) O.show_message(text("\icon[P] *[P.ttone]*"))
+ P.play_ringtone()
//Search for holder of the PDA.
var/mob/living/L = null
if(P.loc && isliving(P.loc))
@@ -951,6 +944,15 @@ var/global/list/obj/item/device/pda/PDAs = list()
else
U << "ERROR: Messaging server is not responding."
+/obj/item/device/pda/proc/play_ringtone()
+ if (!silent)
+ var/sound/S = sound('sound/machines/twobeep.ogg')
+
+ if(ttone in ttone_sound)
+ S = ttone_sound[ttone]
+ playsound(loc, S, 50, 1)
+ for (var/mob/O in hearers(3, loc))
+ if(!silent) O.show_message(text("\icon[src] *[ttone]*"))
/obj/item/device/pda/verb/verb_remove_id()
set category = null
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index ff16cf9e43c..2e6a91b6909 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -13,9 +13,9 @@
if(!istype(M, /mob/living/silicon/ai))//If target is not an AI.
return ..()
- M.attack_log += text("\[[time_stamp()]\] Has been carded with [src.name] by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to card [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] used the [src.name] to card [M.name] ([M.ckey]) (JMP)")
+ M.attack_log += text("\[[time_stamp()]\] Has been carded with [src.name] by [key_name(user)]")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to card [key_name(M)]")
+ msg_admin_attack("[key_name_admin(user)] used the [src.name] to card [M.name] ([M.ckey])")
transfer_ai("AICORE", "AICARD", M, user)
return
diff --git a/code/game/objects/items/devices/pizza_bomb.dm b/code/game/objects/items/devices/pizza_bomb.dm
index 9a3180a15e8..1f1b362078d 100644
--- a/code/game/objects/items/devices/pizza_bomb.dm
+++ b/code/game/objects/items/devices/pizza_bomb.dm
@@ -30,7 +30,7 @@
timer = Clamp(timer, 10, 100)
icon_state = "pizzabox1"
user << "You set the timer to [timer / 10] before activating the payload and closing \the [src]."
- message_admins("[key_name(usr)]? has set a timer on a pizza bomb to [timer/10] seconds at (JMP).")
+ message_admins("[key_name_admin(usr)] has set a timer on a pizza bomb to [timer/10] seconds at (JMP).")
log_game("[key_name(usr)] has set the timer on a pizza bomb to [timer/10] seconds ([loc.x],[loc.y],[loc.z]).")
armer = usr
name = "pizza box"
@@ -42,7 +42,7 @@
icon_state = "pizzabox_bomb"
audible_message("\icon[src] *beep* *beep*")
user << "That's no pizza! That's a bomb!"
- message_admins("[key_name(usr)]? has triggered a pizza bomb armed by [armer] at (JMP).")
+ message_admins("[key_name_admin(usr)] has triggered a pizza bomb armed by [armer] at (JMP).")
log_game("[key_name(usr)] has triggered a pizza bomb armed by [armer] ([loc.x],[loc.y],[loc.z]).")
primed = 1
sleep(timer)
diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm
index 7db62612994..ab61e766c91 100644
--- a/code/game/objects/items/devices/powersink.dm
+++ b/code/game/objects/items/devices/powersink.dm
@@ -42,6 +42,8 @@
anchored = 1
mode = 1
src.visible_message("[user] attaches [src] to the cable!")
+ message_admins("Power sink activated by [key_name_admin(user)] at ([x],[y],[z] - JMP)")
+ log_game("Power sink activated by [key_name(user)] at ([x],[y],[z])")
return
else
user << "Device must be placed over an exposed cable to attach to it."
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 7aafc777268..62498009f0b 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -60,7 +60,7 @@
frequency = sanitize_frequency(frequency, maxf)
// The max freq is higher than a regular headset to decrease the chance of people listening in, if you use the higher channels.
else if (frequency < 1441 || frequency > maxf)
- //world.log << "[src] ([type]) has a frequency of [frequency], sanitizing."
+ //log_to_dd("[src] ([type]) has a frequency of [frequency], sanitizing.")
frequency = sanitize_frequency(frequency, maxf)
set_frequency(frequency)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 30f09d8713d..82402e273c9 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -72,7 +72,7 @@ REAGENT SCANNER
spawn(pulse_duration)
if(O)
var/turf/U = O.loc
- if(U.intact)
+ if(U && U.intact)
O.invisibility = 101
O.alpha = 255
for(var/mob/living/M in T.contents)
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index ee4f96b9230..a533efe0a58 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -51,7 +51,7 @@
A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb).
bombers += "[key_name(user)] attached a [item] to a transfer valve."
- msg_admin_attack("[key_name_admin(user)][isAntag(user) ? "(ANTAG)" : ""] attached [item] to a transfer valve.")
+ msg_admin_attack("[key_name_admin(user)]attached [item] to a transfer valve.")
log_game("[key_name_admin(user)] attached [item] to a transfer valve.")
attacher = user
nanomanager.update_uis(src) // update all UIs attached to src
@@ -179,23 +179,13 @@
if(!attacher)
attacher_name = "Unknown"
else
- attacher_name = "[attacher.name]([attacher.ckey])"
-
- var/log_str = "Bomb valve opened in [A.name] "
- log_str += "with [attached_device ? attached_device : "no device"] attacher: [attacher_name]"
-
- if(attacher)
- log_str += "(?)"
+ attacher_name = "[key_name_admin(attacher)]"
var/mob/mob = get_mob_by_key(src.fingerprintslast)
- var/last_touch_info = ""
- if(mob)
- last_touch_info = "(?)"
-
- log_str += " Last touched by: [src.fingerprintslast][last_touch_info]"
- bombers += log_str
- msg_admin_attack(log_str, 0, 1)
- log_game(log_str)
+
+ bombers += "Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]"
+ message_admins("Bomb valve opened at [A.name] (JMP) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name_admin(mob)]")
+ log_game("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]")
merge_gases()
spawn(20) // In case one tank bursts
for (var/i=0,i<5,i++)
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index d8baba60d41..3d496ca3b86 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -10,10 +10,10 @@
icon_state = "shock"
attack(mob/M as mob, mob/living/silicon/robot/user as mob)
- M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])")
+ M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [key_name(user)]")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [key_name(M)]")
if(M.ckey)
- msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] used the [src.name] to attack [M.name] ([M.ckey]) (JMP)")
+ msg_admin_attack("[key_name_admin(user)] used the [src.name] to attack [key_name_admin(M)]")
if(!iscarbon(user))
M.LAssailant = null
diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm
index 09f3776bc01..7e49a4465b9 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(5,20),IRRADIATE,0)
+ M.apply_effect(rand(10,25),IRRADIATE,0)
if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed
// UI in syringe.
@@ -85,8 +85,6 @@
M.dna.SetSEValue(block,src.GetValue())
domutcheck(M, null, block!=null)
uses--
- if(prob(5))
- trigger_side_effect(M)
spawn(0)//this prevents the collapse of space-time continuum
if (user)
diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm
index 8c2bb4fe51e..45ed9da7217 100644
--- a/code/game/objects/items/weapons/explosives.dm
+++ b/code/game/objects/items/weapons/explosives.dm
@@ -41,6 +41,8 @@
user.say(message_say)
target = user
+ message_admins("[key_name_admin(user)] suicided with [src.name] at ([x],[y],[z] - JMP)",0,1)
+ message_admins("[key_name(user)] suicided with [src.name] at ([x],[y],[z])")
explode(get_turf(user))
return .
@@ -78,12 +80,12 @@
if (ismob(target))
add_logs(target, user, "planted [name] on")
user.visible_message("\red [user.name] finished planting an explosive on [target.name]!")
- message_admins("[key_name(user, user.client)](?) planted C4 on [key_name(target)](?) with [timer] second fuse",0,1)
- log_game("[key_name(user)] planted C4 on [key_name(target)] with [timer] second fuse")
+ message_admins("[key_name_admin(user)] planted [src.name] on [key_name_admin(target)] with [timer] second fuse",0,1)
+ log_game("[key_name(user)] planted [src.name] on [key_name(target)] with [timer] second fuse")
else
- message_admins("[key_name(user, user.client)](?) planted C4 on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [timer] second fuse",0,1)
- log_game("[key_name(user)] planted C4 on [target.name] at ([target.x],[target.y],[target.z]) with [timer] second fuse")
+ message_admins("[key_name_admin(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [timer] second fuse",0,1)
+ log_game("[key_name(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z]) with [timer] second fuse")
target.overlays += image('icons/obj/assemblies.dmi', "plastic-explosive2")
user << "Bomb has been planted. Timer counting down from [timer]."
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index 9e81b02d31c..57aec40f09e 100644
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -66,6 +66,7 @@
var/turf/target_turf = get_turf(target)
if(target_turf)
var/turflist = getline(user, target_turf)
+ add_logs(user, target, "flamethrowered", addition="at [target.x],[target.y],[target.z]")
flame_turf(turflist)
/obj/item/weapon/flamethrower/attackby(obj/item/W as obj, mob/user as mob, params)
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index 28bea3240a3..c5705d31069 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -18,7 +18,7 @@
var/affected_area = 3
var/obj/item/device/assembly_holder/nadeassembly = null
var/label = null
-
+ var/assemblyattacher
/obj/item/weapon/grenade/chem_grenade/New()
create_reagents(1000)
@@ -90,10 +90,9 @@
update_icon()
else if(clown_check(user))
// This used to go before the assembly check, but that has absolutely zero to do with priming the damn thing. You could spam the admins with it.
- var/log_str = "[key_name(usr)][isAntag(usr) ? "(ANTAG)" : ""]? has primed a [name] for detonation at [A.name] (JMP)."
- msg_admin_attack(log_str)
- log_game(log_str)
- bombers += "[log_str]"
+ message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP)")
+ log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])")
+ bombers += "[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])"
user << "You prime the [name]! [det_time / 10] second\s!"
active = 1
update_icon()
@@ -138,9 +137,8 @@
contained = "\[[contained]\]"
var/turf/bombturf = get_turf(loc)
var/area/A = bombturf.loc
- var/log_str = "[key_name(usr)][isAntag(usr) ? "(ANTAG)" : ""]? has completed [name] at [A.name] (JMP) [contained]."
- msg_admin_attack(log_str)
- log_game(log_str)
+ message_admins("[key_name_admin(usr)] has completed [name] at [A.name] (JMP) [contained].")
+ log_game("[key_name(usr)] has completed [name] at [bombturf.x], [bombturf.y], [bombturf.z].")
else
user << "You need to add at least one beaker before locking the assembly."
else if(stage == READY && !nadeassembly)
@@ -173,7 +171,7 @@
nadeassembly = A
A.master = src
A.loc = src
-
+ assemblyattacher = user.ckey
stage = WIRED
user << "You add [A] to [src]!"
update_icon()
@@ -259,7 +257,15 @@
if(!has_reagents)
playsound(loc, 'sound/items/Screwdriver2.ogg', 50, 1)
- return
+ return
+
+ if(nadeassembly)
+ var/mob/M = get_mob_by_ckey(assemblyattacher)
+ var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
+ var/turf/T = get_turf(src)
+ var/area/A = get_area(T)
+ message_admins("grenade primed by an assembly, attached by [key_name_admin(M)](?) ([admin_jump_link(M, "holder")]) and last touched by [key_name_admin(last)](?) ([admin_jump_link(last, "holder")]) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).")
+ log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")
playsound(loc, 'sound/effects/bamf.ogg', 50, 1)
diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm
index bdbfd1fd4ea..d7d3dfb88e2 100644
--- a/code/game/objects/items/weapons/grenades/ghettobomb.dm
+++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm
@@ -112,8 +112,8 @@
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
- message_admins("[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP).")
- log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
+ message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP)")
+ log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])")
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index 2d5f6ac0d90..a2b5dccd963 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -63,10 +63,9 @@
add_fingerprint(user)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
- var/log_str = "[key_name(usr)][isAntag(usr) ? "(ANTAG)" : ""]? has primed a [name] for detonation at [A.name] (JMP)."
- msg_admin_attack(log_str)
- log_game(log_str)
- bombers += "[log_str]"
+ message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP)")
+ log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])")
+ bombers += "[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])"
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm
index 9b34938d480..f622a516b82 100644
--- a/code/game/objects/items/weapons/hydroponics.dm
+++ b/code/game/objects/items/weapons/hydroponics.dm
@@ -196,9 +196,9 @@
if(istype(M, /mob/living))
M << "\red You are stunned by the powerful acid of the Deathnettle!"
- M.attack_log += text("\[[time_stamp()]\] Had the [src.name] used on them by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] on [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] used the [src.name] on [M.name] ([M.ckey]) (JMP)")
+ M.attack_log += text("\[[time_stamp()]\] Had the [src.name] used on them by [key_name(user)]")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] on [key_name(M)]")
+ msg_admin_attack("[key_name_admin(user)] used the [src.name] on [key_name_admin(M)]")
if(!iscarbon(user))
M.LAssailant = null
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index 965da5e0478..c964dd1e0b4 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -162,8 +162,8 @@ Implant Specifics:
"}
var/need_gib = null
if(istype(imp_in, /mob/))
var/mob/T = imp_in
- message_admins("Explosive implant triggered in [T] ([T.key]). (JMP) ")
- log_game("Explosive implant triggered in [T] ([T.key]).")
+ message_admins("Explosive implant triggered in [key_name_admin(T)]")
+ log_game("Explosive implant triggered in [key_name(T)].")
need_gib = 1
if(ishuman(imp_in))
diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm
index 7e9b207ea4b..4de580b70de 100644
--- a/code/game/objects/items/weapons/implants/implanter.dm
+++ b/code/game/objects/items/weapons/implants/implanter.dm
@@ -32,9 +32,9 @@
for (var/mob/O in viewers(M, null))
O.show_message("\red [M] has been implanted by [user].", 1)
- M.attack_log += text("\[[time_stamp()]\] Implanted with [src.name] ([src.imp.name]) by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] ([src.imp.name]) to implant [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] implanted [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)")
+ M.attack_log += text("\[[time_stamp()]\] Implanted with [src.name] ([src.imp.name]) by [key_name(user)]")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] ([src.imp.name]) to implant [key_name(M)]")
+ msg_admin_attack("[key_name_admin(user)] implanted [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])")
user.show_message("\red You implanted the implant into [M].")
if(src.imp.implanted(M, user))
diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm
index 207deb0bfc7..1925455529c 100644
--- a/code/game/objects/items/weapons/legcuffs.dm
+++ b/code/game/objects/items/weapons/legcuffs.dm
@@ -44,11 +44,8 @@
if(2,3)
user.drop_item(src)
I.loc = src
- var/turf/bombturf = get_turf(src)
- var/area/A = get_area(bombturf)
- var/log_str = "[key_name(usr)]? has rigged a beartrap with an IED at [A.name] (JMP)."
- message_admins(log_str)
- log_game(log_str)
+ message_admins("[key_name_admin(user)] has rigged a beartrap with an IED.")
+ log_game("[key_name(user)] has rigged a beartrap with an IED.")
user << "You sneak the [IED] underneath the pressure plate and connect the trigger wire."
desc = "A trap used to catch bears and other legged creatures. There is an IED hooked up to it."
else
@@ -70,11 +67,8 @@
IED.overlays -= image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")
IED.icon_state = initial(icon_state) + "_active"
IED.assembled = 3
- var/turf/bombturf = get_turf(src)
- var/area/A = get_area(bombturf)
- var/log_str = "[key_name(usr)]? has triggered an IED-rigged [name] at [A.name] (JMP)."
- message_admins(log_str)
- log_game(log_str)
+ message_admins("[key_name_admin(usr)] has triggered an IED-rigged [name].")
+ log_game("[key_name(usr)] has triggered an IED-rigged [name].")
spawn(IED.det_time)
IED.prime()
if(ishuman(AM))
@@ -95,7 +89,7 @@
H.update_inv_legcuffed()
H << "You step on \the [src]!"
if(IED && IED.active)
- H << "The [src]'s IED has been activated!"
+ H << "\The [src]'s IED has been activated!"
feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart.
for(var/mob/O in viewers(H, null))
if(O == H)
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index 6aa5340245d..a8551e96fd6 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -165,6 +165,7 @@
if(display_contents_with_number)
for(var/datum/numbered_display/ND in display_contents)
+ ND.sample_object.mouse_opacity = 2
ND.sample_object.screen_loc = "[cx]:16,[cy]:16"
ND.sample_object.maptext = "[(ND.number > 1)? "[ND.number]" : ""]"
ND.sample_object.layer = 20
@@ -174,6 +175,7 @@
cy--
else
for(var/obj/O in contents)
+ O.mouse_opacity = 2 //This is here so storage items that spawn with contents correctly have the "click around item to equip"
O.screen_loc = "[cx]:16,[cy]:16"
O.maptext = ""
O.layer = 20
@@ -310,6 +312,7 @@
src.orient2hud(usr)
if(usr.s_active)
usr.s_active.show_to(usr)
+ W.mouse_opacity = 2 //So you can click on the area around the item to equip it, instead of having to pixel hunt
update_icon()
return 1
@@ -345,6 +348,7 @@
W.maptext = ""
W.on_exit_storage(src)
update_icon()
+ W.mouse_opacity = initial(W.mouse_opacity)
return 1
//This proc is called when you want to place an item into the storage item.
@@ -442,6 +446,9 @@
return
/obj/item/weapon/storage/Destroy()
+ for(var/obj/O in contents)
+ O.mouse_opacity = initial(O.mouse_opacity)
+
qdel(boxes)
qdel(closer)
return ..()
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 56a31ed5284..ee6fb876f05 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -41,11 +41,7 @@
else
M.LAssailant = user
- msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)")
-
- if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
- user << "\red You don't have the dexterity to do this!"
- return
+ msg_admin_attack("[key_name_admin(user)] attacked [key_name_admin(M)] with [src.name] (INTENT: [uppertext(user.a_intent)])")
if ((CLUMSY in user.mutations) && prob(50))
user << "\red The rod slips out of your hand and hits your head."
diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm
index 6a773177c59..10898e80a47 100644
--- a/code/game/objects/structures/dresser.dm
+++ b/code/game/objects/structures/dresser.dm
@@ -6,47 +6,26 @@
density = 1
anchored = 1
-/obj/structure/dresser/proc/convUnM(mund)
- return underwear_m.Find(mund)
-
-/obj/structure/dresser/proc/convUnF(fund)
- return underwear_f.Find(fund)
-
-/obj/structure/dresser/proc/convUs(us)
- return undershirt_list.Find(us)
-
/obj/structure/dresser/attack_hand(mob/user as mob)
if(!Adjacent(user))//no tele-grooming
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
- var/choice = input(user, "Underwear, or Undershirt?", "Changing") as null|anything in list("Underwear","Undershirt")
+ var/choice = input(user, "Underwear or Undershirt?", "Changing") as null|anything in list("Underwear","Undershirt")
if(!Adjacent(user))
return
switch(choice)
if("Underwear")
- if(H.gender == FEMALE)
- var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in underwear_f
- if(new_undies)
- H << "\red You selected [new_undies]."
- var/freturn = convUnF(new_undies)
- H.underwear = freturn
-
- else
- var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in underwear_m
- if(new_undies)
- H << "\red You selected [new_undies]."
- var/mreturn = convUnM(new_undies)
- H.underwear = mreturn
+ var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in underwear_list
+ if(new_undies)
+ H.underwear = new_undies
if("Undershirt")
var/new_undershirt = input(user, "Select your undershirt", "Changing") as null|anything in undershirt_list
if(new_undershirt)
- H << "\red You selected [new_undershirt]"
- var/usreturn = convUs(new_undershirt)
- H.undershirt = usreturn
+ H.undershirt = new_undershirt
add_fingerprint(H)
H.update_body()
\ No newline at end of file
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 967b96d2c05..21208b26ca6 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -221,6 +221,14 @@
icon_state = ""
mineral = "plasma"
walltype = "plasma"
+
+/obj/structure/falsewall/plasma/attackby(obj/item/weapon/W, mob/user, params)
+ if(is_hot(W) > 300)
+ message_admins("Plasma falsewall ignited by [key_name_admin(user)] in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma falsewall ignited by [key_name(user)] in ([x],[y],[z])")
+ burnbabyburn()
+ return
+ ..()
/obj/structure/falsewall/plasma/proc/burnbabyburn(user)
playsound(src, 'sound/items/Welder.ogg', 100, 1)
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 69508a41940..3a792030371 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -194,10 +194,10 @@
mineralType = "plasma"
attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W,/obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = W
- if(WT.remove_fuel(0, user))
- TemperatureAct(100)
+ if(is_hot(W))
+ message_admins("Plasma mineral door ignited by [key_name_admin(user)] in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma mineral door ignited by [key_name(user)] in ([x],[y],[z])")
+ TemperatureAct(100)
..()
temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index 35c57a0f9f8..ee2b57d19d7 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -417,3 +417,51 @@
usr << "\red Access denied."
return
+/hook/Login/proc/update_morgue(var/client/client, var/mob/L)
+ //Update morgues on login/logout
+ if (L.stat == DEAD)
+ var/obj/structure/morgue/Morgue = null
+ var/mob/living/carbon/human/C = null
+ if (istype(L,/mob/dead/observer)) //We're a ghost, let's find our corpse
+ var/mob/dead/observer/G = L
+ if(!G.mind) //This'll probably break morgue sprites, but the line under the next If statement causes runtimes with Assume Direct Control.
+ return
+ if (G.can_reenter_corpse && G.mind.current)
+ C = G.mind.current
+ else if (istype(L,/mob/living/carbon/human))
+ C = L
+
+ if (C) //We found our corpse, is it inside a morgue?
+ if (istype(C.loc,/obj/structure/morgue))
+ Morgue = C.loc
+ else if (istype(C.loc,/obj/structure/closet/body_bag))
+ var/obj/structure/closet/body_bag/B = C.loc
+ if (istype(B.loc,/obj/structure/morgue))
+ Morgue = B.loc
+ if (Morgue)
+ Morgue.update()
+
+/hook/Logout/proc/update_morgue(var/client/client, var/mob/L)
+ //Update morgues on login/logout
+ if (L.stat == DEAD)
+ var/obj/structure/morgue/Morgue = null
+ var/mob/living/carbon/human/C = null
+ if (istype(L,/mob/dead/observer)) //We're a ghost, let's find our corpse
+ var/mob/dead/observer/G = L
+ if(!G.mind) //This'll probably break morgue sprites, but the line under the next If statement causes runtimes with Assume Direct Control.
+ return 1
+ if (G.can_reenter_corpse && G.mind.current)
+ C = G.mind.current
+ else if (istype(L,/mob/living/carbon/human))
+ C = L
+
+ if (C) //We found our corpse, is it inside a morgue?
+ if (istype(C.loc,/obj/structure/morgue))
+ Morgue = C.loc
+ else if (istype(C.loc,/obj/structure/closet/body_bag))
+ var/obj/structure/closet/body_bag/B = C.loc
+ if (istype(B.loc,/obj/structure/morgue))
+ Morgue = B.loc
+ if (Morgue)
+ Morgue.update()
+
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index 334086d5f36..956bc6d7d07 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -155,9 +155,9 @@
if(pulling)
occupant.visible_message("[pulling] has thrusted \the [name] into \the [A], throwing \the [occupant] out of it!")
- pulling.attack_log += "\[[time_stamp()]\] Crashed [occupant.name]'s ([occupant.ckey]) [name] into \a [A]"
- occupant.attack_log += "\[[time_stamp()]\] Thrusted into \a [A] by [pulling.name] ([pulling.ckey]) with \the [name]"
- msg_admin_attack("[pulling.name] ([pulling.ckey])[isAntag(pulling) ? "(ANTAG)" : ""] has thrusted [occupant.name]'s ([occupant.ckey]) [name] into \a [A] (JMP)")
+ pulling.attack_log += "\[[time_stamp()]\] Crashed [key_name(occupant)] [name] into \a [A]"
+ occupant.attack_log += "\[[time_stamp()]\] Thrusted into \a [A] by [key_name(pulling)] with \the [name]"
+ msg_admin_attack("[key_name_admin(pulling)] has thrusted [key_name_admin(occupant)] [name] into \a [A]")
else
occupant.visible_message("[occupant] crashed into \the [A]!")
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 06e878f5d2f..a0255e1344f 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -299,6 +299,10 @@
user.do_attack_animation(src)
visible_message("[user] slices [src] apart!")
destroy()
+
+/obj/structure/table/mech_melee_attack(obj/mecha/M)
+ visible_message("[M] smashes [src] apart!")
+ destroy()
/obj/structure/table/attack_animal(mob/living/simple_animal/user)
if(user.environment_smash)
@@ -905,13 +909,15 @@
W.Move(loc)
return
-/obj/structure/table/attack_hand(mob/user)
+/obj/structure/rack/attack_hand(mob/user)
if(HULK in user.mutations)
visible_message("[user] smashes [src] apart!")
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
destroy()
-
-
+
+/obj/structure/rack/mech_melee_attack(obj/mecha/M)
+ visible_message("[M] smashes [src] apart!")
+ destroy()
/obj/structure/rack/attack_alien(mob/living/user)
user.do_attack_animation(src)
diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm
index 1abfa6cfb31..d40539cdbf7 100644
--- a/code/game/supplyshuttle.dm
+++ b/code/game/supplyshuttle.dm
@@ -530,11 +530,11 @@ var/list/mechtoys = list(
/obj/machinery/computer/supplycomp/Topic(href, href_list)
if(!supply_controller)
- world.log << "## ERROR: Eek. The supply_controller controller datum is missing somehow."
+ log_to_dd("## ERROR: Eek. The supply_controller controller datum is missing somehow.")
return
var/datum/shuttle/ferry/supply/shuttle = supply_controller.shuttle
if (!shuttle)
- world.log << "## ERROR: Eek. The supply/shuttle datum is missing somehow."
+ log_to_dd("## ERROR: Eek. The supply/shuttle datum is missing somehow.")
return
if(..())
return
diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm
index 20d476238cb..1c2605238e0 100644
--- a/code/game/turfs/simulated/walls_mineral.dm
+++ b/code/game/turfs/simulated/walls_mineral.dm
@@ -89,6 +89,8 @@
/turf/simulated/wall/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(is_hot(W) > 300)//If the temperature of the object is over 300, then ignite
+ message_admins("Plasma wall ignited by [key_name_admin(user)] in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma wall ignited by [key_name(user)] in ([x],[y],[z])")
ignite(is_hot(W))
return
..()
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index 1cf5e73bc19..afbb84847f5 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -17,7 +17,7 @@ var/global/normal_ooc_colour = "#002eb8"
src << "\red You have OOC muted."
return
- if(!(holder && holder.rights && (holder.rights & R_MOD)))
+ if(!check_rights(R_MOD,0))
if(!ooc_allowed)
src << "\red OOC is globally muted"
return
@@ -141,9 +141,8 @@ var/global/normal_ooc_colour = "#002eb8"
if(!M.client)
continue
var/client/C = M.client
- if(C in admins)
- if(C.holder.rights | R_MENTOR)
- continue //they are handled after that
+ if(check_rights(R_MENTOR,0))
+ continue //they are handled after that
if(C.prefs.toggles & CHAT_LOOC)
if(holder)
@@ -160,7 +159,7 @@ var/global/normal_ooc_colour = "#002eb8"
display_name = "[S.name]/([S.key])"
for(var/client/C in admins)
- if(C.holder.rights | R_MENTOR)
+ if(check_rights(R_MENTOR,0))
if(C.prefs.toggles & CHAT_LOOC)
var/prefix = "(R)LOOC"
if (C.mob in heard)
diff --git a/code/modules/DetectiveWork/detective_work.dm b/code/modules/DetectiveWork/detective_work.dm
index 93c94aebf8e..01267f2fb08 100644
--- a/code/modules/DetectiveWork/detective_work.dm
+++ b/code/modules/DetectiveWork/detective_work.dm
@@ -17,19 +17,19 @@ atom/proc/add_fibers(mob/living/carbon/human/M)
if(M.wear_suit)
fibertext = "Material from \a [M.wear_suit]."
if(prob(10*item_multiplier) && !(fibertext in suit_fibers))
- //world.log << "Added fibertext: [fibertext]"
+ //log_to_dd("Added fibertext: [fibertext]")
suit_fibers += fibertext
if(!(M.wear_suit.body_parts_covered & UPPER_TORSO))
if(M.w_uniform)
fibertext = "Fibers from \a [M.w_uniform]."
if(prob(12*item_multiplier) && !(fibertext in suit_fibers)) //Wearing a suit means less of the uniform exposed.
- //world.log << "Added fibertext: [fibertext]"
+ //log_to_dd("Added fibertext: [fibertext]")
suit_fibers += fibertext
if(!(M.wear_suit.body_parts_covered & HANDS))
if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
- //world.log << "Added fibertext: [fibertext]"
+ //log_to_dd("Added fibertext: [fibertext]")
suit_fibers += fibertext
else if(M.w_uniform)
fibertext = "Fibers from \a [M.w_uniform]."
@@ -39,10 +39,10 @@ atom/proc/add_fibers(mob/living/carbon/human/M)
if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
- //world.log << "Added fibertext: [fibertext]"
+ //log_to_dd("Added fibertext: [fibertext]")
suit_fibers += "Material from a pair of [M.gloves.name]."
else if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
- //world.log << "Added fibertext: [fibertext]"
+ //log_to_dd("Added fibertext: [fibertext]")
suit_fibers += "Material from a pair of [M.gloves.name]."
\ No newline at end of file
diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm
index da0c6d64e60..8cd511a3c9a 100644
--- a/code/modules/admin/DB ban/functions.dm
+++ b/code/modules/admin/DB ban/functions.dm
@@ -48,7 +48,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
computerid = bancid
ip = banip
- var/DBQuery/query = dbcon.NewQuery("SELECT id FROM erro_player WHERE ckey = '[ckey]'")
+ var/DBQuery/query = dbcon.NewQuery("SELECT id FROM [format_table_name("player")] WHERE ckey = '[ckey]'")
query.Execute()
var/validckey = 0
if(query.NextRow())
@@ -83,7 +83,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
reason = sql_sanitize_text(reason)
- var/sql = "INSERT INTO erro_ban (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`) VALUES (null, Now(), '[serverip]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], [(rounds)?"[rounds]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', '[ip]', '[a_ckey]', '[a_computerid]', '[a_ip]', '[who]', '[adminwho]', '', null, null, null, null, null)"
+ var/sql = "INSERT INTO [format_table_name("ban")] (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`) VALUES (null, Now(), '[serverip]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], [(rounds)?"[rounds]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', '[ip]', '[a_ckey]', '[a_computerid]', '[a_ip]', '[who]', '[adminwho]', '', null, null, null, null, null)"
var/DBQuery/query_insert = dbcon.NewQuery(sql)
query_insert.Execute()
usr << "\blue Ban saved to database."
@@ -125,7 +125,7 @@ datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "")
else
bantype_sql = "bantype = '[bantype_str]'"
- var/sql = "SELECT id FROM erro_ban WHERE ckey = '[ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
+ var/sql = "SELECT id FROM [format_table_name("ban")] WHERE ckey = '[ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
if(job)
sql += " AND job = '[job]'"
@@ -166,7 +166,7 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
usr << "Cancelled"
return
- var/DBQuery/query = dbcon.NewQuery("SELECT ckey, duration, reason FROM erro_ban WHERE id = [banid]")
+ var/DBQuery/query = dbcon.NewQuery("SELECT ckey, duration, reason FROM [format_table_name("ban")] WHERE id = [banid]")
query.Execute()
var/eckey = usr.ckey //Editing admin ckey
@@ -194,7 +194,7 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
usr << "Cancelled"
return
- var/DBQuery/update_query = dbcon.NewQuery("UPDATE erro_ban SET reason = '[value]', edits = CONCAT(edits,'- [eckey] changed ban reason from \\\"[reason]\\\" to \\\"[value]\\\"
') WHERE id = [banid]")
+ var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("ban")] SET reason = '[value]', edits = CONCAT(edits,'- [eckey] changed ban reason from \\\"[reason]\\\" to \\\"[value]\\\"
') WHERE id = [banid]")
update_query.Execute()
message_admins("[key_name_admin(usr)] has edited a ban for [pckey]'s reason from [reason] to [value]",1)
if("duration")
@@ -204,7 +204,7 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
usr << "Cancelled"
return
- var/DBQuery/update_query = dbcon.NewQuery("UPDATE erro_ban SET duration = [value], edits = CONCAT(edits,'- [eckey] changed ban duration from [duration] to [value]
'), expiration_time = DATE_ADD(bantime, INTERVAL [value] MINUTE) WHERE id = [banid]")
+ var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("ban")] SET duration = [value], edits = CONCAT(edits,'- [eckey] changed ban duration from [duration] to [value]
'), expiration_time = DATE_ADD(bantime, INTERVAL [value] MINUTE) WHERE id = [banid]")
message_admins("[key_name_admin(usr)] has edited a ban for [pckey]'s duration from [duration] to [value]",1)
update_query.Execute()
if("unban")
@@ -222,7 +222,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
if(!check_rights(R_BAN)) return
- var/sql = "SELECT ckey FROM erro_ban WHERE id = [id]"
+ var/sql = "SELECT ckey FROM [format_table_name("ban")] WHERE id = [id]"
establish_db_connection()
if(!dbcon.IsConnected())
@@ -252,7 +252,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
var/unban_computerid = src.owner:computer_id
var/unban_ip = src.owner:address
- var/sql_update = "UPDATE erro_ban SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey = '[unban_ckey]', unbanned_computerid = '[unban_computerid]', unbanned_ip = '[unban_ip]' WHERE id = [id]"
+ var/sql_update = "UPDATE [format_table_name("ban")] SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey = '[unban_ckey]', unbanned_computerid = '[unban_computerid]', unbanned_ip = '[unban_ip]' WHERE id = [id]"
message_admins("[key_name_admin(usr)] has lifted [pckey]'s ban.",1)
var/DBQuery/query_update = dbcon.NewQuery(sql_update)
@@ -410,7 +410,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
bantypesearch += "'PERMABAN' "
- var/DBQuery/select_query = dbcon.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, ip, computerid FROM erro_ban WHERE 1 [playersearch] [adminsearch] [ipsearch] [cidsearch] [bantypesearch] ORDER BY bantime DESC LIMIT 100")
+ var/DBQuery/select_query = dbcon.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, ip, computerid FROM [format_table_name("ban")] WHERE 1 [playersearch] [adminsearch] [ipsearch] [cidsearch] [bantypesearch] ORDER BY bantime DESC LIMIT 100")
select_query.Execute()
while(select_query.NextRow())
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index 29f745a8c17..6f843bc148b 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -6,7 +6,7 @@ world/IsBanned(key,address,computer_id)
//Guest Checking
if(!guests_allowed && IsGuestKey(key))
log_access("Failed Login: [key] - Guests not allowed")
- message_admins("\blue Failed Login: [key] - Guests not allowed")
+ // message_admins("\blue Failed Login: [key] - Guests not allowed")
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")
//check if the IP address is a known TOR node
@@ -34,7 +34,7 @@ world/IsBanned(key,address,computer_id)
var/ckeytext = ckey(key)
if(!establish_db_connection())
- world.log << "Ban database connection failure. Key [ckeytext] not checked"
+ log_to_dd("Ban database connection failure. Key [ckeytext] not checked")
diary << "Ban database connection failure. Key [ckeytext] not checked"
return
@@ -51,7 +51,7 @@ world/IsBanned(key,address,computer_id)
failedcid = 0
cidquery = " OR computerid = '[computer_id]' "
- var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM erro_ban WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
+ var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM [format_table_name("ban")] WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
query.Execute()
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 050e21a8e17..060518108a1 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -44,7 +44,7 @@ var/global/nologevent = 0
body += "Options panel for [M]"
if(M.client)
body += " played by [M.client] "
- body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\]"
+ body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\]"
if(istype(M, /mob/new_player))
body += " Hasn't Entered Game "
@@ -64,7 +64,8 @@ var/global/nologevent = 0
Ban |
Jobban |
Appearance Ban |
- Notes
+ Notes |
+ Watchlist Flag
"}
if(M.client)
@@ -121,7 +122,7 @@ var/global/nologevent = 0
Make Mask |
Make Robot |
Make Alien |
- Make slime
+ Make Slime |
Make Superhero
"}
@@ -1006,7 +1007,6 @@ proc/formatPlayerPanel(var/mob/U,var/text="PP")
if (!frommob.ckey)
return 0
-
var/question = ""
if (tomob.ckey)
question = "This mob already has a user ([tomob.key]) in control of it! "
@@ -1029,4 +1029,5 @@ proc/formatPlayerPanel(var/mob/U,var/text="PP")
tomob.ckey = frommob.ckey
qdel(frommob)
- return 1
\ No newline at end of file
+ return 1
+
\ No newline at end of file
diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm
index 4323644b480..aea9f51f715 100644
--- a/code/modules/admin/admin_investigate.dm
+++ b/code/modules/admin/admin_investigate.dm
@@ -23,10 +23,10 @@
if(!message) return
var/F = investigate_subject2file(subject)
if(!F) return
- F << "[time2text(world.timeofday,"hh:mm")] \ref[src] ([x],[y],[z]) || [src] [message]
"
+ F << "[time_stamp()] \ref[src] ([x],[y],[z]) || [src] [message]
"
//ADMINVERBS
-/client/proc/investigate_show( subject in list("hrefs","pda","singulo","gold core","cult") )
+/client/proc/investigate_show( subject in list("hrefs","pda","singulo","atmos","ntsl","gold core","cult") )
set name = "Investigate"
set category = "Admin"
if(!holder) return
@@ -57,6 +57,20 @@
src << browse(F,"window=investigate[subject];size=800x300")
if("cult")
+ var/F = investigate_subject2file(subject)
+ 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")
+
+ if("atmos")
+ var/F = investigate_subject2file(subject)
+ 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")
+
+ if("ntsl")
var/F = investigate_subject2file(subject)
if(!F)
src << "Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed."
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index d9f5d7d54ba..236fbe42779 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -61,6 +61,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
//clear the datums references
admin_datums.Cut()
for(var/client/C in admins)
+ C.remove_admin_verbs()
C.holder = null
admins.Cut()
@@ -102,13 +103,13 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
establish_db_connection()
if(!dbcon.IsConnected())
- world.log << "Failed to connect to database in load_admins(). Reverting to legacy system."
+ log_to_dd("Failed to connect to database in load_admins(). Reverting to legacy system.")
diary << "Failed to connect to database in load_admins(). Reverting to legacy system."
config.admin_legacy_system = 1
load_admins()
return
- var/DBQuery/query = dbcon.NewQuery("SELECT ckey, rank, level, flags FROM erro_admin")
+ var/DBQuery/query = dbcon.NewQuery("SELECT ckey, rank, level, flags FROM [format_table_name("admin")]")
query.Execute()
while(query.NextRow())
var/ckey = query.item[1]
@@ -122,7 +123,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
//find the client for a ckey if they are connected and associate them with the new admin datum
D.associate(directory[ckey])
if(!admin_datums)
- world.log << "The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system."
+ log_to_dd("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
diary << "The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system."
config.admin_legacy_system = 1
load_admins()
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 71990e49d55..b5274601aa3 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -2,6 +2,7 @@
var/list/admin_verbs_default = list(
// /datum/admins/proc/show_player_panel, /*shows an interface for individual players, with various links (links require additional flags*/
/client/proc/deadmin_self, /*destroys our own admin datum so we can play as a regular player*/
+ /client/proc/hide_verbs, /*hides all our adminverbs*/
// /client/proc/check_antagonists, /*shows all antags*/
// /client/proc/deadchat /*toggles deadchat on/off*/
/client/proc/cmd_mentor_check_new_players
@@ -202,6 +203,48 @@ var/list/admin_verbs_mentor = list(
if(holder.rights & R_SPAWN) verbs += admin_verbs_spawn
if(holder.rights & R_MOD) verbs += admin_verbs_mod
if(holder.rights & R_MENTOR) verbs += admin_verbs_mentor
+
+/client/proc/remove_admin_verbs()
+ verbs.Remove(
+ admin_verbs_default,
+ /client/proc/togglebuildmodeself,
+ admin_verbs_admin,
+ admin_verbs_ban,
+ admin_verbs_event,
+ admin_verbs_server,
+ admin_verbs_debug,
+ admin_verbs_possess,
+ admin_verbs_permissions,
+ /client/proc/stealth,
+ admin_verbs_rejuv,
+ admin_verbs_sounds,
+ admin_verbs_spawn,
+ admin_verbs_mod,
+ admin_verbs_mentor,
+ admin_verbs_show_debug_verbs,
+ /client/proc/readmin,
+ )
+
+/client/proc/hide_verbs()
+ set name = "Adminverbs - Hide All"
+ set category = "Admin"
+
+ remove_admin_verbs()
+ verbs += /client/proc/show_verbs
+
+ src << "Almost all of your adminverbs have been hidden."
+ feedback_add_details("admin_verb","TAVVH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return
+
+/client/proc/show_verbs()
+ set name = "Adminverbs - Show"
+ set category = "Admin"
+
+ verbs -= /client/proc/show_verbs
+ add_admin_verbs()
+
+ src << "All of your adminverbs are now visible."
+ feedback_add_details("admin_verb","TAVVS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/admin_ghost()
set category = "Admin"
@@ -526,12 +569,61 @@ var/list/admin_verbs_mentor = list(
set category = "Admin"
if(holder)
- if(alert("Confirm self-deadmin for the round? You can't re-admin yourself without someont promoting you.",,"Yes","No") == "Yes")
- log_admin("[src] deadmined themself.")
- message_admins("[src] deadmined themself.", 1)
- deadmin()
- src << "You are now a normal player."
+ log_admin("[src] deadmined themself.")
+ message_admins("[src] deadmined themself.")
+ deadmin()
+ verbs += /client/proc/readmin
+ deadmins += ckey
+ src << "You are now a normal player."
feedback_add_details("admin_verb","DAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/readmin()
+ set name = "Re-admin self"
+ set category = "Admin"
+ set desc = "Regain your admin powers."
+ var/datum/admins/D = admin_datums[ckey]
+ var/rank = null
+ if(config.admin_legacy_system)
+ //load text from file
+ var/list/Lines = file2list("config/admins.txt")
+ for(var/line in Lines)
+ var/list/splitline = text2list(line, " - ")
+ if(n_lower(splitline[1]) == ckey)
+ if(splitline.len >= 2)
+ rank = ckeyEx(splitline[2])
+ break
+ continue
+ else
+ if(!dbcon.IsConnected())
+ message_admins("Warning, mysql database is not connected.")
+ src << "Warning, mysql database is not connected."
+ return
+ var/sql_ckey = sanitizeSQL(ckey)
+ var/DBQuery/query = dbcon.NewQuery("SELECT rank FROM [format_table_name("admin")] WHERE ckey = '[sql_ckey]'")
+ query.Execute()
+ while(query.NextRow())
+ rank = ckeyEx(query.item[1])
+ if(!D)
+ if(admin_ranks[rank] == null)
+ var/error_extra = ""
+ if(!config.admin_legacy_system)
+ error_extra = " Check mysql DB connection."
+ error("Error while re-adminning [src], admin rank ([rank]) does not exist.[error_extra]")
+ src << "Error while re-adminning, admin rank ([rank]) does not exist.[error_extra]"
+ return
+ D = new(rank,admin_ranks[rank],ckey)
+ var/client/C = directory[ckey]
+ D.associate(C)
+ message_admins("[src] re-adminned themselves.")
+ log_admin("[src] re-adminned themselves.")
+ deadmins -= ckey
+ feedback_add_details("admin_verb","RAS")
+ return
+ else
+ src << "You are already an admin."
+ verbs -= /client/proc/readmin
+ deadmins -= ckey
+ return
/client/proc/toggle_log_hrefs()
set name = "Toggle href logging"
diff --git a/code/modules/admin/banappearance.dm b/code/modules/admin/banappearance.dm
index 3262fb66219..7ecbde4c3fb 100644
--- a/code/modules/admin/banappearance.dm
+++ b/code/modules/admin/banappearance.dm
@@ -52,14 +52,14 @@ DEBUG
log_admin("appearance_keylist was empty")
else
if(!establish_db_connection())
- world.log << "Database connection failed. Reverting to the legacy ban system."
+ log_to_dd("Database connection failed. Reverting to the legacy ban system.")
diary << "Database connection failed. Reverting to the legacy ban system."
config.ban_legacy_system = 1
appearance_loadbanfile()
return
//appearance bans
- var/DBQuery/query = dbcon.NewQuery("SELECT ckey FROM erro_ban WHERE bantype = 'APPEARANCE_BAN' AND NOT unbanned = 1")
+ var/DBQuery/query = dbcon.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE bantype = 'APPEARANCE_BAN' AND NOT unbanned = 1")
query.Execute()
while(query.NextRow())
@@ -101,7 +101,7 @@ proc/DB_ban_isappearancebanned(var/playerckey)
var/sqlplayerckey = sql_sanitize_text(ckey(playerckey))
- var/DBQuery/query = dbcon.NewQuery("SELECT id FROM erro_ban WHERE CKEY = '[sqlplayerckey]' AND ((bantype = 'APPEARANCE_BAN') OR (bantype = 'APPEARANCE_TEMPBAN' AND expiration_time > Now())) AND unbanned != 1")
+ var/DBQuery/query = dbcon.NewQuery("SELECT id FROM [format_table_name("ban")] WHERE CKEY = '[sqlplayerckey]' AND ((bantype = 'APPEARANCE_BAN') OR (bantype = 'APPEARANCE_TEMPBAN' AND expiration_time > Now())) AND unbanned != 1")
query.Execute()
while(query.NextRow())
return 1
diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm
index 3ae14b22a31..a28de25ee39 100644
--- a/code/modules/admin/banjob.dm
+++ b/code/modules/admin/banjob.dm
@@ -64,14 +64,14 @@ DEBUG
log_admin("jobban_keylist was empty")
else
if(!establish_db_connection())
- world.log << "Database connection failed. Reverting to the legacy ban system."
+ log_to_dd("Database connection failed. Reverting to the legacy ban system.")
diary << "Database connection failed. Reverting to the legacy ban system."
config.ban_legacy_system = 1
jobban_loadbanfile()
return
//Job permabans
- var/DBQuery/query = dbcon.NewQuery("SELECT ckey, job FROM erro_ban WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)")
+ var/DBQuery/query = dbcon.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)")
query.Execute()
while(query.NextRow())
@@ -81,7 +81,7 @@ DEBUG
jobban_keylist.Add("[ckey] - [job]")
//Job tempbans
- var/DBQuery/query1 = dbcon.NewQuery("SELECT ckey, job FROM erro_ban WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()")
+ var/DBQuery/query1 = dbcon.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()")
query1.Execute()
while(query1.NextRow())
diff --git a/code/modules/admin/create_object.dm b/code/modules/admin/create_object.dm
index 5b5ee047852..584dd9331b6 100644
--- a/code/modules/admin/create_object.dm
+++ b/code/modules/admin/create_object.dm
@@ -1,4 +1,5 @@
-/var/create_object_html = null
+var/create_object_html = null
+var/list/create_object_forms = list(/obj, /obj/structure, /obj/machinery, /obj/effect, /obj/item, /obj/mecha, /obj/item/weapon, /obj/item/clothing, /obj/item/stack, /obj/item/device, /obj/item/weapon/reagent_containers, /obj/item/weapon/gun)
/datum/admins/proc/create_object(var/mob/user)
if (!create_object_html)
@@ -9,20 +10,14 @@
user << browse(replacetext(create_object_html, "/* ref src */", "\ref[src]"), "window=create_object;size=425x475")
-
/datum/admins/proc/quick_create_object(var/mob/user)
+ var/path = input("Select the path of the object you wish to create.", "Path", /obj) in create_object_forms
+ var/html_form = create_object_forms[path]
- var/quick_create_object_html = null
- var/pathtext = null
+ if (!html_form)
+ var/objectjs = list2text(typesof(path), ";")
+ html_form = file2text('html/create_object.html')
+ html_form = replacetext(html_form, "null /* object types */", "\"[objectjs]\"")
+ create_object_forms[path] = html_form
- pathtext = input("Select the path of the object you wish to create.", "Path", "/obj") in list("/obj","/obj/structure","/obj/item","/obj/item/weapon","/obj/item/clothing","/obj/machinery","/obj/mecha")
-
- var path = text2path(pathtext)
-
- if (!quick_create_object_html)
- var/objectjs = null
- objectjs = list2text(typesof(path), ";")
- quick_create_object_html = file2text('html/create_object.html')
- quick_create_object_html = replacetext(quick_create_object_html, "null /* object types */", "\"[objectjs]\"")
-
- user << browse(replacetext(quick_create_object_html, "/* ref src */", "\ref[src]"), "window=quick_create_object;size=425x475")
\ No newline at end of file
+ user << browse(replacetext(html_form, "/* ref src */", "\ref[src]"), "window=qco[path];size=425x475")
\ No newline at end of file
diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm
index 33fc2240830..17a2fc42239 100644
--- a/code/modules/admin/holder2.dm
+++ b/code/modules/admin/holder2.dm
@@ -28,11 +28,13 @@ var/list/admin_datums = list()
owner = C
owner.holder = src
owner.add_admin_verbs() //TODO
+ owner.verbs -= /client/proc/readmin
admins |= C
/datum/admins/proc/disassociate()
if(owner)
admins -= owner
+ owner.remove_admin_verbs()
owner.holder = null
owner = null
@@ -78,11 +80,17 @@ you will have to do something like if(client.holder.rights & R_ADMIN) yourself.
usr << "Error: Cannot proceed. They have more or equal rights to us."
return 0
-
-
/client/proc/deadmin()
admin_datums -= ckey
if(holder)
holder.disassociate()
del(holder)
return 1
+
+//This proc checks whether subject has at least ONE of the rights specified in rights_required.
+/proc/check_rights_for(client/subject, rights_required)
+ if(subject && subject.holder)
+ if(rights_required && !(rights_required & subject.holder.rights))
+ return 0
+ return 1
+ return 0
diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm
index fbd33cf0734..e53d4644c33 100644
--- a/code/modules/admin/permissionverbs/permissionedit.dm
+++ b/code/modules/admin/permissionverbs/permissionedit.dm
@@ -76,7 +76,7 @@
if(!istext(adm_ckey) || !istext(new_rank))
return
- var/DBQuery/select_query = dbcon.NewQuery("SELECT id FROM erro_admin WHERE ckey = '[adm_ckey]'")
+ var/DBQuery/select_query = dbcon.NewQuery("SELECT id FROM [format_table_name("admin")] WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/new_admin = 1
@@ -86,16 +86,16 @@
admin_id = text2num(select_query.item[1])
if(new_admin)
- var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO `erro_admin` (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, '[adm_ckey]', '[new_rank]', -1, 0)")
+ var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("admin")] (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, '[adm_ckey]', '[new_rank]', -1, 0)")
insert_query.Execute()
- var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');")
+ var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');")
log_query.Execute()
usr << "\blue New admin added."
else
if(!isnull(admin_id) && isnum(admin_id))
- var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET rank = '[new_rank]' WHERE id = [admin_id]")
+ var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET rank = '[new_rank]' WHERE id = [admin_id]")
insert_query.Execute()
- var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');")
+ var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');")
log_query.Execute()
usr << "\blue Admin rank changed."
@@ -128,7 +128,7 @@
if(!istext(adm_ckey) || !isnum(new_permission))
return
- var/DBQuery/select_query = dbcon.NewQuery("SELECT id, flags FROM erro_admin WHERE ckey = '[adm_ckey]'")
+ var/DBQuery/select_query = dbcon.NewQuery("SELECT id, flags FROM [format_table_name("admin")] WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/admin_id
@@ -141,14 +141,24 @@
return
if(admin_rights & new_permission) //This admin already has this permission, so we are removing it.
- var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET flags = [admin_rights & ~new_permission] WHERE id = [admin_id]")
+ var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = [admin_rights & ~new_permission] WHERE id = [admin_id]")
insert_query.Execute()
- var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');")
+ var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');")
log_query.Execute()
usr << "\blue Permission removed."
else //This admin doesn't have this permission, so we are adding it.
- var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]")
+ var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]")
insert_query.Execute()
- var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')")
+ var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')")
log_query.Execute()
- usr << "\blue Permission added."
\ No newline at end of file
+ usr << "\blue Permission added."
+
+/datum/admins/proc/updateranktodb(ckey,newrank)
+ establish_db_connection()
+ if (!dbcon.IsConnected())
+ return
+ var/sql_ckey = sanitizeSQL(ckey)
+ var/sql_admin_rank = sanitizeSQL(newrank)
+
+ var/DBQuery/query_update = dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastadminrank = '[sql_admin_rank]' WHERE ckey = '[sql_ckey]'")
+ query_update.Execute()
\ No newline at end of file
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 8d9a61b10e9..8873f385d90 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -81,9 +81,9 @@
body += "TP - "
body += "PM - "
body += "SM - "
- body += "JMP"
+ body += "FLW"
if(eyeref)
- body += "|EYE"
+ body += "|EYE"
body += "
"
if(antagonist > 0)
body += "Antagonist";
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index a0ce958a5f4..3336a2ad10d 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -160,6 +160,7 @@
admin_datums -= adm_ckey
D.disassociate()
+ updateranktodb(adm_ckey, "player")
message_admins("[key_name_admin(usr)] removed [adm_ckey] from the admins list")
log_admin("[key_name(usr)] removed [adm_ckey] from the admins list")
log_admin_rank_modification(adm_ckey, "Removed")
@@ -204,6 +205,7 @@
var/client/C = directory[adm_ckey] //find the client with the specified ckey (if they are logged in)
D.associate(C) //link up with the client and add verbs
+ updateranktodb(adm_ckey, new_rank)
message_admins("[key_name_admin(usr)] edited the admin rank of [adm_ckey] to [new_rank]")
log_admin("[key_name(usr)] edited the admin rank of [adm_ckey] to [new_rank]")
log_admin_rank_modification(adm_ckey, new_rank)
@@ -1032,6 +1034,63 @@
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."
+ 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)
+
else if(href_list["mute"])
if(!check_rights(R_MOD))
return
@@ -1452,6 +1511,17 @@
if(!isobserver(usr)) C.admin_ghost()
sleep(2)
C.jumptomob(M)
+
+ else if(href_list["adminplayerobservefollow"])
+ if(!check_rights(R_MOD,0) && !check_rights(R_ADMIN)) return
+
+ var/mob/M = locate(href_list["adminplayerobservefollow"])
+
+ var/client/C = usr.client
+ if(!isobserver(usr)) C.admin_ghost()
+ var/mob/dead/observer/A = C.mob
+ sleep(2)
+ A.ManualFollow(M)
else if(href_list["check_antagonist"])
check_antagonists()
@@ -1519,7 +1589,7 @@
src.owner << "Name = [M.name]; Real_name = [M.real_name]; Mind_name = [M.mind?"[M.mind.name]":""]; Key = [M.key];"
src.owner << "Location = [location_description];"
src.owner << "[special_role_description]"
- src.owner << "(PM) (PP) (VV) (SM) ([admin_jump_link(M, src)]) (CA)"
+ src.owner << "(PM) (PP) (VV) (SM) (FLW) (CA)"
else if(href_list["adminspawncookie"])
if(!check_rights(R_ADMIN|R_EVENT)) return
@@ -1935,28 +2005,13 @@
dirty_paths = href_list["object_list"]
var/paths = list()
- var/removed_paths = list()
for(var/dirty_path in dirty_paths)
var/path = text2path(dirty_path)
if(!path)
- removed_paths += dirty_path
continue
else if(!ispath(path, /obj) && !ispath(path, /turf) && !ispath(path, /mob))
- removed_paths += dirty_path
continue
- else if(ispath(path, /obj/item/weapon/gun/energy/pulse_rifle))
- if(!check_rights((R_SERVER|R_EVENT),0))
- removed_paths += dirty_path
- continue
- else if(ispath(path, /obj/item/weapon/melee/energy/blade))//Not an item one should be able to spawn./N
- if(!check_rights((R_SERVER|R_EVENT),0))
- removed_paths += dirty_path
- continue
- else if(ispath(path, /obj/effect/anomaly/bhole))
- if(!check_rights((R_SERVER|R_EVENT),0))
- removed_paths += dirty_path
- continue
paths += path
if(!paths)
@@ -1965,8 +2020,6 @@
if(length(paths) > 5)
alert("Select fewer object types, (max 5)")
return
- else if(length(removed_paths))
- alert("Removed:\n" + list2text(removed_paths, "\n"))
var/list/offset = text2list(href_list["offset"],",")
var/number = dd_range(1, 100, text2num(href_list["object_count"]))
@@ -1978,41 +2031,36 @@
if(!obj_dir || !(obj_dir in list(1,2,4,8,5,6,9,10)))
obj_dir = 2
var/obj_name = sanitize(href_list["object_name"])
+
+
+ var/atom/target //Where the object will be spawned
var/where = href_list["object_where"]
if (!( where in list("onfloor","inhand","inmarked") ))
where = "onfloor"
- if( where == "inhand" )
- usr << "Support for inhand not available yet. Will spawn on floor."
- where = "onfloor"
- if ( where == "inhand" ) //Can only give when human or monkey
- if ( !( ishuman(usr) ) )
- usr << "Can only spawn in hand when you're a human or a monkey."
- where = "onfloor"
- else if ( usr.get_active_hand() )
- usr << "Your active hand is full. Spawning on floor."
- where = "onfloor"
+ switch(where)
+ if("inhand")
+ if (!iscarbon(usr) && !isrobot(usr))
+ usr << "Can only spawn in hand when you're a carbon mob or cyborg."
+ where = "onfloor"
+ target = usr
- if ( where == "inmarked" )
- if ( !marked_datum )
- usr << "You don't have any object marked. Abandoning spawn."
- return
- else
- if ( !istype(marked_datum,/atom) )
- usr << "The object you have marked cannot be used as a target. Target must be of type /atom. Abandoning spawn."
- return
-
- var/atom/target //Where the object will be spawned
- switch ( where )
- if ( "onfloor" )
- switch (href_list["offset_type"])
+ if("onfloor")
+ switch(href_list["offset_type"])
if ("absolute")
target = locate(0 + X,0 + Y,0 + Z)
if ("relative")
target = locate(loc.x + X,loc.y + Y,loc.z + Z)
- if ( "inmarked" )
- target = marked_datum
+ if("inmarked")
+ if(!marked_datum)
+ usr << "You don't have any object marked. Abandoning spawn."
+ return
+ else if(!istype(marked_datum,/atom))
+ usr << "The object you have marked cannot be used as a target. Target must be of type /atom. Abandoning spawn."
+ return
+ else
+ target = marked_datum
if(target)
for (var/path in paths)
@@ -2020,9 +2068,8 @@
if(path in typesof(/turf))
var/turf/O = target
var/turf/N = O.ChangeTurf(path)
- if(N)
- if(obj_name)
- N.name = obj_name
+ if(N && obj_name)
+ N.name = obj_name
else
var/atom/O = new path(target)
if(O)
@@ -2032,18 +2079,30 @@
if(istype(O,/mob))
var/mob/M = O
M.real_name = obj_name
+ if(where == "inhand" && isliving(usr) && istype(O, /obj/item))
+ var/mob/living/L = usr
+ var/obj/item/I = O
+ L.put_in_hands(I)
+ if(isrobot(L))
+ var/mob/living/silicon/robot/R = L
+ if(R.module)
+ R.module.modules += I
+ I.loc = R.module
+ R.module.rebuild()
+ R.activate_module(I)
+ R.module.fix_modules()
if (number == 1)
log_admin("[key_name(usr)] created a [english_list(paths)]")
for(var/path in paths)
if(ispath(path, /mob))
- message_admins("[key_name_admin(usr)] created a [english_list(paths)]", 1)
+ message_admins("[key_name_admin(usr)] created a [english_list(paths)]")
break
else
log_admin("[key_name(usr)] created [number]ea [english_list(paths)]")
for(var/path in paths)
if(ispath(path, /mob))
- message_admins("[key_name_admin(usr)] created [number]ea [english_list(paths)]", 1)
+ message_admins("[key_name_admin(usr)] created [number]ea [english_list(paths)]")
break
return
@@ -2992,15 +3051,15 @@
if(isAI(target)) // AI core/eye follow links
var/mob/living/silicon/ai/A = target
- . = "JMP"
+ . = "FLW"
if(A.client && A.eyeobj) // No point following clientless AI eyes
- . += "|EYE"
+ . += "|EYE"
return
else if(istype(target, /mob/dead/observer))
var/mob/dead/observer/O = target
- . = "JMP"
+ . = "FLW"
if(O.mind && O.mind.current)
- . += "|BDY"
+ . += "|BDY"
return
else
- return "JMP"
+ return "FLW"
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 0a4b63a6892..1d7196c0d97 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -87,7 +87,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
mobs_found += found
if(!ai_found && isAI(found))
ai_found = 1
- msg += "[original_word] (?) "
+ msg += "[original_word] "
continue
msg += "[original_word] "
@@ -147,3 +147,31 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
send2adminirc("[selected_type] from [key_name(src)]: [original_msg]")
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
+
+/proc/send2irc_adminless_only(source, msg, requiredflags = R_BAN)
+ var/admin_number_total = 0 //Total number of admins
+ var/admin_number_afk = 0 //Holds the number of admins who are afk
+ var/admin_number_ignored = 0 //Holds the number of admins without +BAN (so admins who are not really admins)
+ var/admin_number_decrease = 0 //Holds the number of admins with are afk, ignored or both
+ for(var/client/X in admins)
+ admin_number_total++;
+ var/invalid = 0
+ if(requiredflags != 0 && !check_rights_for(X, requiredflags))
+ admin_number_ignored++
+ invalid = 1
+ if(X.is_afk())
+ admin_number_afk++
+ invalid = 1
+ if(X.holder.fakekey)
+ admin_number_ignored++
+ invalid = 1
+ if(invalid)
+ admin_number_decrease++
+ var/admin_number_present = admin_number_total - admin_number_decrease //Number of admins who are neither afk nor invalid
+ if(admin_number_present <= 0)
+ if(!admin_number_afk && !admin_number_ignored)
+ send2irc(source, "[msg] - No admins online")
+ else
+ send2irc(source, "[msg] - All admins AFK ([admin_number_afk]/[admin_number_total]) or skipped ([admin_number_ignored]/[admin_number_total])")
+ return admin_number_present
+
\ No newline at end of file
diff --git a/code/modules/admin/verbs/check_customitem_activity.dm b/code/modules/admin/verbs/check_customitem_activity.dm
index 19dfd6bbdce..18a796a0b08 100644
--- a/code/modules/admin/verbs/check_customitem_activity.dm
+++ b/code/modules/admin/verbs/check_customitem_activity.dm
@@ -55,7 +55,7 @@ var/inactive_keys = "None
"
//run a query to get all ckeys inactive for over 2 months
var/list/inactive_ckeys = list()
if(ckeys_with_customitems.len)
- var/DBQuery/query_inactive = dbcon.NewQuery("SELECT ckey, lastseen FROM erro_player WHERE datediff(Now(), lastseen) > 60")
+ var/DBQuery/query_inactive = dbcon.NewQuery("SELECT ckey, lastseen FROM [format_table_name("player")] WHERE datediff(Now(), lastseen) > 60")
query_inactive.Execute()
while(query_inactive.NextRow())
var/cur_ckey = query_inactive.item[1]
@@ -67,7 +67,7 @@ var/inactive_keys = "None
"
//if there are ckeys left over, check whether they have a database entry at all
if(ckeys_with_customitems.len)
for(var/cur_ckey in ckeys_with_customitems)
- var/DBQuery/query_inactive = dbcon.NewQuery("SELECT ckey FROM erro_player WHERE ckey = '[cur_ckey]'")
+ var/DBQuery/query_inactive = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[cur_ckey]'")
query_inactive.Execute()
if(!query_inactive.RowCount())
inactive_ckeys += cur_ckey
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 18729e36a79..eb6b02cc626 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -1103,7 +1103,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M.regenerate_icons()
log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].")
- message_admins("\blue [key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode]..", 1)
+ message_admins("\blue [key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode].", 1)
return
/client/proc/startSinglo()
diff --git a/code/modules/admin/verbs/honksquad.dm b/code/modules/admin/verbs/honksquad.dm
index 9b383a93d17..e64cbf66574 100644
--- a/code/modules/admin/verbs/honksquad.dm
+++ b/code/modules/admin/verbs/honksquad.dm
@@ -79,13 +79,13 @@ var/global/sent_honksquad = 0
var/honksquad_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/honksquad_name = pick(clown_names)
- new_honksquad.gender = pick(MALE, FEMALE)
-
var/datum/preferences/A = new()//Randomize appearance for the commando.
- A.randomize_appearance_for(new_honksquad)
-
- new_honksquad.real_name = "[!honk_leader_selected ? honksquad_rank : honksquad_leader_rank] [honksquad_name]"
- new_honksquad.age = !honk_leader_selected ? rand(23,35) : rand(35,45)
+ if(honk_leader_selected)
+ A.age = rand(35,45)
+ A.real_name = "[honksquad_leader_rank] [honksquad_name]"
+ else
+ A.real_name = "[honksquad_rank] [honksquad_name]"
+ A.copy_to(new_honksquad)
new_honksquad.dna.ready_dna(new_honksquad)//Creates DNA.
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 319c76a6974..5acf6c21b44 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -118,33 +118,37 @@ var/intercom_range_display_status = 0
del(F)
feedback_add_details("admin_verb","mIRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+var/list/admin_verbs_show_debug_verbs = list(
+ /client/proc/camera_view, //-errorage
+ /client/proc/sec_camera_report, //-errorage
+ /client/proc/intercom_view, //-errorage
+ /client/proc/Cell, //More air things
+ /client/proc/atmosscan, //check plumbing
+ /client/proc/powerdebug, //check power
+ /client/proc/count_objects_on_z_level,
+ /client/proc/count_objects_all,
+ /client/proc/cmd_assume_direct_control, //-errorage
+ /client/proc/startSinglo,
+ /client/proc/ticklag,
+ /client/proc/cmd_admin_grantfullaccess,
+// /client/proc/splash,
+ /client/proc/cmd_admin_areatest,
+ /client/proc/cmd_admin_rejuvenate,
+ /datum/admins/proc/show_traitor_panel,
+ /client/proc/print_jobban_old,
+ /client/proc/print_jobban_old_filter,
+ /client/proc/forceEvent,
+ ///client/proc/cmd_admin_rejuvenate,
+ /client/proc/nanomapgen_DumpImage
+)
+
/client/proc/enable_debug_verbs()
set category = "Debug"
set name = "Debug verbs"
if(!check_rights(R_DEBUG)) return
- src.verbs += /client/proc/camera_view //-errorage
- src.verbs += /client/proc/sec_camera_report //-errorage
- src.verbs += /client/proc/intercom_view //-errorage
- src.verbs += /client/proc/Cell //More air things
- src.verbs += /client/proc/atmosscan //check plumbing
- src.verbs += /client/proc/powerdebug //check power
- src.verbs += /client/proc/count_objects_on_z_level
- src.verbs += /client/proc/count_objects_all
- src.verbs += /client/proc/cmd_assume_direct_control //-errorage
- src.verbs += /client/proc/startSinglo
- src.verbs += /client/proc/ticklag
- src.verbs += /client/proc/cmd_admin_grantfullaccess
-// src.verbs += /client/proc/splash
- src.verbs += /client/proc/cmd_admin_areatest
- src.verbs += /client/proc/cmd_admin_rejuvenate
- src.verbs += /datum/admins/proc/show_traitor_panel
- src.verbs += /client/proc/print_jobban_old
- src.verbs += /client/proc/print_jobban_old_filter
- src.verbs += /client/proc/forceEvent
- //src.verbs += /client/proc/cmd_admin_rejuvenate
- src.verbs += /client/proc/nanomapgen_DumpImage
+ verbs += admin_verbs_show_debug_verbs
feedback_add_details("admin_verb","mDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm
index abca2a40d33..b49a0fe609a 100644
--- a/code/modules/admin/verbs/modifyvariables.dm
+++ b/code/modules/admin/verbs/modifyvariables.dm
@@ -546,7 +546,7 @@ var/list/forbidden_varedit_object_types = list(
if("marked datum")
O.vars[variable] = holder.marked_datum
- world.log << "### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]"
+ log_to_dd("### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]")
log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]", 1)
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index 6bb2f96ba06..93e5bb5c078 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -396,16 +396,8 @@ client/proc/one_click_antag()
//First we spawn a dude.
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
- new_character.gender = pick(MALE,FEMALE)
-
var/datum/preferences/A = new()
- A.randomize_appearance_for(new_character)
- if(new_character.gender == MALE)
- new_character.real_name = "[pick(first_names_male)] [pick(last_names)]"
- else
- new_character.real_name = "[pick(first_names_female)] [pick(last_names)]"
- new_character.name = new_character.real_name
- new_character.age = rand(17,45)
+ A.copy_to(new_character)
new_character.dna.ready_dna(new_character)
new_character.key = G_found.key
@@ -418,14 +410,13 @@ client/proc/one_click_antag()
var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/syndicate_commando_name = pick(last_names)
- new_syndicate_commando.gender = pick(MALE, FEMALE)
-
var/datum/preferences/A = new()//Randomize appearance for the commando.
- A.randomize_appearance_for(new_syndicate_commando)
-
- new_syndicate_commando.real_name = "[!syndicate_leader_selected ? syndicate_commando_rank : syndicate_commando_leader_rank] [syndicate_commando_name]"
- new_syndicate_commando.name = new_syndicate_commando.real_name
- new_syndicate_commando.age = !syndicate_leader_selected ? rand(23,35) : rand(35,45)
+ if(syndicate_leader_selected)
+ A.real_name = "[syndicate_commando_leader_rank] [syndicate_commando_name]"
+ A.age = rand(35,45)
+ else
+ A.real_name = "[syndicate_commando_rank] [syndicate_commando_name]"
+ A.copy_to(new_syndicate_commando)
new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA.
@@ -610,14 +601,7 @@ client/proc/one_click_antag()
var/mob/living/carbon/human/newMember = new(L.loc)
- newMember.gender = pick(MALE,FEMALE)
- A.randomize_appearance_for(newMember)
- if(newMember.gender == MALE)
- newMember.real_name = "[pick(first_names_male)] [pick(last_names)]"
- else
- newMember.real_name = "[pick(first_names_female)] [pick(last_names)]"
- newMember.name = newMember.real_name
- newMember.age = rand(17,45)
+ A.copy_to(newMember)
newMember.dna.ready_dna(newMember)
@@ -639,14 +623,7 @@ client/proc/one_click_antag()
var/mob/living/carbon/human/newMember = new(L.loc)
- newMember.gender = pick(MALE,FEMALE)
- A.randomize_appearance_for(newMember)
- if(newMember.gender == MALE)
- newMember.real_name = "[pick(first_names_male)] [pick(last_names)]"
- else
- newMember.real_name = "[pick(first_names_female)] [pick(last_names)]"
- newMember.name = newMember.real_name
- newMember.age = rand(17,45)
+ A.copy_to(newMember)
newMember.dna.ready_dna(newMember)
diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm
index 5560b5438ad..2985f05aab8 100644
--- a/code/modules/admin/verbs/pray.dm
+++ b/code/modules/admin/verbs/pray.dm
@@ -26,7 +26,7 @@
/proc/Centcomm_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
- msg = "\blue CENTCOMM:[key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (RPLY): [msg]"
+ msg = "\blue CENTCOMM: [key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (RPLY): [msg]"
for(var/client/X in admins)
if(R_EVENT & X.holder.rights)
@@ -34,7 +34,7 @@
/proc/Syndicate_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
- msg = "\blue SYNDICATE: [key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (REPLY): [msg]"
+ msg = "\blue SYNDICATE: [key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (REPLY): [msg]"
for(var/client/X in admins)
if(R_EVENT & X.holder.rights)
@@ -42,7 +42,7 @@
/proc/HONK_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
- msg = "\blue HONK:[key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (RPLY): [msg]"
+ msg = "\blue HONK: [key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (RPLY): [msg]"
for(var/client/X in admins)
if(R_EVENT & X.holder.rights)
@@ -50,8 +50,15 @@
/proc/ERT_Announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
- msg = "\blue ERT REQUEST:[key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (REPLY): [msg]"
+ msg = "\blue ERT REQUEST: [key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (REPLY): [msg]"
for(var/client/X in admins)
if(R_EVENT & X.holder.rights)
- X << msg
\ No newline at end of file
+ X << msg
+
+/proc/Nuke_request(text , mob/Sender)
+ var/nuke_code = get_nuke_code()
+ var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
+ msg = "NUKE CODE REQUEST: [key_name(Sender)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (RPLY): [msg]"
+ admins << msg
+ admins << "The nuke code is [nuke_code]."
\ No newline at end of file
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index feb735baef2..088e9c7a050 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -433,14 +433,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
else
new_character.gender = pick(MALE,FEMALE)
var/datum/preferences/A = new()
- A.randomize_appearance_for(new_character)
- new_character.real_name = G_found.real_name
+ A.real_name = G_found.real_name
+ A.copy_to(new_character)
if(!new_character.real_name)
- if(new_character.gender == MALE)
- new_character.real_name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
- else
- new_character.real_name = capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
+ new_character.real_name = random_name(new_character.gender)
new_character.name = new_character.real_name
if(G_found.mind && !G_found.mind.active)
@@ -911,10 +908,13 @@ Traitors and the like can also be revived with the previous role mostly intact.
choice = input("The shuttle will not be able to leave if you call it. Call anyway?") in list("Confirm", "Cancel")
if(choice != "Confirm")
return
+
+
choice = input("Is this an emergency evacuation or a crew transfer?") in list("Emergency", "Crew Transfer")
if (choice == "Emergency")
- emergency_shuttle.call_evac()
+ var/reason = input(usr, "Optional: Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","") as text|null
+ emergency_shuttle.call_evac(reason)
else
emergency_shuttle.call_transfer()
diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm
index 347f461dca8..c4fda49439a 100644
--- a/code/modules/admin/verbs/striketeam.dm
+++ b/code/modules/admin/verbs/striketeam.dm
@@ -104,13 +104,13 @@ var/global/sent_strike_team = 0
var/commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/commando_name = pick(last_names)
- new_commando.gender = pick(MALE, FEMALE)
-
var/datum/preferences/A = new()//Randomize appearance for the commando.
- A.randomize_appearance_for(new_commando)
-
- new_commando.real_name = "[!leader_selected ? commando_rank : commando_leader_rank] [commando_name]"
- new_commando.age = !leader_selected ? rand(23,35) : rand(35,45)
+ if(leader_selected)
+ A.age = rand(35,45)
+ A.real_name = "[commando_leader_rank] [commando_name]"
+ else
+ A.real_name = "[commando_rank] [commando_name]"
+ A.copy_to(new_commando)
new_commando.dna.ready_dna(new_commando)//Creates DNA.
diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm
index 3113e58c2be..42a635feafb 100644
--- a/code/modules/admin/verbs/striketeam_syndicate.dm
+++ b/code/modules/admin/verbs/striketeam_syndicate.dm
@@ -108,13 +108,13 @@ var/global/sent_syndicate_strike_team = 0
var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
var/syndicate_commando_name = pick(last_names)
- new_syndicate_commando.gender = pick(MALE, FEMALE)
-
var/datum/preferences/A = new()//Randomize appearance for the commando.
- A.randomize_appearance_for(new_syndicate_commando)
-
- new_syndicate_commando.real_name = "[!syndicate_leader_selected ? syndicate_commando_rank : syndicate_commando_leader_rank] [syndicate_commando_name]"
- new_syndicate_commando.age = !syndicate_leader_selected ? rand(23,35) : rand(35,45)
+ if(syndicate_leader_selected)
+ A.age = rand(35,45)
+ A.real_name = "[syndicate_commando_leader_rank] [syndicate_commando_name]"
+ else
+ A.real_name = "[syndicate_commando_rank] [syndicate_commando_name]"
+ A.copy_to(new_syndicate_commando)
new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA.
diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm
index f773d23229f..2b0e72aaade 100644
--- a/code/modules/assembly/timer.dm
+++ b/code/modules/assembly/timer.dm
@@ -53,7 +53,7 @@
process()
if(timing && (time > 0))
- time--
+ time -= 2 // 2 seconds per process()
if(timing && time <= 0)
timing = repeat
timer_end()
@@ -110,6 +110,10 @@
if(href_list["time"])
timing = !timing
+ if(timing && istype(holder, /obj/item/device/transfer_valve))
+ message_admins("[key_name_admin(usr)] activated [src] attachment on [holder].")
+ bombers += "[key_name(usr)] activated [src] attachment for [loc]"
+ log_game("[key_name(usr)] activated [src] attachment for [loc]")
update_icon()
if(href_list["reset"])
time = set_time
@@ -120,7 +124,7 @@
if(href_list["tp"])
var/tp = text2num(href_list["tp"])
set_time += tp
- set_time = min(max(round(set_time), 5), 600)
+ set_time = min(max(round(set_time), 6), 600)
if(!timing)
time = set_time
diff --git a/code/modules/awaymissions/bluespaceartillery.dm b/code/modules/awaymissions/bluespaceartillery.dm
index 03509d38ac3..76a0e4d490b 100644
--- a/code/modules/awaymissions/bluespaceartillery.dm
+++ b/code/modules/awaymissions/bluespaceartillery.dm
@@ -1,15 +1,59 @@
-
-/obj/machinery/artillerycontrol
- var/reload = 180
+/obj/machinery/computer/artillerycontrol
name = "bluespace artillery control"
- icon_state = "control_boxp1"
- icon = 'icons/obj/machines/particle_accelerator.dmi'
- density = 1
- anchored = 1
+ icon_screen = "accelerator"
+ icon_keyboard = "accelerator_key"
+ icon_state = "computer-wires"
+ req_access = list(access_cent_commander)
+ var/last_fire = 0
+ var/reload_cooldown = 180 // 3 minute cooldown
+
+ light_color = LIGHT_COLOR_LIGHTBLUE
-/obj/machinery/artillerycontrol/process()
- if(src.reload<180)
- src.reload++
+/obj/machinery/computer/artillerycontrol/attack_ai(user as mob)
+ user << "Access denied."
+ return
+
+/obj/machinery/computer/artillerycontrol/attack_hand(user as mob)
+ ui_interact(user)
+
+/obj/machinery/computer/artillerycontrol/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ var/data[0]
+ var/time_to_wait = round(reload_cooldown - ((world.time / 10) - last_fire), 1)
+ var/mins = round(time_to_wait / 60)
+ var/seconds = time_to_wait - (60*mins)
+ data["reloadtime_mins"] = mins
+ data["reloadtime_secs"] = (seconds < 10) ? "0[seconds]" : seconds
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+
+ if (!ui)
+ ui = new(user, src, ui_key, "bluespace_artillery.tmpl", "Bluespace Control", 400, 260)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(1)
+
+/obj/machinery/computer/artillerycontrol/Topic(href, href_list)
+ if(..())
+ return 1
+
+ var/A
+ A = input("Area to jump bombard", "Open Fire", A) in teleportlocs
+ var/area/thearea = teleportlocs[A]
+ if(..() || !istype(thearea))
+ return
+
+ var/delta = (world.time / 10) - last_fire
+ if(reload_cooldown > delta)
+ return 1
+
+ command_announcement.Announce("Bluespace artillery fire detected. Brace for impact.")
+ message_admins("[key_name_admin(usr)] has launched an artillery strike.", 1)
+ var/list/L = list()
+ for(var/turf/T in get_area_turfs(thearea.type))
+ L+=T
+ var/loc = pick(L)
+ explosion(loc,2,5,11)
+ last_fire = world.time / 10
/obj/structure/artilleryplaceholder
name = "artillery"
@@ -19,47 +63,3 @@
/obj/structure/artilleryplaceholder/decorative
density = 0
-
-/obj/machinery/artillerycontrol/attack_hand(mob/user as mob)
- user.set_machine(src)
- var/dat = "Bluespace Artillery Control:
"
- dat += "Locked on
"
- dat += "Charge progress: [reload]/180:
"
- dat += "Open Fire
"
- dat += "Deployment of weapon authorized by
Nanotrasen Naval Command
Remember, friendly fire is grounds for termination of your contract and life.
"
- user << browse(dat, "window=scroll")
- onclose(user, "scroll")
- return
-
-/obj/machinery/artillerycontrol/Topic(href, href_list)
- ..()
- if (usr.stat || usr.restrained())
- return
- if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
- var/A
- A = input("Area to jump bombard", "Open Fire", A) in teleportlocs
- var/area/thearea = teleportlocs[A]
- if (usr.stat || usr.restrained()) return
- if(src.reload < 180) return
- if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
- command_announcement.Announce("Bluespace artillery fire detected. Brace for impact.")
- message_admins("[key_name_admin(usr)] has launched an artillery strike.", 1)
- var/list/L = list()
- for(var/turf/T in get_area_turfs(thearea.type))
- L+=T
- var/loc = pick(L)
- explosion(loc,2,5,11)
- reload = 0
-
-/*mob/proc/openfire()
- var/A
- A = input("Area to jump bombard", "Open Fire", A) in teleportlocs
- var/area/thearea = teleportlocs[A]
- command_announcement.Announce("Bluespace artillery fire detected. Brace for impact.")
- spawn(30)
- var/list/L = list()
-
- for(var/turf/T in get_area_turfs(thearea.type))
- L+=T
- var/loc = pick(L)
- explosion(loc,2,5,11)*/
\ No newline at end of file
diff --git a/code/modules/awaymissions/maploader/swapmaps.dm b/code/modules/awaymissions/maploader/swapmaps.dm
index a53bd552329..8f15d071b0f 100644
--- a/code/modules/awaymissions/maploader/swapmaps.dm
+++ b/code/modules/awaymissions/maploader/swapmaps.dm
@@ -585,7 +585,7 @@ proc/SwapMaps_CreateFromTemplate(template_id)
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[template_id].txt"))
text=1
else
- world.log << "SwapMaps error in SwapMaps_CreateFromTemplate(): map_[template_id] file not found."
+ log_to_dd("SwapMaps error in SwapMaps_CreateFromTemplate(): map_[template_id] file not found.")
return
if(text)
S=new
@@ -612,7 +612,7 @@ proc/SwapMaps_LoadChunk(chunk_id,turf/locorner)
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[chunk_id].txt"))
text=1
else
- world.log << "SwapMaps error in SwapMaps_LoadChunk(): map_[chunk_id] file not found."
+ log_to_dd("SwapMaps error in SwapMaps_LoadChunk(): map_[chunk_id] file not found.")
return
if(text)
S=new
@@ -630,9 +630,9 @@ proc/SwapMaps_LoadChunk(chunk_id,turf/locorner)
proc/SwapMaps_SaveChunk(chunk_id,turf/corner1,turf/corner2)
if(!corner1 || !corner2)
- world.log << "SwapMaps error in SwapMaps_SaveChunk():"
- if(!corner1) world.log << " corner1 turf is null"
- if(!corner2) world.log << " corner2 turf is null"
+ log_to_dd("SwapMaps error in SwapMaps_SaveChunk():")
+ if(!corner1) log_to_dd(" corner1 turf is null")
+ if(!corner2) log_to_dd(" corner2 turf is null")
return
var/swapmap/M=new
M.id=chunk_id
@@ -659,7 +659,7 @@ proc/SwapMaps_GetSize(id)
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[id].txt"))
text=1
else
- world.log << "SwapMaps error in SwapMaps_GetSize(): map_[id] file not found."
+ log_to_dd("SwapMaps error in SwapMaps_GetSize(): map_[id] file not found.")
return
if(text)
S=new
diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm
index 51b66024215..06689601523 100644
--- a/code/modules/awaymissions/zlevel.dm
+++ b/code/modules/awaymissions/zlevel.dm
@@ -44,7 +44,7 @@ proc/createRandomZlevel()
if(air_master)
air_master.setup_allturfs(block(locate(1, 1, world.maxz), locate(world.maxx, world.maxy, world.maxz)))
create_lighting_overlays(world.maxz)
- world.log << "away mission loaded: [map]"
+ log_to_dd("away mission loaded: [map]")
for(var/obj/effect/landmark/L in landmarks_list)
if (L.name != "awaystart")
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 2efc59f66c5..80c4114059a 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -31,7 +31,7 @@
//search the href for script injection
if( findtext(href,"