diff --git a/_maps/shuttles/emergency_nature.dmm b/_maps/shuttles/emergency_nature.dmm
new file mode 100644
index 0000000000..9639e37852
--- /dev/null
+++ b/_maps/shuttles/emergency_nature.dmm
@@ -0,0 +1,2040 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"as" = (
+/obj/structure/flora/ausbushes/lavendergrass,
+/obj/structure/flora/ausbushes/sparsegrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"au" = (
+/obj/structure/sink/puddle,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"ay" = (
+/obj/structure/flora/ausbushes/leafybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"aA" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 6
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"aJ" = (
+/obj/structure/flora/ausbushes/stalkybush,
+/obj/structure/flora/ausbushes/fullgrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"bd" = (
+/obj/structure/flora/rock/pile/largejungle,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"bg" = (
+/obj/structure/table/reinforced,
+/obj/item/storage/toolbox/mechanical{
+ pixel_y = 8;
+ pixel_x = -2
+ },
+/obj/item/storage/toolbox/electrical,
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"bS" = (
+/obj/structure/table/reinforced,
+/obj/item/storage/box/lights/mixed{
+ pixel_y = 9;
+ pixel_x = -5
+ },
+/obj/item/storage/box/matches{
+ pixel_y = 5
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 10
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"cm" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/machinery/portable_atmospherics/canister/oxygen,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"cL" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 3
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"cR" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 5
+ },
+/obj/structure/sign/warning/nosmoking{
+ pixel_y = 32
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"cZ" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 1
+ },
+/obj/machinery/computer/emergency_shuttle,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"dj" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 3
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/obj/item/radio/intercom{
+ name = "Station Intercom (General)";
+ pixel_y = -31
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"dP" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_y = 30
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"dT" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/turf/open/floor/plating{
+ icon_state = "platingdmg3"
+ },
+/area/shuttle/escape)
+"eq" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/plating{
+ icon_state = "platingdmg1"
+ },
+/area/shuttle/escape)
+"ev" = (
+/obj/effect/turf_decal/trimline/green/filled/corner,
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 4
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"ex" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 6
+ },
+/obj/structure/flora/ausbushes/leafybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"eB" = (
+/obj/item/rack_parts,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/corner{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"eS" = (
+/obj/effect/turf_decal/trimline/red/filled/end{
+ dir = 1
+ },
+/obj/structure/table/reinforced,
+/obj/machinery/recharger,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"eY" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 9
+ },
+/obj/structure/table/reinforced,
+/obj/item/storage/toolbox/emergency{
+ pixel_y = 3
+ },
+/obj/machinery/light{
+ dir = 8
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"fD" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 1
+ },
+/obj/machinery/computer/security,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"fG" = (
+/obj/structure/flora/ausbushes/fullgrass,
+/obj/structure/flora/ausbushes/genericbush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"fJ" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 1
+ },
+/obj/machinery/computer/communications,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"fT" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 10
+ },
+/obj/machinery/door/window/westleft{
+ name = "Infirmary"
+ },
+/turf/open/floor/plasteel{
+ dir = 1
+ },
+/area/shuttle/escape)
+"gg" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 1
+ },
+/obj/structure/chair/comfy/shuttle,
+/obj/item/radio/intercom{
+ dir = 4;
+ name = "Station Intercom (General)";
+ pixel_y = 27
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"gj" = (
+/obj/machinery/door/airlock/maintenance_hatch,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"gl" = (
+/obj/structure/flora/junglebush/large,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"gu" = (
+/obj/structure/shuttle/engine/propulsion,
+/turf/open/floor/plating/airless,
+/area/shuttle/escape)
+"gx" = (
+/turf/open/floor/plating/airless,
+/area/shuttle/escape)
+"gI" = (
+/obj/item/shovel,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"gM" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 5
+ },
+/obj/structure/table/reinforced,
+/obj/item/storage/fancy/donut_box,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"gR" = (
+/obj/effect/turf_decal/weather/dirt,
+/obj/machinery/hydroponics/soil,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"ht" = (
+/obj/effect/turf_decal/trimline/red/filled/line{
+ dir = 9
+ },
+/obj/structure/chair/comfy/shuttle,
+/obj/machinery/light{
+ dir = 8
+ },
+/obj/structure/reagent_dispensers/peppertank{
+ pixel_y = 28
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"hC" = (
+/obj/effect/turf_decal/trimline/red/filled/corner{
+ dir = 1
+ },
+/obj/effect/turf_decal/trimline/red/filled/line{
+ dir = 4
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 8
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"hJ" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 8
+ },
+/obj/structure/table/reinforced,
+/obj/item/storage/box/monkeycubes{
+ pixel_x = 6;
+ pixel_y = 5
+ },
+/obj/item/storage/box/monkeycubes{
+ pixel_x = -6;
+ pixel_y = 2
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"ib" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 4
+ },
+/obj/structure/flora/ausbushes/fullgrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"it" = (
+/mob/living/carbon/monkey,
+/obj/structure/flora/grass/jungle/b{
+ icon_state = "bushb3"
+ },
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"iD" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 5
+ },
+/obj/structure/table/reinforced,
+/obj/item/restraints/handcuffs{
+ pixel_y = 3
+ },
+/obj/machinery/light{
+ dir = 1
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"iF" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 8
+ },
+/obj/structure/flora/ausbushes/brflowers,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"iO" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/machinery/space_heater,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"iV" = (
+/obj/effect/decal/cleanable/robot_debris,
+/obj/effect/turf_decal/stripes/corner{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"jO" = (
+/obj/structure/table/reinforced,
+/obj/item/storage/box/stockparts{
+ pixel_y = 7
+ },
+/obj/effect/turf_decal/stripes/line,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"jX" = (
+/obj/effect/turf_decal/trimline/red/filled/line{
+ dir = 9
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 4
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"jZ" = (
+/obj/effect/turf_decal/trimline/red/filled/corner{
+ dir = 1
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"ke" = (
+/obj/item/shovel/spade,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"ku" = (
+/obj/effect/turf_decal/trimline/blue/filled/corner{
+ dir = 4
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"lo" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 8
+ },
+/obj/structure/flora/ausbushes/leafybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"lH" = (
+/obj/structure/reagent_dispensers/fueltank,
+/obj/effect/turf_decal/stripes/end{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"lN" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/structure/grille/broken,
+/turf/open/floor/plating{
+ icon_state = "panelscorched"
+ },
+/area/shuttle/escape)
+"lS" = (
+/obj/effect/turf_decal/trimline/red/filled/line{
+ dir = 4
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 8
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"lT" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 8
+ },
+/obj/structure/table/reinforced,
+/obj/item/cigbutt{
+ pixel_x = 8
+ },
+/obj/machinery/recharger,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"lV" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 5
+ },
+/obj/structure/table/glass,
+/obj/item/reagent_containers/food/snacks/soup/monkeysdelight{
+ pixel_y = 4
+ },
+/obj/item/reagent_containers/food/drinks/soda_cans/monkey_energy{
+ pixel_y = 5;
+ pixel_x = 6
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"me" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 9
+ },
+/obj/structure/sign/warning/nosmoking{
+ pixel_y = 32
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"mq" = (
+/mob/living/carbon/monkey,
+/obj/machinery/light/floor,
+/obj/structure/flora/ausbushes/sparsegrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"mw" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 10
+ },
+/obj/item/reagent_containers/food/snacks/grown/banana,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"nA" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 9
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"nD" = (
+/obj/structure/flora/ausbushes/fernybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"nQ" = (
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 8
+ },
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 1
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"og" = (
+/obj/effect/turf_decal/trimline/blue/filled/corner{
+ dir = 4
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"os" = (
+/obj/effect/turf_decal/trimline/green/filled/end{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/machinery/door/window/westleft{
+ name = "Nature pen"
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"oE" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 5
+ },
+/obj/structure/table/reinforced,
+/obj/item/storage/firstaid/regular,
+/obj/machinery/light{
+ dir = 4
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"qD" = (
+/obj/structure/flora/ausbushes/sparsegrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"rg" = (
+/obj/item/clothing/glasses/welding{
+ pixel_y = 8;
+ pixel_x = 3
+ },
+/obj/item/weldingtool/largetank{
+ pixel_x = -3
+ },
+/obj/structure/rack,
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"rI" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 8
+ },
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 4
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"sm" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/structure/reagent_dispensers/watertank,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"su" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 6
+ },
+/obj/structure/table/optable,
+/obj/effect/decal/cleanable/blood/old,
+/turf/open/floor/plasteel{
+ dir = 1
+ },
+/area/shuttle/escape)
+"sF" = (
+/obj/effect/turf_decal/trimline/blue/filled/line,
+/obj/item/storage/backpack/duffelbag/med/surgery{
+ pixel_y = 5
+ },
+/obj/structure/rack,
+/turf/open/floor/plasteel{
+ dir = 1
+ },
+/area/shuttle/escape)
+"sN" = (
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 8
+ },
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 4
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"sV" = (
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 1
+ },
+/obj/effect/turf_decal/trimline/green/filled/corner,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"tL" = (
+/obj/effect/turf_decal/trimline/red/filled/line{
+ dir = 8
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 4
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"uc" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 10
+ },
+/obj/structure/flora/ausbushes/fullgrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"ui" = (
+/obj/structure/extinguisher_cabinet,
+/turf/closed/wall/mineral/titanium/nodiagonal,
+/area/shuttle/escape)
+"ur" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 8
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 4
+ },
+/obj/machinery/light{
+ dir = 8
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"uI" = (
+/obj/structure/flora/rock/jungle{
+ icon_state = "rock3"
+ },
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"vt" = (
+/obj/effect/turf_decal/trimline/red/filled/line{
+ dir = 10
+ },
+/obj/structure/table/reinforced,
+/obj/item/restraints/handcuffs{
+ pixel_y = 7
+ },
+/obj/item/storage/fancy/donut_box,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"vx" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 6
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"vP" = (
+/obj/effect/turf_decal/trimline/red/filled/line,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"vW" = (
+/obj/effect/turf_decal/trimline/red/filled/line{
+ dir = 6
+ },
+/obj/structure/table/reinforced,
+/obj/item/storage/box/handcuffs{
+ pixel_y = 5
+ },
+/obj/machinery/light{
+ dir = 4
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"wg" = (
+/obj/effect/turf_decal/trimline/green/filled/end{
+ dir = 1
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/door/window/northleft,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"wX" = (
+/obj/effect/turf_decal/trimline/blue/filled/line,
+/obj/machinery/light,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"xA" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 8
+ },
+/obj/structure/flora/ausbushes/fernybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"xZ" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 10
+ },
+/obj/structure/tank_dispenser/oxygen{
+ layer = 2.7;
+ pixel_x = -1;
+ pixel_y = 2
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"yt" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 8
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"yI" = (
+/obj/item/reagent_containers/food/snacks/grown/banana,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"yR" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 6
+ },
+/obj/machinery/suit_storage_unit/standard_unit,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"yZ" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 6
+ },
+/obj/structure/sign/poster/official/pda_ad{
+ pixel_y = -32
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"zf" = (
+/obj/structure/flora/ausbushes/pointybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"zr" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 10
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"zs" = (
+/obj/machinery/light/floor,
+/obj/structure/flora/ausbushes/sparsegrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"zD" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"zE" = (
+/obj/machinery/door/airlock/security{
+ name = "Brig";
+ req_access_txt = "63; 42"
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"Ai" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 6
+ },
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Aw" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 4
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 8
+ },
+/obj/machinery/status_display/evac{
+ dir = 8;
+ pixel_x = 32
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"AM" = (
+/obj/structure/flora/ausbushes/ywflowers,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Bm" = (
+/obj/machinery/door/airlock/command/glass{
+ name = "Cockpit";
+ req_access_txt = "19"
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"Bo" = (
+/obj/structure/flora/ausbushes/sunnybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Bt" = (
+/obj/structure/flora/ausbushes/fullgrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Bv" = (
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 8
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"BA" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 9
+ },
+/obj/structure/table/glass,
+/obj/item/defibrillator/loaded{
+ pixel_y = 5
+ },
+/turf/open/floor/plasteel{
+ dir = 1
+ },
+/area/shuttle/escape)
+"BG" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 10
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"BM" = (
+/obj/structure/flora/ausbushes/ppflowers,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Cb" = (
+/obj/structure/flora/rock/jungle{
+ icon_state = "bushc2"
+ },
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Co" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 1
+ },
+/obj/structure/chair/comfy/shuttle,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"CA" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 9
+ },
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/structure/chair/comfy/shuttle,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"CE" = (
+/obj/structure/flora/tree/jungle/small,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"CQ" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 1
+ },
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/machinery/vending/cola/space_up,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Db" = (
+/obj/structure/sign/poster/official/help_others,
+/turf/closed/wall/mineral/titanium/nodiagonal,
+/area/shuttle/escape)
+"DD" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 9
+ },
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/mob/living/simple_animal/bot/medbot{
+ name = "\improper emergency medibot";
+ pixel_x = -3;
+ pixel_y = 2
+ },
+/turf/open/floor/plasteel{
+ dir = 1
+ },
+/area/shuttle/escape)
+"DQ" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"EI" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 1
+ },
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/machinery/vending/snack/green,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Fo" = (
+/obj/item/cultivator,
+/mob/living/simple_animal/hostile/lizard,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Fp" = (
+/obj/structure/flora/ausbushes/grassybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Gf" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 8
+ },
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"GO" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 8
+ },
+/obj/structure/table/glass,
+/obj/item/storage/box/monkeycubes{
+ pixel_y = 10;
+ pixel_x = 5
+ },
+/obj/item/reagent_containers/food/snacks/cube/monkey{
+ pixel_x = 5
+ },
+/obj/item/paicard{
+ pixel_x = -6;
+ pixel_y = 1
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"GV" = (
+/obj/structure/shuttle/engine/huge,
+/turf/open/floor/plating/airless,
+/area/shuttle/escape)
+"He" = (
+/obj/effect/turf_decal/trimline/blue/filled/corner{
+ dir = 1
+ },
+/turf/open/floor/plasteel{
+ icon_state = "floorscorched1"
+ },
+/area/shuttle/escape)
+"Hi" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/turf/open/floor/plating{
+ icon_state = "platingdmg1"
+ },
+/area/shuttle/escape)
+"Hq" = (
+/obj/structure/flora/rock/pile,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"HV" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 1
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Ia" = (
+/mob/living/carbon/monkey,
+/obj/structure/flora/ausbushes/sparsegrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Io" = (
+/obj/effect/turf_decal/trimline/green/filled/corner,
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 1
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Iw" = (
+/obj/item/reagent_containers/glass/bucket,
+/mob/living/simple_animal/hostile/retaliate/frog,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Iz" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/vomit,
+/turf/open/floor/plasteel{
+ dir = 1
+ },
+/area/shuttle/escape)
+"IB" = (
+/obj/effect/decal/cleanable/oil,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"Jw" = (
+/obj/structure/shuttle/engine/heater,
+/obj/structure/window/reinforced{
+ dir = 1
+ },
+/turf/open/floor/plating/airless,
+/area/shuttle/escape)
+"JD" = (
+/obj/effect/turf_decal/trimline/blue/filled/end{
+ dir = 1
+ },
+/obj/structure/table/glass,
+/obj/item/storage/firstaid/brute{
+ pixel_x = 4;
+ pixel_y = 2
+ },
+/obj/item/storage/firstaid/regular{
+ pixel_x = -3
+ },
+/turf/open/floor/plasteel{
+ dir = 1
+ },
+/area/shuttle/escape)
+"JR" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 4
+ },
+/obj/machinery/suit_storage_unit/standard_unit,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"Ka" = (
+/obj/effect/turf_decal/weather/dirt,
+/obj/structure/flora/ausbushes/sparsegrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Kv" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/structure/sign/poster/contraband/tools{
+ pixel_y = 32
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"Kx" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 3
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"KT" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 5
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Lm" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 1
+ },
+/obj/structure/flora/ausbushes/pointybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"LG" = (
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 8
+ },
+/obj/effect/turf_decal/trimline/green/filled/corner,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"LO" = (
+/obj/structure/flora/rock/jungle{
+ icon_state = "grassa4"
+ },
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"LW" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"LY" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"MJ" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 4
+ },
+/obj/structure/flora/ausbushes/leafybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"MS" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 6
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Nu" = (
+/obj/effect/turf_decal/weather/dirt,
+/obj/item/hatchet,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Ob" = (
+/obj/effect/turf_decal/trimline/green/filled/end,
+/obj/effect/turf_decal/stripes/line,
+/obj/machinery/door/window/southleft{
+ name = "Nature pen"
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"OS" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 3
+ },
+/obj/machinery/vending/coffee,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Ps" = (
+/obj/structure/flora/ausbushes/brflowers,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"PG" = (
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/green/filled/corner{
+ dir = 1
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"PP" = (
+/obj/structure/flora/ausbushes/genericbush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"QC" = (
+/obj/structure/flora/ausbushes/lavendergrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"QM" = (
+/obj/item/bodypart,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/plating{
+ icon_state = "panelscorched"
+ },
+/area/shuttle/escape)
+"QO" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 4
+ },
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"QZ" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/blue/filled/corner{
+ dir = 1
+ },
+/obj/structure/chair,
+/obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6{
+ pixel_x = 30
+ },
+/turf/open/floor/plasteel{
+ dir = 1
+ },
+/area/shuttle/escape)
+"Ru" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 9
+ },
+/obj/machinery/vending/hydroseeds,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Sl" = (
+/obj/effect/turf_decal/trimline/blue/filled/line,
+/obj/machinery/computer/operating{
+ dir = 1
+ },
+/turf/open/floor/plasteel{
+ dir = 1
+ },
+/area/shuttle/escape)
+"Sr" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 6
+ },
+/obj/structure/table/glass,
+/obj/item/clothing/suit/monkeysuit{
+ pixel_y = 4;
+ pixel_x = -2
+ },
+/obj/item/clothing/mask/gas/monkeymask{
+ pixel_x = 5;
+ pixel_y = 4
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"SS" = (
+/obj/machinery/door/airlock/titanium{
+ name = "Emergency Shuttle Airlock"
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"ST" = (
+/obj/effect/turf_decal/weather/dirt,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Ti" = (
+/obj/structure/flora/rock/jungle{
+ icon_state = "busha3"
+ },
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Ts" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 1
+ },
+/obj/machinery/hydroponics/soil,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"TH" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 5
+ },
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/structure/chair/comfy/shuttle,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"TK" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 5
+ },
+/obj/item/hatchet,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"TT" = (
+/obj/effect/turf_decal/weather/dirt,
+/obj/structure/flora/ausbushes/fullgrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Um" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"Uy" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 1
+ },
+/obj/item/reagent_containers/food/snacks/grown/banana,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"UE" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 5
+ },
+/obj/machinery/vending/hydronutrients,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"UO" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 8
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 4
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Vu" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 1
+ },
+/mob/living/carbon/monkey,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Vv" = (
+/mob/living/carbon/monkey,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"VI" = (
+/obj/effect/spawner/structure/window/shuttle,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"VM" = (
+/obj/structure/flora/tree/jungle,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"VU" = (
+/turf/closed/wall/mineral/titanium,
+/area/shuttle/escape)
+"Wa" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 4
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Wr" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 9
+ },
+/obj/structure/flora/ausbushes/reedbush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Wz" = (
+/obj/effect/turf_decal/stripes/line,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/recharge_station,
+/turf/open/floor/plating,
+/area/shuttle/escape)
+"WE" = (
+/turf/template_noop,
+/area/template_noop)
+"WH" = (
+/obj/structure/flora/ausbushes/fullgrass,
+/obj/structure/flora/ausbushes/sunnybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"WL" = (
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"Xm" = (
+/obj/structure/flora/rock,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"XK" = (
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"XY" = (
+/obj/effect/turf_decal/trimline/blue/filled/line{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel{
+ dir = 1
+ },
+/area/shuttle/escape)
+"Ym" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 1
+ },
+/obj/structure/flora/rock/pile,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Yp" = (
+/obj/machinery/door/airlock/titanium{
+ name = "Emergency Shuttle Airlock"
+ },
+/obj/docking_port/mobile/emergency,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Yu" = (
+/turf/closed/wall/mineral/titanium/nodiagonal,
+/area/shuttle/escape)
+"YH" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 9
+ },
+/obj/structure/flora/ausbushes/fullgrass,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"YP" = (
+/obj/effect/turf_decal/trimline/green/filled/end{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/obj/machinery/door/window/eastleft{
+ name = "Nature pen"
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"YW" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 3
+ },
+/obj/machinery/vending/wardrobe/hydro_wardrobe,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Zd" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 3
+ },
+/obj/machinery/light,
+/obj/structure/chair/comfy/shuttle{
+ dir = 1
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"Zg" = (
+/obj/effect/turf_decal/trimline/blue/filled/line,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/escape)
+"Zl" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 5
+ },
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Zm" = (
+/obj/effect/turf_decal/weather/dirt{
+ dir = 10
+ },
+/obj/structure/flora/ausbushes/fernybush,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"Zt" = (
+/obj/effect/turf_decal/trimline/green/filled/line,
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"ZD" = (
+/obj/structure/chair/comfy/shuttle{
+ dir = 8
+ },
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 4
+ },
+/obj/machinery/light{
+ dir = 4
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+"ZL" = (
+/obj/machinery/hydroponics/soil,
+/obj/item/seeds/banana,
+/turf/open/floor/grass,
+/area/shuttle/escape)
+"ZT" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 8
+ },
+/obj/structure/chair/comfy/shuttle{
+ dir = 4
+ },
+/obj/machinery/light{
+ dir = 8
+ },
+/turf/open/floor/plasteel/white,
+/area/shuttle/escape)
+
+(1,1,1) = {"
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+VU
+SS
+Yu
+Yp
+Yu
+Yu
+Yu
+Yu
+Yu
+SS
+Yu
+SS
+Yu
+Yu
+Yu
+Yu
+Yu
+Yu
+VU
+WE
+WE
+WE
+"}
+(2,1,1) = {"
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+VU
+Yu
+nA
+UO
+yt
+ZT
+UO
+GO
+UO
+ZT
+yt
+UO
+zr
+Yu
+Yu
+lH
+eB
+lN
+bS
+Yu
+VU
+WE
+WE
+"}
+(3,1,1) = {"
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+VU
+Yu
+me
+Io
+Wa
+Wa
+Wa
+Wa
+ev
+Wa
+Wa
+Wa
+Wa
+Bv
+zr
+Yu
+Yu
+rg
+iV
+jO
+Jw
+gx
+gx
+GV
+"}
+(4,1,1) = {"
+WE
+WE
+VU
+VI
+VI
+VI
+VU
+Yu
+nA
+Io
+MS
+VI
+VI
+VI
+VI
+YP
+VI
+VI
+VI
+VI
+KT
+Bv
+zr
+Yu
+Yu
+eq
+bg
+Jw
+gx
+gx
+gx
+"}
+(5,1,1) = {"
+WE
+VU
+Yu
+jX
+tL
+vt
+Yu
+CA
+Io
+MS
+VI
+VI
+YH
+iF
+xA
+Gf
+lo
+Gf
+Zm
+VI
+VI
+KT
+Bv
+BG
+Yu
+Kv
+DQ
+Jw
+gx
+gx
+gx
+"}
+(6,1,1) = {"
+VU
+Yu
+ht
+jZ
+WL
+vP
+zE
+HV
+Zt
+VI
+VI
+Wr
+Vv
+Ti
+Fo
+PP
+Xm
+ZL
+LO
+mw
+VI
+VI
+HV
+Zd
+Yu
+IB
+iO
+Jw
+gu
+WE
+WE
+"}
+(7,1,1) = {"
+VI
+eS
+hC
+lS
+lS
+vW
+Yu
+Co
+Zt
+VI
+Ru
+zs
+Bt
+qD
+Bo
+aJ
+fG
+CE
+Vv
+zs
+uc
+VI
+HV
+Kx
+Yu
+dP
+dT
+Jw
+gu
+WE
+WE
+"}
+(8,1,1) = {"
+Yu
+Yu
+VI
+VI
+ui
+Yu
+Db
+Co
+Zt
+VI
+Ym
+XK
+au
+XK
+VM
+Hq
+QC
+XK
+BM
+Bt
+Ka
+VI
+HV
+YW
+Yu
+LY
+sm
+Jw
+gu
+WE
+WE
+"}
+(9,1,1) = {"
+VI
+eY
+hJ
+lT
+ur
+xZ
+Yu
+CQ
+Zt
+VI
+Ts
+WH
+XK
+XK
+Ps
+gl
+Bt
+it
+AM
+gI
+TT
+VI
+HV
+Zd
+Yu
+Um
+DQ
+Jw
+gx
+gx
+GV
+"}
+(10,1,1) = {"
+VI
+fD
+LW
+WL
+WL
+Zg
+Bm
+HV
+LG
+Ob
+Uy
+Xm
+Vv
+Fp
+qD
+zs
+XK
+XK
+PP
+Bt
+ST
+wg
+PG
+cL
+gj
+Um
+cm
+Jw
+gx
+gx
+gx
+"}
+(11,1,1) = {"
+VI
+cZ
+LW
+WL
+WL
+Zg
+VI
+EI
+Zt
+VI
+Lm
+as
+XK
+VM
+Iw
+au
+XK
+bd
+Bt
+XK
+Nu
+VI
+HV
+Zd
+Yu
+Um
+Hi
+Jw
+gx
+gx
+gx
+"}
+(12,1,1) = {"
+VI
+fJ
+LW
+WL
+WL
+Zg
+VI
+Co
+Zt
+VI
+Vu
+nD
+qD
+PP
+Bt
+yI
+QC
+Bt
+XK
+uI
+gR
+VI
+HV
+OS
+Yu
+Um
+Wz
+Jw
+gu
+WE
+WE
+"}
+(13,1,1) = {"
+VI
+gM
+ku
+WL
+WL
+wX
+Yu
+gg
+Zt
+VI
+UE
+zs
+zf
+ke
+zf
+ay
+XK
+ay
+AM
+mq
+ex
+VI
+HV
+dj
+Yu
+QM
+DQ
+Jw
+gu
+WE
+WE
+"}
+(14,1,1) = {"
+VU
+Yu
+iD
+og
+WL
+Zg
+ui
+Co
+Zt
+VI
+VI
+TK
+Cb
+Bt
+qD
+BM
+Bo
+Ia
+XK
+Ai
+VI
+VI
+HV
+Zd
+Yu
+zD
+vx
+Jw
+gu
+WE
+WE
+"}
+(15,1,1) = {"
+WE
+VU
+Yu
+oE
+JR
+yR
+Yu
+TH
+sN
+zr
+VI
+VI
+Zl
+QO
+MJ
+QO
+ib
+MJ
+Ai
+VI
+VI
+nA
+sV
+aA
+Yu
+DD
+fT
+Jw
+gx
+gx
+GV
+"}
+(16,1,1) = {"
+WE
+WE
+VU
+Yu
+Yu
+Yu
+VU
+Yu
+KT
+sN
+zr
+VI
+VI
+VI
+VI
+os
+VI
+VI
+VI
+VI
+nA
+sV
+MS
+Yu
+Yu
+XY
+sF
+Jw
+gx
+gx
+gx
+"}
+(17,1,1) = {"
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+VU
+Yu
+cR
+sN
+yt
+yt
+yt
+yt
+nQ
+yt
+yt
+yt
+yt
+sV
+yZ
+Yu
+Yu
+BA
+He
+Sl
+Jw
+gx
+gx
+gx
+"}
+(18,1,1) = {"
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+VU
+Yu
+lV
+rI
+ZD
+rI
+rI
+Aw
+rI
+rI
+ZD
+rI
+Sr
+Yu
+Yu
+JD
+QZ
+Iz
+su
+Yu
+VU
+WE
+WE
+"}
+(19,1,1) = {"
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+WE
+VU
+Yu
+VI
+VI
+VI
+VI
+Yu
+VI
+VI
+VI
+VI
+Yu
+Yu
+Yu
+Yu
+Yu
+Yu
+Yu
+VU
+WE
+WE
+WE
+"}
diff --git a/code/__DEFINES/_flags/obj_flags.dm b/code/__DEFINES/_flags/obj_flags.dm
index a936a5cef5..ce1e126f12 100644
--- a/code/__DEFINES/_flags/obj_flags.dm
+++ b/code/__DEFINES/_flags/obj_flags.dm
@@ -9,8 +9,11 @@
#define UNIQUE_RENAME (1<<6) //can you customize the description/name of the thing?
#define USES_TGUI (1<<7) //put on things that use tgui on ui_interact instead of custom/old UI.
#define FROZEN (1<<8)
-#define SHOVABLE_ONTO (1<<9) //called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check.
-#define BLOCK_Z_FALL (1<<10)
+#define BLOCK_Z_OUT_DOWN (1<<9) // Should this object block z falling from loc?
+#define BLOCK_Z_OUT_UP (1<<10) // Should this object block z uprise from loc?
+#define BLOCK_Z_IN_DOWN (1<<11) // Should this object block z falling from above?
+#define BLOCK_Z_IN_UP (1<<12) // Should this object block z uprise from below?
+#define SHOVABLE_ONTO (1<<13) //called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check.
/// Integrity defines for clothing (not flags but close enough)
#define CLOTHING_PRISTINE 0 // We have no damage on the clothing
@@ -18,3 +21,6 @@
#define CLOTHING_SHREDDED 2 // The clothing is useless and cannot be equipped unless repaired first
// If you add new ones, be sure to add them to /obj/Initialize as well for complete mapping support
+
+/// Flags for the pod_flags var on /obj/structure/closet/supplypod
+#define FIRST_SOUNDS (1<<0) // If it shouldn't play sounds the first time it lands, used for reverse mode
diff --git a/code/__DEFINES/actionspeed_modifiers.dm b/code/__DEFINES/actionspeed_modifiers.dm
new file mode 100644
index 0000000000..40fbd3fe26
--- /dev/null
+++ b/code/__DEFINES/actionspeed_modifiers.dm
@@ -0,0 +1,2 @@
+//ids
+#define ACTIONSPEED_ID_SANITY "sanity_component"
diff --git a/code/__DEFINES/cargo.dm b/code/__DEFINES/cargo.dm
index bba5b5c5ed..ac5272057a 100644
--- a/code/__DEFINES/cargo.dm
+++ b/code/__DEFINES/cargo.dm
@@ -13,27 +13,43 @@
#define STYLE_GONDOLA 13
#define STYLE_SEETHROUGH 14
-#define POD_ICON_STATE 1
-#define POD_NAME 2
-#define POD_DESC 3
+#define POD_SHAPE 1
+#define POD_BASE 2
+#define POD_DOOR 3
+#define POD_DECAL 4
+#define POD_GLOW 5
+#define POD_RUBBLE_TYPE 6
+#define POD_NAME 7
+#define POD_DESC 8
-#define POD_STYLES list(\
- list("supplypod", "supply pod", "A Nanotrasen supply drop pod."),\
- list("bluespacepod", "bluespace supply pod" , "A Nanotrasen Bluespace supply pod. Teleports back to CentCom after delivery."),\
- list("centcompod", "\improper Centcom supply pod", "A Nanotrasen supply pod, this one has been marked with Central Command's designations. Teleports back to Centcom after delivery."),\
- list("syndiepod", "blood-red supply pod", "A dark, intimidating supply pod, covered in the blood-red markings of the Syndicate. It's probably best to stand back from this."),\
- list("squadpod", "\improper MK. II supply pod", "A Nanotrasen supply pod. This one has been marked the markings of some sort of elite strike team."),\
- list("cultpod", "bloody supply pod", "A Nanotrasen supply pod covered in scratch-marks, blood, and strange runes."),\
- list("missilepod", "cruise missile", "A big ass missile that didn't seem to fully detonate. It was likely launched from some far-off deep space missile silo. There appears to be an auxillery payload hatch on the side, though manually opening it is likely impossible."),\
- list("smissilepod", "\improper Syndicate cruise missile", "A big ass, blood-red missile that didn't seem to fully detonate. It was likely launched from some deep space Syndicate missile silo. There appears to be an auxillery payload hatch on the side, though manually opening it is likely impossible."),\
- list("boxpod", "\improper Aussec supply crate", "An incredibly sturdy supply crate, designed to withstand orbital re-entry. Has 'Aussec Armory - 2532' engraved on the side."),\
- list("honkpod", "\improper HONK pod", "A brightly-colored supply pod. It likely originated from the Clown Federation."),\
- list("fruitpod", "\improper Orange", "An angry orange."),\
- list("", "\improper S.T.E.A.L.T.H. pod MKVII", "A supply pod that, under normal circumstances, is completely invisible to conventional methods of detection. How are you even seeing this?"),\
- list("gondolapod", "gondola", "The silent walker. This one seems to be part of a delivery agency."),\
- list("", "", "")\
-)
+#define RUBBLE_NONE 1
+#define RUBBLE_NORMAL 2
+#define RUBBLE_WIDE 3
+#define RUBBLE_THIN 4
+#define POD_SHAPE_NORML 1
+#define POD_SHAPE_OTHER 2
+
+#define SUPPLYPOD_X_OFFSET -16
+
+GLOBAL_LIST_EMPTY(supplypod_loading_bays)
+
+GLOBAL_LIST_INIT(podstyles, list(\
+ list(POD_SHAPE_NORML, "pod", TRUE, "default", "yellow", RUBBLE_NORMAL, "supply pod", "A Nanotrasen supply drop pod."),\
+ list(POD_SHAPE_NORML, "advpod", TRUE, "bluespace", "blue", RUBBLE_NORMAL, "bluespace supply pod" , "A Nanotrasen Bluespace supply pod. Teleports back to CentCom after delivery."),\
+ list(POD_SHAPE_NORML, "advpod", TRUE, "centcom", "blue", RUBBLE_NORMAL, "\improper CentCom supply pod", "A Nanotrasen supply pod, this one has been marked with Central Command's designations. Teleports back to CentCom after delivery."),\
+ list(POD_SHAPE_NORML, "darkpod", TRUE, "syndicate", "red", RUBBLE_NORMAL, "blood-red supply pod", "An intimidating supply pod, covered in the blood-red markings of the Syndicate. It's probably best to stand back from this."),\
+ list(POD_SHAPE_NORML, "darkpod", TRUE, "deathsquad", "blue", RUBBLE_NORMAL, "\improper Deathsquad drop pod", "A Nanotrasen drop pod. This one has been marked the markings of Nanotrasen's elite strike team."),\
+ list(POD_SHAPE_NORML, "pod", TRUE, "cultist", "red", RUBBLE_NORMAL, "bloody supply pod", "A Nanotrasen supply pod covered in scratch-marks, blood, and strange runes."),\
+ list(POD_SHAPE_OTHER, "missile", FALSE, FALSE, FALSE, RUBBLE_THIN, "cruise missile", "A big ass missile that didn't seem to fully detonate. It was likely launched from some far-off deep space missile silo. There appears to be an auxillery payload hatch on the side, though manually opening it is likely impossible."),\
+ list(POD_SHAPE_OTHER, "smissile", FALSE, FALSE, FALSE, RUBBLE_THIN, "\improper Syndicate cruise missile", "A big ass, blood-red missile that didn't seem to fully detonate. It was likely launched from some deep space Syndicate missile silo. There appears to be an auxillery payload hatch on the side, though manually opening it is likely impossible."),\
+ list(POD_SHAPE_OTHER, "box", TRUE, FALSE, FALSE, RUBBLE_WIDE, "\improper Aussec supply crate", "An incredibly sturdy supply crate, designed to withstand orbital re-entry. Has 'Aussec Armory - 2532' engraved on the side."),\
+ list(POD_SHAPE_NORML, "clownpod", TRUE, "clown", "green", RUBBLE_NORMAL, "\improper HONK pod", "A brightly-colored supply pod. It likely originated from the Clown Federation."),\
+ list(POD_SHAPE_OTHER, "orange", TRUE, FALSE, FALSE, RUBBLE_NONE, "\improper Orange", "An angry orange."),\
+ list(POD_SHAPE_OTHER, FALSE, FALSE, FALSE, FALSE, RUBBLE_NONE, "\improper S.T.E.A.L.T.H. pod MKVII", "A supply pod that, under normal circumstances, is completely invisible to conventional methods of detection. How are you even seeing this?"),\
+ list(POD_SHAPE_OTHER, "gondola", FALSE, FALSE, FALSE, RUBBLE_NONE, "gondola", "The silent walker. This one seems to be part of a delivery agency."),\
+ list(POD_SHAPE_OTHER, FALSE, FALSE, FALSE, FALSE, RUBBLE_NONE, FALSE, FALSE, "rl_click", "give_po")\
+))
#define PACK_GOODY_NONE 0
#define PACK_GOODY_PUBLIC 1 //can be bought by both privates and cargo
-#define PACK_GOODY_PRIVATE 2 //can be bought only by privates
\ No newline at end of file
+#define PACK_GOODY_PRIVATE 2 //can be bought only by privates
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index cf669b905a..7b214df421 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -85,7 +85,7 @@
#define COMSIG_ATOM_EMP_ACT "atom_emp_act"
///from base of atom/fire_act(): (exposed_temperature, exposed_volume)
#define COMSIG_ATOM_FIRE_ACT "atom_fire_act"
-///from base of atom/bullet_act(): (/obj/projectile, def_zone)
+///from base of atom/bullet_act(): (/obj/item/projectile, def_zone)
#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act"
///from base of atom/blob_act(): (/obj/structure/blob)
#define COMSIG_ATOM_BLOB_ACT "atom_blob_act"
@@ -381,6 +381,8 @@
#define COMSIG_MINE_TRIGGERED "minegoboom" ///from [/obj/effect/mine/proc/triggermine]:
// Uncovered information
#define COMPONENT_DEEPSCAN_UNCOVERED_INFORMATION 1
+///from [/obj/structure/closet/supplypod/proc/endlaunch]:
+#define COMSIG_SUPPLYPOD_LANDED "supplypodgoboom"
// /obj/item/grenade signals
#define COMSIG_GRENADE_PRIME "grenade_prime" //called in /obj/item/gun/process_fire (user, target, params, zone_override)
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 66f741b2c7..21b66f5e37 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -44,7 +44,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
#define isplatingturf(A) (istype(A, /turf/open/floor/plating))
-#define istransparentturf(A) (istype(A, /turf/open/transparent))
+#define istransparentturf(A) (istype(A, /turf/open/transparent)||istype(A, /turf/open/space/transparent))
//Mobs
#define isliving(A) (istype(A, /mob/living))
@@ -235,3 +235,5 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
#define isblobmonster(O) (istype(O, /mob/living/simple_animal/hostile/blob))
#define isshuttleturf(T) (length(T.baseturfs) && (/turf/baseturf_skipover/shuttle in T.baseturfs))
+
+#define isProbablyWallMounted(O) (O.pixel_x > 20 || O.pixel_x < -20 || O.pixel_y > 20 || O.pixel_y < -20)
diff --git a/code/__DEFINES/layers_planes.dm b/code/__DEFINES/layers_planes.dm
index 9188efacfd..8ab33689d3 100644
--- a/code/__DEFINES/layers_planes.dm
+++ b/code/__DEFINES/layers_planes.dm
@@ -37,7 +37,9 @@
#define FIELD_OF_VISION_VISUAL_RENDER_TARGET "FIELD_OF_VISION_VISUAL_PLANE"
#define CHAT_PLANE -1 //We don't want heard messages to be hidden by FoV.
-#define CHAT_LAYER 12.1 //Legacy, it doesn't matter that much because we are displayed above the game plane anyway.
+
+#define CHAT_LAYER 12.0001 // Do not insert layers between these two values
+#define CHAT_LAYER_MAX 12.9999
#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals
#define BLACKNESS_PLANE_RENDER_TARGET "BLACKNESS_PLANE"
diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm
index 84eed5483a..aef77e7b57 100644
--- a/code/__DEFINES/preferences.dm
+++ b/code/__DEFINES/preferences.dm
@@ -40,6 +40,16 @@
#define PARALLAX_LOW 2
#define PARALLAX_DISABLE 3 //this option must be the highest number
+#define PIXEL_SCALING_AUTO 0
+#define PIXEL_SCALING_1X 1
+#define PIXEL_SCALING_1_2X 1.5
+#define PIXEL_SCALING_2X 2
+#define PIXEL_SCALING_3X 3
+
+#define SCALING_METHOD_NORMAL "normal"
+#define SCALING_METHOD_DISTORT "distort"
+#define SCALING_METHOD_BLUR "blur"
+
#define PARALLAX_DELAY_DEFAULT world.tick_lag
#define PARALLAX_DELAY_MED 1
#define PARALLAX_DELAY_LOW 2
diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm
index 80983b34be..a188bf8363 100644
--- a/code/__DEFINES/shuttles.dm
+++ b/code/__DEFINES/shuttles.dm
@@ -31,6 +31,11 @@
#define EARLY_LAUNCHED 2
#define ENDGAME_TRANSIT 3
+//positive value = cannot puchase
+#define SHUTTLEPURCHASE_PURCHASABLE 0 //station can buy a shuttle
+#define SHUTTLEPURCHASE_PURCHASED 1 //station has already bought a shuttle, so cannot
+#define SHUTTLEPURCHASE_FORCED 2 //station was given a new shuttle through events or other shenanigans
+
// Ripples, effects that signal a shuttle's arrival
#define SHUTTLE_RIPPLE_TIME 100
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 9deddd4b46..b405db83b0 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -124,6 +124,7 @@
#define FIRE_PRIORITY_ATMOS_ADJACENCY 300
#define FIRE_PRIORITY_STATPANEL 390
#define FIRE_PRIORITY_CHAT 400
+#define FIRE_PRIORITY_RUNECHAT 410
#define FIRE_PRIORITY_OVERLAYS 500
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
diff --git a/code/__HELPERS/do_after.dm b/code/__HELPERS/do_after.dm
index 30d40f3867..c65cd80394 100644
--- a/code/__HELPERS/do_after.dm
+++ b/code/__HELPERS/do_after.dm
@@ -38,11 +38,11 @@
return FALSE
if((do_after_flags & DO_AFTER_REQUIRES_USER_ON_TURF) && !isturf(user.loc))
return FALSE
+ if(!(do_after_flags & DO_AFTER_NO_COEFFICIENT) && living_user)
+ delay *= living_user.cached_multiplicative_actions_slowdown
var/starttime = world.time
var/endtime = world.time + delay
var/obj/item/initially_held_item = mob_redirect?.get_active_held_item()
- if(!(do_after_flags & DO_AFTER_NO_COEFFICIENT) && living_user)
- delay *= living_user.do_after_coefficent()
var/atom/movable/AM_user = ismovable(user) && user
var/drifting = AM_user?.Process_Spacemove(NONE) && AM_user.inertia_dir
var/initial_dx = targetturf.x - userturf.x
@@ -245,7 +245,7 @@
if(holding)
holdingnull = 0 //Users hand started holding something, check to see if it's still holding that
- delay *= user.do_after_coefficent()
+ delay *= user.cached_multiplicative_actions_slowdown
var/datum/progressbar/progbar
if (progress)
@@ -300,10 +300,6 @@
LAZYREMOVE(user.do_afters, target)
LAZYREMOVE(target.targeted_by, user)
-/mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1
- . = 1
- return
-
/proc/do_after_mob(mob/user, var/list/targets, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks)
if(!user || !targets)
return 0
@@ -326,6 +322,8 @@
if(progress)
progbar = new(user, time, targets[1])
+ time *= user.cached_multiplicative_actions_slowdown
+
var/endtime = world.time + time
var/starttime = world.time
. = 1
diff --git a/code/__HELPERS/view.dm b/code/__HELPERS/view.dm
index 48e68be20f..1c92971802 100644
--- a/code/__HELPERS/view.dm
+++ b/code/__HELPERS/view.dm
@@ -2,7 +2,7 @@
var/viewX
var/viewY
if(isnum(view))
- var/totalviewrange = 1 + 2 * view
+ var/totalviewrange = (view < 0 ? -1 : 1) + 2 * view
viewX = totalviewrange
viewY = totalviewrange
else
diff --git a/code/_onclick/hud/map_popups.dm b/code/_onclick/hud/map_popups.dm
index 777ebb0718..2ecfe80ab5 100644
--- a/code/_onclick/hud/map_popups.dm
+++ b/code/_onclick/hud/map_popups.dm
@@ -1,30 +1,11 @@
-/client
- /**
- * Assoc list with all the active maps - when a screen obj is added to
- * a map, it's put in here as well.
- *
- * Format: list(
- Reverse Drop-off Location:
- {data.dropoff_turf ? data.dropoff_turf : 'None'}
-
- [Enable Reverse Mode for this feature]
- "+e+"
"
dat += "HUD Button Flash Color: Change
"
+/* CITADEL EDIT - We're using top menu instead
+ button_name = pixel_size
+ dat += "Pixel Scaling: [(button_name) ? "Pixel Perfect [button_name]x" : "Stretch to fit"]
"
+
+ switch(scaling_method)
+ if(SCALING_METHOD_NORMAL)
+ button_name = "Nearest Neighbor"
+ if(SCALING_METHOD_DISTORT)
+ button_name = "Point Sampling"
+ if(SCALING_METHOD_BLUR)
+ button_name = "Bilinear"
+ dat += "Scaling Method: [button_name]
"
+*/
+
if (CONFIG_GET(flag/maprotation) && CONFIG_GET(flag/tgstyle_maprotation))
var/p_map = preferred_map
if (!p_map)
@@ -2239,7 +2260,32 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["has_womb"] = !features["has_womb"]
if("widescreenpref")
widescreenpref = !widescreenpref
- user.client.change_view(CONFIG_GET(string/default_view))
+ user.client.view_size.setDefault(getScreenSize(widescreenpref))
+
+ if("pixel_size")
+ switch(pixel_size)
+ if(PIXEL_SCALING_AUTO)
+ pixel_size = PIXEL_SCALING_1X
+ if(PIXEL_SCALING_1X)
+ pixel_size = PIXEL_SCALING_1_2X
+ if(PIXEL_SCALING_1_2X)
+ pixel_size = PIXEL_SCALING_2X
+ if(PIXEL_SCALING_2X)
+ pixel_size = PIXEL_SCALING_3X
+ if(PIXEL_SCALING_3X)
+ pixel_size = PIXEL_SCALING_AUTO
+ user.client.view_size.apply() //Let's winset() it so it actually works
+
+ if("scaling_method")
+ switch(scaling_method)
+ if(SCALING_METHOD_NORMAL)
+ scaling_method = SCALING_METHOD_DISTORT
+ if(SCALING_METHOD_DISTORT)
+ scaling_method = SCALING_METHOD_BLUR
+ if(SCALING_METHOD_BLUR)
+ scaling_method = SCALING_METHOD_NORMAL
+ user.client.view_size.setZoomMode()
+
if("autostand")
autostand = !autostand
if("auto_ooc")
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 7d4ad08e6a..ab30e48b67 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -280,6 +280,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["parallax"] >> parallax
S["ambientocclusion"] >> ambientocclusion
S["auto_fit_viewport"] >> auto_fit_viewport
+ S["widescreenpref"] >> widescreenpref
+ S["pixel_size"] >> pixel_size
+ S["scaling_method"] >> scaling_method
S["hud_toggle_flash"] >> hud_toggle_flash
S["hud_toggle_color"] >> hud_toggle_color
S["menuoptions"] >> menuoptions
@@ -297,7 +300,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["arousable"] >> arousable
S["screenshake"] >> screenshake
S["damagescreenshake"] >> damagescreenshake
- S["widescreenpref"] >> widescreenpref
S["autostand"] >> autostand
S["cit_toggles"] >> cit_toggles
S["preferred_chaos"] >> preferred_chaos
@@ -333,6 +335,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, null)
ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion))
auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport))
+ widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref))
+ pixel_size = sanitize_integer(pixel_size, PIXEL_SCALING_AUTO, PIXEL_SCALING_3X, initial(pixel_size))
+ scaling_method = sanitize_text(scaling_method, initial(scaling_method))
hud_toggle_flash = sanitize_integer(hud_toggle_flash, 0, 1, initial(hud_toggle_flash))
hud_toggle_color = sanitize_hexcolor(hud_toggle_color, 6, 1, initial(hud_toggle_color))
ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form))
@@ -346,7 +351,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT)
screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake))
damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake))
- widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref))
autostand = sanitize_integer(autostand, 0, 1, initial(autostand))
cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles))
auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc))
diff --git a/code/modules/events/shuttle_catastrophe b/code/modules/events/shuttle_catastrophe
new file mode 100644
index 0000000000..d948b39d3b
--- /dev/null
+++ b/code/modules/events/shuttle_catastrophe
@@ -0,0 +1,37 @@
+/datum/round_event_control/shuttle_catastrophe
+ name = "Shuttle Catastrophe"
+ typepath = /datum/round_event/shuttle_catastrophe
+ weight = 10
+ max_occurrences = 1
+
+/datum/round_event_control/shuttle_catastrophe/canSpawnEvent(players, gamemode)
+ if(SSshuttle.emergency.name == "Build your own shuttle kit")
+ return FALSE //don't undo manual player engineering, it also would unload people and ghost them, there's just a lot of problems
+ return ..()
+
+
+/datum/round_event/shuttle_catastrophe
+ var/datum/map_template/shuttle/new_shuttle
+
+/datum/round_event/shuttle_catastrophe/announce(fake)
+ var/cause = pick("was attacked by [syndicate_name()] Operatives", "mysteriously teleported away", "had its refuelling crew mutiny",
+ "was found with its engines stolen", "\[REDACTED\]", "flew into the sunset, and melted", "learned something from a very wise cow, and left on its own",
+ "had cloning devices on it", "had its shuttle inspector put the shuttle in reverse instead of park, causing the shuttle to crash into the hangar")
+
+ priority_announce("Your emergency shuttle [cause]. Your replacement shuttle will be the [new_shuttle.name] until further notice.", "CentCom Spacecraft Engineering")
+
+/datum/round_event/shuttle_catastrophe/setup()
+ var/list/valid_shuttle_templates = list()
+ for(var/shuttle_id in SSmapping.shuttle_templates)
+ var/datum/map_template/shuttle/template = SSmapping.shuttle_templates[shuttle_id]
+ if(template.can_be_bought && template.credit_cost < INFINITY) //if we could get it from the communications console, it's cool for us to get it here
+ valid_shuttle_templates += template
+ new_shuttle = pick(valid_shuttle_templates)
+
+/datum/round_event/shuttle_catastrophe/start()
+ SSshuttle.shuttle_purchased = SHUTTLEPURCHASE_FORCED
+ SSshuttle.unload_preview()
+ SSshuttle.load_template(new_shuttle)
+ SSshuttle.existing_shuttle = SSshuttle.emergency
+ SSshuttle.action_load(new_shuttle)
+ log_shuttle("Shuttle Catastrophe set a new shuttle, [new_shuttle.name].")
diff --git a/code/modules/events/stray_cargo.dm b/code/modules/events/stray_cargo.dm
index 031642c875..aae39e28a4 100644
--- a/code/modules/events/stray_cargo.dm
+++ b/code/modules/events/stray_cargo.dm
@@ -55,7 +55,7 @@
crate.update_icon()
var/obj/structure/closet/supplypod/pod = make_pod()
crate.forceMove(pod)
- new /obj/effect/abstract/DPtarget(LZ, pod)
+ new /obj/effect/pod_landingzone(LZ, pod)
///Handles the creation of the pod, in case it needs to be modified beforehand
/datum/round_event/stray_cargo/proc/make_pod()
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index e1d078c632..0c57c13e3f 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -408,7 +408,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(mind.current.key && mind.current.key[1] != "@") //makes sure we don't accidentally kick any clients
to_chat(usr, "Another consciousness is in your body...It is resisting you.")
return
- client.change_view(CONFIG_GET(string/default_view))
+ client.view_size.setDefault(getScreenSize(client.prefs.widescreenpref))//Let's reset so people can't become allseeing gods
transfer_ckey(mind.current, FALSE)
SStgui.on_transfer(src, mind.current) // Transfer NanoUIs.
mind.current.client.init_verbs()
@@ -568,15 +568,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc = "Change your view range."
var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT
- if(client.view == CONFIG_GET(string/default_view))
+ if(client.view_size.getView() == client.view_size.default)
var/list/views = list()
for(var/i in 7 to max_view)
views |= i
- var/new_view = input("Choose your new view", "Modify view range", 7) as null|anything in views
+ var/new_view = input("Choose your new view", "Modify view range", 0) as null|anything in views
if(new_view)
- client.change_view(clamp(new_view, 7, max_view))
+ client.view_size.setTo(clamp(new_view, 7, max_view) - 7)
else
- client.change_view(CONFIG_GET(string/default_view))
+ client.view_size.resetToDefault()
/mob/dead/observer/verb/add_view_range(input as num)
set name = "Add View Range"
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 1706763f6b..eaa1a73a19 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -979,21 +979,6 @@
O.held_index = r_arm_index_next //2, 4, 6, 8...
hand_bodyparts += O
-/mob/living/carbon/do_after_coefficent()
- . = ..()
- var/datum/component/mood/mood = src.GetComponent(/datum/component/mood) //Currently, only carbons or higher use mood, move this once that changes.
- if(mood)
- switch(mood.sanity) //Alters do_after delay based on how sane you are
- if(SANITY_INSANE to SANITY_DISTURBED)
- . *= 1.25
- if(SANITY_NEUTRAL to SANITY_GREAT)
- . *= 0.90
-
- for(var/i in status_effects)
- var/datum/status_effect/S = i
- . *= S.interact_speed_modifier()
-
-
/mob/living/carbon/proc/create_internal_organs()
for(var/X in internal_organs)
var/obj/item/organ/I = X
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index a6ba4cb610..904753f9b1 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1058,11 +1058,6 @@
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
-
-/mob/living/carbon/human/do_after_coefficent()
- . = ..()
- . *= physiology.do_after_speed
-
/mob/living/carbon/human/is_bleeding()
if(NOBLOOD in dna.species.species_traits || bleedsuppress)
return FALSE
diff --git a/code/modules/mob/living/carbon/human/physiology.dm b/code/modules/mob/living/carbon/human/physiology.dm
index fd0df0bde9..22c197f7de 100644
--- a/code/modules/mob/living/carbon/human/physiology.dm
+++ b/code/modules/mob/living/carbon/human/physiology.dm
@@ -23,8 +23,6 @@
var/hunger_mod = 1 //% of hunger rate taken per tick.
- var/do_after_speed = 1 //Speed mod for do_after. Lower is better. If temporarily adjusting, please only modify using *= and /=, so you don't interrupt other calculations.
-
/// footstep type override for both shoeless and not footstep sounds.
var/footstep_type
diff --git a/code/modules/mob/living/living_active_block.dm b/code/modules/mob/living/living_active_block.dm
index 2493509e16..8e8b94463b 100644
--- a/code/modules/mob/living/living_active_block.dm
+++ b/code/modules/mob/living/living_active_block.dm
@@ -231,6 +231,7 @@
active_block_do_stamina_damage(owner, object, stamina_cost, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
block_return[BLOCK_RETURN_ACTIVE_BLOCK_DAMAGE_MITIGATED] = damage - final_damage
block_return[BLOCK_RETURN_SET_DAMAGE_TO] = final_damage
+ block_return[BLOCK_RETURN_MITIGATION_PERCENT] = clamp(1 - (final_damage / damage), 0, 1)
. = BLOCK_SHOULD_CHANGE_DAMAGE
if((final_damage <= 0) || (damage <= 0))
. |= BLOCK_SUCCESS //full block
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 186fe36a10..37eb9b7f67 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -52,6 +52,19 @@
var/lose_patience_timer_id //id for a timer to call LoseTarget(), used to stop mobs fixating on a target they can't reach
var/lose_patience_timeout = 300 //30 seconds by default, so there's no major changes to AI behaviour, beyond actually bailing if stuck forever
+ ///When a target is found, will the mob attempt to charge at it's target?
+ var/charger = FALSE
+ ///Tracks if the target is actively charging.
+ var/charge_state = FALSE
+ ///In a charge, how many tiles will the charger travel?
+ var/charge_distance = 3
+ ///How often can the charging mob actually charge? Effects the cooldown between charges.
+ var/charge_frequency = 6 SECONDS
+ ///If the mob is charging, how long will it stun it's target on success, and itself on failure?
+ var/knockdown_time = 3 SECONDS
+ ///Declares a cooldown for potential charges right off the bat.
+ COOLDOWN_DECLARE(charge_cooldown)
+
/mob/living/simple_animal/hostile/Initialize()
. = ..()
@@ -292,6 +305,9 @@
if(ranged) //We ranged? Shoot at em
if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown
OpenFire(target)
+ if(charger && (target_distance > minimum_distance) && (target_distance <= charge_distance))//Attempt to close the distance with a charge.
+ enter_charge(target)
+ return TRUE
if(!Process_Spacemove()) //Drifting
walk(src,0)
return 1
@@ -599,3 +615,64 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega
. += M
else if (M.loc.type in hostile_machines)
. += M.loc
+
+
+/**
+ * Proc that handles a charge attack windup for a mob.
+ */
+/mob/living/simple_animal/hostile/proc/enter_charge(var/atom/target)
+ if((mobility_flags & (MOBILITY_MOVE | MOBILITY_STAND)) != (MOBILITY_MOVE | MOBILITY_STAND) || charge_state)
+ return FALSE
+
+ if(!(COOLDOWN_FINISHED(src, charge_cooldown)) || !has_gravity() || !target.has_gravity())
+ return FALSE
+ Shake(15, 15, 1 SECONDS)
+ addtimer(CALLBACK(src, .proc/handle_charge_target, target), 1.5 SECONDS, TIMER_STOPPABLE)
+
+/**
+ * Proc that throws the mob at the target after the windup.
+ */
+/mob/living/simple_animal/hostile/proc/handle_charge_target(var/atom/target)
+ charge_state = TRUE
+ throw_at(target, charge_distance, 1, src, FALSE, TRUE, callback = CALLBACK(src, .proc/charge_end))
+ COOLDOWN_START(src, charge_cooldown, charge_frequency)
+ return TRUE
+
+/**
+ * Proc that handles a charge attack after it's concluded.
+ */
+/mob/living/simple_animal/hostile/proc/charge_end()
+ charge_state = FALSE
+
+/**
+ * Proc that handles the charge impact of the charging mob.
+ */
+/mob/living/simple_animal/hostile/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
+ if(!charge_state)
+ return ..()
+
+ if(hit_atom)
+ if(isliving(hit_atom))
+ var/mob/living/L = hit_atom
+ var/blocked = FALSE
+ if(ishuman(hit_atom))
+ var/mob/living/carbon/human/H = hit_atom
+ var/list/return_list = list()
+ if(H.mob_run_block(src, 0, "the [name]", ATTACK_TYPE_TACKLE, 0, src, null, return_list) & BLOCK_SUCCESS)
+ blocked = TRUE
+ if(!blocked)
+ blocked = return_list[BLOCK_RETURN_MITIGATION_PERCENT]
+ if(!blocked)
+ L.visible_message("[src] charges on [L]!", "[src] charges into you!")
+ L.Knockdown(knockdown_time)
+ else
+ Stun((knockdown_time * 2), 1, 1)
+ charge_end()
+ else if(hit_atom.density && !hit_atom.CanPass(src))
+ visible_message("[src] smashes into [hit_atom]!")
+ Stun((knockdown_time * 2), 1, 1)
+
+ if(charge_state)
+ charge_state = FALSE
+ update_icons()
+ update_mobility()
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/lobsterosity.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/lobsterosity.dm
new file mode 100644
index 0000000000..140042024d
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/lobsterosity.dm
@@ -0,0 +1,42 @@
+/**
+ * Lobstrosities, the poster boy of charging AI mobs. Drops crab meat and bones.
+ * Outside of charging, it's intended behavior is that it is generally slow moving, but makes up for that with a knockdown attack to score additional hits.
+ */
+/mob/living/simple_animal/hostile/asteroid/lobstrosity
+ name = "arctic lobstrosity"
+ desc = "A marvel of evolution gone wrong, the frosty ice produces underground lakes where these ill tempered seafood gather. Beware its charge."
+ icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
+ icon_state = "arctic_lobstrosity"
+ icon_living = "arctic_lobstrosity"
+ icon_dead = "arctic_lobstrosity_dead"
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
+ mouse_opacity = MOUSE_OPACITY_ICON
+ friendly_verb_continuous = "chitters at"
+ friendly_verb_simple = "chits at"
+ speak_emote = list("chitters")
+ speed = 3
+ move_to_delay = 20
+ maxHealth = 150
+ health = 150
+ obj_damage = 15
+ melee_damage_lower = 15
+ melee_damage_upper = 19
+ attack_verb_continuous = "snips"
+ attack_verb_simple = "snip"
+ attack_sound = 'sound/weapons/bite.ogg'
+ weather_immunities = list("snow")
+ vision_range = 5
+ aggro_vision_range = 7
+ charger = TRUE
+ charge_distance = 4
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/crab = 2, /obj/item/stack/sheet/bone = 2)
+ robust_searching = TRUE
+ footstep_type = FOOTSTEP_MOB_CLAW
+ gold_core_spawnable = HOSTILE_SPAWN
+
+/mob/living/simple_animal/hostile/asteroid/lobstrosity/lava
+ name = "tropical lobstrosity"
+ desc = "A marvel of evolution gone wrong, the sulfur lakes of lavaland have given them a vibrant, red hued shell. Beware its charge."
+ icon_state = "lobstrosity"
+ icon_living = "lobstrosity"
+ icon_dead = "lobstrosity_dead"
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index 0d4afd0915..2ed0bfa9d2 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -39,8 +39,7 @@
update_client_colour()
update_mouse_pointer()
if(client)
- client.change_view(CONFIG_GET(string/default_view)) // Resets the client.view in case it was changed.
-
+ client.view_size?.resetToDefault()
if(client.player_details && istype(client.player_details))
if(client.player_details.player_actions.len)
for(var/datum/action/A in client.player_details.player_actions)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index e1a4ac6118..ab2556abb5 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -39,6 +39,7 @@
. = ..()
update_config_movespeed()
update_movespeed(TRUE)
+ initialize_actionspeed()
hook_vr("mob_new",list(src))
/mob/GenerateTag()
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 03a3ab1001..8c6b722140 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -58,6 +58,13 @@
var/list/movespeed_mod_immunities //Lazy list, see mob_movespeed.dm
/// The calculated mob speed slowdown based on the modifiers list
var/cached_multiplicative_slowdown
+ /// List of action speed modifiers applying to this mob
+ var/list/actionspeed_modification //Lazy list, see mob_movespeed.dm
+ /// List of action speed modifiers ignored by this mob. List -> List (id) -> List (sources)
+ var/list/actionspeed_mod_immunities //Lazy list, see mob_movespeed.dm
+ /// The calculated mob action speed slowdown based on the modifiers list
+ var/cached_multiplicative_actions_slowdown
+
/////////////////
var/name_archive //For admin things like possession
diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm
index 0e553ced35..25b5cfb51b 100644
--- a/code/modules/paperwork/ticketmachine.dm
+++ b/code/modules/paperwork/ticketmachine.dm
@@ -160,8 +160,7 @@
/obj/machinery/ticket_machine/proc/reset_cooldown()
ready = TRUE
-/obj/machinery/ticket_machine/attack_hand(mob/living/carbon/user)
- . = ..()
+/obj/machinery/ticket_machine/on_attack_hand(mob/living/carbon/user)
INVOKE_ASYNC(src, .proc/attempt_ticket, user)
/obj/machinery/ticket_machine/proc/attempt_ticket(mob/living/carbon/user)
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index 50dae7d6bb..6961ec54bb 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -364,7 +364,7 @@
icon_state_on = "protoemitter_+a"
can_buckle = TRUE
buckle_lying = FALSE
- var/view_range = 12
+ var/view_range = 4.5
var/datum/action/innate/protoemitter/firing/auto
//BUCKLE HOOKS
@@ -379,7 +379,7 @@
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 0
if(buckled_mob.client)
- buckled_mob.client.change_view(CONFIG_GET(string/default_view))
+ buckled_mob.client.view_size.resetToDefault()
auto.Remove(buckled_mob)
. = ..()
@@ -395,7 +395,7 @@
M.pixel_y = 14
layer = 4.1
if(M.client)
- M.client.change_view(view_range)
+ M.client.view_size.setTo(view_range)
if(!auto)
auto = new()
auto.Grant(M, src)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 8cddd5d02f..1369115b0d 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -134,7 +134,7 @@
/obj/item/gun/equipped(mob/living/user, slot)
. = ..()
if(zoomed && user.get_active_held_item() != src)
- zoom(user, FALSE) //we can only stay zoomed in if it's in our hands //yeah and we only unzoom if we're actually zoomed using the gun!!
+ zoom(user, user.dir, FALSE) //we can only stay zoomed in if it's in our hands //yeah and we only unzoom if we're actually zoomed using the gun!!
//called after the gun has successfully fired its chambered ammo.
/obj/item/gun/proc/process_chamber(mob/living/user)
@@ -439,7 +439,7 @@
/obj/item/gun/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_scope_zoom))
- zoom(user)
+ zoom(user, user.dir)
else if(istype(action, alight))
toggle_gunlight()
@@ -554,14 +554,19 @@
. = ..()
if(!.)
var/obj/item/gun/G = target
- G.zoom(owner, FALSE)
+ G.zoom(owner, owner.dir)
/datum/action/item_action/toggle_scope_zoom/Remove(mob/living/L)
var/obj/item/gun/G = target
- G.zoom(L, FALSE)
+ G.zoom(L, L.dir)
return ..()
-/obj/item/gun/proc/zoom(mob/living/user, forced_zoom)
+/obj/item/gun/proc/rotate(atom/thing, old_dir, new_dir)
+ if(ismob(thing))
+ var/mob/lad = thing
+ lad.client.view_size.zoomOut(zoom_out_amt, zoom_amt, new_dir)
+
+/obj/item/gun/proc/zoom(mob/living/user, direct, forced_zoom)
if(!(user?.client))
return
@@ -573,25 +578,11 @@
zoomed = !zoomed
if(zoomed)
- var/_x = 0
- var/_y = 0
- switch(user.dir)
- if(NORTH)
- _y = zoom_amt
- if(EAST)
- _x = zoom_amt
- if(SOUTH)
- _y = -zoom_amt
- if(WEST)
- _x = -zoom_amt
-
- user.client.change_view(zoom_out_amt)
- user.client.pixel_x = world.icon_size*_x
- user.client.pixel_y = world.icon_size*_y
+ RegisterSignal(user, COMSIG_ATOM_DIR_CHANGE, .proc/rotate)
+ user.client.view_size.zoomOut(zoom_out_amt, zoom_amt, direct)
else
- user.client.change_view(CONFIG_GET(string/default_view))
- user.client.pixel_x = 0
- user.client.pixel_y = 0
+ UnregisterSignal(user, COMSIG_ATOM_DIR_CHANGE)
+ user.client.view_size.zoomIn()
/obj/item/gun/handle_atom_del(atom/A)
if(A == chambered)
diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm
index 9210e66f22..00e59d09f8 100644
--- a/code/modules/projectiles/guns/ballistic/automatic.dm
+++ b/code/modules/projectiles/guns/ballistic/automatic.dm
@@ -374,7 +374,7 @@
inaccuracy_modifier = 0.5
zoomable = TRUE
zoom_amt = 10 //Long range, enough to see in front of you, but no tiles behind you.
- zoom_out_amt = 13
+ zoom_out_amt = 5
slot_flags = ITEM_SLOT_BACK
automatic_burst_overlay = FALSE
actions_types = list()
diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm
index 5e250d44e2..9d9f6aeb83 100644
--- a/code/modules/projectiles/guns/misc/beam_rifle.dm
+++ b/code/modules/projectiles/guns/misc/beam_rifle.dm
@@ -69,7 +69,8 @@
//ZOOMING
var/zoom_current_view_increase = 0
- var/zoom_target_view_increase = 10
+ ///The radius you want to zoom by
+ var/zoom_target_view_increase = 9.5
var/zooming = FALSE
var/zoom_lock = ZOOM_LOCK_OFF
var/zooming_angle
@@ -133,7 +134,7 @@
if(zoom_lock == ZOOM_LOCK_OFF)
return
zooming = TRUE
- current_user.client.change_view(world.view + zoom_target_view_increase)
+ current_user.client.view_size.setTo(zoom_target_view_increase)
zoom_current_view_increase = zoom_target_view_increase
/obj/item/gun/energy/beam_rifle/proc/stop_zooming(mob/user)
@@ -146,9 +147,8 @@
user = current_user
if(!user || !user.client)
return FALSE
- animate(user.client, pixel_x = 0, pixel_y = 0, 0, FALSE, LINEAR_EASING, ANIMATION_END_NOW)
+ user.client.view_size.zoomIn()
zoom_current_view_increase = 0
- user.client.change_view(CONFIG_GET(string/default_view))
zooming_angle = 0
current_zoom_x = 0
current_zoom_y = 0
diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm
index df417ad734..b3737a8388 100644
--- a/code/modules/projectiles/projectile/special/rocket.dm
+++ b/code/modules/projectiles/projectile/special/rocket.dm
@@ -73,4 +73,4 @@
explosion(target, 0, 1, 1, 2)
return BULLET_ACT_HIT
//if(istype(target, /turf/closed) || ismecha(target))
- new /obj/item/broken_missile(get_turf(src), 1)
\ No newline at end of file
+ new /obj/item/broken_missile(get_turf(src), 1)
diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
index ed43576a61..cbfbbe2a36 100644
--- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
@@ -335,15 +335,11 @@ datum/status_effect/rebreathing/tick()
duration = 600
/datum/status_effect/timecookie/on_apply()
- if(ishuman(owner))
- var/mob/living/carbon/human/H
- H.physiology.do_after_speed *= 0.95
+ owner.add_actionspeed_modifier(/datum/actionspeed_modifier/timecookie)
return ..()
/datum/status_effect/timecookie/on_remove()
- if(ishuman(owner))
- var/mob/living/carbon/human/H
- H.physiology.do_after_speed /= 0.95
+ owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/timecookie)
return ..()
/datum/status_effect/lovecookie
diff --git a/code/modules/ruins/spaceruin_code/caravanambush.dm b/code/modules/ruins/spaceruin_code/caravanambush.dm
index a7d89f3324..740850524c 100644
--- a/code/modules/ruins/spaceruin_code/caravanambush.dm
+++ b/code/modules/ruins/spaceruin_code/caravanambush.dm
@@ -68,7 +68,7 @@
lock_override = NONE
shuttlePortId = "caravantrade1_custom"
jumpto_ports = list("whiteship_away" = 1, "whiteship_home" = 1, "whiteship_z4" = 1, "caravantrade1_ambush" = 1)
- view_range = 14
+ view_range = 6.5
x_offset = -5
y_offset = -5
designate_time = 100
@@ -92,7 +92,7 @@
lock_override = NONE
shuttlePortId = "caravanpirate_custom"
jumpto_ports = list("caravanpirate_ambush" = 1)
- view_range = 14
+ view_range = 6.5
x_offset = 3
y_offset = -6
@@ -116,7 +116,7 @@
lock_override = NONE
shuttlePortId = "caravansyndicate1_custom"
jumpto_ports = list("caravansyndicate1_ambush" = 1, "caravansyndicate1_listeningpost" = 1)
- view_range = 7
+ view_range = 0
x_offset = 2
y_offset = 0
@@ -140,7 +140,7 @@
lock_override = NONE
shuttlePortId = "caravansyndicate2_custom"
jumpto_ports = list("caravansyndicate2_ambush" = 1, "caravansyndicate1_listeningpost" = 1)
- view_range = 7
+ view_range = 0
x_offset = 0
y_offset = 2
@@ -164,6 +164,6 @@
lock_override = NONE
shuttlePortId = "caravansyndicate3_custom"
jumpto_ports = list("caravansyndicate3_ambush" = 1, "caravansyndicate3_listeningpost" = 1)
- view_range = 10
+ view_range = 2.5
x_offset = -1
y_offset = -3
diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm
index 195e87720c..21a9c6c5d7 100644
--- a/code/modules/shuttle/navigation_computer.dm
+++ b/code/modules/shuttle/navigation_computer.dm
@@ -2,6 +2,7 @@
name = "navigation computer"
desc = "Used to designate a precise transit location for a spacecraft."
jump_action = null
+ should_supress_view_changes = FALSE
var/datum/action/innate/shuttledocker_rotate/rotate_action = new
var/datum/action/innate/shuttledocker_place/place_action = new
var/shuttleId = ""
@@ -10,7 +11,7 @@
var/list/jumpto_ports = list() //hashset of ports to jump to and ignore for collision purposes
var/obj/docking_port/stationary/my_port //the custom docking port placed by this console
var/obj/docking_port/mobile/shuttle_port //the mobile docking port of the connected shuttle
- var/view_range = 7
+ var/view_range = 0
var/x_offset = 0
var/y_offset = 0
var/list/whitelist_turfs = list(/turf/open/space, /turf/open/floor/plating, /turf/open/lava)
@@ -88,7 +89,7 @@
to_add += SSshuttle.hidden_shuttle_turf_images
user.client.images += to_add
- user.client.change_view(view_range)
+ user.client.view_size.setTo(view_range)
/obj/machinery/computer/camera_advanced/shuttle_docker/remove_eye_control(mob/living/user)
..()
@@ -101,7 +102,7 @@
to_remove += SSshuttle.hidden_shuttle_turf_images
user.client.images -= to_remove
- user.client.change_view(CONFIG_GET(string/default_view))
+ user.client.view_size.resetToDefault()
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/placeLandingSpot()
if(designating_target_loc || !current_user)
diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm
index bdbdc08c6f..794f2bcd44 100644
--- a/code/modules/shuttle/syndicate.dm
+++ b/code/modules/shuttle/syndicate.dm
@@ -60,7 +60,7 @@
lock_override = CAMERA_LOCK_STATION
shuttlePortId = "syndicate_custom"
jumpto_ports = list("syndicate_ne" = 1, "syndicate_nw" = 1, "syndicate_n" = 1, "syndicate_se" = 1, "syndicate_sw" = 1, "syndicate_s" = 1)
- view_range = 13
+ view_range = 5.5
x_offset = -7
y_offset = -1
space_turfs_only = FALSE
diff --git a/code/modules/shuttle/white_ship.dm b/code/modules/shuttle/white_ship.dm
index f25fe30f36..66146edea1 100644
--- a/code/modules/shuttle/white_ship.dm
+++ b/code/modules/shuttle/white_ship.dm
@@ -25,7 +25,7 @@
lock_override = NONE
shuttlePortId = "whiteship_custom"
jumpto_ports = list("whiteship_away" = 1, "whiteship_home" = 1, "whiteship_z4" = 1)
- view_range = 18
+ view_range = 10
x_offset = -6
y_offset = -10
designate_time = 100
@@ -36,7 +36,7 @@
shuttleId = "whiteship_pod"
shuttlePortId = "whiteship_pod_custom"
jumpto_ports = list("whiteship_pod_home" = 1)
- view_range = 7
+ view_range = 0
x_offset = -2
y_offset = 0
designate_time = 0
diff --git a/code/modules/spells/spell_types/devil_boons.dm b/code/modules/spells/spell_types/devil_boons.dm
index 8ba106d77b..cf11466d19 100644
--- a/code/modules/spells/spell_types/devil_boons.dm
+++ b/code/modules/spells/spell_types/devil_boons.dm
@@ -43,7 +43,7 @@
for(var/mob/C in targets)
if(!C.client)
continue
- C.client.change_view(input("Select view range:", "Range", 4) in ranges)
+ C.client.view_size.setTo((input("Select view range:", "Range", 4) in ranges) - 7)
/obj/effect/proc_holder/spell/targeted/summon_friend
name = "Summon Friend"
diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html
index 3cab68da6a..60bd358031 100644
--- a/code/modules/tooltip/tooltip.html
+++ b/code/modules/tooltip/tooltip.html
@@ -120,12 +120,17 @@
window.location = 'byond://winset?id='+tooltip.control+';anchor1=0,0;size=999x999';
//Get the real icon size according to the client view
+ //FYI, this bit is even more borrowed from goon, our widescreen broke tooltips so I took a look at how they do it
+ //To improve our code. Thanks gooncoders, very cool
var mapWidth = map['view-size'].x,
mapHeight = map['view-size'].y,
- tilesShown = tooltip.client_view_h
- realIconSize = mapHeight / tilesShown,
- resizeRatio = realIconSize / tooltip.tileSize,
- //Calculate letterboxing offsets
+ tilesShownX = tooltip.client_view_w
+ tilesShownY = tooltip.client_view_h
+ realIconSizeX = mapWidth / tilesShownX,
+ realIconSizeY = mapHeight / tilesShownY,
+ resizeRatioX = realIconSizeX / tooltip.tileSize,
+ resizeRatioY = realIconSizeY / tooltip.tileSize,
+ //Calculate letterboxing offsets
leftOffset = (map.size.x - mapWidth) / 2,
topOffset = (map.size.y - mapHeight) / 2;
@@ -168,7 +173,7 @@
if ((iconX + westOffset) !== enteredX) { //Cursor entered on the offset tile
left = left + (westOffset < 0 ? 1 : -1);
}
- leftOffset = leftOffset + (westOffset * resizeRatio);
+ leftOffset = leftOffset + (westOffset * resizeRatioX);
}
}
@@ -179,13 +184,13 @@
if (northOffset !== 0) {
if ((iconY + northOffset) === enteredY) { //Cursor entered on the original tile
top--;
- topOffset = topOffset - ((tooltip.tileSize + northOffset) * resizeRatio);
+ topOffset = topOffset - ((tooltip.tileSize + northOffset) * resizeRatioY);
} else { //Cursor entered on the offset tile
if (northOffset < 0) { //Offset southwards
- topOffset = topOffset - ((tooltip.tileSize + northOffset) * resizeRatio);
+ topOffset = topOffset - ((tooltip.tileSize + northOffset) * resizeRatioY);
} else { //Offset northwards
top--;
- topOffset = topOffset - (northOffset * resizeRatio);
+ topOffset = topOffset - (northOffset * resizeRatioY);
}
}
}
@@ -198,12 +203,12 @@
}
//Clamp values
- left = (left < 0 ? 0 : (left > tilesShown ? tilesShown : left));
- top = (top < 0 ? 0 : (top > tilesShown ? tilesShown : top));
+ left = (left < 0 ? 0 : (left > tilesShownX ? tilesShownX : left));
+ top = (top < 0 ? 0 : (top > tilesShownY ? tilesShownY : top));
//Calculate where on the screen the popup should appear (below the hovered tile)
- var posX = Math.round(((left - 1) * realIconSize) + leftOffset + tooltip.padding); //-1 to position at the left of the target tile
- var posY = Math.round(((tilesShown - top + 1) * realIconSize) + topOffset + tooltip.padding); //+1 to position at the bottom of the target tile
+ var posX = Math.round(((left - 1) * realIconSizeX) + leftOffset + tooltip.padding); //-1 to position at the left of the target tile
+ var posY = Math.round(((tilesShownY - top + 1) * realIconSizeY) + topOffset + tooltip.padding); //+1 to position at the bottom of the target tile
//alert(mapWidth+' | '+mapHeight+' | '+tilesShown+' | '+realIconSize+' | '+leftOffset+' | '+topOffset+' | '+left+' | '+top+' | '+posX+' | '+posY); //DEBUG
@@ -221,7 +226,7 @@
docHeight = $wrap.outerHeight();
if (posY + docHeight > map.size.y) { //Is the bottom edge below the window? Snap it up if so
- posY = (posY - docHeight) - realIconSize - tooltip.padding;
+ posY = (posY - docHeight) - realIconSizeY - tooltip.padding;
}
//Actually size, move and show the tooltip box
diff --git a/icons/mob/icemoon/icemoon_monsters.dmi b/icons/mob/icemoon/icemoon_monsters.dmi
index 4f0b5df64a..02b39cc3c7 100644
Binary files a/icons/mob/icemoon/icemoon_monsters.dmi and b/icons/mob/icemoon/icemoon_monsters.dmi differ
diff --git a/icons/obj/supplypods.dmi b/icons/obj/supplypods.dmi
index d21da6d53a..68674c4006 100644
Binary files a/icons/obj/supplypods.dmi and b/icons/obj/supplypods.dmi differ
diff --git a/icons/obj/supplypods_32x32.dmi b/icons/obj/supplypods_32x32.dmi
new file mode 100644
index 0000000000..855132f649
Binary files /dev/null and b/icons/obj/supplypods_32x32.dmi differ
diff --git a/icons/radials/taperecorder.dmi b/icons/radials/taperecorder.dmi
new file mode 100644
index 0000000000..6230ab1363
Binary files /dev/null and b/icons/radials/taperecorder.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index ddeb8f16c2..c27d68e7bc 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -22,6 +22,7 @@
#include "code\__DEFINES\_protect.dm"
#include "code\__DEFINES\_tick.dm"
#include "code\__DEFINES\access.dm"
+#include "code\__DEFINES\actionspeed_modifiers.dm"
#include "code\__DEFINES\admin.dm"
#include "code\__DEFINES\antagonists.dm"
#include "code\__DEFINES\atmospherics.dm"
@@ -338,6 +339,7 @@
#include "code\controllers\subsystem\radiation.dm"
#include "code\controllers\subsystem\radio.dm"
#include "code\controllers\subsystem\research.dm"
+#include "code\controllers\subsystem\runechat.dm"
#include "code\controllers\subsystem\server_maint.dm"
#include "code\controllers\subsystem\shuttle.dm"
#include "code\controllers\subsystem\sounds.dm"
@@ -410,6 +412,7 @@
#include "code\datums\spawners_menu.dm"
#include "code\datums\tgs_event_handler.dm"
#include "code\datums\verbs.dm"
+#include "code\datums\view.dm"
#include "code\datums\weakrefs.dm"
#include "code\datums\world_topic.dm"
#include "code\datums\actions\beam_rifle.dm"
@@ -1347,6 +1350,10 @@
#include "code\game\turfs\simulated\wall\reinf_walls.dm"
#include "code\game\turfs\space\space.dm"
#include "code\game\turfs\space\transit.dm"
+#include "code\modules\actionspeed\_actionspeed_modifier.dm"
+#include "code\modules\actionspeed\modifiers\base.dm"
+#include "code\modules\actionspeed\modifiers\mood.dm"
+#include "code\modules\actionspeed\modifiers\status_effects.dm"
#include "code\modules\admin\admin.dm"
#include "code\modules\admin\admin_investigate.dm"
#include "code\modules\admin\admin_ranks.dm"
@@ -2746,6 +2753,7 @@
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\hivelord.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice_demon.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice_whelp.dm"
+#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\lobsterosity.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\mining_mobs.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\polarbear.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\wolf.dm"
diff --git a/tgui/packages/tgui/interfaces/CentcomPodLauncher.js b/tgui/packages/tgui/interfaces/CentcomPodLauncher.js
index 05982b2fbf..a0d507e154 100644
--- a/tgui/packages/tgui/interfaces/CentcomPodLauncher.js
+++ b/tgui/packages/tgui/interfaces/CentcomPodLauncher.js
@@ -1,518 +1,1135 @@
+import { toFixed } from 'common/math';
+import { classes } from 'common/react';
+import { storage } from 'common/storage';
import { multiline } from 'common/string';
-import { Fragment } from 'inferno';
-import { useBackend } from '../backend';
-import { Button, LabeledList, NoticeBox, Section } from '../components';
+import { createUuid } from 'common/uuid';
+import { Component } from 'inferno';
+import { useBackend, useLocalState } from '../backend';
+import { Box, Button, ByondUi, Divider, Flex, Fragment, Input, Knob, LabeledControls, NumberInput, Section } from '../components';
import { Window } from '../layouts';
-export const CentcomPodLauncher = () => {
+const pod_grey = {
+ color: 'grey',
+};
+
+const useCompact = context => {
+ const [compact, setCompact] = useLocalState(context, 'compact', false);
+ const toggleCompact = () => setCompact(!compact);
+ return [compact, toggleCompact];
+};
+
+export const CentcomPodLauncher = (props, context) => {
+ const [compact] = useCompact(context);
return (
+ blueprint pod and edit vars directly
+
+
+ NOTE: Custom sounds from outside the base game files will not save! :(
+
+
/gi,"\n").replace(/<\/?[a-z0-9-_]+[^>]*>/gi,"").replace(/&(nbsp|amp|quot|lt|gt|apos);/g,(function(e,n){return t[n]})).replace(/?([0-9]+);/gi,(function(e,t){var n=parseInt(t,10);return String.fromCharCode(n)})).replace(/?([0-9a-f]+);/gi,(function(e,t){var n=parseInt(t,16);return String.fromCharCode(n)}))};t.buildQueryString=function(e){return Object.keys(e).map((function(t){return encodeURIComponent(t)+"="+encodeURIComponent(e[t])})).join("&")}},function(e,t,n){"use strict";var r={}.hasOwnProperty;e.exports=function(e,t){return r.call(e,t)}},function(e,t,n){"use strict";var r=n(53),o=n(66),i=n(18),a=n(12),c=n(72),u=[].push,s=function(e){var t=1==e,n=2==e,s=3==e,l=4==e,f=6==e,d=5==e||f;return function(p,h,g,v){for(var m,y,b=i(p),x=o(b),w=r(h,g,3),_=a(x.length),E=0,k=v||c,S=t?k(p,_):n?k(p,0):undefined;_>E;E++)if((d||E in x)&&(y=w(m=x[E],E,b),e))if(t)S[E]=y;else if(y)switch(e){case 3:return!0;case 5:return m;case 6:return E;case 2:u.call(S,m)}else if(l)return!1;return f?-1:s||l?l:S}};e.exports={forEach:s(0),map:s(1),filter:s(2),some:s(3),every:s(4),find:s(5),findIndex:s(6)}},function(e,t,n){"use strict";t.__esModule=!0,t.useSelector=t.useDispatch=t.createAction=t.combineReducers=t.applyMiddleware=t.createStore=void 0;n(0);var r=n(35);function o(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return i(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return i(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);nu||n!=n?l*Infinity:l*n}},function(e,t,n){"use strict";var r=n(7).isFinite;e.exports=Number.isFinite||function(e){return"number"==typeof e&&r(e)}},function(e,t,n){"use strict";var r=n(7),o=n(62).trim,i=n(92),a=r.parseFloat,c=1/a(i+"-0")!=-Infinity;e.exports=c?function(e){var t=o(String(e)),n=a(t);return 0===n&&"-"==t.charAt(0)?-0:n}:a},function(e,t,n){"use strict";var r=n(36);e.exports=function(e){if("number"!=typeof e&&"Number"!=r(e))throw TypeError("Incorrect invocation");return+e}},function(e,t,n){"use strict";var r=n(9),o=n(5),i=n(71),a=n(115),c=n(82),u=n(18),s=n(66),l=Object.assign,f=Object.defineProperty;e.exports=!l||o((function(){if(r&&1!==l({b:1},l(f({},"a",{enumerable:!0,get:function(){f(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},t={},n=Symbol();return e[n]=7,"abcdefghijklmnopqrst".split("").forEach((function(e){t[e]=e})),7!=l({},e)[n]||"abcdefghijklmnopqrst"!=i(l({},t)).join("")}))?function(e,t){for(var n=u(e),o=arguments.length,l=1,f=a.f,d=c.f;o>l;)for(var p,h=s(arguments[l++]),g=f?i(h).concat(f(h)):i(h),v=g.length,m=0;v>m;)p=g[m++],r&&!d.call(h,p)||(n[p]=h[p]);return n}:l},function(e,t,n){"use strict";var r=n(121),o=n(85);e.exports=r?{}.toString:function(){return"[object "+o(this)+"]"}},function(e,t,n){"use strict";var r=n(7);e.exports=function(e,t){var n=r.console;n&&n.error&&(1===arguments.length?n.error(e):n.error(e,t))}},function(e,t,n){"use strict";var r=n(37);e.exports=function(e){var t=r(e);if(t<0)throw RangeError("The argument can't be less than 0");return t}},function(e,t,n){"use strict";t.__esModule=!0,t._CI=Ae,t._HI=B,t._M=Te,t._MCCC=Le,t._ME=Ie,t._MFCC=Ve,t._MP=Ce,t._MR=ye,t.__render=je,t.createComponentVNode=function(e,t,n,r,o){var a=new T(1,null,null,e=function(e,t){if(12&e)return e;if(t.prototype&&t.prototype.render)return 4;if(t.render)return 32776;return 8}(e,t),r,function(e,t,n){var r=(32768&e?t.render:t).defaultProps;if(i(r))return n;if(i(n))return l(r,null);return N(n,r)}(e,t,n),function(e,t,n){if(4&e)return n;var r=(32768&e?t.render:t).defaultHooks;if(i(r))return n;if(i(n))return r;return N(n,r)}(e,t,o),t);k.createVNode&&k.createVNode(a);return a},t.createFragment=M,t.createPortal=function(e,t){var n=B(e);return O(1024,1024,null,n,0,null,n.key,t)},t.createRef=function(){return{current:null}},t.createRenderer=function(e){return function(t,n,r,o){e||(e=t),Fe(n,e,r,o)}},t.createTextVNode=I,t.createVNode=O,t.directClone=L,t.findDOMfromVNode=b,t.forwardRef=function(e){return{render:e}},t.getFlagsForElementVnode=function(e){switch(e){case"svg":return 32;case"input":return 64;case"select":return 256;case"textarea":return 128;case"$F":return 8192;default:return 1}},t.linkEvent=function(e,t){if(c(t))return{data:e,event:t};return null},t.normalizeProps=function(e){var t=e.props;if(t){var n=e.flags;481&n&&(void 0!==t.children&&i(e.children)&&P(e,t.children),void 0!==t.className&&(e.className=t.className||null,t.className=undefined)),void 0!==t.key&&(e.key=t.key,t.key=undefined),void 0!==t.ref&&(e.ref=8&n?l(e.ref,t.ref):t.ref,t.ref=undefined)}return e},t.render=Fe,t.rerender=He,t.version=t.options=t.Fragment=t.EMPTY_OBJ=t.Component=void 0;var r=Array.isArray;function o(e){var t=typeof e;return"string"===t||"number"===t}function i(e){return null==e}function a(e){return null===e||!1===e||!0===e||void 0===e}function c(e){return"function"==typeof e}function u(e){return"string"==typeof e}function s(e){return null===e}function l(e,t){var n={};if(e)for(var r in e)n[r]=e[r];if(t)for(var o in t)n[o]=t[o];return n}function f(e){return!s(e)&&"object"==typeof e}var d={};t.EMPTY_OBJ=d;function p(e){return e.substr(2).toLowerCase()}function h(e,t){e.appendChild(t)}function g(e,t,n){s(n)?h(e,t):e.insertBefore(t,n)}function v(e,t){e.removeChild(t)}function m(e){for(var t=0;t
\n":"'+(n?e:Y(e,!0))+"
\n"},t.blockquote=function(e){return""+(n?e:Y(e,!0))+"\n"+e+"
\n"},t.html=function(e){return e},t.heading=function(e,t,n,r){return this.options.headerIds?"
\n":"
\n"},t.list=function(e,t,n){var r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+""+r+">\n"},t.listitem=function(e){return"\n\n"+e+"\n"+t+"
\n"},t.tablerow=function(e){return"\n"+e+" \n"},t.tablecell=function(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' align="'+t.align+'">':"<"+n+">")+e+""+n+">\n"},t.strong=function(e){return""+e+""},t.em=function(e){return""+e+""},t.codespan=function(e){return""+e+""},t.br=function(){return this.options.xhtml?"
":"
"},t.del=function(e){return""+e+""},t.link=function(e,t,n){if(null===(e=z(this.options.sanitize,this.options.baseUrl,e)))return n;var r='"+n+""},t.image=function(e,t,n){if(null===(e=z(this.options.sanitize,this.options.baseUrl,e)))return n;var r='":">"},t.text=function(e){return e},e}(),$=function(){function e(){}var t=e.prototype;return t.strong=function(e){return e},t.em=function(e){return e},t.codespan=function(e){return e},t.del=function(e){return e},t.html=function(e){return e},t.text=function(e){return e},t.link=function(e,t,n){return""+n},t.image=function(e,t,n){return""+n},t.br=function(){return""},e}(),H=function(){function e(){this.seen={}}return e.prototype.slug=function(e){var t=e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-");if(this.seen.hasOwnProperty(t)){var n=t;do{this.seen[n]++,t=n+"-"+this.seen[n]}while(this.seen.hasOwnProperty(t))}return this.seen[t]=0,t},e}(),W=r.defaults,q=w.unescape,G=function(){function e(e){this.options=e||W,this.options.renderer=this.options.renderer||new U,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new $,this.slugger=new H}e.parse=function(t,n){return new e(n).parse(t)};var t=e.prototype;return t.parse=function(e,t){void 0===t&&(t=!0);var n,r,o,i,a,c,u,s,l,f,d,p,h,g,v,m,y,b,x="",w=e.length;for(n=0;n
"+Q(u.message+"",!0)+"";throw u}}return ne.options=ne.setOptions=function(e){return X(ne.defaults,e),ee(ne.defaults),ne},ne.getDefaults=J,ne.defaults=te,ne.use=function(e){var t=X({},e);if(e.renderer&&function(){var n=ne.defaults.renderer||new U,r=function(t){var r=n[t];n[t]=function(){for(var o=arguments.length,i=new Array(o),a=0;a
'+(n?e:Y(e,!0))+"\n":""+(n?e:Y(e,!0))+"\n"},t.blockquote=function(e){return"\n"+e+"\n"},t.html=function(e){return e},t.heading=function(e,t,n,r){return this.options.headerIds?"
"+e+"
\n"},t.table=function(e,t){return t&&(t=""+t+""),""+e+""},t.br=function(){return this.options.xhtml?""+Q(u.message+"",!0)+"";throw u}}return ne.options=ne.setOptions=function(e){return X(ne.defaults,e),ee(ne.defaults),ne},ne.getDefaults=J,ne.defaults=te,ne.use=function(e){var t=X({},e);if(e.renderer&&function(){var n=ne.defaults.renderer||new U,r=function(t){var r=n[t];n[t]=function(){for(var o=arguments.length,i=new Array(o),a=0;a
'+(n?e:Y(e,!0))+"\n":""+(n?e:Y(e,!0))+"\n"},t.blockquote=function(e){return"\n"+e+"\n"},t.html=function(e){return e},t.heading=function(e,t,n,r){return this.options.headerIds?"
"+e+"
\n"},t.table=function(e,t){return t&&(t=""+t+""),""+e+""},t.br=function(){return this.options.xhtml?""+Q(u.message+"",!0)+"";throw u}}return ne.options=ne.setOptions=function(e){return X(ne.defaults,e),ee(ne.defaults),ne},ne.getDefaults=J,ne.defaults=te,ne.use=function(e){var t=X({},e);if(e.renderer&&function(){var n=ne.defaults.renderer||new U,r=function(t){var r=n[t];n[t]=function(){for(var o=arguments.length,i=new Array(o),a=0;a