diff --git a/_maps/map_files/LayeniaStation/LayeniaStation.dmm b/_maps/map_files/LayeniaStation/LayeniaStation.dmm index 142e187b..56a6154a 100644 --- a/_maps/map_files/LayeniaStation/LayeniaStation.dmm +++ b/_maps/map_files/LayeniaStation/LayeniaStation.dmm @@ -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 diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 7a09f40c..96190e6d 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -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, diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 53119bfc..d994d515 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -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 diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 160151f1..22bdc0ff 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -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]") diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index e0d54c9e..ec59dd69 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -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) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 7bfd0ff1..291ed19c 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -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 "" 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 "" diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index 5354a6e0..0d370545 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -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) diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index 03d52cd9..600a4106 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -434,3 +434,5 @@ /datum/config_entry/flag/picture_logging_camera +/datum/config_entry/flag/minimaps_enabled + config_entry_value = TRUE diff --git a/code/controllers/subsystem/assets.dm b/code/controllers/subsystem/assets.dm index 7b6554bd..72852982 100644 --- a/code/controllers/subsystem/assets.dm +++ b/code/controllers/subsystem/assets.dm @@ -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) diff --git a/code/controllers/subsystem/minimaps.dm b/code/controllers/subsystem/minimaps.dm new file mode 100644 index 00000000..c25036a4 --- /dev/null +++ b/code/controllers/subsystem/minimaps.dm @@ -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, "Minimaps disabled! Skipping init.") + 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") diff --git a/code/datums/browser.dm b/code/datums/browser.dm index a43adbfc..f0d9b996 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -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, "The [title] browser you tried to open failed a sanity check! Please report this on github!") 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)) diff --git a/code/datums/components/lockon_aiming.dm b/code/datums/components/lockon_aiming.dm index 1cf42496..045611ab 100644 --- a/code/datums/components/lockon_aiming.dm +++ b/code/datums/components/lockon_aiming.dm @@ -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 diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 142d38db..1a61d189 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -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 diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 5661ad71..f89d5e87 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -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() diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 66fe2c9f..3f4ff87d 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -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() diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index ad563635..320dff0d 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -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) ..() diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 0c87ca84..4025aa71 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -256,7 +256,7 @@ user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") if(12) if(diff==FORWARD) - user.visible_message("[user] secures [I].", "You secure [I].") + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") else user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") if(13) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index d415e230..dba5bd75 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -72,6 +72,9 @@ /turf/open/space/Assimilate_Air() return +/turf/open/space/remove_air(amount) + return null + /turf/open/space/proc/update_starlight() if(CONFIG_GET(flag/starlight)) for(var/t in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm diff --git a/code/game/world.dm b/code/game/world.dm index 5bd39779..8ef4d371 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -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" diff --git a/code/modules/antagonists/abductor/machinery/camera.dm b/code/modules/antagonists/abductor/machinery/camera.dm index 00e48cb1..9e0a2b46 100644 --- a/code/modules/antagonists/abductor/machinery/camera.dm +++ b/code/modules/antagonists/abductor/machinery/camera.dm @@ -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) ..() diff --git a/code/modules/antagonists/blob/blob/overmind.dm b/code/modules/antagonists/blob/blob/overmind.dm index 57ae1d4c..8bcf019a 100644 --- a/code/modules/antagonists/blob/blob/overmind.dm +++ b/code/modules/antagonists/blob/blob/overmind.dm @@ -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 diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm index 9be21053..9c1f8720 100644 --- a/code/modules/antagonists/disease/disease_mob.dm +++ b/code/modules/antagonists/disease/disease_mob.dm @@ -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 diff --git a/code/modules/asset_cache/asset_cache.dm b/code/modules/asset_cache/asset_cache.dm new file mode 100644 index 00000000..7a12e5e9 --- /dev/null +++ b/code/modules/asset_cache/asset_cache.dm @@ -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))]" diff --git a/code/modules/asset_cache/asset_cache_client.dm b/code/modules/asset_cache/asset_cache_client.dm new file mode 100644 index 00000000..f9b3752b --- /dev/null +++ b/code/modules/asset_cache/asset_cache_client.dm @@ -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({""}, "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 diff --git a/code/modules/asset_cache/asset_cache_item.dm b/code/modules/asset_cache/asset_cache_item.dm new file mode 100644 index 00000000..0e7d44a7 --- /dev/null +++ b/code/modules/asset_cache/asset_cache_item.dm @@ -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 diff --git a/code/modules/asset_cache/asset_list.dm b/code/modules/asset_cache/asset_list.dm new file mode 100644 index 00000000..fe9859f2 --- /dev/null +++ b/code/modules/asset_cache/asset_list.dm @@ -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 {""} + +/datum/asset/spritesheet/proc/icon_tag(sprite_name) + var/sprite = sprites[sprite_name] + if (!sprite) + return null + var/size_id = sprite[SPR_SIZE] + return {""} + +/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) diff --git a/code/modules/client/asset_cache.dm b/code/modules/asset_cache/asset_list_items.dm similarity index 51% rename from code/modules/client/asset_cache.dm rename to code/modules/asset_cache/asset_list_items.dm index 959f2baa..f38c40dc 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -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({" - - "}, "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({" - - "}, "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 {""} - -/datum/asset/spritesheet/proc/icon_tag(sprite_name) - var/sprite = sprites[sprite_name] - if (!sprite) - return null - var/size_id = sprite[SPR_SIZE] - return {""} - -/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 diff --git a/code/modules/asset_cache/validate_assets.html b/code/modules/asset_cache/validate_assets.html new file mode 100644 index 00000000..205a7f4d --- /dev/null +++ b/code/modules/asset_cache/validate_assets.html @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 792e40ad..00a6e281 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -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 diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 69c52c91..96ba948b 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -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, "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)") - 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, "[msg]") 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, "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)") + 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] diff --git a/code/modules/client/verbs/minimap.dm b/code/modules/client/verbs/minimap.dm new file mode 100644 index 00000000..3cdb1d57 --- /dev/null +++ b/code/modules/client/verbs/minimap.dm @@ -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, "Minimap generation is not enabled in the server's configuration.") + return + if(!SSminimaps.station_minimap) + to_chat(usr, "Minimap generation is in progress, please wait!") + return + SSminimaps.station_minimap.show(src) diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index d2423a3f..dd91258f 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -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 diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index 6ec2865f..91c7204c 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -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 diff --git a/code/modules/food_and_drinks/food/snacks/meat.dm b/code/modules/food_and_drinks/food/snacks/meat.dm index 8fa96603..c4e63937 100644 --- a/code/modules/food_and_drinks/food/snacks/meat.dm +++ b/code/modules/food_and_drinks/food/snacks/meat.dm @@ -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" \ No newline at end of file + icon_state = "bird_cutlet_cooked" diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index 27ee5481..6bf7fb49 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -46,7 +46,8 @@ God bless America. /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/food/condiment, /obj/item/storage/part_replacer, - /obj/item/his_grace)) + /obj/item/his_grace, + /obj/item/portallight)) var/datum/looping_sound/deep_fryer/fry_loop /obj/machinery/deepfryer/Initialize() diff --git a/code/modules/mapping/minimaps.dm b/code/modules/mapping/minimaps.dm new file mode 100644 index 00000000..7a62e9ab --- /dev/null +++ b/code/modules/mapping/minimaps.dm @@ -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, "ERROR: Attempted to access an empty datum/minimap_group. This should probably not happen.") + 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 += {" +
+
+ + +
+
+
+ "} + datas += json_encode(M.color_area_names); + + info = info.Join() + //this is bad. Too bad! + var/headerJS = {" + + + "} + + 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) diff --git a/code/modules/mob/dead/new_player/sprite_accessories/moth_wings.dm b/code/modules/mob/dead/new_player/sprite_accessories/moth_wings.dm index f21dd5f5..1bb01d6c 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/moth_wings.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/moth_wings.dm @@ -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" \ No newline at end of file + icon_state = "witchwing" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 5b8bf4bc..c36aa535 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -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)) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 04d241d2..8e7ebc06 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -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) diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index 3804bfe5..8864abd6 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -18,6 +18,7 @@ update_canmove() if(eyeobj) eyeobj.setLoc(get_turf(src)) + set_eyeobj_visible(FALSE) GLOB.shuttle_caller_list -= src SSshuttle.autoEvac() diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index e5484a3c..7477ba77 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -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" diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 0fd33110..15a04235 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -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) diff --git a/code/modules/mob/living/silicon/ai/login.dm b/code/modules/mob/living/silicon/ai/login.dm index 742edfc5..98f38652 100644 --- a/code/modules/mob/living/silicon/ai/login.dm +++ b/code/modules/mob/living/silicon/ai/login.dm @@ -6,6 +6,7 @@ O.mode = 1 O.emotion = "Neutral" O.update() + set_eyeobj_visible(TRUE) if(multicam_on) end_multicam() view_core() diff --git a/code/modules/mob/living/silicon/ai/logout.dm b/code/modules/mob/living/silicon/ai/logout.dm index 7989d1c1..73161f12 100644 --- a/code/modules/mob/living/silicon/ai/logout.dm +++ b/code/modules/mob/living/silicon/ai/logout.dm @@ -4,4 +4,5 @@ var/obj/machinery/status_display/ai/O = each O.mode = 0 O.update() + set_eyeobj_visible(FALSE) view_core() diff --git a/code/modules/mob/living/silicon/ai/multicam.dm b/code/modules/mob/living/silicon/ai/multicam.dm index fcc068b7..b358cefd 100644 --- a/code/modules/mob/living/silicon/ai/multicam.dm +++ b/code/modules/mob/living/silicon/ai/multicam.dm @@ -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 diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index 23531e9f..25519842 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -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) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index f75607df..972bf29c 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -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 \ No newline at end of file + connected_ai.connected_robots |= src diff --git a/code/modules/oracle_ui/assets.dm b/code/modules/oracle_ui/assets.dm index 5d26d80a..348860b4 100644 --- a/code/modules/oracle_ui/assets.dm +++ b/code/modules/oracle_ui/assets.dm @@ -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', ) diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 2d276cfb..b3831106 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -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" diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 04cf006e..d0a924ee 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -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() @@ -80,8 +80,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) ..() diff --git a/html/blank.png b/html/blank.png new file mode 100644 index 00000000..86c96304 Binary files /dev/null and b/html/blank.png differ diff --git a/html/statbrowser.html b/html/statbrowser.html index f293891a..b59b98db 100644 --- a/html/statbrowser.html +++ b/html/statbrowser.html @@ -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"); diff --git a/hyperstation/code/datums/mood_events/events.dm b/hyperstation/code/datums/mood_events/events.dm index 5c58d9ab..b61bff1c 100644 --- a/hyperstation/code/datums/mood_events/events.dm +++ b/hyperstation/code/datums/mood_events/events.dm @@ -22,3 +22,8 @@ description = "I feel like I'm held together by flimsy string, and could fall apart at any moment!\n" mood_change = -4 timeout = 2 MINUTES + +/datum/mood_event/copium + description = "Things are going to be okay, right?\n" + mood_change = 3 + timeout = 3 MINUTES diff --git a/hyperstation/code/modules/reagents/chemistry/reagents/food_reagents.dm b/hyperstation/code/modules/reagents/chemistry/reagents/food_reagents.dm index e5a052d1..d8cda7c0 100644 --- a/hyperstation/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/hyperstation/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -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) - ..() \ No newline at end of file diff --git a/hyperstation/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/hyperstation/code/modules/reagents/chemistry/reagents/medicine_reagents.dm new file mode 100644 index 00000000..3db0e93f --- /dev/null +++ b/hyperstation/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -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 diff --git a/hyperstation/code/modules/reagents/chemistry/recipes/medicine.dm b/hyperstation/code/modules/reagents/chemistry/recipes/medicine.dm new file mode 100644 index 00000000..7a542dc5 --- /dev/null +++ b/hyperstation/code/modules/reagents/chemistry/recipes/medicine.dm @@ -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 diff --git a/hyperstation/code/obj/fleshlight.dm b/hyperstation/code/obj/fleshlight.dm index 7ba5421d..19aff71e 100644 --- a/hyperstation/code/obj/fleshlight.dm +++ b/hyperstation/code/obj/fleshlight.dm @@ -164,6 +164,13 @@ C.adjustArousalLoss(20) M.adjustArousalLoss(20) M.do_jitter_animation() //make your partner shake too! + + if (M.getArousalLoss() >= 100 && ishuman(M) && prob(5))//Why not have a probability to cum when someone's getting nailed with max arousal?~ + if(V.is_exposed()) //Oh yea, if vagina is not exposed, the climax will not cause a spill + M.mob_climax_outside(V, spillage = TRUE) + else + M.mob_climax_outside(V, spillage = FALSE) + if (C.getArousalLoss() >= 100 && ishuman(C) && C.has_dna()) var/mob/living/carbon/human/O = C diff --git a/icons/mob/blob.dmi b/icons/mob/blob.dmi index 115629dd..6964160c 100644 Binary files a/icons/mob/blob.dmi and b/icons/mob/blob.dmi differ diff --git a/icons/mob/cameramob.dmi b/icons/mob/cameramob.dmi new file mode 100644 index 00000000..a35d6c37 Binary files /dev/null and b/icons/mob/cameramob.dmi differ diff --git a/icons/mob/suit_digi.dmi b/icons/mob/suit_digi.dmi index cfe1617e..88c30722 100644 Binary files a/icons/mob/suit_digi.dmi and b/icons/mob/suit_digi.dmi differ diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi index b5dc7e00..75f84347 100644 Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ diff --git a/modular_citadel/code/modules/arousal/arousal.dm b/modular_citadel/code/modules/arousal/arousal.dm index 8c5bf255..beb5f8b9 100644 --- a/modular_citadel/code/modules/arousal/arousal.dm +++ b/modular_citadel/code/modules/arousal/arousal.dm @@ -284,7 +284,7 @@ setArousalLoss(min_arousal) -/mob/living/carbon/human/proc/mob_climax_outside(obj/item/organ/genital/G, mb_time = 30) //This is used for forced orgasms and other hands-free climaxes +/mob/living/carbon/human/proc/mob_climax_outside(obj/item/organ/genital/G, mb_time = 30, spillage = TRUE) //This is used for forced orgasms and other hands-free climaxes var/total_fluids = 0 var/datum/reagents/fluid_source = null var/unable_to_come = FALSE @@ -310,12 +310,18 @@ "You feel yourself about to orgasm.", \ "You feel yourself about to orgasm.") if(do_after(src, mb_time, target = src)) - if(total_fluids > 5) - fluid_source.reaction(src.loc, TOUCH, 1, 0) - fluid_source.clear_reagents() - src.visible_message("[src] orgasms[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""], using [p_their()] [G.name]!", \ - "You climax[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""] with your [G.name].", \ - "You climax using your [G.name].") + if(spillage) + if(total_fluids > 5) + fluid_source.reaction(src.loc, TOUCH, 1, 0) + fluid_source.clear_reagents() + src.visible_message("[src] orgasms[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""], with [p_their()] [G.name]!", \ + "You climax[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""] with your [G.name].", \ + "You climax using your [G.name].") + else //Else from spillage check, also note subtle text change + src.visible_message("[src] orgasms with [p_their()] [G.name]!", \ + "You climax with your [G.name].", \ + "You climax using your [G.name].") + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) if(G.can_climax) setArousalLoss(min_arousal) @@ -420,7 +426,7 @@ src.visible_message("[src] climaxes with someone, using [p_their()] [G.name]!", \ "You ejaculate with someone, using your [G.name].", \ "You have climaxed inside someone, using your [G.name].") - to_chat(L, "You feel someone ejeculate inside you.") + to_chat(L, "You feel someone ejaculate inside you.") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) diff --git a/modular_citadel/icons/mob/suit_digi.dmi b/modular_citadel/icons/mob/suit_digi.dmi index f3edd3c2..fb2ba77f 100644 Binary files a/modular_citadel/icons/mob/suit_digi.dmi and b/modular_citadel/icons/mob/suit_digi.dmi differ diff --git a/modular_citadel/interface/skin.dmf b/modular_citadel/interface/skin.dmf index 9fa01387..28a498a8 100644 --- a/modular_citadel/interface/skin.dmf +++ b/modular_citadel/interface/skin.dmf @@ -80,6 +80,7 @@ window "mainwindow" anchor2 = none background-color = #272727 is-visible = false + auto-format = false saved-params = "" elem "tooltip" type = BROWSER diff --git a/tgstation.dme b/tgstation.dme index 64aa43da..c95472b0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1,4 +1,3 @@ - // DM Environment file for tgstation.dme. // All manual changes should be made outside the BEGIN_ and END_ blocks. // New source code should be placed in .dm files: choose File/New --> Code File. @@ -261,6 +260,7 @@ #include "code\controllers\subsystem\machines.dm" #include "code\controllers\subsystem\mapping.dm" #include "code\controllers\subsystem\medals.dm" +#include "code\controllers\subsystem\minimaps.dm" #include "code\controllers\subsystem\minor_mapping.dm" #include "code\controllers\subsystem\mobs.dm" #include "code\controllers\subsystem\moods.dm" @@ -1444,6 +1444,11 @@ #include "code\modules\assembly\signaler.dm" #include "code\modules\assembly\timer.dm" #include "code\modules\assembly\voice.dm" +#include "code\modules\asset_cache\asset_cache.dm" +#include "code\modules\asset_cache\asset_cache_client.dm" +#include "code\modules\asset_cache\asset_cache_item.dm" +#include "code\modules\asset_cache\asset_list.dm" +#include "code\modules\asset_cache\asset_list_items.dm" #include "code\modules\atmospherics\multiz.dm" #include "code\modules\atmospherics\environmental\LINDA_fire.dm" #include "code\modules\atmospherics\environmental\LINDA_system.dm" @@ -1587,7 +1592,6 @@ #include "code\modules\cargo\packs\security.dm" #include "code\modules\cargo\packs\service.dm" #include "code\modules\chatter\chatter.dm" -#include "code\modules\client\asset_cache.dm" #include "code\modules\client\client_colour.dm" #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" @@ -1601,6 +1605,7 @@ #include "code\modules\client\verbs\aooc.dm" #include "code\modules\client\verbs\etips.dm" #include "code\modules\client\verbs\looc.dm" +#include "code\modules\client\verbs\minimap.dm" #include "code\modules\client\verbs\ooc.dm" #include "code\modules\client\verbs\ping.dm" #include "code\modules\client\verbs\suicide.dm" @@ -1984,6 +1989,7 @@ #include "code\modules\lighting\lighting_turf.dm" #include "code\modules\mapping\dmm_suite.dm" #include "code\modules\mapping\map_template.dm" +#include "code\modules\mapping\minimaps.dm" #include "code\modules\mapping\preloader.dm" #include "code\modules\mapping\reader.dm" #include "code\modules\mapping\ruins.dm" @@ -3118,7 +3124,9 @@ #include "hyperstation\code\modules\power\reactor\rbmk.dm" #include "hyperstation\code\modules\power\reactor\reactor_cargo.dm" #include "hyperstation\code\modules\reagents\chemistry\reagents\food_reagents.dm" +#include "hyperstation\code\modules\reagents\chemistry\reagents\medicine_reagents.dm" #include "hyperstation\code\modules\reagents\chemistry\reagents\hydroponics_reactions.dm" +#include "hyperstation\code\modules\reagents\chemistry\recipes\medicine.dm" #include "hyperstation\code\modules\resize\resize_action.dm" #include "hyperstation\code\modules\resize\resizing.dm" #include "hyperstation\code\modules\resize\sizechems.dm" @@ -3367,4 +3375,4 @@ #include "modular_citadel\code\modules\vore\eating\vorepanel_vr.dm" #include "modular_citadel\interface\skin.dmf" #include "yogstation\code\modules\power\energyharvester.dm" -// END_INCLUDE +// END_INCLUDE \ No newline at end of file