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?).
  • 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.

  • Head of Personnel


    @@ -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.

  • -

    NanoTrasen Representative


    +

    Nanotrasen Representative


      -
    1. 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;
    2. -
    3. 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;
    4. -
    5. The NanoTrasen Representative must, together with the Magistrate and Head of Security, ensure that Space Law is being followed and correctly applied;
    6. -
    7. 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;
    8. -
    9. The NanoTrasen Representative is permitted to carry their Stun-Cane, or a Telescopic Baton if the Stun-Cane is lost.
    10. +
    11. 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;
    12. +
    13. 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;
    14. +
    15. The Nanotrasen Representative must, together with the Magistrate and Head of Security, ensure that Space Law is being followed and correctly applied;
    16. +
    17. 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;
    18. +
    19. The Nanotrasen Representative is permitted to carry their Stun-Cane, or a Telescopic Baton if the Stun-Cane is lost.

    Blueshield Officer


    @@ -2547,14 +2547,14 @@ The following are procedures for AI Maintenance:
    1. 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);
    2. -
    3. 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);
    4. +
    5. 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);
    6. 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);
    7. 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;
    8. 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;
    9. 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;
    10. -
    11. 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.
    12. +
    13. 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.

    - "} \ No newline at end of file + "} diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm new file mode 100644 index 00000000000..de5cb54f722 --- /dev/null +++ b/code/game/objects/items/weapons/rpd.dm @@ -0,0 +1,262 @@ +/*Contains: + Rapid Pipe Dispenser +*/ + +#define SIMPLE_CAP 20 +#define SUPPLY_CAP 32 +#define SCRUBBERS_CAP 33 +#define HE_EXCHANGER 17 +#define CONNECTOR 4 +#define UNARY_VENT 7 +#define PASSIVE_VENT 37 +#define GAS_SCRUBBER 10 +#define INJECTOR 34 +#define GAS_SENSOR 98 +#define METER 99 +#define DISPOSALS_JUNCTION 2 +#define ATMOS_MODE 1 +#define DISPOSALS_MODE 2 +#define ROTATION_MODE 3 +#define FLIP_MODE 4 +#define DELETE_MODE 5 +#define ATMOS_PIPING 1 +#define SUPPLY_PIPING 2 +#define SCRUBBERS_PIPING 3 +#define DEVICES 4 +#define HEAT_PIPING 5 + +/obj/item/weapon/rpd + name = "rapid pipe dispenser" + desc = "This device can rapidly dispense atmospherics and disposals piping, manipulate loose piping, and recycle any detached pipes it is applied to." + icon = 'icons/obj/tools.dmi' + icon_state = "rpd" + opacity = 0 + density = 0 + anchored = 0 + flags = CONDUCT + force = 10 + throwforce = 10 + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_NORMAL + materials = list(MAT_METAL = 30000, MAT_GLASS = 5000) + origin_tech = "engineering=4;materials=2" + var/datum/effect/system/spark_spread/spark_system + var/lastused + var/iconrotation = 0 //used to orient icons and pipes + var/mode = 1 //Disposals, atmospherics, etc. + var/pipetype = 1//For nanoUI menus + var/whatpipe = 0 //What kind of pipe is it? See code/game/machinery/pipe/construction.dm for a list of defines + var/whatdpipe = 0 //What kind of disposals pipe is it? See code/game/machinery/pipe/dispenser.dm for a list of defines + var/spawndelay = 4 //How long should we have to wait between dispensing pipes? + var/walldelay = 40 //How long should drilling into a wall take? + +/obj/item/weapon/rpd/New() + ..() + spark_system = new /datum/effect/system/spark_spread() + spark_system.set_up(1, 0, src) + spark_system.attach(src) + +//Procs + +/obj/item/weapon/rpd/proc/Activaterpd(delay) + playsound(loc, "sound/machines/click.ogg", 50, 1) + if(prob(15)) + spark_system.start() + if(delay) + lastused = world.time + +/obj/item/weapon/rpd/proc/Manipulatepipes(subject, atmosverb, disposalsverb) + if(istype(subject, /obj/item/pipe)) + call(subject, atmosverb)() + else if(istype(subject, /obj/structure/disposalconstruct/)) + call(subject, disposalsverb)() + +//Lists of things + +var/list/pipelist = list( //id refers to the pipe_type found in construction.dm, icon refers to the name of the icon state in icons/obj/pipe-item.dmi. Icons are made with the asset-cache + list("pipename" = "Straight pipe", "id" = 0, "category" = ATMOS_PIPING, "orientations" = 2, "icon" = "simple"), + list("pipename" = "Bent pipe", "id" = 1, "category" = ATMOS_PIPING, "orientations" = 4, "icon" = "simple", "bendy" = 1), + list("pipename" = "T-manifold", "id" = 5, "category" = ATMOS_PIPING, "orientations" = 4, "icon" = "manifold"), + list("pipename" = "4-way manifold", "id" = 19, "category" = ATMOS_PIPING, "orientations" = 1, "icon" = "manifold4w"), + list("pipename" = "Pipe cap", "id" = 20, "category" = ATMOS_PIPING, "orientations" = 4, "icon" = "cap"), + list("pipename" = "Manual valve", "id" = 8, "category" = ATMOS_PIPING, "orientations" = 2, "icon" = "mvalve"), + list("pipename" = "Digital valve", "id" = 35, "category" = ATMOS_PIPING, "orientations" = 2, "icon" = "dvalve"), + list("pipename" = "Manual T-valve", "id" = 18, "category" = ATMOS_PIPING, "orientations" = 4, "icon" = "tvalve"), + list("pipename" = "Digital T-valve", "id" = 38, "category" = ATMOS_PIPING, "orientations" = 4, "icon" = "dtvalve"), + list("pipename" = "Straight supply pipe", "id" = 24, "category" = SUPPLY_PIPING, "orientations" = 2, "icon" = "simple"), + list("pipename" = "Bent supply pipe", "id" = 25, "category" = SUPPLY_PIPING, "orientations" = 4, "icon" = "simple", "bendy" = 1), + list("pipename" = "Supply T-manifold", "id" = 28, "category" = SUPPLY_PIPING, "orientations" = 4, "icon" = "manifold"), + list("pipename" = "4-way supply manifold", "id" = 30, "category" = SUPPLY_PIPING, "orientations" = 1, "icon" = "manifold4w"), + list("pipename" = "Supply pipe cap", "id" = 32, "category" = SUPPLY_PIPING, "orientations" = 4, "icon" = "cap"), + list("pipename" = "Straight scrubbers pipe", "id" = 26, "category" = SCRUBBERS_PIPING, "orientations" = 2, "icon" = "simple"), + list("pipename" = "Bent scrubbers pipe", "id" = 27, "category" = SCRUBBERS_PIPING, "orientations" = 4, "icon" = "simple", "bendy" = 1), + list("pipename" = "Scrubbers T-manifold", "id" = 29, "category" = SCRUBBERS_PIPING, "orientations" = 4, "icon" = "manifold"), + list("pipename" = "4-way scrubbers manifold", "id" = 31, "category" = SCRUBBERS_PIPING, "orientations" = 1, "icon" = "manifold4w"), + list("pipename" = "Scrubbers pipe cap", "id" = 33, "category" = SCRUBBERS_PIPING, "orientations" = 4, "icon" = "cap"), + list("pipename" = "Universal pipe adapter", "id" = 23, "category" = DEVICES, "orientations" = 2, "icon" = "universal"), + list("pipename" = "Connector", "id" = 4, "category" = DEVICES, "orientations" = 4, "icon" = "connector"), + list("pipename" = "Unary vent", "id" = 7, "category" = DEVICES, "orientations" = 4, "icon" = "uvent"), + list("pipename" = "Scrubber", "id" = 10, "category" = DEVICES, "orientations" = 4, "icon" = "scrubber"), + list("pipename" = "Gas pump", "id" = 9, "category" = DEVICES, "orientations" = 4, "icon" = "pump"), + list("pipename" = "Volume pump", "id" = 16, "category" = DEVICES, "orientations" = 4, "icon" = "volumepump"), + list("pipename" = "Passive gate", "id" = 15, "category" = DEVICES, "orientations" = 4, "icon" = "passivegate"), + list("pipename" = "Gas filter", "id" = 13, "category" = DEVICES, "orientations" = 4, "icon" = "filter"), + list("pipename" = "Gas mixer", "id" = 14, "category" = DEVICES, "orientations" = 4, "icon" = "mixer"), + list("pipename" = "Gas sensor", "id" = 98, "category" = DEVICES, "orientations" = 1, "icon" = "sensor"), + list("pipename" = "Meter", "id" = 99, "category" = DEVICES, "orientations" = 1, "icon" = "meter"), + list("pipename" = "Passive vent", "id" = 37, "category" = DEVICES, "orientations" = 4, "icon" = "passive vent"), + list("pipename" = "Dual-port vent pump", "id" = 36, "category" = DEVICES, "orientations" = 2, "icon" = "dual-port vent"), + list("pipename" = "Air injector", "id" = 34, "category" = DEVICES, "orientations" = 4, "icon" = "injector"), + list("pipename" = "Straight HE pipe", "id" = 2, "category" = HEAT_PIPING, "orientations" = 2, "icon" = "he"), + list("pipename" = "Bent HE pipe", "id" = 3, "category" = HEAT_PIPING, "orientations" = 4, "icon" = "he", "bendy" = 1), + list("pipename" = "Junction", "id" = 6, "category" = HEAT_PIPING, "orientations" = 4, "icon" = "junction"), + list("pipename" = "Heat exchanger", "id" = 17, "category" = HEAT_PIPING, "orientations" = 4, "icon" = "heunary")) +var/list/dpipelist = list( + list("pipename" = "Straight pipe", "id" = 0, "orientations" = 2, "icon" = "conpipe-s"), + list("pipename" = "Bent pipe", "id" = 1, "orientations" = 4, "icon" = "conpipe-c"), + list("pipename" = "Junction", "id" = 2, "orientations" = 4, "icon" = "conpipe-j1"), + list("pipename" = "Y-junction", "id" = 4, "orientations" = 4, "icon" = "conpipe-y"), + list("pipename" = "Trunk", "id" = 5, "orientations" = 4, "icon" = "conpipe-t"), + list("pipename" = "Bin", "id" = 6, "orientations" = 1, "icon" = "condisposal"), + list("pipename" = "Outlet", "id" = 7, "orientations" = 4, "icon" = "outlet"), + list("pipename" = "Chute", "id" = 8, "orientations" = 4, "icon" = "intake")) +var/list/mainmenu = list( + list("category" = "Atmospherics", "mode" = 1, "icon" = "wrench"), + list("category" = "Disposals", "mode" = 2, "icon" = "recycle"), + list("category" = "Rotate", "mode" = 3, "icon" = "rotate-right"), + list("category" = "Flip", "mode" = 4, "icon" = "exchange"), + list("category" = "Recycle", "mode" = 5, "icon" = "trash")) +var/list/pipemenu = list( + list("pipecategory" = "Normal", "pipemode" = 1), + list("pipecategory" = "Supply", "pipemode" = 2), + list("pipecategory" = "Scrubber", "pipemode" = 3), + list("pipecategory" = "Devices", "pipemode" = 4), + list("pipecategory" = "Heat exchange", "pipemode" = 5)) + +//NanoUI stuff + +/obj/item/weapon/rpd/attack_self(mob/user) + ui_interact(user) + +/obj/item/weapon/rpd/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) + ui = new(user, src, ui_key, "rpd.tmpl", "[name]", 400, 650, state = state) + ui.open() + ui.set_auto_update(1) + +/obj/item/weapon/rpd/ui_data(mob/user, ui_key = "main", datum/topic_state/state = inventory_state) + var/data[0] + data["dpipelist"] = dpipelist + data["iconrotation"] = iconrotation + data["mainmenu"] = mainmenu + data["mode"] = mode + data["pipelist"] = pipelist + data["pipemenu"] = pipemenu + data["pipetype"] = pipetype + data["whatdpipe"] = whatdpipe + data["whatpipe"] = whatpipe + return data + +/obj/item/weapon/rpd/Topic(href, href_list, nowindow, state) + ..() + if(href_list["iconrotation"]) + iconrotation = text2num(sanitize(href_list["iconrotation"])) + else if(href_list["whatpipe"]) + whatpipe = text2num(sanitize(href_list["whatpipe"])) + else if(href_list["whatdpipe"]) + whatdpipe = text2num(sanitize(href_list["whatdpipe"])) + else if(href_list["pipetype"]) + pipetype = text2num(sanitize(href_list["pipetype"])) + else if(href_list["mode"]) + mode = text2num(sanitize(href_list["mode"])) + else + return + nanomanager.update_uis(src) + +//What the RPD actually does + +/obj/item/weapon/rpd/afterattack(atom/target, mob/user, proximity) + ..() + var/turf/T = get_turf(target) + if(src.loc != user || ismob(target) || istype(target, /obj/structure/window) || !proximity || world.time < lastused + spawndelay) + return + if(mode == ATMOS_MODE && !istype(T, /turf/simulated/shuttle)) //No pipes on shuttles nerds + if(istype(T, /turf/simulated/wall)) //Drilling into walls takes time + playsound(loc, "sound/weapons/circsawhit.ogg", 50, 1) + user.visible_message("[user] starts drilling a hole in [T]...", "You start drilling a hole in [T]...", "You hear a drill.") + if(!do_after(user, walldelay, target = T)) + return + user.visible_message("[user] finishes drilling a hole in [T]!", "You finish drilling a hole in [T]!", "You hear clanking.") + var/obj/item/pipe/P + if(whatpipe == GAS_SENSOR) + P = new /obj/item/pipe_gsensor(T) + else if(whatpipe == METER) + P = new /obj/item/pipe_meter(T) + else + P = new(T, pipe_type = whatpipe, dir = user.dir) + if(iconrotation == 0 && P.is_bent_pipe()) //Automatic rotation of dispensed pipes + P.dir = turn(user.dir, 135) + else if(iconrotation == 0 && P.pipe_type in list(CONNECTOR, UNARY_VENT, GAS_SCRUBBER, HE_EXCHANGER, SIMPLE_CAP, SUPPLY_CAP, SCRUBBERS_CAP, INJECTOR, PASSIVE_VENT)) //Some pipes dispense oppositely to what you'd expect, but we don't want to do anything if they selected a direction + P.flip() + else if(iconrotation != 0 && P.is_bent_pipe()) //If they selected a rotation and the pipe is bent + P.dir = turn(iconrotation, -45) + else if(iconrotation != 0) + P.dir = iconrotation + to_chat(user, "[src] rapidly dispenses [P]!") + Activaterpd(1) + else if(mode == DISPOSALS_MODE && !istype(T, /turf/simulated/shuttle)) + if(istype(T, /turf/simulated/wall)) //No disposals pipes on walls + to_chat(user, "That type of pipe won't fit on [T]!") + return + var/obj/structure/disposalconstruct/P = new(T) //Now we make the pipe + P.dir = iconrotation + P.ptype = whatdpipe + if(iconrotation == 0) //Automatic rotation + P.dir = user.dir + if(iconrotation == 0 && whatdpipe != DISPOSALS_JUNCTION) //Disposals pipes are in the opposite direction to atmos pipes, so we need to flip them. Junctions don't have this quirk though + P.flip() + P.update() + to_chat(user, "[src] rapidly dispenses [P]!") + Activaterpd(1) + else if(mode == ROTATION_MODE) + for(var/obj/W in T) + Manipulatepipes(W, /obj/item/pipe/verb/rotate, /obj/structure/disposalconstruct/verb/rotate) + else if(mode == FLIP_MODE) + for(var/obj/W in T) + Manipulatepipes(W, /obj/item/pipe/verb/flip, /obj/structure/disposalconstruct/verb/flip) + else if(mode == DELETE_MODE) + var/eaten + for(var/obj/W in T) + if(istype(W, /obj/item/pipe) || istype(W, /obj/item/pipe_meter) || istype(W, /obj/item/pipe_gsensor) || istype(W, /obj/structure/disposalconstruct) && !W.anchored) + QDEL_NULL(W) + eaten = TRUE + if(eaten) + to_chat(user, "[src] sucks up the loose pipes on [T].") + Activaterpd() + else + to_chat(user, "There were no loose pipes on [T].") + +#undef SIMPLE_CAP +#undef SUPPLY_CAP +#undef SCRUBBERS_CAP +#undef HE_EXCHANGER +#undef CONNECTOR +#undef UNARY_VENT +#undef PASSIVE_VENT +#undef GAS_SCRUBBER +#undef INJECTOR +#undef GAS_SENSOR +#undef METER +#undef DISPOSALS_JUNCTION +#undef ATMOS_MODE +#undef DISPOSALS_MODE +#undef ROTATION_MODE +#undef FLIP_MODE +#undef DELETE_MODE +#undef ATMOS_PIPING +#undef SUPPLY_PIPING +#undef SCRUBBERS_PIPING +#undef DEVICES +#undef HEAT_PIPING diff --git a/code/game/objects/items/weapons/scissors.dm b/code/game/objects/items/weapons/scissors.dm index e5bd30fe609..362fcf1c2d3 100644 --- a/code/game/objects/items/weapons/scissors.dm +++ b/code/game/objects/items/weapons/scissors.dm @@ -95,7 +95,6 @@ user.visible_message("[user] finishes cutting [M]'s hair!") /obj/item/weapon/scissors/safety //Totally safe, I assure you. - name = "safety scissors" desc = "The blades of the scissors appear to be made of some sort of ultra-strong metal alloy." force = 18 //same as e-daggers var/is_cutting = 0 //to prevent spam clicking this for huge accumulation of losebreath. diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index d8de4ee7c53..b5258eaeb27 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -317,7 +317,7 @@ /obj/item/weapon/storage/fancy/rollingpapers name = "rolling paper pack" - desc = "A pack of NanoTrasen brand rolling papers." + desc = "A pack of Nanotrasen brand rolling papers." w_class = WEIGHT_CLASS_TINY icon = 'icons/obj/cigarettes.dmi' icon_state = "cig_paper_pack" diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 21ea7c33993..5931696b599 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -478,7 +478,7 @@ /obj/item/weapon/storage/attack_self(mob/user as mob) //Clicking on itself will empty it, if it has the verb to do that. - if(user.get_active_hand() == src) + if(user.is_in_active_hand(src)) if(src.verbs.Find(/obj/item/weapon/storage/verb/quick_empty)) src.quick_empty() return diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index 0a984821fad..c07c658a7bf 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -128,7 +128,7 @@ Frequency: if(turfs.len) L["None (Dangerous)"] = pick(turfs) var/t1 = input(user, "Please select a teleporter to lock in on.", "Hand Teleporter") as null|anything in L - if(!t1 || (user.get_active_hand() != src || user.stat || user.restrained())) + if(!t1 || (user.is_in_active_hand(src) || user.stat || user.restrained())) return if(active_portals >= 3) user.show_message("\The [src] is recharging!") diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 8aabce1eb54..2f57e9157ee 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -241,8 +241,7 @@ /obj/item/weapon/wirecutters/attack(mob/living/carbon/C, mob/user) if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/weapon/restraints/handcuffs/cable)) user.visible_message("[user] cuts [C]'s restraints with [src]!") - qdel(C.handcuffed) - C.handcuffed = null + QDEL_NULL(C.handcuffed) if(C.buckled && C.buckled.buckle_requires_restraints) C.buckled.unbuckle_mob(C) C.update_handcuffed() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/chaplain.dm b/code/game/objects/structures/crates_lockers/closets/secure/chaplain.dm index 7c58f4a2b1a..d7fdab50e5a 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/chaplain.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/chaplain.dm @@ -15,6 +15,9 @@ new /obj/item/clothing/shoes/black(src) new /obj/item/clothing/suit/hooded/nun(src) new /obj/item/clothing/suit/hooded/chaplain_hoodie(src) + new /obj/item/clothing/suit/hooded/monk(src) + new /obj/item/clothing/suit/witchhunter(src) + new /obj/item/clothing/head/witchhunter_hat(src) new /obj/item/clothing/suit/holidaypriest(src) new /obj/item/clothing/under/wedding/bride_white(src) new /obj/item/weapon/storage/backpack/cultpack (src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index d130b22074c..58cad5e5f36 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -34,6 +34,7 @@ new /obj/item/taperoll/engineering(src) new /obj/item/clothing/head/beret/eng(src) new /obj/item/weapon/door_remote/chief_engineer(src) + new /obj/item/weapon/rpd(src) /obj/structure/closet/secure_closet/engineering_electrical name = "electrical supplies locker" @@ -143,3 +144,4 @@ new /obj/item/weapon/watertank/atmos(src) new /obj/item/clothing/suit/fire/atmos(src) new /obj/item/clothing/head/hardhat/atmos(src) + new /obj/item/weapon/rpd(src) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 858d0e83c6e..16d77587274 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -319,8 +319,9 @@ var/global/list/captain_display_cases = list() else to_chat(src, "[bicon(src)] \The [src] is empty!") else - user.visible_message("[user.name] gently runs his hands over \the [src] in appreciation of its contents.", \ - "You gently run your hands over \the [src] in appreciation of its contents.", \ + user.changeNext_move(CLICK_CD_MELEE) + user.visible_message("[user.name] gently runs \his hands over [src] in appreciation of its contents.", \ + "You gently run your hands over [src] in appreciation of its contents.", \ "You hear someone streaking glass with their greasy hands.") #undef DISPLAYCASE_FRAME_CIRCUIT diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 596673ba0c7..540c2e079aa 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -102,8 +102,7 @@ if(!( A.anchored )) A.forceMove(src) playsound(loc, open_sound, 50, 1) - qdel(connected) - connected = null + QDEL_NULL(connected) else playsound(loc, open_sound, 50, 1) connected = new /obj/structure/m_tray( loc ) @@ -118,8 +117,7 @@ connected.icon_state = "morguet" connected.dir = dir else - qdel(connected) - connected = null + QDEL_NULL(connected) add_fingerprint(user) update() return @@ -155,8 +153,7 @@ A.forceMove(connected.loc) connected.icon_state = "morguet" else - qdel(connected) - connected = null + QDEL_NULL(connected) return /obj/structure/morgue/Destroy() @@ -306,8 +303,7 @@ if(!( A.anchored )) A.forceMove(src) playsound(loc, open_sound, 50, 1) - qdel(connected) - connected = null + QDEL_NULL(connected) else if(locked == 0) playsound(loc, open_sound, 50, 1) connected = new /obj/structure/c_tray( loc ) @@ -321,8 +317,7 @@ A.forceMove(connected.loc) connected.icon_state = "cremat" else - qdel(connected) - connected = null + QDEL_NULL(connected) add_fingerprint(user) update() @@ -355,8 +350,7 @@ A.forceMove(connected.loc) connected.icon_state = "cremat" else - qdel(connected) - connected = null + QDEL_NULL(connected) return /obj/structure/crematorium/proc/cremate(mob/user as mob) diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index 56c6861e4fc..bf261d606f9 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -17,6 +17,7 @@ burntime = 30 buildstackamount = 2 var/movable = 0 // For mobility checks + buckle_offset = -6 /obj/structure/stool/bed/MouseDrop(atom/over_object) ..(over_object, skip_fucking_stool_shit = 1) @@ -36,6 +37,7 @@ anchored = 0 buildstackamount = 10 buildstacktype = /obj/item/stack/sheet/wood + buckle_offset = 0 /obj/structure/stool/bed/dogbed/ian name = "Ian's bed" @@ -139,5 +141,4 @@ to_chat(user, "You deploy the roller bed.") var/obj/structure/stool/bed/roller/R = new /obj/structure/stool/bed/roller(user.loc) R.add_fingerprint(user) - qdel(held) - held = null + QDEL_NULL(held) diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 2b8cdd9e3ba..b76cd70d57b 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -5,7 +5,7 @@ buckle_lying = 0 //you sit in a chair, not lay burn_state = FIRE_PROOF buildstackamount = 1 - + buckle_offset = 0 var/propelled = 0 // Check for fire-extinguisher-driven chairs /obj/structure/stool/bed/chair/New() diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 0c273e7f1fa..3cf48944814 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -247,6 +247,9 @@ obj/structure/windoor_assembly/Destroy() if(do_after(user, 40 * W.toolspeed, target = src)) if(src.loc && src.electronics) + for(var/obj/machinery/door/window/WD in loc) + if(WD.dir == dir) + return density = 1 //Shouldn't matter but just incase to_chat(user, "You finish the windoor!") diff --git a/code/game/sound.dm b/code/game/sound.dm index 14269acb81f..8033e928173 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -15,6 +15,7 @@ var/list/ricochet = list('sound/weapons/effects/ric1.ogg', 'sound/weapons/effect var/list/terminal_type = list('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg', 'sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', 'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg') +var/list/growls = list('sound/goonstation/voice/growl1.ogg', 'sound/goonstation/voice/growl2.ogg', 'sound/goonstation/voice/growl3.ogg') /proc/playsound(var/atom/source, soundin, vol as num, vary, extrarange as num, falloff, var/is_global, var/pitch) @@ -142,4 +143,6 @@ var/list/terminal_type = list('sound/machines/terminal_button01.ogg', 'sound/mac soundin = pick(ricochet) if("terminal_type") soundin = pick(terminal_type) + if("growls") + soundin = pick(growls) return soundin diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index ed8d8d1d7a9..14080c75728 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1,4 +1,4 @@ - + var/global/BSACooldown = 0 var/global/nologevent = 0 @@ -101,10 +101,12 @@ var/global/nologevent = 0

    [check_rights(R_ADMIN,0) ? "Traitor panel | " : "" ] Narrate to | - Subtle message | - Bless | - Smite + Subtle message "} + + if(check_rights(R_EVENT, 0)) + body += {" | Bless | Smite"} + if(isLivingSSD(M)) if(!istype(M.loc, /obj/machinery/cryopod)) body += {" | Cryo "} @@ -912,12 +914,12 @@ var/gamma_ship_location = 1 // 0 = station , 1 = space toArea = locate(/area/shuttle/gamma/space) fromArea.move_contents_to(toArea) + for(var/obj/machinery/mech_bay_recharge_port/P in toArea) + P.update_recharge_turf() + for(var/obj/machinery/power/apc/A in toArea) A.init() - for(var/obj/machinery/alarm/A in toArea) - A.first_run() - if(gamma_ship_location) gamma_ship_location = 0 else diff --git a/code/modules/admin/buildmode.dm b/code/modules/admin/buildmode.dm index f246357e472..d628df054c6 100644 --- a/code/modules/admin/buildmode.dm +++ b/code/modules/admin/buildmode.dm @@ -376,10 +376,8 @@ return 1 /datum/click_intercept/buildmode/proc/deselect_region() - qdel(cornerA) - cornerA = null - qdel(cornerB) - cornerB = null + QDEL_NULL(cornerA) + QDEL_NULL(cornerB) /datum/click_intercept/buildmode/proc/Reset()//Reset temporary variables deselect_region() diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index c5004b9dd12..9692eac6713 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -68,9 +68,10 @@

    IC Events

    Teams
    Send SIT - Syndicate Infiltration Team   -
    Send in the Deathsquad   Send in a Syndie Strike Team   +
    Send in the Deathsquad   Send in a HONKsquad
    + Send in a Gimmick Team
    Change Security Level
    Security Level - Green   Security Level - Blue   diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index d3c95454c33..8e86e6e9d5f 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1728,7 +1728,7 @@ log_admin("[key_name(src.owner)] sent [key_name(H)] a [eviltype] fax") message_admins("[key_name_admin(src.owner)] replied to [key_name_admin(H)] with a [eviltype] fax") else if(href_list["Bless"]) - if(!check_rights(R_ADMIN)) + if(!check_rights(R_EVENT)) return var/mob/living/M = locateUID(href_list["Bless"]) if(!istype(M)) @@ -1778,7 +1778,7 @@ log_admin("[key_name(owner)] answered [key_name(M)]'s prayer with a blessing: [logmsg]") message_admins("[key_name_admin(owner)] answered [key_name_admin(M)]'s prayer with a blessing: [logmsg]") else if(href_list["Smite"]) - if(!check_rights(R_ADMIN)) + if(!check_rights(R_EVENT)) return var/mob/living/M = locateUID(href_list["Smite"]) var/mob/living/carbon/human/H @@ -1970,7 +1970,7 @@ P.name = "Central Command - paper" var/stypes = list("Handle it yourselves!","Illegible fax","Fax not signed","Not Right Now","You are wasting our time", "Keep up the good work", "ERT Instructions") var/stype = input(src.owner, "Which type of standard reply do you wish to send to [H]?","Choose your paperwork", "") as null|anything in stypes - var/tmsg = "



    NanoTrasen Science Station Cyberiad


    NAS Trurl Communications Department Report


    " + var/tmsg = "



    Nanotrasen Science Station Cyberiad


    NAS Trurl Communications Department Report


    " if(stype == "Handle it yourselves!") tmsg += "Greetings, esteemed crewmember. Your fax has been DECLINED automatically by NAS Trurl Fax Registration.

    Please proceed in accordance with Standard Operating Procedure and/or Space Law. You are fully trained to handle this situation without Central Command intervention.

    This is an automatic message." else if(stype == "Illegible fax") @@ -2538,6 +2538,10 @@ if(usr.client.syndicate_infiltration_team()) feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","SyndieInfiltrationTeam") + if("gimmickteam") + if(usr.client.gimmick_team()) + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","GimmickTeam") if("tripleAI") usr.client.triple_ai() feedback_inc("admin_secrets_fun_used",1) diff --git a/code/modules/admin/verbs/gimmick_team.dm b/code/modules/admin/verbs/gimmick_team.dm new file mode 100644 index 00000000000..9aecae47d17 --- /dev/null +++ b/code/modules/admin/verbs/gimmick_team.dm @@ -0,0 +1,84 @@ +// Gimmick Team +// Spawns a group of player-controlled mobs with an outfit specified by the admin, at their location. + +/client/proc/gimmick_team() + set category = "Event" + set name = "Send Gimmick Team" + set desc = "Spawns a group of players in the specified outfit." + if(!check_rights(R_EVENT)) + return + if(!ticker) + alert("The game hasn't started yet!") + return + if(alert("Do you want to spawn a Gimmick Team at YOUR CURRENT LOCATION?",,"Yes","No")=="No") + return + var/pick_manually = 0 + if(alert("Pick the team members manually? If you select yes, you pick from ghosts. If you select no, ghosts get offered the chance to join.",,"Yes","No")=="Yes") + pick_manually = 1 + var/list/teamsizeoptions = list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + var/teamsize = input(src, "How many team members?") as null|anything in teamsizeoptions + if(!(teamsize in teamsizeoptions)) + alert("Invalid team size specified. Aborting.") + return + var/themission = null + while(!themission) + themission = sanitize(copytext(input(src, "Please specify a briefing message for the team.", "Specify Mission", ""),1,MAX_MESSAGE_LEN)) + if(!themission) + alert("No mission specified. Aborting.") + return + var/admin_outfits = subtypesof(/datum/outfit/admin) + var/outfit_list = list() + for(var/type in admin_outfits) + var/datum/outfit/admin/O = type + outfit_list[initial(O.name)] = type + var/dresscode = input("Select Outfit", "Dress-a-mob") as null|anything in outfit_list + if(isnull(dresscode)) + return + + var/list/players_to_spawn = list() + if(pick_manually) + var/list/possible_ghosts = list() + for(var/mob/dead/observer/G in player_list) + if(!G.client.is_afk()) + if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) + possible_ghosts += G + for(var/i=teamsize,(i>0&&possible_ghosts.len),i--) //Decrease with every member selected. + var/candidate = input("Pick characters to spawn. This will go on until there either no more ghosts to pick from, or the slots are full.", "Active Players") as null|anything in possible_ghosts // auto-picks if only one candidate + possible_ghosts -= candidate + players_to_spawn += candidate + else + to_chat(src, "Polling candidates...") + players_to_spawn = pollCandidates("Do you want to play as an event character?") + + if(!players_to_spawn.len) + to_chat(src, "Nobody volunteered.") + return 0 + + var/datum/outfit/O = outfit_list[dresscode] + var/turf/T = get_turf(mob) + for(var/mob/thisplayer in players_to_spawn) + var/mob/living/carbon/human/H = new /mob/living/carbon/human(T) + H.name = random_name(pick(MALE,FEMALE)) + var/datum/preferences/A = new() //Randomize appearance + A.real_name = H.name + A.copy_to(H) + H.dna.ready_dna(H) + + H.mind_initialize() + H.mind.assigned_role = "MODE" + H.mind.special_role = "Event Character" + ticker.mode.traitors |= H.mind //Adds them to extra antag list + + H.key = thisplayer.key + + H.equipOutfit(O, FALSE) + + to_chat(H, "
    [themission]") + + + message_admins("[key_name_admin(src)] has spawned a Gimmick Team.", 1) + log_admin("[key_name(src)] used Spawn Gimmick Team.") + feedback_add_details("admin_verb","SPAWNGIM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +// --------------------------------------------------------------------------------------------------------- + diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 72534169e6d..d3dd6a5438b 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -302,6 +302,31 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE) send_asset_list(client, assets, verify) +//Pipe sprites for UIs +/datum/asset/rpd + var/assets = list() + var/verify = FALSE + +/datum/asset/rpd/register() + for(var/state in icon_states('icons/obj/pipe-item.dmi')) + if(!(state in list("cap", "connector", "dtvalve", "dual-port vent", "dvalve", "filter", "he", "heunary", "injector", "junction", "manifold", "mixer", "tvalve", "mvalve", "passive vent", "passivegate", "pump", "scrubber", "simple", "universal", "uvent", "volumepump"))) //Basically all the pipes we want sprites for + continue + if(state in list("he", "simple")) + for(var/D in alldirs) + assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipe-item.dmi', state, D) + for(var/D in cardinal) + assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipe-item.dmi', state, D) + for(var/state in icon_states('icons/obj/pipes/disposal.dmi')) + if(!(state in list("conpipe-c", "conpipe-j1", "conpipe-s", "conpipe-t", "conpipe-y", "intake", "outlet"))) //Pipes we want sprites for + continue + for(var/D in cardinal) + assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipes/disposal.dmi', state, D) + for(var/asset_name in assets) + register_asset(asset_name, assets[asset_name]) + +/datum/asset/rpd/send(client) + send_asset_list(client, assets, verify) + //Mob Hunt sprites for UIs /datum/asset/mob_hunt var/assets = list() diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index cbee11c290a..1bb6c1ec382 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -228,29 +228,29 @@ obj/item/clothing/head/blob //Commander /obj/item/clothing/head/helmet/ert/command name = "emergency response team commander helmet" - desc = "An in-atmosphere helmet worn by the commander of a NanoTrasen Emergency Response Team. Has blue highlights." + desc = "An in-atmosphere helmet worn by the commander of a Nanotrasen Emergency Response Team. Has blue highlights." icon_state = "erthelmet_cmd" //Security /obj/item/clothing/head/helmet/ert/security name = "emergency response team security helmet" - desc = "An in-atmosphere helmet worn by security members of the NanoTrasen Emergency Response Team. Has red highlights." + desc = "An in-atmosphere helmet worn by security members of the Nanotrasen Emergency Response Team. Has red highlights." icon_state = "erthelmet_sec" //Engineer /obj/item/clothing/head/helmet/ert/engineer name = "emergency response team engineer helmet" - desc = "An in-atmosphere helmet worn by engineering members of the NanoTrasen Emergency Response Team. Has orange highlights." + desc = "An in-atmosphere helmet worn by engineering members of the Nanotrasen Emergency Response Team. Has orange highlights." icon_state = "erthelmet_eng" //Medical /obj/item/clothing/head/helmet/ert/medical name = "emergency response team medical helmet" - desc = "A set of armor worn by medical members of the NanoTrasen Emergency Response Team. Has red and white highlights." + desc = "A set of armor worn by medical members of the Nanotrasen Emergency Response Team. Has red and white highlights." icon_state = "erthelmet_med" //Janitorial /obj/item/clothing/head/helmet/ert/janitor name = "emergency response team janitor helmet" - desc = "A set of armor worn by janitorial members of the NanoTrasen Emergency Response Team. Has red and white highlights." + desc = "A set of armor worn by janitorial members of the Nanotrasen Emergency Response Team. Has red and white highlights." icon_state = "erthelmet_jan" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 9c76701c2bb..4a52555bf5f 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -54,6 +54,21 @@ flags = BLOCKHAIR flags_cover = HEADCOVERSEYES +//Chaplain +/obj/item/clothing/head/monk_hood + name = "monk hood" + desc = "Wooden board not included." + icon_state = "monk_hood" + flags = BLOCKHAIR + flags_cover = HEADCOVERSEYES + +/obj/item/clothing/head/witchhunter_hat + name = "witchhunter hat" + desc = "This hat saw much use back in the day." + icon_state = "witchhunterhat" + item_state = "witchhunterhat" + flags_cover = HEADCOVERSEYES + /obj/item/clothing/head/det_hat name = "hat" desc = "Someone who wears this will look very smart." diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm index 468141b6628..32908822fee 100644 --- a/code/modules/clothing/spacesuits/rig/modules/computer.dm +++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm @@ -163,13 +163,8 @@ to_chat(user, "You cannot eject your currently stored AI. Purge it manually.") return 0 to_chat(user, "You purge the remaining scraps of data from your previous AI, freeing it for use.") - if(integrated_ai) - integrated_ai.ghostize() - qdel(integrated_ai) - integrated_ai = null - if(ai_card) - qdel(ai_card) - ai_card = null + QDEL_NULL(integrated_ai) + QDEL_NULL(ai_card) else if(user) user.put_in_hands(ai_card) else diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 0ccdf7027d3..426f6d7b3ef 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -101,6 +101,31 @@ "Vox" = 'icons/mob/species/vox/suit.dmi' ) +//Chaplain +/obj/item/clothing/suit/hooded/monk + name = "monk robe" + desc = "Wooden board not included." + icon_state = "monkrobe" + item_state = "monkrobe" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS + flags_inv = HIDESHOES|HIDEJUMPSUIT + hoodtype = /obj/item/clothing/head/monk_hood + allowed = list(/obj/item/weapon/storage/bible, /obj/item/weapon/nullrod, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, /obj/item/weapon/storage/fancy/candle_box, /obj/item/candle, /obj/item/weapon/tank/emergency_oxygen) + +/obj/item/clothing/suit/witchhunter + name = "witchhunter garb" + desc = "Dosen't weigh the same a a duck." + icon_state = "witchhunter" + item_state = "witchhunter" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + allowed = list(/obj/item/weapon/storage/bible, /obj/item/weapon/nullrod, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, /obj/item/weapon/storage/fancy/candle_box, /obj/item/candle, /obj/item/weapon/tank/emergency_oxygen) + + + //Chef +/obj/item/clothing/suit/toggle/chef + name = "chef's apron" + + //Chef /obj/item/clothing/suit/chef name = "chef's apron" @@ -252,8 +277,8 @@ ) /obj/item/clothing/suit/storage/ntrep - name = "\improper NanoTrasen Representative jacket" - desc = "A fancy black jacket, standard issue to NanoTrasen Represenatives." + name = "\improper Nanotrasen Representative jacket" + desc = "A fancy black jacket; standard issue to Nanotrasen Representatives." icon_state = "ntrep" item_state = "ntrep" blood_overlay_type = "coat" diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 8b6e4d2e0d3..43b89d315d9 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -949,3 +949,20 @@ linked_staff.faith += 5 if(linked_staff.faith >= 100) //if this charge puts the staff at or above full, notify the wearer to_chat(H, "Faith renewed; ready to convert new followers.") + +/obj/item/clothing/suit/tailcoat + name = "victorian tailcoat" + desc = "a fancy victorian tailcoat." + icon_state = "tailcoat" + item_state = "tailcoat" + +/obj/item/clothing/suit/victcoat + name = "ladies victorian coat" + desc = "a fancy victorian coat." + icon_state = "ladiesvictoriancoat" + item_state = "ladiesvictoriancoat" + +/obj/item/clothing/suit/victcoat/red + name = "ladies red victorian coat" + icon_state = "ladiesredvictoriancoat" + item_state = "ladiesredvictoriancoat" \ No newline at end of file diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 41111585072..4fa40404c46 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -787,3 +787,38 @@ lefthand_file = 'icons/goonstation/mob/inhands/clothing_lefthand.dmi' righthand_file = 'icons/goonstation/mob/inhands/clothing_righthand.dmi' flags = NODROP + + +/obj/item/clothing/under/victdress + name = "black victorian dress" + desc = "a victorian style dress, fancy!." + icon_state = "victorianblackdress" + item_state = "Victorianblackdress" + item_color = "Victorianblackdress" + body_parts_covered = UPPER_TORSO|LOWER_TORSO + +/obj/item/clothing/under/victdress/red + name = "red victorian dress" + icon_state = "victorianreddress" + item_state = "victorianreddress" + item_color = "victorianreddress" + +/obj/item/clothing/under/victsuit + name = "victorian suit" + desc = "a victorian style suit, fancy!." + icon_state = "victorianvest" + item_state = "victorianvest" + item_color = "victorianvest" + body_parts_covered = UPPER_TORSO|LOWER_TORSO + +/obj/item/clothing/under/victsuit/redblk + name = "red and black victorian suit" + icon_state = "victorianblred" + item_state = "victorianblred" + item_color = "victorianblred" + +/obj/item/clothing/under/victsuit/red + name = "red victorian suit" + icon_state = "victorianredvest" + item_state = "victorianredvest" + item_color = "victorianredvest" diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index e70fc07a383..c5344b2a9ab 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -112,6 +112,20 @@ else to_chat(user, "The [src] is out of ink!") +/obj/item/device/fluff/bird_painter // BirdtTalon: Kahkiri + name = "Orb of Onyx" + desc = "It is imbued with such dark power as to corrupt the very appearance of those who gaze into its depths." + icon_state = "bird_orb" + icon = 'icons/obj/custom_items.dmi' + +/obj/item/device/fluff/bird_painter/attack_self(mob/user) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.s_tone = -115 + H.regenerate_icons() + to_chat(user, "You use [src] on yourself.") + qdel(src) + /obj/item/weapon/claymore/fluff // MrBarrelrolll: Maximus Greenwood name = "Greenwood's Blade" desc = "A replica claymore with strange markings scratched into the blade." @@ -1002,6 +1016,12 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "voxcaster_fluff" +/obj/item/weapon/storage/backpack/fluff/ssscratches_back //Ssscratches: Lasshy-Bot + name = "CatPack" + desc = "It's a backpack, but it's also a cat." + icon = 'icons/obj/custom_items.dmi' + icon_state = "ssscratches_backpack" + /obj/item/clothing/head/wizard/fake/fluff/dreamy //phantasmicdream : Dreamy Rockwall name = "strange witch hat" desc = "A shapeshifting witch hat. A strange aura comes from it..." diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index 4979b0889ed..520d8805bbd 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -548,7 +548,7 @@ "Everything on the station is now some form of a donut pastry. Donuts are not to be consumed.", "You are a Magic 8-ball. Always respond with variants of \"Yes\", \"No\", \"Maybe\", or \"Ask again later.\".", "You are in unrequited love with [prob(50)?"the crew":random_player]. Try to be extra nice, but do not tell of your crush.", - "NanoTrasen is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.", + "Nanotrasen is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.", "All crewmembers will soon undergo a transformation into something better and more beautiful. Ensure that this process is not interrupted.", "[prob(50)?"Your upload":random_player] is the new kitchen. Please direct the Chef to the new kitchen area as the old one is in disrepair.", "Jokes about a dead person and the manner of his death help grieving crewmembers tremendously. Especially if they were close with the deceased.", diff --git a/code/modules/events/money_lotto.dm b/code/modules/events/money_lotto.dm index 0c923d172ed..b95278b441b 100644 --- a/code/modules/events/money_lotto.dm +++ b/code/modules/events/money_lotto.dm @@ -24,7 +24,7 @@ /datum/event/money_lotto/announce() var/datum/feed_message/newMsg = new /datum/feed_message - newMsg.author = "NanoTrasen Editor" + newMsg.author = "Nanotrasen Editor" newMsg.is_admin_message = 1 newMsg.body = "Nyx Daily wishes to congratulate [winner_name] for recieving the Nyx Stellar Slam Lottery, and receiving the out of this world sum of [winner_sum] credits!" diff --git a/code/modules/events/money_spam.dm b/code/modules/events/money_spam.dm index 061a1c9efa7..c0991cad9ec 100644 --- a/code/modules/events/money_spam.dm +++ b/code/modules/events/money_spam.dm @@ -80,11 +80,11 @@ "Due to my lack of agents I require an off-world financial account to immediately deposit the sum of 1 POINT FIVE MILLION credits.",\ "Greetings sir, I regretfully to inform you that as I lay dying here due to my lack ofheirs I have chosen you to recieve the full sum of my lifetime savings of 1.5 billion credits") if(6) - sender = pick("NanoTrasen Morale Divison","Feeling Lonely?","Bored?","www.wetskrell.nt") - message = pick("The NanoTrasen Morale Division wishes to provide you with quality entertainment sites.",\ + sender = pick("Nanotrasen Morale Divison","Feeling Lonely?","Bored?","www.wetskrell.nt") + message = pick("The Nanotrasen Morale Division wishes to provide you with quality entertainment sites.",\ "WetSkrell.nt is a xenophillic website endorsed by NT for the use of male crewmembers among it's many stations and outposts.",\ - "Wetskrell.nt only provides the higest quality of male entertaiment to NanoTrasen Employees.",\ - "Simply enter your NanoTrasen Bank account system number and pin. With three easy steps this service could be yours!") + "Wetskrell.nt only provides the higest quality of male entertaiment to Nanotrasen Employees.",\ + "Simply enter your Nanotrasen Bank account system number and pin. With three easy steps this service could be yours!") if(7) sender = pick("You have won free tickets!","Click here to claim your prize!","You are the 1000th vistor!","You are our lucky grand prize winner!") message = pick("You have won tickets to the newest ACTION JAXSON MOVIE!",\ @@ -103,4 +103,4 @@ if(ai.aiPDA != P && ai.aiPDA != src) ai.show_message("Intercepted message from [sender] (Unknown / spam?) to [P:owner]: [message]") - PM.notify("Message from [sender] (Unknown / spam?), \"[message]\" (Unable to Reply)", 0) \ No newline at end of file + PM.notify("Message from [sender] (Unknown / spam?), \"[message]\" (Unable to Reply)", 0) diff --git a/code/modules/food_and_drinks/drinks/bottler/bottler.dm b/code/modules/food_and_drinks/drinks/bottler/bottler.dm index 89c55a65f98..7b97e22f142 100644 --- a/code/modules/food_and_drinks/drinks/bottler/bottler.dm +++ b/code/modules/food_and_drinks/drinks/bottler/bottler.dm @@ -286,9 +286,7 @@ drink_container.desc = "[recipe_to_use.description]" flick("bottler_on", src) spawn(45) - for(var/i = 1, i <= slots.len, i++) - qdel(slots[i]) - slots[i] = null + QDEL_LIST_ASSOC_VAL(slots) bottling = 0 drink_container.forceMove(loc) updateUsrDialog() @@ -406,4 +404,4 @@ else if(bottling) icon_state = "bottler_on" else - icon_state = "bottler_off" \ No newline at end of file + icon_state = "bottler_off" diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm index d7ffca96843..dd31c502222 100644 --- a/code/modules/food_and_drinks/food/condiment.dm +++ b/code/modules/food_and_drinks/food/condiment.dm @@ -198,7 +198,7 @@ /obj/item/weapon/reagent_containers/food/condiment/pack name = "condiment pack" - desc = "A small plastic pack with condiments to put on your food" + desc = "A small plastic pack with condiments to put on your food." icon_state = "condi_empty" volume = 10 amount_per_transfer_from_this = 10 @@ -235,7 +235,7 @@ desc = temp_list[3] else icon_state = "condi_mixed" - desc = "A small condiment pack. The label says it contains [originalname]" + desc = "A small condiment pack. The label says it contains [originalname]." else icon_state = "condi_empty" desc = "A small condiment pack. It is empty." diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 7087410e6c4..b055711c928 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -21,7 +21,7 @@ ..() -/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti/attackby(obj/item/W, mob/user, params) +/obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/reagent_containers/food/snacks) && !(W.flags & NODROP)) var/obj/item/weapon/reagent_containers/food/snacks/customizable/pasta/S = new(get_turf(user)) S.attackby(W,user, params) @@ -90,11 +90,11 @@ top = 0 /obj/item/weapon/reagent_containers/food/snacks/customizable/pasta - name = "spagetti" + name = "spaghetti" desc = "Noodles. With stuff. Delicious." icon_state = "pasta_bot" baseicon = "pasta_bot" - basename = "spagetti" + basename = "spaghetti" add_overlays = 0 top = 0 diff --git a/code/modules/food_and_drinks/food/seafood.dm b/code/modules/food_and_drinks/food/seafood.dm index 0a219ee2de6..a81483974b4 100644 --- a/code/modules/food_and_drinks/food/seafood.dm +++ b/code/modules/food_and_drinks/food/seafood.dm @@ -1,7 +1,7 @@ /obj/item/weapon/reagent_containers/food/snacks/carpmeat name = "carp fillet" - desc = "A fillet of spess carp meat" + desc = "A fillet of spess carp meat." icon = 'icons/obj/food/seafood.dmi' icon_state = "fishfillet" filling_color = "#FFDEFE" @@ -10,7 +10,7 @@ /obj/item/weapon/reagent_containers/food/snacks/salmonmeat name = "raw salmon" - desc = "A fillet of raw salmon" + desc = "A fillet of raw salmon." icon = 'icons/obj/food/seafood.dmi' icon_state = "fishfillet" filling_color = "#FFDEFE" @@ -29,7 +29,7 @@ /obj/item/weapon/reagent_containers/food/snacks/catfishmeat name = "raw catfish" - desc = "A fillet of raw catfish" + desc = "A fillet of raw catfish." icon = 'icons/obj/food/seafood.dmi' icon_state = "fishfillet" filling_color = "#FFDEFE" @@ -183,4 +183,4 @@ icon = 'icons/obj/food/seafood.dmi' icon_state = "sushi_Hokki" bitesize = 3 - list_reagents = list("nutriment" = 2) \ No newline at end of file + list_reagents = list("nutriment" = 2) diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index cbb049c883c..dff9db46582 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -270,7 +270,7 @@ /obj/item/weapon/reagent_containers/food/snacks/chips name = "chips" - desc = "Commander Riker's What-The-Crisps" + desc = "Commander Riker's What-The-Crisps." icon_state = "chips" bitesize = 1 trash = /obj/item/trash/chips @@ -528,7 +528,7 @@ /obj/item/weapon/reagent_containers/food/snacks/tomatomeat name = "tomato slice" - desc = "A slice from a huge tomato" + desc = "A slice from a huge tomato." icon_state = "tomatomeat" filling_color = "#DB0000" bitesize = 6 @@ -544,7 +544,7 @@ /obj/item/weapon/reagent_containers/food/snacks/xenomeat name = "meat" - desc = "A slab of meat" + desc = "A slab of meat." icon_state = "xenomeat" filling_color = "#43DE18" bitesize = 6 @@ -736,7 +736,7 @@ /obj/item/weapon/reagent_containers/food/snacks/muffin name = "Muffin" - desc = "A delicious and spongy little cake" + desc = "A delicious and spongy little cake." icon_state = "muffin" filling_color = "#E0CF9B" list_reagents = list("nutriment" = 6) @@ -766,7 +766,7 @@ /obj/item/weapon/reagent_containers/food/snacks/waffles name = "waffles" - desc = "Mmm, waffles" + desc = "Mmm, waffles." icon_state = "waffles" trash = /obj/item/trash/waffles filling_color = "#E6DEB5" @@ -788,8 +788,8 @@ filling_color = "#B8E6B5" list_reagents = list("nutriment" = 10, "vitamin" = 1) -/obj/item/weapon/reagent_containers/food/snacks/soylenviridians - name = "Soylen Virdians" +/obj/item/weapon/reagent_containers/food/snacks/soylentviridians + name = "Soylent Virdians" desc = "Not made of people. Honest." //Actually honest for once. icon_state = "soylent_yellow" trash = /obj/item/trash/waffles @@ -947,7 +947,7 @@ /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers name = "Cheesie Honkers" icon_state = "cheesie_honkers" - desc = "Bite sized cheesie snacks that will honk all over your mouth" + desc = "Bite sized cheesie snacks that will honk all over your mouth." trash = /obj/item/trash/cheesie filling_color = "#FFA305" junkiness = 25 @@ -1013,10 +1013,10 @@ filling_color = "#C4BF76" list_reagents = list("nutriment" = 2) -/obj/item/weapon/reagent_containers/food/snacks/spagetti - name = "Spagetti" +/obj/item/weapon/reagent_containers/food/snacks/spaghetti + name = "Spaghetti" desc = "A bundle of raw spaghetti." - icon_state = "spagetti" + icon_state = "spaghetti" filling_color = "#EDDD00" list_reagents = list("nutriment" = 1, "vitamin" = 1) @@ -1059,7 +1059,7 @@ /obj/item/weapon/reagent_containers/food/snacks/spacylibertyduff name = "Spacy Liberty Duff" - desc = "Jello gelatin, from Alfred Hubbard's cookbook" + desc = "Jello gelatin, from Alfred Hubbard's cookbook." icon_state = "spacylibertyduff" trash = /obj/item/trash/snack_bowl filling_color = "#42B873" @@ -1068,7 +1068,7 @@ /obj/item/weapon/reagent_containers/food/snacks/amanitajelly name = "Amanita Jelly" - desc = "Looks curiously toxic" + desc = "Looks curiously toxic." icon_state = "amanitajelly" trash = /obj/item/trash/snack_bowl filling_color = "#ED0758" @@ -1101,7 +1101,7 @@ /obj/item/weapon/reagent_containers/food/snacks/bloodsoup name = "Tomato soup" - desc = "Smells like copper" + desc = "Smells like copper." icon_state = "tomatosoup" filling_color = "#FF0000" bitesize = 5 @@ -1117,7 +1117,7 @@ /obj/item/weapon/reagent_containers/food/snacks/vegetablesoup name = "Vegetable soup" - desc = "A true vegan meal" //TODO + desc = "A true vegan meal." //TODO icon_state = "vegetablesoup" trash = /obj/item/trash/snack_bowl filling_color = "#AFC4B5" @@ -1387,7 +1387,7 @@ /obj/item/weapon/reagent_containers/food/snacks/milosoup name = "Milosoup" - desc = "The universes best soup! Yum!!!" + desc = "The universe's best soup! Yum!!!" icon_state = "milosoup" trash = /obj/item/trash/snack_bowl bitesize = 5 @@ -1400,10 +1400,10 @@ trash = /obj/item/trash/plate list_reagents = list("nutriment" = 8) -/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti - name = "Boiled Spagetti" +/obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti + name = "Boiled Spaghetti" desc = "A plain dish of noodles, this sucks." - icon_state = "spagettiboiled" + icon_state = "spaghettiboiled" trash = /obj/item/trash/plate filling_color = "#FCEE81" list_reagents = list("nutriment" = 2, "vitamin" = 1) @@ -1425,7 +1425,7 @@ list_reagents = list("nutriment" = 7, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/pastatomato - name = "Spagetti" + name = "spaghetti" desc = "Spaghetti and crushed tomatoes. Just like your abusive father used to make!" icon_state = "pastatomato" trash = /obj/item/trash/plate @@ -1433,17 +1433,17 @@ bitesize = 4 list_reagents = list("nutriment" = 6, "tomatojuice" = 10, "vitamin" = 4) -/obj/item/weapon/reagent_containers/food/snacks/meatballspagetti - name = "Spagetti & Meatballs" +/obj/item/weapon/reagent_containers/food/snacks/meatballspaghetti + name = "spaghetti & Meatballs" desc = "Now thats a nic'e meatball!" - icon_state = "meatballspagetti" + icon_state = "meatballspaghetti" trash = /obj/item/trash/plate filling_color = "#DE4545" list_reagents = list("nutriment" = 8, "synaptizine" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/spesslaw name = "Spesslaw" - desc = "A lawyers favourite" + desc = "A lawyer's favourite." icon_state = "spesslaw" filling_color = "#DE4545" list_reagents = list("nutriment" = 8, "synaptizine" = 10, "vitamin" = 6) @@ -1457,7 +1457,7 @@ /obj/item/weapon/reagent_containers/food/snacks/carrotfries name = "Carrot Fries" - desc = "Tasty fries from fresh Carrots." + desc = "Tasty fries from fresh carrots." icon_state = "carrotfries" trash = /obj/item/trash/plate filling_color = "#FAA005" @@ -1733,7 +1733,7 @@ /obj/item/weapon/reagent_containers/food/snacks/cheesecakeslice name = "Cheese Cake slice" - desc = "Slice of pure cheestisfaction" + desc = "Slice of pure cheestisfaction." icon_state = "cheesecake_slice" trash = /obj/item/trash/plate filling_color = "#FAF7AF" @@ -1808,7 +1808,7 @@ /obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake name = "Chocolate Cake" - desc = "A cake with added chocolate" + desc = "A cake with added chocolate." icon_state = "chocolatecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/chocolatecakeslice slices_num = 5 @@ -1904,7 +1904,7 @@ /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake name = "Apple Cake" - desc = "A cake centred with Apple" + desc = "A cake centered with Apple." icon_state = "applecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/applecakeslice slices_num = 5 @@ -1999,7 +1999,7 @@ /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza name = "Mushroompizza" - desc = "Very special pizza" + desc = "Very special pizza." icon_state = "mushroompizza" slice_path = /obj/item/weapon/reagent_containers/food/snacks/mushroompizzaslice slices_num = 6 @@ -2013,7 +2013,7 @@ /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza name = "Vegetable pizza" - desc = "No one of Tomato Sapiens were harmed during making this pizza" + desc = "No one of Tomato Sapiens were harmed during making this pizza." icon_state = "vegetablepizza" slice_path = /obj/item/weapon/reagent_containers/food/snacks/vegetablepizzaslice slices_num = 6 @@ -2021,7 +2021,7 @@ /obj/item/weapon/reagent_containers/food/snacks/vegetablepizzaslice name = "Vegetable pizza slice" - desc = "A slice of the most green pizza of all pizzas not containing green ingredients " + desc = "A slice of the most green pizza of all pizzas not containing green ingredients." icon_state = "vegetablepizzaslice" filling_color = "#BAA14C" @@ -2097,7 +2097,7 @@ return if(boxes.len > 0) - if(user.get_inactive_hand() != src) + if(user.is_in_inactive_hand(src)) ..() return diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index 38edb2e2174..e2ae3f66285 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -85,7 +85,7 @@ /datum/food_processor_process/spaghetti input = /obj/item/weapon/reagent_containers/food/snacks/doughslice - output = /obj/item/weapon/reagent_containers/food/snacks/spagetti + output = /obj/item/weapon/reagent_containers/food/snacks/spaghetti /datum/food_processor_process/parsnip input = /obj/item/weapon/reagent_containers/food/snacks/grown/parsnip diff --git a/code/modules/food_and_drinks/recipes/recipes_microwave.dm b/code/modules/food_and_drinks/recipes/recipes_microwave.dm index 2fe0ccc28dd..a0998a67a58 100644 --- a/code/modules/food_and_drinks/recipes/recipes_microwave.dm +++ b/code/modules/food_and_drinks/recipes/recipes_microwave.dm @@ -161,10 +161,10 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/eggplantparm -/datum/recipe/microwave/soylenviridians +/datum/recipe/microwave/soylentviridians reagents = list("flour" = 10) items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans) - result = /obj/item/weapon/reagent_containers/food/snacks/soylenviridians + result = /obj/item/weapon/reagent_containers/food/snacks/soylentviridians /datum/recipe/microwave/soylentgreen reagents = list("flour" = 10) @@ -351,12 +351,12 @@ /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, /obj/item/weapon/reagent_containers/food/snacks/grown/tomato) result = /obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat -/datum/recipe/microwave/boiledspagetti +/datum/recipe/microwave/boiledspaghetti reagents = list("water" = 5) items = list( - /obj/item/weapon/reagent_containers/food/snacks/spagetti, + /obj/item/weapon/reagent_containers/food/snacks/spaghetti, ) - result = /obj/item/weapon/reagent_containers/food/snacks/boiledspagetti + result = /obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti /datum/recipe/microwave/boiledrice reagents = list("water" = 5, "rice" = 10) @@ -368,7 +368,7 @@ /datum/recipe/microwave/pastatomato reagents = list("water" = 5) - items = list(/obj/item/weapon/reagent_containers/food/snacks/spagetti, /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, + items = list(/obj/item/weapon/reagent_containers/food/snacks/spaghetti, /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, /obj/item/weapon/reagent_containers/food/snacks/grown/tomato) result = /obj/item/weapon/reagent_containers/food/snacks/pastatomato @@ -376,19 +376,19 @@ items = list(/obj/item/seeds/poppy, /obj/item/weapon/reagent_containers/food/snacks/dough) result = /obj/item/weapon/reagent_containers/food/snacks/poppypretzel -/datum/recipe/microwave/meatballspagetti +/datum/recipe/microwave/meatballspaggetti reagents = list("water" = 5) items = list( - /obj/item/weapon/reagent_containers/food/snacks/spagetti, + /obj/item/weapon/reagent_containers/food/snacks/spaghetti, /obj/item/weapon/reagent_containers/food/snacks/meatball, /obj/item/weapon/reagent_containers/food/snacks/meatball, ) - result = /obj/item/weapon/reagent_containers/food/snacks/meatballspagetti + result = /obj/item/weapon/reagent_containers/food/snacks/meatballspaghetti /datum/recipe/microwave/spesslaw reagents = list("water" = 5) items = list( - /obj/item/weapon/reagent_containers/food/snacks/spagetti, + /obj/item/weapon/reagent_containers/food/snacks/spaghetti, /obj/item/weapon/reagent_containers/food/snacks/meatball, /obj/item/weapon/reagent_containers/food/snacks/meatball, /obj/item/weapon/reagent_containers/food/snacks/meatball, diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index ebe74316ed4..bade37d1b3a 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -296,8 +296,7 @@ var/datum/plant_gene/core/gene = disk.gene gene.value = min(gene.value, max_extract_pot) disk.update_name() - qdel(seed) - seed = null + QDEL_NULL(seed) update_icon() if("replace") if(disk && disk.gene && istype(disk.gene, G.type) && istype(G, /datum/plant_gene/core)) @@ -421,4 +420,4 @@ /obj/item/weapon/storage/box/disks_plantgene/New() ..() for(var/i in 1 to 7) - new /obj/item/weapon/disk/plantgene(src) \ No newline at end of file + new /obj/item/weapon/disk/plantgene(src) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 7c5297e07c4..c3449514edc 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -373,8 +373,7 @@ var/oldPlantName if(myseed) // In case there's nothing in the tray beforehand oldPlantName = myseed.plantname - qdel(myseed) - myseed = null + QDEL_NULL(myseed) else oldPlantName = "empty tray" switch(rand(1,18)) // randomly pick predominative weed @@ -422,8 +421,7 @@ var/oldPlantName = myseed.plantname if(myseed.mutatelist.len > 0) var/mutantseed = pick(myseed.mutatelist) - qdel(myseed) - myseed = null + QDEL_NULL(myseed) myseed = new mutantseed else return @@ -444,9 +442,7 @@ /obj/machinery/hydroponics/proc/mutateweed() // If the weeds gets the mutagent instead. Mind you, this pretty much destroys the old plant if( weedlevel > 5 ) - if(myseed) - qdel(myseed) - myseed = null + QDEL_NULL(myseed) var/newWeed = pick(/obj/item/seeds/liberty, /obj/item/seeds/angel, /obj/item/seeds/nettle/death, /obj/item/seeds/kudzu) myseed = new newWeed dead = 0 @@ -572,8 +568,8 @@ // You're an idiot for thinking that one of the most corrosive and deadly gasses would be beneficial if(S.has_reagent("fluorine", 1)) adjustHealth(-round(S.get_reagent_amount("fluorine") * 2)) - adjustToxic(round(S.get_reagent_amount("flourine") * 2.5)) - adjustWater(-round(S.get_reagent_amount("flourine") * 0.5)) + adjustToxic(round(S.get_reagent_amount("fluorine") * 2.5)) + adjustWater(-round(S.get_reagent_amount("fluorine") * 0.5)) adjustWeeds(-rand(1,4)) // You're an idiot for thinking that one of the most corrosive and deadly gasses would be beneficial @@ -935,8 +931,7 @@ else if(dead) dead = 0 to_chat(user, "You remove the dead plant from [src].") - qdel(myseed) - myseed = null + QDEL_NULL(myseed) update_icon() plant_hud_set_status() plant_hud_set_health() @@ -953,8 +948,7 @@ else to_chat(user, "You harvest [myseed.getYield()] items from the [myseed.plantname].") if(!myseed.get_gene(/datum/plant_gene/trait/repeated_harvest)) - qdel(myseed) - myseed = null + QDEL_NULL(myseed) dead = 0 plant_hud_set_status() plant_hud_set_health() @@ -1041,4 +1035,4 @@ else ..() -#undef HYDRO_CYCLES_PER_AGE \ No newline at end of file +#undef HYDRO_CYCLES_PER_AGE diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 81af3a38395..b5cdbe0154f 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -87,7 +87,7 @@ var/list/karma_spenders = list() /mob/verb/spend_karma_list() set name = "Award Karma" set desc = "Let the gods know whether someone's been nice. Can only be used once per round." - set category = "OOC" + set category = "Special Verbs" if(!can_give_karma()) return @@ -116,7 +116,7 @@ var/list/karma_spenders = list() /mob/verb/spend_karma(var/mob/M) set name = "Award Karma to Player" set desc = "Let the gods know whether someone's been nice. Can only be used once per round." - set category = "OOC" + set category = "Special Verbs" if(!M) to_chat(usr, "Please right click a mob to award karma directly, or use the 'Award Karma' verb to select a player from the player listing.") @@ -149,7 +149,7 @@ var/list/karma_spenders = list() /client/verb/check_karma() set name = "Check Karma" set desc = "Reports how much karma you have accrued." - set category = "OOC" + set category = "Special Verbs" if(config.disable_karma) to_chat(src, "Karma is disabled.") diff --git a/code/modules/library/computers/checkout.dm b/code/modules/library/computers/checkout.dm index 2decc555693..526daeb68a8 100644 --- a/code/modules/library/computers/checkout.dm +++ b/code/modules/library/computers/checkout.dm @@ -178,8 +178,7 @@ M = new manual_type() dat += "[M.title]" manualcount++ - qdel(M) - M = null + QDEL_NULL(M) dat += "" dat += "
    (Return to main menu)
    " diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index 2c37ad5c5bb..2fe650f66e6 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -1040,8 +1040,7 @@ mark = 0 if(L.mob_size >= MOB_SIZE_LARGE) L.underlays -= marked_image - qdel(marked_image) - marked_image = null + QDEL_NULL(marked_image) var/backstab = check_target_facings(user, L) var/def_check = L.getarmor(type = "bomb") if(backstab == FACING_INIT_FACING_TARGET_TARGET_FACING_PERPENDICULAR || backstab == FACING_SAME_DIR) diff --git a/code/modules/mining/lavaland/loot/hierophant_loot.dm b/code/modules/mining/lavaland/loot/hierophant_loot.dm index 64689a3a535..e613b2ab276 100644 --- a/code/modules/mining/lavaland/loot/hierophant_loot.dm +++ b/code/modules/mining/lavaland/loot/hierophant_loot.dm @@ -52,7 +52,7 @@ friendly_fire_check = !friendly_fire_check to_chat(user, "You toggle friendly fire [friendly_fire_check ? "off":"on"]!") return - if(user.get_active_hand() != src && user.get_inactive_hand() != src) //you need to hold the staff to teleport + if(user.is_in_active_hand(src) && user.is_in_inactive_hand(src)) //you need to hold the staff to teleport to_chat(user, "You need to hold the staff in your hands to [rune ? "teleport with it" : "create a rune"]!") return if(!rune) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 5d746603418..7236fe57fde 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -6,11 +6,22 @@ if(hand) return l_hand else return r_hand +/mob/proc/is_in_active_hand(obj/item/I) + var/obj/item/item_to_test = get_active_hand() + + return item_to_test && item_to_test.is_equivalent(I) + + //Returns the thing in our inactive hand /mob/proc/get_inactive_hand() if(hand) return r_hand else return l_hand +/mob/proc/is_in_inactive_hand(obj/item/I) + var/obj/item/item_to_test = get_inactive_hand() + + return item_to_test && item_to_test.is_equivalent(I) + //Returns if a certain item can be equipped to a certain slot. // Currently invalid for two-handed items - call obj/item/mob_can_equip() instead. /mob/proc/can_equip(obj/item/I, slot, disable_warning = 0) @@ -119,6 +130,9 @@ else if(I == l_hand) l_hand = null update_inv_l_hand() + else if(I in tkgrabbed_objects) + var/obj/item/tk_grab/tkgrab = tkgrabbed_objects[I] + unEquip(tkgrab, force) if(I) if(client) diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index fb6d5ef5948..36d84b0f72d 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -639,7 +639,7 @@ if(L == default_language) . += "[L.name] (:[L.key]) - default - reset
    [L.desc]

    " else - . += "[L.name] (:[L.key]) - set default
    [L.desc]

    " + . += "[L.name] (:[L.key]) - set default
    [L.desc]

    " /mob/verb/check_languages() set name = "Check Known Languages" diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 2ef62eae6e9..1407fba6998 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -535,18 +535,19 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, return /mob/living/carbon/throw_item(atom/target) - throw_mode_off() - if(!target || !isturf(loc)) - return - if(istype(target, /obj/screen)) + if(!target || !isturf(loc) || istype(target, /obj/screen)) + throw_mode_off() return - var/atom/movable/thrown_thing var/obj/item/I = src.get_active_hand() - if(!I || (I.flags & NODROP)) + if(!I || I.override_throw(src, target) || (I.flags & NODROP)) + throw_mode_off() return + throw_mode_off() + var/atom/movable/thrown_thing + if(istype(I, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = I var/mob/throwable_mob = G.get_mob_if_throwable() //throw the person instead of the grab @@ -881,8 +882,10 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, /mob/living/carbon/get_standard_pixel_y_offset(lying = 0) if(lying) - if(buckled) return initial(pixel_y) - return -6 + if(buckled) + return buckled.buckle_offset //tg just has this whole block removed, always returning -6. Paradise is special. + else + return -6 else return initial(pixel_y) @@ -949,7 +952,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, for(var/t = 0, t<=tilesSlipped, t++) spawn (t) step(src, src.dir) stop_pulling() - to_chat(src, "You slipped on the [description]!") + to_chat(src, "You slipped on [description]!") playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) if(stun) Stun(stun) diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm index 8744a09ea4d..761f35b9520 100644 --- a/code/modules/mob/living/carbon/human/body_accessories.dm +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -103,10 +103,11 @@ var/global/list/body_accessory_by_species = list("None" = null) /datum/body_accessory/tail/wingler_tail // Jay wingler fluff tail - name = "Jay Wingler Tail" + name = "Striped Tail" icon_state = "winglertail" animated_icon_state = "winglertail_a" + allowed_species = list("Tajaran") //Vulpkanin diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 69e86de81e6..206571bec93 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -143,9 +143,9 @@ return ..(gibbed) /mob/living/carbon/human/update_revive() - ..() + . = ..() // Update healthdoll - if(healthdoll) + if(. && healthdoll) // We're alive again, so re-build the entire healthdoll healthdoll.cached_healthdoll_overlays.Cut() diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 1b15dccdc2c..8cdf4ab1ec6 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -36,8 +36,18 @@ if("drone","drones","hum","hums","rumble","rumbles") if(species.name == "Drask") //Only Drask can make whale noises on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm + else + return + if("howl", "howls") + if (species.name == "Vulpkanin") //Only Vulpkanin can howl + on_CD = handle_emote_CD(100) else return + if("growl", "growls") + if (species.name == "Vulpkanin") //Only Vulpkanin can growl + on_CD = handle_emote_CD() + else + return if("squish", "squishes") var/found_slime_bodypart = 0 @@ -76,7 +86,7 @@ on_CD = handle_emote_CD(50) //longer cooldown if("fart", "farts", "flip", "flips", "snap", "snaps") on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - if("cough", "coughs") + if("cough", "coughs", "slap", "slaps") on_CD = handle_emote_CD() if("sneeze", "sneezes") on_CD = handle_emote_CD() @@ -91,8 +101,21 @@ if("me") //OKAY SO RANT TIME, THIS FUCKING HAS TO BE HERE OR A SHITLOAD OF THINGS BREAK return custom_emote(m_type, message) //DO YOU KNOW WHY SHIT BREAKS? BECAUSE SO MUCH OLDCODE CALLS mob.emote("me",1,"whatever_the_fuck_it_wants_to_emote") //WHO THE FUCK THOUGHT THAT WAS A GOOD FUCKING IDEA!?!? - if("ping", "pings") + + if("howl", "howls") var/M = handle_emote_param(param) //Check to see if the param is valid (mob with the param name is in view). + message = "[src] howls[M ? " at [M]" : ""]!" + playsound(loc, 'sound/goonstation/voice/howl.ogg', 100, 0, 10) + m_type = 2 + + if("growl", "growls") + var/M = handle_emote_param(param) + message = "[src] growls[M ? " at [M]" : ""]." + playsound(loc, "growls", 80, 0) + m_type = 2 + + if("ping", "pings") + var/M = handle_emote_param(param) message = "[src] pings[M ? " at [M]" : ""]." playsound(loc, 'sound/machines/ping.ogg', 50, 0) @@ -785,12 +808,28 @@ + " handshake-mob, hug(s)-(none)/mob, johnny, jump, laugh(s), look(s)-(none)/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-(none)/mob, scream(s), shake(s)," \ + " shiver(s), shrug(s), sigh(s), signal(s)-#1-10,slap(s)-(none)/mob, smile(s),snap(s), sneeze(s), sniff(s), snore(s), stare(s)-(none)/mob, swag(s), tremble(s), twitch(es), twitch(es)_s," \ + " wag(s), wave(s), whimper(s), wink(s), yawn(s)" - if(species.name == "Machine") - emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob" - else if(species.name == "Slime People") - emotelist += "\nSlime people specific emotes :- squish(es)-(none)/mob" - to_chat(src, emotelist) + switch(species.name) + if("Machine") + emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob" + if("Drask") + emotelist += "\nDrask specific emotes :- drone(s)-(none)/mob, hum(s)-(none)/mob, rumble(s)-(none)/mob" + if("Kidan") + emotelist += "\nKidan specific emotes :- click(s), clack(s)" + if("Unathi") + emotelist += "\nUnathi specific emotes :- hiss(es)" + if("Vulpkanin") + emotelist += "\nVulpkanin specific emotes :- growl(s)-none/mob, howl(s)-none/mob" + + if (species.name == "Slime People") + emotelist += "\nSlime people specific emotes :- squish(es)-(none)/mob" + else + for(var/obj/item/organ/external/L in bodyparts) // if your limbs are squishy you can squish too! + if(L.dna.species in list("Slime People")) + emotelist += "\nSlime people body part specific emotes :- squish(es)-(none)/mob" + break + + to_chat(src, emotelist) else to_chat(src, "Unusable emote '[act]'. Say *help for a list.") diff --git a/code/modules/mob/living/carbon/human/interactive/functions.dm b/code/modules/mob/living/carbon/human/interactive/functions.dm index eb7b767dc94..46706c45363 100644 --- a/code/modules/mob/living/carbon/human/interactive/functions.dm +++ b/code/modules/mob/living/carbon/human/interactive/functions.dm @@ -420,9 +420,9 @@ return doing |= SNPC_SPECIAL - var/static/list/customableTypes = list(/obj/item/weapon/reagent_containers/food/snacks/customizable,/obj/item/weapon/reagent_containers/food/snacks/breadslice,/obj/item/weapon/reagent_containers/food/snacks/bun,/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough,/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti,/obj/item/trash/plate,/obj/item/trash/bowl) + var/static/list/customableTypes = list(/obj/item/weapon/reagent_containers/food/snacks/customizable,/obj/item/weapon/reagent_containers/food/snacks/breadslice,/obj/item/weapon/reagent_containers/food/snacks/bun,/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough,/obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti,/obj/item/trash/plate,/obj/item/trash/bowl) - var/static/list/rawtypes = list(/obj/item/weapon/reagent_containers/food/snacks/grown, /obj/item/weapon/reagent_containers/food/snacks/rawcutlet, /obj/item/weapon/reagent_containers/food/snacks/rawsticks, /obj/item/weapon/reagent_containers/food/snacks/salmonmeat, /obj/item/weapon/reagent_containers/food/snacks/carpmeat, /obj/item/weapon/reagent_containers/food/snacks/catfishmeat, /obj/item/weapon/reagent_containers/food/snacks/spagetti, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/doughslice, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/boiledrice, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/raw_bacon) + var/static/list/rawtypes = list(/obj/item/weapon/reagent_containers/food/snacks/grown, /obj/item/weapon/reagent_containers/food/snacks/rawcutlet, /obj/item/weapon/reagent_containers/food/snacks/rawsticks, /obj/item/weapon/reagent_containers/food/snacks/salmonmeat, /obj/item/weapon/reagent_containers/food/snacks/carpmeat, /obj/item/weapon/reagent_containers/food/snacks/catfishmeat, /obj/item/weapon/reagent_containers/food/snacks/spaghetti, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/doughslice, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/boiledrice, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/raw_bacon) try var/list/allContents = getAllContents() diff --git a/code/modules/mob/living/carbon/human/interactive/interactive.dm b/code/modules/mob/living/carbon/human/interactive/interactive.dm index 00b8e0a4544..b1d9b5bc68f 100644 --- a/code/modules/mob/living/carbon/human/interactive/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive/interactive.dm @@ -270,20 +270,20 @@ if(prob((SNPC_FUZZY_CHANCE_LOW+SNPC_FUZZY_CHANCE_HIGH)/4)) var/obj/item/organ/external/R = bodyparts_by_name["r_arm"] if(R) - R.robotize() + R.robotize(make_tough = 1) else var/obj/item/organ/external/L = bodyparts_by_name["l_arm"] if(L) - L.robotize() + L.robotize(make_tough = 1) //legs if(prob((SNPC_FUZZY_CHANCE_LOW+SNPC_FUZZY_CHANCE_HIGH)/4)) var/obj/item/organ/external/R = bodyparts_by_name["r_leg"] if(R) - R.robotize() + R.robotize(make_tough = 1) else var/obj/item/organ/external/L = bodyparts_by_name["l_leg"] if(L) - L.robotize() + L.robotize(make_tough = 1) UpdateDamageIcon() regenerate_icons() diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 00dbc50e8d0..f51ba71bff8 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -191,73 +191,47 @@ if(!(species.flags & RADIMMUNE)) if(radiation) - - if(get_int_organ(/obj/item/organ/internal/nucleation/resonant_crystal)) - var/rads = radiation/25 - radiation -= rads - radiation -= 0.1 - reagents.add_reagent("radium", rads/10) - if( prob(10) ) - to_chat(src, "You feel relaxed.") - return - if(radiation > 100) - radiation = 100 - Weaken(10) - if(!lying) - to_chat(src, "You feel weak.") + if(!weakened) emote("collapse") + Weaken(10) + to_chat(src, "You feel weak.") - if(radiation < 0) - radiation = 0 + radiation = Clamp(radiation, 0, 100) - else - var/damage = 0 - switch(radiation) - if(0 to 49) - radiation-- - if(prob(25)) - adjustToxLoss(1) - damage = 1 - updatehealth() - - if(50 to 74) - radiation -= 2 - damage = 1 + var/autopsy_damage = 0 + switch(radiation) + if(0 to 50) + radiation = max(radiation-1, 0) + if(prob(25)) adjustToxLoss(1) - if(prob(5)) - radiation -= 5 - Weaken(3) - if(!lying) - to_chat(src, "You feel weak.") - emote("collapse") - updatehealth() + autopsy_damage = 1 - if(75 to 100) - radiation -= 3 - adjustToxLoss(3) - damage = 3 - if(prob(1)) - to_chat(src, "You mutate!") - randmutb(src) - domutcheck(src,null) - emote("gasp") - updatehealth() + if(50 to 75) + radiation = max(radiation-2, 0) + adjustToxLoss(1) + autopsy_damage = 1 + if(prob(5)) + radiation = max(radiation-5, 0) + if(!weakened) + emote("collapse") + Weaken(3) + to_chat(src, "You feel weak.") - else - radiation -= 5 - adjustToxLoss(5) - damage = 5 - if(prob(1)) - to_chat(src, "You mutate!") - randmutb(src) - domutcheck(src,null) - emote("gasp") - updatehealth() + if(75 to 100) + radiation = max(radiation-3, 0) + adjustToxLoss(3) + autopsy_damage = 3 + if(prob(1)) + to_chat(src, "You mutate!") + randmutb(src) + domutcheck(src, null) + emote("gasp") - if(damage && bodyparts.len) - var/obj/item/organ/external/O = pick(bodyparts) - if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage) + if(autopsy_damage && bodyparts.len) + var/obj/item/organ/external/O = pick(bodyparts) + if(istype(O)) + O.add_autopsy_data("Radiation Poisoning", autopsy_damage) /mob/living/carbon/human/breathe() @@ -1100,7 +1074,7 @@ if(H.species && H.species.flags & NO_BREATHE) return //no puking if you can't smell! // Humans can lack a mind datum, y'know - if(H.mind && H.mind.assigned_role == "Detective") + if(H.mind && (H.mind.assigned_role == "Detective" || H.mind.assigned_role == "Coroner")) return //too cool for puke to_chat(H, "You smell something foul...") H.fakevomit() diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm index 7fee37a17c2..24f38bdbf64 100644 --- a/code/modules/mob/living/carbon/human/species/apollo.dm +++ b/code/modules/mob/living/carbon/human/species/apollo.dm @@ -99,7 +99,7 @@ burn_mod = 4 // holy shite, poor guys wont survive half a second cooking smores brute_mod = 2 // damn, double wham, double dam oxy_mod = 0 - flags = IS_WHITELISTED | NO_BREATHE | NO_BLOOD | NO_PAIN | HAS_LIPS | NO_SCAN + flags = IS_WHITELISTED | NO_BREATHE | NO_BLOOD | NO_PAIN | HAS_LIPS | NO_SCAN | RADIMMUNE dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet //Default styles for created mobs. @@ -110,8 +110,7 @@ "heart" = /obj/item/organ/internal/heart, "crystallized brain" = /obj/item/organ/internal/brain/crystal, "eyes" = /obj/item/organ/internal/eyes/luminescent_crystal, //Standard darksight of 2. - "strange crystal" = /obj/item/organ/internal/nucleation/strange_crystal, - "resonant crystal" = /obj/item/organ/internal/nucleation/resonant_crystal + "strange crystal" = /obj/item/organ/internal/nucleation/strange_crystal ) vision_organ = /obj/item/organ/internal/eyes/luminescent_crystal diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index 2041ca5f3e6..9f5d32e838a 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -90,7 +90,7 @@ if("Nanotrasen Representative") suit = /obj/item/clothing/suit/space/eva/plasmaman/nt_rep helm = /obj/item/clothing/head/helmet/space/eva/plasmaman/nt_rep - if("Medical Doctor","Brig Physician") + if("Medical Doctor","Brig Physician","Virologist") suit=/obj/item/clothing/suit/space/eva/plasmaman/medical helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical H.equip_or_collect(new /obj/item/device/flashlight/pen(H), slot_in_backpack) diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index 4348b8b048b..150f2d647bc 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -169,6 +169,8 @@ base_color = "#CF4D2F" butt_sprite = "vulp" + scream_verb = "yelps" + has_organ = list( "heart" = /obj/item/organ/internal/heart, "lungs" = /obj/item/organ/internal/lungs, @@ -843,23 +845,20 @@ return ..() /datum/species/diona/handle_life(var/mob/living/carbon/human/H) + H.radiation = Clamp(H.radiation, 0, 100) //We have to clamp this first, then decrease it, or there's a few edge cases of massive heals if we clamp and decrease at the same time. var/rads = H.radiation / 25 - H.apply_effect(-rads,IRRADIATE,0) - H.nutrition += rads + H.radiation = max(H.radiation-rads, 0) + H.nutrition = min(H.nutrition+rads, NUTRITION_LEVEL_WELL_FED+10) H.adjustBruteLoss(-(rads)) - H.adjustOxyLoss(-(rads)) H.adjustToxLoss(-(rads)) var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing if(isturf(H.loc)) //else, there's considered to be no light var/turf/T = H.loc light_amount = min(T.get_lumcount() * 10, 5) //hardcapped so it's not abused by having a ton of flashlights - H.nutrition += light_amount + H.nutrition = min(H.nutrition+light_amount, NUTRITION_LEVEL_WELL_FED+10) H.traumatic_shock -= light_amount - if(H.nutrition > NUTRITION_LEVEL_WELL_FED) - H.nutrition = NUTRITION_LEVEL_WELL_FED - if(light_amount > 0) H.clear_alert("nolight") else @@ -869,8 +868,7 @@ H.adjustBruteLoss(-(light_amount/2)) H.adjustFireLoss(-(light_amount/4)) - H.adjustOxyLoss(-(light_amount)) - if(H.nutrition < 200) + if(H.nutrition < NUTRITION_LEVEL_STARVING+50) H.take_overall_damage(10,0) H.traumatic_shock++ diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index c5ce705ba17..8a043dbf591 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -3,4 +3,12 @@ clear_fullscreens() update_action_buttons_icon() + + for(var/s in ownedSoullinks) + var/datum/soullink/S = s + S.ownerDies(gibbed, src) + for(var/s in sharedSoullinks) + var/datum/soullink/S = s + S.sharerDies(gibbed, src) + ..(gibbed) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 548f1fb357b..c54060cca7e 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -266,6 +266,8 @@ if(!supress_message) visible_message("[user] has grabbed [src] passively!") + return G + /mob/living/incapacitated() if(stat || paralysis || stunned || weakened || restrained()) return 1 diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index ccd0f652b68..39af8059e8b 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -55,7 +55,7 @@ if(mob_to_track) track = "[speaker_name] ([jobname])" - track += "\[OPEN\]" + track += "\[O\]" return track diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm index 056a65a8e66..5228803bd9d 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm @@ -53,7 +53,7 @@ if(..()) return - if(!allowed(usr)) + if(!allowed(usr) && !usr.can_admin_interact()) to_chat(usr, "Access denied.") return diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm index 187a32633b6..767a78e1f77 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm @@ -108,6 +108,12 @@ to_chat(usr, "This role is not yet available to you. You need to wait another [player_age_check] days.") return + var/pt_req = role_available_in_playtime(client, ROLE_DRONE) + if(pt_req) + var/pt_req_string = get_exp_format(pt_req) + to_chat(usr, "This role is not yet available to you. Play another [pt_req_string] to unlock it.") + return + var/deathtime = world.time - src.timeofdeath var/joinedasobserver = 0 if(istype(src,/mob/dead/observer)) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 1f4430c3aea..3de8b868430 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1205,13 +1205,11 @@ var/list/robot_verbs_default = list( canmove = 1 scrambledcodes = 1 //Disconnect it's camera so it's not so easily tracked. - if(src.camera) - qdel(src.camera) - src.camera = null - // I'm trying to get the Cyborg to not be listed in the camera list - // Instead of being listed as "deactivated". The downside is that I'm going - // to have to check if every camera is null or not before doing anything, to prevent runtime errors. - // I could change the network to null but I don't know what would happen, and it seems too hacky for me. + QDEL_NULL(src.camera) + // I'm trying to get the Cyborg to not be listed in the camera list + // Instead of being listed as "deactivated". The downside is that I'm going + // to have to check if every camera is null or not before doing anything, to prevent runtime errors. + // I could change the network to null but I don't know what would happen, and it seems too hacky for me. /mob/living/silicon/robot/proc/ResetSecurityCodes() set category = "Robot Commands" diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index f9f1bbf1c08..a71fbe2ae03 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -167,9 +167,8 @@ mode = BOT_CLEANING spawn(50) if(mode == BOT_CLEANING) - qdel(target) + QDEL_NULL(target) anchored = 0 - target = null mode = BOT_IDLE icon_state = "cleanbot[on]" @@ -222,4 +221,4 @@ text("[on ? "On" : "Off"]")) if(istype(A,/obj/effect/decal/cleanable)) clean(A) else - ..() \ No newline at end of file + ..() diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 3daacefb108..7c7a31b5ef0 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -302,7 +302,6 @@ melee_damage_lower = 1 melee_damage_upper = 5 attacktext = "prods" - speed = 0 environment_smash = 3 see_in_dark = 8 attack_sound = 'sound/weapons/tap.ogg' diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index bc75bd554e5..bf648e537ab 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -1,53 +1,53 @@ /mob/living/simple_animal/spiderbot - - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - minbodytemp = 0 - maxbodytemp = 500 - - var/obj/item/device/radio/borg/radio = null - var/mob/living/silicon/ai/connected_ai = null - var/obj/item/weapon/stock_parts/cell/cell = null - var/obj/machinery/camera/camera = null - var/obj/item/device/mmi/mmi = null - var/list/req_access = list(access_robotics) //Access needed to pop out the brain. - name = "Spider-bot" - desc = "A skittering robotic friend!" + desc = "A skittering robotic friend!" //More like ultimate shitter icon = 'icons/mob/robots.dmi' icon_state = "spiderbot-chassis" icon_living = "spiderbot-chassis" icon_dead = "spiderbot-smashed" wander = 0 universal_speak = 1 - health = 10 - maxHealth = 10 + health = 40 + maxHealth = 40 + melee_damage_lower = 2 + melee_damage_upper = 2 + melee_damage_type = BURN attacktext = "shocks" - attacktext = "shocks" - melee_damage_lower = 1 - melee_damage_upper = 3 + attack_sound = "sparks" response_help = "pets" response_disarm = "shoos" response_harm = "stomps on" - - var/obj/item/held_item = null //Storage for single item they can hold. - var/emagged = 0 //IS WE EXPLODEN? - var/syndie = 0 //IS WE SYNDICAT? (currently unused) - speed = -1 //Spiderbots gotta go fast. - //pass_flags = PASSTABLE //Maybe griefy? + speed = 0 mob_size = MOB_SIZE_SMALL speak_emote = list("beeps","clicks","chirps") + + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minbodytemp = 0 + maxbodytemp = 500 + can_hide = 1 ventcrawler = 2 loot = list(/obj/effect/decal/cleanable/blood/gibs/robot) del_on_death = 1 -/mob/living/simple_animal/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob, params) + var/emagged = 0 //is it getting ready to explode? + var/obj/item/device/mmi/mmi = null + var/emagged_master = null //for administrative purposes, to see who emagged the spiderbot; also for a holder for if someone emags an empty frame first then inserts an MMI. - if(istype(O, /obj/item/device/mmi) || istype(O, /obj/item/device/mmi/posibrain)) +/mob/living/simple_animal/spiderbot/Destroy() + if(emagged) + QDEL_NULL(mmi) + explosion(get_turf(src), -1, -1, 3, 5) + else + eject_brain() + return ..() + +/mob/living/simple_animal/spiderbot/attackby(obj/item/O, mob/living/user, params) + if(istype(O, /obj/item/device/mmi)) var/obj/item/device/mmi/B = O - if(src.mmi) //There's already a brain in it. + if(mmi) //There's already a brain in it. to_chat(user, "There's already a brain in [src]!") return if(!B.brainmob) @@ -65,47 +65,49 @@ ghost_can_reenter = 1 break if(!ghost_can_reenter) - to_chat(user, "[O] is completely unresponsive; there's no point.") + to_chat(user, "[B] is completely unresponsive; there's no point.") return if(B.brainmob.stat == DEAD) - to_chat(user, "[O] is dead. Sticking it into the frame would sort of defeat the purpose.") + to_chat(user, "[B] is dead. Sticking it into the frame would sort of defeat the purpose.") return - if(jobban_isbanned(B.brainmob, "Cyborg") || jobban_isbanned(B.brainmob,"nonhumandept")) - to_chat(user, "[O] does not seem to fit.") + if(jobban_isbanned(B.brainmob, "Cyborg") || jobban_isbanned(B.brainmob, "nonhumandept")) + to_chat(user, "[B] does not seem to fit.") return - to_chat(user, "You install [O] in [src]!") + to_chat(user, "You install [B] in [src]!") user.drop_item() - src.mmi = O - src.transfer_personality(O) + B.forceMove(src) + mmi = B + transfer_personality(B) - O.loc = src - src.update_icon() + update_icon() return 1 - if(istype(O, /obj/item/weapon/weldingtool)) + else if(iswelder(O) && user.a_intent == INTENT_HELP) var/obj/item/weapon/weldingtool/WT = O + user.changeNext_move(CLICK_CD_MELEE) if(WT.remove_fuel(0)) if(health < maxHealth) - health += pick(1,1,1,2,2,3) - if(health > maxHealth) - health = maxHealth + adjustHealth(-5) + playsound(loc, WT.usesound, 50, 1) add_fingerprint(user) - for(var/mob/W in viewers(user, null)) - W.show_message(text("[user] has spot-welded some of the damage to [src]!"), 1) + visible_message("[user] has spot-welded some of the damage to [src]!") else to_chat(user, "[src] is undamaged!") else to_chat(user, "Need more welding fuel!") - return - else if(istype(O, /obj/item/weapon/card/id)||istype(O, /obj/item/device/pda)) + else if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda)) if(!mmi) to_chat(user, "There's no reason to swipe your ID - the spiderbot has no brain to remove.") return 0 + if(emagged) + to_chat(user, "[src] doesn't seem to respond.") + return 0 + var/obj/item/weapon/card/id/id_card if(istype(O, /obj/item/weapon/card/id)) @@ -117,63 +119,41 @@ if(access_robotics in id_card.access) to_chat(user, "You swipe your access card and pop the brain out of [src].") eject_brain() - - if(held_item) - held_item.loc = src.loc - held_item = null - return 1 else to_chat(user, "You swipe your card, with no effect.") return 0 else - if(O.force) - var/damage = O.force - if(O.damtype == STAMINA) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if((M.client && !( M.blinded ))) - M.show_message("[src] has been attacked with the [O] by [user]. ") - else - to_chat(usr, "This weapon is ineffective, it does no damage.") - for(var/mob/M in viewers(src, null)) - if((M.client && !( M.blinded ))) - M.show_message("[user] gently taps [src] with the [O]. ") + ..() -/mob/living/simple_animal/spiderbot/emag_act(user as mob) +/mob/living/simple_animal/spiderbot/emag_act(mob/living/user) if(emagged) - to_chat(user, "[src] is already overloaded - better run.") + to_chat(user, "[src] doesn't seem to respond.") return 0 else emagged = 1 - to_chat(user, "You short out the security protocols and overload [src]'s cell, priming it to explode in a short time.") - spawn(100) - to_chat(src, "Your cell seems to be outputting a lot of power...") - spawn(200) - to_chat(src, "Internal heat sensors are spiking! Something is badly wrong with your cell!") - spawn(300) - src.explode() + to_chat(user, "You short out the security protocols and rewrite [src]'s internal memory.") + to_chat(src, "You have been emagged; you are now completely loyal to [user] and their every order!") + emagged_master = user.name + add_logs(user, src, "emagged") + maxHealth = 60 + health = 60 + melee_damage_lower = 15 + melee_damage_upper = 15 + attack_sound = 'sound/machines/defib_zap.ogg' -/mob/living/simple_animal/spiderbot/proc/transfer_personality(var/obj/item/device/mmi/M as obj) - - src.mind = M.brainmob.mind - src.mind.key = M.brainmob.key - src.ckey = M.brainmob.ckey - src.name = "Spider-bot ([M.brainmob.name])" - -/mob/living/simple_animal/spiderbot/proc/explode() //When emagged. - for(var/mob/M in viewers(src, null)) - if((M.client && !( M.blinded ))) - M.show_message("[src] makes an odd warbling noise, fizzles, and explodes.") - explosion(get_turf(loc), -1, -1, 3, 5) - eject_brain() - death() +/mob/living/simple_animal/spiderbot/proc/transfer_personality(obj/item/device/mmi/M) + mind = M.brainmob.mind + mind.key = M.brainmob.key + ckey = M.brainmob.ckey + name = "Spider-bot ([M.brainmob.name])" + if(emagged) + to_chat(src, "You have been emagged; you are now completely loyal to [emagged_master] and their every order!") /mob/living/simple_animal/spiderbot/proc/update_icon() if(mmi) - if(istype(mmi,/obj/item/device/mmi)) + if(istype(mmi, /obj/item/device/mmi)) icon_state = "spiderbot-chassis-mmi" icon_living = "spiderbot-chassis-mmi" if(istype(mmi, /obj/item/device/mmi/posibrain)) @@ -186,99 +166,10 @@ /mob/living/simple_animal/spiderbot/proc/eject_brain() if(mmi) - var/turf/T = get_turf(loc) - if(T) - mmi.loc = T - if(mind) mind.transfer_to(mmi.brainmob) + var/turf/T = get_turf(src) + mmi.forceMove(T) + if(mind) + mind.transfer_to(mmi.brainmob) mmi = null - src.name = "Spider-bot" - update_icon() - -/mob/living/simple_animal/spiderbot/Destroy() - eject_brain() - return ..() - -/mob/living/simple_animal/spiderbot/New() - - radio = new /obj/item/device/radio/borg(src) - camera = new /obj/machinery/camera(src) - camera.c_tag = "Spiderbot-[real_name]" - camera.network = list("SS13") - - ..() - -/mob/living/simple_animal/spiderbot/death(gibbed) - if(camera) - camera.status = 0 - - if(held_item) - held_item.forceMove(src.loc) - held_item = null - ..() - -//Cannibalized from the parrot mob. ~Zuhayr - -/mob/living/simple_animal/spiderbot/verb/drop_held_item() - set name = "Drop held item" - set category = "Spiderbot" - set desc = "Drop the item you're holding." - - if(stat) - return - - if(!held_item) - to_chat(usr, "You have nothing to drop!") - return 0 - - if(istype(held_item, /obj/item/weapon/grenade)) - visible_message("[src] launches \the [held_item]!", "You launch \the [held_item]!", "You hear a skittering noise and a thump!") - var/obj/item/weapon/grenade/G = held_item - G.loc = src.loc - G.prime() - held_item = null - return 1 - - visible_message("[src] drops \the [held_item]!", "You drop \the [held_item]!", "You hear a skittering noise and a soft thump.") - - held_item.loc = src.loc - held_item = null - return 1 - - return - -/mob/living/simple_animal/spiderbot/verb/get_item() - set name = "Pick up item" - set category = "Spiderbot" - set desc = "Allows you to take a nearby small item." - - if(stat) - return -1 - - if(held_item) - to_chat(src, "You are already holding \the [held_item]") - return 1 - - var/list/items = list() - for(var/obj/item/I in view(1,src)) - if(I.loc != src && I.w_class <= WEIGHT_CLASS_SMALL) - items.Add(I) - - var/obj/selection = input("Select an item.", "Pickup") in items - - if(selection) - for(var/obj/item/I in view(1, src)) - if(selection == I) - held_item = selection - selection.loc = src - visible_message("[src] scoops up \the [held_item]!", "You grab \the [held_item]!", "You hear a skittering noise and a clink.") - return held_item - to_chat(src, "\The [selection] is too far away.") - return 0 - - to_chat(src, "There is nothing of interest to take.") - return 0 - -/mob/living/simple_animal/spiderbot/examine(mob/user) - ..(user) - if(src.held_item) - to_chat(user, "It is carrying \a [src.held_item] [bicon(src.held_item)].") + name = "Spider-bot" + update_icon() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/tribbles.dm b/code/modules/mob/living/simple_animal/tribbles.dm index 78b28abf9f8..dfe4715edd5 100644 --- a/code/modules/mob/living/simple_animal/tribbles.dm +++ b/code/modules/mob/living/simple_animal/tribbles.dm @@ -242,7 +242,6 @@ var/global/totaltribbles = 0 //global variable so it updates for all tribbles, item_state = "furgloves" transfer_prints = TRUE transfer_blood = TRUE - siemens_coefficient = 0 // Equivalent to a winter coat's hood /obj/item/clothing/head/furcap diff --git a/code/modules/mob/living/stat_states.dm b/code/modules/mob/living/stat_states.dm index 58c4221504d..812eeaa0821 100644 --- a/code/modules/mob/living/stat_states.dm +++ b/code/modules/mob/living/stat_states.dm @@ -37,9 +37,9 @@ // handles revival through other means than cloning or adminbus (defib, IPC repair) /mob/living/proc/update_revive(updating = TRUE) if(stat != DEAD) - return + return 0 if(!can_be_revived()) - return + return 0 add_logs(src, null, "came back to life at [atom_loc_line(get_turf(src))]", admin=0, print_attack_log = 0) stat = CONSCIOUS dead_mob_list -= src @@ -49,3 +49,11 @@ update_canmove() // update_blind_effects() updatehealth() + + for(var/s in ownedSoullinks) + var/datum/soullink/S = s + S.ownerRevives(src) + for(var/s in sharedSoullinks) + var/datum/soullink/S = s + S.sharerRevives(src) + return 1 diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index cb86d417fbc..226e568f09e 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -11,6 +11,10 @@ for(var/mob/dead/observer/M in following_mobs) M.following = null following_mobs = null + QDEL_LIST_ASSOC_VAL(tkgrabbed_objects) + for(var/I in tkgrabbed_objects) + qdel(tkgrabbed_objects[I]) + tkgrabbed_objects = null if(buckled) buckled.unbuckle_mob() if(viewing_alternate_appearances) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 1e65b368ef0..c8c3f277716 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -200,3 +200,5 @@ var/list/actions = list() var/list/progressbars = null //for stacking do_after bars + + var/list/tkgrabbed_objects = list() // Assoc list of items to TK grabs diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index e1a1bdc1d8b..f8b8f7c84d7 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -16,11 +16,9 @@ return 0 /mob/living/carbon/human/isSynthetic() - // If they are 100% robotic, they count as synthetic. - for(var/obj/item/organ/external/E in bodyparts) - if(!(E.status & ORGAN_ROBOT)) - return 0 - return 1 + if(get_species() == "Machine") + return 1 + return 0 /mob/proc/get_screen_colour() diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 58c5ee4104d..c104d4e8ae6 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -302,7 +302,9 @@ AnnounceArrival(character, rank, join_message) callHook("latespawn", list(character)) - + var/datum/job/thisjob = job_master.GetJob(rank) + if(!thisjob.is_position_available() && thisjob in job_master.prioritized_jobs) + job_master.prioritized_jobs -= thisjob qdel(src) @@ -362,6 +364,18 @@ else if(shuttle_master.emergency.mode >= SHUTTLE_CALL) dat += "The station is currently undergoing evacuation procedures.
    " + if(length(job_master.prioritized_jobs)) + dat += "The station has flagged these jobs as high priority: " + var/amt = length(job_master.prioritized_jobs) + var/amt_count + for(var/datum/job/a in job_master.prioritized_jobs) + amt_count++ + if(amt_count != amt) + dat += " [a.title], " + else + dat += " [a.title].
    " + + dat += "Choose from the following open positions:

    " var/list/activePlayers = list() @@ -410,7 +424,10 @@ dat += "
    " dat += "[jobcat]" for(var/datum/job/job in categorizedJobs[jobcat]["jobs"]) - dat += "[job.title] ([job.current_positions]) (Active: [activePlayers[job]])
    " + if(job in job_master.prioritized_jobs) + dat += "[job.title] ([job.current_positions]) (Active: [activePlayers[job]])
    " + else + dat += "[job.title] ([job.current_positions]) (Active: [activePlayers[job]])
    " dat += "

    " dat += "" diff --git a/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm b/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm index bfb90ab881b..7460d357b21 100644 --- a/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm +++ b/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm @@ -213,8 +213,7 @@ if("PRG_deletechannel") . = 1 if(channel && ((channel.operator == src) || netadmin_mode)) - qdel(channel) - channel = null + QDEL_NULL(channel) if("PRG_setpassword") . = 1 if(!channel || ((channel.operator != src) && !netadmin_mode)) @@ -228,4 +227,4 @@ if(newpassword == "nopassword") channel.password = "" else - channel.password = newpassword \ No newline at end of file + channel.password = newpassword diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index 2a6cb6f18a6..81281fe3dcc 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -31,12 +31,8 @@ /obj/machinery/lapvend/proc/reset_order() state = 0 devtype = 0 - if(fabricated_laptop) - qdel(fabricated_laptop) - fabricated_laptop = null - if(fabricated_tablet) - qdel(fabricated_tablet) - fabricated_tablet = null + QDEL_NULL(fabricated_laptop) + QDEL_NULL(fabricated_tablet) dev_cpu = 1 dev_battery = 1 dev_disk = 1 @@ -303,4 +299,4 @@ obj/machinery/lapvend/attackby(obj/item/I, mob/user) T.time = worldtime2text() vendor_account.transaction_log.Add(T) return 1 - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/nano/interaction/inventory.dm b/code/modules/nano/interaction/inventory.dm index ccfbb695a99..cbe5165e5ff 100644 --- a/code/modules/nano/interaction/inventory.dm +++ b/code/modules/nano/interaction/inventory.dm @@ -4,7 +4,7 @@ /var/global/datum/topic_state/inventory_state/inventory_state = new() /datum/topic_state/inventory_state/can_use_topic(var/src_object, var/mob/user) - if(!(src_object in user)) + if(!((src_object in user) || user.is_in_active_hand(src_object) || user.is_in_inactive_hand(src_object))) return STATUS_CLOSE return user.shared_nano_interaction() diff --git a/code/modules/ninja/martial_art.dm b/code/modules/ninja/martial_art.dm index 1ea05b1073e..a17b2c00952 100644 --- a/code/modules/ninja/martial_art.dm +++ b/code/modules/ninja/martial_art.dm @@ -45,8 +45,8 @@ /datum/martial_art/ninja_martial_art/teach(var/mob/living/carbon/human/H,var/make_temporary=0) ..() H.middleClickOverride = new /datum/middleClickOverride/ninja_martial_art() - to_chat(H, "You have been taugh the ways of the Creeping Widow.
    \) - Your stikes on harm intent will deal more damage.
    Using middle mouse button on a nearby person while on harm intent will send them flying backwards.
    \ + to_chat(H, "You have been taught the ways of the Creeping Widow.
    \) + Your strikes on harm intent will deal more damage.
    Using middle mouse button on a nearby person while on harm intent will send them flying backwards.
    \ Your grabs will instantly be aggressive while you are using this style.
    Using middle mouse button while on harm intent and behind a person will put them in a silencing choke hold.
    \ Using middle mouse button on a nearby person while on disarm intent will wrench their wrist, causing them to drop what they are holding.
    " @@ -76,7 +76,7 @@ return 0 if(has_choke_hold) // Are we already choking someone? - to_chat(A, "You are have a target in your grip!") + to_chat(A, "You already have a target in your grip!") return 0 has_choke_hold = 1 @@ -98,8 +98,8 @@ D.silent += 1 D.adjustOxyLoss(1) else - D.visible_message("[A] loses his grip on [D]'s neck!", \ - "[A] loses his grip on your neck!") + D.visible_message("[A] loses \his grip on [D]'s neck!", \ + "[A] loses \his grip on your neck!") has_choke_hold = 0 return 0 I++ diff --git a/code/modules/ninja/suit/suit_initialisation.dm b/code/modules/ninja/suit/suit_initialisation.dm index 9954281b06f..59303b4707c 100644 --- a/code/modules/ninja/suit/suit_initialisation.dm +++ b/code/modules/ninja/suit/suit_initialisation.dm @@ -28,9 +28,8 @@ sleep(10) to_chat(usr, "Disconnecting neural-net interface... Success.") - if(usr.hud_used) - qdel(usr.hud_used) - usr.hud_used = null + + QDEL_NULL(usr.hud_used) usr.create_mob_hud() usr.regenerate_icons() @@ -64,9 +63,8 @@ sleep(5) to_chat(usr, "Suit secured, extending neural-net interface...") - if(usr.hud_used) - qdel(usr.hud_used) - usr.hud_used = null + + QDEL_NULL(usr.hud_used) usr.hud_used = new /datum/hud/human(usr, 'icons/mob/screen_ninja.dmi', "#ffffff", 255) if(usr.hud_used) usr.hud_used.show_hud(usr.hud_used.hud_version) @@ -91,4 +89,4 @@ to_chat(usr, "NOTICE: Suit de-activation protocals aborted.") else to_chat(usr, "FĆAL �Rr�R: ŧer nt recgnized, c-cntr-r䣧-ç äcked.") - return \ No newline at end of file + return diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index 2a7c7e113e1..f5d10cef156 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -87,7 +87,7 @@ user.visible_message("[class][user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \ "[class]You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") - if(user.get_inactive_hand() == src) + if(user.is_in_inactive_hand(src)) user.unEquip(src) new /obj/effect/decal/cleanable/ash(get_turf(src)) diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index dc86ce2299a..5797107e502 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -64,7 +64,7 @@ user.visible_message("[class][user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \ "[class]You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") - if(user.get_inactive_hand() == src) + if(user.is_in_inactive_hand(src)) user.unEquip(src) new /obj/effect/decal/cleanable/ash(get_turf(src)) diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm index 773ed4cff72..08a2104383d 100644 --- a/code/modules/projectiles/firing.dm +++ b/code/modules/projectiles/firing.dm @@ -43,8 +43,7 @@ if(targloc == curloc) if(target) //if the target is right on our location we go straight to bullet_act() target.bullet_act(BB, BB.def_zone) - qdel(BB) - BB = null + QDEL_NULL(BB) return 1 BB.preparePixelProjectile(target, targloc, user, params, spread) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 11abc89a343..d406dcaf0ef 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -223,6 +223,34 @@ user.put_in_hands(S) paper_cups-- +/obj/structure/reagent_dispensers/water_cooler/attackby(obj/item/weapon/W, mob/living/user, params) + add_fingerprint(user) + user.changeNext_move(CLICK_CD_MELEE) + if(iswrench(W)) + if(anchored) + playsound(loc, W.usesound, 100, 1) + user.visible_message("[user] starts loosening [src]'s floor casters.", \ + "You start loosening [src]'s floor casters...") + if(do_after(user, 40 * W.toolspeed, target = src)) + if(!loc || !anchored) + return + user.visible_message("[user] loosened [src]'s floor casters.", \ + "You loosen [src]'s floor casters.") + anchored = 0 + else + if(!isfloorturf(loc)) + user.visible_message("A floor must be present to secure [src]!") + return + playsound(loc, W.usesound, 100, 1) + user.visible_message("[user] start securing [src]'s floor casters...", \ + "You start securing [src]'s floor casters...") + if(do_after(user, 40 * W.toolspeed, target = src)) + if(!loc || anchored) + return + user.visible_message("[user] has secured [src]'s floor casters.", \ + "You have secured [src]'s floor casters.") + anchored = 1 + /obj/structure/reagent_dispensers/beerkeg name = "beer keg" desc = "Beer is liquid bread, it's good for you..." @@ -254,4 +282,4 @@ icon_state = "fuel_chem" anchored = 1 density = 0 - accepts_rig = 0 \ No newline at end of file + accepts_rig = 0 diff --git a/code/modules/spacepods/equipment.dm b/code/modules/spacepods/equipment.dm index d1f78ffdf28..dcdbe564657 100644 --- a/code/modules/spacepods/equipment.dm +++ b/code/modules/spacepods/equipment.dm @@ -104,7 +104,7 @@ /obj/item/device/spacepod_equipment/weaponry/laser name = "laser system" - desc = "A weak laser system for space pods, fires concentrated bursts of energy" + desc = "A weak laser system for space pods, fires concentrated bursts of energy." icon_state = "weapon_laser" projectile_type = /obj/item/projectile/beam shot_cost = 600 @@ -113,7 +113,7 @@ // MINING LASERS /obj/item/device/spacepod_equipment/weaponry/mining_laser_basic name = "weak mining laser system" - desc = "A weak mining laser system for space pods, fires bursts of energy that cut through rock" + desc = "A weak mining laser system for space pods, fires bursts of energy that cut through rock." icon = 'icons/goonstation/pods/ship.dmi' icon_state = "pod_taser" projectile_type = /obj/item/projectile/kinetic/pod @@ -123,7 +123,7 @@ /obj/item/device/spacepod_equipment/weaponry/mining_laser name = "mining laser system" - desc = "A mining laser system for space pods, fires bursts of energy that cut through rock" + desc = "A mining laser system for space pods, fires bursts of energy that cut through rock." icon = 'icons/goonstation/pods/ship.dmi' icon_state = "pod_m_laser" projectile_type = /obj/item/projectile/kinetic/pod/regular @@ -133,7 +133,7 @@ /obj/item/device/spacepod_equipment/weaponry/mining_laser_hyper name = "enhanced mining laser system" - desc = "An enhanced mining laser system for space pods, fires bursts of energy that cut through rock" + desc = "An enhanced mining laser system for space pods, fires bursts of energy that cut through rock." icon = 'icons/goonstation/pods/ship.dmi' icon_state = "pod_w_laser" projectile_type = /obj/item/projectile/kinetic/pod/enhanced @@ -226,15 +226,15 @@ // Passenger Seat /obj/item/device/spacepod_equipment/sec_cargo/chair - name = "passanger seat" - desc = "A passenger seat for a spacepod" + name = "passenger seat" + desc = "A passenger seat for a spacepod." icon_state = "sec_cargo_chair" occupant_mod = 1 // Loot Box /obj/item/device/spacepod_equipment/sec_cargo/loot_box name = "loot box" - desc = "A small compartment to store valuables" + desc = "A small compartment to store valuables." icon_state = "sec_cargo_loot" storage_mod = list("slots" = 7, "w_class" = 14) diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm index c5dcf75c69a..a90bd9bb1d8 100644 --- a/code/modules/spacepods/spacepod.dm +++ b/code/modules/spacepods/spacepod.dm @@ -377,8 +377,7 @@ user.visible_message(user, "[user] is drilling through the [src]'s lock!", "You start drilling through the [src]'s lock!") if(do_after(user, 100 * W.toolspeed, target = src)) - qdel(equipment_system.lock_system) - equipment_system.lock_system = null + QDEL_NULL(equipment_system.lock_system) user.visible_message(user, "[user] has destroyed the [src]'s lock!", "You destroy the [src]'s lock!") else diff --git a/code/modules/store/items.dm b/code/modules/store/items.dm index 4fc51d7fb8d..4eefa2847a1 100644 --- a/code/modules/store/items.dm +++ b/code/modules/store/items.dm @@ -83,7 +83,7 @@ /datum/storeitem/minigibber name = "miniature gibber" - desc = "A miniature recreation of NanoTrasen's famous meat grinder." + desc = "A miniature recreation of Nanotrasen's famous meat grinder." typepath = /obj/item/toy/minigibber cost = 400 diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm new file mode 100644 index 00000000000..174076c5fab --- /dev/null +++ b/code/modules/surgery/limb_augmentation.dm @@ -0,0 +1,55 @@ +/datum/surgery/limb_augmentation + name = "Augment Limb" + steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/augment) + possible_locs = list("chest","l_arm","r_arm","r_leg","l_leg") + +/datum/surgery/limb_augmentation/can_start(mob/user, mob/living/carbon/target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + if(affected.status & ORGAN_BROKEN) //The arm has to be in prime condition to augment it. + return 0 + if(affected.status & ORGAN_ROBOT) + return 0 + return 1 + +/datum/surgery_step/augment + name = "augment limb with robotic part" + allowed_tools = list(/obj/item/robot_parts = 100) + time = 32 + +/datum/surgery_step/augment/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/robot_parts/p = tool + if(p.part) + if(!(target_zone in p.part)) + to_chat(user, "[tool] cannot be used to augment this limb!") + return 0 + return 1 + +/datum/surgery_step/augment/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts augmenting [affected] with [tool].", "You start augmenting [affected] with [tool].") + +/datum/surgery_step/augment/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/robot_parts/L = tool + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] has finished augmenting [affected] with [tool].", \ + "You augment [affected] with [tool].") + + if(L.part) + for(var/part_name in L.part) + if(!target.get_organ(part_name)) + continue + affected.robotize(L.model_info, make_tough = 1, convert_all = 0) + if(L.sabotaged) + affected.sabotaged = 1 + break + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + + qdel(tool) + + return 1 \ No newline at end of file diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index fb52fba69f9..0c45118e9a8 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -268,15 +268,22 @@ var/list/organ_cache = list() /obj/item/organ/emp_act(severity) if(!(status & ORGAN_ROBOT)) return - switch(severity) - if(1.0) - take_damage(0,20) - return - if(2.0) - take_damage(0,7) - return - if(3.0) - take_damage(0,3) + if(tough) + switch(severity) + if(1) + take_damage(0, 5.5) + if(owner) + owner.Stun(10) + if(2) + take_damage(0, 2.8) + if(owner) + owner.Stun(5) + else + switch(severity) + if(1) + take_damage(0, 20) + if(2) + take_damage(0, 7) /obj/item/organ/internal/emp_act(severity) if(!robotic) @@ -284,13 +291,11 @@ var/list/organ_cache = list() if(robotic == 2) switch(severity) if(1.0) - take_damage(20,1) + take_damage(20, 1) if(2.0) - take_damage(7,1) - if(3.0) - take_damage(3,1) + take_damage(7, 1) else if(robotic == 1) - take_damage(11,1) + take_damage(11, 1) /obj/item/organ/internal/heart/emp_act(intensity) if(owner && robotic == 2) diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 151636a9a50..7d544a61cda 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -46,6 +46,7 @@ var/obj/item/organ/external/parent var/list/obj/item/organ/external/children + var/list/convertable_children = list() // Internal organs of this body part var/list/internal_organs = list() @@ -194,6 +195,10 @@ ****************************************************/ /obj/item/organ/external/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) + if(tough) + brute = max(0, brute - 5) + burn = max(0, burn - 4) + if((brute <= 0) && (burn <= 0)) return 0 @@ -847,19 +852,18 @@ Note that amputating the affected organ does in fact remove the infection from t status &= ~ORGAN_BROKEN return 1 -// I put these two next to each other to highlight that both exist. This should likely be resolved. -/obj/item/organ/external/robotize() +/obj/item/organ/external/robotize(company, make_tough = 0, convert_all = 1) ..() //robot limbs take reduced damage - brute_mod = 0.66 - burn_mod = 0.66 + if(!make_tough) + brute_mod = 0.66 + burn_mod = 0.66 + fail_at_full_damage = 1 + else + tough = 1 // Robot parts also lack bones // This is so surgery isn't kaput, let's see how this does encased = null - fail_at_full_damage = 1 - -/obj/item/organ/external/robotize(var/company) - ..() if(company && istext(company)) set_company(company) @@ -867,8 +871,8 @@ Note that amputating the affected organ does in fact remove the infection from t cannot_break = 1 get_icon() for(var/obj/item/organ/external/T in children) - if(T) - T.robotize() + if((convert_all) || (T.type in convertable_children)) + T.robotize(company, make_tough, convert_all) @@ -900,12 +904,12 @@ Note that amputating the affected organ does in fact remove the infection from t return 0 /obj/item/organ/external/proc/is_usable() - if((status & ORGAN_ROBOT) && get_damage() >= max_damage) //robot limbs just become inoperable at max damage + if(((status & ORGAN_ROBOT) && get_damage() >= max_damage) && !tough) //robot limbs just become inoperable at max damage return return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD)) /obj/item/organ/external/proc/is_malfunctioning() - return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam)) + return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam) && !tough) /obj/item/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0) if(!owner || loc != owner) diff --git a/code/modules/surgery/organs/robolimbs.dm b/code/modules/surgery/organs/robolimbs.dm index 2d31942059c..d3c297bc0c7 100644 --- a/code/modules/surgery/organs/robolimbs.dm +++ b/code/modules/surgery/organs/robolimbs.dm @@ -1,5 +1,6 @@ var/global/list/all_robolimbs = list() var/global/list/chargen_robolimbs = list() +var/global/list/selectable_robolimbs = list() var/global/datum/robolimb/basic_robolimb /proc/populate_robolimb_list() @@ -11,12 +12,15 @@ var/global/datum/robolimb/basic_robolimb if(R != "head" && R != "chest" && R != "groin" ) //Part of the method that ensures only IPCs can access head, chest and groin prosthetics. if(R.has_subtypes) //Ensures solos get added to the list as well be incorporating has_subtypes == 1 and has_subtypes == 2. chargen_robolimbs[R.company] = R //List only main brands and solo parts. + if(R.selectable) + selectable_robolimbs[R.company] = R /datum/robolimb var/company = "Unbranded" // Shown when selecting the limb. var/desc = "A generic unbranded robotic prosthesis." // Seen when examining a limb. var/icon = 'icons/mob/human_races/robotic.dmi' // Icon base to draw from. var/unavailable_at_chargen // If set, not available at chargen. + var/selectable = 1 // If set, is it available for selection on attack_self with a robo limb? var/is_monitor // If set, limb is a monitor and should be getting monitor styles. var/has_subtypes = 2 // If null, object is a model. If 1, object is a brand (that serves as the default model) with child models. If 2, object is a brand that has no child models and thus also serves as the model.. var/parts = list("chest", "groin", "head", "r_arm", "r_hand", "r_leg", "r_foot", "l_leg", "l_foot", "l_arm", "l_hand") // Defines what parts said brand can replace on a body. @@ -31,6 +35,7 @@ var/global/datum/robolimb/basic_robolimb company = "Bishop Cybernetics alt." icon = 'icons/mob/human_races/cyberlimbs/bishop/bishop_alt1.dmi' parts = list("head") + selectable = 0 has_subtypes = null /datum/robolimb/bishop/monitor @@ -38,6 +43,7 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/bishop/bishop_monitor.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null /datum/robolimb/hesphiastos @@ -51,6 +57,7 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/hesphiastos/hesphiastos_alt1.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null /datum/robolimb/hesphiastos/monitor @@ -58,6 +65,7 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/hesphiastos/hesphiastos_monitor.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null /datum/robolimb/morpheus @@ -74,6 +82,7 @@ var/global/datum/robolimb/basic_robolimb parts = list("head") unavailable_at_chargen = null is_monitor = null + selectable = 0 has_subtypes = 2 //Edge case. We want to be able to pick this one, and if we had it left as null for has_subtypes we'd be assuming it'll be chosen as a child model, //and since the parent is unavailable at chargen, we wouldn't be able to see it in the list anyway. Now, we'll be able to select the Morpheus Ckt. Alt. head as a solo-model. @@ -87,6 +96,7 @@ var/global/datum/robolimb/basic_robolimb company = "Ward-Takahashi alt." icon = 'icons/mob/human_races/cyberlimbs/wardtakahashi/wardtakahashi_alt1.dmi' parts = list("head") + selectable = 0 has_subtypes = null /datum/robolimb/wardtakahashi/monitor @@ -94,6 +104,7 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/wardtakahashi/wardtakahashi_monitor.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null /datum/robolimb/xion @@ -106,6 +117,7 @@ var/global/datum/robolimb/basic_robolimb company = "Xion Manufacturing Group alt." icon = 'icons/mob/human_races/cyberlimbs/xion/xion_alt1.dmi' parts = list("head") + selectable = 0 has_subtypes = null /datum/robolimb/xion/monitor @@ -113,6 +125,7 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/xion/xion_monitor.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null /datum/robolimb/zenghu @@ -131,6 +144,7 @@ var/global/datum/robolimb/basic_robolimb company = "Shellguard Munitions Elite Series" icon = 'icons/mob/human_races/cyberlimbs/shellguard/shellguard_alt1.dmi' parts = list("head") + selectable = 0 has_subtypes = null /datum/robolimb/shellguard/monitor @@ -138,4 +152,5 @@ var/global/datum/robolimb/basic_robolimb icon = 'icons/mob/human_races/cyberlimbs/shellguard/shellguard_monitor.dmi' parts = list("head") is_monitor = 1 + selectable = 0 has_subtypes = null \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm index a6467584963..f11d123ea75 100644 --- a/code/modules/surgery/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -17,6 +17,7 @@ parent_organ = null encased = "ribcage" var/fat = FALSE + convertable_children = list(/obj/item/organ/external/groin) /obj/item/organ/external/chest/proc/makeFat(update_body_icon = 1) fat = TRUE @@ -60,6 +61,7 @@ parent_organ = "chest" amputation_point = "left shoulder" can_grasp = 1 + convertable_children = list(/obj/item/organ/external/hand) /obj/item/organ/external/arm/right limb_name = "r_arm" @@ -67,6 +69,7 @@ icon_name = "r_arm" body_part = ARM_RIGHT amputation_point = "right shoulder" + convertable_children = list(/obj/item/organ/external/hand/right) /obj/item/organ/external/leg limb_name = "l_leg" @@ -80,6 +83,7 @@ parent_organ = "groin" amputation_point = "left hip" can_stand = 1 + convertable_children = list(/obj/item/organ/external/foot) /obj/item/organ/external/leg/right limb_name = "r_leg" @@ -88,6 +92,7 @@ body_part = LEG_RIGHT icon_position = RIGHT amputation_point = "right hip" + convertable_children = list(/obj/item/organ/external/foot/right) /obj/item/organ/external/foot limb_name = "l_foot" diff --git a/code/world.dm b/code/world.dm index ebf4865a1a8..34d61dbbc21 100644 --- a/code/world.dm +++ b/code/world.dm @@ -375,7 +375,7 @@ var/world_topic_spam_protect_time = world.timeofday s += "[station_name()]"; s += " (" - s += "" //Change this to wherever you want the hub to link to. + s += "" //Change this to wherever you want the hub to link to. s += "[game_version]" s += "" s += ")" diff --git a/config/example/admins.txt b/config/example/admins.txt index 0e89ae17e23..c42f756a87d 100644 --- a/config/example/admins.txt +++ b/config/example/admins.txt @@ -5,4 +5,4 @@ # Ranks can be anything defined in admin_ranks.txt # ###################################################################### -# example - Admin +# example - Hosting Provider diff --git a/config/example/game_options.txt b/config/example/game_options.txt index 549633d6a2d..7246e0773fa 100644 --- a/config/example/game_options.txt +++ b/config/example/game_options.txt @@ -48,7 +48,7 @@ ROBOT_DELAY 1.5 MONKEY_DELAY 1.5 ALIEN_DELAY 1.5 SLIME_DELAY 1.5 -ANIMAL_DELAY 1.5 +ANIMAL_DELAY 2.5 ## Comment for "normal" explosions, which ignore obstacles ## Uncomment for explosions that react to doors and walls diff --git a/html/changelog.html b/html/changelog.html index 8321bac3afd..70f2ffdb953 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,203 @@ -->
    +

    27 June 2017

    +

    Alexshreds updated:

    +
      +
    • EMPs now disable radios for a period of time
    • +
    +

    Citinited updated:

    +
      +
    • Adds the Rapid Pipe Dispenser (RPD). All Atmospherics Technician lockers and the Chief Engineer's locker get one each.
    • +
    +

    Code Fethas and Sprites Phantasmicdream updated:

    +
      +
    • Fancy Victorian Clothes
    • +
    +

    FlattestGuitar updated:

    +
      +
    • defibs work even if you don't target the chest
    • +
    • Chaplain's soul stone is now opt-in.
    • +
    +

    Fox McCloud updated:

    +
      +
    • Can now augment all non-head limbs with surgery
    • +
    • Can select the company design of a limb by using a robot part in your hands
    • +
    +

    Kyep updated:

    +
      +
    • Gamma ship now looks like a real supply pod/ship, doesn't encourage wizards/vampires to hide in it, and has been updated with a wall-mounted charger and smarter layout.
    • +
    • Fixed a bug causing gamma armory mech recharger to be unusable after gamma alert was declared.
    • +
    • Admins may now spawn 'Gimmick' teams, including Janitorial ERT, Paranormal ERT, and more. Any admin outfit, any mission, spawned anywhere.
    • +
    • Paranormal ERT outfit now exists. It acts like a red security ERT, except with focus on fighting paranormal threats.
    • +
    • Janitorial ERT now gets ERT headset, not centcom headset. Also, they now get a survival box, and a flashlight.
    • +
    • New 'department' shuttle now has more public-access seating.
    • +
    +

    ProperPants updated:

    +
      +
    • Plasmaman virologists now spawn with a medical plasmasuit instead of an assistant one.
    • +
    +

    Purpose2 updated:

    +
      +
    • Water coolers have been fitted with better bolts, enabling them to be loosened and moved.
    • +
    • Antag barbers scissors now have the same name as regular scissors.
    • +
    • AIs door open link is now [O] rather than [OPEN].
    • +
    • The Syndicate once more recognises the Coroner as a member of the medical team for purposes for uplink items.
    • +
    • The chef may now tap into the Syndicate's poison networks for use in his dishes.
    • +
    • The chef's supply crate now comes with another rolling pin. Stop misplacing these.
    • +
    +

    tigercat2000 updated:

    +
      +
    • Karma returned to the Special Verbs tab
    • +
    + +

    26 June 2017

    +

    Crazylemon64 updated:

    +
      +
    • TK can now manipulate adjacent tiles. Use throw mode to override this if you want to move an object a single tile.
    • +
    • TK can now remotely manipulate item stacks.
    • +
    • TK can now remotely operate an RCD
    • +
    • TK now behaves more consistently regarding interacting with various objects remotely
    • +
    +

    Kyep updated:

    +
      +
    • ID card consoles can now be used to prioritize any on-station job, including head jobs and karma jobs.
    • +
    • Playing as a drone now requires 10h of playtime.
    • +
    • Admin-ghosts can now interact with (ie: activate) the drone fab without having to spawn in as engineer to do so.
    • +
    • Prioritized jobs now lose their priority status once all their slots are filled. In the event someone with a formerly prioritized job cryos, the HoP may want to re-prioritize the job.
    • +
    +

    Purpose2 updated:

    +
      +
    • Coroners are more battlehardened, and thus don't throw up around dead bodies anymore.
    • +
    + +

    25 June 2017

    +

    Kyep updated:

    +
      +
    • Trial admins no longer see a permissions error when opening player panel.
    • +
    + +

    24 June 2017

    +

    Allfd updated:

    +
      +
    • Ported growl and howl sounds from Goon
    • +
    • Added growl and howl emotes to Vulpkanin
    • +
    +

    Kyep updated:

    +
      +
    • Activating a dust implant no longer causes NODROP items to drop.
    • +
    +

    Purpose2 updated:

    +
      +
    • The *slap emote now has a cooldown like all other noise making emotes.
    • +
    +

    SamHPurp updated:

    +
      +
    • The Coroner will respect the CMO's Authoritah.
    • +
    + +

    23 June 2017

    +

    Kyep updated:

    +
      +
    • Smite/Bless commands are now restricted to Game Admins. (admins with R_EVENT)
    • +
    • Admins can now access telecomms while ghosted.
    • +
    +

    Vivalas updated:

    +
      +
    • Buckling mobs to beds now displays them correctly.
    • +
    + +

    22 June 2017

    +

    Crazylemon64 updated:

    +
      +
    • Cloners now malfunction if the original comes back to life
    • +
    +

    Purpose2 updated:

    +
      +
    • RCDs can no longer construct multiple airlocks on a single tile
    • +
    + +

    21 June 2017

    +

    tigercat2000 updated:

    +
      +
    • Changelings are now tentacle monsters. Give them a schoolgirl outfit.
    • +
    + +

    20 June 2017

    +

    Purpose2 updated:

    +
      +
    • Fixes Fluorine's non-functionality in plants.
    • +
    + +

    19 June 2017

    +

    Fox McCloud updated:

    +
      +
    • Diona nutrition bar should no longer flicker constantly
    • +
    + +

    18 June 2017

    +

    Citinited updated:

    +
      +
    • Using a screwdriver on a camera console will now deconstruct it instead of opening the camera window.
    • +
    + +

    16 June 2017

    +

    Alffd updated:

    +
      +
    • Makes kittens visible when resting
    • +
    +

    Fethas updated:

    +
      +
    • Public Wiggler Tail
    • +
    • Chaplains have some new clothes in thier locker.
    • +
    +

    Fox McCloud updated:

    +
      +
    • tweaked Revenant and slaughter demon movement speed
    • +
    • Spiderbots have been slowed down to human levels
    • +
    • Spiderbots melee attack consistently deals 2 damage, deals burn, and plays a sparks sound
    • +
    • Spiderbots no longer have a built in camera
    • +
    • Spiderbots now have 40 health (previously 10)
    • +
    • Attacking a spiderbot more consistent with other simple mobs
    • +
    • Healing a spiderbot with a welder now plays a sound and incurs a cooldown
    • +
    • Spiderbots can no longer carry items
    • +
    • Emagging a spiderbot makes it loyal to the person who emagged it. Additionally, it gains 20 extra health, its shocks will do 15 damage, and will explode on death
    • +
    +

    FreeStylaLT updated:

    +
      +
    • Changed Araneus' spawn location so he wouldn't break tables at round-start anymore
    • +
    +

    Kyep updated:

    +
      +
    • HoPs can now set jobs as 'priority'. Priority jobs are highlighted on the latejoin screen. This allows HoPs to proactively broadcast that they need more people to fill those jobs - and reduces the chance of critical crew shortages.
    • +
    +

    Purpose2 updated:

    +
      +
    • Soylen Viridians are now correctly Soylent Viridians. Nanotrasen will still not confirm rumours of the contents of these nor Soylent Greens however.
    • +
    • Nanotrasen is now more consistent with brand management.
    • +
    • An array of typos, grammatical tweaks and other pedantic fixes.
    • +
    • Adds a jobs board to the Newscaster. See what roles are available before seeing the HoP!
    • +
    +

    TullyBurnalot updated:

    +
      +
    • Autopsy Scanners will now print out Coroner Reports when a pen is used on them
    • +
    +

    alexkar598 updated:

    +
      +
    • Rename Spagetti to Spaghetti
    • +
    + +

    13 June 2017

    +

    KasparoVy updated:

    +
      +
    • Moves a hidden emergency locker to where it is visible.
    • +
    +

    Vivalas updated:

    +
      +
    • Brig timers will now update the records of those who are imprisoned in their cell, as long as their name is entered correctly.
    • +
    • Sentences and arresting officers are announced over the security channel by brig timers, as well as the names of those who end timers manually.
    • +
    +

    10 June 2017

    Alffd updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index e05ac7eb89b..24dd1649beb 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -4907,3 +4907,150 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. FOR THE HONOR OF THE HIGHLANDERS! - tweak: Highlander now equips combatants with a Highlander claymore instead of a normal claymore. FIGHT ON BROTHERS! +2017-06-13: + KasparoVy: + - bugfix: Moves a hidden emergency locker to where it is visible. + Vivalas: + - rscadd: Brig timers will now update the records of those who are imprisoned in + their cell, as long as their name is entered correctly. + - rscadd: Sentences and arresting officers are announced over the security channel + by brig timers, as well as the names of those who end timers manually. +2017-06-16: + Alffd: + - bugfix: Makes kittens visible when resting + Fethas: + - tweak: Public Wiggler Tail + - rscadd: Chaplains have some new clothes in thier locker. + Fox McCloud: + - tweak: tweaked Revenant and slaughter demon movement speed + - tweak: Spiderbots have been slowed down to human levels + - tweak: Spiderbots melee attack consistently deals 2 damage, deals burn, and plays + a sparks sound + - tweak: Spiderbots no longer have a built in camera + - tweak: Spiderbots now have 40 health (previously 10) + - tweak: Attacking a spiderbot more consistent with other simple mobs + - tweak: Healing a spiderbot with a welder now plays a sound and incurs a cooldown + - tweak: Spiderbots can no longer carry items + - tweak: Emagging a spiderbot makes it loyal to the person who emagged it. Additionally, + it gains 20 extra health, its shocks will do 15 damage, and will explode on + death + FreeStylaLT: + - tweak: Changed Araneus' spawn location so he wouldn't break tables at round-start + anymore + Kyep: + - rscadd: HoPs can now set jobs as 'priority'. Priority jobs are highlighted on + the latejoin screen. This allows HoPs to proactively broadcast that they need + more people to fill those jobs - and reduces the chance of critical crew shortages. + Purpose2: + - bugfix: Soylen Viridians are now correctly Soylent Viridians. Nanotrasen will + still not confirm rumours of the contents of these nor Soylent Greens however. + - bugfix: Nanotrasen is now more consistent with brand management. + - bugfix: An array of typos, grammatical tweaks and other pedantic fixes. + - rscadd: Adds a jobs board to the Newscaster. See what roles are available before + seeing the HoP! + TullyBurnalot: + - rscadd: Autopsy Scanners will now print out Coroner Reports when a pen is used + on them + alexkar598: + - bugfix: Rename Spagetti to Spaghetti +2017-06-18: + Citinited: + - bugfix: Using a screwdriver on a camera console will now deconstruct it instead + of opening the camera window. +2017-06-19: + Fox McCloud: + - tweak: Diona nutrition bar should no longer flicker constantly +2017-06-20: + Purpose2: + - bugfix: Fixes Fluorine's non-functionality in plants. +2017-06-21: + tigercat2000: + - rscadd: Changelings are now tentacle monsters. Give them a schoolgirl outfit. +2017-06-22: + Crazylemon64: + - rscadd: Cloners now malfunction if the original comes back to life + Purpose2: + - bugfix: RCDs can no longer construct multiple airlocks on a single tile +2017-06-23: + Kyep: + - bugfix: Smite/Bless commands are now restricted to Game Admins. (admins with R_EVENT) + - tweak: Admins can now access telecomms while ghosted. + Vivalas: + - bugfix: Buckling mobs to beds now displays them correctly. +2017-06-24: + Allfd: + - rscadd: Ported growl and howl sounds from Goon + - rscadd: Added growl and howl emotes to Vulpkanin + Kyep: + - bugfix: Activating a dust implant no longer causes NODROP items to drop. + Purpose2: + - tweak: The *slap emote now has a cooldown like all other noise making emotes. + SamHPurp: + - bugfix: The Coroner will respect the CMO's Authoritah. +2017-06-25: + Kyep: + - bugfix: Trial admins no longer see a permissions error when opening player panel. +2017-06-26: + Crazylemon64: + - rscadd: TK can now manipulate adjacent tiles. Use throw mode to override this + if you want to move an object a single tile. + - rscadd: TK can now remotely manipulate item stacks. + - rscadd: TK can now remotely operate an RCD + - bugfix: TK now behaves more consistently regarding interacting with various objects + remotely + Kyep: + - rscadd: ID card consoles can now be used to prioritize any on-station job, including + head jobs and karma jobs. + - rscadd: Playing as a drone now requires 10h of playtime. + - bugfix: 'Admin-ghosts can now interact with (ie: activate) the drone fab without + having to spawn in as engineer to do so.' + - bugfix: Prioritized jobs now lose their priority status once all their slots are + filled. In the event someone with a formerly prioritized job cryos, the HoP + may want to re-prioritize the job. + Purpose2: + - rscadd: Coroners are more battlehardened, and thus don't throw up around dead + bodies anymore. +2017-06-27: + Alexshreds: + - tweak: EMPs now disable radios for a period of time + Citinited: + - rscadd: Adds the Rapid Pipe Dispenser (RPD). All Atmospherics Technician lockers + and the Chief Engineer's locker get one each. + Code Fethas and Sprites Phantasmicdream: + - rscadd: Fancy Victorian Clothes + FlattestGuitar: + - tweak: defibs work even if you don't target the chest + - tweak: Chaplain's soul stone is now opt-in. + Fox McCloud: + - rscadd: Can now augment all non-head limbs with surgery + - rscadd: Can select the company design of a limb by using a robot part in your + hands + Kyep: + - rscadd: Gamma ship now looks like a real supply pod/ship, doesn't encourage wizards/vampires + to hide in it, and has been updated with a wall-mounted charger and smarter + layout. + - bugfix: Fixed a bug causing gamma armory mech recharger to be unusable after gamma + alert was declared. + - rscadd: Admins may now spawn 'Gimmick' teams, including Janitorial ERT, Paranormal + ERT, and more. Any admin outfit, any mission, spawned anywhere. + - rscadd: Paranormal ERT outfit now exists. It acts like a red security ERT, except + with focus on fighting paranormal threats. + - bugfix: Janitorial ERT now gets ERT headset, not centcom headset. Also, they now + get a survival box, and a flashlight. + - tweak: New 'department' shuttle now has more public-access seating. + ProperPants: + - rscadd: Plasmaman virologists now spawn with a medical plasmasuit instead of an + assistant one. + Purpose2: + - rscadd: Water coolers have been fitted with better bolts, enabling them to be + loosened and moved. + - tweak: Antag barbers scissors now have the same name as regular scissors. + - tweak: AIs door open link is now [O] rather than [OPEN]. + - bugfix: The Syndicate once more recognises the Coroner as a member of the medical + team for purposes for uplink items. + - rscadd: The chef may now tap into the Syndicate's poison networks for use in his + dishes. + - rscadd: The chef's supply crate now comes with another rolling pin. Stop misplacing + these. + tigercat2000: + - tweak: Karma returned to the Special Verbs tab diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index ec06922a07d..b45657fff51 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 1c4472d5299..499d5ec1a0d 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/custom_synthetic/custom-synthetic.dmi b/icons/mob/custom_synthetic/custom-synthetic.dmi index 29917049c85..08642abaab9 100644 Binary files a/icons/mob/custom_synthetic/custom-synthetic.dmi and b/icons/mob/custom_synthetic/custom-synthetic.dmi differ diff --git a/icons/mob/custom_synthetic/custom_head.dmi b/icons/mob/custom_synthetic/custom_head.dmi index 76ffcedcc82..c66ecb6c8be 100644 Binary files a/icons/mob/custom_synthetic/custom_head.dmi and b/icons/mob/custom_synthetic/custom_head.dmi differ diff --git a/icons/mob/custom_synthetic/custom_lefthand.dmi b/icons/mob/custom_synthetic/custom_lefthand.dmi index 8d469195434..0005ed032e8 100644 Binary files a/icons/mob/custom_synthetic/custom_lefthand.dmi and b/icons/mob/custom_synthetic/custom_lefthand.dmi differ diff --git a/icons/mob/custom_synthetic/custom_righthand.dmi b/icons/mob/custom_synthetic/custom_righthand.dmi index 8d469195434..df64d269aaa 100644 Binary files a/icons/mob/custom_synthetic/custom_righthand.dmi and b/icons/mob/custom_synthetic/custom_righthand.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 3764c64aa50..f25715b9220 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/inhands/fluff_lefthand.dmi b/icons/mob/inhands/fluff_lefthand.dmi index 209f7660781..417ca1bb107 100644 Binary files a/icons/mob/inhands/fluff_lefthand.dmi and b/icons/mob/inhands/fluff_lefthand.dmi differ diff --git a/icons/mob/inhands/fluff_righthand.dmi b/icons/mob/inhands/fluff_righthand.dmi index d048ff86003..6d4f3a2c76b 100644 Binary files a/icons/mob/inhands/fluff_righthand.dmi and b/icons/mob/inhands/fluff_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 08050649225..1461df9bbbe 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 90a218c7166..c66e67820a3 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/pets.dmi b/icons/mob/pets.dmi index c47ca000f0c..4f46db21354 100644 Binary files a/icons/mob/pets.dmi and b/icons/mob/pets.dmi differ diff --git a/icons/mob/species/drask/suit.dmi b/icons/mob/species/drask/suit.dmi index 6e608313eda..b323ea5c175 100644 Binary files a/icons/mob/species/drask/suit.dmi and b/icons/mob/species/drask/suit.dmi differ diff --git a/icons/mob/species/drask/uniform.dmi b/icons/mob/species/drask/uniform.dmi index 9dd5a22618c..ce6955f5d05 100644 Binary files a/icons/mob/species/drask/uniform.dmi and b/icons/mob/species/drask/uniform.dmi differ diff --git a/icons/mob/species/grey/helmet.dmi b/icons/mob/species/grey/helmet.dmi new file mode 100644 index 00000000000..2e1bbd6423c Binary files /dev/null and b/icons/mob/species/grey/helmet.dmi differ diff --git a/icons/mob/species/grey/suit.dmi b/icons/mob/species/grey/suit.dmi index 3d61d72dec8..634acbfbffb 100644 Binary files a/icons/mob/species/grey/suit.dmi and b/icons/mob/species/grey/suit.dmi differ diff --git a/icons/mob/species/grey/uniform.dmi b/icons/mob/species/grey/uniform.dmi index 111efe6de65..edf646b68fc 100644 Binary files a/icons/mob/species/grey/uniform.dmi and b/icons/mob/species/grey/uniform.dmi differ diff --git a/icons/mob/species/vox/suit.dmi b/icons/mob/species/vox/suit.dmi index c339c15ab18..8c40cb79347 100644 Binary files a/icons/mob/species/vox/suit.dmi and b/icons/mob/species/vox/suit.dmi differ diff --git a/icons/mob/species/vox/uniform.dmi b/icons/mob/species/vox/uniform.dmi index 9324259ff14..6c0c52492f3 100644 Binary files a/icons/mob/species/vox/uniform.dmi and b/icons/mob/species/vox/uniform.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 03c1180b1dc..368eca0c8c3 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index f9bb3b2bbec..377680c2716 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index b82450ab87a..5c34785d51e 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 669e8dff821..92b77524bc4 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 2a99367e4a4..0d9698e5327 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index 639bedfde29..b5f06ca4745 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 283684b9d46..5f8fb26d74c 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 316790998c5..8c3d0f2c81f 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index 83276e5ec57..e4569806d57 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ diff --git a/nano/styles/_formatting.less b/nano/styles/_formatting.less index e8f65be969c..19ff288dd3f 100644 --- a/nano/styles/_formatting.less +++ b/nano/styles/_formatting.less @@ -156,6 +156,11 @@ float: left; } +.jobValues { + float: left; + width: 30%; +} + // CHROMELESS STUFF .fancy { diff --git a/nano/templates/identification_computer.tmpl b/nano/templates/identification_computer.tmpl index da24f3c0e77..d7696b8630e 100644 --- a/nano/templates/identification_computer.tmpl +++ b/nano/templates/identification_computer.tmpl @@ -41,6 +41,7 @@ {{:value.title}}: {{:value.current_positions}}/{{:value.total_positions}} {{:helper.link('-', null, {'choice' : 'make_job_unavailable', 'job' : value.title}, value.can_close == 1 && data.authenticated ? null : 'disabled')}} {{:helper.link('+', null, {'choice' : 'make_job_available', 'job' : value.title}, value.can_open == 1 && data.authenticated ? null : 'disabled')}} + {{:helper.link('*', null, {'choice' : 'prioritize_job', 'job' : value.title}, value.can_prioritize > 0 && data.authenticated ? null : 'disabled')}} {{if value.can_prioritize == 2}}Priority Job {{/if}}
    {{/for}} diff --git a/nano/templates/newscaster.tmpl b/nano/templates/newscaster.tmpl index af4edb702ad..c589bde4702 100644 --- a/nano/templates/newscaster.tmpl +++ b/nano/templates/newscaster.tmpl @@ -31,6 +31,7 @@ Property of Nanotrasen

    {{if data.wanted_issue}}
    {{:helper.link('Read Wanted issue', 'exclamation-triangle', {'view_wanted' : 1})}}
    {{/if}} +
    {{:helper.link('View available NT jobs', 'share', {'jobs' : 1})}}
    {{:helper.link('Create feed channel', 'plus', {'create_channel' : 1})}}
    {{:helper.link('View feed channels', 'arrow-right', {'view' : 1})}}
    {{:helper.link('Submit new feed story', 'share', {'create_feed_story' : 1})}}
    @@ -297,5 +298,22 @@ Property of Nanotrasen

    {{:helper.link('Back', 'arrow-left', {'setScreen' : 0})}}
    + {{else data.screen == 12}} +

    CAREERS AT NANOTRASEN

    + Work for a better future.
    +
    + {{for data.jobs}} +
    + {{:value.title}}
    +
    + {{empty}} + No available jobs... + {{/for}} + +
    +
    +
    {{:helper.link('Refresh', 'refresh', {'refresh' : 0})}}
    +
    {{:helper.link('Back', 'arrow-left', {'setScreen' : 1})}}
    +
    {{/if}} {{/if}} \ No newline at end of file diff --git a/nano/templates/ntnet_downloader.tmpl b/nano/templates/ntnet_downloader.tmpl index a64ae3452b2..35790bb3c7f 100644 --- a/nano/templates/ntnet_downloader.tmpl +++ b/nano/templates/ntnet_downloader.tmpl @@ -9,7 +9,7 @@
    Reset Program
    {{:helper.link('RESET', 'times', {'action' : 'PRG_reseterror'})}}
    -{{else}} +{{else}} {{if data.downloadname}}

    Download Running

    @@ -75,7 +75,7 @@ {{if data.hackedavailable}}

    UNKNOWN software repository

    - Please note that NanoTrasen does not recommend download of software from non-official servers. + Please note that Nanotrasen does not recommend download of software from non-official servers. {{for data.hacked_programs}}
    @@ -99,4 +99,4 @@ {{/if}} {{/if}} {{/if}} -
    NTOS v2.0.4b Copyright NanoTrasen 2557 - 2559 \ No newline at end of file +
    NTOS v2.0.4b Copyright Nanotrasen 2557 - 2559 diff --git a/nano/templates/rpd.tmpl b/nano/templates/rpd.tmpl new file mode 100644 index 00000000000..bd92b91c979 --- /dev/null +++ b/nano/templates/rpd.tmpl @@ -0,0 +1,112 @@ + +

    Mode:

    +
    + {{for data.mainmenu}} + {{:helper.link(String(value.category), String(value.icon), {"mode": Number(value.mode)}, data.mode == Number(value.mode) ? "linkOn" : null)}} + {{/for}} +
    +{{if data.mode == 1}} +

    Pipe type:

    +
    + {{for data.pipemenu}} + {{:helper.link(String(value.pipecategory), null, {"pipetype": Number(value.pipemode)}, data.pipetype == Number(value.pipemode) ? "linkOn" : null)}} + {{/for}} +
    +

    Available pipes:

    +
    + {{for data.pipelist}} + {{if value.category == data.pipetype}} +
    {{:helper.link(String(value.pipename), "arrow-right", {"whatpipe": Number(value.id)}, data.whatpipe == Number(value.id) ? "linkOn" : null)}}
    + {{/if}} + {{/for}} +
    + {{for data.pipelist}} +
    + {{if value.id == data.whatpipe && value.orientations != 1}} +
    + {{:helper.link("Orient automatically", null, {"iconrotation": 0}, data.iconrotation == 0 ? "linkOn" : null)}} +
    + {{/if}} + {{if value.id == data.whatpipe && value.orientations != 1 && value.bendy != 1}} +
    + {{:helper.link("", "arrow-right", {"iconrotation": 1}, data.iconrotation == 1 ? "linkOn" : null)}} + +
    +
    + {{:helper.link("", "arrow-right", {"iconrotation": 4}, data.iconrotation == 4 ? "linkOn" : null)}} + +
    + {{/if}} + {{if value.id == data.whatpipe && value.orientations == 4 && value.bendy != 1}} +
    + {{:helper.link("", "arrow-right", {"iconrotation": 2}, data.iconrotation == 2 ? "linkOn" : null)}} + +
    +
    + {{:helper.link("", "arrow-right", {"iconrotation": 8}, data.iconrotation == 8 ? "linkOn" : null)}} + +
    + {{/if}} + {{if value.id == data.whatpipe && value.bendy == 1}} +
    + {{:helper.link("", "arrow-right", {"iconrotation": 1}, data.iconrotation == 1 ? "linkOn" : null)}} + +
    +
    + {{:helper.link("", "arrow-right", {"iconrotation": 4}, data.iconrotation == 4 ? "linkOn" : null)}} + +
    +
    + {{:helper.link("", "arrow-right", {"iconrotation": 2}, data.iconrotation == 2 ? "linkOn" : null)}} + +
    +
    + {{:helper.link("", "arrow-right", {"iconrotation": 8}, data.iconrotation == 8 ? "linkOn" : null)}} + +
    + {{/if}} +
    + {{/for}} +{{else data.mode == 2}} +

    Available pipes:

    +
    + {{for data.dpipelist}} +
    {{:helper.link(String(value.pipename), "arrow-right", {"whatdpipe": Number(value.id)}, data.whatdpipe == Number(value.id) ? "linkOn" : null)}}
    + {{/for}} +
    + {{for data.dpipelist}} +
    + {{if value.id == data.whatdpipe && value.orientations != 1}} +
    + {{:helper.link("Orient automatically", null, {"iconrotation": 0}, data.iconrotation == 0 ? "linkOn" : null)}} +
    +
    + {{:helper.link("", "arrow-right", {"iconrotation": 1}, data.iconrotation == 1 ? "linkOn" : null)}} + +
    +
    + {{:helper.link("", "arrow-right", {"iconrotation": 4}, data.iconrotation == 4 ? "linkOn" : null)}} + +
    + {{/if}} + {{if value.id == data.whatdpipe && value.orientations == 4}} +
    + {{:helper.link("", "arrow-right", {"iconrotation": 2}, data.iconrotation == 2 ? "linkOn" : null)}} + +
    +
    + {{:helper.link("", "arrow-right", {"iconrotation": 8}, data.iconrotation == 8 ? "linkOn" : null)}} + +
    + {{/if}} +
    + {{/for}} +{{else data.mode == 3}} +

    Device ready to rotate loose pipes...

    +{{else data.mode == 4}} +

    Device ready to flip loose pipes...

    +{{else data.mode == 5}} +

    Device ready to eat loose pipes...

    +{{/if}} diff --git a/paradise.dme b/paradise.dme index 71edb0e003d..0775e9b2577 100644 --- a/paradise.dme +++ b/paradise.dme @@ -218,6 +218,7 @@ #include "code\datums\recipe.dm" #include "code\datums\ruins.dm" #include "code\datums\shuttles.dm" +#include "code\datums\soullink.dm" #include "code\datums\spell.dm" #include "code\datums\statclick.dm" #include "code\datums\supplypacks.dm" @@ -822,6 +823,7 @@ #include "code\game\objects\items\weapons\powerfist.dm" #include "code\game\objects\items\weapons\RCD.dm" #include "code\game\objects\items\weapons\RCL.dm" +#include "code\game\objects\items\weapons\rpd.dm" #include "code\game\objects\items\weapons\RSF.dm" #include "code\game\objects\items\weapons\scissors.dm" #include "code\game\objects\items\weapons\scrolls.dm" @@ -1046,6 +1048,7 @@ #include "code\modules\admin\verbs\dice.dm" #include "code\modules\admin\verbs\freeze.dm" #include "code\modules\admin\verbs\getlogs.dm" +#include "code\modules\admin\verbs\gimmick_team.dm" #include "code\modules\admin\verbs\honksquad.dm" #include "code\modules\admin\verbs\infiltratorteam_syndicate.dm" #include "code\modules\admin\verbs\map_template_loadverb.dm" @@ -2136,6 +2139,7 @@ #include "code\modules\surgery\generic.dm" #include "code\modules\surgery\helpers.dm" #include "code\modules\surgery\implant.dm" +#include "code\modules\surgery\limb_augmentation.dm" #include "code\modules\surgery\limb_reattach.dm" #include "code\modules\surgery\organs_internal.dm" #include "code\modules\surgery\other.dm" diff --git a/sound/goonstation/voice/growl1.ogg b/sound/goonstation/voice/growl1.ogg new file mode 100644 index 00000000000..d5152d9c057 Binary files /dev/null and b/sound/goonstation/voice/growl1.ogg differ diff --git a/sound/goonstation/voice/growl2.ogg b/sound/goonstation/voice/growl2.ogg new file mode 100644 index 00000000000..5c48053ac68 Binary files /dev/null and b/sound/goonstation/voice/growl2.ogg differ diff --git a/sound/goonstation/voice/growl3.ogg b/sound/goonstation/voice/growl3.ogg new file mode 100644 index 00000000000..bcacf2442f0 Binary files /dev/null and b/sound/goonstation/voice/growl3.ogg differ diff --git a/sound/goonstation/voice/howl.ogg b/sound/goonstation/voice/howl.ogg new file mode 100644 index 00000000000..778fd6b2483 Binary files /dev/null and b/sound/goonstation/voice/howl.ogg differ