diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index afb8adfa849..48ccd7f83e6 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -393,8 +393,8 @@
"ahC" = (/obj/structure/table,/obj/item/weapon/paper,/obj/item/weapon/pen,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/security/permabrig)
"ahD" = (/obj/structure/stool/bed,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/security/permabrig)
"ahE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/permabrig)
-"ahF" = (/obj/item/weapon/restraints/handcuffs/pinkcuffs,/turf/simulated/floor/plating,/area/security/permabrig)
-"ahG" = (/obj/item/clothing/mask/muzzle/gag,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/security/permabrig)
+"ahF" = (/turf/space,/area/shuttle/gamma/station)
+"ahG" = (/obj/structure/table,/obj/effect/decal/warning_stripes/red/hollow,/obj/item/weapon/storage/toolbox/mechanical,/obj/item/device/lock_buster,/obj/machinery/light{dir = 1; on = 1},/obj/item/device/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/obj/item/weapon/storage/box/chemimp{pixel_x = 4; pixel_y = 3},/obj/item/weapon/storage/box/trackimp,/obj/item/weapon/storage/lockbox/mindshield,/turf/simulated/floor/plasteel,/area/security/armoury)
"ahH" = (/obj/machinery/deployable/barrier,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/armoury)
"ahI" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/shuttle/plating/vox,/area/shuttle/vox)
"ahJ" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id_tag = "voxshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end (EAST)"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 4},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox)
@@ -422,7 +422,7 @@
"aif" = (/obj/machinery/deployable/barrier,/obj/structure/window/reinforced{dir = 8},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 10},/area/security/armoury)
"aig" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/permabrig)
"aih" = (/turf/simulated/wall/r_wall,/area/security/hos)
-"aii" = (/obj/structure/table,/obj/effect/decal/warning_stripes/red/hollow,/obj/item/weapon/storage/toolbox/mechanical,/obj/item/device/lock_buster,/obj/machinery/light{dir = 1; on = 1},/obj/item/device/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel,/area/security/armoury)
+"aii" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/permabrig)
"aij" = (/obj/machinery/deployable/barrier,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{dir = 6; icon_state = "red"},/area/security/armoury)
"aik" = (/obj/machinery/flasher/portable,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{dir = 6; icon_state = "red"},/area/security/armoury)
"ail" = (/turf/simulated/shuttle/plating/vox,/area/shuttle/vox)
@@ -434,9 +434,9 @@
"air" = (/obj/effect/decal/warning_stripes/west,/obj/effect/decal/warning_stripes/east,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/securearmoury)
"ais" = (/obj/machinery/door/airlock{name = "Toilet"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/security/vacantoffice{name = "\improper Security Toilet"})
"ait" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/permabrig)
-"aiu" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/permabrig)
+"aiu" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig)
"aiv" = (/turf/simulated/wall/r_wall,/area/security/securearmoury)
-"aiw" = (/obj/machinery/power/apc{cell_type = 5000; dir = 8; name = "west bump Important Area"; pixel_x = -24; shock_proof = 0},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/armoury)
+"aiw" = (/obj/machinery/power/apc{cell_type = 5000; dir = 8; name = "west bump Important Area"; pixel_x = -24; shock_proof = 0},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/obj/machinery/camera{c_tag = "Brig Armory"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/armoury)
"aix" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel,/area/security/armoury)
"aiy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/armoury)
"aiz" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 4},/area/security/armoury)
@@ -472,7 +472,7 @@
"ajd" = (/obj/item/weapon/storage/toolbox/syndicate,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
"aje" = (/obj/item/weapon/skeleton/r_arm,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox)
"ajf" = (/obj/structure/stool/bed,/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/execution{name = "\improper Prisoner Transfer Center"})
-"ajg" = (/obj/structure/rack,/obj/item/weapon/storage/box/chemimp{pixel_x = 4; pixel_y = 3},/obj/item/weapon/storage/box/trackimp,/obj/effect/decal/warning_stripes/red/hollow,/obj/item/weapon/storage/lockbox/mindshield,/obj/machinery/light_switch{pixel_x = -25},/obj/machinery/camera{c_tag = "Brig Armory"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/armoury)
+"ajg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/permabrig)
"ajh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/armoury)
"aji" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 101; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/armoury)
"ajj" = (/obj/effect/decal/warning_stripes/north,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/securearmoury)
@@ -527,7 +527,7 @@
"akg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"})
"akh" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"})
"aki" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/permabrig)
-"akj" = (/obj/structure/rack,/obj/item/weapon/storage/box/seccarts{pixel_x = 3; pixel_y = 2},/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/flashbangs{pixel_x = -2; pixel_y = -2},/obj/item/weapon/storage/box/handcuffs,/obj/effect/decal/warning_stripes/red/hollow,/obj/item/weapon/storage/box/teargas{pixel_x = -3; pixel_y = -3},/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/armoury)
+"akj" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig)
"akk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/armoury)
"akl" = (/obj/machinery/door/airlock/security{name = "Warden's office"; req_access = null; req_access_txt = "3"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/armoury)
"akm" = (/obj/effect/decal/warning_stripes/northwestcorner,/obj/effect/decal/warning_stripes/northeastcorner,/obj/machinery/atmospherics/unary/vent_pump{on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/securearmoury)
@@ -737,7 +737,7 @@
"aoi" = (/obj/effect/landmark/start{name = "Brig Physician"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/medbay)
"aoj" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/security/medbay)
"aok" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/medbay)
-"aol" = (/turf/simulated/floor/plasteel,/area/shuttle/gamma/station)
+"aol" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/permabrig)
"aom" = (/turf/simulated/wall,/area/security/prisonlockers)
"aon" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/medbay)
"aoo" = (/obj/structure/table/glass,/obj/machinery/computer/med_data/laptop,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/security/medbay)
@@ -1720,6 +1720,7 @@
"aHd" = (/obj/structure/stool/bed,/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating,/area/maintenance/fpmaint2)
"aHe" = (/obj/machinery/camera{c_tag = "Fore Primary Hallway West"; dir = 4; network = list("SS13")},/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = -27},/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/hallway/primary/fore)
"aHf" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/disposal,/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/hallway/primary/fore)
+"aHg" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
"aHh" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs)
"aHi" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/item/weapon/twohanded/required/kirbyplants,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5; level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/civilian/barber)
"aHj" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/civilian/barber)
@@ -2475,7 +2476,7 @@
"aVF" = (/obj/machinery/camera{c_tag = "Bar Storage"; network = list("SS13")},/obj/structure/table/woodentable,/obj/machinery/reagentgrinder,/obj/item/weapon/reagent_containers/dropper,/turf/simulated/floor/wood,/area/crew_quarters/bar)
"aVG" = (/obj/machinery/vending/coffee,/turf/simulated/floor/wood,/area/crew_quarters/bar)
"aVH" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/shaker,/obj/item/weapon/gun/projectile/revolver/doublebarrel,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/glass{amount = 50; pixel_x = 3; pixel_y = 3},/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/item/weapon/storage/fancy/candle_box/eternal,/obj/item/weapon/storage/fancy/candle_box/eternal,/obj/item/weapon/storage/fancy/candle_box/eternal,/turf/simulated/floor/wood,/area/crew_quarters/bar)
-"aVI" = (/obj/structure/closet/walllocker/emerglocker/north,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
+"aVI" = (/obj/structure/closet/walllocker/emerglocker/north,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
"aVJ" = (/obj/effect/decal/cleanable/blood/oil/streak,/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
"aVK" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/crew_quarters/fitness)
"aVL" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/crew_quarters/fitness)
@@ -2609,7 +2610,7 @@
"aYj" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel,/area/bridge)
"aYk" = (/obj/machinery/door/window/eastright{name = "Coroner Office"; req_access_txt = "5"},/turf/simulated/floor/plasteel,/area/medical/morgue)
"aYl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay2)
-"aYm" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
+"aYm" = (/obj/structure/rack,/obj/item/weapon/storage/box/seccarts{pixel_x = 3; pixel_y = 2},/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/flashbangs{pixel_x = -2; pixel_y = -2},/obj/item/weapon/storage/box/handcuffs,/obj/effect/decal/warning_stripes/red/hollow,/obj/item/weapon/storage/box/teargas{pixel_x = -3; pixel_y = -3},/obj/machinery/light{dir = 8},/obj/machinery/light_switch{pixel_x = -22; pixel_y = 9},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/armoury)
"aYn" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
"aYo" = (/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes/stokcubes,/obj/item/weapon/storage/box/monkeycubes/neaeracubes,/obj/structure/table/glass,/obj/item/weapon/storage/box/monkeycubes/wolpincubes,/obj/item/weapon/storage/box/monkeycubes/farwacubes,/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{tag = "icon-whitepurple (SOUTHEAST)"; icon_state = "whitepurple"; dir = 6},/area/medical/genetics)
"aYp" = (/obj/machinery/ai_status_display{pixel_y = 32},/obj/machinery/computer/card/minor/rd,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/crew_quarters/hor)
@@ -2684,7 +2685,10 @@
"aZG" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor/plasteel{icon_state = "bluecorner"},/area/hallway/primary/fore)
"aZH" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/obj/machinery/requests_console{department = "Atmospherics"; departmentType = 3; name = "Atmospherics Requests Console"; pixel_y = -30},/obj/item/stack/sheet/glass{amount = 50},/obj/item/clothing/head/welding,/obj/item/clothing/head/welding,/turf/simulated/floor/plasteel,/area/atmos)
"aZI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
+"aZJ" = (/obj/effect/decal/cleanable/cobweb,/obj/item/clothing/mask/muzzle/gag,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig)
"aZK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
+"aZL" = (/obj/item/weapon/restraints/handcuffs/pinkcuffs,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig)
+"aZM" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig)
"aZN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
"aZV" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/crew_quarters/bar)
"aZW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint2)
@@ -9042,18 +9046,18 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNagkagjagmaglagoagnagqagpagragrafsagsagsaftagsagvabNaabaabaabaabaabaaaaaaaaaaabaaaafOafXafXafOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiCaiDaiEaiFaiGaiHagwahZagZahZagZahZagwaiIaiJaiKaiLaiDaiMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNagMagLagNagOagPagQafvafuafUafwafUafVafYafWagPagWabNaaaaaaaabaaaaabaabaivaivaivaivaaaafOafXafXafOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahJaiDahaahaahaajdagwahaahaahaahaahaagwahaahaajeahaaiDahMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNabNabNabNabNabNahjahkabNabNabNabNabNabNabNagtagtagtagtagtagtagtaaaaguaivagSagRaivaguaaaafOafXafXagUagTagTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwajzajAajBajCajDagwajEahaahaahaajFagwajGahaajHajIajzagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNagVahDahCabNahEaigacWahGahFabNaaaaaaaaaagtahHahRagtahTahSagtaaaaivahUahVahVahWaivaaaaaaafOafXagTahXahYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwajYajYagZagZagZagwajZahaahaahaakaagwagZagZagZajYajYagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNaiaaicaibaieaidaitabNabNabNabNabNabNabNagtaifaijaiiainaikagtaaaaivaioaiqaipairaivaaaaaaaaaagTagTaisagTagTagTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahsakpakpahnaaaaaaagwakqahaahaahaakragwaaaaaaahsakpakpahnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahQahQahQahQahQahQajJaiuabNaolaolaolaolaolaolagtaiwaiyaixannaizagtaivaivaiAaiNaiBaiOaivaivaaaaabagTaiQaiPaiSaiRagTaaaanHaiTaiVaiUanHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwakAahaahaahaakragwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahQahQahQahQaiZaiXajfajaahQahEaigabNaolaolaolaolaolaolagtajgajiajhajlajkajnajmajpajoajrajqajLajKaivaaaajMagTajOajNajQajPanAanHanHajRajTajSanHanHaihaihaihaihaihaihaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwakRakPahZakRakPagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajWajUakcakbakeakdakhakgahQakiaitalcaolaolaolaolaolaolajnakjanWakkannanWaklajjajjakmajjaksakwaktaivaabaabagTakCakxakEakDanAakFakGaoJaoJakHakJakIakvakKakMakLakNaihaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvalvalvalwalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwalxalyahaalzalAagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajWakOakSakQakVakTalaakYaldalbaitaleaolaolaolaolaolaolagtalfalgakkalialhajnaljallalkalnalmakfakuaivanHanHanAanAanAanAaloanAalpalralqalualtalFalCalGaiYaiYaiYalHaihaihaaaaaaaaaajbajbajbajbajbajbajbalIalJaaaabpaaaaaaalvaaaaabaaaamhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwamiamjahaamkamlagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajWalKalMalLalOalNalQalPahQalRalSalcaolaolaolaolaolaolagtagtalUalTapPagtagtalValWaivalYalXalZaivaivanHambamaamdamcamfameanAamgaoJammampamnalFamqamrajVamvamsamuamtaihaaaaaaaaaajbajsajtajvajuajwajxajyaaaaaaaaaaaaaaaamWaabamUaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahsagZamYamZanaagZahnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahQahQaqqahQahQahQahQahQahQamwaigapFapFapFapFapFapFapFapFamxamzamyamzamAamCamBamEamDamGamFamIamHamJauiaoJamKamKamKamKamLakIaoJapmamMamOamNamQamPamTamSanbamXandancaneaaaaaaaaaajbajXajwajwajwajwajxajyaaaaaaaaaaaaamWalvaaaanGaaaalvamWamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahsagZagZagZahnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanfangaomanianhankanjanlajJanmapGanpanoanranqantansapFanuanwanvanzanyanCanBanEanDanIanFanJanJanJanKaoJanLanNanManPanOanQaofaofanRanTanSalFanUanVajVajVanXanZanYaoaaaaaaaaaaajbaknajwakoajwajwajxajyaaaaaaaaaaaaamWaabaabanGaabaabaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwalwalvalwalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanfangaomaocaobaoeaodaohaogaitapGaojaoiaonaokaopaooapFaoqaosaoraouaotaowaovaoxalWaozaoyaoBaoAaoDaoCaoJaoEaoGaoFaoFaoHaoLaoIaoIaoMaoPaoNalFaoQaoRaiYaiYaiYaoTaoSaihaabaaaaaaajbakyajwajwajwajwakzajyaaaaaaaaaaaaamWaaaaaaaoKaaaaaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaaaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanfaoUaomaoValEaoXaoWanlajJaigapGaoZaoYapbapaapdapcapFapeapgapfaphamyapjapiapkapSapAaplapCapBapEapDapIapHapJapJapLapKapNapMapOaoJapQaoJapRapNapTaiYapVapUapXapWaihaaaaabaabajbapYaqaapZaqcaqbajbalIaqeaaaaaaaaaamWaabappapnapqaabaabamWamWamWamWamWamWaqpamWamWamWamWamWamWamWamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsaprapuaptapwapraprapxapraprapvaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabapyaabalvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBakBakBakBaslakWakZaomaomaomaomakUaqsapFapGapGapGaqtaquapGapFaqvalUaqwaqwalTaqxaqxapPapSapSaqyaqzapSapSapSanAaqAaqCaqBanxanAanAaqAaqDanxaqFaqEanxanAaqGaqGaqGaqGaqHaihaihaqIaqIaqIaqIajbalsaqJaqKalsajbaabaaaaaaaaaaaaamWaaaappaqdapqaaaaaaaabaabaabaabaabaabaabaabaqLaabaabaabaaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNagVahDahCabNahEaigacWahFahFahFahFahFahFagtahHahRagtahTahSagtaaaaivahUahVahVahWaivaaaaaaafOafXagTahXahYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwajYajYagZagZagZagwajZahaahaahaakaagwagZagZagZajYajYagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNaiaaicaibaieaidaitabNahFahFahFahFahFahFagtaifaijahGainaikagtaaaaivaioaiqaipairaivaaaaaaaaaagTagTaisagTagTagTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahsakpakpahnaaaaaaagwakqahaahaahaakragwaaaaaaahsakpakpahnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahQahQahQahQahQahQaiiaigaiuahFahFahFahFahFahFagtaiwaiyaixannaizagtaivaivaiAaiNaiBaiOaivaivaaaaabagTaiQaiPaiSaiRagTaaaanHaiTaiVaiUanHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwakAahaahaahaakragwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahQahQahQahQaiZaiXajfajaahQajgaolakjahFahFahFahFahFahFalealgajiajhajlajkajnajmajpajoajrajqajLajKaivaaaajMagTajOajNajQajPanAanHanHajRajTajSanHanHaihaihaihaihaihaihaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwakRakPahZakRakPagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajWajUakcakbakeakdakhakgahQakiaitalcahFahFahFahFahFahFajnaYmanWakkannanWaklajjajjakmajjaksakwaktaivaabaabagTakCakxakEakDanAakFakGaoJaoJakHakJakIakvakKakMakLakNaihaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvalvalvalwalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwalxalyahaalzalAagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajWakOakSakQakVakTalaakYaldalbaitaleahFahFahFahFahFahFagtalfalgakkalialhajnaljallalkalnalmakfakuaivanHanHanAanAanAanAaloanAalpalralqalualtalFalCalGaiYaiYaiYalHaihaihaaaaaaaaaajbajbajbajbajbajbajbalIalJaaaabpaaaaaaalvaaaaabaaaamhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwamiamjahaamkamlagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajWalKalMalLalOalNalQalPahQalRalSabNahFahFahFahFahFahFagtagtalUalTapPagtagtalValWaivalYalXalZaivaivanHambamaamdamcamfameanAamgaoJammampamnalFamqamramvajVamsamuamtaihaaaaaaaaaajbajsajtajvajuajwajxajyaaaaaaaaaaaaaaaamWaabamUaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahsagZamYamZanaagZahnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahQahQaqqahQahQahQahQahQahQamwaigapFapFapFapFapFapFapFapFamxamzamyamzamAamCamBamEamDamGamFamIamHamJauiaoJamKamKamKamKamLakIaoJapmamMamOamNamQamPamTamSanbamXandancaneaaaaaaaabajbajXajwajwajwajwajxajyaaaaaaaaaaaaamWalvaaaanGaaaalvamWamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahsagZagZagZahnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanfangaomanianhankanjanlajJanmapGanpanoanranqantansapFanuanwanvanzanyanCanBanEanDanIanFanJanJanJanKaoJanLanNanManPanOanQaofaofanRanTanSalFanUanVajVajVanXanZanYaoaaaaaabaabajbaknajwakoajwajwajxajyaaaaaaaaaaaaamWaabaabanGaabaabaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwalwalvalwalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanfangaomaocaobaoeaodaohaogaitapGaojaoiaonaokaopaooapFaoqaosaoraouaotaowaovaoxalWaozaoyaoBaoAaoDaoCaoJaoEaoGaoFaoFaoHaoLaoIaoIaoMaoPaoNalFaoQaoRaiYaiYaiYaoTaoSaihaqIaqIaqIajbakyajwajwajwajwakzajyaaaaaaaaaaaaamWaaaaaaaoKaaaaaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaaaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanfaoUaomaoValEaoXaoWanlajJaigapGaoZaoYapbapaapdapcapFapeapgapfaphamyapjapiapkapSapAaplapCapBapEapDapIapHapJapJapLapKapNapMapOaoJapQaoJapRapNapTaiYapVapUapXapWaihaZJaZMaZLajbapYaqaapZaqcaqbajbalIaqeaaaaaaaaaamWaabappapnapqaabaabamWamWamWamWamWamWaqpamWamWamWamWamWamWamWamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsaprapuaptapwapraprapxapraprapvaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabapyaabalvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBakBakBakBaslakWakZaomaomaomaomakUaqsapFapGapGapGaqtaquapGapFaqvalUaqwaqwalTaqxaqxapPapSapSaqyaqzapSapSapSanAaqAaqCaqBanxanAanAaqAaqDanxaqFaqEanxanAaqGaqGaqGaqGaqHaihaihaqIaucaqIaqIajbalsaqJaqKalsajbaabaaaaaaaaaaaaamWaaaappaqdapqaaaaaaaabaabaabaabaabaabaabaabaqLaabaabaabaaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqfaqhaqiaqgaqkaqlaqlaqlaqmaqjaqoaaaaaaaaaalwalwalwalvalvaabaabaaaaqnaaaaabaabalvalvalwalwalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBakXaqraqMaqNaqraqOapzaqQaqPakWaqRaqSaqXaqVaqUaqXaqWariaqYarjaqXaqXaqXaqXarkaqXaqXaqXarlarnarmarparoarrarqarsarsarsartarsaruarwarvarxaqXaryaqWaqXarzarBarAarCaqXariaqXaqXarDarEaqVaqXarFarHarGarJarIajbaabaaaaaaaaaaaaamWaaaappaqdapqaaaaaaaabaqZaraaraaraaraarbaraaraaraaraarcaabaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaardaqhareargaqlarharharharharharfaaaaaaaaaalwaaaaaaaabaaaaabaaaaaaaqnaaaaaaaabaaaaabaaaaaaalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBalDarKalDarLalDarNarMarParOarRaqTarSarQasdascaseaseasfaseasgaseaseaseasiashasiasjasiasiassaskasnasmaspasoasoasoasoasqasoasoasoasrastasAasvasuasxaswaszasyasAasAasCasBasBasDasEasEasEasFasHasGasIamRamVaaaaaaaaaaaaaaaamWaabappaqdapqaaaaaaaabarUaabaaaaaaaabarUaabaabaaaaaaarUaabaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarVaqharWarYarharharharharZasaaqoaaaaaaaaaalwaabarXarXarXarXarXaaaasbaaaarXarXarXarXarXaabalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBamoasYasXasZasYasYataatbalBakWaryatgatgatgatfatiathatkatjatmatlatnatjatpatoatratqatratsatuattatwatvatyatxatAatzatCatBatEatDatAatOatRatQaFLaFLaFLaFLaFLaFLaFLaxeatSatSatSatTatSatSatSarFatVatUatXatWajbaaaaaaaaaaaaaabamWaaaappaqdapqaabaabappapnapqaabaabappapnapqaabaabappapnapqaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -9114,7 +9118,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdbKybKxbKpaQZaQZaQZbndaSfaSfbCfbKCbCfbKDbKsbKtbKEbCfblQbKvbKvbKwbKFbKwbKwbKwbKFbKwblQblQbxbbxbbxbbKGbxbbKzbKzbKzbKzbKzbKzbJfbKAbKBbKHbzFbKIbKKbKJbKMbKLbKObKNbKQbKPbKSbKRbKVbKUbKXbKXbLabKZbKTbLbbLfbKWbLgbKYbFCbLhbHDbLibHBbLkbFCaaabLcbLdbLebLnbLdbLdbLdbLdbLpbxvbLqbFObLrbLjbLsbLlbLmbLtbLobEobLvbLubLxbLwbLzbLybLBbLAbGabLDbEtaTHaTLaTKaTNaTMbHQaTObHQaSVbIbbHUbHQbIbbEubIebGqbLNbLEbLPbLSbLQbLIbLTbLKbLLbLMbLUbLObLVbEAbLXbLRbLYbEDbLZbMfbMabIpbLWbMgbEDbKubGGbMhbGHaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdbMjbMibKpaSeaSebMbbMcaSebMdbCfbMebIBbMlbMkbMnbMmbCfaaaaabaabbMpbMobMobMobMobMobMraaaaaabKBbMtbMsbMubMqbKzbKzbKzbKzbKzbKzbMwbMvbMzbMybMDbMBbMxbDXbzJbzJbMFbMAbzJbzJbMJbMCbMLbMEbMMbMGbMGbMHbMGbMIbMNbMGbMKbKYbFCbMObFEbFEbFEbMPbFCaaabLcbLdbMRbMQbMVbMTbMWbMSbNbbMUbNcbFObNdbEobMXbMYbMZbNabNfbNebNjbNgbNlbNkbNhbNibNnbNmbNqbNpbNrbLFaTQaTPbEtaTRaTTaTSaTUaSVbNAaTVaTWbGvbEubNKbNzbNLbNBbNBbNMbNDbNEbNFbNGbNHbNIbNJbNObNNbEAbNQbLRbNRbEDbNSbNPbNTbIpbIpbNUbEDbIzbGGbNWbGHaaaaaaaaaaaaaabbNXbNZbNVbNZbNVbNZbOaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdbKpbKpbObaSdaSdbjQaLdaSdaSdbCfbOdbIBbIBbIBbCfbCfbCfaaaaaaaaabOebOcbOcbOfbOcbOcbOeaaaaaabKBbOgbKzbOibOhbOhbOhbOhbOhbOkbOjbOhbOlbOnbOmbOpbOobOrbOqbzJbOtbBnbOvbOsbDXbOwbOubOxbMEbMEbMGbOAbOybOCbOBbODbMGbFBbKYbFCbOEbOHbOFbOObOMbFCaaabOGbLdbOPbOIbOJbOKbOLbOKbOSbONbOXbFObOYbEobOQbOQbORbPabOTbOUbOVbOWbPcbPbbOZbOZbPebPdbPhbPfbEtbNoaUOaTYbEtbEubPgbEubEuaUPbEubEubEubEubPrbPmbGqbPvbLEbLPbPxbNBbNEbPnbPobPobPpbIdbPqbPybPsbPtbIrbPubEDbPzbPwbIpbPHbPBbPJbEDbKubPAbGHbGHaaaaaaaaaaaaaabbPKbPCbPDbPEbPFbPGbPKaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbPIbPIbPIbPIbPNbPMbPIbPIbPIbPIbPRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbOebPTbKBbKBbPUbPObPPbPQbPQbPQbPObKzbJfbKAbKzbKzbKBbPZbPSbQcbQdbPVbQebPXbBnbBnbPYbDXbOwbOubQhbQfbQbbQibQkbOzbQlbQgbQnbMGbQobQjbHmbQpbQqbQmbQsbQrbHsbHtbQtbLdbQvbQubQwbOKbQxbOKbQybONbQzbFObQAbEobQDbQBbQGbQEbQHbQCbQJbQIbQFbQFbQMbQKbQFbQFbQObQNbQPbQLaVyaVxbQTbQSaWIaVIaYmaYlaWObQVbRebQXbRgbRfbGqbRabRbbRcbRjbRibIabRkbPobPobRlbRhbPqbRmbEAbRnbRnbRobEDbRpbRybRqbRzbIpbREbEDbKubRFbGHaaaaaaaaaaaaaaaaabbRrbRsbPDbPFbPDbRtbNVaabaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbPIbPIbPIbPIbPNbPMbPIbPIbPIbPIbPRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbOebPTbKBbKBbPUbPObPPbPQbPQbPQbPObKzbJfbKAbKzbKzbKBbPZbPSbQcbQdbPVbQebPXbBnbBnbPYbDXbOwbOubQhbQfbQbbQibQkbOzbQlbQgbQnbMGbQobQjbHmbQpbQqbQmbQsbQrbHsbHtbQtbLdbQvbQubQwbOKbQxbOKbQybONbQzbFObQAbEobQDbQBbQGbQEbQHbQCbQJbQIbQFbQFbQMbQKbQFbQFbQObQNbQPbQLaVyaVxbQTbQSaWIaHgaVIaYlaWObQVbRebQXbRgbRfbGqbRabRbbRcbRjbRibIabRkbPobPobRlbRhbPqbRmbEAbRnbRnbRobEDbRpbRybRqbRzbIpbREbEDbKubRFbGHaaaaaaaaaaaaaaaaabbRrbRsbPDbPFbPDbRtbNVaabaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbRubRvbRwbRxbRGbRHbRAbRGbRBbRCbRDbPIbPIbPRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbRJbRIbRKbRIbRSbRRbRTbRRbRRbRRbRRbRUbJfbKAbRLbxbbxbbRMbBnbzFbQdbRNbDXbRObRPbRPbRQbNYbRYbRXbRZbRVbRWbSbbSdbScbSabQgbSebMGbMKbKYbFCbSfbShbSgbSlbSkbFCaaabOGbSibSjbSibSibSibSibSibSmbSibSpbFObQAbEobSqbSnbSnbSobSrbOUbStbSsbSvbSubSxbSwbSybSvbSAbSzbSDbSBaWSaWRbSGbSGbSEbSHbSJbSIbSLbSKbSNbSMbSPbSObSRbSQbSQbSSbSUbSTbIabSWbIdbIdbSXbSVbPqbSYbTabSZbTfbTcbTbbTgbTdbTebTjbTebEDbEDbTkbPtbThbTibTibTibTibTibThbPKbPFbPDbPFbPFbPGbPKaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbPIbRAbRAbRAbTlbRGbTnbTnbRGbTobRAbRAbTpbWLbPIbPRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbTtbTrbTqbTrbTubKzbPPbPQbPQbPQbKzbKzbJfbKAbTsbTxbxbbTAbBnbTBbQdbTvbDXbTwbBnbBobBnbPWbOwbTybTzbRVbRWbTCbTEbTDbTKbTFbTLbTGbTHbTIbTJbTJbTNbTMbTPbFCbFCaaabOGbSibTQbTObTSbTRbTVbTTbTWbTUbTXbFObQAbNebTZbTYbUbbUabUcbOUbUebUdbUibUhbUfbUgbUkbUjbUmbUlbUobUnbUqbUpbUsbUrbUubUtbUybUvbUDbQVbUwbQXbUxbUGbGrbUzbUAbUBbUCbUCbIabUIbUEbUFbIabUJbPqbUHbIabUKbUMbULbUObUNbUQbUPbUSbURbUUbUTbUWbUVbUYbUXbUXbUZbVbbVabQabVcbNZbNVbVdbNVbNZbVjaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbPIbVebVfbVgbVhbVibRGbVkbRAbVlbRAbRAbRAbRAbRAbTlbRGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebVmbOcbOcbOcbVnbOebPTbKBbKBbVobKzbPPbKzbKzbKzbKzbKzbJfbKAbTsbVpbxbbVrbBnbVqbVsbBnbVwbzEbBnbBnbVtbDXbOwbTybTzbRVbRWbMGbVubVvbVybVxbVzbMHbVBbVAbVDbVCbHsbVEbVFbHsbHtbHtbVGbSibVIbVHbVKbVJbVLbVLbVNbVMbVObFObVPbEobOUbVQbOQbVSbVRbOUbUebVUbVTbVVbVXbVWbVYbVTbUebVZbWebWabWbbWabWcbWabWdbWdbWhbWfbWgbWgbWgbWmbWgbWgbWibWibWjbWkbWjbWjbIabIabIabIabIabWlbWnbLIbIabWobWrbWpbWqbWqbWvbWsbWtbWubWxbWwbWzbWybWBbWAbWAbWCbWEbWDbThbQabQabQabWFbThaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm
index 79d5bede9fd..7c6dbdded8c 100644
--- a/_maps/map_files/cyberiad/z2.dmm
+++ b/_maps/map_files/cyberiad/z2.dmm
@@ -152,7 +152,7 @@
"cV" = (/obj/structure/flora/ausbushes/brflowers,/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/specops)
"cW" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/specops)
"cX" = (/obj/structure/flora/ausbushes/reedbush,/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/specops)
-"cY" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun/buck,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/turf/simulated/floor/engine,/area/shuttle/gamma/space)
+"cY" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/shuttle/gamma/space)
"cZ" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/box/trackimp,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin)
"da" = (/obj/structure/table/reinforced,/obj/item/weapon/scalpel,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin)
"db" = (/turf/simulated/floor/holofloor{tag = "icon-carpet2-0 (EAST)"; icon_state = "carpet2-0"; dir = 4},/area/holodeck/source_theatre)
@@ -756,25 +756,25 @@
"oB" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (WEST)"; icon_state = "fakewindows"; dir = 8},/area/syndicate_mothership)
"oC" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (EAST)"; icon_state = "fakewindows"; dir = 4},/area/syndicate_mothership)
"oD" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership)
-"oE" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/machinery/light{dir = 1},/turf/simulated/floor/engine,/area/shuttle/gamma/space)
-"oF" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine,/area/shuttle/gamma/space)
-"oG" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/ammo_casing/rocket,/obj/item/ammo_casing/rocket,/obj/item/ammo_casing/rocket,/obj/item/weapon/gun/rocketlauncher,/obj/machinery/ai_status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine,/area/shuttle/gamma/space)
+"oE" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/shuttle/gamma/space)
+"oF" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/gamma/space)
+"oG" = (/turf/simulated/shuttle/wall{tag = "icon-swall3"; icon_state = "swall3"; dir = 2},/area/shuttle/gamma/space)
"oH" = (/obj/structure/table,/obj/item/weapon/storage/fancy/crayons,/obj/item/weapon/storage/fancy/crayons,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership)
"oI" = (/obj/machinery/washing_machine,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership)
-"oJ" = (/obj/structure/table/reinforced,/obj/item/weapon/grenade/clusterbuster,/turf/simulated/floor/engine,/area/shuttle/gamma/space)
+"oJ" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
"oK" = (/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/centcom/gamma)
"oL" = (/turf/unsimulated/floor{tag = "icon-red (EAST)"; icon_state = "red"; dir = 4},/area/centcom/gamma)
"oM" = (/obj/machinery/door/airlock/centcom{name = "Team Storage"; opacity = 1; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/specops)
-"oN" = (/obj/machinery/power/apc{dir = 8; name = "Gamma Armory APC"; pixel_x = -27; pixel_y = 2},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/engine,/area/shuttle/gamma/space)
+"oN" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun/buck,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
"oO" = (/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
-"oP" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/engine,/area/shuttle/gamma/space)
+"oP" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/weapon/gun/energy/sniperrifle,/obj/item/weapon/gun/energy/sniperrifle,/obj/item/weapon/gun/energy/sniperrifle,/obj/machinery/light/spot{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/obj/machinery/ai_status_display{pixel_y = 32},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
"oQ" = (/obj/machinery/vending/syndisnack,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
"oR" = (/obj/machinery/vending/syndicigs,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
"oS" = (/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_x = 6; pixel_y = 6; 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_x = -6; pixel_y = 6; 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_x = 6; pixel_y = -6; req_access_txt = "114"},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "CCGAMMA"; name = "Gamma Lockdown"; pixel_x = -6; pixel_y = -6; req_access_txt = "114"},/turf/unsimulated/floor{dir = 8; icon_state = "carpetside"},/area/centcom/specops)
"oT" = (/turf/simulated/floor/plasteel{icon_state = "red"},/area/centcom/gamma)
"oU" = (/turf/simulated/floor/plasteel{icon_state = "red"; dir = 10},/area/centcom/gamma)
"oV" = (/turf/simulated/floor/plasteel{icon_state = "red"; dir = 6},/area/centcom/gamma)
-"oW" = (/obj/structure/sign/securearea,/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/shuttle/gamma/space)
+"oW" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
"oX" = (/obj/machinery/door/airlock/centcom{name = "Prison"; opacity = 1; req_access_txt = "104"},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops)
"oY" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/flora/ausbushes,/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/specops)
"oZ" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/flora/ausbushes/fernybush,/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/specops)
@@ -783,20 +783,21 @@
"pc" = (/mob/living/simple_animal/pet/fox/Syndifox,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
"pd" = (/obj/effect/decal/warning_stripes/southeastcorner,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
"pe" = (/obj/effect/decal/warning_stripes/south,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
-"pf" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/shuttle/gamma/space)
-"pg" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/shuttle/gamma/space)
-"ph" = (/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/plasteel{icon_state = "dark"},/area/shuttle/gamma/space)
-"pi" = (/obj/structure/cable,/obj/machinery/mech_bay_recharge_port/upgraded,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/shuttle/gamma/space)
-"pj" = (/obj/structure/cable,/obj/machinery/computer/mech_bay_power_console,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/shuttle/gamma/space)
-"pk" = (/obj/mecha/combat/durand/loaded{operation_req_access = list(1)},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/shuttle/gamma/space)
+"pf" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
+"pg" = (/obj/structure/grille,/obj/structure/window/full/shuttle{icon_state = "16"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
+"ph" = (/obj/machinery/recharger/wallcharger{pixel_x = 32},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
+"pi" = (/obj/structure/grille,/obj/structure/window/full/shuttle{icon_state = "15"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
+"pj" = (/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
+"pk" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/ammo_casing/rocket,/obj/item/ammo_casing/rocket,/obj/item/ammo_casing/rocket,/obj/item/weapon/gun/rocketlauncher,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
"pl" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
"pm" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/cans/beer{pixel_x = -2; pixel_y = 5},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
-"pn" = (/obj/structure/table/reinforced,/obj/item/weapon/kitchen/knife/combat,/obj/item/weapon/kitchen/knife/combat,/obj/item/weapon/kitchen/knife/combat,/turf/simulated/floor/engine,/area/shuttle/gamma/space)
-"po" = (/obj/structure/table/reinforced,/obj/item/weapon/grenade/chem_grenade/incendiary{name = "Incendiary Grenade"},/turf/simulated/floor/engine,/area/shuttle/gamma/space)
+"pn" = (/obj/machinery/door/airlock/shuttle,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
+"po" = (/obj/structure/table/reinforced,/obj/item/weapon/grenade/clusterbuster,/obj/item/weapon/grenade/chem_grenade/incendiary{name = "Incendiary Grenade"},/obj/item/weapon/kitchen/knife/combat,/obj/item/weapon/kitchen/knife/combat,/obj/item/weapon/kitchen/knife/combat,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
"pp" = (/obj/machinery/computer/telecrystals/uplinker,/turf/unsimulated/floor{icon_state = "floor4"},/area/syndicate_mothership)
"pq" = (/obj/machinery/camera{c_tag = "CentComm Special Ops. Bathroom"; dir = 2; network = list("ERT","CentComm")},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops)
"pr" = (/obj/machinery/door/airlock/centcom{name = "Bathroom"; opacity = 1; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops)
"ps" = (/obj/machinery/telecomms/server/presets/centcomm,/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control)
+"pt" = (/obj/machinery/door/airlock/shuttle{req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
"pu" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (NORTHWEST)"; icon_state = "fakewindows"; dir = 9},/area/syndicate_mothership)
"pv" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows2 (WEST)"; icon_state = "fakewindows2"; dir = 8},/area/syndicate_mothership)
"pw" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/snacks/mushroompizzaslice{pixel_x = -5; pixel_y = 5},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
@@ -806,6 +807,7 @@
"pA" = (/obj/machinery/light,/turf/unsimulated/floor{icon_state = "floor"},/area/syndicate_mothership)
"pB" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/structure/mirror{dir = 4; pixel_x = 32; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops)
"pC" = (/obj/machinery/door/poddoor{id_tag = "nukeop_ready"; name = "Shuttle Dock Door"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership)
+"pD" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/gamma/space)
"pE" = (/obj/structure/stool/bed,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops)
"pF" = (/turf/unsimulated/wall/fakeglass,/area/syndicate_mothership)
"pG" = (/obj/structure/toilet{dir = 8},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops)
@@ -890,16 +892,15 @@
"rh" = (/obj/structure/toilet{dir = 8},/turf/unsimulated/floor{icon_state = "platingdmg1"},/area/centcom)
"ri" = (/obj/structure/toilet{dir = 8},/turf/unsimulated/floor{icon_state = "floorscorched2"},/area/centcom)
"rj" = (/obj/structure/rack,/obj/item/weapon/implanter/adrenalin{pixel_x = 12; pixel_y = -12},/obj/item/weapon/implanter/emp{pixel_x = 9; pixel_y = -9},/obj/item/weapon/implanter/explosive{pixel_x = 6; pixel_y = -6},/obj/item/weapon/implanter/explosive_macro{pixel_x = 3; pixel_y = -3},/obj/item/weapon/implanter/freedom,/obj/item/weapon/implanter/krav_maga{pixel_x = -9; pixel_y = 9},/obj/item/weapon/implanter/mindshield{pixel_x = -6; pixel_y = 6},/obj/item/weapon/implanter/storage{pixel_x = -3; pixel_y = 3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin)
+"rk" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/gamma/space)
+"rl" = (/obj/structure/sign/securearea{pixel_x = 32; pixel_y = 0},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
+"rm" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/mech_bay_recharge_port/upgraded,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
+"rn" = (/obj/machinery/power/apc{dir = 2; name = "Gamma Armory APC"; pixel_y = -24},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
+"ro" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/computer/mech_bay_power_console,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/gamma/space)
+"rp" = (/obj/mecha/combat/durand/loaded{operation_req_access = list(1)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/mech_bay_recharge_floor,/area/shuttle/gamma/space)
"rE" = (/turf/unsimulated/wall,/area/start)
"rH" = (/obj/effect/landmark/start,/turf/unsimulated/floor,/area/start)
"rK" = (/turf/unsimulated/wall/splashscreen,/area/start)
-"rV" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/weapon/gun/energy/sniperrifle,/obj/item/weapon/gun/energy/sniperrifle,/obj/item/weapon/gun/energy/sniperrifle,/turf/simulated/floor/engine,/area/shuttle/gamma/space)
-"rX" = (/turf/simulated/floor/engine,/area/shuttle/gamma/space)
-"sa" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/shuttle/gamma/space)
-"sb" = (/turf/simulated/floor/plasteel{tag = "icon-stage_stairs"; icon_state = "stage_stairs"},/area/shuttle/gamma/space)
-"se" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{tag = "icon-stage_stairs"; icon_state = "stage_stairs"},/area/shuttle/gamma/space)
-"sg" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/shuttle/gamma/space)
-"sm" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/table/reinforced,/obj/machinery/recharger{pixel_y = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/shuttle/gamma/space)
"sq" = (/turf/unsimulated/wall,/area/centcom/control)
"sr" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control)
"ss" = (/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control)
@@ -1619,14 +1620,14 @@ aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNthtitititititititItktitititItJtmtntdtdtdsqtKtLtMedtFtFtFtFtFeesqsusxsusqsusususususususqsqfLsqsqsqsqsqsqsqsqsqsqsqsqsqsqfXaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXsXsXsXsXsXsXsXsXsXsXsXsXtatttutdtdtdsqsqeWeVsqeWeVsqsqsqsqsqtQtRtStTtTtTtTtTtTtTtTtTuEtRtZsqfXaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNthtitititititititVtktitititVtWtXtYtdtdtdsXaNaNaNaNaNaNsXfecoflsqtQtRtRtRtRtRtRtRtRtRtRtRtRtRtZsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
-aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmfmfmfmfmfmfmfmfmfmsXsXsXsXsXsXuaubsXsXsXsXsXsXsXsXsXfeujflsqtQtRucudududududududududuetRtZsqaNaNoeodododododododofaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
-aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmfofnfqfpfsfrfnfEfmufuguguhuiujujujsXukukukukulukumunfeujflsqtQtRtZsususususususususutQtRtZsqaNaNohogojoioioioiokohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
-aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmfmfmfmfmfmfmfmjHfFkdkdkdkdfFlZmdujujujujujujujujuqururururururussXfeujflsqtQtRtZsuutuuuvuwuxuyuzsutQtRtZsqaNaNohogogogogogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
-aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmcYoFoErVoGoJfmoKkdkdkdkdkdkdoLmdujujujujujujujujsXuAuBuBuBuBuBuCsXsXoMsXsquEtRtSsuuFtRuGuHtRtRtRsuuEtRtZsqsqsqohogogogogogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
-aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmoNoPrXrXrXrXfdoUoToToToToToToVfdujujujuIuIujujujuJuKuKuKuKuKuKuKuLuKuKuKuMtRtRtRuNtRtRtRtRtRtRtRuNtRtRtZoltRolomogogogogogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
-aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmsasesbsbsaoWfmfmfmfmfmfmfmfmfmfmujujuOuPuQuRujuSsXsXuTuUuTsXsXoXsXoZoYpbsquetRucsutRtRtRtRtRtRtRsuuetRtZsqsqsqohogogogogogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
-aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmpfphpgsgsgsgfmaNaNaNaNaNaNaNaNsXujuXuRooonvavbujvcvdvdvdvdvesXuKsXsXsXsXsqtQtRtZsuvfuuvgvgvgvhvisutQtRtZsqaNaNohogogogogogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
-aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmpipkpjsmpnpofmaNaNaNaNsXuWuWsXsXujujvauRvmuRujujvnvdvovpvqvdsXuKsXvrtTtUsqtQtRtZsqsqvsvtvuvvvwsqsqtQtRtZsqaNaNohogogogopogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
+aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmfmfmfmfmfmfmfmfmfmfmfmfmfmfmfmfmsXsXsXsXsXsXuaubsXsXsXsXsXsXsXsXsXfeujflsqtQtRucudududududududududuetRtZsqaNaNoeodododododododofaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
+aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmcYoEoEoEoEoFfmfofnfqfpfsfrfnfEfmufuguguhuiujujujsXukukukukulukumunfeujflsqtQtRtZsususususususususutQtRtZsqaNaNohogojoioioioiokohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
+aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmoGoNoJoWoPoGfmjHfFkdkdkdkdfFlZmdujujujujujujujujuqururururururussXfeujflsqtQtRtZsuutuuuvuwuxuyuzsutQtRtZsqaNaNohogogogogogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
+aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmpgpfpfpfphoGfmoKkdkdkdkdkdkdoLmdujujujujujujujujsXuAuBuBuBuBuBuCsXsXoMsXsquEtRtSsuuFtRuGuHtRtRtRsuuEtRtZsqsqsqohogogogogogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
+aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmpipfpkpopfptfdoUoToToToToToToVfdujujujuIuIujujujuJuKuKuKuKuKuKuKuLuKuKuKuMtRtRtRuNtRtRtRtRtRtRtRuNtRtRtZoltRolomogogogogogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
+aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmoGpjpfpfrloGfmfmfmfmfmfmfmfmfmfmujujuOuPuQuRujuSsXsXuTuUuTsXsXoXsXoZoYpbsquetRucsutRtRtRtRtRtRtRsuuetRtZsqsqsqohogogogogogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
+aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmpnrnrmrprooGfmaNaNaNaNaNaNaNaNsXujuXuRooonvavbujvcvdvdvdvdvesXuKsXsXsXsXsqtQtRtZsuvfuuvgvgvgvhvisutQtRtZsqaNaNohogogogogogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
+aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmpDoEoEoEoErkfmaNaNaNaNsXuWuWsXsXujujvauRvmuRujujvnvdvovpvqvdsXuKsXvrtTtUsqtQtRtZsqsqvsvtvuvvvwsqsqtQtRtZsqaNaNohogogogopogogogohaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfmfmfmfmfmfmfmfmaNaNaNaNsXvkvkpqprujujujvyvyujujujvzvdvAvBvCbesXuKsqpstRtRvFtRtRtZsqsqsusususususqsqtQtRtZsqaNaNoqodododododododoraNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXvkvkvksXvIvJujujujujvLujsXvdoSmjeTvPsXuKsqvQtRtZsutQtRtStTtTtTtTtTtTtTtTtTuEtRtZsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXvkpBsXsXsXsXsXsXbfbfsXsXsXvSvTvUvVvdsXuKsqvWtRvXsutQtRtRtRtRtRtRtRtRtRtRtRtRtRtZsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN
diff --git a/_maps/map_files/shuttles/emergency_dept.dmm b/_maps/map_files/shuttles/emergency_dept.dmm
index 64b903a78f5..0a17d3d7095 100644
--- a/_maps/map_files/shuttles/emergency_dept.dmm
+++ b/_maps/map_files/shuttles/emergency_dept.dmm
@@ -45,30 +45,30 @@
"aS" = (/turf/simulated/shuttle/wall{tag = "icon-swall7"; icon_state = "swall7"; dir = 2},/area/shuttle/escape)
"aT" = (/obj/docking_port/mobile/emergency{dir = 4; dwidth = 11; height = 13; timid = 1; width = 24},/obj/machinery/door/airlock/shuttle{aiControlDisabled = 1; hackProof = 1; id_tag = "s_docking_airlock"; name = "Shuttle Hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape)
"aU" = (/turf/simulated/floor/plasteel,/area/shuttle/escape)
-"aV" = (/obj/structure/stool/bed/chair{dir = 4},/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
-"aW" = (/obj/machinery/door/window/northleft{req_access_txt = "32"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
+"aV" = (/obj/machinery/door/window/southright{autoclose = 1; name = "engineering door"; req_access_txt = "32"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
+"aW" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor4,/area/shuttle/escape)
"aX" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
"aY" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plasteel,/area/shuttle/escape)
"aZ" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plasteel,/area/shuttle/escape)
"ba" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
-"bb" = (/obj/machinery/door/window/northleft{req_access_txt = "47"},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
-"bc" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/obj/machinery/light/spot{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
-"bd" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
-"be" = (/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
-"bf" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
+"bb" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor4,/area/shuttle/escape)
+"bc" = (/obj/machinery/door/window/southright{autoclose = 1; name = "science door"; req_access_txt = "47"},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
+"bd" = (/obj/machinery/door/window/northleft{autoclose = 1; name = "security door"; req_access_txt = "2"},/turf/simulated/shuttle/floor4,/area/shuttle/escape)
+"be" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
+"bf" = (/obj/structure/stool/bed/chair{dir = 4},/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor4,/area/shuttle/escape)
"bg" = (/obj/structure/grille,/obj/structure/window/full/shuttle{icon_state = "8"},/turf/simulated/floor/plating,/area/shuttle/escape)
"bh" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel,/area/shuttle/escape)
"bi" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel,/area/shuttle/escape)
-"bj" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
-"bk" = (/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
-"bl" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
+"bj" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
+"bk" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor4,/area/shuttle/escape)
+"bl" = (/obj/machinery/door/window/northleft{autoclose = 1; name = "medical door"; req_access_txt = "5"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape)
"bm" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/window/reinforced,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
-"bn" = (/obj/machinery/door/window/southright{req_access_txt = "32"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
+"bn" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
"bo" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/window/reinforced,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
"bp" = (/obj/structure/window/reinforced,/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel,/area/shuttle/escape)
"bq" = (/obj/structure/window/reinforced,/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel,/area/shuttle/escape)
"br" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/window/reinforced,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
-"bs" = (/obj/machinery/door/window/southright{req_access_txt = "47"},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
+"bs" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/obj/machinery/light/spot{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape)
"bt" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/window/reinforced,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
"bu" = (/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel,/area/shuttle/escape)
"bv" = (/obj/machinery/light/spot{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/turf/simulated/floor/plasteel,/area/shuttle/escape)
@@ -76,8 +76,7 @@
"bx" = (/obj/structure/noticeboard,/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/escape)
"by" = (/obj/machinery/door/airlock/shuttle{aiControlDisabled = 1; hackProof = 1; id_tag = null; name = "Shuttle Cargo Hatch"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape)
"bz" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape)
-"bA" = (/obj/machinery/door/window/northleft{req_access_txt = "5"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape)
-"bB" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape)
+"bA" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/escape)
"bC" = (/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Escape Shuttle Infirmary"; req_access_txt = "0"},/turf/simulated/floor/plasteel,/area/shuttle/escape)
"bD" = (/turf/simulated/shuttle/wall{icon_state = "swall11"; dir = 2},/area/shuttle/escape)
"bE" = (/obj/machinery/door/airlock/shuttle{aiControlDisabled = 1; hackProof = 1; id_tag = "s_docking_airlock"; name = "Shuttle Hatch"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
@@ -111,16 +110,16 @@ apaIaIaIaIaMaCaDaEaCaNaOap
aPaIaIaQaQaBaCaDaEaCaRaRac
aSaeaeaeaeaJaCaDaEaCaCaCap
aTaUaUaUaUaUaUaUaUaUaUaUap
-apaVaWaXaBaYaUaZaBbabbbcap
-aBbdbebfbgbhaUbibgbjbkblaB
-bgbdbebfbgbhaUbibgbjbkblbg
-aJbmbnboaJbpaUbqaJbrbsbtaJ
+apbfbdbkaBaYaUaZaBbzblbsap
+aBaWaIbbbgbhaUbibgbFbGbHaB
+bgbjbeaXbgbhaUbibgbabnbAbg
+aJbmaVboaJbpaUbqaJbrbcbtaJ
apbuaUaUaUaUaUaUaUaUaUbvap
bwaUaUaUaUaUaUaUaUaUaUaUac
-aSaebxbyaBbzbAbBaBbCacaebD
-bEaUaUaUbgbFbGbHbgaUaUbIap
-acaUaUaUbgbFbGbHbgaUaUbJap
-apbKbLbLaJbFbGbHaJbNbMbOap
+aSaebxbyaBaYaUaZaBbCacaebD
+bEaUaUaUbgbhaUbibgaUaUbIap
+acaUaUaUbgbhaUbibgaUaUbJap
+apbKbLbLaJbhaUbiaJbNbMbOap
bPaxbQbQawaeaeaeawbRbRaxbS
aabPbTbTbSbUbUbUbPbTbTbSaa
"}
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 1b848686bc3..257e12f4093 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -39,7 +39,7 @@
#define ROLE_ERT "emergency response team"
#define ROLE_NYMPH "Dionaea"
#define ROLE_GSPIDER "giant spider"
-
+#define ROLE_DRONE "drone"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 0abf2ac1af3..f20be8c1c0b 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -464,3 +464,7 @@ proc/add_logs(mob/user, mob/target, what_done, var/object=null, var/addition=nul
set hidden = 1
set name = ".mouse"
LogMouseMacro(".mouse", params)
+
+/proc/update_all_mob_security_hud()
+ for(var/mob/living/carbon/human/H in mob_list)
+ H.sec_hud_set_security_status()
\ No newline at end of file
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 68a24f87a3e..5ebe1f9ac6d 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -405,6 +405,27 @@ so as to remain in compliance with the most up-to-date laws."
if(NOTIFY_FOLLOW)
G.ManualFollow(target)
+/obj/screen/alert/notify_soulstone
+ name = "Soul Stone"
+ desc = "Someone is trying to capture your soul in a soul stone. Click to allow it."
+ icon_state = "template"
+ timeout = 10 SECONDS
+ var/obj/item/device/soulstone/stone = null
+ var/stoner = null
+
+/obj/screen/alert/notify_soulstone/Click()
+ if(!usr || !usr.client)
+ return
+ if(stone)
+ if(alert(usr, "Do you want to be captured by [stoner]'s soul stone? This will destroy your corpse and make it \
+ impossible for you to get back into the game as your regular character.",, "No", "Yes") == "Yes")
+ stone.opt_in = TRUE
+
+/obj/screen/alert/notify_soulstone/Destroy()
+ stone = null
+ return ..()
+
+
//OBJECT-BASED
/obj/screen/alert/restrained/buckled
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index d309cc37e0f..fbba17c7b6b 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -43,9 +43,7 @@
/mob/living/carbon/human/proc/remake_hud() //used for preference changes mid-round; can't change hud icons without remaking the hud.
- if(hud_used)
- qdel(hud_used)
- hud_used = null
+ QDEL_NULL(hud_used)
create_mob_hud()
if(hud_used)
hud_used.show_hud(hud_used.hud_version)
diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm
index f32161b92a2..eba4da0fe65 100644
--- a/code/_onclick/telekinesis.dm
+++ b/code/_onclick/telekinesis.dm
@@ -11,7 +11,8 @@ var/const/tk_maxrange = 15
By default, emulate the user's unarmed attack
*/
/atom/proc/attack_tk(mob/user)
- if(user.stat) return
+ if(user.stat)
+ return
user.UnarmedAttack(src,0) // attack_hand, attack_paw, etc
return
@@ -26,27 +27,23 @@ var/const/tk_maxrange = 15
return
/obj/attack_tk(mob/user)
- if(user.stat) return
+ if(user.stat)
+ return
if(anchored)
..()
return
var/obj/item/tk_grab/O = new(src)
- user.put_in_active_hand(O)
- O.host = user
- O.focus_object(src)
- return
+ O.form_grab(user, src)
/obj/item/attack_tk(mob/user)
- if(user.stat || !isturf(loc)) return
+ if(user.stat || !isturf(loc))
+ return
if((TK in user.mutations) && !user.get_active_hand()) // both should already be true to get here
var/obj/item/tk_grab/O = new(src)
- user.put_in_active_hand(O)
- O.host = user
- O.focus_object(src)
+ O.form_grab(user, src)
else
warning("Strange attack_tk(): TK([TK in user.mutations]) empty hand([!user.get_active_hand()])")
- return
/mob/attack_tk(mob/user)
@@ -75,104 +72,137 @@ var/const/tk_maxrange = 15
var/atom/movable/focus = null
var/mob/living/host = null
+/obj/item/tk_grab/Destroy()
+ if(focus)
+ release_object()
+ // Focus is null now
+ host = null
+ return ..()
- dropped(mob/user as mob)
- if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item
- if(focus.Adjacent(loc))
- focus.loc = loc
+/obj/item/tk_grab/dropped(mob/user)
+ if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item
+ if(focus.Adjacent(loc))
+ focus.loc = loc
- qdel(src)
- return
+ qdel(src)
//stops TK grabs being equipped anywhere but into hands
- equipped(var/mob/user, var/slot)
- if( (slot == slot_l_hand) || (slot== slot_r_hand) ) return
+/obj/item/tk_grab/equipped(mob/user, var/slot)
+ if( (slot == slot_l_hand) || (slot== slot_r_hand) )
+ return
+ qdel(src)
+
+
+/obj/item/tk_grab/attack_self(mob/user)
+ if(focus)
+ focus.attack_self_tk(user)
+
+/obj/item/tk_grab/override_throw(mob/user, atom/target)
+ afterattack(target, user)
+ return TRUE
+
+/obj/item/tk_grab/afterattack(atom/target , mob/living/user, proximity, params)//TODO: go over this
+ if(!target || !user)
+ return
+ if(last_throw+3 > world.time)
+ return
+ if(!host || host != user)
qdel(src)
return
-
-
- attack_self(mob/user as mob)
- if(focus)
- focus.attack_self_tk(user)
-
- afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)//TODO: go over this
- if(!target || !user) return
- if(last_throw+3 > world.time) return
- if(!host || host != user)
- qdel(src)
- return
- if(!(TK in host.mutations))
- qdel(src)
- return
- if(isobj(target) && !isturf(target.loc))
- return
-
- var/d = get_dist(user, target)
- if(focus)
- d = max(d,get_dist(user,focus)) // whichever is further
- if(d > tk_maxrange)
- to_chat(user, "Your mind won't reach that far.")
- return
-
- if(!focus)
- focus_object(target, user)
- return
-
- if(target == focus)
- target.attack_self_tk(user)
- return // todo: something like attack_self not laden with assumptions inherent to attack_self
-
-
- if(!istype(target, /turf) && istype(focus,/obj/item) && target.Adjacent(focus))
- var/obj/item/I = focus
- var/resolved = target.attackby(I, user, params)
- if(!resolved && target && I)
- I.afterattack(target,user,1) // for splashing with beakers
-
-
- else
- apply_focus_overlay()
- focus.throw_at(target, 10, 1, user)
- last_throw = world.time
+ if(!(TK in host.mutations))
+ qdel(src)
+ return
+ if(isobj(target) && !isturf(target.loc))
return
- attack(mob/living/M as mob, mob/living/user as mob, def_zone)
+ var/d = get_dist(user, target)
+ if(focus)
+ d = max(d,get_dist(user,focus)) // whichever is further
+ if(d > tk_maxrange)
+ to_chat(user, "Your mind won't reach that far.")
return
+ if(!focus)
+ focus_object(target, user)
+ return
- proc/focus_object(var/obj/target, var/mob/living/user)
- if(!istype(target,/obj)) return//Cant throw non objects atm might let it do mobs later
- if(target.anchored || !isturf(target.loc))
- qdel(src)
- return
- focus = target
- update_icon()
+ if(target == focus)
+ target.attack_self_tk(user)
+ return // todo: something like attack_self not laden with assumptions inherent to attack_self
+
+
+ if(istype(focus,/obj/item) && target.Adjacent(focus) && !user.in_throw_mode)
+ var/obj/item/I = focus
+ var/resolved = target.attackby(I, user, params)
+ if(!resolved && target && I)
+ I.afterattack(target,user,1) // for splashing with beakers
+
+
+ else
apply_focus_overlay()
+ focus.throw_at(target, 10, 1, user)
+ last_throw = world.time
+
+/obj/item/tk_grab/attack(mob/living/M, mob/living/user, def_zone)
+ return
+
+/obj/item/tk_grab/is_equivalent(obj/item/I)
+ . = ..()
+ if(!.)
+ return I == focus
+
+/obj/item/tk_grab/proc/focus_object(var/obj/target, var/mob/user)
+ if(!istype(target,/obj))
+ return//Cant throw non objects atm might let it do mobs later
+ if(target.anchored || !isturf(target.loc))
+ qdel(src)
return
-
-
- proc/apply_focus_overlay()
- if(!focus) return
- var/obj/effect/overlay/O = new /obj/effect/overlay(locate(focus.x,focus.y,focus.z))
- O.name = "sparkles"
- O.anchored = 1
- O.density = 0
- O.layer = FLY_LAYER
- O.dir = pick(cardinal)
- O.icon = 'icons/effects/effects.dmi'
- O.icon_state = "nothing"
- flick("empdisable",O)
- spawn(5)
- qdel(O)
- return
-
-
+ focus = target
update_icon()
- overlays.Cut()
- if(focus && focus.icon && focus.icon_state)
- overlays += icon(focus.icon,focus.icon_state)
+ apply_focus_overlay()
+ // Make it behave like other equipment
+ if(istype(target, /obj/item))
+ if(target in user.tkgrabbed_objects)
+ // Release the old grab first
+ user.unEquip(user.tkgrabbed_objects[target])
+ user.tkgrabbed_objects[target] = src
+
+/obj/item/tk_grab/proc/release_object()
+ if(!focus)
return
+ if(istype(focus, /obj/item))
+ // Delete the key/value pair of item to TK grab
+ host.tkgrabbed_objects -= focus
+ focus = null
+ update_icon()
+
+/obj/item/tk_grab/proc/apply_focus_overlay()
+ if(!focus)
+ return
+ // Oh jeez ow
+ var/obj/effect/overlay/O = new /obj/effect/overlay(locate(focus.x,focus.y,focus.z))
+ O.name = "sparkles"
+ O.anchored = 1
+ O.density = 0
+ O.layer = FLY_LAYER
+ O.dir = pick(cardinal)
+ O.icon = 'icons/effects/effects.dmi'
+ O.icon_state = "nothing"
+ flick("empdisable",O)
+ spawn(5)
+ qdel(O)
+
+/obj/item/tk_grab/proc/form_grab(mob/user, obj/target)
+ user.put_in_active_hand(src)
+ host = user
+ focus_object(target, user)
+
+
+/obj/item/tk_grab/update_icon()
+ overlays.Cut()
+ if(focus && focus.icon && focus.icon_state)
+ overlays += icon(focus.icon,focus.icon_state)
/*Not quite done likely needs to use something thats not get_step_to
proc/check_path()
@@ -197,4 +227,3 @@ var/const/tk_maxrange = 15
var/Z = source:z
*/
-
diff --git a/code/datums/beam.dm b/code/datums/beam.dm
index 7a8c802b42d..bb1cef167d6 100644
--- a/code/datums/beam.dm
+++ b/code/datums/beam.dm
@@ -15,12 +15,13 @@
var/static_beam = 0
var/beam_type = /obj/effect/ebeam //must be subtype
-/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam)
+/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam,beam_sleep_time=3)
endtime = world.time+time
origin = beam_origin
origin_oldloc = get_turf(origin)
target = beam_target
target_oldloc = get_turf(target)
+ sleep_time = beam_sleep_time
if(origin_oldloc == origin && target_oldloc == target)
static_beam = 1
max_distance = maxdistance
@@ -117,13 +118,13 @@
/obj/effect/ebeam/Destroy()
owner = null
return ..()
-
+
/obj/effect/ebeam/deadly/Crossed(atom/A)
..()
A.ex_act(1)
-/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam)
- var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type)
+/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3)
+ var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time)
spawn(0)
newbeam.Start()
return newbeam
\ No newline at end of file
diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm
index 40c38ac0627..4a6f2a941ff 100644
--- a/code/datums/outfits/outfit_admin.dm
+++ b/code/datums/outfits/outfit_admin.dm
@@ -721,6 +721,38 @@
/obj/item/weapon/melee/classic_baton/telescopic = 1,
/obj/item/ammo_box/magazine/m50 = 2)
+/datum/outfit/admin/paranormal_ert
+ name = "Paranormal ERT member"
+
+ uniform = /obj/item/clothing/under/syndicate
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/paranormal
+ back = /obj/item/weapon/storage/backpack/ert/security
+ belt = /obj/item/weapon/gun/energy/gun/nuclear
+ gloves = /obj/item/clothing/gloves/color/black
+ shoes = /obj/item/clothing/shoes/combat
+ head = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal
+ l_ear = /obj/item/device/radio/headset/ert/alt
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+ id = /obj/item/weapon/card/id/centcom
+ pda = /obj/item/device/pda/centcom
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/clothing/mask/gas/sechailer/swat = 1,
+ /obj/item/weapon/storage/box/zipties = 1,
+ /obj/item/device/flashlight = 1)
+
+/datum/outfit/admin/paranormal_ert/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_centcom_access("Emergency Response Team Member"), "Emergency Response Team Member")
+
+ var/obj/item/weapon/implant/L = new /obj/item/weapon/implant/mindshield(H)
+ L.implant(H)
+
/datum/outfit/admin/janitorial_ert
name = "Janitorial ERT member"
@@ -731,16 +763,18 @@
gloves = /obj/item/clothing/gloves/color/yellow
shoes = /obj/item/clothing/shoes/galoshes
head = /obj/item/clothing/head/helmet/space/hardsuit/ert/janitor
- l_ear = /obj/item/device/radio/headset/centcom
+ l_ear = /obj/item/device/radio/headset/ert/alt
glasses = /obj/item/clothing/glasses/sunglasses
id = /obj/item/weapon/card/id/centcom
pda = /obj/item/device/pda/centcom
backpack_contents = list(
/obj/item/weapon/caution = 2,
+ /obj/item/weapon/storage/box/survival = 1,
/obj/item/weapon/reagent_containers/spray/cleaner = 1,
/obj/item/weapon/storage/bag/trash = 1,
/obj/item/weapon/storage/box/lights/mixed = 1,
- /obj/item/weapon/holosign_creator = 1)
+ /obj/item/weapon/holosign_creator = 1,
+ /obj/item/device/flashlight = 1)
/datum/outfit/admin/janitorial_ert/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
. = ..()
diff --git a/code/datums/soullink.dm b/code/datums/soullink.dm
new file mode 100644
index 00000000000..1f17c635e84
--- /dev/null
+++ b/code/datums/soullink.dm
@@ -0,0 +1,214 @@
+/mob/living
+ var/list/ownedSoullinks //soullinks we are the owner of
+ var/list/sharedSoullinks //soullinks we are a/the sharer of
+
+/mob/living/Destroy()
+ for(var/s in ownedSoullinks)
+ var/datum/soullink/S = s
+ S.ownerDies(FALSE)
+ qdel(s) //If the owner is destroy()'d, the soullink is destroy()'d
+ ownedSoullinks = null
+ for(var/s in sharedSoullinks)
+ var/datum/soullink/S = s
+ S.sharerDies(FALSE)
+ S.removeSoulsharer(src) //If a sharer is destroy()'d, they are simply removed
+ sharedSoullinks = null
+ return ..()
+
+//Keeps track of a Mob->Mob (potentially Player->Player) connection
+//Can be used to trigger actions on one party when events happen to another
+//Eg: shared deaths
+//Can be used to form a linked list of mob-hopping
+//Does NOT transfer with minds
+/datum/soullink
+ var/mob/living/soulowner
+ var/mob/living/soulsharer
+ var/id //Optional ID, for tagging and finding specific instances
+
+/datum/soullink/Destroy()
+ if(soulowner)
+ LAZYREMOVE(soulowner.ownedSoullinks, src)
+ soulowner = null
+ if(soulsharer)
+ LAZYREMOVE(soulsharer.sharedSoullinks, src)
+ soulsharer = null
+ return ..()
+
+/datum/soullink/proc/removeSoulsharer(mob/living/sharer)
+ if(soulsharer == sharer)
+ soulsharer = null
+ LAZYREMOVE(sharer.sharedSoullinks, src)
+
+//Used to assign variables, called primarily by soullink()
+//Override this to create more unique soullinks (Eg: 1->Many relationships)
+//Return TRUE/FALSE to return the soullink/null in soullink()
+/datum/soullink/proc/parseArgs(mob/living/owner, mob/living/sharer)
+ if(!owner || !sharer)
+ return FALSE
+ soulowner = owner
+ soulsharer = sharer
+ LAZYADD(owner.ownedSoullinks, src)
+ LAZYADD(sharer.sharedSoullinks, src)
+ return TRUE
+
+//Runs after /living death()
+//Override this for content
+/datum/soullink/proc/ownerDies(gibbed, mob/living/owner)
+
+//Runs after /living death()
+//Override this for content
+/datum/soullink/proc/sharerDies(gibbed, mob/living/owner)
+
+//Runs after /living update_revive()
+//Override this for content
+/datum/soullink/proc/ownerRevives(mob/living/owner)
+
+//Runs after /living update_revive()
+//Override this for content
+/datum/soullink/proc/sharerRevives(mob/living/owner)
+
+//Quick-use helper
+/proc/soullink(typepath, ...)
+ var/datum/soullink/S = new typepath()
+ if(S.parseArgs(arglist(args.Copy(2, 0))))
+ return S
+
+
+
+/////////////////
+// MULTISHARER //
+/////////////////
+//Abstract soullink for use with 1 Owner -> Many Sharer setups
+/datum/soullink/multisharer
+ var/list/soulsharers
+
+/datum/soullink/multisharer/parseArgs(mob/living/owner, list/sharers)
+ if(!owner || !LAZYLEN(sharers))
+ return FALSE
+ soulowner = owner
+ soulsharers = sharers
+ LAZYADD(owner.ownedSoullinks, src)
+ for(var/l in sharers)
+ var/mob/living/L = l
+ LAZYADD(L.sharedSoullinks, src)
+ return TRUE
+
+/datum/soullink/multisharer/removeSoulsharer(mob/living/sharer)
+ LAZYREMOVE(soulsharers, sharer)
+
+
+
+/////////////////
+// SHARED FATE //
+/////////////////
+//When the soulowner dies, the soulsharer dies, and vice versa
+//This is intended for two players(or AI) and two mobs
+
+/datum/soullink/sharedfate/ownerDies(gibbed, mob/living/owner)
+ if(soulsharer)
+ soulsharer.death(gibbed)
+
+/datum/soullink/sharedfate/sharerDies(gibbed, mob/living/sharer)
+ if(soulowner)
+ soulowner.death(gibbed)
+
+/////////////////
+// Demon Bind //
+/////////////////
+//When the soulowner dies, the soulsharer dies, but NOT vice versa
+//This is intended for two players(or AI) and two mobs
+
+/datum/soullink/oneway/ownerDies(gibbed, mob/living/owner)
+ if(soulsharer)
+ soulsharer.dust(FALSE)
+
+
+/////////////////
+// SHARED BODY //
+/////////////////
+//When the soulsharer dies, they're placed in the soulowner, who remains alive
+//If the soulowner dies, the soulsharer is killed and placed into the soulowner (who is still dying)
+//This one is intended for one player moving between many mobs
+
+/datum/soullink/sharedbody/ownerDies(gibbed, mob/living/owner)
+ if(soulowner && soulsharer)
+ if(soulsharer.mind)
+ soulsharer.mind.transfer_to(soulowner)
+ soulsharer.death(gibbed)
+
+/datum/soullink/sharedbody/sharerDies(gibbed, mob/living/sharer)
+ if(soulowner && soulsharer && soulsharer.mind)
+ soulsharer.mind.transfer_to(soulowner)
+
+
+
+//////////////////////
+// REPLACEMENT POOL //
+//////////////////////
+//When the owner dies, one of the sharers is placed in the owner's body, fully healed
+//Sort of a "winner-stays-on" soullink
+//Gibbing ends it immediately
+
+/datum/soullink/multisharer/replacementpool/ownerDies(gibbed, mob/living/owner)
+ if(LAZYLEN(soulsharers) && !gibbed) //let's not put them in some gibs
+ var/list/souls = shuffle(soulsharers.Copy())
+ for(var/l in souls)
+ var/mob/living/L = l
+ if(L.stat != DEAD && L.mind)
+ L.mind.transfer_to(soulowner)
+ soulowner.revive(TRUE, TRUE)
+ L.death(FALSE)
+
+//Lose your claim to the throne!
+/datum/soullink/multisharer/replacementpool/sharerDies(gibbed, mob/living/sharer)
+ removeSoulsharer(sharer)
+
+
+////////////////
+// SOUL HOOK //
+////////////////
+// When the owner transitions from dead to alive or vice versa,
+// the linked atom is notified
+
+// Atoms that actually utilize this system are responsible for handling the GC cleanup themselves
+// Splashing the GC handling onto every atom would be a big old waste
+
+/datum/soullink/soulhook
+ var/atom/movable/otherend
+
+/datum/soullink/soulhook/Destroy()
+ if(otherend)
+ LAZYREMOVE(otherend.sharedSoulhooks, src)
+ otherend = null
+ return ..()
+
+/datum/soullink/soulhook/parseArgs(mob/living/owner, atom/movable/other)
+ if(!owner || !other)
+ return FALSE
+ soulowner = owner
+ otherend = other
+ LAZYADD(owner.ownedSoullinks, src)
+ LAZYADD(other.sharedSoulhooks, src)
+ return TRUE
+
+/datum/soullink/soulhook/ownerDies(gibbed, mob/living/owner)
+ if(otherend)
+ otherend.onSoullinkDeath(gibbed, owner)
+
+/datum/soullink/soulhook/ownerRevives(mob/living/owner)
+ if(otherend)
+ otherend.onSoullinkRevive(owner)
+
+// oops I'm butchering the application of this
+/datum/soullink/soulhook/removeSoulsharer(atom/movable/other)
+ if(otherend == other)
+ otherend = null
+ LAZYREMOVE(other.sharedSoulhooks, src)
+ qdel(src) // not much point in a soul link with one end out of the picture for good
+
+/atom/movable
+ var/list/sharedSoulhooks = null
+
+/atom/movable/proc/onSoullinkDeath(gibbed, mob/living/owner)
+
+/atom/movable/proc/onSoullinkRevive(mob/living/owner)
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index dbe111b6dbe..e05efe09158 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -932,6 +932,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/obj/item/weapon/reagent_containers/food/condiment/soymilk,
/obj/item/weapon/reagent_containers/food/condiment/saltshaker,
/obj/item/weapon/reagent_containers/food/condiment/peppermill,
+ /obj/item/weapon/kitchen/rollingpin,
/obj/item/weapon/storage/fancy/egg_box,
/obj/item/weapon/reagent_containers/food/condiment/enzyme,
/obj/item/weapon/reagent_containers/food/condiment/sugar,
@@ -1722,4 +1723,4 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/obj/item/weapon/vending_refill/cigarette,
/obj/item/weapon/vending_refill/cigarette)
cost = 15
- containername = "cigarette supply crate"
\ No newline at end of file
+ containername = "cigarette supply crate"
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index 1aa65685d5e..ef3b4a4e278 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -54,7 +54,7 @@ var/list/uplink_items = list()
var/list/excludefrom = list() //Empty list does nothing. Place the name of gamemode you don't want this item to be available in here. This is so you dont have to list EVERY mode to exclude something.
var/list/job = null
var/surplus = 100 //Chance of being included in the surplus crate (when pick() selects it)
- var/hijack_only = 0 //can this item be purchased only during hijackings?
+ var/hijack_only = FALSE //can this item be purchased only during hijackings?
/datum/uplink_item/proc/spawn_item(var/turf/loc, var/obj/item/device/uplink/U)
if(hijack_only)
@@ -129,7 +129,7 @@ var/list/uplink_items = list()
job = list("Clown")
//mime
-/datum/uplink_item/job_specific/caneshotgun
+/datum/uplink_item/jobspecific/caneshotgun
name = "Cane Shotgun + Assassination Darts"
desc = "A specialized, one shell shotgun with a built-in cloaking device to mimic a cane. The shotgun is capable of hiding it's contents and the pin alongside being supressed. Comes with 6 special darts and a preloaded shrapnel round."
reference = "MCS"
@@ -137,14 +137,6 @@ var/list/uplink_items = list()
cost = 15
job = list("Mime")
-/datum/uplink_item/dangerous/cat_grenade
- name = "Feral Cat Delivery Grenade"
- desc = "The feral cat delivery grenade contains 8 dehydrated feral cats in a similar manner to dehydrated monkeys, which, upon detonation, will be rehydrated by a small reservoir of water contained within the grenade. These cats will then attack anything in sight."
- item = /obj/item/weapon/grenade/spawnergrenade/feral_cats
- reference = "CCLG"
- cost = 5
- job = list("Psychiatrist")//why? Becuase its funny that a person in charge of your mental wellbeing has a cat granade..
-
//Chef
/datum/uplink_item/jobspecific/specialsauce
name = "Chef Excellence's Special Sauce"
@@ -195,8 +187,8 @@ var/list/uplink_items = list()
item = /obj/item/weapon/storage/toolbox/green/memetic
cost = 20
job = list("Chaplain")
- surplus = 0 //No lucky chances from the crate; if you get this, this is ALL you're getting
- hijack_only = 1 //This is a murderbone weapon, as such, it should only be available in those scenarios.
+ surplus = 0 //No lucky chances from the crate; if you get this, this is ALL you're getting
+ hijack_only = TRUE //This is a murderbone weapon, as such, it should only be available in those scenarios.
//Janitor
@@ -211,23 +203,21 @@ var/list/uplink_items = list()
//Medical
-
/datum/uplink_item/jobspecific/rad_laser
name = "Radiation Laser"
- desc = "A radiation laser concealed inside of a Health Analyser. After a moderate delay, causes temporary collapse and radiation. Has adjustable controls, but will not function as a regular health analyser, only appears like one. May not function correctly on radiation resistant humanoids!"
+ desc = "A radiation laser concealed inside of a Health Analyser. After a moderate delay, causes temporary collapse and radiation. Has adjustable controls, but will not function as a regular health analyser, only appears like one. May not function correctly on radiation resistant humanoids!"
reference = "RL"
item = /obj/item/device/rad_laser
cost = 5
- job = list(
- "Chief Medical Officer",
- "Medical Doctor",
- "Geneticist",
- "Psychiatrist",
- "Chemist",
- "Paramedic",
- "Virologist",
- "Brig Physician"
- )
+ job = list("Chief Medical Officer", "Medical Doctor", "Geneticist", "Psychiatrist", "Chemist", "Paramedic", "Coroner", "Virologist")
+
+/datum/uplink_item/dangerous/cat_grenade
+ name = "Feral Cat Delivery Grenade"
+ desc = "The feral cat delivery grenade contains 8 dehydrated feral cats in a similar manner to dehydrated monkeys, which, upon detonation, will be rehydrated by a small reservoir of water contained within the grenade. These cats will then attack anything in sight."
+ item = /obj/item/weapon/grenade/spawnergrenade/feral_cats
+ reference = "CCLG"
+ cost = 5
+ job = list("Psychiatrist")//why? Becuase its funny that a person in charge of your mental wellbeing has a cat granade..
//Assistant
@@ -249,10 +239,9 @@ var/list/uplink_items = list()
cost = 6
job = list("Bartender")
-
//Barber
-/datum/uplink_item/jobspecific/safety_scissors //Hue
+/datum/uplink_item/jobspecific/safety_scissors //Hue
name = "Safety Scissors"
desc = "A pair of scissors that are anything but what their name implies; can easily cut right into someone's throat."
reference = "CTS"
@@ -278,7 +267,7 @@ var/list/uplink_items = list()
reference = "PG"
item = /obj/item/clothing/gloves/color/yellow/power
cost = 10
- job = list("Station Engineer","Chief Engineer")
+ job = list("Station Engineer", "Chief Engineer")
//RD
@@ -299,7 +288,6 @@ var/list/uplink_items = list()
cost = 3
job = list("Librarian")
-
//Botanist
/datum/uplink_item/jobspecific/ambrosiacruciatus
name = "Ambrosia Cruciatus Seeds"
@@ -309,7 +297,6 @@ var/list/uplink_items = list()
cost = 2
job = list("Botanist")
-
//Atmos Tech
/datum/uplink_item/jobspecific/contortionist
name = "Contortionist's Jumpsuit"
@@ -335,7 +322,7 @@ var/list/uplink_items = list()
reference = "ST"
item = /obj/item/weapon/reagent_containers/hypospray/autoinjector/stimulants
cost = 7
- job = list("Scientist","Research Director","Geneticist","Chief Medical Officer","Medical Doctor","Psychiatrist","Chemist","Paramedic","Virologist","Brig Physician")
+ job = list("Scientist", "Research Director", "Geneticist", "Chief Medical Officer", "Medical Doctor", "Psychiatrist", "Chemist", "Paramedic", "Coroner", "Virologist")
//Tator Poison Bottles
@@ -345,7 +332,7 @@ var/list/uplink_items = list()
reference = "TPB"
item = /obj/item/weapon/reagent_containers/glass/bottle/traitor
cost = 2
- job = list("Research Director","Chief Medical Officer","Medical Doctor","Psychiatrist","Paramedic","Virologist","Bartender")
+ job = list("Research Director", "Chief Medical Officer", "Medical Doctor", "Psychiatrist", "Paramedic", "Virologist", "Bartender", "Chef")
// Paper contact poison pen
@@ -400,7 +387,7 @@ var/list/uplink_items = list()
/datum/uplink_item/dangerous/machinegun
name = "L6 Squad Automatic Weapon"
- desc = "A fully-loaded Aussec Armoury belt-fed machine gun. This deadly weapon has a massive 50-round magazine of devastating 7.62x51mm ammunition."
+ desc = "A fully-loaded Aussec Armory belt-fed machine gun. This deadly weapon has a massive 50-round magazine of devastating 7.62x51mm ammunition."
reference = "LMG"
item = /obj/item/weapon/gun/projectile/automatic/l6_saw
cost = 40
@@ -1088,6 +1075,7 @@ var/list/uplink_items = list()
reference = "SNGB"
item = /obj/item/device/radio/beacon/syndicate
cost = 14
+ surplus = 0
/datum/uplink_item/device_tools/syndicate_bomb
name = "Syndicate Bomb"
diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm
index 4f023d8021f..52cd4226327 100644
--- a/code/game/dna/genes/monkey.dm
+++ b/code/game/dna/genes/monkey.dm
@@ -42,9 +42,7 @@
H.set_species(H.species.primitive_form)
- if(H.hud_used)
- qdel(H.hud_used)
- H.hud_used = null
+ QDEL_NULL(H.hud_used)
if(H.client)
H.hud_used = new /datum/hud/monkey(H, ui_style2icon(H.client.prefs.UI_style), H.client.prefs.UI_style_color, H.client.prefs.UI_style_alpha)
@@ -89,13 +87,11 @@
H.real_name = H.dna.real_name
H.name = H.real_name
- if(H.hud_used)
- qdel(H.hud_used)
- H.hud_used = null
+ QDEL_NULL(H.hud_used)
if(H.client)
H.hud_used = new /datum/hud/human(H, ui_style2icon(H.client.prefs.UI_style), H.client.prefs.UI_style_color, H.client.prefs.UI_style_alpha)
to_chat(H, "You are now a [H.species.name].")
- return H
\ No newline at end of file
+ return H
diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm
index c7d393b77a7..57f086b46ed 100644
--- a/code/game/gamemodes/changeling/powers/mutations.dm
+++ b/code/game/gamemodes/changeling/powers/mutations.dm
@@ -17,18 +17,21 @@
dna_cost = -1
genetic_damage = 1000
+ var/silent = FALSE
var/weapon_type
var/weapon_name_simple
/obj/effect/proc_holder/changeling/weapon/try_to_sting(var/mob/user, var/mob/target)
if(istype(user.l_hand, weapon_type)) //Not the nicest way to do it, but eh
qdel(user.l_hand)
- user.visible_message("With a sickening crunch, [user] reforms his [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "With a sickening crunch, [user] reforms his [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "With a sickening crunch, [user] reforms his [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "With a sickening crunch, [user] reforms his [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "[user] forces the airlock to open with \his [src]!", "We force the airlock to open.", "You hear a metal screeching sound.")
A.open(2)
+/***************************************\
+|***********COMBAT TENTACLES*************|
+\***************************************/
+
+/obj/effect/proc_holder/changeling/weapon/tentacle
+ name = "Tentacle"
+ desc = "We ready a tentacle to grab items or victims with."
+ helptext = "We can use it once to retrieve a distant item. If used on living creatures, the effect depends on the intent: \
+ Help will simply drag them closer, Disarm will grab whatever they are holding instead of them, Grab will put the victim in our hold after catching it, \
+ and Harm will stun it, and stab it if we are also holding a sharp weapon. Cannot be used while in lesser form."
+ chemical_cost = 10
+ dna_cost = 2
+ genetic_damage = 5
+ req_human = 1
+ max_genetic_damage = 10
+ weapon_type = /obj/item/weapon/gun/magic/tentacle
+ weapon_name_simple = "tentacle"
+ silent = TRUE
+
+/obj/item/weapon/gun/magic/tentacle
+ name = "tentacle"
+ desc = "A fleshy tentacle that can stretch out and grab things or people."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "tentacle"
+ item_state = "tentacle"
+ flags = ABSTRACT | NODROP | NOBLUDGEON
+ w_class = WEIGHT_CLASS_HUGE
+ ammo_type = /obj/item/ammo_casing/magic/tentacle
+ fire_sound = 'sound/effects/splat.ogg'
+ force = 0
+ max_charges = 1
+ throwforce = 0 //Just to be on the safe side
+ throw_range = 0
+ throw_speed = 0
+
+/obj/item/weapon/gun/magic/tentacle/New(location,silent)
+ ..()
+ if(ismob(loc))
+ if(!silent)
+ loc.visible_message("[loc.name]\'s arm starts stretching inhumanly!", "Our arm twists and mutates, transforming it into a tentacle.", "You hear organic matter ripping and tearing!")
+ else
+ to_chat(loc, "You prepare to extend a tentacle.")
+
+/obj/item/weapon/gun/magic/tentacle/dropped()
+ . = ..()
+ qdel(src)
+
+/obj/item/weapon/gun/magic/tentacle/shoot_with_empty_chamber(mob/living/user as mob|obj)
+ to_chat(user, "The [name] is not ready yet.")
+
+/obj/item/weapon/gun/magic/tentacle/suicide_act(mob/user)
+ user.visible_message("[user] coils [src] tightly around \his neck! It looks like \he's trying to commit suicide.")
+ return (OXYLOSS)
+
+/obj/item/ammo_casing/magic/tentacle
+ name = "tentacle"
+ desc = "a tentacle."
+ projectile_type = /obj/item/projectile/tentacle
+ caliber = "tentacle"
+ icon_state = "tentacle_end"
+ var/obj/item/weapon/gun/magic/tentacle/gun //the item that shot it
+
+/obj/item/ammo_casing/magic/tentacle/New(obj/item/weapon/gun/magic/tentacle/tentacle_gun)
+ gun = tentacle_gun
+ ..()
+
+/obj/item/ammo_casing/magic/tentacle/Destroy()
+ gun = null
+ return ..()
+
+/obj/item/projectile/tentacle
+ name = "tentacle"
+ icon_state = "tentacle_end"
+ pass_flags = PASSTABLE
+ damage = 0
+ damage_type = BRUTE
+ range = 8
+ hitsound = 'sound/weapons/thudswoosh.ogg'
+ var/chain
+ var/obj/item/ammo_casing/magic/tentacle/source //the item that shot it
+
+/obj/item/projectile/tentacle/New(obj/item/ammo_casing/magic/tentacle/tentacle_casing)
+ source = tentacle_casing
+ ..()
+
+/obj/item/projectile/tentacle/fire(setAngle)
+ if(firer)
+ chain = firer.Beam(src, icon_state = "tentacle", time = INFINITY, maxdistance = INFINITY, beam_sleep_time = 1)
+ ..()
+
+/obj/item/projectile/tentacle/proc/reset_throw(mob/living/carbon/human/H)
+ if(H.in_throw_mode)
+ H.throw_mode_off() //Don't annoy the changeling if he doesn't catch the item
+
+/mob/proc/tentacle_grab(mob/living/carbon/C)
+ if(Adjacent(C))
+ var/obj/item/weapon/grab/G = C.grabbedby(src,1)
+ if(istype(G))
+ G.state = GRAB_AGGRESSIVE //Instant aggressive grab
+
+/mob/proc/tentacle_stab(mob/living/carbon/C)
+ if(Adjacent(C))
+ var/obj/item/I = r_hand
+ if(!is_sharp(I))
+ I = l_hand
+ if(!is_sharp(I))
+ return
+
+ C.visible_message("[src] impales [C] with [I]!", "[src] impales you with [I]!")
+ C.apply_damage(I.force, BRUTE, "chest")
+ do_attack_animation(C)
+ add_blood(C)
+ playsound(get_turf(src), I.hitsound, 75, 1)
+
+
+/obj/item/projectile/tentacle/on_hit(atom/target, blocked = 0)
+ qdel(source.gun) //one tentacle only unless you miss
+ if(blocked >= 100)
+ return 0
+ var/mob/living/carbon/human/H = firer
+ if(istype(target, /obj/item))
+ var/obj/item/I = target
+ if(!I.anchored)
+ to_chat(firer, "You pull [I] towards yourself.")
+ H.throw_mode_on()
+ I.throw_at(H, 10, 2)
+ . = 1
+
+ else if(isliving(target))
+ var/mob/living/L = target
+ if(!L.anchored && !L.throwing)//avoid double hits
+ if(iscarbon(L))
+ var/mob/living/carbon/C = L
+ switch(firer.a_intent)
+ if(INTENT_HELP)
+ C.visible_message("[L] is pulled by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!")
+ C.throw_at(get_step_towards(H,C), 8, 2)
+ return 1
+
+ if(INTENT_DISARM)
+ var/obj/item/I = C.get_active_hand()
+ if(I)
+ if(C.drop_item())
+ C.visible_message("[I] is yanked out of [C]'s hand by [src]!","A tentacle pulls [I] away from you!")
+ on_hit(I) //grab the item as if you had hit it directly with the tentacle
+ return 1
+ else
+ to_chat(firer, "You can't seem to pry [I] out of [C]'s hands!")
+ return 0
+ else
+ to_chat(firer, "[C] has nothing in hand to disarm!")
+ return 0
+
+ if(INTENT_GRAB)
+ C.visible_message("[L] is grabbed by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!")
+ C.throw_at(get_step_towards(H,C), 8, 2, callback=CALLBACK(H, /mob/proc/tentacle_grab, C))
+ return 1
+
+ if(INTENT_HARM)
+ C.visible_message("[L] is thrown towards [H] by a tentacle!","A tentacle grabs you and throws you towards [H]!")
+ C.throw_at(get_step_towards(H,C), 8, 2, callback=CALLBACK(H, /mob/proc/tentacle_stab, C))
+ return 1
+ else
+ L.visible_message("[L] is pulled by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!")
+ L.throw_at(get_step_towards(H,L), 8, 2)
+ . = 1
+
+/obj/item/projectile/tentacle/Destroy()
+ qdel(chain)
+ source = null
+ return ..()
+
/***************************************\
|****************SHIELD*****************|
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index f3191491c88..fb4ba668bef 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -327,9 +327,7 @@ var/round_start_time = 0
//If its actually the end of the round, wait for it to end.
//Otherwise if its a verb it will continue on afterwards.
spawn(300)
- if(cinematic)
- qdel(cinematic) //end the cinematic
- cinematic = null
+ QDEL_NULL(cinematic) //end the cinematic
if(temp_buckle)
qdel(temp_buckle) //release everybody
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index ca9e7b7ac28..338484a5ebc 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -35,6 +35,7 @@
anchored = 1
mob_size = MOB_SIZE_TINY
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
+ speed = 1
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
var/essence = 75 //The resource of revenants. Max health is equal to three times this amount
diff --git a/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm b/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
index 73165079b6e..a6b083d5b72 100644
--- a/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
+++ b/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
@@ -132,8 +132,7 @@
playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1)
flick("jauntup",animation)
- qdel(holder)
- holder = null
+ QDEL_NULL(holder)
if(iscarbon(src))
var/mob/living/carbon/C = src
@@ -171,4 +170,4 @@
return
/obj/effect/dummy/slaughter/singularity_act()
- return
\ No newline at end of file
+ return
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
index 8fbc0563181..25ebd7bc379 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
@@ -83,7 +83,7 @@
/mob/living/simple_animal/slaughter/Life()
..()
if(boostDe-vampired")
if(vampire_mind.vampire)
vampire_mind.vampire.remove_vampire_powers()
- qdel(vampire_mind.vampire)
- vampire_mind.vampire = null
+ QDEL_NULL(vampire_mind.vampire)
if(issilicon(vampire_mind.current))
to_chat(vampire_mind.current, "You have been turned into a robot! You can feel your powers fading away...")
else
@@ -455,6 +454,5 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
return
static_inventory -= vampire_blood_display
- qdel(vampire_blood_display)
- vampire_blood_display = null
+ QDEL_NULL(vampire_blood_display)
show_hud(hud_version)
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index 13f05048393..c66a0304316 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -215,7 +215,7 @@
stat_allowed = 1
/obj/effect/proc_holder/spell/vampire/mob_aoe/glare/cast(list/targets, mob/user = usr)
- user.visible_message("[user]'s eyes emit a blinding flash!")
+ user.visible_message("[user]'s eyes emit a blinding flash!")
if(istype(user:glasses, /obj/item/clothing/glasses/sunglasses/blindfold))
to_chat(user, "You're blindfolded!")
return
@@ -242,9 +242,9 @@
user.regenerate_icons()
/obj/effect/proc_holder/spell/vampire/self/screech
- name = "Chiroptean Screech (30)"
+ name = "Chiropteran Screech (30)"
desc = "An extremely loud shriek that stuns nearby humans and breaks windows as well."
- gain_desc = "You have gained the Chriopteran Screech ability which stuns anything with ears in a large radius and shatters glass in the process."
+ gain_desc = "You have gained the Chiropteran Screech ability which stuns anything with ears in a large radius and shatters glass in the process."
action_icon_state = "vampire_screech"
required_blood = 30
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index 1dd20906704..4f9af54457c 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -465,7 +465,7 @@ var/global/list/multiverse = list()
if("cyborg")
if(M.get_species() != "Machine")
for(var/obj/item/organ/O in M.bodyparts)
- O.robotize()
+ O.robotize(make_tough = 1)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses)
M.equip_to_slot_or_del(sword, slot_r_hand)
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index 3e396ae14a8..b416b297cca 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -9,10 +9,13 @@
origin_tech = "bluespace=4;materials=5"
var/imprinted = "empty"
+ var/optional = FALSE //does this soulstone ask the victim whether they want to be turned into a shade
var/usability = TRUE // Can this soul stone be used by anyone, or only cultists/wizards?
var/reusable = TRUE // Can this soul stone be used more than once?
var/spent = FALSE // If the soul stone can only be used once, has it been used?
+ var/opt_in = FALSE // for tracking during the 'optional' bit
+
/obj/item/device/soulstone/proc/can_use(mob/living/user)
if(iscultist(user) || iswizard(user) || usability)
return TRUE
@@ -33,6 +36,7 @@
/obj/item/device/soulstone/anybody/chaplain
name = "mysterious old shard"
reusable = FALSE
+ optional = TRUE
/obj/item/device/soulstone/pickup(mob/living/user)
..()
@@ -69,6 +73,50 @@
M.create_attack_log("Has had their soul captured with [src.name] by [key_name(user)]")
user.create_attack_log("Used the [src.name] to capture the soul of [key_name(M)]")
+ if(optional)
+ if(!M.ckey)
+ to_chat(user, "They have no soul!")
+ return
+
+ to_chat(user, "You attempt to channel [M]'s soul into [src]. You must give the soul some time to react and stand still...")
+
+ var/mob/player_mob = M
+ if(M.get_ghost())//in case our player ghosted and we need to throw the alert at their ghost instead
+ player_mob = M.get_ghost()
+ var/client/player_client = player_mob.client
+ to_chat(player_mob, "[user] is trying to capture your soul into [src]! Click the button in the top right of the game window to respond.")
+ player_client << 'sound/misc/notice2.ogg'
+ window_flash(player_client)
+
+ var/obj/screen/alert/notify_soulstone/A = player_mob.throw_alert("\ref[src]_soulstone_thingy", /obj/screen/alert/notify_soulstone)
+ if(player_client.prefs && player_client.prefs.UI_style)
+ A.icon = ui_style2icon(player_client.prefs.UI_style)
+
+ //pass the stuff to the alert itself
+ A.stone = src
+ A.stoner = user.real_name
+
+ //layer shenanigans to make the alert display the soulstone
+ var/old_layer = layer
+ var/old_plane = plane
+ layer = FLOAT_LAYER
+ plane = FLOAT_PLANE
+ A.overlays += src
+ layer = old_layer
+ plane = old_plane
+
+ //give the victim 10 seconds to respond
+ sleep(10 SECONDS)
+
+ if(!opt_in)
+ to_chat(user, "The soul resists your attempts at capturing it!")
+ return
+
+ opt_in = FALSE
+
+ if(spent)//checking one more time against shenanigans
+ return
+
M.create_attack_log("Has had their soul captured with [src.name] by [key_name(user)]")
user.create_attack_log("Used the [src.name] to capture the soul of [key_name(M)]")
log_attack("[key_name(user)] used the [src.name] to capture the soul of [key_name(M)]")
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 4f3e7fe9001..c97b3ac9445 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -78,8 +78,7 @@
if(initial(S.name) == initial(aspell.name))
spell_levels = aspell.spell_level
user.mind.spell_list.Remove(aspell)
- qdel(S)
- S = null
+ QDEL_NULL(S)
return cost * (spell_levels+1)
return -1
diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm
index bac7efd0b8a..c8e7d9e2433 100644
--- a/code/game/jobs/job/job.dm
+++ b/code/game/jobs/job/job.dm
@@ -206,15 +206,15 @@
var/atom/placed_in = H.equip_or_collect(G.spawn_item(null, H.client.prefs.gear[G.display_name]))
if(istype(placed_in))
if(isturf(placed_in))
- to_chat(H, "Placing \the [G] on [placed_in]!")
+ to_chat(H, "Placing [G.display_name] on [placed_in]!")
else
- to_chat(H, "Placing \the [G] in [placed_in.name]")
+ to_chat(H, "Placing [G.display_name] in [placed_in.name]")
continue
if(H.equip_to_appropriate_slot(G))
- to_chat(H, "Placing \the [G] in your inventory!")
+ to_chat(H, "Placing [G.display_name] in your inventory!")
continue
if(H.put_in_hands(G))
- to_chat(H, "Placing \the [G] in your hands!")
+ to_chat(H, "Placing [G.display_name] in your hands!")
continue
to_chat(H, "Failed to locate a storage object on your mob, either you spawned with no hands free and no backpack or this is a bug.")
qdel(G)
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index e92a95e70b6..218172b1884 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -83,6 +83,7 @@
spawn_positions = 1
is_medical = 1
supervisors = "the chief medical officer"
+ department_head = list("Chief Medical Officer")
selection_color = "#ffeef0"
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_mineral_storeroom)
minimal_access = list(access_medical, access_morgue, access_maint_tunnels)
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 82238f732b9..7179c5340cf 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -10,11 +10,13 @@ var/global/datum/controller/occupations/job_master
var/list/occupations = list()
var/list/name_occupations = list() //Dict of all jobs, keys are titles
var/list/type_occupations = list() //Dict of all jobs, keys are types
+ var/list/prioritized_jobs = list() // List of jobs set to priority by HoP/Captain
//Players who need jobs
var/list/unassigned = list()
//Debug info
var/list/job_debug = list()
+
/datum/controller/occupations/proc/SetupOccupations(var/list/faction = list("Station"))
occupations = list()
diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm
index 4a1624426b7..3c17c6f0107 100644
--- a/code/game/jobs/job_exp.dm
+++ b/code/game/jobs/job_exp.dm
@@ -7,6 +7,7 @@ var/global/list/role_playtime_requirements = list(
ROLE_SENTIENT = 5,
ROLE_ERT = 10, // High, because they're team-based, and we want ERT to be robust
ROLE_TRADER = 5,
+ ROLE_DRONE = 10, // High, because they're like mini engineering cyborgs that can ignore the AI, ventcrawl, and respawn themselves
// SOLO ANTAGS
ROLE_TRAITOR = 3,
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 721372b56f5..b85fb249c2e 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -87,6 +87,10 @@
/obj/machinery/clonepod/Destroy()
if(connected)
connected.pods -= src
+ for(var/s in sharedSoulhooks)
+ var/datum/soullink/S = s
+ S.removeSoulsharer(src) //If a sharer is destroy()'d, they are simply removed
+ sharedSoulhooks = null
QDEL_NULL(Radio)
QDEL_NULL(countdown)
QDEL_LIST(missing_organs)
@@ -288,6 +292,8 @@
to_chat(clonemind.current, {"Your body is
beginning to regenerate in a cloning pod. You will
become conscious when it is complete."})
+ // Set up a soul link with the dead body to catch a revival
+ soullink(/datum/soullink/soulhook, clonemind.current, src)
update_icon()
@@ -467,7 +473,12 @@
update_clone_antag(occupant)
to_chat(occupant, "There is a bright flash!
\
You feel like a new being.")
- occupant.flash_eyes(visual = 1)
+ occupant.flash_eyes(visual = 1)
+ for(var/s in sharedSoulhooks)
+ var/datum/soullink/S = s
+ S.removeSoulsharer(src) //If a sharer is destroy()'d, they are simply removed
+ sharedSoulhooks = null
+
for(var/i in missing_organs)
qdel(i)
@@ -479,17 +490,22 @@
occupant = null
update_icon()
-/obj/machinery/clonepod/proc/malfunction()
+/obj/machinery/clonepod/proc/malfunction(go_easy = FALSE)
if(occupant)
connected_message("Critical Error!")
announce_radio_message("Critical error! Please contact a Thinktronic Systems technician, as your warranty may be affected.")
- if(occupant.mind != clonemind)
- clonemind.transfer_to(occupant)
- occupant.grab_ghost() // We really just want to make you suffer.
- to_chat(occupant, {"Agony blazes across your
- consciousness as your body is torn apart.
- Is this what dying is like? Yes it is."})
- occupant << sound('sound/hallucinations/veryfar_noise.ogg',0,1,50)
+ for(var/s in sharedSoulhooks)
+ var/datum/soullink/S = s
+ S.removeSoulsharer(src) //If a sharer is destroy()'d, they are simply removed
+ sharedSoulhooks = null
+ if(!go_easy)
+ if(occupant.mind != clonemind)
+ clonemind.transfer_to(occupant)
+ occupant.grab_ghost() // We really just want to make you suffer.
+ to_chat(occupant, {"Agony blazes across your
+ consciousness as your body is torn apart.
+ Is this what dying is like? Yes it is."})
+ occupant << sound('sound/hallucinations/veryfar_noise.ogg',0,1,50)
for(var/i in missing_organs)
qdel(i)
missing_organs.Cut()
@@ -542,6 +558,11 @@
else
return
+/obj/machinery/clonepod/onSoullinkRevive(mob/living/L)
+ if(occupant && L == clonemind.current)
+ // The old body's back in shape, time to ditch the cloning one
+ malfunction(go_easy = TRUE)
+
/obj/machinery/clonepod/proc/maim_clone(mob/living/carbon/human/H)
LAZYINITLIST(missing_organs)
for(var/i in missing_organs)
diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm
index ba7aadc3054..72dcbb7deb6 100644
--- a/code/game/machinery/computer/HolodeckControl.dm
+++ b/code/game/machinery/computer/HolodeckControl.dm
@@ -546,7 +546,7 @@
power_channel = ENVIRON
/obj/machinery/readybutton/attack_ai(mob/user as mob)
- to_chat(user, "The station AI is not to interact with these devices")
+ to_chat(user, "The station AI is not to interact with these devices.")
return
/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm
index f42e50d9618..2cb5b8a46a2 100644
--- a/code/game/machinery/computer/camera.dm
+++ b/code/game/machinery/computer/camera.dm
@@ -71,7 +71,9 @@
ui_interact(user)
/obj/machinery/computer/security/attackby(obj/item/I, user as mob, params)
- if(I.GetAccess()) // If hit by something with access.
+ if(isscrewdriver(I))
+ ..()
+ else if(I.GetAccess()) // If hit by something with access.
attack_hand(user)
else
..()
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index a6c072fec60..e7ef931ff53 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -20,8 +20,14 @@ var/time_last_changed_position = 0
//if set to -1: No cooldown... probably a bad idea
//if set to 0: Not able to close "original" positions. You can only close positions that you have opened before
var/change_position_cooldown = 60
- //Jobs you cannot open new positions for
- var/list/blacklisted = list(
+ // Jobs that do not appear in the list at all.
+ var/list/blacklisted_full = list(
+ /datum/job/ntnavyofficer,
+ /datum/job/ntspecops,
+ /datum/job/civilian
+ )
+ // Jobs that appear in the list, and you can prioritize, but not open/close slots for
+ var/list/blacklisted_partial = list(
/datum/job/ai,
/datum/job/cyborg,
/datum/job/captain,
@@ -37,12 +43,8 @@ var/time_last_changed_position = 0
/datum/job/brigdoc,
/datum/job/mechanic,
/datum/job/barber,
- /datum/job/chaplain,
- /datum/job/ntnavyofficer,
- /datum/job/ntspecops,
- /datum/job/civilian
+ /datum/job/chaplain
)
-
//The scaling factor of max total positions in relation to the total amount of people on board the station in %
var/max_relative_positions = 30 //30%: Seems reasonable, limit of 6 @ 20 players
@@ -77,7 +79,7 @@ var/time_last_changed_position = 0
/obj/machinery/computer/card/proc/format_job_slots()
var/list/formatted = list()
for(var/datum/job/job in job_master.occupations)
- if(job_blacklisted(job))
+ if(job_blacklisted_full(job))
continue
if(!job_in_department(job))
continue
@@ -86,7 +88,9 @@ var/time_last_changed_position = 0
"current_positions" = job.current_positions,
"total_positions" = job.total_positions,
"can_open" = can_open_job(job),
- "can_close" = can_close_job(job))))
+ "can_close" = can_close_job(job),
+ "can_prioritize" = can_prioritize_job(job)
+ )))
return formatted
@@ -137,14 +141,18 @@ var/time_last_changed_position = 0
nanomanager.update_uis(src)
attack_hand(user)
-//Check if you can't open a new position for a certain job
-/obj/machinery/computer/card/proc/job_blacklisted(datum/job/job)
- return (job.type in blacklisted)
+//Check if you can't touch a job in any way whatsoever
+/obj/machinery/computer/card/proc/job_blacklisted_full(datum/job/job)
+ return (job.type in blacklisted_full)
+
+//Check if you can't open/close positions for a certain job
+/obj/machinery/computer/card/proc/job_blacklisted_partial(datum/job/job)
+ return (job.type in blacklisted_partial)
//Logic check for Topic() if you can open the job
/obj/machinery/computer/card/proc/can_open_job(datum/job/job)
if(job)
- if(!job_blacklisted(job) && job_in_department(job, FALSE))
+ if(!job_blacklisted_full(job) && !job_blacklisted_partial(job) && job_in_department(job, FALSE))
if((job.total_positions <= player_list.len * (max_relative_positions / 100)))
var/delta = (world.time / 10) - time_last_changed_position
if((change_position_cooldown < delta) || (opened_positions[job.title] < 0))
@@ -156,7 +164,7 @@ var/time_last_changed_position = 0
//Logic check for Topic() if you can close the job
/obj/machinery/computer/card/proc/can_close_job(datum/job/job)
if(job)
- if(!job_blacklisted(job) && job_in_department(job, FALSE))
+ if(!job_blacklisted_full(job) && !job_blacklisted_partial(job) && job_in_department(job, FALSE))
if(job.total_positions > job.current_positions)
var/delta = (world.time / 10) - time_last_changed_position
if((change_position_cooldown < delta) || (opened_positions[job.title] > 0))
@@ -165,6 +173,18 @@ var/time_last_changed_position = 0
return -1
return 0
+/obj/machinery/computer/card/proc/can_prioritize_job(datum/job/job)
+ if(job)
+ if(!job_blacklisted_full(job) && job_in_department(job, FALSE))
+ if(job in job_master.prioritized_jobs)
+ return 2
+ else
+ if(job_master.prioritized_jobs.len >= 3)
+ return 0
+ return 1
+ return -1
+
+
/obj/machinery/computer/card/proc/job_in_department(datum/job/targetjob, includecivs = 1)
if(!scan || !scan.access)
return 0
@@ -488,7 +508,25 @@ var/time_last_changed_position = 0
opened_positions[edit_job_target]--
log_game("[key_name(usr)] has closed a job slot for job \"[j]\".")
nanomanager.update_uis(src)
-
+ if("prioritize_job")
+ // TOGGLE WHETHER JOB APPEARS AS PRIORITIZED IN THE LOBBY
+ if(is_authenticated(usr) && !target_dept)
+ var/priority_target = href_list["job"]
+ var/datum/job/j = job_master.GetJob(priority_target)
+ if(!j)
+ return 0
+ if(!job_in_department(j))
+ return 0
+ var/priority = TRUE
+ if(j in job_master.prioritized_jobs)
+ job_master.prioritized_jobs -= j
+ priority = FALSE
+ else if(job_master.prioritized_jobs.len < 3)
+ job_master.prioritized_jobs += j
+ else
+ return 0
+ log_game("[key_name(usr)] [priority ? "prioritized" : "unprioritized"] the job \"[j.title]\".")
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if(modify)
modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])")
@@ -499,7 +537,8 @@ var/time_last_changed_position = 0
circuit = /obj/item/weapon/circuitboard/card/centcom
req_access = list(access_cent_commander)
change_position_cooldown = -1
- blacklisted = list()
+ blacklisted_full = list()
+ blacklisted_partial = list()
/obj/machinery/computer/card/minor
name = "department management console"
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index 7c2df327285..d016a0df7bd 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -198,9 +198,7 @@
if("op")
active2.fields["b_type"] = "O+"
if("del_r2")
- if(active2)
- qdel(active2)
- active2 = null
+ QDEL_NULL(active2)
if(href_list["scan"])
if(scan)
@@ -565,4 +563,4 @@
#undef MED_DATA_MAINT
#undef MED_DATA_RECORD
#undef MED_DATA_V_DATA
-#undef MED_DATA_MEDBOT
\ No newline at end of file
+#undef MED_DATA_MEDBOT
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 16efcb7de76..c4aefaa555d 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -156,11 +156,8 @@
for(var/datum/data/record/R in data_core.medical)
if(R.fields["name"] == active1.fields["name"] && R.fields["id"] == active1.fields["id"])
qdel(R)
- qdel(active1)
- active1 = null
- if(active2)
- qdel(active2)
- active2 = null
+ QDEL_NULL(active1)
+ QDEL_NULL(active2)
update_all_mob_security_hud()
screen = SEC_DATA_R_LIST
if("criminal")
@@ -485,10 +482,6 @@
/obj/machinery/computer/secure_data/proc/setTemp(text, list/buttons = list())
temp = list("text" = text, "buttons" = buttons, "has_buttons" = buttons.len > 0)
-/obj/machinery/computer/secure_data/proc/update_all_mob_security_hud()
- for(var/mob/living/carbon/human/H in mob_list)
- H.sec_hud_set_security_status()
-
/obj/machinery/computer/secure_data/proc/create_record_photo(datum/data/record/R)
// basically copy-pasted from the camera code but different enough that it has to be redone
var/icon/photoimage = get_record_photo(R)
@@ -560,4 +553,4 @@
#undef SEC_DATA_R_LIST
#undef SEC_DATA_MAINT
-#undef SEC_DATA_RECORD
\ No newline at end of file
+#undef SEC_DATA_RECORD
diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm
index e98028e3807..66d0bfdbaee 100644
--- a/code/game/machinery/computer/skills.dm
+++ b/code/game/machinery/computer/skills.dm
@@ -111,8 +111,7 @@
for(var/datum/data/record/R in data_core.medical)
if(R.fields["name"] == active1.fields["name"] && R.fields["id"] == active1.fields["id"])
qdel(R)
- qdel(active1)
- active1 = null
+ QDEL_NULL(active1)
screen = SKILL_DATA_R_LIST
if("rank")
if(active1)
@@ -322,4 +321,4 @@
#undef SKILL_DATA_R_LIST
#undef SKILL_DATA_MAINT
-#undef SKILL_DATA_RECORD
\ No newline at end of file
+#undef SKILL_DATA_RECORD
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 6a336a5f55e..d3cbc93d4f0 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -316,9 +316,7 @@
if(istype(W,/obj/item/device/pda))
var/obj/item/device/pda/P = W
- if(P.id)
- qdel(P.id)
- P.id = null
+ QDEL_NULL(P.id)
qdel(P)
if(!preserve)
@@ -421,8 +419,7 @@
occupant.ghostize(0) // Players despawned too early may not re-enter the game
else
occupant.ghostize(1)
- qdel(occupant)
- occupant = null
+ QDEL_NULL(occupant)
name = initial(name)
diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm
index a24af37dc72..68987b63ebd 100644
--- a/code/game/machinery/doors/brigdoors.dm
+++ b/code/game/machinery/doors/brigdoors.dm
@@ -29,32 +29,51 @@
var/timetoset = 0 // Used to set releasetime upon starting the timer
var/obj/item/device/radio/Radio
var/printed = 0
+ var/datum/data/record/prisoner
maptext_height = 26
maptext_width = 32
/obj/machinery/door_timer/proc/print_report()
- var/logname = input(usr, "Name of the guilty?","[id] log name")
- var/logcharges = stripped_multiline_input(usr, "What have they been charged with?","[id] log charges")
+ var/logname = input(usr, "Name of the guilty?","[id] log name")
+ var/logcharges = stripped_multiline_input(usr, "What have they been charged with?","[id] log charges")
- if(!logname || !logcharges)
- return 0
+ if(!logname || !logcharges)
+ return 0
- for(var/obj/machinery/computer/prisoner/C in prisoncomputer_list)
- var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(C.loc)
- P.name = "[id] log - [logname] [worldtime2text()]"
- P.info = "[id] - Brig record
"
- P.info += {"[station_name()] - Security Department
- Admission data:
- Log generated at: [worldtime2text()]
- Detainee: [logname]
- Duration: [timetoset/10] seconds
- Charge(s): [logcharges]
- Arresting Officer: [usr.name]
- This log file was generated automatically upon activation of a cell timer."}
+ for(var/obj/machinery/computer/prisoner/C in prisoncomputer_list)
+ var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(C.loc)
+ P.name = "[id] log - [logname] [worldtime2text()]"
+ P.info = "[id] - Brig record
"
+ P.info += {"[station_name()] - Security Department
+ Admission data:
+ Log generated at: [worldtime2text()]
+ Detainee: [logname]
+ Duration: [timetoset/10] seconds
+ Charge(s): [logcharges]
+ Arresting Officer: [usr.name]
+ This log file was generated automatically upon activation of a cell timer."}
- playsound(C.loc, "sound/goonstation/machines/printer_dotmatrix.ogg", 50, 1)
- cell_logs += P
- return 1
+ playsound(C.loc, "sound/goonstation/machines/printer_dotmatrix.ogg", 50, 1)
+ cell_logs += P
+
+ var/datum/data/record/R = find_security_record("name", logname)
+ Radio.autosay("Detainee [logname] has been incarcerated for [timetoset/10] seconds for the charges of, '[logcharges]'. \
+ Arresting Officer: [usr.name].[R ? "" : " Detainee record not found, manual record update required."]", name, "Security", list(z))
+
+ if(R)
+ prisoner = R
+ R.fields["criminal"] = "Incarcerated"
+ var/mob/living/carbon/human/M = usr
+ var/rank = "UNKNOWN RANK"
+ if(istype(M) && M.wear_id)
+ var/obj/item/weapon/card/id/I = M.wear_id
+ rank = I.assignment
+ if(!R.fields["comments"] || !islist(R.fields["comments"])) //copied from security computer code because apparently these need to be initialized
+ R.fields["comments"] = list()
+ R.fields["comments"] += "Autogenerated by [name] on [current_date_string] [worldtime2text()]
Sentenced to [timetoset/10] seconds for the charges of \"[logcharges]\" by [rank] [usr.name]."
+ update_all_mob_security_hud()
+
+ return 1
/obj/machinery/door_timer/initialize()
..()
@@ -91,6 +110,7 @@
/obj/machinery/door_timer/Destroy()
QDEL_NULL(Radio)
targets.Cut()
+ prisoner = null
return ..()
//Main door timer loop, if it's timing and time is >0 reduce time by 1.
@@ -166,6 +186,10 @@
// Reset releasetime
releasetime = 0
printed = 0
+ if(prisoner)
+ prisoner.fields["criminal"] = "Released"
+ update_all_mob_security_hud()
+ prisoner = null
for(var/obj/machinery/door/window/brigdoor/door in targets)
if(!door.density)
@@ -294,6 +318,7 @@
timer_start()
else
timer_end()
+ Radio.autosay("Timer stopped manually by [usr.name].", name, "Security", list(z))
else
if(href_list["tp"]) //adjust timer, close door if not already closed
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index aa345e29643..6cb866d27ed 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -142,8 +142,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/machinery/hologram/holopad/proc/clear_holo()
// hologram.set_light(0)//Clear lighting. //handled by the lighting controller when its ower is deleted
- qdel(hologram)//Get rid of hologram.
- hologram = null
+ QDEL_NULL(hologram)//Get rid of hologram.
if(master.holo == src)
master.holo = null
master = null//Null the master, since no-one is using it now.
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index 65cd281340c..f7272e8e29a 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -68,6 +68,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
#define NEWSCASTER_D_NOTICE_FC 9 // D-Notice feed channel
#define NEWSCASTER_W_ISSUE_H 10 // Wanted Issue handler
#define NEWSCASTER_W_ISSUE 11 // STATIONWIDE WANTED ISSUE
+#define NEWSCASTER_JOBS 12 // Available jobs
/obj/machinery/newscaster
name = "newscaster"
@@ -94,6 +95,21 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
var/silence = 0
var/temp = null
var/temp_back_screen = NEWSCASTER_MAIN
+ var/list/jobblacklist = list(
+ /datum/job/ai,
+ /datum/job/cyborg,
+ /datum/job/captain,
+ /datum/job/judge,
+ /datum/job/blueshield,
+ /datum/job/nanotrasenrep,
+ /datum/job/pilot,
+ /datum/job/brigdoc,
+ /datum/job/mechanic,
+ /datum/job/barber,
+ /datum/job/chaplain,
+ /datum/job/ntnavyofficer,
+ /datum/job/ntspecops,
+ /datum/job/civilian)
var/static/REDACTED = "\[REDACTED\]"
light_range = 0
@@ -252,6 +268,14 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
data["criminal"] = news_network.wanted_issue.author
data["description"] = news_network.wanted_issue.body
data["photo"] = news_network.wanted_issue.img ? icon2base64(news_network.wanted_issue.img) : 0
+ if(12)
+ var/list/jobs = list()
+ data["jobs"] = jobs
+ for(var/datum/job/job in job_master.occupations)
+ if(job_blacklisted(job))
+ continue
+ if(job.is_position_available())
+ jobs[++jobs.len] = list("title" = job.title)
return data
/obj/machinery/newscaster/Topic(href, href_list)
@@ -535,6 +559,9 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
if(can_scan(usr))
scan_user(usr) //Newscaster scans you
+ else if(href_list["jobs"])
+ screen = NEWSCASTER_JOBS
+
nanomanager.update_uis(src)
return 1
@@ -748,6 +775,9 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
////////////////////////////////////helper procs
+/obj/machinery/newscaster/proc/job_blacklisted(datum/job/job)
+ return (job.type in jobblacklist)
+
/obj/machinery/newscaster/proc/scan_user(mob/user)
if(ishuman(user)) //User is a human
var/mob/living/carbon/human/human_user = user
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index eee465e062a..4fe0d47f12c 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -948,7 +948,7 @@
occupant.take_organ_damage(0,radiation_level*2 + rand(1,3))
if(radiation_level > 1)
occupant.take_organ_damage(0,radiation_level + rand(1,3))
- occupant.radiation += radiation_level*10
+ occupant.apply_effect(radiation_level*10, IRRADIATE)
/obj/machinery/suit_cycler/proc/finished_job()
var/turf/T = get_turf(src)
diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm
index 2aa0c2a5d59..592815bbc24 100644
--- a/code/game/machinery/telecomms/traffic_control.dm
+++ b/code/game/machinery/telecomms/traffic_control.dm
@@ -192,7 +192,7 @@
add_fingerprint(user)
user.set_machine(src)
- if(!allowed(user) && !emagged)
+ if(!allowed(user) && !emagged && !user.can_admin_interact())
to_chat(user, "Access Denied.")
return 0
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index f9de8b8d596..d6751d8d62a 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -1064,7 +1064,9 @@
/obj/item/clothing/shoes/singerb = 1,/obj/item/clothing/under/singerb = 1,
/obj/item/clothing/suit/hooded/carp_costume = 1,/obj/item/clothing/suit/hooded/bee_costume = 1,
/obj/item/clothing/suit/snowman = 1,/obj/item/clothing/head/snowman = 1,
- /obj/item/clothing/head/cueball = 1,/obj/item/clothing/under/scratch = 1)
+ /obj/item/clothing/head/cueball = 1,/obj/item/clothing/under/scratch = 1,
+ /obj/item/clothing/under/victdress = 1, /obj/item/clothing/under/victdress/red = 1, /obj/item/clothing/suit/victcoat = 1, /obj/item/clothing/suit/victcoat/red = 1,
+ /obj/item/clothing/under/victsuit = 1, /obj/item/clothing/under/victsuit/redblk = 1, /obj/item/clothing/under/victsuit/red = 1, /obj/item/clothing/suit/tailcoat = 1)
contraband = list(/obj/item/clothing/suit/judgerobe = 1,/obj/item/clothing/head/powdered_wig = 1,/obj/item/weapon/gun/magic/wand = 1, /obj/item/clothing/mask/balaclava=1, /obj/item/clothing/mask/horsehead = 2)
premium = list(/obj/item/clothing/suit/hgpirate = 1, /obj/item/clothing/head/hgpiratecap = 1, /obj/item/clothing/head/helmet/roman = 1, /obj/item/clothing/head/helmet/roman/legionaire = 1, /obj/item/clothing/under/roman = 1, /obj/item/clothing/shoes/roman = 1, /obj/item/weapon/shield/riot/roman = 1)
refill_canister = /obj/item/weapon/vending_refill/autodrobe
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index e27a97c796c..c73d72d0c2d 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -172,8 +172,7 @@
H.item_color = wash_color
H.name = new_softcap_name
H.desc = new_desc
- qdel(crayon)
- crayon = null
+ QDEL_NULL(crayon)
if( locate(/mob,contents) )
diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm
index 24b6b1822d9..b3e42bb968e 100644
--- a/code/game/mecha/mech_bay.dm
+++ b/code/game/mecha/mech_bay.dm
@@ -33,6 +33,9 @@
component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
component_parts += new /obj/item/stack/cable_coil(null, 1)
RefreshParts()
+ update_recharge_turf()
+
+/obj/machinery/mech_bay_recharge_port/proc/update_recharge_turf()
recharging_turf = get_step(loc, dir)
/obj/machinery/mech_bay_recharge_port/upgraded/New()
@@ -46,7 +49,7 @@
component_parts += new /obj/item/weapon/stock_parts/capacitor/super(null)
component_parts += new /obj/item/stack/cable_coil(null, 1)
RefreshParts()
- recharging_turf = get_step(loc, dir)
+ update_recharge_turf()
/obj/machinery/mech_bay_recharge_port/RefreshParts()
var/MC
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index 8ff0d7cfcf4..3871517b366 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -5,6 +5,7 @@
var/buckle_lying = -1 //bed-like behaviour, forces mob.lying = buckle_lying if != -1 //except -1 actually means "rotate 90 degrees to the left" as it is used by 1*buckle_lying.
var/buckle_requires_restraints = 0 //require people to be handcuffed before being able to buckle. eg: pipes
var/mob/living/buckled_mob = null
+ var/buckle_offset = 0
//Interaction
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index 1cd105367ed..6cf11f4f3c8 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -440,8 +440,7 @@ steam.start() -- spawns the effect
var/obj/chemholder
Destroy()
- qdel(chemholder)
- chemholder = null
+ QDEL_NULL(chemholder)
return ..()
New()
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 00eb1bd6884..ae198664806 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -558,3 +558,10 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
/obj/item/proc/is_crutch() //Does an item prop up a human mob and allow them to stand if they are missing a leg/foot?
return 0
+
+// Return true if you don't want regular throw handling
+/obj/item/proc/override_throw(mob/user, atom/target)
+ return FALSE
+
+/obj/item/proc/is_equivalent(obj/item/I)
+ return I == src
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index a3d302f1326..7b49607f9f4 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -73,7 +73,7 @@
temp = pick(graffiti)
else
temp = href_list["type"]
- if((usr.restrained() || usr.stat || usr.get_active_hand() != src))
+ if((usr.restrained() || usr.stat || !usr.is_in_active_hand(src)))
return
drawtype = temp
update_window(usr)
@@ -147,6 +147,29 @@
colour = "#DA00FF"
colourName = "purple"
+/obj/item/toy/crayon/random/New()
+ icon_state = pick(list("crayonred", "crayonorange", "crayonyellow", "crayongreen", "crayonblue", "crayonpurple"))
+ switch(icon_state)
+ if("crayonred")
+ colour = "#DA0000"
+ colourName = "red"
+ if("crayonorange")
+ colour = "#FF9300"
+ colourName = "orange"
+ if("crayonyellow")
+ colour = "#FFF200"
+ colourName = "yellow"
+ if("crayongreen")
+ colour = "#A8E61D"
+ colourName = "green"
+ if("crayonblue")
+ colour = "#00B7EF"
+ colourName = "blue"
+ if("crayonpurple")
+ colour = "#DA00FF"
+ colourName = "purple"
+ ..()
+
/obj/item/toy/crayon/white
icon_state = "crayonwhite"
colour = "#FFFFFF"
@@ -167,7 +190,7 @@
..()
/obj/item/toy/crayon/mime/Topic(href,href_list)
- if((usr.restrained() || usr.stat || usr.get_active_hand() != src))
+ if((usr.restrained() || usr.stat || usr.is_in_active_hand(src)))
return
if(href_list["color"])
if(colour != "#FFFFFF")
@@ -195,7 +218,7 @@
if(href_list["color"])
var/temp = input(usr, "Please select colour.", "Crayon colour") as color
- if((usr.restrained() || usr.stat || usr.get_active_hand() != src))
+ if((usr.restrained() || usr.stat || usr.is_in_active_hand(src)))
return
colour = temp
update_window(usr)
@@ -214,7 +237,7 @@
/obj/item/toy/crayon/spraycan/New()
..()
- name = "NanoTrasen-brand Rapid Paint Applicator"
+ name = "Nanotrasen-brand Rapid Paint Applicator"
update_icon()
/obj/item/toy/crayon/spraycan/attack_self(mob/living/user as mob)
diff --git a/code/game/objects/items/devices/autopsy.dm b/code/game/objects/items/devices/autopsy.dm
index 3bad7c09cf6..62e4354f238 100644
--- a/code/game/objects/items/devices/autopsy.dm
+++ b/code/game/objects/items/devices/autopsy.dm
@@ -74,6 +74,21 @@
if(O.trace_chemicals[V] > 0 && !chemtraces.Find(V))
chemtraces += V
+/obj/item/weapon/autopsy_scanner/attackby(obj/item/weapon/P, mob/user)
+ if(istype(P, /obj/item/weapon/pen))
+ var/dead_name = input("Insert name of deceased individual")
+ var/dead_rank = input("Insert rank of deceased individual")
+ var/dead_tod = input("Insert time of death")
+ var/dead_cause = input("Insert cause of death")
+ var/dead_chems = input("Insert any chemical traces")
+ var/dead_notes = input("Insert any relevant notes")
+ var/obj/item/weapon/paper/R = new(user.loc)
+ R.name = "Official Coroner's Report - [dead_name]"
+ R.info = "NanoTrasen Science Station Cyberiad - Coroner's Report
Name of Deceased: [dead_name]
Rank of Deceased: [dead_rank]
Time of Death: [dead_tod]
Cause of Death: [dead_cause]
Trace Chemicals: [dead_chems]
Additional Coroner's Notes: [dead_notes]
Coroner's Signature: "
+ playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1)
+ sleep(10)
+ user.put_in_hands(R)
+
/obj/item/weapon/autopsy_scanner/attack_self(mob/user)
if(!wdata.len && !chemtraces.len)
return
@@ -181,4 +196,4 @@
M.visible_message("[user] scans the wounds on [M]'s [S] with [src]")
add_data(S)
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm
index ff7eb0ac2cc..eef0b2072b8 100644
--- a/code/game/objects/items/devices/chameleonproj.dm
+++ b/code/game/objects/items/devices/chameleonproj.dm
@@ -43,8 +43,7 @@
if(active_dummy)
eject_all()
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6)
- qdel(active_dummy)
- active_dummy = null
+ QDEL_NULL(active_dummy)
to_chat(usr, "You deactivate \the [src].")
var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src))
T.icon = 'icons/effects/effects.dmi'
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index e309cae9bbe..de82f0b8c34 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -39,6 +39,11 @@
overcharged = 1
overlays += "overcharge"
+/obj/item/device/flash/random/New()
+ ..()
+ if(prob(25))
+ broken = 1
+ icon_state = "[initial(icon_state)]burnt"
/obj/item/device/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something.
broken = 1
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 99096ac2649..3c9c0211663 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -37,6 +37,7 @@ var/global/list/default_medbay_channels = list(
var/list/channels = list() //see communications.dm for full list. First channes is a "default" for :h
var/subspace_transmission = 0
var/syndie = 0//Holder to see if it's a syndicate encrpyed radio
+ var/disable_timer = 0 //How many times this is disabled by EMPs
var/is_special = 0 //For electropacks mostly, skips Topic() checks
@@ -599,12 +600,25 @@ var/global/list/default_medbay_channels = list(
else return
/obj/item/device/radio/emp_act(severity)
+ on = 0
+ disable_timer++
+ addtimer(src, "enable_radio", rand(100, 200))
+
+ if(listening)
+ visible_message("[src] buzzes violently!")
+
broadcasting = 0
listening = 0
for(var/ch_name in channels)
channels[ch_name] = 0
..()
+/obj/item/device/radio/proc/enable_radio()
+ if(disable_timer > 0)
+ disable_timer--
+ if(!disable_timer)
+ on = 1
+
///////////////////////////////
//////////Borg Radios//////////
///////////////////////////////
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index ef1589f50b7..b744edd79a6 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -7,7 +7,7 @@
slot_flags = SLOT_BELT
var/list/part = null
var/sabotaged = 0 //Emagging limbs can have repercussions when installed as prosthetics.
- var/model_info
+ var/model_info = "Unbranded"
dir = SOUTH
/obj/item/robot_parts/New(newloc, model)
@@ -23,33 +23,38 @@
else
name = "robot [initial(name)]"
+/obj/item/robot_parts/attack_self(mob/user)
+ var/choice = input(user, "Select the company appearance for this limb.", "Limb Company Selection") as null|anything in selectable_robolimbs
+ if(!choice)
+ return
+ if(loc != user)
+ return
+ model_info = choice
+ to_chat(usr, "You change the company limb model to [choice].")
+
/obj/item/robot_parts/l_arm
name = "left arm"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
icon_state = "l_arm"
part = list("l_arm","l_hand")
- model_info = 1
/obj/item/robot_parts/r_arm
name = "right arm"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
icon_state = "r_arm"
part = list("r_arm","r_hand")
- model_info = 1
/obj/item/robot_parts/l_leg
name = "left leg"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
icon_state = "l_leg"
part = list("l_leg","l_foot")
- model_info = 1
/obj/item/robot_parts/r_leg
name = "right leg"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
icon_state = "r_leg"
part = list("r_leg","r_foot")
- model_info = 1
/obj/item/robot_parts/chest
name = "torso"
@@ -80,6 +85,7 @@
name = "endoskeleton"
desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors."
icon_state = "robo_suit"
+ model_info = null
var/obj/item/robot_parts/l_arm/l_arm = null
var/obj/item/robot_parts/r_arm/r_arm = null
var/obj/item/robot_parts/l_leg/l_leg = null
@@ -108,6 +114,9 @@
forced_ai = null
return ..()
+/obj/item/robot_parts/robot_suit/attack_self(mob/user)
+ return
+
/obj/item/robot_parts/robot_suit/proc/updateicon()
overlays.Cut()
if(l_arm)
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index c5ecb18edec..1f8cb43fbb2 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -37,8 +37,7 @@
R.hands.icon_state = "nomod"
R.icon_state = "robot"
R.module.remove_subsystems_and_actions(R)
- qdel(R.module)
- R.module = null
+ QDEL_NULL(R.module)
R.camera.network.Remove(list("Engineering", "Medical", "Mining Outpost"))
R.rename_character(R.real_name, R.get_default_name("Default"))
diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm
index 96d5d381a72..9de205d483c 100644
--- a/code/game/objects/items/stacks/rods.dm
+++ b/code/game/objects/items/stacks/rods.dm
@@ -55,7 +55,7 @@ var/global/list/datum/stack_recipe/rod_recipes = list ( \
"You shape [src] into metal with the welding tool.", \
"You hear welding.")
- var/replace = user.get_inactive_hand() == src
+ var/replace = user.is_in_inactive_hand(src)
use(2)
if(get_amount() <= 0 && replace)
user.unEquip(src, 1)
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index d4d4ae7f48c..eeacb71e9b3 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -36,6 +36,23 @@
/obj/item/stack/attack_self(mob/user)
list_recipes(user)
+/obj/item/stack/attack_self_tk(mob/user)
+ list_recipes(user)
+
+/obj/item/stack/attack_tk(mob/user)
+ if(user.stat || !isturf(loc)) return
+ // Allow remote stack splitting, because telekinetic inventory managing
+ // is really cool
+ if(src in user.tkgrabbed_objects)
+ var/obj/item/stack/F = split(user, 1)
+ F.attack_tk(user)
+ if(src && user.machine == src)
+ spawn(0)
+ interact(user)
+ else
+ ..()
+
+
/obj/item/stack/proc/list_recipes(mob/user, recipes_sublist)
if(!recipes)
return
@@ -107,7 +124,7 @@
/obj/item/stack/Topic(href, href_list)
..()
- if(usr.incapacitated() || usr.get_active_hand() != src)
+ if(usr.incapacitated() || !usr.is_in_active_hand(src))
return 0
if(href_list["sublist"] && !href_list["make"])
@@ -124,6 +141,7 @@
var/datum/stack_recipe/R = recipes_list[text2num(href_list["make"])]
var/multiplier = text2num(href_list["multiplier"])
+ var/atom/creation_loc = (loc == usr) ? usr.loc : loc
if(!multiplier)
multiplier = 1
@@ -134,11 +152,11 @@
to_chat(usr, "You haven't got enough [src] to build \the [R.title]!")
return 0
- if(R.one_per_turf && (locate(R.result_type) in usr.loc))
+ if(R.one_per_turf && (locate(R.result_type) in creation_loc))
to_chat(usr, "There is another [R.title] here!")
return 0
- if(R.on_floor && !istype(usr.loc, /turf/simulated))
+ if(R.on_floor && !istype(creation_loc, /turf/simulated))
to_chat(usr, "\The [R.title] must be constructed on the floor!")
return 0
@@ -150,7 +168,7 @@
if(amount < R.req_amount * multiplier)
return
- var/atom/O = new R.result_type(usr.loc)
+ var/atom/O = new R.result_type(creation_loc)
O.dir = usr.dir
if(R.max_res_amount > 1)
var/obj/item/stack/new_item = O
@@ -215,7 +233,7 @@
return max_amount
/obj/item/stack/proc/split(mob/user, amt)
- var/obj/item/stack/F = new type(user, amt)
+ var/obj/item/stack/F = new type(loc, amt)
F.copy_evidences(src)
if(isliving(user))
add_fingerprint(user)
@@ -224,7 +242,7 @@
return F
/obj/item/stack/attack_hand(mob/user)
- if(user.get_inactive_hand() == src)
+ if(user.is_in_inactive_hand(src))
var/obj/item/stack/F = split(user, 1)
user.put_in_hands(F)
if(src && usr.machine == src)
@@ -241,7 +259,7 @@
return 1
var/to_transfer
- if(user.get_inactive_hand() == src)
+ if(user.is_in_inactive_hand(src))
var/desired = input("How much would you like to transfer from this stack?", "How much?", 1) as null|num
if(!desired)
return
@@ -267,4 +285,4 @@
fingerprints = from.fingerprints
fingerprintshidden = from.fingerprintshidden
fingerprintslast = from.fingerprintslast
- //TODO bloody overlay
\ No newline at end of file
+ //TODO bloody overlay
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 83b6d31a0ea..b4bacd5326a 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -1276,7 +1276,7 @@ obj/item/toy/cards/deck/syndicate/black
/obj/item/toy/minigibber
name = "miniature gibber"
- desc = "A miniature recreation of NanoTrasen's famous meat grinder."
+ desc = "A miniature recreation of Nanotrasen's famous meat grinder."
icon = 'icons/obj/toy.dmi'
icon_state = "minigibber"
attack_verb = list("grinded", "gibbed")
@@ -1288,8 +1288,7 @@ obj/item/toy/cards/deck/syndicate/black
if(stored_minature)
to_chat(user, "\The [src] makes a violent grinding noise as it tears apart the miniature figure inside!")
- qdel(stored_minature)
- stored_minature = null
+ QDEL_NULL(stored_minature)
playsound(user, 'sound/goonstation/effects/gib.ogg', 20, 1)
cooldown = world.time
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index 2623c70606e..3e79df2c213 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -6,7 +6,7 @@ RCD
*/
/obj/item/weapon/rcd
name = "rapid-construction-device (RCD)"
- desc = "A device used to rapidly build and deconstruct walls and floors."
+ desc = "A device used to rapidly build and deconstruct walls, floors and airlocks."
icon = 'icons/obj/tools.dmi'
icon_state = "rcd"
opacity = 0
@@ -68,7 +68,7 @@ RCD
if(istype(W, /obj/item/weapon/rcd_ammo))
var/obj/item/weapon/rcd_ammo/R = W
if((matter + R.ammoamt) > max_matter)
- to_chat(user, "The RCD cant hold any more matter-units.")
+ to_chat(user, "The RCD can't hold any more matter-units.")
return
matter += R.ammoamt
user.drop_item()
@@ -84,6 +84,9 @@ RCD
//Change the mode
ui_interact(user)
+/obj/item/weapon/rcd/attack_self_tk(mob/user)
+ ui_interact(user)
+
/obj/item/weapon/rcd/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = inventory_state)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
@@ -199,7 +202,8 @@ RCD
to_chat(user, "Building Wall ...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 20 * toolspeed, target = A))
- if(!useResource(3, user)) return 0
+ if(!useResource(3, user))
+ return 0
activate()
var/turf/AT = A
AT.ChangeTurf(/turf/simulated/wall)
@@ -212,7 +216,10 @@ RCD
to_chat(user, "Building Airlock...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 50 * toolspeed, target = A))
- if(!useResource(10, user)) return 0
+ for(var/obj/machinery/door/airlock/D in A.contents)
+ return 0
+ if(!useResource(10, user))
+ return 0
activate()
var/obj/machinery/door/airlock/T = new door_type(A)
T.name = door_name
@@ -233,7 +240,8 @@ RCD
to_chat(user, "Deconstructing Wall...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 40 * toolspeed, target = A))
- if(!useResource(5, user)) return 0
+ if(!useResource(5, user))
+ return 0
activate()
var/turf/AT = A
AT.ChangeTurf(/turf/simulated/floor/plating)
@@ -245,7 +253,8 @@ RCD
to_chat(user, "Deconstructing Floor...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 50 * toolspeed, target = A))
- if(!useResource(5, user)) return 0
+ if(!useResource(5, user))
+ return 0
activate()
var/turf/AT = A
AT.ChangeTurf(/turf/space)
@@ -257,7 +266,8 @@ RCD
to_chat(user, "Deconstructing Airlock...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 50 * toolspeed, target = A))
- if(!useResource(20, user)) return 0
+ if(!useResource(20, user))
+ return 0
activate()
qdel(A)
return 1
@@ -361,7 +371,7 @@ RCD
/obj/item/weapon/rcd/borg/New()
..()
- desc = "A device used to rapidly build and deconstruct walls and floors."
+ desc = "A device used to rapidly build and deconstruct walls, floors and airlocks."
canRwall = 1
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index 8705b86ea3a..2ac5fb102e1 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -337,105 +337,100 @@
update_icon()
defib.cooldowncheck(user)
return
- if(user.zone_sel && user.zone_sel.selecting == "chest")
- user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest.")
- busy = 1
- update_icon()
- if(do_after(user, 30 * toolspeed, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
- user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.")
- playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
- var/mob/dead/observer/ghost = H.get_ghost()
- if(ghost && !ghost.client)
- // In case the ghost's not getting deleted for some reason
- H.key = ghost.key
- log_runtime(EXCEPTION("Ghost of name [ghost.name] is bound to [H.real_name], but lacks a client. Deleting ghost."), src)
+ user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest.")
+ busy = 1
+ update_icon()
+ if(do_after(user, 30 * toolspeed, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
+ user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.")
+ playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
+ var/mob/dead/observer/ghost = H.get_ghost()
+ if(ghost && !ghost.client)
+ // In case the ghost's not getting deleted for some reason
+ H.key = ghost.key
+ log_runtime(EXCEPTION("Ghost of name [ghost.name] is bound to [H.real_name], but lacks a client. Deleting ghost."), src)
- qdel(ghost)
- ghost = null
- var/tplus = world.time - H.timeofdeath
- var/tlimit = 1800 //past this much time the patient is unrecoverable (in deciseconds)
- var/tloss = 600 //brain damage starts setting in on the patient after some time left rotting
- var/total_burn = 0
- var/total_brute = 0
- if(do_after(user, 20 * toolspeed, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
- for(var/obj/item/carried_item in H.contents)
- if(istype(carried_item, /obj/item/clothing/suit/space))
- if(!defib.combat)
- user.visible_message("[defib] buzzes: Patient's chest is obscured. Operation aborted.")
- playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
- busy = 0
- update_icon()
- return
- if(H.undergoing_cardiac_arrest())
- if(!H.get_int_organ(/obj/item/organ/internal/heart) && !H.get_int_organ(/obj/item/organ/internal/brain/slime)) //prevents defibing someone still alive suffering from a heart attack attack if they lack a heart
- user.visible_message("[defib] buzzes: Resuscitation failed - Failed to pick up any heart electrical activity.")
+ QDEL_NULL(ghost)
+ var/tplus = world.time - H.timeofdeath
+ var/tlimit = 1800 //past this much time the patient is unrecoverable (in deciseconds)
+ var/tloss = 600 //brain damage starts setting in on the patient after some time left rotting
+ var/total_burn = 0
+ var/total_brute = 0
+ if(do_after(user, 20 * toolspeed, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
+ for(var/obj/item/carried_item in H.contents)
+ if(istype(carried_item, /obj/item/clothing/suit/space))
+ if(!defib.combat)
+ user.visible_message("[defib] buzzes: Patient's chest is obscured. Operation aborted.")
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
busy = 0
update_icon()
return
- else
- H.set_heartattack(FALSE)
- user.visible_message("[defib] pings: Cardiac arrhythmia corrected.")
- M.visible_message("[M]'s body convulses a bit.")
- playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
- playsound(get_turf(src), "bodyfall", 50, 1)
- playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
- defib.deductcharge(revivecost)
- busy = 0
- cooldown = 1
- update_icon()
- defib.cooldowncheck(user)
- return
- if(H.stat == DEAD)
- var/health = H.health
- M.visible_message("[M]'s body convulses a bit.")
- playsound(get_turf(src), "bodyfall", 50, 1)
- playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
- for(var/obj/item/organ/external/O in H.bodyparts)
- total_brute += O.brute_dam
- total_burn += O.burn_dam
- if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations) && (H.get_int_organ(/obj/item/organ/internal/heart) || H.get_int_organ(/obj/item/organ/internal/brain/slime)))
- tobehealed = min(health + threshold, 0) // It's HILARIOUS without this min statement, let me tell you
- tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived
- H.adjustOxyLoss(tobehealed)
- H.adjustToxLoss(tobehealed)
- H.adjustFireLoss(tobehealed)
- H.adjustBruteLoss(tobehealed)
- user.visible_message("[defib] pings: Resuscitation successful.")
- playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
- H.update_revive(FALSE)
- H.KnockOut(FALSE)
- H.Paralyse(5)
- H.emote("gasp")
- if(tplus > tloss)
- H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))))
- defib.deductcharge(revivecost)
- add_logs(user, M, "revived", object="defibrillator")
- else
- if(tplus > tlimit|| !H.get_int_organ(/obj/item/organ/internal/heart))
- user.visible_message("[defib] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.")
- else if(total_burn >= 180 || total_brute >= 180)
- user.visible_message("[defib] buzzes: Resuscitation failed - Severe tissue damage detected.")
- else if(ghost)
- user.visible_message("[defib] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.")
- to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)")
- window_flash(ghost.client)
- ghost << sound('sound/effects/genetics.ogg')
- else
- user.visible_message("[defib] buzzes: Resuscitation failed.")
- playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
- defib.deductcharge(revivecost)
- update_icon()
- cooldown = 1
- defib.cooldowncheck(user)
- else
- user.visible_message("[defib] buzzes: Patient is not in a valid state. Operation aborted.")
+ if(H.undergoing_cardiac_arrest())
+ if(!H.get_int_organ(/obj/item/organ/internal/heart) && !H.get_int_organ(/obj/item/organ/internal/brain/slime)) //prevents defibing someone still alive suffering from a heart attack attack if they lack a heart
+ user.visible_message("[defib] buzzes: Resuscitation failed - Failed to pick up any heart electrical activity.")
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
- busy = 0
- update_icon()
- else
- to_chat(user, "You need to target your patient's chest with [src].")
- return
+ busy = 0
+ update_icon()
+ return
+ else
+ H.set_heartattack(FALSE)
+ user.visible_message("[defib] pings: Cardiac arrhythmia corrected.")
+ M.visible_message("[M]'s body convulses a bit.")
+ playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
+ playsound(get_turf(src), "bodyfall", 50, 1)
+ playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
+ defib.deductcharge(revivecost)
+ busy = 0
+ cooldown = 1
+ update_icon()
+ defib.cooldowncheck(user)
+ return
+ if(H.stat == DEAD)
+ var/health = H.health
+ M.visible_message("[M]'s body convulses a bit.")
+ playsound(get_turf(src), "bodyfall", 50, 1)
+ playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
+ for(var/obj/item/organ/external/O in H.bodyparts)
+ total_brute += O.brute_dam
+ total_burn += O.burn_dam
+ if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations) && (H.get_int_organ(/obj/item/organ/internal/heart) || H.get_int_organ(/obj/item/organ/internal/brain/slime)))
+ tobehealed = min(health + threshold, 0) // It's HILARIOUS without this min statement, let me tell you
+ tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived
+ H.adjustOxyLoss(tobehealed)
+ H.adjustToxLoss(tobehealed)
+ H.adjustFireLoss(tobehealed)
+ H.adjustBruteLoss(tobehealed)
+ user.visible_message("[defib] pings: Resuscitation successful.")
+ playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
+ H.update_revive(FALSE)
+ H.KnockOut(FALSE)
+ H.Paralyse(5)
+ H.emote("gasp")
+ if(tplus > tloss)
+ H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))))
+ defib.deductcharge(revivecost)
+ add_logs(user, M, "revived", object="defibrillator")
+ else
+ if(tplus > tlimit|| !H.get_int_organ(/obj/item/organ/internal/heart))
+ user.visible_message("[defib] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.")
+ else if(total_burn >= 180 || total_brute >= 180)
+ user.visible_message("[defib] buzzes: Resuscitation failed - Severe tissue damage detected.")
+ else if(ghost)
+ user.visible_message("[defib] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.")
+ to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)")
+ window_flash(ghost.client)
+ ghost << sound('sound/effects/genetics.ogg')
+ else
+ user.visible_message("[defib] buzzes: Resuscitation failed.")
+ playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
+ defib.deductcharge(revivecost)
+ update_icon()
+ cooldown = 1
+ defib.cooldowncheck(user)
+ else
+ user.visible_message("[defib] buzzes: Patient is not in a valid state. Operation aborted.")
+ playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
+ busy = 0
+ update_icon()
/obj/item/weapon/borg_defib
name = "defibrillator paddles"
@@ -487,80 +482,75 @@
cooldown = 0
update_icon()
return
- if(user.zone_sel && user.zone_sel.selecting == "chest")
- user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest.")
- busy = 1
- update_icon()
- if(do_after(user, 30 * toolspeed, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
- user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.")
- playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
- var/mob/dead/observer/ghost = H.get_ghost()
- if(ghost && !ghost.client)
- // In case the ghost's not getting deleted for some reason
- H.key = ghost.key
- log_runtime(EXCEPTION("Ghost of name [ghost.name] is bound to [H.real_name], but lacks a client. Deleting ghost."), H)
+ user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest.")
+ busy = 1
+ update_icon()
+ if(do_after(user, 30 * toolspeed, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
+ user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.")
+ playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
+ var/mob/dead/observer/ghost = H.get_ghost()
+ if(ghost && !ghost.client)
+ // In case the ghost's not getting deleted for some reason
+ H.key = ghost.key
+ log_runtime(EXCEPTION("Ghost of name [ghost.name] is bound to [H.real_name], but lacks a client. Deleting ghost."), H)
- qdel(ghost)
- ghost = null
- var/tplus = world.time - H.timeofdeath
- var/tlimit = 1800 //past this much time the patient is unrecoverable (in deciseconds)
- var/tloss = 600 //brain damage starts setting in on the patient after some time left rotting
- var/total_burn = 0
- var/total_brute = 0
- if(do_after(user, 20 * toolspeed, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
- if(H.stat == 2)
- var/health = H.health
- M.visible_message("[M]'s body convulses a bit.")
- playsound(get_turf(src), "bodyfall", 50, 1)
- playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
- for(var/obj/item/organ/external/O in H.bodyparts)
- total_brute += O.brute_dam
- total_burn += O.burn_dam
- if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations))
- tobehealed = min(health + threshold, 0) // It's HILARIOUS without this min statement, let me tell you
- tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived
- H.adjustOxyLoss(tobehealed)
- H.adjustToxLoss(tobehealed)
- H.adjustFireLoss(tobehealed)
- H.adjustBruteLoss(tobehealed)
- user.visible_message("[user] pings: Resuscitation successful.")
- playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
- H.update_revive(FALSE)
- H.KnockOut(FALSE)
- H.Paralyse(5)
- H.emote("gasp")
- if(tplus > tloss)
- H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))))
- if(isrobot(user))
- var/mob/living/silicon/robot/R = user
- R.cell.use(revivecost)
- add_logs(user, M, "revived", object="defibrillator")
- else
- if(tplus > tlimit)
- user.visible_message("[user] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.")
- else if(total_burn >= 180 || total_brute >= 180)
- user.visible_message("[user] buzzes: Resuscitation failed - Severe tissue damage detected.")
- else if(ghost)
- user.visible_message("[user] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.")
- to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)")
- window_flash(ghost.client)
- ghost << sound('sound/effects/genetics.ogg')
- else
- user.visible_message("[user] buzzes: Resuscitation failed.")
- playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
- if(isrobot(user))
- var/mob/living/silicon/robot/R = user
- R.cell.use(revivecost)
- update_icon()
- cooldown = 1
- spawn(50)
- cooldown = 0
- update_icon()
+ QDEL_NULL(ghost)
+ var/tplus = world.time - H.timeofdeath
+ var/tlimit = 1800 //past this much time the patient is unrecoverable (in deciseconds)
+ var/tloss = 600 //brain damage starts setting in on the patient after some time left rotting
+ var/total_burn = 0
+ var/total_brute = 0
+ if(do_after(user, 20 * toolspeed, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
+ if(H.stat == 2)
+ var/health = H.health
+ M.visible_message("[M]'s body convulses a bit.")
+ playsound(get_turf(src), "bodyfall", 50, 1)
+ playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
+ for(var/obj/item/organ/external/O in H.bodyparts)
+ total_brute += O.brute_dam
+ total_burn += O.burn_dam
+ if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations))
+ tobehealed = min(health + threshold, 0) // It's HILARIOUS without this min statement, let me tell you
+ tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived
+ H.adjustOxyLoss(tobehealed)
+ H.adjustToxLoss(tobehealed)
+ H.adjustFireLoss(tobehealed)
+ H.adjustBruteLoss(tobehealed)
+ user.visible_message("[user] pings: Resuscitation successful.")
+ playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
+ H.update_revive(FALSE)
+ H.KnockOut(FALSE)
+ H.Paralyse(5)
+ H.emote("gasp")
+ if(tplus > tloss)
+ H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))))
+ if(isrobot(user))
+ var/mob/living/silicon/robot/R = user
+ R.cell.use(revivecost)
+ add_logs(user, M, "revived", object="defibrillator")
else
- user.visible_message("[user] buzzes: Patient is not in a valid state. Operation aborted.")
+ if(tplus > tlimit)
+ user.visible_message("[user] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.")
+ else if(total_burn >= 180 || total_brute >= 180)
+ user.visible_message("[user] buzzes: Resuscitation failed - Severe tissue damage detected.")
+ else if(ghost)
+ user.visible_message("[user] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.")
+ to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)")
+ window_flash(ghost.client)
+ ghost << sound('sound/effects/genetics.ogg')
+ else
+ user.visible_message("[user] buzzes: Resuscitation failed.")
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
- busy = 0
- update_icon()
- else
- to_chat(user, "You need to target your patient's chest with [src].")
- return
+ if(isrobot(user))
+ var/mob/living/silicon/robot/R = user
+ R.cell.use(revivecost)
+ update_icon()
+ cooldown = 1
+ spawn(50)
+ cooldown = 0
+ update_icon()
+ else
+ user.visible_message("[user] buzzes: Patient is not in a valid state. Operation aborted.")
+ playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
+ busy = 0
+ update_icon()
diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm
index ea89aab651c..58de51085de 100644
--- a/code/game/objects/items/weapons/explosives.dm
+++ b/code/game/objects/items/weapons/explosives.dm
@@ -61,7 +61,7 @@
nadeassembly.attack_self(user)
return
var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num
- if(user.get_active_hand() == src)
+ if(user.is_in_active_hand(src))
newtime = Clamp(newtime, 10, 60000)
det_time = newtime
to_chat(user, "Timer set for [det_time] seconds.")
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index f02eb57ae8b..024783359b5 100644
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -62,7 +62,7 @@
/obj/item/weapon/flamethrower/afterattack(atom/target, mob/user, flag)
if(flag) return // too close
// Make sure our user is still holding us
- if(user && user.get_active_hand() == src)
+ if(user && user.is_in_active_hand(src))
var/turf/target_turf = get_turf(target)
if(target_turf)
var/turflist = getline(user, target_turf)
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index 88abd66913f..a5998591d08 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -32,7 +32,7 @@
/*/obj/item/weapon/grenade/afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
if(istype(target, /obj/item/weapon/storage)) return ..() // Trying to put it in a full container
if(istype(target, /obj/item/weapon/gun/grenadelauncher)) return ..()
- if((user.get_active_hand() == src) && (!active) && (clown_check(user)) && target.loc != src.loc)
+ if((user.is_in_active_hand(src)) && (!active) && (clown_check(user)) && target.loc != src.loc)
to_chat(user, "You prime the [name]! [det_time/10] seconds!")
active = 1
icon_state = initial(icon_state) + "_active"
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index f22c706d4f5..0b7850bba1f 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -104,6 +104,10 @@
/obj/item/weapon/restraints/handcuffs/cable/white
color = COLOR_WHITE
+/obj/item/weapon/restraints/handcuffs/cable/random/New()
+ color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
+ ..()
+
/obj/item/weapon/restraints/handcuffs/alien
icon_state = "handcuffAlien"
diff --git a/code/game/objects/items/weapons/implants/implant_explosive.dm b/code/game/objects/items/weapons/implants/implant_explosive.dm
index c02c3ba9fcc..158cab57d88 100644
--- a/code/game/objects/items/weapons/implants/implant_explosive.dm
+++ b/code/game/objects/items/weapons/implants/implant_explosive.dm
@@ -159,6 +159,11 @@
return 0
to_chat(imp_in, "Your dusting implant activates!")
imp_in.visible_message("[imp_in] burns up in a flash!")
+ for(var/obj/item/I in imp_in.contents)
+ if(I == src)
+ continue
+ if(I.flags & NODROP)
+ qdel(I)
imp_in.dust()
/obj/item/weapon/implant/dust/emp_act(severity)
diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm
index 973f25e6d2f..88311c5f149 100644
--- a/code/game/objects/items/weapons/manuals.dm
+++ b/code/game/objects/items/weapons/manuals.dm
@@ -1183,9 +1183,9 @@
/obj/item/weapon/book/manual/faxes
name = "A Guide to Faxes"
- desc = "A NanoTrasen-approved guide to writing faxes"
+ desc = "A Nanotrasen-approved guide to writing faxes"
icon_state = "book6"
- author = "NanoTrasen"
+ author = "Nanotrasen"
title = "A Guide to Faxes"
dat = {"
@@ -1213,14 +1213,14 @@
Faxes are your main method of communicating with the NAS Trurl, better known as Central Command.
Faxes allow personnel on the station to maintain open lines of communication with the NAS Trurl, allowing for vital information to flow both ways.
Being written communications, proper grammar, syntax and typography is required, in addition to a signature and, if applicable, a stamp. Failure to sign faxes will lead to an automatic rejection.
- We at NanoTrasen provide Fax Machines to every Head of Staff, in addition to the Magistrate, NanoTrasen Representative, and Internal Affairs Agents.
+ We at Nanotrasen provide Fax Machines to every Head of Staff, in addition to the Magistrate, Nanotrasen Representative, and Internal Affairs Agents.
This means that we trust the recipients of these fax machines to only use them in the proper circumstances (see When to Fax?).
While it is up to the discretion of each individual person to decide when to fax Central Command, there are some simple guidelines on when to do this.
Firstly, any situation that can reasonably be solved on-site, should be handled on-site. Knowledge of Standard Operating Procedure is mandatory for everyone with access to a fax machine.
Resolving issues on-site not only leads to more expedient problem-solving, it also frees up company resources and provides valuable work experience for all parties involved.
- This means that you should work with the Heads of Staff concerning personnel and workplace issues, and attempt to resolve situations with them. If, for whatever reason, the relevent Head of Staff is not available or receptive, consider speaking with the Captain and/or NanoTrasen Representative.
+ This means that you should work with the Heads of Staff concerning personnel and workplace issues, and attempt to resolve situations with them. If, for whatever reason, the relevent Head of Staff is not available or receptive, consider speaking with the Captain and/or Nanotrasen Representative.
If, for whatever reason, these issues cannot be solved on-site, either due to incompetence or just plain refusal to cooperate, faxing Central Command becomes a viable option.
Secondly, station status reports should be sent occasionally, but never at the start of the shift. Remember, we assign personnel to the station. We do not need a repeat of what we just signed off on.
Thirdly, staff/departmental evaluations are always welcome, especially in cases of noticeable (in)competence. Just as a brilliant coworker can be rewarded, an incompetent one can be punished.
@@ -2487,7 +2487,7 @@
Foreword
Captain
Head of Personnel
- NanoTrasen Representative
+ Nanotrasen Representative
Blueshield Officer
AI
@@ -2507,9 +2507,9 @@
The Captain must keep the Nuclear Authentication Disk on their person at all times or, failing that, in the possession of the Head of Security or Blueshield;
The Captain is to attempt to resolve every issue that arises in Command locally before contacting Central Command;
The Captain is not permitted to carry their Antique Laser Gun or Space Armor unless there's an immediate emergency that requires attending to;
- The Captain, despite being in charge of the Cyberiad, is not independent from NanoTrasen. Any attempts to disregard general company policy are to be considered an instant condition for contract termination;
+ The Captain, despite being in charge of the Cyberiad, is not independent from Nanotrasen. Any attempts to disregard general company policy are to be considered an instant condition for contract termination;
The Captain may only promote personnel to a Acting Head of Staff position if there is no assigned Head of Staff associated with the Department. Said Acting Head of Staff must be a member of the Department they are to lead. See below for more information on Chain of Command;
- The Captain may not fire any Head of Staff without reasonable justification (ie, incompetency, criminal activity, or otherwise any action that endangers/compromises the station and/or crew). The Captain may not fire any Central Command VIPs (ie, Blueshield, Magistrate, NanoTrasen Representative) without permission from Central Command, unless they are blatantly acting against the well-being and safety of the crew and station.
+ The Captain may not fire any Head of Staff without reasonable justification (ie, incompetency, criminal activity, or otherwise any action that endangers/compromises the station and/or crew). The Captain may not fire any Central Command VIPs (ie, Blueshield, Magistrate, Nanotrasen Representative) without permission from Central Command, unless they are blatantly acting against the well-being and safety of the crew and station.
@@ -2518,7 +2518,7 @@
The Head of Personnel may not give any personnel increased access without authorization from the relevant Head of Staff. This includes the Head of Personnel. In addition, the Head of Personnel may only give Captain-Level access to someone if they are the Acting Captain. This access is to be removed when a proper Captain arrives on the station;
The Head of Personnel may not increase any Job Openings unless the relevant Head of Staff approves;
The Head of Personnel may not fire any personnel without authorization from the relevant Head of Staff, unless other conditions apply (see Space Law and General Standard Operating Procedure);
- The Head of Personnel may not promote any personnel to the following Jobs without authorization from Central Command: Barber, Brig Physician, NanoTrasen Representative, Blueshield, Security Pod Pilot, Mechanic and Magistrate; (This is due to them being karma locked. Do not promote people to these positions without approval from the Administrators);
+ The Head of Personnel may not promote any personnel to the following Jobs without authorization from Central Command: Barber, Brig Physician, Nanotrasen Representative, Blueshield, Security Pod Pilot, Mechanic and Magistrate; (This is due to them being karma locked. Do not promote people to these positions without approval from the Administrators);
The Head of Personnel is free to utilize paperwork at their discretion. However, during major station emergencies, expediency should take precedence over bureaucracy;
The Head of Personnel may not leave their office unmanned if there are personnel waiting in line. Failure to respond to personnel with a legitimate request within ten (10) minutes, either via radio or in person, is to be considered a breach of Standard Operating Procedure;
Despite nominally being in charge of Supply, the Head of Personnel should allow the Quartermaster to run the Department, unless they prove themselves to be incompetent/dangerous;
@@ -2526,13 +2526,13 @@
The Head of Personnel is not permitted to perform Security duty. The Head of Personnel is permitted to carry an Energy Gun, for self-defence only.
-
+
- - The NanoTrasen Representative is to ensure that every Department is following Standard Operating Procedure, up to and including the respective Head of Staff. If a Head of Staff is not available for a Department, the NanoTrasen Representative must ensure that the Captain appoints an Acting Head of Staff for said Department;
- - The NanoTrasen Representative must attempt to resolve any breach of Standard Operating Procedure locally before contacting Central Command. This is an imperative: Standard Operating Procedure should always be followed unless there is a very good reason not to;
- - The NanoTrasen Representative must, together with the Magistrate and Head of Security, ensure that Space Law is being followed and correctly applied;
- - The NanoTrasen Representative may not threaten the use of a fax in order to gain leverage over any personnel, up to and including Command. In addition they may not threaten to fire, or have Central Command, fire anyone, unless they actually possess a demotion note;
- - The NanoTrasen Representative is permitted to carry their Stun-Cane, or a Telescopic Baton if the Stun-Cane is lost.
+ - The Nanotrasen Representative is to ensure that every Department is following Standard Operating Procedure, up to and including the respective Head of Staff. If a Head of Staff is not available for a Department, the Nanotrasen Representative must ensure that the Captain appoints an Acting Head of Staff for said Department;
+ - The Nanotrasen Representative must attempt to resolve any breach of Standard Operating Procedure locally before contacting Central Command. This is an imperative: Standard Operating Procedure should always be followed unless there is a very good reason not to;
+ - The Nanotrasen Representative must, together with the Magistrate and Head of Security, ensure that Space Law is being followed and correctly applied;
+ - The Nanotrasen Representative may not threaten the use of a fax in order to gain leverage over any personnel, up to and including Command. In addition they may not threaten to fire, or have Central Command, fire anyone, unless they actually possess a demotion note;
+ - The Nanotrasen Representative is permitted to carry their Stun-Cane, or a Telescopic Baton if the Stun-Cane is lost.
@@ -2547,14 +2547,14 @@
The following are procedures for AI Maintenance:
- Only the Captain or Research Director may enter the AI Upload to perform Law Changes (see below), and only the Captain, Research Director or Chief Engineer may enter the AI Core to perform a Carding (see below);
- - No Law Changes are to be performed without approval from the Captain and Research Director. The only Lawsets to be used are those provided by NanoTrasen. Failure to legally perform a Law Change is to be considered Sabotage. Command must be informed prior to the Law Change, and all objections must be taken into consideration. If the number of Command personnel opposing the Law Change is greater than the number of Command personnel in favour, the Law Change is not to be done. If the Law Change is performed, the crew is to be immediately informed of the new Law(s);
+ - No Law Changes are to be performed without approval from the Captain and Research Director. The only Lawsets to be used are those provided by Nanotrasen. Failure to legally perform a Law Change is to be considered Sabotage. Command must be informed prior to the Law Change, and all objections must be taken into consideration. If the number of Command personnel opposing the Law Change is greater than the number of Command personnel in favour, the Law Change is not to be done. If the Law Change is performed, the crew is to be immediately informed of the new Law(s);
- The AI may not be Carded unless it it clearly malfunctioning or subverted. However, any member of Command may card it if the AI agrees to it, either at the end of the shift, or due to external circumstances (such as massive damage to the AI Satellite);
- The AI Upload and Minisat Antechamber Turrets are to be kept on Non-Lethal in Code Green and Code Blue. The AI Core Turrets are to be kept on Lethal at all times. If a legal Law Change or Carding is occurring, the Turrets are to be disabled;
- If the AI Unit is not malfunctioning or subverted, any attempt at performing an illegal Carding or Law Change is to be responded to with non-lethal force. If the illegal attempts persist, and the perpetrator is demonstrably hostile, lethal force from Command/Security is permitted;
- Freeform Laws are only to be added if absolutely necessary due to external circumstances (such as major station emergencies). Adding unnecessary Freeform Laws is not permitted. Exception is made if the AI Unit and majority of Command agree to the Freeform Law that is proposed;
- - Any use of the "Purge" Module is to be followed by the upload of a NanoTrasen-approved Lawset immediately. AI Units must be bound to a Lawset at all times.
+ - Any use of the "Purge" Module is to be followed by the upload of a Nanotrasen-approved Lawset immediately. AI Units must be bound to a Lawset at all times.