Merge remote-tracking branch 'upstream/master' into fuck512

This commit is contained in:
Archie
2021-06-28 03:32:04 -03:00
61 changed files with 4386 additions and 3937 deletions
@@ -25,7 +25,7 @@
"aee" = (/obj/machinery/vending/engivend,/obj/effect/turf_decal/tile/yellow{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/machinery/firealarm{dir = 4; pixel_x = 28},/turf/open/floor/plasteel,/area/engine/engineering)
"aem" = (/obj/structure/chair/office/dark{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 10; name = "air supply pipe"},/turf/open/floor/plasteel,/area/engine/break_room)
"aes" = (/obj/structure/table/wood,/obj/item/flashlight/lamp/green{on = 0; pixel_x = -3; pixel_y = 8},/turf/open/floor/wood,/area/crew_quarters/heads/hos)
"aex" = (/obj/structure/lattice/catwalk,/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/turf/open/floor/plasteel/elevatorshaft,/area/layenia)
"aex" = (/obj/structure/lattice/catwalk,/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/turf/open/floor/plasteel/elevatorshaft,/area/ai_monitored/storage/satellite)
"aeD" = (/obj/structure/cable{icon_state = "0-4"},/obj/effect/turf_decal/stripes/line{dir = 1},/obj/effect/turf_decal/stripes/line,/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"aeP" = (/obj/effect/turf_decal/tile/purple{dir = 4},/obj/effect/turf_decal/tile/purple{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel/cafeteria{dir = 5},/area/science/research)
"aeR" = (/obj/machinery/light{dir = 1; pixel_y = 16},/obj/structure/railing{dir = 1},/turf/open/floor/plasteel/stairs/medium{dir = 8},/area/security/prison)
@@ -250,6 +250,7 @@
"aHS" = (/obj/effect/spawner/lootdrop/maintenance,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/open/floor/plating,/area/maintenance/fore)
"aHV" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9},/turf/open/floor/plating,/area/maintenance/fore)
"aHW" = (/obj/effect/turf_decal/stripes/line{dir = 9},/turf/open/floor/plasteel{dir = 8; icon_state = "floor_plate"},/area/engine/engine_smes)
"aIl" = (/obj/structure/flora/crystal/small/growth,/turf/open/indestructible/layenia/crystal,/area/ai_monitored/storage/satellite)
"aIp" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 6; name = "scrubbers pipe"},/turf/open/floor/plasteel,/area/crew_quarters/fitness/pool)
"aIr" = (/obj/effect/turf_decal/stripes/line{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 5; name = "air supply pipe"},/turf/open/floor/plasteel{dir = 8; icon_state = "floor_trim"},/area/ai_monitored/security/armory)
"aIB" = (/obj/machinery/chem_heater,/obj/effect/turf_decal/tile/yellow{dir = 8},/obj/effect/turf_decal/tile/yellow{dir = 1},/turf/open/floor/plasteel/white,/area/medical/chemistry)
@@ -310,7 +311,7 @@
"aQs" = (/obj/machinery/space_heater,/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/turf/open/floor/plating,/area/maintenance/fore)
"aQC" = (/obj/item/twohanded/required/kirbyplants/random,/turf/open/floor/plasteel/showroomfloor,/area/security/main)
"aQE" = (/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1{dir = 8; name = "air scrubber"},/turf/open/floor/plasteel{dir = 4; icon_state = "floor_plate"},/area/science/misc_lab)
"aQF" = (/obj/machinery/door/poddoor/incinerator_atmos_aux,/turf/open/floor/engine/vacuum,/area/maintenance/disposal/incinerator)
"aQF" = (/obj/machinery/door/poddoor/incinerator_atmos_aux,/obj/effect/turf_decal/delivery/red,/turf/open/floor/engine/vacuum,/area/maintenance/disposal/incinerator)
"aQK" = (/obj/structure/table,/obj/item/ashtray,/turf/open/floor/wood,/area/maintenance/port/aft)
"aQO" = (/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/turf/open/chasm/cloud,/area/layenia/cloudlayer)
"aRi" = (/obj/machinery/atmospherics/components/unary/portables_connector/visible,/obj/effect/turf_decal/stripes/line{dir = 4},/obj/structure/sign/poster/official/random{pixel_y = 32},/obj/structure/extinguisher_cabinet{pixel_x = 27},/obj/machinery/portable_atmospherics/pump,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/turf/open/floor/plasteel/dark,/area/science/mixing)
@@ -326,7 +327,7 @@
"aSW" = (/obj/structure/flora/junglebush/large,/turf/open/floor/plating/asteroid/layenia,/area/layenia)
"aTJ" = (/obj/structure/flora/junglebush,/obj/structure/flora/grass/jungle/b,/mob/living/simple_animal/butterfly,/obj/structure/window/reinforced{dir = 8},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/turf/open/floor/grass,/area/crew_quarters/dorms)
"aTT" = (/obj/effect/turf_decal/tile/green{dir = 4},/obj/structure/chair/office/light{dir = 4},/turf/open/floor/plasteel,/area/bridge)
"aUb" = (/obj/effect/turf_decal/bot,/obj/structure/closet/crate/engineering,/turf/open/floor/plating,/area/layenia)
"aUb" = (/obj/effect/turf_decal/bot,/obj/structure/closet/crate/engineering,/turf/open/floor/plating,/area/ai_monitored/storage/satellite)
"aUc" = (/obj/machinery/door/firedoor/heavy,/obj/machinery/door/poddoor/preopen{id = "Biohazard"; name = "biohazard containment door"},/obj/effect/turf_decal/bot,/obj/effect/turf_decal/delivery,/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/structure/disposalpipe/segment,/turf/open/floor/plasteel/dark,/area/hallway/primary/starboard)
"aUh" = (/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "drain"; name = "drain"},/obj/effect/decal/cleanable/cobweb,/turf/open/floor/plasteel,/area/medical/morgue)
"aUs" = (/obj/structure/cable/yellow{icon_state = "4-8"},/obj/effect/turf_decal/stripes/line{dir = 8},/turf/open/floor/plasteel/dark,/area/engine/engineering/reactor_control)
@@ -376,7 +377,7 @@
"baB" = (/obj/machinery/space_heater,/turf/open/floor/plating,/area/maintenance/port/aft)
"baL" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel{dir = 1; icon_state = "floor_plate"},/area/science/misc_lab)
"baY" = (/obj/structure/barricade/wooden,/turf/open/floor/plating,/area/maintenance/fore)
"bbg" = (/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/engine_waste{dir = 8},/turf/open/floor/plating{icon_state = "panelscorched"},/area/layenia)
"bbg" = (/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/engine_waste{dir = 8},/turf/open/floor/engine/vacuum,/area/layenia)
"bbj" = (/obj/effect/turf_decal/stripes/line{dir = 1},/turf/open/indestructible/concrete,/area/layenia/cloudlayer)
"bbk" = (/obj/structure/table/glass,/obj/item/stock_parts/manipulator,/obj/item/stock_parts/capacitor,/obj/item/stock_parts/capacitor,/obj/item/stock_parts/manipulator,/obj/item/stock_parts/micro_laser,/obj/item/stock_parts/micro_laser,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/obj/item/stack/cable_coil,/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/turf/open/floor/plasteel/white,/area/science/lab)
"bbw" = (/obj/effect/turf_decal/stripes/line{dir = 1},/obj/docking_port/stationary/random{id = "pod_lavaland3"; name = "lavaland"},/turf/open/indestructible/concrete,/area/layenia/cloudlayer)
@@ -579,7 +580,7 @@
"bBp" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 2},/obj/machinery/airalarm{dir = 4; pixel_x = -23},/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 6; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 6; name = "scrubbers pipe"},/turf/open/floor/plasteel/dark,/area/security/execution/transfer)
"bBL" = (/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 6; name = "scrubbers pipe"},/turf/open/floor/plasteel{dir = 4; icon_state = "floor_plate"},/area/hallway/primary/port)
"bBN" = (/obj/machinery/door/airlock/security/glass{dir = 8; name = "Death Row Cell"; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/turf/open/floor/plasteel,/area/security/execution/transfer)
"bBT" = (/turf/open/floor/plating{icon_state = "panelscorched"},/area/layenia)
"bBT" = (/turf/open/floor/engine/vacuum,/area/layenia)
"bBU" = (/obj/effect/turf_decal/loading_area{dir = 10; icon_state = "steel_panel"; name = "steel pannel"},/obj/effect/turf_decal/tile/blue{dir = 4},/obj/effect/turf_decal/tile/blue{dir = 1},/turf/open/floor/plasteel/white,/area/medical/sleeper)
"bBZ" = (/obj/effect/turf_decal/tile/yellow{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/structure/cable{icon_state = "1-2"},/obj/machinery/light{dir = 8; pixel_x = -7; pixel_y = 0},/turf/open/floor/plasteel/dark/corner{dir = 1},/area/engine/atmos)
"bCd" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer3{dir = 4; name = "air supply pipe"},/obj/structure/cable{icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/open/floor/plasteel{dir = 1; icon_plating = "floor"; icon_state = "floor_whole"},/area/crew_quarters/locker)
@@ -587,7 +588,7 @@
"bCf" = (/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/incinerator_input{dir = 8},/turf/open/floor/engine,/area/maintenance/disposal/incinerator)
"bCm" = (/obj/structure/table/reinforced,/obj/effect/turf_decal/tile/red{dir = 8},/obj/effect/turf_decal/tile/red,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 1},/turf/open/floor/plasteel/dark/side{dir = 1},/area/security/brig)
"bCt" = (/obj/structure/disposalpipe/segment,/turf/closed/wall,/area/medical/sleeper)
"bCw" = (/obj/effect/turf_decal/stripes/line,/obj/effect/turf_decal/stripes/line{dir = 1},/obj/structure/cable{icon_state = "4-8"},/obj/machinery/camera{c_tag = "MiniSat Walkway 2"; network = list("minisat"); start_active = 1},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"bCw" = (/obj/effect/turf_decal/stripes/line,/obj/effect/turf_decal/stripes/line{dir = 1},/obj/structure/cable{icon_state = "4-8"},/obj/machinery/camera{c_tag = "MiniSat Walkway 2"; network = list("minisat"); start_active = 1},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/ai_monitored/storage/satellite)
"bCK" = (/obj/structure/sign/warning/fire,/turf/closed/wall/r_wall,/area/maintenance/disposal/incinerator)
"bDd" = (/obj/effect/turf_decal/stripes/line{dir = 8},/obj/effect/turf_decal/stripes/line{dir = 4},/obj/effect/landmark/carpspawn,/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"bDe" = (/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 10; name = "air supply pipe"},/turf/open/floor/plasteel/dark,/area/security/execution/transfer)
@@ -756,7 +757,7 @@
"bZS" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/structure/cable{icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/open/floor/plasteel/white,/area/medical/medbay/central)
"bZY" = (/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "drain"; name = "drain"},/turf/open/floor/carpet/red,/area/crew_quarters/heads/hos)
"cae" = (/obj/effect/turf_decal/tile/red,/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/stripes/corner,/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/turf/open/floor/plasteel/dark/side{dir = 8},/area/security/main)
"caH" = (/obj/structure/railing{dir = 4},/obj/structure/railing{dir = 1},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"caH" = (/obj/structure/railing{dir = 4},/obj/structure/railing{dir = 1},/turf/open/floor/engine/vacuum,/area/layenia)
"caK" = (/obj/effect/turf_decal/stripes/line{dir = 1},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"caX" = (/obj/structure/table,/obj/item/folder/white{pixel_x = -4; pixel_y = 3},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel/white,/area/medical/virology)
"cbd" = (/obj/machinery/door/airlock{name = "Law Office"; req_access_txt = "38"},/turf/open/floor/plasteel,/area/lawoffice)
@@ -1124,7 +1125,7 @@
"ddL" = (/obj/effect/turf_decal/loading_area{icon_state = "drain"; name = "drain"},/obj/structure/sign/warning/nosmoking{pixel_y = -32},/turf/open/floor/plasteel{icon_state = "floor_plate"},/area/crew_quarters/fitness)
"ddP" = (/obj/structure/table/wood,/obj/structure/window/reinforced{dir = 8},/obj/item/flashlight/lamp/green{pixel_y = 3},/obj/structure/window/reinforced,/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/obj/effect/turf_decal/loading_area{icon_state = "drain"; name = "drain"},/obj/item/toy/figure/captain{pixel_x = 10},/turf/open/floor/carpet/royalblue,/area/crew_quarters/heads/captain)
"ddQ" = (/obj/structure/chair/sofa/left{desc = "More inviting than the average couch."; dir = 8; name = "comfy couch"},/turf/open/floor/wood,/area/maintenance/starboard/aft)
"deG" = (/obj/machinery/door/poddoor/incinerator_atmos_main{dir = 8},/turf/open/floor/engine/vacuum,/area/maintenance/disposal/incinerator)
"deG" = (/obj/machinery/door/poddoor/incinerator_atmos_main{dir = 8},/obj/effect/turf_decal/delivery/red,/turf/open/floor/engine/vacuum,/area/maintenance/disposal/incinerator)
"deU" = (/obj/structure/table/reinforced,/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/stripes/line{dir = 8},/obj/machinery/recharger,/turf/open/floor/plasteel/dark,/area/security/range)
"deX" = (/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral,/obj/structure/chair{dir = 8},/obj/effect/turf_decal/stripes/corner{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 9; name = "air supply pipe"},/turf/open/floor/plasteel/dark,/area/security/range)
"dfd" = (/obj/structure/filingcabinet/employment,/turf/open/floor/wood,/area/lawoffice)
@@ -1198,7 +1199,7 @@
"dnx" = (/obj/effect/turf_decal/tile/blue{dir = 1},/obj/effect/turf_decal/tile/blue{dir = 4},/obj/machinery/firealarm{pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel/white,/area/medical/sleeper)
"dnK" = (/obj/structure/flora/crystal/small/pile{icon_state = "crystals4"},/turf/open/floor/plating/asteroid/layenia,/area/layenia/cloudlayer)
"dnT" = (/obj/structure/table,/obj/structure/bedsheetbin,/obj/effect/turf_decal/tile/blue{dir = 4},/obj/effect/turf_decal/tile/blue{dir = 8},/turf/open/floor/plasteel/cafeteria,/area/security/prison)
"dnV" = (/obj/effect/turf_decal/bot,/obj/structure/closet/crate,/turf/open/floor/plating,/area/layenia)
"dnV" = (/obj/effect/turf_decal/bot,/obj/structure/closet/crate,/turf/open/floor/plating,/area/ai_monitored/storage/satellite)
"dnX" = (/obj/machinery/atmospherics/pipe/simple/general/visible,/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel{icon_state = "floor_plate"},/area/science/xenobiology)
"dob" = (/obj/structure/chair/sofa{dir = 1},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/turf/open/floor/carpet/black,/area/crew_quarters/bar)
"doc" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/turf/open/floor/plasteel/dark,/area/ai_monitored/turret_protected/ai)
@@ -1482,7 +1483,7 @@
"eeI" = (/obj/machinery/atmospherics/components/binary/pump/on{dir = 1; name = "N2 Outlet Pump"},/obj/effect/turf_decal/tile/red,/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/tile/red{dir = 8},/turf/open/floor/plasteel,/area/engine/atmos)
"eeT" = (/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/structure/cable{icon_state = "0-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/power/apc/highcap/five_k{areastring = "/area/ai_monitored/security/armory"; name = "Armory APC"; pixel_x = 1; pixel_y = -24},/turf/open/floor/plasteel/dark,/area/ai_monitored/security/armory)
"eeX" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 5; name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 5; name = "air supply pipe"},/obj/structure/cable{icon_state = "1-4"},/turf/open/floor/plating,/area/maintenance/aft)
"efe" = (/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel/stairs/medium{dir = 1},/area/layenia)
"efe" = (/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel/stairs/medium{dir = 1},/area/ai_monitored/storage/satellite)
"efj" = (/obj/effect/turf_decal/stripes/line{dir = 4},/obj/structure/cable{icon_state = "2-8"},/turf/open/floor/plasteel{dir = 8; icon_state = "floor_trim"},/area/ai_monitored/security/armory)
"efE" = (/obj/structure/cable/yellow{icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{dir = 4},/turf/open/floor/plasteel,/area/engine/engineering)
"efO" = (/obj/structure/fence,/turf/open/floor/grass,/area/layenia)
@@ -1925,6 +1926,7 @@
"fsx" = (/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/open/floor/plasteel{dir = 4; icon_state = "floor_trim"},/area/security/processing)
"fsC" = (/obj/machinery/door/airlock/research/glass{dir = 1; name = "Test Chamber"; req_access_txt = "47"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/turf/open/floor/plasteel/dark,/area/science/misc_lab)
"fsY" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/turf/open/floor/plasteel/dark,/area/security/courtroom)
"ftj" = (/obj/effect/turf_decal/stripes/line{dir = 8},/obj/effect/turf_decal/stripes/line{dir = 4},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/ai_monitored/storage/satellite)
"ftq" = (/obj/effect/turf_decal/tile/red{dir = 8},/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red,/obj/structure/table,/obj/item/restraints/handcuffs,/obj/item/assembly/timer,/turf/open/floor/plasteel,/area/security/main)
"ftt" = (/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3{dir = 1; name = "air vent"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel/dark,/area/science/storage)
"ftw" = (/obj/effect/turf_decal/loading_area{dir = 10; icon_state = "steel_panel"; name = "steel pannel"},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/dark,/area/crew_quarters/bar)
@@ -2366,7 +2368,7 @@
"gIz" = (/obj/structure/cable/white{icon_state = "2-4"},/turf/closed/wall/r_wall,/area/engine/engineering/reactor_control)
"gID" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/turf/open/floor/plasteel{dir = 4; icon_state = "floor_plate"},/area/engine/atmos)
"gIO" = (/obj/effect/turf_decal/stripes/line{dir = 4},/obj/effect/turf_decal/stripes/line{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/structure/cable{icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/cyan/hidden{dir = 1; name = "air supply pipe"},/turf/open/floor/plating/airless,/area/layenia/cloudlayer)
"gIX" = (/obj/structure/plasticflaps/opaque,/obj/effect/turf_decal/bot,/turf/open/floor/plating,/area/crew_quarters/bar)
"gIX" = (/obj/structure/plasticflaps/opaque,/obj/effect/turf_decal/bot,/turf/open/floor/plating,/area/maintenance/fore/secondary)
"gJv" = (/obj/machinery/vending/cola/random,/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel/dark,/area/bridge)
"gJw" = (/obj/structure/railing{dir = 8},/obj/structure/lattice/catwalk,/turf/open/floor/plating/asteroid/layenia,/area/layenia)
"gJx" = (/obj/effect/turf_decal/stripes/line{dir = 10},/obj/effect/turf_decal/stripes/corner{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 5; name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 5; name = "air supply pipe"},/obj/structure/cable{icon_state = "1-4"},/obj/structure/disposalpipe/segment{dir = 5},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia/cloudlayer)
@@ -2523,7 +2525,7 @@
"hhR" = (/obj/machinery/power/smes{charge = 5e+006},/obj/structure/cable/yellow{icon_state = "0-8"},/obj/structure/cable/yellow{icon_state = "0-4"},/obj/machinery/light{dir = 1; pixel_y = 16},/turf/open/floor/plasteel/dark,/area/ai_monitored/turret_protected/ai)
"hib" = (/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3{name = "air vent"},/turf/open/floor/plasteel/dark,/area/security/execution/transfer)
"hif" = (/obj/effect/turf_decal/stripes/line{dir = 1},/turf/open/floor/plasteel,/area/construction/mining/aux_base)
"hik" = (/obj/machinery/status_display/ai{pixel_x = 32},/obj/structure/cable/yellow{icon_state = "2-8"},/turf/open/floor/circuit,/area/ai_monitored/turret_protected/ai)
"hik" = (/obj/machinery/status_display/ai{pixel_x = 32},/obj/structure/cable/yellow{icon_state = "2-8"},/obj/machinery/airalarm{pixel_y = 23},/turf/open/floor/circuit,/area/ai_monitored/turret_protected/ai)
"hil" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/effect/turf_decal/tile/blue{dir = 1},/obj/effect/turf_decal/stripes/corner{dir = 1},/turf/open/floor/plasteel/dark,/area/ai_monitored/turret_protected/ai)
"hiB" = (/obj/machinery/door/airlock/security{dir = 1; id_tag = "laborexit"; name = "Labor Shuttle"; req_access_txt = "63"},/obj/machinery/door/firedoor,/obj/structure/cable{icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/structure/disposalpipe/segment,/turf/open/floor/plasteel,/area/security/processing)
"hiI" = (/obj/structure/closet/firecloset,/obj/effect/turf_decal/stripes/line{dir = 8},/obj/machinery/light{dir = 8; pixel_x = -7; pixel_y = 0},/turf/open/floor/plasteel/white/side{dir = 4},/area/science/research)
@@ -3015,7 +3017,7 @@
"iyh" = (/obj/structure/window/reinforced/fulltile,/obj/structure/transit_tube,/turf/open/floor/plating,/area/ai_monitored/turret_protected/aisat_interior)
"iyi" = (/obj/effect/turf_decal/stripes/line{dir = 1},/obj/structure/sink{pixel_y = 30},/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1{name = "air scrubber"},/turf/open/floor/plasteel{icon_state = "floor_trim"},/area/science/xenobiology)
"iyk" = (/obj/machinery/light{dir = 8; pixel_x = -7; pixel_y = 0},/obj/structure/lattice/catwalk,/obj/structure/railing{dir = 4},/obj/structure/railing{dir = 1},/turf/open/chasm/cloud,/area/layenia/cloudlayer)
"iym" = (/obj/machinery/atmospherics/pipe/layer_manifold{dir = 4},/obj/machinery/door/poddoor{dir = 4; id = "TEG_Vent"},/turf/open/floor/engine/vacuum,/area/engine/engineering)
"iym" = (/obj/machinery/atmospherics/pipe/layer_manifold{dir = 4},/obj/machinery/door/poddoor{dir = 4; id = "TEG_Vent"},/obj/effect/turf_decal/delivery/red,/turf/open/floor/engine/vacuum,/area/engine/engineering)
"iyr" = (/obj/item/radio/intercom{freerange = 1; frequency = 1447; name = "Private Channel"; pixel_x = 27; pixel_y = -9},/obj/machinery/turretid{name = "AI Chamber turret control"; pixel_x = 18; pixel_y = -24},/obj/machinery/camera/motion{c_tag = "MiniSat AI Chamber North"; dir = 1; network = list("aicore")},/turf/open/floor/circuit,/area/ai_monitored/turret_protected/ai)
"iyw" = (/obj/structure/table,/obj/item/storage/box/cups{pixel_y = 10},/obj/machinery/airalarm{dir = 1; pixel_y = -22},/turf/open/floor/plasteel/dark,/area/security/courtroom)
"iyy" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/light{pixel_y = -1},/turf/open/floor/plasteel/dark/corner{dir = 4},/area/engine/break_room)
@@ -3300,7 +3302,7 @@
"jjH" = (/obj/structure/chair/office/light,/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/turf/open/floor/plasteel/grimy,/area/chapel/office)
"jjI" = (/obj/item/coin/gold,/obj/effect/decal/cleanable/cobweb,/turf/open/floor/plating,/area/maintenance/port/aft)
"jjJ" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "4-8"},/obj/structure/disposalpipe/junction/flip{dir = 4},/turf/open/floor/plating,/area/maintenance/port)
"jjN" = (/obj/structure/lattice/catwalk,/obj/structure/closet/crate,/turf/open/floor/plasteel/elevatorshaft,/area/layenia)
"jjN" = (/obj/structure/lattice/catwalk,/obj/structure/closet/crate,/turf/open/floor/plasteel/elevatorshaft,/area/ai_monitored/storage/satellite)
"jjR" = (/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{dir = 1},/turf/open/floor/engine/vacuum,/area/science/mixing)
"jjT" = (/turf/open/floor/plasteel{dir = 1; icon_state = "floor_plate"},/area/security/main)
"jjV" = (/obj/machinery/holopad,/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/effect/turf_decal/box,/turf/open/floor/plasteel/grimy,/area/chapel/office)
@@ -3514,7 +3516,7 @@
"jTq" = (/turf/open/floor/plasteel{dir = 8; icon_state = "floor_plate"},/area/science/xenobiology)
"jTt" = (/obj/effect/spawner/structure/window/reinforced,/obj/machinery/door/poddoor/shutters/preopen{id = "robotics2"; name = "robotics lab shutters"},/turf/open/floor/plating,/area/science/robotics/lab)
"jTu" = (/obj/structure/chair/foldingchair{dir = 4},/turf/open/indestructible/concrete,/area/layenia)
"jTB" = (/obj/structure/lattice/catwalk,/turf/open/floor/plasteel/elevatorshaft,/area/layenia)
"jTB" = (/obj/structure/lattice/catwalk,/turf/open/floor/plasteel/elevatorshaft,/area/ai_monitored/storage/satellite)
"jTE" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/structure/cable{icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/open/floor/plasteel{dir = 4; icon_state = "floor_plate"},/area/hallway/secondary/entry)
"jTK" = (/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/tile/red,/obj/structure/window/reinforced{dir = 4},/obj/structure/table/glass,/obj/item/storage/backpack/duffelbag/sec/surgery{pixel_y = 5},/turf/open/floor/plasteel/white,/area/security/execution/transfer)
"jTP" = (/obj/effect/turf_decal/stripes/line{dir = 8},/turf/open/floor/plasteel/white,/area/science/lab)
@@ -3905,7 +3907,7 @@
"lcH" = (/obj/structure/cable/yellow{icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/turf/open/floor/circuit,/area/ai_monitored/turret_protected/ai)
"lcK" = (/obj/machinery/door/airlock/external{name = "Engineering External Access"; req_access_txt = "10;13"},/obj/effect/mapping_helpers/airlock/cyclelink_helper,/turf/open/floor/plating,/area/maintenance/fore)
"lcQ" = (/obj/effect/spawner/lootdrop/maintenance,/obj/structure/closet,/turf/open/floor/plating,/area/maintenance/fore)
"ldJ" = (/obj/structure/lattice/catwalk,/obj/structure/reagent_dispensers/fueltank,/turf/open/floor/plasteel/elevatorshaft,/area/layenia)
"ldJ" = (/obj/structure/lattice/catwalk,/obj/structure/reagent_dispensers/fueltank,/turf/open/floor/plasteel/elevatorshaft,/area/ai_monitored/storage/satellite)
"ldO" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/turf/open/floor/plasteel/white,/area/medical/sleeper)
"ldX" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/atmos/glass{dir = 8; name = "Turbine Hallway Access"; req_access_txt = "32"},/obj/effect/turf_decal/delivery,/turf/open/floor/plasteel/dark,/area/engine/atmos)
"lej" = (/obj/machinery/atmospherics/components/binary/pump/on{dir = 8; name = "Mix to Filter"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/turf/open/floor/plasteel,/area/engine/atmos)
@@ -3923,7 +3925,7 @@
"lfB" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 6; name = "scrubbers pipe"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel/white,/area/medical/sleeper)
"lfC" = (/obj/effect/turf_decal/stripes/line{dir = 8},/obj/effect/turf_decal/stripes/corner{dir = 8},/obj/effect/turf_decal/stripes/corner{dir = 2},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"lfD" = (/obj/item/stack/cable_coil/random,/obj/structure/lattice/catwalk,/turf/open/floor/plating/asteroid/layenia,/area/layenia)
"lfO" = (/obj/structure/lattice/catwalk,/obj/structure/reagent_dispensers/watertank,/turf/open/floor/plating/asteroid/layenia,/area/layenia)
"lfO" = (/obj/structure/lattice/catwalk,/obj/structure/reagent_dispensers/watertank,/turf/open/floor/plating/asteroid/layenia,/area/ai_monitored/storage/satellite)
"lfS" = (/obj/effect/spawner/structure/window/reinforced,/obj/machinery/door/poddoor/preopen{id = "hos"},/obj/structure/cable{icon_state = "0-4"},/turf/open/floor/plating,/area/crew_quarters/heads/hos)
"lfX" = (/obj/structure/closet/emcloset,/turf/open/indestructible/concrete,/area/layenia)
"lgd" = (/obj/machinery/atmospherics/pipe/simple/cyan/hidden{dir = 4; name = "air supply pipe"},/obj/effect/spawner/structure/window/plasma/reinforced,/turf/open/floor/plating,/area/engine/engineering)
@@ -4078,7 +4080,7 @@
"lDF" = (/obj/effect/spawner/structure/window/reinforced,/obj/structure/cable,/turf/open/floor/plating,/area/science/xenobiology)
"lEc" = (/obj/machinery/mineral/stacking_machine{input_dir = 1; stack_amt = 10},/turf/open/floor/plating,/area/maintenance/disposal)
"lEd" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel/white,/area/medical/sleeper)
"lEt" = (/obj/structure/cable{icon_state = "1-4"},/obj/effect/turf_decal/stripes/line{dir = 10},/obj/effect/turf_decal/stripes/corner{dir = 8},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"lEt" = (/obj/structure/cable{icon_state = "1-4"},/obj/effect/turf_decal/stripes/line{dir = 10},/obj/effect/turf_decal/stripes/corner{dir = 8},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/ai_monitored/storage/satellite)
"lEv" = (/turf/open/floor/plasteel,/area/science/robotics/lab)
"lED" = (/obj/effect/spawner/structure/window,/obj/machinery/door/firedoor,/turf/open/floor/plating,/area/hydroponics)
"lEV" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible/layer1{dir = 8; name = "visible"},/obj/machinery/atmospherics/pipe/simple/green/visible/layer3{dir = 8; name = "visible"},/obj/effect/turf_decal/stripes/end{dir = 8},/obj/structure/railing{dir = 8},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
@@ -4117,7 +4119,7 @@
"lKe" = (/obj/effect/spawner/structure/window/reinforced,/obj/effect/baseturf_helper/asteroid/layenia,/turf/open/floor/plating,/area/hallway/secondary/exit)
"lKn" = (/obj/effect/turf_decal/tile/red,/obj/effect/baseturf_helper/asteroid/layenia,/turf/open/floor/plasteel{dir = 1; icon_state = "floor_plate"},/area/hallway/primary/fore)
"lKO" = (/obj/structure/reagent_dispensers/water_cooler,/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3{name = "air vent"},/turf/open/floor/plasteel/white/side,/area/medical/psych)
"lLh" = (/obj/effect/turf_decal/stripes/line,/obj/effect/turf_decal/stripes/line{dir = 1},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"lLh" = (/obj/effect/turf_decal/stripes/line,/obj/effect/turf_decal/stripes/line{dir = 1},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/ai_monitored/storage/satellite)
"lLo" = (/obj/machinery/atmospherics/pipe/simple/yellow/visible,/turf/open/floor/plasteel{dir = 1; icon_state = "floor_trim"},/area/engine/atmos)
"lLv" = (/obj/machinery/air_sensor/atmos/nitrous_tank,/turf/open/floor/engine/n2o,/area/engine/atmos)
"lLD" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/turf/open/floor/plasteel/chapel{dir = 4},/area/chapel/main)
@@ -4357,7 +4359,7 @@
"mwe" = (/obj/effect/turf_decal/loading_area{dir = 4},/obj/machinery/light{pixel_y = -1},/turf/open/floor/plasteel/dark,/area/quartermaster/storage)
"mwj" = (/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/tile/red,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1,/turf/open/floor/plasteel/dark,/area/security/checkpoint/supply)
"mwm" = (/obj/machinery/atmospherics/pipe/manifold/general/visible{dir = 8},/obj/effect/turf_decal/stripes/line{dir = 8},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/landmark/start/scientist,/turf/open/floor/plasteel/dark,/area/science/mixing)
"mwz" = (/obj/machinery/door/airlock/maintenance{name = "Bar Maintenance"; req_access_txt = "25"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/structure/cable{icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/open/floor/plasteel/dark,/area/crew_quarters/bar)
"mwz" = (/obj/machinery/door/airlock/maintenance{name = "Bar Maintenance"; req_access_txt = "25"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/structure/cable{icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/open/floor/plasteel/dark,/area/maintenance/fore/secondary)
"mwC" = (/obj/effect/turf_decal/tile/blue{dir = 8},/obj/effect/turf_decal/tile/blue{dir = 1},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/structure/disposalpipe/segment{dir = 4},/obj/item/radio/intercom{frequency = 1485; name = "Station Intercom (Medbay)"; pixel_x = -30},/turf/open/floor/plasteel/white,/area/medical/sleeper)
"mwT" = (/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral,/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1{name = "air scrubber"},/turf/open/floor/plasteel/dark/side,/area/security/main)
"mwV" = (/turf/open/floor/plasteel/stairs/medium,/area/hallway/primary/port)
@@ -4406,7 +4408,7 @@
"mDK" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 10; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 10; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "2-8"},/obj/structure/cable{icon_state = "0-8"},/obj/structure/disposalpipe/segment{dir = 10},/turf/open/floor/plating,/area/maintenance/aft)
"mDL" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 10; name = "air supply pipe"},/turf/open/floor/carpet/red,/area/security/checkpoint/auxiliary{name = "Security Checkpoint"})
"mDS" = (/obj/machinery/light{dir = 1; pixel_y = 19},/turf/open/floor/plating/asteroid/layenia,/area/layenia)
"mEn" = (/obj/structure/railing{dir = 4},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"mEn" = (/obj/structure/railing{dir = 4},/turf/open/floor/engine/vacuum,/area/layenia)
"mEt" = (/obj/structure/table,/obj/item/aiModule/supplied/oxygen,/obj/item/aiModule/zeroth/oneHuman,/obj/item/aiModule/reset/purge,/obj/effect/spawner/lootdrop/aimodule_harmful,/obj/item/aiModule/supplied/protectStation,/obj/machinery/flasher{id = "brigentry"; pixel_x = 28},/obj/effect/turf_decal/tile/blue,/obj/effect/turf_decal/tile/blue{dir = 4},/obj/effect/turf_decal/tile/blue{dir = 8},/obj/machinery/door/window{base_state = "right"; icon_state = "right"; name = "Core Modules"; req_access_txt = "20"},/obj/structure/window/reinforced{dir = 8},/obj/effect/turf_decal/tile/blue{dir = 1},/obj/machinery/light/small{dir = 1; pixel_y = 16},/turf/open/floor/plasteel,/area/ai_monitored/turret_protected/ai_upload)
"mEz" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/structure/cable{icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel/stairs/medium{dir = 8},/area/maintenance/starboard/aft)
"mEG" = (/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/stripes/line,/turf/open/floor/plasteel{dir = 1; icon_state = "floor_plate"},/area/storage/primary)
@@ -4502,7 +4504,7 @@
"mTg" = (/obj/structure/cable/yellow{icon_state = "1-2"},/obj/structure/chair/office/dark{dir = 1},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/grimy,/area/ai_monitored/turret_protected/aisat_interior)
"mTi" = (/obj/machinery/door/airlock/atmos/abandoned{dir = 4; name = "Atmospherics Maintenance"; req_access_txt = "12;24"},/obj/machinery/atmospherics/pipe/simple/cyan/hidden{dir = 4; name = "air supply pipe"},/turf/open/floor/plating,/area/maintenance/aft)
"mTk" = (/obj/effect/spawner/structure/window/reinforced,/obj/structure/cable{icon_state = "0-2"},/obj/structure/cable,/obj/structure/cable{icon_state = "0-4"},/turf/open/floor/plating,/area/bridge)
"mTq" = (/obj/effect/turf_decal/stripes/corner{dir = 4},/obj/structure/cable{icon_state = "1-8"},/obj/structure/cable{icon_state = "1-2"},/obj/effect/turf_decal/stripes/corner{dir = 1},/obj/effect/turf_decal/stripes/line{dir = 4},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"mTq" = (/obj/effect/turf_decal/stripes/corner{dir = 4},/obj/structure/cable{icon_state = "1-8"},/obj/structure/cable{icon_state = "1-2"},/obj/effect/turf_decal/stripes/corner{dir = 1},/obj/effect/turf_decal/stripes/line{dir = 4},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/ai_monitored/storage/satellite)
"mTs" = (/obj/structure/cable{icon_state = "2-8"},/obj/structure/cable{icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer3{dir = 4; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/effect/turf_decal/tile/green{dir = 8},/obj/effect/turf_decal/tile/green{dir = 1},/obj/effect/turf_decal/tile/green{dir = 4},/obj/effect/turf_decal/tile/green,/turf/open/floor/plasteel/dark/side{dir = 1},/area/engine/break_room)
"mTy" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 5; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 5; name = "scrubbers pipe"},/obj/structure/trash_pile,/turf/open/floor/plating,/area/maintenance/fore)
"mTD" = (/obj/machinery/shower{dir = 4; name = "emergency shower"},/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/obj/structure/chair/stool{pixel_y = 8},/turf/open/floor/plasteel/freezer,/area/crew_quarters/fitness)
@@ -5033,7 +5035,7 @@
"opn" = (/obj/structure/chair/sofa{dir = 4},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "drain"; name = "drain"},/obj/machinery/light{dir = 8; pixel_x = -7; pixel_y = 0},/turf/open/floor/carpet/black,/area/crew_quarters/bar)
"opB" = (/obj/structure/table,/obj/machinery/smartfridge/disks{pixel_y = 2},/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral,/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1{dir = 1; name = "air scrubber"},/obj/structure/disposalpipe/segment,/obj/machinery/power/apc{areastring = "/area/hydroponics"; name = "Hydroponics APC"; pixel_y = -24},/obj/structure/cable,/turf/open/floor/plasteel/dark,/area/hydroponics)
"opC" = (/obj/structure/table/wood,/obj/item/storage/pill_bottle/dice,/turf/open/floor/carpet,/area/crew_quarters/dorms)
"opN" = (/obj/structure/lattice/catwalk,/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/obj/structure/railing{dir = 1},/obj/machinery/camera{c_tag = "MiniSat Cyborg Storage Entrance"; dir = 9; network = list("minisat"); start_active = 1},/turf/open/floor/plasteel/elevatorshaft,/area/layenia)
"opN" = (/obj/structure/lattice/catwalk,/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/obj/structure/railing{dir = 1},/obj/machinery/camera{c_tag = "MiniSat Cyborg Storage Entrance"; dir = 9; network = list("minisat"); start_active = 1},/turf/open/floor/plasteel/elevatorshaft,/area/ai_monitored/storage/satellite)
"opP" = (/obj/structure/sink/kitchen{pixel_y = 28},/turf/open/floor/plasteel/cafeteria{dir = 5},/area/maintenance/port/aft)
"opW" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "4-8"},/obj/machinery/airalarm/unlocked{pixel_y = 24},/turf/open/floor/plasteel,/area/science/mixing)
"oqd" = (/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "drain"; name = "drain"},/obj/structure/chair/comfy/brown{dir = 8},/turf/open/floor/carpet,/area/crew_quarters/dorms)
@@ -5352,7 +5354,7 @@
"piv" = (/obj/machinery/door/airlock{dir = 4; id_tag = "null"; name = "Unit 1"},/turf/open/floor/plasteel/freezer,/area/crew_quarters/toilet/locker)
"piD" = (/obj/structure/table,/obj/item/storage/toolbox/electrical{pixel_x = 1; pixel_y = 5},/turf/open/floor/plating,/area/maintenance/solars/port/fore)
"piS" = (/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral,/obj/structure/chair/comfy{dir = 4},/obj/effect/turf_decal/loading_area{icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel{dir = 1; icon_state = "floor_plate"},/area/crew_quarters/fitness/pool)
"pjc" = (/obj/machinery/door/poddoor{dir = 4; id = "TEG_Vent"},/turf/open/floor/engine/vacuum,/area/engine/engineering)
"pjc" = (/obj/machinery/door/poddoor{dir = 4; id = "TEG_Vent"},/obj/effect/turf_decal/delivery/red,/turf/open/floor/engine/vacuum,/area/engine/engineering)
"pjf" = (/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/red{dir = 8},/obj/effect/turf_decal/tile/red,/obj/effect/turf_decal/tile/red{dir = 4},/obj/machinery/door/airlock/glass{dir = 4; id_tag = "checkpointinner"; name = "inner airlock"},/obj/effect/mapping_helpers/airlock/cyclelink_helper{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel,/area/hallway/primary/port)
"pjj" = (/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/obj/effect/turf_decal/tile/blue{dir = 8},/obj/effect/turf_decal/tile/neutral,/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1{dir = 8; name = "air scrubber"},/turf/open/floor/plasteel{dir = 1; icon_state = "floor_plate"},/area/hallway/primary/starboard)
"pjk" = (/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral,/obj/structure/chair/comfy{dir = 8},/obj/effect/turf_decal/loading_area{icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel{dir = 1; icon_state = "floor_plate"},/area/crew_quarters/fitness/pool)
@@ -5421,6 +5423,7 @@
"psh" = (/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o{dir = 1},/turf/open/floor/plasteel,/area/engine/atmos)
"psj" = (/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/obj/structure/chair/comfy/brown,/obj/effect/landmark/start/assistant,/turf/open/floor/carpet,/area/crew_quarters/dorms)
"pso" = (/obj/effect/turf_decal/stripes/line,/obj/structure/cable{icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/turf/open/floor/plasteel/dark,/area/hallway/secondary/exit)
"pst" = (/obj/structure/lattice/catwalk,/turf/open/floor/plating/asteroid/layenia,/area/ai_monitored/storage/satellite)
"psB" = (/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/stripes/line{dir = 1},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 6},/turf/open/floor/plasteel{icon_state = "floor_plate"},/area/storage/primary)
"psF" = (/obj/docking_port/stationary{dir = 8; dwidth = 3; height = 15; id = "arrivals_stationary"; name = "arrivals"; roundstart_template = /datum/map_template/shuttle/arrival/box; width = 7},/turf/open/indestructible/concrete,/area/layenia/cloudlayer)
"psI" = (/obj/machinery/door/airlock/external{name = "Nuclear Reactor Access"; req_access_txt = "24"},/obj/effect/mapping_helpers/airlock/cyclelink_helper,/obj/structure/cable{icon_state = "1-2"},/obj/effect/turf_decal/delivery,/turf/open/floor/plasteel/dark,/area/engine/engineering/reactor_control)
@@ -6088,7 +6091,7 @@
"red" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/structure/cable{icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel/stairs/medium{dir = 8},/area/science/research)
"rek" = (/obj/machinery/telecomms/bus/preset_two,/turf/open/floor/circuit/telecomms/mainframe,/area/tcommsat/server)
"reu" = (/obj/structure/cable/yellow,/obj/effect/turf_decal/stripes/line{dir = 6},/obj/machinery/power/apc{areastring = "/area/engine/engineering/reactor_control"; dir = 4; name = "Reactor Control Room APC"; pixel_x = 24},/turf/open/floor/plasteel/dark,/area/engine/engineering/reactor_control)
"reB" = (/obj/structure/lattice/catwalk,/obj/structure/railing{dir = 1},/turf/open/floor/plasteel/elevatorshaft,/area/layenia)
"reB" = (/obj/structure/lattice/catwalk,/obj/structure/railing{dir = 1},/turf/open/floor/plasteel/elevatorshaft,/area/ai_monitored/storage/satellite)
"reG" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 10; name = "scrubbers pipe"},/turf/open/floor/plasteel,/area/maintenance/fore)
"reT" = (/obj/machinery/telecomms/processor/preset_two,/turf/open/floor/circuit/telecomms/mainframe,/area/tcommsat/server)
"reW" = (/obj/effect/spawner/structure/window/reinforced,/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/open/floor/plating,/area/engine/break_room)
@@ -6132,7 +6135,7 @@
"rjF" = (/obj/effect/turf_decal/box,/obj/machinery/holopad,/turf/open/floor/plasteel{dir = 4; icon_plating = "floor"; icon_state = "floor_whole"},/area/quartermaster/storage)
"rjG" = (/obj/structure/cable{icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/structure/disposalpipe/segment,/turf/open/floor/plasteel/white/side{dir = 5},/area/bridge)
"rjH" = (/obj/machinery/door/airlock/maintenance{dir = 8; name = "Maintenance Access"; req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plating,/area/maintenance/starboard/central)
"rjK" = (/obj/effect/turf_decal/stripes/line,/obj/effect/turf_decal/stripes/line{dir = 1},/obj/structure/cable{icon_state = "4-8"},/obj/machinery/light{pixel_y = -1},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"rjK" = (/obj/effect/turf_decal/stripes/line,/obj/effect/turf_decal/stripes/line{dir = 1},/obj/structure/cable{icon_state = "4-8"},/obj/machinery/light{pixel_y = -1},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/ai_monitored/storage/satellite)
"rjX" = (/obj/effect/spawner/structure/window/reinforced,/turf/open/floor/plating,/area/quartermaster/qm)
"rjY" = (/obj/effect/turf_decal/tile/yellow{dir = 8},/obj/effect/turf_decal/tile/yellow{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/structure/disposalpipe/sorting/mail/flip{dir = 1; sortType = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/turf/open/floor/plasteel,/area/engine/break_room)
"rjZ" = (/obj/effect/turf_decal/tile/yellow{dir = 8},/obj/machinery/disposal/bin,/obj/structure/disposalpipe/trunk{dir = 4},/turf/open/floor/plasteel/dark/corner,/area/engine/break_room)
@@ -6828,7 +6831,7 @@
"sYQ" = (/obj/effect/turf_decal/tile/red,/obj/effect/turf_decal/tile/red{dir = 1},/obj/effect/turf_decal/tile/blue{dir = 8},/obj/effect/turf_decal/tile/blue{dir = 4},/obj/structure/bed,/obj/item/bedsheet/clown,/obj/effect/landmark/start/clown,/turf/open/floor/plasteel,/area/crew_quarters/theatre)
"sZc" = (/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3{dir = 1; name = "air vent"},/turf/open/floor/plasteel,/area/hallway/primary/fore)
"sZd" = (/obj/effect/turf_decal/stripes/line{dir = 6},/obj/effect/turf_decal/stripes/corner{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 9; name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 9; name = "air supply pipe"},/obj/structure/cable{icon_state = "1-8"},/obj/structure/disposalpipe/segment{dir = 9},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia/cloudlayer)
"sZf" = (/obj/effect/turf_decal/stripes/line{dir = 8},/obj/effect/turf_decal/stripes/line{dir = 4},/obj/structure/cable{icon_state = "1-2"},/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
"sZf" = (/obj/effect/turf_decal/stripes/line{dir = 8},/obj/effect/turf_decal/stripes/line{dir = 4},/obj/structure/cable{icon_state = "1-2"},/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/ai_monitored/storage/satellite)
"sZv" = (/turf/open/floor/plasteel/white/corner{dir = 1},/area/hallway/secondary/entry)
"sZF" = (/obj/structure/chair{dir = 4},/turf/open/floor/plasteel,/area/engine/break_room)
"sZQ" = (/obj/machinery/light{pixel_y = -1},/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1{dir = 8; name = "air scrubber"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/turf/open/floor/plasteel/white,/area/medical/virology)
@@ -7306,6 +7309,7 @@
"umu" = (/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/white,/area/medical/medbay/central)
"umv" = (/obj/structure/cable{icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/turf/open/floor/plasteel,/area/security/main)
"umx" = (/obj/structure/trash_pile,/turf/open/floor/plasteel,/area/maintenance/port/aft)
"umz" = (/obj/structure/flora/crystal/medium/growth,/turf/open/indestructible/layenia/crystal,/area/ai_monitored/storage/satellite)
"umX" = (/obj/structure/chair/sofa/left{dir = 4},/obj/structure/window{dir = 8},/turf/open/floor/wood{icon_state = "wood-broken"},/area/maintenance/starboard/aft)
"unk" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/turf/open/floor/plasteel/dark,/area/chapel/main)
"unq" = (/obj/structure/table,/obj/item/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/item/storage/box/syringes,/turf/open/floor/plasteel/dark,/area/medical/sleeper)
@@ -7373,7 +7377,7 @@
"uua" = (/obj/machinery/atmospherics/components/binary/pump/on{dir = 2},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/airlock_sensor/incinerator_toxmix{pixel_x = -24},/turf/open/floor/engine,/area/science/mixing)
"uug" = (/obj/machinery/door/poddoor/preopen{id = "primaryshut1"; name = "primary blast door"},/obj/machinery/door/firedoor,/obj/effect/turf_decal/delivery,/obj/effect/turf_decal/delivery,/obj/effect/turf_decal/loading_area{dir = 8; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel{dir = 8; icon_plating = "floor"; icon_state = "floor_whole"},/area/hallway/primary/starboard)
"uut" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/closed/wall/r_wall,/area/engine/engineering/reactor_control)
"uuU" = (/obj/structure/lattice/catwalk,/obj/structure/railing{dir = 8},/turf/open/floor/plasteel/elevatorshaft,/area/layenia)
"uuU" = (/obj/structure/lattice/catwalk,/obj/structure/railing{dir = 8},/turf/open/floor/plasteel/elevatorshaft,/area/ai_monitored/storage/satellite)
"uuV" = (/obj/machinery/door/poddoor/shutters/preopen{id = "hop"; name = "Privacy Shutters"},/obj/effect/spawner/structure/window/reinforced,/obj/structure/cable,/turf/open/floor/plating,/area/crew_quarters/heads/hop)
"uuW" = (/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 1; icon_state = "rightsecure"; name = "Head of Personnel's Desk"; req_access_txt = "57"},/obj/machinery/door/firedoor,/obj/machinery/door/window/northleft{dir = 2; icon_state = "left"; name = "Reception Window"},/obj/machinery/door/poddoor/preopen{id = "hop"; name = "privacy shutters"},/turf/open/floor/plasteel,/area/crew_quarters/heads/hop)
"uva" = (/obj/machinery/door/firedoor,/obj/effect/turf_decal/delivery,/obj/machinery/door/poddoor/preopen{dir = 8; id = "primaryshut1"; name = "primary blast door"},/obj/structure/cable{icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel,/area/bridge)
@@ -7387,6 +7391,7 @@
"uwA" = (/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "drain"; name = "drain"},/obj/structure/cable{icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/disposalpipe/segment{dir = 10},/turf/open/floor/plasteel,/area/crew_quarters/heads/captain)
"uwG" = (/obj/machinery/door/airlock{name = "Clown Room"; req_access_txt = "46"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/item/grown/bananapeel,/turf/open/floor/plating,/area/crew_quarters/theatre)
"uwH" = (/obj/machinery/light{dir = 8; pixel_x = -7; pixel_y = 0},/turf/open/floor/plating/beach/sand,/area/hallway/secondary/exit)
"uwK" = (/obj/effect/turf_decal/stripes/line{dir = 1},/obj/effect/turf_decal/stripes/line,/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/ai_monitored/storage/satellite)
"uwT" = (/obj/structure/table/glass,/obj/item/cigbutt,/obj/item/trash/plate{pixel_y = 7},/obj/effect/turf_decal/tile/blue{dir = 4},/obj/effect/turf_decal/tile/blue{dir = 8},/obj/machinery/light{dir = 8; pixel_x = -7; pixel_y = 0},/turf/open/floor/plasteel/cafeteria{dir = 5},/area/medical/medbay/central)
"uwV" = (/mob/living/simple_animal/crab/Coffee,/turf/open/floor/plating/beach/sand,/area/hallway/secondary/exit)
"uxd" = (/obj/machinery/light{dir = 1; pixel_y = 16},/obj/structure/table,/obj/item/stack/sheet/mineral/plasma{amount = 35},/obj/item/stack/sheet/mineral/plasma{pixel_y = 4},/turf/open/floor/plating,/area/ai_monitored/turret_protected/aisat/service)
@@ -7669,6 +7674,7 @@
"viI" = (/turf/open/floor/plasteel,/area/crew_quarters/heads/chief)
"viZ" = (/turf/closed/wall/r_wall,/area/security/main)
"vjc" = (/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1{dir = 4; name = "air scrubber"},/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Security Checkpoint East"; dir = 5},/turf/open/floor/plasteel,/area/hallway/primary/port)
"vjd" = (/obj/structure/flora/crystal/small/pile,/turf/open/floor/plating/asteroid/layenia,/area/ai_monitored/storage/satellite)
"vjw" = (/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3{dir = 8; name = "air vent"},/turf/open/floor/plasteel,/area/hallway/primary/fore)
"vjA" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3{dir = 1; name = "air vent"},/turf/open/floor/plasteel,/area/hallway/primary/central)
"vjC" = (/obj/structure/cable{icon_state = "2-4"},/turf/open/floor/carpet/purple,/area/crew_quarters/heads/hor)
@@ -7847,6 +7853,7 @@
"vGY" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable,/obj/effect/spawner/structure/window/reinforced,/obj/machinery/door/poddoor/preopen{dir = 8; id = "xenobio5"; name = "containment blast door"},/turf/open/floor/engine,/area/science/xenobiology)
"vHb" = (/obj/structure/flora/crystal/small/pile,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/open/indestructible/layenia/crystal/garden,/area/hallway/primary/central)
"vHe" = (/obj/effect/turf_decal/tile/blue{dir = 1},/obj/effect/turf_decal/tile/blue{dir = 4},/obj/machinery/light{dir = 1; pixel_y = 19},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel/white,/area/medical/sleeper)
"vHk" = (/turf/open/floor/plating/asteroid/layenia,/area/ai_monitored/storage/satellite)
"vHD" = (/turf/open/floor/grass,/area/security/prison)
"vHF" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel,/area/hallway/secondary/exit)
"vHJ" = (/obj/effect/turf_decal/tile/purple{dir = 4},/obj/effect/turf_decal/tile/purple{dir = 8},/obj/effect/turf_decal/loading_area{dir = 4; icon_state = "drain"; name = "drain"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 9; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 9; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "1-8"},/turf/open/floor/plasteel/cafeteria{dir = 5},/area/science/research)
@@ -8150,7 +8157,7 @@
"wui" = (/obj/effect/turf_decal/loading_area{dir = 6; icon_state = "steel_panel"; name = "steel pannel"},/obj/effect/turf_decal/stripes/line{dir = 4},/turf/open/floor/plasteel/dark,/area/layenia)
"wul" = (/turf/open/floor/engine,/area/engine/engineering/reactor_core)
"wut" = (/obj/structure/table/wood,/obj/item/book/manual/wiki/engineering_construction{pixel_x = 3; pixel_y = -3},/obj/item/book/manual/wiki/engineering_guide,/obj/item/book/manual/wiki/engineering_hacking{pixel_x = -3; pixel_y = 3},/obj/effect/decal/cleanable/dirt,/turf/open/floor/wood,/area/engine/engineering)
"wuv" = (/obj/structure/lattice/catwalk,/obj/structure/reagent_dispensers/fueltank,/obj/structure/railing{dir = 8},/turf/open/floor/plasteel/elevatorshaft,/area/layenia)
"wuv" = (/obj/structure/lattice/catwalk,/obj/structure/reagent_dispensers/fueltank,/obj/structure/railing{dir = 8},/turf/open/floor/plasteel/elevatorshaft,/area/ai_monitored/storage/satellite)
"wuC" = (/obj/machinery/atmospherics/pipe/manifold/yellow/visible{dir = 8},/turf/open/floor/plasteel,/area/engine/atmos)
"wuE" = (/obj/structure/cable{icon_state = "0-8"},/obj/effect/spawner/structure/window/reinforced,/obj/structure/cable{icon_state = "0-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/turf/open/floor/plating,/area/security/brig)
"wuG" = (/obj/effect/turf_decal/loading_area{dir = 6; icon_state = "steel_panel"; name = "steel pannel"},/obj/effect/turf_decal/loading_area{dir = 9; icon_state = "steel_panel"; name = "steel pannel"},/obj/effect/turf_decal/stripes/line{dir = 1},/obj/structure/fence/corner{dir = 9},/turf/open/floor/plating{initial_gas_mix = "o2=22;n2=82;TEMP=180"; planetary_atmos = 1},/area/layenia)
@@ -8763,6 +8770,7 @@
"ydt" = (/turf/open/floor/plasteel/white/side{dir = 4},/area/science/research)
"ydu" = (/obj/machinery/light_switch{pixel_y = 28},/obj/effect/turf_decal/tile/neutral{dir = 4},/turf/open/floor/plasteel/dark,/area/ai_monitored/nuke_storage)
"ydD" = (/obj/machinery/computer/atmos_control/tank/toxin_tank{dir = 8},/obj/effect/turf_decal/stripes/line{dir = 4},/obj/machinery/atmospherics/pipe/simple/purple/visible{dir = 4},/turf/open/floor/plasteel{dir = 8; icon_state = "floor_plate"},/area/engine/atmos)
"ydE" = (/obj/effect/baseturf_helper/asteroid/layenia,/turf/closed/wall/r_wall,/area/ai_monitored/storage/satellite)
"ydH" = (/obj/effect/turf_decal/loading_area{icon_state = "drain"; name = "drain"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer3{dir = 4; name = "air supply pipe"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel,/area/science/misc_lab)
"ydK" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 9; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 10; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel/white,/area/medical/psych)
"ydL" = (/obj/effect/turf_decal/loading_area{icon_state = "drain"; name = "drain"},/obj/machinery/door/airlock/research{dir = 4; name = "Testing Lab"; req_access_txt = "47"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/open/floor/plasteel,/area/science/research)
@@ -8924,18 +8932,18 @@ gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgT
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWtBctBctBcyfmyfmyfmyfmtBctBctBctBctBctBctBctBctBctyzeKvtyztBcgJIlgfltMltMltMltMtBctBctBctBctBctBcyfmyfmyfmyfmyfmnUzprtprtprtqjBprtprtprtxspfLcobJvnphyxcjZekBiEvhyKfOpgnYhAegnYxobhBllTRgulhBsiuAwtHbFRhBMiuAwtHbFRhBMiuAwtHbFRkHZazkqMIhBPwADjxFxOlwGIwGIwGIwGIwGIwGIktuooTquExJUxJUxJUxJUxJUpSppSppSpxJUpYvxMyxMyrhaozsxMyxMypOkwPehRahZDxMyemivKfhGqgWKwUuxNLiOMhGOnhRhusliptvCjYejCOapFapFapFapFknJhuRhuRhuRbhPhuRlEVapFtOSujatBcitUgTWgTWgTWgTWgTWgPqgPqgPqgPqklggPqgPqgPqgTWgPqgTWgTWyfmyfmyfmyfmnGEhOHiWeheIlgWadxbPWwAmnGEyfmyfmyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWtBctBctBctBctBcvlJyfmyfmyfmtBctBctBctBctBctBctBctBctyzeKvtyzmewmFGltMnZFoebpdNltMjXCtBctBctBctBctBcyfmyfmyfmyfmyfmhGWxDVxDVxDVxDVxDVxDVxDVxspxEphHCpSaeJEhIYekBfOcfOcfOcfOcpuefOcfOcfOcfOcgulrwliuAibZbFRhKtiuAhKXbFRdyaiuAohPbFRvlbazkjqrhLfhLNhMHhNshNyuPPmivuLxuLxuLxjbVhLOxJUqmCmGxlxzaeexJUqXhhWTjGSxJUvridpWxKirhaozsapCsXDsXDsXDhRahZDxMyxOHvKfhTMgWKwUuxNLeHCrMEadYrknvvKfPZfPZfPZfPZfPZfPZfPZpZJhuRhuRhuRhuRhuRmqAqSaqSafSFtBccRKgTWgTWgTWgTWgTWgPqgTWgTWgPqklggPqgTWgPqgTWgPqgTWgTWtBcyfmyfmyfmnGEwErxufdXExtvlYupXSwAmnGEyfmyfmyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmyfmyfmgTWgTWgTWgTWtBctBcyfmtBctBcgOntBcyfmyfmyfmyfmtBctBctzMtBctBctBctBctyzucepyjpwmwoBmcrtKHcSDinRmFGmFGmewvKglGrkqRqIYyfmyfmyfmyfmyfmyfmvlJgOntBcyfmtBcwpFixvtqEtqEtqEtqEnjyhUmdQQqFgniAniAniAiYWniAniAniAhUBgulhWfilhilhdSWilhilhilhdSWilhilhhWqoBThWNhWRoBToBThXOoBToBThXXoBTrZUsnasnasnasnasnaxJUhOKpUjfQeufktQOxFIfePvkqocsgIvxKixMyrhaozsxMyylPrTwxKihRahZDxMyemivKfibAgWKwUuxNLaorrGnrGnrGnxJUyizyizyizpDvyizyizyizpNZltyramtBctBctBctBctBctBctBctBcxizgTWgTWgTWgTWgTWgPqgTWgTWgPqklggPqgTWgPqgTWgPqgTWgTWgTWtBcyfmyfmnGEqeCeYNnGEujznGEjsawAmnGEyfmyfmyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmvlJyfmyfmyfmtBctBcgTWtBcyfmyfmvlJvlJgOngOnyfmtBcyfmyfmtEkuXIuXIuXIuXIuXItEkeHAeHAeHAltMfwqmFGxIBdPtinRxFidPtsGjnhRnhRfbDqMpyfmyfmyfmyfmyfmyfmyfmwpFyfmyfmwpFlRQvqeigwigSihttqEiilpBNiiofKlsszsszssziiJsszgUIniAfsYeoSlKnmdXmdXsMEmdXmdXmdXvNwmdXmdXjQSvNwmdXxHojMRoBTkIbijkoBTijVkVCbVzsnabvybWIbWItQTxJUijWkpqiwAmuWueUgostDofVIslGwuKurfurftJYsVHefElzqikxilyufKirrewBptfnUZgKzwxMgKznFbaIUiuTgPAxmQxJUxJUxJUxJUxJUxJUxJUnhRnhRcaHcectBctBctBctBctBctBctBctBcdDhgTWgTWgTWgTWgTWgPqgTWgTWgPqklggPqgTWgPqgTWgPqgTWgTWgTWtBctBcqFHnGEiyhoHVnGEsFInGEoHVoHVnGEyfmyfmyfmtEkgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmvlJyfmyfmyfmtBctBcgTWtBcyfmyfmvlJvlJgOngOnyfmtBcyfmyfmtEkuXIuXIuXIuXIuXItEkeHAeHAeHAltMfwqmFGxIBdPtinRxFidPtsGjnhRnhRfbDqMpyfmyfmyfmyfmyfmyfmyfmwpFyfmyfmwpFlRQvqeigwigSihttqEiilpBNiiofKlsszsszssziiJsszgUIniAfsYeoSlKnmdXmdXsMEmdXmdXmdXvNwmdXmdXjQSvNwmdXxHojMRoBTkIbijkoBTijVkVCbVzsnabvybWIbWItQTxJUijWkpqiwAmuWueUgostDofVIslGwuKurfurftJYsVHefElzqikxilyufKirrewBptfnUZgKzwxMgKznFbaIUiuTgPAxmQxJUxJUxJUxJUxJUxJUxJUbBTbBTcaHcectBctBctBctBctBctBctBctBcdDhgTWgTWgTWgTWgTWgPqgTWgTWgPqklggPqgTWgPqgTWgPqgTWgTWgTWtBctBcqFHnGEiyhoHVnGEsFInGEoHVoHVnGEyfmyfmyfmtEkgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmwpFgOnwpFyfmyfmtBctBctBcyfmyfmyfmtBcwpFgOntBchhGyfmyfmyfmtkPtBctBcbsZnKGmGKtyzuOFpyjpwmwoBmcrvpIwoBuNNmFGmFGmewibnnhRfbDnYxyfmyfmyfmyfmyfmyfmyfmyfmyfmyfmyfmvlJvqerNTdjJipFtqEvjTvjTvjTlxOkWwkWwkWwkWwkWworGfikuEcqFJgvkmrJvRJaCggvklCPgvkgvkgvkgvkwmGgvkiCVipGapkjvEylxiqcoBTdVCoBTbVzsnabvybWIbWItQTxJUiqpmCLfLFufktQObfhiiuyiGpEVgIvxMyxMyxMyxMyufKsVUnDYirrfDNsINpSdrcjeuOitaqKEjjkpusdtiwrgwrgrTnhNNeCetOAvXmvXmqrBpjcbBTbBTmEncectBctBctBctBctBctBctBctBcitUgTWgTWgTWgTWgTWgPqgTWgTWgPqklggPqgTWgPqgTWgPqgTWgTWgTWgTWtBcqFHfOWvlCtBcnGEohwnGEtBctBcfOWyfmyfmyfmgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmvlJwpFgOnyfmyfmyfmtBctBctBcyfmtBcgOngOnwpFuKhyfmyfmyfmyfmwedtBctBctBctBctyzeKvtyzmewmFGltMfGimufpiDltMejgxejxejxejxejxejyfmyfmyfmyfmyfmyfmyfmyfmylMgOnyfmtBcvqeooYepctWabYDbKpixavjThPdixiixXiyweMskWwpCEizFhPdeoSczLdKZvcofhjrdRrdRrdRrdRrdRqnyrdRiBdamqipGapkbJbsmvuDUoBTuALaELajSsnanxVbWItQTtQTxJUiBjdTZdvOiBPxJUiCJdQsarXxJUxaUqnHxMyxMyxMykoFhCZjennhwdpWvOHsECiDIiFfwrWpTXwrWfNkxGQwrWwrWrFligMiUdsWnafmoRRwlSiymbbgbBTmEncectBctBctBctBctBctBctBctBccRKgTWgTWgTWgTWgTWwOpgPqgPqgPqklggPqgPqwOpgPqwOpgPqgPqgPqgPqgPqqJHwgkrWoipjiNOoZQvbyipjxejxejuCcgPqgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmgOnhhGvlJyfmyfmtBcgTWtBcyfmvlJgOnhhGgOnyfmyfmyfmyfmyfmpSstBctBctBctBctyzeKvtyztBctBxltMltMltMltMltMgTWgTWgTWgTWgTWgTWgTWyfmyfmwcKyfmyfmyfmyfmtBcgOnwpFyfmtqEtqEtqEtqEtqEazfxbCvjTvjTvjTqxDcGAcGAcGAcGAcGAcGAcGAcGAgbIvmOntmntmcbdntmntmkUZkUZkUZecQaBpbrziJclpkiJoiJDoBTsKewLylXpsnaiKOvXXtEKsnapUXeywiLPceXeywsnasnasnasnasnasnasnaioSxMydAdiaLdgevMCiMukATiMvnpGiMTeuOiNPboUkxnpusqDxqYfsqjsqjqBaeCevXmvXmvXmijQpjcbBTbBTmEnjOAxizwWhxhaayBxizwWhxhaayBxizgTWgTWgTWgTWgTWgPqgTWgTWgPqklggPqgTWgPqgTWgPqgTWgTWgTWgTWgPqgPqgPqxPYgPqiEgeOknusgPqgPqgPqgPqgPqgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmvlJwpFgOngOnyfmyfmgTWgTWyfmwpFtBcvlJgOnwpFyfmyfmyfmyfmyfmtBctBctBctBctyzeKvtyztBctBclADgSCyjKiVKpQXgTWgTWgTWgTWgTWgTWgTWyfmyfmgOnvlJyfmyfmyfmgTWtBcgOntBcvqeiSXiVefBshytcXssYgexJsYgaifcGAiWiskbskbrtYdHZoiaiWZcGArnrkUZdfdiZXcPjjaBcPjrPhjaZkUZjdrjdGjdRwtgoBToBToBToBTaELaELajSsnabNctEKtEKpaZnwzfzOemxqEPdsisnacfToPKtzGjfzqAzsnaioSxMykEzjfUhWCsnLjgMjhpnBJvEgxJUvKfsXDrHisXDuPoxJUxJUxJUxJUxJUxJUxJUxJUxJUxJUxJUeAAeAAeAAuEpeAAgPqgPqgPqgPqgPqgPqgPqqurgPqgPqgPqgPqgPqgPqgPqgPqgPqklggPqgTWgPqgTWgPqgTWgTWgTWgTWgPqgPqchFgPqgPqiEgeOknusgPqgTWgTWgPqgTWgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmyfmwpFvlJwpFyfmyfmgTWyfmtBcyfmgOnwpFvlJuKhyfmyfmyfmyfmtBctBctBcbgPjmaeKvjmabgPtBcxQunhRnhRnhRnusgTWgTWgTWgTWgTWgTWgTWyfmyfmylMwHbuKhyfmgTWgTWgTWtBcvqevqevqekdYqmDjjbqmDqmDqmDqmDkmvqTMskbmsfjjHjjViNnwWckOJcGArnrkUZiQLtpatpatpatpaqKwkUZkUZxoadbApdZjYDnkkamWamWrqSmGnamWeWysnawwqtEKtEKpaZnwzmPmexOxBWxqusnauZEnPmnPmjkbnPmsnajkuxMykEzjlzvaVfZijmzuWQnBJtSifqBhmFlAUvzBhBqyheizrjqMjstnByqqiqqiqqiqqiqqilJMqqiqqiqqiqqiqqilJMqqiqqiqqiqqiqqiqqiqqiqqiqqiqqiqqiqqiqqiqqiqqiqqichLfaSchLqqichLchLqqichLchLchLchLqqiuodgPqgPqgPqrRMmIrhkmgPqgTWgTWgPqgTWgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWtEkyfmyfmyfmyfmyfmyfmyfmgTWyfmyfmyfmgOngOngOntBcyfmyfmyfmyfmyfmtzMtBctBctyzeKvtyztBcpPVqcTipjxejxejxAUgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmgOnylMyfmgTWgTWgTWuSTiQRjvBiQRuyjqmDqdHqmDqmDqmDqmDkmvqTMskbjwCjyXjzpgdhkDpkOJcGArnrkUZcPCuXqbHrjzYjAiawcntmpXgfCCdtQjArmVdvicsnasnawPRkXIsnaymipeIhHVhHVhHVhHVhVttQrnoxilSyhusnawdediOiuRiobnPmxCxjBVxMycJxmtZhtLemyjCEaCBhwBbfgvKfjCVlAUvpBeCPjfmofyjGgxeLwOpgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFfoHgJFfoHgJFfoHgJFgJFgJFgJFgJFgJFgJFgJFdnsyfmyfmyfmeAAxdeeAAyfmyfmyfmgPqgTWgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgPqgTWgTWgTWyfmyfmyfmyfmgTWyfmyfmwpFtBcwpFhhGgOnyfmyfmyfmyfmyfmyfmtBctBctyzeKvtyzxpHgTWgTWgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmwcKyfmyfmgTWgTWtBcvqevqevqejGZjJsqmDqmDqmDqmDqmDkmvqTMskbskbuBVjJFnrUblujOlcGArnrkUZjKdkUZiMbhzsjKGocwntmapkfCCaqUjArjKVsnaqaajajvbbjNSsnahHVhHVaMvjNYsIJkEWhHVodbnoxnAhjOTsnawdediOslDwYwnPmxCxewcxMybsDxOTbxSraYjQcusumBFtSivKfwmLlAUppMyhuyheipCerAxeLnusgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqklggPqklggPqklggPqgPqgPqgPqgPqgPqgPqgPqyfmyfmyfmvlJtyzxdetyzylMyfmyfmtEkyfmyfmdiGyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWyfmuKhtBcuKhtBcvlJwpFyfmyfmyfmyfmyfmyfmtBctBctyzeKvnDpgTWgTWgTWgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmyfmyfmyfmyfmtBctBcwpFvqejYNaUujYQbVaunkunkunkunkmVqcGAqTMqTMqTMqTMcGAuUhcGAcGAuKajXIrnwkUZkaokbmkbKpdQntmhdHfCCaqUjArnHdsnadyvjajsiujNSsnahHVuUdkcbuePmBwkeehHVeksnoxilSqYVsnaqVuvRbcFNkefnPmxCxxQgxMykghdmRvYQdmRkheeuAkhjguWvKfkjklAUppMyhuyhejhUhXwsnawOpfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHwOpfoHwOpfoHwOpfoHfoHfoHfoHfoHfoHfoHbaleAAlfOtyztyzeAAsZfeAAtBcaUbyfmoYSoYSoYSoYSyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgPqgTWgTWgTWgTWgTWtBcylMgTWyfmyfmtBctBcyfmyfmyfmyfmktDjWUyfmyfmtEktBctyztyzeKvtyzguZgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqnTyobMlVzoYPsaasaasaasaasaasaasaasaatqEtqEtqEkvpeXBkvyepcyiatfhbPSkeFkeFjVutixpFkkvWvjTvjTvjTtVOkUZkUZkUZkUZkUZkUZvAWfCCaqUjArapkkwnkwPfcduHswomkxehHVhHVhHVhHVuachHVhHVhHVtAnpmfkBVsnanyUimdcLtpLQmWQkCCrcturfkDntLItYgpIjpIjwFOqoirHlvKfkDvlAUppMyhuyhewgdrHbxMDvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkqoPbCwlLhlLhlLhrjKmTqtyztBcdnVyfmoYSjkzuFfoYSyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWiFlfoHfoHfoHguZgTWgTWgTWgTWtBcgTWgTWyfmyfmyfmyfmyfmyfmyfmtBctBctBctBcalOtyztyzemJrTxikBwOpfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHnJFnJFnJFwZnsaahqVjAYpLVrIEkKfsxpqfwrIEkKwkrLtqExBXqmDkLzepcyiaekQbUjkeFkeFkLKaiMjjzkLbkNskNLvjTprSxXjkNZggrkrBqPVxGapZEfCCaqUjArapktJnkPlcsdvucsazdhMhHVkPqkPTkQdtcKayToJHhHVwcQgGYyhuuHfnvsqKQtJXkQwnPmxCxaYyxMyaNNxMykRVfedwPeoYslAPemivKfwmLlAUppMyhuyhesnasnasnasnaaFMxBmxBmxBmxBmxBmxBmxBmxBmxejxejxejxejwOpxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejmLneAAtyztyztyzeAAefeeAAreBopNoYSoYSmSGojyoYSyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWiEgiQcftOkdknusgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmorfyfmtEktBctBctBctBctBclfCjBPjBPqHZtEkeCdqoPqoPqoPqoPqoPqoPqoPqoPqoPqoPqoPqoPqoPqoPeZJgmBaFFqGesaaqJewXCqTLrIEvIGlhCqUOrIElkGadItqEfhEqmDkLzepcyiagRGgRolmOlnblnepomdQAnhrvjTlntvjTrnrksyksyksyksyksyksylnQfCCsZcjArapkloeioblnYvIpaemhAMhHVlpniQBlqqlqKsfvkiTqYvnDQryzsXNbTKhkamsjhMOeTlnPmxCxgkgxMymjUxMysXDsXDsXDoYslAPfIevKfjfelAUqkJyhuyhefWVxMMoNzdVxxBmpvBiOfaaYqdGuMuhdldJBxBmgPqgPqgPqgPqmapgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqyfmyfmwcKvlJuuUlEtxIYxIYxIYpWhdABgKCygjoYSyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWtEkyfmyfmyfmyfmyfmyfmyfmgTWyfmyfmyfmgOngOngOntBcyfmyfmyfmyfmyfmtzMtBctBctyzeKvtyztBcpPVqcTipjxejxejxAUgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmgOnylMyfmgTWgTWgTWuSTiQRjvBiQRuyjqmDqdHqmDqmDqmDqmDkmvqTMskbjwCjyXjzpgdhkDpkOJcGArnrkUZcPCuXqbHrjzYjAiawcntmpXgfCCdtQjArmVdvicsnasnawPRkXIsnaymipeIhHVhHVhHVhHVhVttQrnoxilSyhusnawdediOiuRiobnPmxCxjBVxMycJxmtZhtLemyjCEaCBhwBbfgvKfjCVlAUvpBeCPjfmofyjGgxeLwOpgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFgJFfoHgJFfoHgJFfoHgJFgJFgJFgJFgJFgJFgJFgJFdnsyfmyfmyfmydEftjoYSyfmyfmyfmgPqgTWgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgPqgTWgTWgTWyfmyfmyfmyfmgTWyfmyfmwpFtBcwpFhhGgOnyfmyfmyfmyfmyfmyfmtBctBctyzeKvtyzxpHgTWgTWgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmwcKyfmyfmgTWgTWtBcvqevqevqejGZjJsqmDqmDqmDqmDqmDkmvqTMskbskbuBVjJFnrUblujOlcGArnrkUZjKdkUZiMbhzsjKGocwntmapkfCCaqUjArjKVsnaqaajajvbbjNSsnahHVhHVaMvjNYsIJkEWhHVodbnoxnAhjOTsnawdediOslDwYwnPmxCxewcxMybsDxOTbxSraYjQcusumBFtSivKfwmLlAUppMyhuyheipCerAxeLnusgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqklggPqklggPqklggPqgPqgPqgPqgPqgPqgPqgPqyfmyfmyfmaIlpstftjpstvjdyfmyfmtEkyfmyfmtEkyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWyfmuKhtBcuKhtBcvlJwpFyfmyfmyfmyfmyfmyfmtBctBctyzeKvnDpgTWgTWgTWgTWgPqgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmyfmyfmyfmyfmtBctBcwpFvqejYNaUujYQbVaunkunkunkunkmVqcGAqTMqTMqTMqTMcGAuUhcGAcGAuKajXIrnwkUZkaokbmkbKpdQntmhdHfCCaqUjArnHdsnadyvjajsiujNSsnahHVuUdkcbuePmBwkeehHVeksnoxilSqYVsnaqVuvRbcFNkefnPmxCxxQgxMykghdmRvYQdmRkheeuAkhjguWvKfkjklAUppMyhuyhejhUhXwsnawOpfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHwOpfoHwOpfoHwOpfoHfoHfoHfoHfoHfoHfoHbaloYSlfOpstpstoYSsZfoYSvHkaUbyfmoYSoYSoYSoYSyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgPqgTWgTWgTWgTWgTWtBcylMgTWyfmyfmtBctBcyfmyfmyfmyfmktDjWUyfmyfmtEktBctyztyzeKvtyzguZgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqnTyobMlVzoYPsaasaasaasaasaasaasaasaatqEtqEtqEkvpeXBkvyepcyiatfhbPSkeFkeFjVutixpFkkvWvjTvjTvjTtVOkUZkUZkUZkUZkUZkUZvAWfCCaqUjArapkkwnkwPfcduHswomkxehHVhHVhHVhHVuachHVhHVhHVtAnpmfkBVsnanyUimdcLtpLQmWQkCCrcturfkDntLItYgpIjpIjwFOqoirHlvKfkDvlAUppMyhuyhewgdrHbxMDvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkvwkqoPbCwlLhlLhlLhrjKmTqpstvHkdnVyfmoYSjkzuFfoYSyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWiFlfoHfoHfoHguZgTWgTWgTWgTWtBcgTWgTWyfmyfmyfmyfmyfmyfmyfmtBctBctBctBcalOtyztyzemJrTxikBwOpfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHfoHnJFnJFnJFwZnsaahqVjAYpLVrIEkKfsxpqfwrIEkKwkrLtqExBXqmDkLzepcyiaekQbUjkeFkeFkLKaiMjjzkLbkNskNLvjTprSxXjkNZggrkrBqPVxGapZEfCCaqUjArapktJnkPlcsdvucsazdhMhHVkPqkPTkQdtcKayToJHhHVwcQgGYyhuuHfnvsqKQtJXkQwnPmxCxaYyxMyaNNxMykRVfedwPeoYslAPemivKfwmLlAUppMyhuyhesnasnasnasnaaFMxBmxBmxBmxBmxBmxBmxBmxBmxejxejxejxejwOpxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejxejmLnoYSpstpstpstoYSefeoYSreBopNoYSoYSmSGojyoYSyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWiEgiQcftOkdknusgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmorfyfmtEktBctBctBctBctBclfCjBPjBPqHZtEkeCdqoPqoPqoPqoPqoPqoPqoPqoPqoPqoPqoPqoPqoPqoPeZJgmBaFFqGesaaqJewXCqTLrIEvIGlhCqUOrIElkGadItqEfhEqmDkLzepcyiagRGgRolmOlnblnepomdQAnhrvjTlntvjTrnrksyksyksyksyksyksylnQfCCsZcjArapkloeioblnYvIpaemhAMhHVlpniQBlqqlqKsfvkiTqYvnDQryzsXNbTKhkamsjhMOeTlnPmxCxgkgxMymjUxMysXDsXDsXDoYslAPfIevKfjfelAUqkJyhuyhefWVxMMoNzdVxxBmpvBiOfaaYqdGuMuhdldJBxBmgPqgPqgPqgPqmapgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqgPqyfmyfmumzaIluuUlEtuwKuwKuwKpWhdABgKCygjoYSyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgfhgPqiEgorldiGpggnusgPqgPqgPqgPqgPqgPqgPqgPqtEktBctBctBctBcltjltyltNtBctBcalOxejwOpvQaosUqQOwOpxejxejxejxejxejxejxejxejxejxejxejxejxejnJFnJFnJFkgHsaaszVrmCrMcrIEsIglwHsYQrIEkgHwHEtqExBXqmDkLzepcyiagRGqfWqfWqfWqfWpomdaZnhrtpQhsNvjTrnrksylyiaPQqEMpIxrgGapkpvWcbhjArvjMjtybauluVrjZlyHlzihHVlzpoTllzRlAznJWxwylqPnDQdyjxIquHfwdefWagYWoulfZvxCxoInxKiaNNxMyylPxIDxMyoYslAPtjYvKfsXDlAUppMqYVyhesCHnrHnrHfbXxBmtHpvUrpcatEfflDhyclDkxBmxBmlHzlHPlIiklggTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmyfmwuvldJjjNjTBaexoYSoYSgdOpGaoYSyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWiEgrCwwyjtmAnusgTWgTWgTWgPqiFlfoHfoHfoHbDdtBctBctBctBclJVlJZbgPyfmyfmtEkgTWmcCxejxejxejpPQgPqgPqgPqgPqgPqgPqgPqgPqgPqnTytBctBctBcylMtBclVzudnsaarIEufCrIErIErIEuwGrIErIEkgHwLctqEvjTvjTvjTnrjwGNlLDepcqmDqmDepctbEhiPtYcvjTvjTvjTrnrksymSwciRlLHaHEksyksyiiZaeYlLWwtgsnasnasnahqkeZGhqkhHVlMuviIlMBlNDlNMlQBlQYnDQdyjyhusnauBGgmQtQVwdetvusnaaNougvuUajAmoScoScjAmjAmlwfxJUvKfxJUeholUMqRQclKwHwakBeQPwHwxBmdfEiaBxNTdPGbQixpjdfElVClXglXKlXRlZMklggTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmyfmyfmyfmyfmyfmyfmoYSoYSoYSoYSyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
gTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWmcCxejxejxejpPQgTWgTWgTWgPqiEgwOpwOpwOpmcBtBcyfmyfmmdxcfwlJZyfmyfmwcKylMgTWqITgTWgTWgTWqITgTWgTWgTWqITgTWgTWgTWtBctBctBctBcsGhtBctBcmcSlVzeVhwvTmqFmubmqFmqFjLTmdOgmBhGjuFXuTctqEmeemhdvjTjxhwSGswPmjYqmDqmDmjYvCcmSvnhrvjTtuhfGJuGRksysDlqOdqOdoexmlfksyddqcbhmlFacrhMbhCtpwZgGPmnmmnUvsnmoGmsibxfvsnmtrvsnvsnahEonRpoDpLnpLnpLnpLnpLnpLnpLnmuJlgdlgdmuJlgdlgdmuJlgdlgdmuJmvDhDllAUppMyhurOTejNmwbwyzgBUpsOiHEppEroIaskroIdbqiHEnQBkwxyfGcFHlZMklggTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWyfmyfmyfmyfmyfmyfmyfmyfmyfmyfmyfmyfmgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTWgTW
+2
View File
@@ -157,6 +157,8 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
#define isclown(A) (istype(A, /mob/living/simple_animal/hostile/retaliate/clown))
#define ismimic(A) (istype(A, /mob/living/simple_animal/hostile/hs13mimic))
GLOBAL_LIST_INIT(shoefootmob, typecacheof(list(
/mob/living/carbon/human/,
/mob/living/simple_animal/cow,
+1 -1
View File
@@ -252,7 +252,7 @@
#define OFFSET_NECK "neck"
//MINOR TWEAKS/MISC
#define AGE_MIN 18 //youngest a character can be //CITADEL EDIT - 17 --> 18
#define AGE_MIN 21 //youngest a character can be //Hyper edit - 21
#define AGE_MAX 85 //oldest a character can be
#define WIZARD_AGE_MIN 30 //youngest a wizard can be
#define APPRENTICE_AGE_MIN 29 //youngest an apprentice can be
+3
View File
@@ -65,6 +65,9 @@
if (CONFIG_GET(flag/log_virus))
WRITE_LOG(GLOB.world_virus_log, "VIRUS: [text]")
/proc/log_asset(text)
WRITE_LOG(GLOB.world_asset_log, "ASSET: [text]")
/proc/log_access(text)
if (CONFIG_GET(flag/log_access))
WRITE_LOG(GLOB.world_game_log, "ACCESS: [text]")
+3
View File
@@ -23,6 +23,9 @@ GLOBAL_VAR_INIT(cmp_field, "name")
/proc/cmp_records_dsc(datum/data/record/a, datum/data/record/b)
return sorttext(a.fields[GLOB.cmp_field], b.fields[GLOB.cmp_field])
/proc/cmp_filter_data_priority(list/A, list/B)
return A["priority"] - B["priority"]
/proc/cmp_ckey_asc(client/a, client/b)
return sorttext(b.ckey, a.ckey)
+6 -4
View File
@@ -1128,9 +1128,10 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
if (!isicon(I))
if (isfile(thing)) //special snowflake
var/name = sanitize_filename("[generate_asset_name(thing)].png")
register_asset(name, thing)
if(!SSassets.cache[name])
register_asset(name, thing)
for (var/thing2 in targets)
send_asset(thing2, key, FALSE)
send_asset(thing2, key)
return "<img class='icon icon-misc' src=\"[url_encode(name)]\">"
var/atom/A = thing
if (isnull(dir))
@@ -1152,9 +1153,10 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
I = icon(I, icon_state, dir, frame, moving)
key = "[generate_asset_name(I)].png"
register_asset(key, I)
if(!SSassets.cache[key])
register_asset(key, I)
for (var/thing2 in targets)
send_asset(thing2, key, FALSE)
send_asset(thing2, key)
return "<img class='icon icon-[icon_state]' src=\"[url_encode(key)]\">"
+2
View File
@@ -28,6 +28,8 @@ GLOBAL_VAR(world_job_debug_log)
GLOBAL_PROTECT(world_job_debug_log)
GLOBAL_VAR(world_virus_log)
GLOBAL_PROTECT(world_virus_log)
GLOBAL_VAR(world_asset_log)
GLOBAL_PROTECT(world_asset_log)
GLOBAL_VAR(world_map_error_log)
GLOBAL_PROTECT(world_map_error_log)
@@ -434,3 +434,5 @@
/datum/config_entry/flag/picture_logging_camera
/datum/config_entry/flag/minimaps_enabled
config_entry_value = TRUE
+1 -11
View File
@@ -6,17 +6,7 @@ SUBSYSTEM_DEF(assets)
var/list/preload = list()
/datum/controller/subsystem/assets/Initialize(timeofday)
var/list/priority_assets = list(
/datum/asset/simple/oui_theme_nano,
/datum/asset/simple/goonchat
)
for(var/type in priority_assets)
var/datum/asset/A = new type()
A.register()
for(var/type in typesof(/datum/asset) - (priority_assets | list(/datum/asset, /datum/asset/simple)))
for(var/type in typesof(/datum/asset))
var/datum/asset/A = type
if (type != initial(A._abstract))
get_asset_datum(type)
+20
View File
@@ -0,0 +1,20 @@
SUBSYSTEM_DEF(minimaps)
name = "Minimaps"
flags = SS_NO_FIRE
var/list/station_minimaps = list()
var/datum/minimap_group/station_minimap = null
/datum/controller/subsystem/minimaps/Initialize()
if(!CONFIG_GET(flag/minimaps_enabled))
to_chat(world, "<span class='boldwarning'>Minimaps disabled! Skipping init.</span>")
return ..()
build_minimaps()
return ..()
/datum/controller/subsystem/minimaps/proc/build_minimaps()
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
var/datum/space_level/SL = SSmapping.get_level(z)
var/name = (SL.name == initial(SL.name))? "[z] - Station" : "[z] - [SL.name]"
station_minimaps += new /datum/minimap(z, name = name)
station_minimap = new(station_minimaps, "Station")
+12 -10
View File
@@ -43,8 +43,10 @@
var/datum/asset/spritesheet/sheet = name
stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]"
else
stylesheets["[ckey(name)].css"] = file
register_asset("[ckey(name)].css", file)
var/asset_name = "[name].css"
stylesheets[asset_name] = file
if(!SSassets.cache[asset_name])
register_asset(asset_name, file)
/datum/browser/proc/set_content(ncontent)
content = ncontent
@@ -91,20 +93,20 @@
[get_footer()]
"}
/datum/browser/proc/open(use_onclose = 1)
/datum/browser/proc/open(use_onclose = TRUE)
if(isnull(window_id)) //null check because this can potentially nuke goonchat
WARNING("Browser [title] tried to open with a null ID")
to_chat(user, "<span class='userdanger'>The [title] browser you tried to open failed a sanity check! Please report this on github!</span>")
return
var/window_size = ""
if (width && height)
if(width && height)
window_size = "size=[width]x[height];"
if (stylesheets.len)
send_asset_list(user, stylesheets, verify=FALSE)
if (scripts.len)
send_asset_list(user, scripts, verify=FALSE)
if(stylesheets.len)
send_asset_list(user, stylesheets)
if(scripts.len)
send_asset_list(user, scripts)
user << browse(get_content(), "window=[window_id];[window_size][window_options]")
if (use_onclose)
if(use_onclose)
setup_onclose()
/datum/browser/proc/setup_onclose()
@@ -151,7 +153,7 @@
close()
//designed as a drop in replacement for alert(); functions the same. (outside of needing User specified)
/proc/tgalert(var/mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000)
/proc/tgalert(mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000)
if (!User)
User = usr
switch(askuser(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout))
+1 -1
View File
@@ -4,7 +4,7 @@
/datum/component/lockon_aiming
dupe_mode = COMPONENT_DUPE_ALLOWED
var/lock_icon = 'icons/mob/blob.dmi'
var/lock_icon = 'icons/mob/cameramob.dmi'
var/lock_icon_state = "marker"
var/mutable_appearance/lock_appearance
var/list/image/lock_images
+11 -1
View File
@@ -70,6 +70,9 @@
var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default?
var/list/canSmoothWithAreas //typecache to limit the areas that atoms in this area can smooth with
/// Color on minimaps, if it's null (which is default) it makes one at random.
var/minimap_color
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/
GLOBAL_LIST_EMPTY(teleportlocs)
@@ -92,7 +95,14 @@ GLOBAL_LIST_EMPTY(teleportlocs)
// ===
/area/New()
// This interacts with the map loader, so it needs to be set immediately
if(!minimap_color) // goes in New() because otherwise it doesn't fucking work
// generate one using the icon_state
if(icon_state && icon_state != "unknown")
var/icon/I = new(icon, icon_state, dir)
I.Scale(1,1)
minimap_color = I.GetPixel(1,1)
else // no icon state? use random.
minimap_color = rgb(rand(50,70),rand(50,70),rand(50,70)) // This interacts with the map loader, so it needs to be set immediately
// rather than waiting for atoms to initialize.
if (unique)
GLOB.areas_by_type[type] = src
+2 -3
View File
@@ -877,8 +877,7 @@ Proc for attack log creation, because really why not
// Filter stuff
/atom/movable/proc/add_filter(name,priority,list/params)
if(!filter_data)
filter_data = list()
LAZYINITLIST(filter_data)
var/list/p = params.Copy()
p["priority"] = priority
filter_data[name] = p
@@ -886,7 +885,7 @@ Proc for attack log creation, because really why not
/atom/movable/proc/update_filters()
filters = null
sortTim(filter_data,associative = TRUE)
filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, TRUE)
for(var/f in filter_data)
var/list/data = filter_data[f]
var/list/arguments = data.Copy()
@@ -188,10 +188,10 @@
weight = 3
cost = 10
requirements = list(101,101,50,40,40,30,30,30,20,20)
minimum_players = 15
minimum_players = 30
high_population_requirement = 10
var/team_mode_probability = 30
chaos_min = 3.0
var/team_mode_probability = 0
chaos_min = 3.5
/datum/dynamic_ruleset/roundstart/changeling/pre_execute()
var/num_changelings = min(round(mode.candidates.len / 10) + 1, candidates.len)
@@ -849,7 +849,7 @@
cost = 0
requirements = list(101,101,101,70,60,60,50,50,50,40)
high_population_requirement = 10
chaos_min = 4.0
chaos_min = 3.2
/datum/dynamic_ruleset/roundstart/bloodsucker/pre_execute()
@@ -288,9 +288,9 @@
/obj/machinery/computer/camera_advanced/ratvar/CreateEye()
..()
eyeobj.visible_icon = 1
eyeobj.icon = 'icons/obj/abductor.dmi' //in case you still had any doubts
eyeobj.icon_state = "camera_target"
eyeobj.visible_icon = TRUE
eyeobj.icon = 'icons/mob/cameramob.dmi' //in case you still had any doubts
eyeobj.icon_state = "generic_camera"
/obj/machinery/computer/camera_advanced/ratvar/GrantActions(mob/living/carbon/user)
..()
+1 -1
View File
@@ -256,7 +256,7 @@
user.visible_message("[user] unfastens the scanner module.", "<span class='notice'>You unfasten the scanner module.</span>")
if(12)
if(diff==FORWARD)
user.visible_message("[user] secures [I].", "<span class='notice'>You secure [I].</span>")
user.visible_message("[user] secures the capacitor.", "<span class='notice'>You secure the capacitor.</span>")
else
user.visible_message("[user] removes the capacitor from [parent].", "<span class='notice'>You remove the capacitor from [parent].</span>")
if(13)
+1
View File
@@ -108,6 +108,7 @@ GLOBAL_VAR(restart_counter)
GLOB.world_game_log = "[GLOB.log_directory]/game.log"
GLOB.world_virus_log = "[GLOB.log_directory]/virus.log"
GLOB.world_asset_log = "[GLOB.log_directory]/asset.log"
GLOB.world_attack_log = "[GLOB.log_directory]/attack.log"
GLOB.world_pda_log = "[GLOB.log_directory]/pda.log"
GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log"
@@ -17,9 +17,9 @@
/obj/machinery/computer/camera_advanced/abductor/CreateEye()
..()
eyeobj.visible_icon = 1
eyeobj.icon = 'icons/obj/abductor.dmi'
eyeobj.icon_state = "camera_target"
eyeobj.visible_icon = TRUE
eyeobj.icon = 'icons/mob/cameramob.dmi'
eyeobj.icon_state = "generic_camera"
/obj/machinery/computer/camera_advanced/abductor/GrantActions(mob/living/carbon/user)
..()
@@ -9,7 +9,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
name = "Blob Overmind"
real_name = "Blob Overmind"
desc = "The overmind. It controls the blob."
icon = 'icons/mob/blob.dmi'
icon = 'icons/mob/cameramob.dmi'
icon_state = "marker"
mouse_opacity = MOUSE_OPACITY_ICON
move_on_shuttle = 1
@@ -9,7 +9,7 @@ the new instance inside the host to be updated to the template's stats.
name = "Sentient Disease"
real_name = "Sentient Disease"
desc = ""
icon = 'icons/mob/blob.dmi'
icon = 'icons/mob/cameramob.dmi'
icon_state = "marker"
mouse_opacity = MOUSE_OPACITY_ICON
move_on_shuttle = FALSE
+100
View File
@@ -0,0 +1,100 @@
/*
Asset cache quick users guide:
Make a datum in asset_list_items.dm with your assets for your thing.
Checkout asset_list.dm for the helper subclasses
The simple subclass will most like be of use for most cases.
Then call get_asset_datum() with the type of the datum you created and store the return
Then call .send(client) on that stored return value.
Note: If your code uses output() with assets you will need to call asset_flush on the client and wait for it to return before calling output(). You only need do this if .send(client) returned TRUE
*/
//When sending mutiple assets, how many before we give the client a quaint little sending resources message
#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8
//This proc sends the asset to the client, but only if it needs it.
//This proc blocks(sleeps) unless verify is set to false
/proc/send_asset(client/client, asset_name)
return send_asset_list(client, list(asset_name))
/// Sends a list of assets to a client
/// This proc will no longer block, use client.asset_flush() if you to need know when the client has all assets (such as for output()). (This is not required for browse() calls as they use the same message queue as asset sends)
/// client - a client or mob
/// asset_list - A list of asset filenames to be sent to the client.
/// Returns TRUE if any assets were sent.
/proc/send_asset_list(client/client, list/asset_list)
if(!istype(client))
if(ismob(client))
var/mob/M = client
if(M.client)
client = M.client
else
return
else
return
var/list/unreceived = list()
for (var/asset_name in asset_list)
var/datum/asset_cache_item/asset = SSassets.cache[asset_name]
if (!asset)
continue
var/asset_file = asset.resource
if (!asset_file)
continue
var/asset_md5 = asset.md5
if (client.sent_assets[asset_name] == asset_md5)
continue
unreceived[asset_name] = asset_md5
if (unreceived.len)
if (unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT)
to_chat(client, "Sending Resources...")
for(var/asset in unreceived)
var/datum/asset_cache_item/ACI
if ((ACI = SSassets.cache[asset]))
log_asset("Sending asset [asset] to client [client]")
client << browse_rsc(ACI.resource, asset)
client.sent_assets |= unreceived
addtimer(CALLBACK(client, /client/proc/asset_cache_update_json), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE)
return TRUE
return FALSE
//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start.
//The proc calls procs that sleep for long times.
/proc/getFilesSlow(client/client, list/files, register_asset = TRUE, filerate = 3)
var/startingfilerate = filerate
for(var/file in files)
if (!client)
break
if (register_asset)
register_asset(file, files[file])
if (send_asset(client, file))
if (!(--filerate))
filerate = startingfilerate
client.asset_flush()
stoplag(0) //queuing calls like this too quickly can cause issues in some client versions
//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
//icons and virtual assets get copied to the dyn rsc before use
/proc/register_asset(asset_name, asset)
var/datum/asset_cache_item/ACI = new(asset_name, asset)
//this is technically never something that was supported and i want metrics on how often it happens if at all.
if (SSassets.cache[asset_name])
var/datum/asset_cache_item/OACI = SSassets.cache[asset_name]
if (OACI.md5 != ACI.md5)
stack_trace("ERROR: new asset added to the asset cache with the same name as another asset: [asset_name] existing asset md5: [OACI.md5] new asset md5:[ACI.md5]")
else
var/list/stacktrace = gib_stack_trace()
log_asset("WARNING: dupe asset added to the asset cache: [asset_name] existing asset md5: [OACI.md5] new asset md5:[ACI.md5]\n[stacktrace.Join("\n")]")
SSassets.cache[asset_name] = ACI
//Generated names do not include file extention.
//Used mainly for code that deals with assets in a generic way
//The same asset will always lead to the same asset name
/proc/generate_asset_name(file)
return "asset.[md5(fcopy_rsc(file))]"
@@ -0,0 +1,50 @@
/// Process asset cache client topic calls for "asset_cache_confirm_arrival=[INT]"
/client/proc/asset_cache_confirm_arrival(job_id)
var/asset_cache_job = round(text2num(job_id))
//because we skip the limiter, we have to make sure this is a valid arrival and not somebody tricking us into letting them append to a list without limit.
if (asset_cache_job > 0 && asset_cache_job <= last_asset_job && !(completed_asset_jobs["[asset_cache_job]"]))
completed_asset_jobs["[asset_cache_job]"] = TRUE
last_completed_asset_job = max(last_completed_asset_job, asset_cache_job)
else
return asset_cache_job || TRUE
/// Process asset cache client topic calls for "asset_cache_preload_data=[HTML+JSON_STRING]
/client/proc/asset_cache_preload_data(data)
/*var/jsonend = findtextEx(data, "{{{ENDJSONDATA}}}")
if (!jsonend)
CRASH("invalid asset_cache_preload_data, no jsonendmarker")*/
//var/json = html_decode(copytext(data, 1, jsonend))
var/json = data
var/list/preloaded_assets = json_decode(json)
for (var/preloaded_asset in preloaded_assets)
if (copytext(preloaded_asset, findlasttext(preloaded_asset, ".")+1) in list("js", "jsm", "htm", "html"))
preloaded_assets -= preloaded_asset
continue
sent_assets |= preloaded_assets
/// Updates the client side stored html/json combo file used to keep track of what assets the client has between restarts/reconnects.
/client/proc/asset_cache_update_json(verify = FALSE, list/new_assets = list())
if (world.time - connection_time < 10 SECONDS) //don't override the existing data file on a new connection
return
if (!islist(new_assets))
new_assets = list("[new_assets]" = md5(SSassets.cache[new_assets]))
src << browse(json_encode(new_assets|sent_assets), "file=asset_data.json&display=0")
/// Blocks until all currently sending browser assets have been sent.
/// Due to byond limitations, this proc will sleep for 1 client round trip even if the client has no pending asset sends.
/// This proc will return an untrue value if it had to return before confirming the send, such as timeout or the client going away.
/client/proc/asset_flush(timeout = 50)
var/job = ++last_asset_job
var/t = 0
var/timeout_time = timeout
src << browse({"<script>window.location.href="?asset_cache_confirm_arrival=[job]"</script>"}, "window=asset_cache_browser&file=asset_cache_send_verify.htm")
while(!completed_asset_jobs["[job]"] && t < timeout_time) // Reception is handled in Topic()
stoplag(1) // Lock up the caller until this is received.
t++
if (t < timeout_time)
return TRUE
@@ -0,0 +1,21 @@
/**
* # asset_cache_item
*
* An internal datum containing info on items in the asset cache. Mainly used to cache md5 info for speed.
**/
/datum/asset_cache_item
var/name
var/md5
var/resource
/datum/asset_cache_item/New(name, file)
if (!isfile(file))
file = fcopy_rsc(file)
md5 = md5(file)
if (!md5)
md5 = md5(fcopy_rsc(file))
if (!md5)
CRASH("invalid asset sent to asset cache")
debug_world_log("asset cache unexpected success of second fcopy_rsc")
src.name = name
resource = file
+228
View File
@@ -0,0 +1,228 @@
//These datums are used to populate the asset cache, the proc "register()" does this.
//Place any asset datums you create in asset_list_items.dm
//all of our asset datums, used for referring to these later
GLOBAL_LIST_EMPTY(asset_datums)
//get an assetdatum or make a new one
/proc/get_asset_datum(type)
return GLOB.asset_datums[type] || new type()
/datum/asset
var/_abstract = /datum/asset
/datum/asset/New()
GLOB.asset_datums[type] = src
register()
/datum/asset/proc/register()
return
/datum/asset/proc/send(client)
return
//If you don't need anything complicated.
/datum/asset/simple
_abstract = /datum/asset/simple
var/assets = list()
/datum/asset/simple/register()
for(var/asset_name in assets)
register_asset(asset_name, assets[asset_name])
/datum/asset/simple/send(client)
. = send_asset_list(client, assets)
// For registering or sending multiple others at once
/datum/asset/group
_abstract = /datum/asset/group
var/list/children
/datum/asset/group/register()
for(var/type in children)
get_asset_datum(type)
/datum/asset/group/send(client/C)
for(var/type in children)
var/datum/asset/A = get_asset_datum(type)
. = A.send(C) || .
// spritesheet implementation - coalesces various icons into a single .png file
// and uses CSS to select icons out of that file - saves on transferring some
// 1400-odd individual PNG files
#define SPR_SIZE 1
#define SPR_IDX 2
#define SPRSZ_COUNT 1
#define SPRSZ_ICON 2
#define SPRSZ_STRIPPED 3
/datum/asset/spritesheet
_abstract = /datum/asset/spritesheet
var/name
var/list/sizes = list() // "32x32" -> list(10, icon/normal, icon/stripped)
var/list/sprites = list() // "foo_bar" -> list("32x32", 5)
/datum/asset/spritesheet/register()
if (!name)
CRASH("spritesheet [type] cannot register without a name")
ensure_stripped()
var/res_name = "spritesheet_[name].css"
var/fname = "data/spritesheets/[res_name]"
fdel(fname)
text2file(generate_css(), fname)
register_asset(res_name, fcopy_rsc(fname))
fdel(fname)
for(var/size_id in sizes)
var/size = sizes[size_id]
register_asset("[name]_[size_id].png", size[SPRSZ_STRIPPED])
/datum/asset/spritesheet/send(client/C)
if (!name)
return
var/all = list("spritesheet_[name].css")
for(var/size_id in sizes)
all += "[name]_[size_id].png"
. = send_asset_list(C, all)
/datum/asset/spritesheet/proc/ensure_stripped(sizes_to_strip = sizes)
for(var/size_id in sizes_to_strip)
var/size = sizes[size_id]
if (size[SPRSZ_STRIPPED])
continue
// save flattened version
var/fname = "data/spritesheets/[name]_[size_id].png"
fcopy(size[SPRSZ_ICON], fname)
var/error = rustg_dmi_strip_metadata(fname)
if(length(error))
stack_trace("Failed to strip [name]_[size_id].png: [error]")
size[SPRSZ_STRIPPED] = icon(fname)
fdel(fname)
/datum/asset/spritesheet/proc/generate_css()
var/list/out = list()
for (var/size_id in sizes)
var/size = sizes[size_id]
var/icon/tiny = size[SPRSZ_ICON]
out += ".[name][size_id]{display:inline-block;width:[tiny.Width()]px;height:[tiny.Height()]px;background:url('[name]_[size_id].png') no-repeat;}"
for (var/sprite_id in sprites)
var/sprite = sprites[sprite_id]
var/size_id = sprite[SPR_SIZE]
var/idx = sprite[SPR_IDX]
var/size = sizes[size_id]
var/icon/tiny = size[SPRSZ_ICON]
var/icon/big = size[SPRSZ_STRIPPED]
var/per_line = big.Width() / tiny.Width()
var/x = (idx % per_line) * tiny.Width()
var/y = round(idx / per_line) * tiny.Height()
out += ".[name][size_id].[sprite_id]{background-position:-[x]px -[y]px;}"
return out.Join("\n")
/datum/asset/spritesheet/proc/Insert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE)
I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving)
if (!I || !length(icon_states(I))) // that direction or state doesn't exist
return
var/size_id = "[I.Width()]x[I.Height()]"
var/size = sizes[size_id]
if (sprites[sprite_name])
CRASH("duplicate sprite \"[sprite_name]\" in sheet [name] ([type])")
if (size)
var/position = size[SPRSZ_COUNT]++
var/icon/sheet = size[SPRSZ_ICON]
size[SPRSZ_STRIPPED] = null
sheet.Insert(I, icon_state=sprite_name)
sprites[sprite_name] = list(size_id, position)
else
sizes[size_id] = size = list(1, I, null)
sprites[sprite_name] = list(size_id, 0)
/datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions)
if (length(prefix))
prefix = "[prefix]-"
if (!directions)
directions = list(SOUTH)
for (var/icon_state_name in icon_states(I))
for (var/direction in directions)
var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]-" : ""
Insert("[prefix][prefix2][icon_state_name]", I, icon_state=icon_state_name, dir=direction)
/datum/asset/spritesheet/proc/css_tag()
return {"<link rel="stylesheet" href="spritesheet_[name].css" />"}
/datum/asset/spritesheet/proc/icon_tag(sprite_name)
var/sprite = sprites[sprite_name]
if (!sprite)
return null
var/size_id = sprite[SPR_SIZE]
return {"<span class="[name][size_id] [sprite_name]"></span>"}
/datum/asset/spritesheet/proc/icon_class_name(sprite_name)
var/sprite = sprites[sprite_name]
if (!sprite)
return null
var/size_id = sprite[SPR_SIZE]
return {"[name][size_id] [sprite_name]"}
#undef SPR_SIZE
#undef SPR_IDX
#undef SPRSZ_COUNT
#undef SPRSZ_ICON
#undef SPRSZ_STRIPPED
/datum/asset/spritesheet/simple
_abstract = /datum/asset/spritesheet/simple
var/list/assets
/datum/asset/spritesheet/simple/register()
for (var/key in assets)
Insert(key, assets[key])
..()
//Generates assets based on iconstates of a single icon
/datum/asset/simple/icon_states
_abstract = /datum/asset/simple/icon_states
var/icon
var/list/directions = list(SOUTH)
var/frame = 1
var/movement_states = FALSE
var/prefix = "default" //asset_name = "[prefix].[icon_state_name].png"
var/generic_icon_names = FALSE //generate icon filenames using generate_asset_name() instead the above format
/datum/asset/simple/icon_states/register(_icon = icon)
for(var/icon_state_name in icon_states(_icon))
for(var/direction in directions)
var/asset = icon(_icon, icon_state_name, direction, frame, movement_states)
if (!asset)
continue
asset = fcopy_rsc(asset) //dedupe
var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]." : ""
var/asset_name = sanitize_filename("[prefix].[prefix2][icon_state_name].png")
if (generic_icon_names)
asset_name = "[generate_asset_name(asset)].png"
register_asset(asset_name, asset)
/datum/asset/simple/icon_states/multiple_icons
_abstract = /datum/asset/simple/icon_states/multiple_icons
var/list/icons
/datum/asset/simple/icon_states/multiple_icons/register()
for(var/i in icons)
..(i)
@@ -1,399 +1,22 @@
/*
Asset cache quick users guide:
Make a datum at the bottom of this file with your assets for your thing.
The simple subsystem will most like be of use for most cases.
Then call get_asset_datum() with the type of the datum you created and store the return
Then call .send(client) on that stored return value.
You can set verify to TRUE if you want send() to sleep until the client has the assets.
*/
// Amount of time(ds) MAX to send per asset, if this get exceeded we cancel the sleeping.
// This is doubled for the first asset, then added per asset after
#define ASSET_CACHE_SEND_TIMEOUT 7
//When sending mutiple assets, how many before we give the client a quaint little sending resources message
#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8
//When passively preloading assets, how many to send at once? Too high creates noticable lag where as too low can flood the client's cache with "verify" files
#define ASSET_CACHE_PRELOAD_CONCURRENT 3
/client
var/list/cache = list() // List of all assets sent to this client by the asset cache.
var/list/completed_asset_jobs = list() // List of all completed jobs, awaiting acknowledgement.
var/list/sending = list()
var/last_asset_job = 0 // Last job done.
//This proc sends the asset to the client, but only if it needs it.
//This proc blocks(sleeps) unless verify is set to false
/proc/send_asset(client/client, asset_name, verify = TRUE)
if(!istype(client))
if(ismob(client))
var/mob/M = client
if(M.client)
client = M.client
else
return 0
else
return 0
if(client.cache.Find(asset_name) || client.sending.Find(asset_name))
return 0
client << browse_rsc(SSassets.cache[asset_name], asset_name)
if(!verify)
client.cache += asset_name
return 1
client.sending |= asset_name
var/job = ++client.last_asset_job
client << browse({"
<script>
window.location.href="?asset_cache_confirm_arrival=[job]"
</script>
"}, "window=asset_cache_browser")
var/t = 0
var/timeout_time = (ASSET_CACHE_SEND_TIMEOUT * client.sending.len) + ASSET_CACHE_SEND_TIMEOUT
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
stoplag(1) // Lock up the caller until this is received.
t++
if(client)
client.sending -= asset_name
client.cache |= asset_name
client.completed_asset_jobs -= job
return 1
//This proc blocks(sleeps) unless verify is set to false
/proc/send_asset_list(client/client, list/asset_list, verify = TRUE)
if(!istype(client))
if(ismob(client))
var/mob/M = client
if(M.client)
client = M.client
else
return 0
else
return 0
var/list/unreceived = asset_list - (client.cache + client.sending)
if(!unreceived || !unreceived.len)
return 0
if (unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT)
to_chat(client, "Sending Resources...")
for(var/asset in unreceived)
if (asset in SSassets.cache)
client << browse_rsc(SSassets.cache[asset], asset)
if(!verify) // Can't access the asset cache browser, rip.
client.cache += unreceived
return 1
client.sending |= unreceived
var/job = ++client.last_asset_job
client << browse({"
<script>
window.location.href="?asset_cache_confirm_arrival=[job]"
</script>
"}, "window=asset_cache_browser")
var/t = 0
var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
stoplag(1) // Lock up the caller until this is received.
t++
if(client)
client.sending -= unreceived
client.cache |= unreceived
client.completed_asset_jobs -= job
return 1
//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start.
//The proc calls procs that sleep for long times.
/proc/getFilesSlow(client/client, list/files, register_asset = TRUE)
var/concurrent_tracker = 1
for(var/file in files)
if (!client)
break
if (register_asset)
register_asset(file, files[file])
if (concurrent_tracker >= ASSET_CACHE_PRELOAD_CONCURRENT)
concurrent_tracker = 1
send_asset(client, file)
else
concurrent_tracker++
send_asset(client, file, verify=FALSE)
stoplag(0) //queuing calls like this too quickly can cause issues in some client versions
//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
//if it's an icon or something be careful, you'll have to copy it before further use.
/proc/register_asset(asset_name, asset)
SSassets.cache[asset_name] = asset
//Generated names do not include file extention.
//Used mainly for code that deals with assets in a generic way
//The same asset will always lead to the same asset name
/proc/generate_asset_name(file)
return "asset.[md5(fcopy_rsc(file))]"
//These datums are used to populate the asset cache, the proc "register()" does this.
//all of our asset datums, used for referring to these later
GLOBAL_LIST_EMPTY(asset_datums)
//get an assetdatum or make a new one
/proc/get_asset_datum(type)
return GLOB.asset_datums[type] || new type()
/datum/asset
var/_abstract = /datum/asset
/datum/asset/New()
GLOB.asset_datums[type] = src
register()
/datum/asset/proc/register()
return
/datum/asset/proc/send(client)
return
//If you don't need anything complicated.
/datum/asset/simple
_abstract = /datum/asset/simple
var/assets = list()
var/verify = FALSE
/datum/asset/simple/register()
for(var/asset_name in assets)
register_asset(asset_name, assets[asset_name])
/datum/asset/simple/send(client)
send_asset_list(client,assets,verify)
// For registering or sending multiple others at once
/datum/asset/group
_abstract = /datum/asset/group
var/list/children
/datum/asset/group/register()
for(var/type in children)
get_asset_datum(type)
/datum/asset/group/send(client/C)
for(var/type in children)
var/datum/asset/A = get_asset_datum(type)
A.send(C)
// spritesheet implementation - coalesces various icons into a single .png file
// and uses CSS to select icons out of that file - saves on transferring some
// 1400-odd individual PNG files
#define SPR_SIZE 1
#define SPR_IDX 2
#define SPRSZ_COUNT 1
#define SPRSZ_ICON 2
#define SPRSZ_STRIPPED 3
/datum/asset/spritesheet
_abstract = /datum/asset/spritesheet
var/name
var/list/sizes = list() // "32x32" -> list(10, icon/normal, icon/stripped)
var/list/sprites = list() // "foo_bar" -> list("32x32", 5)
var/verify = FALSE
/datum/asset/spritesheet/register()
if (!name)
CRASH("spritesheet [type] cannot register without a name")
ensure_stripped()
var/res_name = "spritesheet_[name].css"
var/fname = "data/spritesheets/[res_name]"
fdel(fname)
text2file(generate_css(), fname)
register_asset(res_name, fcopy_rsc(fname))
fdel(fname)
for(var/size_id in sizes)
var/size = sizes[size_id]
register_asset("[name]_[size_id].png", size[SPRSZ_STRIPPED])
/datum/asset/spritesheet/send(client/C)
if (!name)
return
var/all = list("spritesheet_[name].css")
for(var/size_id in sizes)
all += "[name]_[size_id].png"
send_asset_list(C, all, verify)
/datum/asset/spritesheet/proc/ensure_stripped(sizes_to_strip = sizes)
for(var/size_id in sizes_to_strip)
var/size = sizes[size_id]
if (size[SPRSZ_STRIPPED])
continue
// save flattened version
var/fname = "data/spritesheets/[name]_[size_id].png"
fcopy(size[SPRSZ_ICON], fname)
var/error = rustg_dmi_strip_metadata(fname)
if(length(error))
stack_trace("Failed to strip [name]_[size_id].png: [error]")
size[SPRSZ_STRIPPED] = icon(fname)
fdel(fname)
/datum/asset/spritesheet/proc/generate_css()
var/list/out = list()
for (var/size_id in sizes)
var/size = sizes[size_id]
var/icon/tiny = size[SPRSZ_ICON]
out += ".[name][size_id]{display:inline-block;width:[tiny.Width()]px;height:[tiny.Height()]px;background:url('[name]_[size_id].png') no-repeat;}"
for (var/sprite_id in sprites)
var/sprite = sprites[sprite_id]
var/size_id = sprite[SPR_SIZE]
var/idx = sprite[SPR_IDX]
var/size = sizes[size_id]
var/icon/tiny = size[SPRSZ_ICON]
var/icon/big = size[SPRSZ_STRIPPED]
var/per_line = big.Width() / tiny.Width()
var/x = (idx % per_line) * tiny.Width()
var/y = round(idx / per_line) * tiny.Height()
out += ".[name][size_id].[sprite_id]{background-position:-[x]px -[y]px;}"
return out.Join("\n")
/datum/asset/spritesheet/proc/Insert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE)
I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving)
if (!I || !length(icon_states(I))) // that direction or state doesn't exist
return
var/size_id = "[I.Width()]x[I.Height()]"
var/size = sizes[size_id]
if (sprites[sprite_name])
CRASH("duplicate sprite \"[sprite_name]\" in sheet [name] ([type])")
if (size)
var/position = size[SPRSZ_COUNT]++
var/icon/sheet = size[SPRSZ_ICON]
size[SPRSZ_STRIPPED] = null
sheet.Insert(I, icon_state=sprite_name)
sprites[sprite_name] = list(size_id, position)
else
sizes[size_id] = size = list(1, I, null)
sprites[sprite_name] = list(size_id, 0)
/datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions)
if (length(prefix))
prefix = "[prefix]-"
if (!directions)
directions = list(SOUTH)
for (var/icon_state_name in icon_states(I))
for (var/direction in directions)
var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]-" : ""
Insert("[prefix][prefix2][icon_state_name]", I, icon_state=icon_state_name, dir=direction)
/datum/asset/spritesheet/proc/css_tag()
return {"<link rel="stylesheet" href="spritesheet_[name].css" />"}
/datum/asset/spritesheet/proc/icon_tag(sprite_name)
var/sprite = sprites[sprite_name]
if (!sprite)
return null
var/size_id = sprite[SPR_SIZE]
return {"<span class="[name][size_id] [sprite_name]"></span>"}
/datum/asset/spritesheet/proc/icon_class_name(sprite_name)
var/sprite = sprites[sprite_name]
if (!sprite)
return null
var/size_id = sprite[SPR_SIZE]
return {"[name][size_id] [sprite_name]"}
#undef SPR_SIZE
#undef SPR_IDX
#undef SPRSZ_COUNT
#undef SPRSZ_ICON
#undef SPRSZ_STRIPPED
/datum/asset/spritesheet/simple
_abstract = /datum/asset/spritesheet/simple
var/list/assets
/datum/asset/spritesheet/simple/register()
for (var/key in assets)
Insert(key, assets[key])
..()
//Generates assets based on iconstates of a single icon
/datum/asset/simple/icon_states
_abstract = /datum/asset/simple/icon_states
var/icon
var/list/directions = list(SOUTH)
var/frame = 1
var/movement_states = FALSE
var/prefix = "default" //asset_name = "[prefix].[icon_state_name].png"
var/generic_icon_names = FALSE //generate icon filenames using generate_asset_name() instead the above format
verify = FALSE
/datum/asset/simple/icon_states/register(_icon = icon)
for(var/icon_state_name in icon_states(_icon))
for(var/direction in directions)
var/asset = icon(_icon, icon_state_name, direction, frame, movement_states)
if (!asset)
continue
asset = fcopy_rsc(asset) //dedupe
var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]." : ""
var/asset_name = sanitize_filename("[prefix].[prefix2][icon_state_name].png")
if (generic_icon_names)
asset_name = "[generate_asset_name(asset)].png"
register_asset(asset_name, asset)
/datum/asset/simple/icon_states/multiple_icons
_abstract = /datum/asset/simple/icon_states/multiple_icons
var/list/icons
/datum/asset/simple/icon_states/multiple_icons/register()
for(var/i in icons)
..(i)
//DEFINITIONS FOR ASSET DATUMS START HERE.
/* uncomment this and delete the tgui def bellow this for the new tgui
/datum/asset/simple/tgui
assets = list(
// tgui
"tgui.bundle.js" = 'tgui/packages/tgui/public/tgui.bundle.js',
"tgui.bundle.css" = 'tgui/packages/tgui/public/tgui.bundle.css',
)
*/
/datum/asset/simple/tgui
assets = list(
// Old TGUI
"tgui.css" = 'tgui/assets/tgui.css',
"tgui.js" = 'tgui/assets/tgui.js',
// tgui-next
"tgui-main.html" = 'tgui-next/packages/tgui/public/tgui-main.html',
"tgui-fallback.html" = 'tgui-next/packages/tgui/public/tgui-fallback.html',
"tgui.bundle.js" = 'tgui-next/packages/tgui/public/tgui.bundle.js',
"tgui.bundle.css" = 'tgui-next/packages/tgui/public/tgui.bundle.css',
// Old TGUI compatability
"tgui-fallback.html" = 'tgui-next/packages/tgui/public/tgui-fallback.html',
"shim-html5shiv.js" = 'tgui-next/packages/tgui/public/shim-html5shiv.js',
"shim-ie8.js" = 'tgui-next/packages/tgui/public/shim-ie8.js',
"shim-dom4.js" = 'tgui-next/packages/tgui/public/shim-dom4.js',
@@ -434,8 +57,16 @@ GLOBAL_LIST_EMPTY(asset_datums)
"smmon_4.gif" = 'icons/program_icons/smmon_4.gif',
"smmon_5.gif" = 'icons/program_icons/smmon_5.gif',
"smmon_6.gif" = 'icons/program_icons/smmon_6.gif'
//"borg_mon.gif" = 'icons/program_icons/borg_mon.gif'
)
/* uncomment if you're porting the new ntnet app
/datum/asset/simple/radar_assets
assets = list(
"ntosradarbackground.png" = 'icons/UI_Icons/tgui/ntosradar_background.png',
"ntosradarpointer.png" = 'icons/UI_Icons/tgui/ntosradar_pointer.png',
"ntosradarpointerS.png" = 'icons/UI_Icons/tgui/ntosradar_pointer_S.png'
)
*/
/datum/asset/spritesheet/simple/pda
name = "pda"
assets = list(
@@ -464,6 +95,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
"refresh" = 'icons/pda_icons/pda_refresh.png',
"scanner" = 'icons/pda_icons/pda_scanner.png',
"signaler" = 'icons/pda_icons/pda_signaler.png',
//"skills" = 'icons/pda_icons/pda_skills.png',
"status" = 'icons/pda_icons/pda_status.png',
"dronephone" = 'icons/pda_icons/pda_dronephone.png'
)
@@ -482,51 +114,10 @@ GLOBAL_LIST_EMPTY(asset_datums)
"stamp-cap" = 'icons/stamp_icons/large_stamp-cap.png',
"stamp-qm" = 'icons/stamp_icons/large_stamp-qm.png',
"stamp-law" = 'icons/stamp_icons/large_stamp-law.png'
)
/datum/asset/spritesheet/simple/minesweeper
name = "minesweeper"
assets = list(
"1" = 'icons/UI_Icons/minesweeper_tiles/one.png',
"2" = 'icons/UI_Icons/minesweeper_tiles/two.png',
"3" = 'icons/UI_Icons/minesweeper_tiles/three.png',
"4" = 'icons/UI_Icons/minesweeper_tiles/four.png',
"5" = 'icons/UI_Icons/minesweeper_tiles/five.png',
"6" = 'icons/UI_Icons/minesweeper_tiles/six.png',
"7" = 'icons/UI_Icons/minesweeper_tiles/seven.png',
"8" = 'icons/UI_Icons/minesweeper_tiles/eight.png',
"empty" = 'icons/UI_Icons/minesweeper_tiles/empty.png',
"flag" = 'icons/UI_Icons/minesweeper_tiles/flag.png',
"hidden" = 'icons/UI_Icons/minesweeper_tiles/hidden.png',
"mine" = 'icons/UI_Icons/minesweeper_tiles/mine.png',
"minehit" = 'icons/UI_Icons/minesweeper_tiles/minehit.png'
)
/datum/asset/spritesheet/simple/pills
name = "pills"
assets = list(
"pill1" = 'icons/UI_Icons/Pills/pill1.png',
"pill2" = 'icons/UI_Icons/Pills/pill2.png',
"pill3" = 'icons/UI_Icons/Pills/pill3.png',
"pill4" = 'icons/UI_Icons/Pills/pill4.png',
"pill5" = 'icons/UI_Icons/Pills/pill5.png',
"pill6" = 'icons/UI_Icons/Pills/pill6.png',
"pill7" = 'icons/UI_Icons/Pills/pill7.png',
"pill8" = 'icons/UI_Icons/Pills/pill8.png',
"pill9" = 'icons/UI_Icons/Pills/pill9.png',
"pill10" = 'icons/UI_Icons/Pills/pill10.png',
"pill11" = 'icons/UI_Icons/Pills/pill11.png',
"pill12" = 'icons/UI_Icons/Pills/pill12.png',
"pill13" = 'icons/UI_Icons/Pills/pill13.png',
"pill14" = 'icons/UI_Icons/Pills/pill14.png',
"pill15" = 'icons/UI_Icons/Pills/pill15.png',
"pill16" = 'icons/UI_Icons/Pills/pill16.png',
"pill17" = 'icons/UI_Icons/Pills/pill17.png',
"pill18" = 'icons/UI_Icons/Pills/pill18.png',
"pill19" = 'icons/UI_Icons/Pills/pill19.png',
"pill20" = 'icons/UI_Icons/Pills/pill20.png',
"pill21" = 'icons/UI_Icons/Pills/pill21.png',
"pill22" = 'icons/UI_Icons/Pills/pill22.png',
//"stamp-chap" = 'icons/stamp_icons/large_stamp-chap.png',
//"stamp-mime" = 'icons/stamp_icons/large_stamp-mime.png',
//"stamp-centcom" = 'icons/stamp_icons/large_stamp-centcom.png',
//"stamp-syndicate" = 'icons/stamp_icons/large_stamp-syndicate.png'
)
/datum/asset/simple/IRV
@@ -572,23 +163,20 @@ GLOBAL_LIST_EMPTY(asset_datums)
)
/datum/asset/simple/jquery
verify = FALSE
assets = list(
"jquery.min.js" = 'code/modules/goonchat/browserassets/js/jquery.min.js',
)
/datum/asset/simple/goonchat
verify = FALSE
assets = list(
"json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js',
"browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js',
"browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css',
"browserOutput_dark.css" = 'code/modules/goonchat/browserassets/css/browserOutput_dark.css',
"browserOutput_dark.css" = 'code/modules/goonchat/browserassets/css/browserOutput_dark.css', //dark theme, cit specific
"browserOutput_light.css" = 'code/modules/goonchat/browserassets/css/browserOutput_light.css'
)
/datum/asset/simple/fontawesome
verify = FALSE
assets = list(
"fa-regular-400.eot" = 'html/font-awesome/webfonts/fa-regular-400.eot',
"fa-regular-400.woff" = 'html/font-awesome/webfonts/fa-regular-400.woff',
@@ -629,6 +217,90 @@ GLOBAL_LIST_EMPTY(asset_datums)
"none_button.png" = 'html/none_button.png',
)
/datum/asset/spritesheet/simple/minesweeper
name = "minesweeper"
assets = list(
"1" = 'icons/UI_Icons/minesweeper_tiles/one.png',
"2" = 'icons/UI_Icons/minesweeper_tiles/two.png',
"3" = 'icons/UI_Icons/minesweeper_tiles/three.png',
"4" = 'icons/UI_Icons/minesweeper_tiles/four.png',
"5" = 'icons/UI_Icons/minesweeper_tiles/five.png',
"6" = 'icons/UI_Icons/minesweeper_tiles/six.png',
"7" = 'icons/UI_Icons/minesweeper_tiles/seven.png',
"8" = 'icons/UI_Icons/minesweeper_tiles/eight.png',
"empty" = 'icons/UI_Icons/minesweeper_tiles/empty.png',
"flag" = 'icons/UI_Icons/minesweeper_tiles/flag.png',
"hidden" = 'icons/UI_Icons/minesweeper_tiles/hidden.png',
"mine" = 'icons/UI_Icons/minesweeper_tiles/mine.png',
"minehit" = 'icons/UI_Icons/minesweeper_tiles/minehit.png'
)
/* Port the app game thing
/datum/asset/simple/arcade
assets = list(
"boss1.gif" = 'icons/UI_Icons/Arcade/boss1.gif',
"boss2.gif" = 'icons/UI_Icons/Arcade/boss2.gif',
"boss3.gif" = 'icons/UI_Icons/Arcade/boss3.gif',
"boss4.gif" = 'icons/UI_Icons/Arcade/boss4.gif',
"boss5.gif" = 'icons/UI_Icons/Arcade/boss5.gif',
"boss6.gif" = 'icons/UI_Icons/Arcade/boss6.gif',
)
*/
/*
/datum/asset/spritesheet/simple/achievements
name ="achievements"
assets = list(
"default" = 'icons/UI_Icons/Achievements/default.png',
"basemisc" = 'icons/UI_Icons/Achievements/basemisc.png',
"baseboss" = 'icons/UI_Icons/Achievements/baseboss.png',
"baseskill" = 'icons/UI_Icons/Achievements/baseskill.png',
"bbgum" = 'icons/UI_Icons/Achievements/Boss/bbgum.png',
"colossus" = 'icons/UI_Icons/Achievements/Boss/colossus.png',
"hierophant" = 'icons/UI_Icons/Achievements/Boss/hierophant.png',
"legion" = 'icons/UI_Icons/Achievements/Boss/legion.png',
"miner" = 'icons/UI_Icons/Achievements/Boss/miner.png',
"swarmer" = 'icons/UI_Icons/Achievements/Boss/swarmer.png',
"tendril" = 'icons/UI_Icons/Achievements/Boss/tendril.png',
"featofstrength" = 'icons/UI_Icons/Achievements/Misc/featofstrength.png',
"helbital" = 'icons/UI_Icons/Achievements/Misc/helbital.png',
"jackpot" = 'icons/UI_Icons/Achievements/Misc/jackpot.png',
"meteors" = 'icons/UI_Icons/Achievements/Misc/meteors.png',
"timewaste" = 'icons/UI_Icons/Achievements/Misc/timewaste.png',
"upgrade" = 'icons/UI_Icons/Achievements/Misc/upgrade.png',
"clownking" = 'icons/UI_Icons/Achievements/Misc/clownking.png',
"clownthanks" = 'icons/UI_Icons/Achievements/Misc/clownthanks.png',
"rule8" = 'icons/UI_Icons/Achievements/Misc/rule8.png',
"snail" = 'icons/UI_Icons/Achievements/Misc/snail.png',
"mining" = 'icons/UI_Icons/Achievements/Skills/mining.png',
)
*/
/datum/asset/spritesheet/simple/pills
name ="pills"
assets = list(
"pill1" = 'icons/UI_Icons/Pills/pill1.png',
"pill2" = 'icons/UI_Icons/Pills/pill2.png',
"pill3" = 'icons/UI_Icons/Pills/pill3.png',
"pill4" = 'icons/UI_Icons/Pills/pill4.png',
"pill5" = 'icons/UI_Icons/Pills/pill5.png',
"pill6" = 'icons/UI_Icons/Pills/pill6.png',
"pill7" = 'icons/UI_Icons/Pills/pill7.png',
"pill8" = 'icons/UI_Icons/Pills/pill8.png',
"pill9" = 'icons/UI_Icons/Pills/pill9.png',
"pill10" = 'icons/UI_Icons/Pills/pill10.png',
"pill11" = 'icons/UI_Icons/Pills/pill11.png',
"pill12" = 'icons/UI_Icons/Pills/pill12.png',
"pill13" = 'icons/UI_Icons/Pills/pill13.png',
"pill14" = 'icons/UI_Icons/Pills/pill14.png',
"pill15" = 'icons/UI_Icons/Pills/pill15.png',
"pill16" = 'icons/UI_Icons/Pills/pill16.png',
"pill17" = 'icons/UI_Icons/Pills/pill17.png',
"pill18" = 'icons/UI_Icons/Pills/pill18.png',
"pill19" = 'icons/UI_Icons/Pills/pill19.png',
"pill20" = 'icons/UI_Icons/Pills/pill20.png',
"pill21" = 'icons/UI_Icons/Pills/pill21.png',
"pill22" = 'icons/UI_Icons/Pills/pill22.png',
)
//this exists purely to avoid meta by pre-loading all language icons.
/datum/asset/language/register()
for(var/path in typesof(/datum/language))
@@ -639,7 +311,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
/datum/asset/spritesheet/pipes
name = "pipes"
/datum/asset/spritesheet/pipes/register()
/datum/asset/spritesheet/pipes/register() //we do not have chempipes
for (var/each in list('icons/obj/atmospherics/pipes/pipe_item.dmi', 'icons/obj/atmospherics/pipes/disposal.dmi', 'icons/obj/atmospherics/pipes/transit_tube.dmi'))
InsertAll("", each, GLOB.alldirs)
..()
@@ -649,7 +321,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
name = "design"
/datum/asset/spritesheet/research_designs/register()
for (var/path in subtypesof(/datum/design))
for(var/path in subtypesof(/datum/design))
var/datum/design/D = path
var/icon_file
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
<script>
//this is used over window.location because window.location has a character limit in IE.
function sendbyond(text) {
var xhr = new XMLHttpRequest();
xhr.open('GET', '?'+text, true);
xhr.send(null);
}
var xhr = new XMLHttpRequest();
xhr.open('GET', 'asset_data.json', true);
xhr.responseType = 'text';
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
var status = xhr.status;
if (status >= 200 && status < 400) {
sendbyond('asset_cache_preload_data=' + encodeURIComponent(xhr.responseText));
}
}
};
xhr.send(null);
</script>
</body>
</html>
+8
View File
@@ -94,3 +94,11 @@
/// Messages currently seen by this client
var/list/seen_messages
// List of all asset filenames sent to this client by the asset cache, along with their assoicated md5s
var/list/sent_assets = list()
/// List of all completed blocking send jobs awaiting acknowledgement by send_asset
var/list/completed_asset_jobs = list()
/// Last asset send job id.
var/last_asset_job = 0
var/last_completed_asset_job = 0
+31 -22
View File
@@ -36,29 +36,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
if(!usr || usr != mob) //stops us calling Topic for somebody else's client. Also helps prevent usr=null
return
// asset_cache
var/asset_cache_job
if(href_list["asset_cache_confirm_arrival"])
var/job = text2num(href_list["asset_cache_confirm_arrival"])
//because we skip the limiter, we have to make sure this is a valid arrival and not somebody tricking us
// into letting append to a list without limit.
if (job && job <= last_asset_job && !(job in completed_asset_jobs))
completed_asset_jobs += job
asset_cache_job = asset_cache_confirm_arrival(href_list["asset_cache_confirm_arrival"])
if (!asset_cache_job)
return
else if (job in completed_asset_jobs) //byond bug ID:2256651
to_chat(src, "<span class='danger'>An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)</span>")
src << browse("...", "window=asset_cache_browser")
// Keypress passthrough
if(href_list["__keydown"])
var/keycode = browser_keycode_to_byond(href_list["__keydown"])
if(keycode)
keyDown(keycode)
return
if(href_list["__keyup"])
var/keycode = browser_keycode_to_byond(href_list["__keyup"])
if(keycode)
keyUp(keycode)
return
var/mtl = CONFIG_GET(number/minute_topic_limit)
if (!holder && mtl)
@@ -75,7 +57,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
topiclimiter[ADMINSWARNED_AT] = minute
msg += " Administrators have been informed."
log_game("[key_name(src)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
to_chat(src, "<span class='danger'>[msg]</span>")
return
@@ -96,6 +78,27 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
if(!(href_list["_src_"] == "chat" && href_list["proc"] == "ping" && LAZYLEN(href_list) == 2))
log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]")
//byond bug ID:2256651
if (asset_cache_job && (asset_cache_job in completed_asset_jobs))
to_chat(src, "<span class='danger'>An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)</span>")
src << browse("...", "window=asset_cache_browser")
return
if (href_list["asset_cache_preload_data"])
asset_cache_preload_data(href_list["asset_cache_preload_data"])
return
// Keypress passthrough
if(href_list["__keydown"])
var/keycode = browser_keycode_to_byond(href_list["__keydown"])
if(keycode)
keyDown(keycode)
return
if(href_list["__keyup"])
var/keycode = browser_keycode_to_byond(href_list["__keyup"])
if(keycode)
keyUp(keycode)
return
// Admin PM
if(href_list["priv_msg"])
cmd_admin_pm(href_list["priv_msg"],null)
@@ -830,8 +833,14 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
'html/browser/playeroptions.css',
)
spawn (10) //removing this spawn causes all clients to not get verbs.
//load info on what assets the client has
src << browse('code/modules/asset_cache/validate_assets.html', "window=asset_cache_browser")
//Precache the client with all other assets slowly, so as to not block other browse() calls
getFilesSlow(src, SSassets.preload, register_asset = FALSE)
addtimer(CALLBACK(GLOBAL_PROC, /proc/getFilesSlow, src, SSassets.preload, FALSE), 5 SECONDS)
#if (PRELOAD_RSC == 0)
for (var/name in GLOB.vox_sounds)
var/file = GLOB.vox_sounds[name]
+12
View File
@@ -0,0 +1,12 @@
/client/verb/show_station_minimap()
set category = "OOC"
set name = "Show Station Minimap"
set desc = "Shows a minimap of the currently loaded station map."
if(!CONFIG_GET(flag/minimaps_enabled))
to_chat(usr, "<span class='boldwarning'>Minimap generation is not enabled in the server's configuration.</span>")
return
if(!SSminimaps.station_minimap)
to_chat(usr, "<span class='boldwarning'>Minimap generation is in progress, please wait!</span>")
return
SSminimaps.station_minimap.show(src)
@@ -408,16 +408,12 @@ Contains:
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/miner
name = "inquisitor's hardsuit"
icon_state = "hardsuit-inq"
item_state = "hardsuit-inq"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/miner
armor = list("melee" = 70, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 60, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80)
slowdown = 1
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/miner
name = "inquisitor's helmet"
icon_state = "hardsuit0-inq"
item_state = "hardsuit0-inq"
armor = list("melee" = 70, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 60, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80)
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/miner
+2 -2
View File
@@ -53,8 +53,8 @@
/datum/reagent/carpet,
/datum/reagent/firefighting_foam,
/datum/reagent/consumable/tearjuice,
/datum/reagent/medicine/strange_reagent
/datum/reagent/medicine/strange_reagent,
/datum/reagent/medicine/copium
)
//needs to be chemid unit checked at some point
@@ -191,7 +191,7 @@
desc = "A synthetic chunk of meat."
icon_state = "meatproduct" //growing meat will make it look like a lumpo
foodtype = RAW | MEAT //hurr durr chemicals we're harmed in the production of this meat thus its non-vegan.
cooked_type = /obj/item/reagent_containers/food/snacks/meat/steak/meatproduct
cooked_type = /obj/item/reagent_containers/food/snacks/meat/steak/plain/meatproduct
/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct
name = "meat product"
@@ -280,7 +280,7 @@
bitesize = 4
tastes = list("meat" = 1, "wheat" = 1)
foodtype = GRAIN
cooked_type = /obj/item/reagent_containers/food/snacks/meat/steak/meatproduct
cooked_type = /obj/item/reagent_containers/food/snacks/meat/steak/plain/meatproduct
/obj/item/reagent_containers/food/snacks/meat/slab/gorilla
name = "gorilla meat"
@@ -340,7 +340,7 @@
/obj/item/reagent_containers/food/snacks/meat/steak/plain
foodtype = MEAT
/obj/item/reagent_containers/food/snacks/meat/steak/meatproduct
/obj/item/reagent_containers/food/snacks/meat/steak/plain/meatproduct
foodtype = MEAT
icon_state = "meatproduct_steak"
@@ -497,4 +497,4 @@
/obj/item/reagent_containers/food/snacks/meat/cutlet/chicken
name = "chicken cutlet"
tastes = list("chicken" = 1)
icon_state = "bird_cutlet_cooked"
icon_state = "bird_cutlet_cooked"
+188
View File
@@ -0,0 +1,188 @@
/datum/minimap
var/name = "minimap"
var/icon/overlay_icon
// The map icons
var/icon/map_icon
var/icon/meta_icon
var/list/color_area_names = list()
var/minx
var/maxx
var/miny
var/maxy
var/z_level
var/id = ""
/datum/minimap/New(z, x1 = 1, y1 = 1, x2 = world.maxx, y2 = world.maxy, name = "minimap")
if(!z)
CRASH("ERROR: new minimap requested without z level") //CRASH to halt the operatio
src.name = name
z_level = z
id = "[md5("[z_level]" + src.name + REF(src))]" //use it's own md5 as a special identifier
var/crop_x1 = x2
var/crop_x2 = x1
var/crop_y1 = y2
var/crop_y2 = y1
// do the generating
map_icon = new('html/blank.png')
meta_icon = new('html/blank.png')
map_icon.Scale(x2 - x1 + 1, y2 - y1 + 1) // arrays start at 1
meta_icon.Scale(x2 - x1 + 1, y2 - y1 + 1)
var/list/area_to_color = list()
for(var/turf/T in block(locate(x1, y1, z_level), locate(x2, y2, z_level)))
var/area/A = T.loc
var/img_x = T.x - x1 + 1 // arrays start at 1
var/img_y = T.y - y1 + 1
if(!istype(A, /area/space) || istype(T, /turf/closed/wall))
crop_x1 = min(crop_x1, T.x)
crop_x2 = max(crop_x2, T.x)
crop_y1 = min(crop_y1, T.y)
crop_y2 = max(crop_y2, T.y)
var/meta_color = area_to_color[A]
if(!meta_color)
meta_color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) // technically conflicts could happen but it's like very unlikely and it's not that big of a deal if one happens
area_to_color[A] = meta_color
color_area_names[meta_color] = A.name
meta_icon.DrawBox(meta_color, img_x, img_y)
if(istype(T, /turf/closed/wall))
map_icon.DrawBox("#000000", img_x, img_y)
else if(!istype(A, /area/space))
var/color = A.minimap_color || "#FF00FF"
if(locate(/obj/machinery/power/solar) in T)
color = "#02026a"
if((locate(/obj/effect/spawner/structure/window) in T) || (locate(/obj/structure/grille) in T))
color = BlendRGB(color, "#000000", 0.5)
map_icon.DrawBox(color, img_x, img_y)
map_icon.Crop(crop_x1, crop_y1, crop_x2, crop_y2)
meta_icon.Crop(crop_x1, crop_y1, crop_x2, crop_y2)
minx = crop_x1
maxx = crop_x2
miny = crop_y1
maxy = crop_y2
overlay_icon = new(map_icon)
overlay_icon.Scale(16, 16)
//we're done baking, now we ship it.
register_asset("minimap-[id].png", map_icon)
register_asset("minimap-[id]-meta.png", meta_icon)
/datum/minimap/proc/send(mob/user)
if(!id)
CRASH("ERROR: send called, but the minimap id is null/missing. ID: [id]")
send_asset_list(user, list("minimap-[id].png" = map_icon, "minimap-[id]-meta.png" = meta_icon))
/datum/minimap_group
var/list/minimaps = list()
var/static/next_id = 0
var/id
var/name
/datum/minimap_group/New(list/maps, name)
id = ++next_id
src.name = name
if(maps)
minimaps = maps
/datum/minimap_group/proc/show(mob/user)
if(!length(minimaps))
to_chat(user, "<span class='boldwarning'>ERROR: Attempted to access an empty datum/minimap_group. This should probably not happen.</span>")
return
var/list/datas = list()
var/list/info = list()
for(var/i in 1 to length(minimaps))// OLD: for(var/i in 1 to length(minimaps))
var/datum/minimap/M = minimaps[i]
M.send(user)
info += {"
<div class="block">
<div> <!-- The div is in here to fit it both in the block div -->
<img id='map-[i]' src='minimap-[M.id].png' />
<img id='map-[i]-meta' src='minimap-[M.id]-meta.png' style='display: none' />
</div>
<div class="statusDisplay" id='label-[i]'></div>
</div>
"}
datas += json_encode(M.color_area_names);
info = info.Join()
//this is bad. Too bad!
var/headerJS = {"
<script>
function hexify(num) {
if(!num){
num = 0;
}
num = num.toString(16);
if(num.length == 1){
num = "0" + num;
}
return num;
}
window.onload = function() {
var datas = \[[jointext(datas, ",")]]
if(!window.HTMLCanvasElement){
//something has gone horribly wrong!
return false
}
for(var i = 0; i < [length(minimaps)]; i++){
//the fuck is this wrapped?
var data = datas\[i];
var img = document.getElementById("map-" + (i + 1));
if(!img){
return; //if it does not exist, it means it's done!
}
var canvas = document.createElement("canvas");
canvas.width = img.width * 2;
canvas.height = img.height * 2;
var ctx = canvas.getContext('2d');
ctx.msImageSmoothingEnabled = false;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
img.parentNode.replaceChild(canvas, img);
ctx = document.createElement("canvas").getContext('2d');
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
ctx.drawImage(document.getElementById("map-" + (i+1) + "-meta"), 0, 0);
var imagedata = ctx.getImageData(0, 0, img.width, img.height);
var label = document.getElementById("label-" + (i+1));
canvas.onmousemove = function(e){
var rect = canvas.getBoundingClientRect();
var x = Math.floor(e.offsetX * img.width / rect.width);
var y = Math.floor(e.offsetY * img.height / rect.height);
var color_idx = x * 4 + (y * 4 * imagedata.width);
var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]);
label.textContent = data\[color];
canvas.title = data\[color];
}
canvas.onmouseout = function(e){
canvas.title = "";
}
}
}
</script>
<style>
img, canvas {
width: 100%;
background-color: white;
}
</style>
"}
var/datum/browser/popup = new(user, "minimap_[id]", name, 500, 700)
popup.add_head_content(headerJS) //set the head
popup.set_content(info)
var/datum/minimap/MICO = minimaps[1]
popup.set_title_image(MICO.overlay_icon)
popup.open(FALSE)
@@ -79,6 +79,10 @@
name = "Witch Wing"
icon_state = "witchwing"
/datum/sprite_accessory/moth_wings/bee
name = "Bee Wing"
icon_state = "bee"
/datum/sprite_accessory/moth_markings // the markings that moths can have. finally something other than the boring tan
icon = 'icons/mob/moth_markings.dmi'
color_src = null
@@ -141,4 +145,4 @@
/datum/sprite_accessory/moth_markings/witchwing
name = "Witch Wing"
icon_state = "witchwing"
icon_state = "witchwing"
+2
View File
@@ -873,6 +873,8 @@
return 0
if(digitalcamo || digitalinvis)
return 0
if(ismimic(src)) // Are we a mimic? Mimics should not be tracked to prevent AI camera cheese.
return 0
// Now, are they viewable by a camera? (This is last because it's the most intensive check)
if(!near_camera(src))
+1
View File
@@ -892,6 +892,7 @@
/mob/living/silicon/ai/revive(full_heal = 0, admin_revive = 0)
. = ..()
if(.) //successfully ressuscitated from death
set_eyeobj_visible(TRUE)
set_core_display_icon(display_icon_override)
/mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc)
@@ -18,6 +18,7 @@
update_canmove()
if(eyeobj)
eyeobj.setLoc(get_turf(src))
set_eyeobj_visible(FALSE)
GLOB.shuttle_caller_list -= src
SSshuttle.autoEvac()
@@ -6,6 +6,8 @@
/mob/camera/aiEye
name = "Inactive AI Eye"
icon_state = "ai_camera"
icon = 'icons/mob/cameramob.dmi'
invisibility = INVISIBILITY_MAXIMUM
hud_possible = list(ANTAG_HUD, AI_DETECT_HUD = HUD_LIST_LIST)
var/list/visibleCameraChunks = list()
@@ -158,11 +160,11 @@
cameraFollow = null
unset_machine()
if(!eyeobj || !eyeobj.loc || QDELETED(eyeobj))
if(isturf(loc) && (QDELETED(eyeobj) || !eyeobj.loc))
to_chat(src, "ERROR: Eyeobj not found. Creating new eye...")
create_eye()
eyeobj.setLoc(loc)
eyeobj?.setLoc(loc)
/mob/living/silicon/ai/proc/create_eye()
if(eyeobj)
@@ -172,6 +174,13 @@
eyeobj.ai = src
eyeobj.setLoc(loc)
eyeobj.name = "[name] (AI Eye)"
set_eyeobj_visible(TRUE)
/mob/living/silicon/ai/proc/set_eyeobj_visible(state = TRUE)
if(!eyeobj)
return
eyeobj.mouse_opacity = state ? MOUSE_OPACITY_ICON : initial(eyeobj.mouse_opacity)
eyeobj.invisibility = state ? INVISIBILITY_OBSERVER : initial(eyeobj.invisibility)
/mob/living/silicon/ai/verb/toggle_acceleration()
set category = "AI Commands"
+1 -1
View File
@@ -19,7 +19,7 @@
// messenging the client
malfhacked(malfhack)
if(!eyeobj || QDELETED(eyeobj) || !eyeobj.loc)
if(isturf(loc) && (QDELETED(eyeobj) || !eyeobj.loc))
view_core()
if(machine)
@@ -6,6 +6,7 @@
O.mode = 1
O.emotion = "Neutral"
O.update()
set_eyeobj_visible(TRUE)
if(multicam_on)
end_multicam()
view_core()
@@ -4,4 +4,5 @@
var/obj/machinery/status_display/ai/O = each
O.mode = 0
O.update()
set_eyeobj_visible(FALSE)
view_core()
@@ -120,6 +120,9 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
/mob/camera/aiEye/pic_in_pic
name = "Secondary AI Eye"
invisibility = INVISIBILITY_OBSERVER
mouse_opacity = MOUSE_OPACITY_ICON
icon_state = "ai_pip_camera"
var/obj/screen/movable/pic_in_pic/ai/screen
var/list/cameras_telegraphed = list()
var/telegraph_cameras = TRUE
@@ -21,6 +21,9 @@
locked = FALSE //unlock cover
if(connected_ai)
deployed = FALSE
update_canmove()
if(!QDELETED(builtInCamera) && builtInCamera.status)
builtInCamera.toggle_cam(src,0)
@@ -1232,7 +1232,6 @@
/mob/living/silicon/robot/proc/TryConnectToAI()
set_connected_ai(select_active_ai_with_fewest_borgs(z))
if(connected_ai)
connected_ai.connected_robots += src
lawsync()
lawupdate = 1
return TRUE
@@ -1270,4 +1269,4 @@
var/mob/living/silicon/ai/old_ai = .
old_ai.connected_robots -= src
if(connected_ai)
connected_ai.connected_robots |= src
connected_ai.connected_robots |= src
+8 -5
View File
@@ -1,8 +1,11 @@
/datum/asset/group/oui_theme_nano
children = list(
/datum/asset/simple/jquery,
/datum/asset/simple/oui_theme_nano
)
/datum/asset/simple/oui_theme_nano
assets = list(
// JavaScript
"sui-nano-common.js" = 'html/oracle_ui/themes/nano/sui-nano-common.js',
"sui-nano-jquery.min.js" = 'html/oracle_ui/themes/nano/sui-nano-jquery.min.js',
// Stylesheets
"sui-nano-common.css" = 'html/oracle_ui/themes/nano/sui-nano-common.css',
"sui-nano-common.js" = 'html/oracle_ui/themes/nano/sui-nano-common.js',
"sui-nano-common.css" = 'html/oracle_ui/themes/nano/sui-nano-common.css',
)
@@ -599,16 +599,22 @@
name = "Cybernetic Stomach"
desc = "A cybernetic stomach."
id = "cybernetic_stomach"
build_type = PROTOLATHE
materials = list(MAT_METAL = 500, MAT_GLASS = 500)
build_path = /obj/item/organ/stomach/cybernetic
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/cybernetic_stomach_u
name = "Upgraded Cybernetic Stomach"
desc = "An upgraded cybernetic stomach."
id = "cybernetic_stomach_u"
build_type = PROTOLATHE
construction_time = 50
materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 500)
build_path = /obj/item/organ/stomach/cybernetic/upgraded
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/cybernetic_tongue
name = "Cybernetic tongue"
@@ -1,8 +1,8 @@
//Xenobio control console
/mob/camera/aiEye/remote/xenobio
visible_icon = TRUE
icon = 'icons/obj/abductor.dmi'
icon_state = "camera_target"
icon = 'icons/mob/cameramob.dmi'
icon_state = "generic_camera"
var/allowed_area = null
/mob/camera/aiEye/remote/xenobio/Initialize()
@@ -78,8 +78,8 @@
eyeobj = new /mob/camera/aiEye/remote/xenobio(get_turf(src))
eyeobj.origin = src
eyeobj.visible_icon = TRUE
eyeobj.icon = 'icons/obj/abductor.dmi'
eyeobj.icon_state = "camera_target"
eyeobj.icon = 'icons/mob/cameramob.dmi'
eyeobj.icon_state = "generic_camera"
/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user)
..()
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

+16 -3
View File
@@ -292,6 +292,8 @@ var imageRetryDelay = 50;
var imageRetryLimit = 50;
var menu = document.querySelector('#menu');
var under_menu = document.querySelector('#under_menu');
var statcontentdiv = document.getElementById('statcontent');
var storedimages = [];
function createStatusTab(name) {
if(document.getElementById(name) || name.trim() == "")
@@ -796,15 +798,26 @@ function iconError(E) {
}
function draw_listedturf() {
var statcontentdiv = document.getElementById("statcontent");
statcontentdiv[textContentKey] = "";
var table = document.createElement("table");
for(var i = 0; i < turfcontents.length; i++) {
var part = turfcontents[i];
if(part[2]) {
if(storedimages[part[1]] == null && part[2]) {
var img = document.createElement("img");
img.src = part[2];
img[addEventListenerKey]("onerror", iconError());
img.id = part[1];
storedimages[part[1]] = part[2];
img.onerror = function() {
iconError();
};
table.appendChild(img);
} else {
var img = document.createElement("img");
img.onerror = function() {
iconError();
};
img.src = storedimages[part[1]];
img.id = part[1];
table.appendChild(img);
}
var b = document.createElement("div");
@@ -22,3 +22,8 @@
description = "<span class='warning'>I feel like I'm held together by flimsy string, and could fall apart at any moment!</span>\n"
mood_change = -4
timeout = 2 MINUTES
/datum/mood_event/copium
description = "<span class='nicegreen'>Things are going to be okay, right?</span>\n"
mood_change = 3
timeout = 3 MINUTES
@@ -6,6 +6,3 @@
nutriment_factor = 5 * REAGENTS_METABOLISM
metabolization_rate = 1 * REAGENTS_METABOLISM
taste_description = "sweetness"
/datum/reagent/consumable/alienhoney/on_mob_life(mob/living/carbon/M)
..()
@@ -0,0 +1,29 @@
/datum/reagent/medicine/copium
name = "copium"
description = "A heavy scented substance meant to help one deal with loss."
reagent_state = LIQUID
color = "#a8707e"
overdose_threshold = 21
metabolization_rate = 0.75 * REAGENTS_METABOLISM
pH = 4
/datum/reagent/medicine/copium/on_mob_life(mob/living/carbon/M)
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
if(mood.sanity <= SANITY_NEUTRAL && current_cycle >= 5)
mood.setSanity(min(mood.sanity+5, SANITY_NEUTRAL))
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "copium", /datum/mood_event/copium)
..()
/datum/reagent/medicine/copium/overdose_process(mob/living/carbon/M) //copious amounts of copium
M.blur_eyes(10)
if(prob(50))
M.adjustToxLoss(1, 0)
if(prob(5))
M.say(pick("That's okay. Things are going to be okay.", "This is fine.", "I'm okay with the events that are unfolding currently.", "World of Spacecraft is still a good game...", "I'm winning.", "Diesels are far more powerful."))
if(prob(5))
M.emote("me", 1, "seems to be crying.")
if(prob(4))
M.emote("me", 1, "falls over, crying.")
M.Knockdown(40)
//To-do: /datum/reagent/medicine/seethium
@@ -0,0 +1,6 @@
/datum/chemical_reaction/copium
name = "copium"
id = /datum/reagent/medicine/copium
results = list(/datum/reagent/medicine/copium = 5)
required_reagents = list(/datum/reagent/medicine/mannitol = 2, /datum/reagent/water = 1, /datum/reagent/medicine/epinephrine = 1, /datum/reagent/consumable/sugar = 1)
required_temp = 266
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB

After

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 430 KiB

After

Width:  |  Height:  |  Size: 430 KiB

+1
View File
@@ -80,6 +80,7 @@ window "mainwindow"
anchor2 = none
background-color = #272727
is-visible = false
auto-format = false
saved-params = ""
elem "tooltip"
type = BROWSER
+3374 -3365
View File
File diff suppressed because it is too large Load Diff