diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm
index 27198fe072..d58594c865 100644
--- a/_maps/map_files/generic/CentCom.dmm
+++ b/_maps/map_files/generic/CentCom.dmm
@@ -2733,10 +2733,7 @@
},
/area/centcom/prison)
"ir" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows2";
- dir = 6
- },
+/turf/closed/indestructible/fakeglass,
/area/centcom/prison)
"is" = (
/obj/structure/table/reinforced,
@@ -4392,12 +4389,6 @@
/obj/structure/flora/grass/both,
/turf/open/floor/plating/asteroid/snow/airless,
/area/syndicate_mothership)
-"mB" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows";
- dir = 1
- },
-/area/syndicate_mothership/control)
"mC" = (
/obj/item/disk/data,
/obj/effect/light_emitter{
@@ -4618,12 +4609,6 @@
icon_state = "alien5"
},
/area/abductor_ship)
-"ng" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows2";
- dir = 1
- },
-/area/syndicate_mothership/control)
"nh" = (
/obj/item/toy/figure/syndie,
/obj/effect/light_emitter{
@@ -5648,12 +5633,6 @@
/obj/effect/turf_decal/bot_white,
/turf/open/floor/plasteel/dark,
/area/shuttle/syndicate/bridge)
-"pE" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows2";
- dir = 6
- },
-/area/syndicate_mothership/control)
"pF" = (
/obj/machinery/door/airlock/centcom{
name = "Auxillary Dock";
@@ -6094,27 +6073,6 @@
"qE" = (
/turf/closed/indestructible/riveted/uranium,
/area/wizard_station)
-"qF" = (
-/turf/closed/indestructible/fakeglass{
- color = "#008000";
- dir = 8;
- icon_state = "fakewindows"
- },
-/area/wizard_station)
-"qG" = (
-/turf/closed/indestructible/fakeglass{
- color = "#008000";
- dir = 8;
- icon_state = "fakewindows2"
- },
-/area/wizard_station)
-"qH" = (
-/turf/closed/indestructible/fakeglass{
- color = "#008000";
- dir = 4;
- icon_state = "fakewindows"
- },
-/area/wizard_station)
"qI" = (
/turf/open/floor/plasteel/vault/side,
/area/shuttle/syndicate/bridge)
@@ -6807,7 +6765,9 @@
/turf/open/floor/plating/airless,
/area/syndicate_mothership/control)
"sq" = (
-/obj/machinery/computer/shuttle/white_ship,
+/obj/machinery/computer/shuttle/white_ship{
+ dir = 4
+ },
/obj/effect/turf_decal/stripes/line{
dir = 5
},
@@ -7141,24 +7101,6 @@
dir = 5
},
/area/shuttle/syndicate/hallway)
-"tb" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows";
- dir = 9
- },
-/area/syndicate_mothership/control)
-"tc" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows2";
- dir = 8
- },
-/area/syndicate_mothership/control)
-"td" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows";
- dir = 4
- },
-/area/syndicate_mothership/control)
"te" = (
/obj/structure/table/wood,
/obj/item/reagent_containers/food/snacks/pizzaslice/mushroom,
@@ -7214,14 +7156,6 @@
},
/turf/open/floor/plating,
/area/shuttle/assault_pod)
-"tm" = (
-/turf/open/floor/plating/asteroid/snow/airless,
-/obj/machinery/porta_turret/syndicate/pod,
-/turf/closed/wall/mineral/plastitanium{
- dir = 1;
- icon_state = "diagonalWall3"
- },
-/area/shuttle/assault_pod)
"tn" = (
/obj/effect/turf_decal/stripes/line{
dir = 10
@@ -7229,7 +7163,9 @@
/turf/open/floor/plating/airless,
/area/syndicate_mothership/control)
"to" = (
-/obj/machinery/computer/shuttle/ferry,
+/obj/machinery/computer/shuttle/ferry{
+ dir = 4
+ },
/obj/effect/turf_decal/stripes/line{
dir = 6
},
@@ -7520,13 +7456,6 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/centcom/evac)
-"tW" = (
-/turf/closed/indestructible/fakeglass{
- color = "#008000";
- dir = 6;
- icon_state = "fakewindows2"
- },
-/area/wizard_station)
"tX" = (
/obj/machinery/door/airlock{
icon = 'icons/obj/doors/airlocks/station/uranium.dmi';
@@ -7568,11 +7497,16 @@
},
/area/shuttle/syndicate/hallway)
"uc" = (
-/obj/machinery/porta_turret/syndicate{
- dir = 4
+/obj/structure/chair{
+ dir = 4;
+ name = "tactical chair"
},
-/turf/closed/wall/mineral/plastitanium,
-/area/shuttle/syndicate/hallway)
+/obj/effect/turf_decal/bot_white,
+/obj/machinery/light{
+ dir = 8
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/syndicate/airlock)
"ud" = (
/obj/machinery/door/poddoor/shutters{
id = "nukeop_ready";
@@ -7826,12 +7760,6 @@
},
/turf/open/floor/plating,
/area/syndicate_mothership/control)
-"uK" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows";
- dir = 8
- },
-/area/syndicate_mothership/control)
"uL" = (
/obj/machinery/button/door{
id = "nukeop_ready";
@@ -8076,47 +8004,6 @@
"vq" = (
/turf/closed/wall/mineral/plastitanium,
/area/shuttle/syndicate/airlock)
-"vr" = (
-/obj/docking_port/stationary{
- area_type = /area/syndicate_mothership;
- baseturf_type = /turf/open/floor/plating/asteroid/snow;
- dheight = 9;
- dir = 2;
- dwidth = 5;
- height = 24;
- id = "syndicate_away";
- name = "syndicate recon outpost";
- turf_type = /turf/open/floor/plating/asteroid/snow;
- width = 18
- },
-/obj/machinery/door/poddoor{
- id = "smindicate";
- name = "outer blast door"
- },
-/obj/machinery/button/door{
- id = "smindicate";
- name = "external door control";
- pixel_x = -26;
- req_access_txt = "150"
- },
-/obj/docking_port/mobile{
- dheight = 9;
- dir = 2;
- dwidth = 5;
- height = 24;
- id = "syndicate";
- name = "syndicate infiltrator";
- port_direction = 1;
- roundstart_move = "syndicate_away";
- hidden = 1;
- width = 18
- },
-/obj/structure/fans/tiny,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/turf/open/floor/mineral/plastitanium,
-/area/shuttle/syndicate/airlock)
"vs" = (
/obj/structure/sign/securearea{
desc = "A warning sign which reads 'EXTERNAL AIRLOCK'";
@@ -8434,14 +8321,6 @@
},
/turf/open/floor/carpet,
/area/wizard_station)
-"we" = (
-/obj/structure/sign/securearea{
- desc = "A warning sign which reads 'FOURTH WALL'.";
- name = "\improper FOURTH WALL";
- pixel_x = -32
- },
-/turf/open/floor/plating/asteroid/snow/airless,
-/area/syndicate_mothership)
"wf" = (
/obj/machinery/portable_atmospherics/canister/oxygen,
/obj/machinery/light{
@@ -8464,31 +8343,6 @@
dir = 8
},
/area/shuttle/syndicate/hallway)
-"wi" = (
-/obj/item/storage/toolbox/syndicate,
-/obj/item/crowbar/red,
-/obj/structure/table/reinforced,
-/obj/machinery/light{
- dir = 8
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 10
- },
-/turf/open/floor/mineral/plastitanium,
-/area/shuttle/syndicate/airlock)
-"wj" = (
-/obj/effect/turf_decal/stripes/line,
-/turf/open/floor/mineral/plastitanium,
-/area/shuttle/syndicate/airlock)
-"wk" = (
-/obj/structure/chair{
- name = "tactical chair"
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 6
- },
-/turf/open/floor/mineral/plastitanium,
-/area/shuttle/syndicate/airlock)
"wl" = (
/obj/machinery/light,
/turf/open/floor/wood,
@@ -8778,21 +8632,6 @@
dir = 2
},
/area/syndicate_mothership/control)
-"wZ" = (
-/turf/open/floor/plating/asteroid/snow/airless,
-/obj/machinery/porta_turret/syndicate/pod,
-/turf/closed/wall/mineral/plastitanium{
- icon_state = "diagonalWall3"
- },
-/area/shuttle/assault_pod)
-"xa" = (
-/turf/open/floor/plating/asteroid/snow/airless,
-/obj/machinery/porta_turret/syndicate/pod,
-/turf/closed/wall/mineral/plastitanium{
- dir = 4;
- icon_state = "diagonalWall3"
- },
-/area/shuttle/assault_pod)
"xb" = (
/obj/docking_port/stationary{
dir = 8;
@@ -8982,21 +8821,6 @@
/obj/structure/window/plastitanium,
/turf/open/floor/plating,
/area/shuttle/syndicate/airlock)
-"xE" = (
-/obj/structure/chair{
- dir = 1;
- name = "tactical chair"
- },
-/obj/effect/turf_decal/bot_white,
-/turf/open/floor/plasteel/dark,
-/area/shuttle/syndicate/airlock)
-"xF" = (
-/obj/structure/rack,
-/obj/item/clothing/suit/space/syndicate/black/red,
-/obj/item/clothing/head/helmet/space/syndicate/black/red,
-/obj/effect/turf_decal/bot_white,
-/turf/open/floor/plasteel/dark,
-/area/shuttle/syndicate/airlock)
"xG" = (
/turf/open/floor/plasteel/dark,
/area/syndicate_mothership/control)
@@ -9640,13 +9464,6 @@
dir = 1
},
/area/centcom/evac)
-"zn" = (
-/turf/closed/indestructible/fakeglass{
- color = "#008000";
- dir = 1;
- icon_state = "fakewindows"
- },
-/area/wizard_station)
"zo" = (
/obj/structure/destructible/cult/tome,
/turf/open/floor/engine/cult,
@@ -9808,13 +9625,6 @@
},
/turf/open/floor/plating/asteroid,
/area/centcom/evac)
-"zM" = (
-/turf/closed/indestructible/fakeglass{
- color = "#008000";
- dir = 1;
- icon_state = "fakewindows2"
- },
-/area/wizard_station)
"zN" = (
/obj/structure/bookcase/random/reference,
/turf/open/floor/engine/cult,
@@ -13147,22 +12957,7 @@
},
/area/tdome/tdomeobserve)
"Il" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows";
- dir = 8
- },
-/area/tdome/tdomeobserve)
-"Im" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows2";
- dir = 8
- },
-/area/tdome/tdomeobserve)
-"In" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows";
- dir = 4
- },
+/turf/closed/indestructible/fakeglass,
/area/tdome/tdomeobserve)
"Io" = (
/obj/item/storage/box/matches{
@@ -13323,13 +13118,6 @@
dir = 4
},
/area/tdome/arena)
-"IK" = (
-/obj/machinery/door/poddoor{
- id = "thunderdome";
- name = "Thunderdome Blast Door"
- },
-/turf/open/floor/plasteel,
-/area/tdome/arena)
"IL" = (
/obj/effect/landmark/thunderdome/one,
/obj/effect/turf_decal/stripes/line{
@@ -13351,13 +13139,6 @@
},
/turf/open/floor/plasteel,
/area/tdome/arena)
-"IO" = (
-/obj/machinery/door/poddoor{
- id = "thunderdomegen";
- name = "General Supply"
- },
-/turf/open/floor/plasteel,
-/area/tdome/arena)
"IP" = (
/obj/structure/rack,
/obj/item/clothing/under/color/green,
@@ -13638,13 +13419,6 @@
/obj/effect/turf_decal/loading_area,
/turf/open/floor/plasteel,
/area/tdome/arena)
-"JE" = (
-/obj/machinery/door/poddoor{
- id = "thunderdomehea";
- name = "Heavy Supply"
- },
-/turf/open/floor/plasteel,
-/area/tdome/arena)
"JF" = (
/obj/machinery/computer/camera_advanced/abductor{
team_number = 1
@@ -13669,22 +13443,7 @@
/turf/open/floor/plasteel,
/area/tdome/arena)
"JI" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows";
- dir = 8
- },
-/area/tdome/tdomeadmin)
-"JJ" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows2";
- dir = 8
- },
-/area/tdome/tdomeadmin)
-"JK" = (
-/turf/closed/indestructible/fakeglass{
- icon_state = "fakewindows";
- dir = 4
- },
+/turf/closed/indestructible/fakeglass,
/area/tdome/tdomeadmin)
"JL" = (
/obj/structure/rack,
@@ -13769,11 +13528,11 @@
/area/tdome/tdomeadmin)
"JV" = (
/turf/closed/wall/mineral/titanium,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"JW" = (
/obj/machinery/status_display,
/turf/closed/wall/mineral/titanium,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"JX" = (
/obj/machinery/door/firedoor,
/obj/effect/turf_decal/stripes/line{
@@ -13816,16 +13575,16 @@
/area/tdome/tdomeadmin)
"Kd" = (
/turf/open/floor/mineral/titanium,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"Ke" = (
/turf/open/floor/mineral/plastitanium,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"Kf" = (
/obj/machinery/computer/emergency_shuttle{
dir = 8
},
/turf/open/floor/mineral/titanium,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"Kg" = (
/turf/closed/indestructible/fakedoor{
name = "Thunderdome Admin"
@@ -13865,18 +13624,18 @@
},
/obj/docking_port/mobile/emergency/backup,
/turf/open/floor/plating,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"Kl" = (
/obj/structure/chair/office/light{
dir = 4
},
/turf/open/floor/mineral/titanium,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"Km" = (
/obj/structure/table/wood,
/obj/item/paper/fluff/stations/centcom/broken_evac,
/turf/open/floor/mineral/titanium,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"Kn" = (
/obj/structure/bookcase/random,
/turf/open/floor/plasteel/vault{
@@ -14012,7 +13771,7 @@
/obj/structure/table/wood,
/obj/item/book/manual/random,
/turf/open/floor/mineral/titanium,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"KA" = (
/obj/structure/flora/ausbushes/lavendergrass,
/obj/structure/flora/ausbushes/sparsegrass,
@@ -14044,13 +13803,13 @@
dir = 8
},
/turf/open/floor/mineral/titanium,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"KF" = (
/obj/machinery/light{
dir = 4
},
/turf/open/floor/mineral/titanium,
-/area/shuttle/escape)
+/area/shuttle/escape/backup)
"KG" = (
/obj/structure/flora/ausbushes/lavendergrass,
/obj/structure/flora/ausbushes/sparsegrass,
@@ -14132,8 +13891,11 @@
/turf/closed/wall/mineral/titanium/interior,
/area/centcom/evac)
"KT" = (
-/turf/closed/wall/mineral/titanium/interior,
-/area/centcom/evac)
+/obj/machinery/computer/camera_advanced{
+ dir = 4
+ },
+/turf/open/floor/wood,
+/area/wizard_station)
"KU" = (
/obj/structure/closet/emcloset,
/turf/open/floor/mineral/titanium/blue,
@@ -14412,7 +14174,9 @@
/turf/open/floor/mineral/titanium/blue,
/area/centcom/evac)
"LP" = (
-/obj/machinery/computer/shuttle,
+/obj/machinery/computer/shuttle{
+ dir = 1
+ },
/turf/open/floor/mineral/titanium/blue,
/area/centcom/evac)
"LQ" = (
@@ -14541,106 +14305,97 @@
},
/turf/open/floor/plasteel,
/area/tdome/arena)
-"Mj" = (
-/obj/machinery/door/poddoor{
- id = "thunderdome";
- name = "Thunderdome Blast Door"
+"Mt" = (
+/obj/structure/chair{
+ dir = 4;
+ name = "tactical chair"
},
-/obj/effect/turf_decal/loading_area{
+/obj/effect/turf_decal/bot_white,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/syndicate/airlock)
+"Mu" = (
+/obj/structure/table/reinforced,
+/obj/item/storage/toolbox/syndicate,
+/obj/item/crowbar/red,
+/obj/effect/turf_decal/stripes/line{
+ dir = 9
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/syndicate/airlock)
+"Mw" = (
+/obj/effect/turf_decal/stripes/line{
dir = 8
},
-/turf/open/floor/plasteel,
-/area/tdome/arena)
-"Mk" = (
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/syndicate/airlock)
+"My" = (
+/obj/docking_port/stationary{
+ area_type = /area/syndicate_mothership;
+ baseturf_type = /turf/open/floor/plating/asteroid/snow;
+ dheight = 1;
+ dir = 8;
+ dwidth = 12;
+ height = 17;
+ id = "syndicate_away";
+ name = "syndicate recon outpost";
+ turf_type = /turf/open/floor/plating/asteroid/snow;
+ width = 23
+ },
/obj/machinery/door/poddoor{
- id = "thunderdomegen";
- name = "General Supply"
+ id = "smindicate";
+ name = "outer blast door"
},
-/obj/effect/turf_decal/loading_area{
- dir = 8
+/obj/machinery/button/door{
+ id = "smindicate";
+ name = "external door control";
+ pixel_x = 0;
+ pixel_y = 26;
+ req_access_txt = "150"
},
-/turf/open/floor/plasteel,
-/area/tdome/arena)
-"Ml" = (
-/obj/machinery/door/poddoor{
- id = "thunderdome";
- name = "Thunderdome Blast Door"
+/obj/docking_port/mobile{
+ dheight = 1;
+ dir = 8;
+ dwidth = 12;
+ height = 17;
+ hidden = 1;
+ id = "syndicate";
+ movement_force = list("KNOCKDOWN" = 0, "THROW" = 0);
+ name = "syndicate infiltrator";
+ port_direction = 4;
+ roundstart_move = null;
+ width = 23
},
-/obj/effect/turf_decal/loading_area{
- dir = 8
+/obj/structure/fans/tiny,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
},
-/turf/open/floor/plasteel,
-/area/tdome/arena)
-"Mm" = (
-/obj/machinery/door/poddoor{
- id = "thunderdomegen";
- name = "General Supply"
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/syndicate/airlock)
+"Mz" = (
+/turf/open/floor/plasteel/dark,
+/area/shuttle/syndicate/airlock)
+"MC" = (
+/obj/structure/rack,
+/obj/item/clothing/suit/space/syndicate/black/red,
+/obj/item/clothing/head/helmet/space/syndicate/black/red,
+/obj/effect/turf_decal/bot_white,
+/obj/effect/turf_decal/stripes/line{
+ dir = 10
},
-/obj/effect/turf_decal/loading_area{
- dir = 8
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/syndicate/airlock)
+"MD" = (
+/obj/effect/light_emitter{
+ set_cap = 1;
+ set_luminosity = 4
},
-/turf/open/floor/plasteel,
-/area/tdome/arena)
-"Mn" = (
-/obj/machinery/door/poddoor{
- id = "thunderdome";
- name = "Thunderdome Blast Door"
+/obj/structure/sign/securearea{
+ desc = "A warning sign which reads 'FOURTH WALL'.";
+ name = "\improper FOURTH WALL";
+ pixel_x = -32
},
-/obj/effect/turf_decal/loading_area{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/tdome/arena)
-"Mo" = (
-/obj/machinery/door/poddoor{
- id = "thunderdomegen";
- name = "General Supply"
- },
-/obj/effect/turf_decal/loading_area{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/tdome/arena)
-"Mp" = (
-/obj/machinery/door/poddoor{
- id = "thunderdome";
- name = "Thunderdome Blast Door"
- },
-/obj/effect/turf_decal/loading_area{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/tdome/arena)
-"Mq" = (
-/obj/machinery/door/poddoor{
- id = "thunderdomegen";
- name = "General Supply"
- },
-/obj/effect/turf_decal/loading_area{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/tdome/arena)
-"Mr" = (
-/obj/machinery/door/poddoor{
- id = "thunderdome";
- name = "Thunderdome Blast Door"
- },
-/obj/effect/turf_decal/loading_area{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/tdome/arena)
-"Ms" = (
-/obj/machinery/door/poddoor{
- id = "thunderdomegen";
- name = "General Supply"
- },
-/obj/effect/turf_decal/loading_area{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/tdome/arena)
+/turf/open/floor/plating/asteroid/snow/airless,
+/area/syndicate_mothership)
(1,1,1) = {"
aa
@@ -19189,8 +18944,8 @@ lI
lI
qE
qE
-zn
-zM
+Ax
+Ax
Ax
qE
qE
@@ -19451,7 +19206,7 @@ zN
zo
Bf
qE
-zn
+Ax
Ax
qE
lI
@@ -19699,7 +19454,7 @@ lI
lI
qE
qE
-uC
+KT
vj
ya
qZ
@@ -20231,7 +19986,7 @@ DZ
Eh
qE
qE
-tW
+Ax
qE
lI
lI
@@ -20474,8 +20229,8 @@ vj
xu
qE
qE
-zn
-zM
+Ax
+Ax
Ax
qE
qE
@@ -21233,11 +20988,11 @@ lI
lI
lI
lI
-qF
+Ax
qZ
qZ
qZ
-tW
+Ax
qZ
qZ
qZ
@@ -21249,7 +21004,7 @@ qZ
qZ
qZ
qZ
-tW
+Ax
qZ
qZ
qZ
@@ -21490,7 +21245,7 @@ lI
lI
lI
lI
-qG
+Ax
ra
qZ
qZ
@@ -21514,7 +21269,7 @@ DD
uE
Ec
uE
-tW
+Ax
EX
qZ
qZ
@@ -21747,11 +21502,11 @@ lI
lI
lI
lI
-qH
+Ax
qZ
qZ
qZ
-tW
+Ax
qZ
qZ
qZ
@@ -21763,7 +21518,7 @@ qZ
qZ
qZ
qZ
-tW
+Ax
qZ
qZ
qZ
@@ -22287,7 +22042,7 @@ Ee
Em
qE
qE
-tW
+Ax
qE
qE
qE
@@ -22530,8 +22285,8 @@ uE
xz
qE
qE
-zn
-zM
+Ax
+Ax
Ax
qE
qE
@@ -22785,13 +22540,13 @@ vn
uE
vl
uE
-qF
+Ax
yH
yK
zQ
Az
yK
-qF
+Ax
qZ
qZ
qZ
@@ -23042,13 +22797,13 @@ qE
uF
wQ
wd
-qG
+Ax
yI
zq
yI
AA
yI
-qG
+Ax
qZ
uE
qZ
@@ -23299,13 +23054,13 @@ qE
qE
vn
uE
-qH
+Ax
yJ
zr
yK
zq
yK
-qH
+Ax
qZ
qZ
qE
@@ -23563,7 +23318,7 @@ yI
AB
Bi
qE
-zn
+Ax
Ax
qE
lI
@@ -26361,38 +26116,38 @@ hl
hl
hl
hh
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
aa
aa
aa
@@ -26617,41 +26372,41 @@ hl
hl
hl
hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+kt
+MD
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+hl
hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
+aa
+aa
aa
aa
aa
@@ -26887,27 +26642,25 @@ hl
hl
hl
hl
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+yc
+yd
+yd
+yd
+yd
+yd
+yd
+yd
+yd
+yd
+kt
hl
-hl
-hl
-hl
-hl
-hl
-hl
-we
-hl
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
hh
aa
aa
@@ -26977,6 +26730,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(49,1,1) = {"
aa
@@ -27144,27 +26899,25 @@ hl
hl
hl
hl
-hl
-hl
-hl
-kt
kt
+tY
+tZ
+tZ
+tZ
+tZ
+tZ
+yd
+yL
+zs
+yL
+AC
+Bj
+BT
+Cj
+CS
+Di
kt
hl
-hl
-hl
-hl
-yc
-yd
-yd
-yd
-yd
-yd
-yd
-yd
-yd
-yd
-kt
hh
aa
aa
@@ -27234,6 +26987,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(50,1,1) = {"
aa
@@ -27401,27 +27156,25 @@ hl
hl
hl
hl
-hl
-hl
-hl
-hl
-tY
-tZ
-tZ
-tZ
-tZ
-tZ
-yd
-yL
-zs
-yL
-AC
-Bj
-BT
-Cj
-CS
-Di
kt
+tZ
+uG
+vo
+vo
+vo
+xA
+yd
+yM
+zt
+zR
+zR
+Bk
+zR
+Ck
+CS
+Dj
+kt
+hl
hh
aa
aa
@@ -27491,6 +27244,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(51,1,1) = {"
aa
@@ -27652,33 +27407,31 @@ hl
hl
hl
hl
-hl
-hl
-hl
-hl
-hl
-hl
-hl
-hl
-hl
+kt
+kt
+kt
+kt
+kt
+kt
kt
tZ
-uG
-vo
-vo
-vo
-xA
-yd
-yM
+uH
+uH
+uH
+uH
+uH
+ye
+yN
zt
-zR
-zR
-Bk
-zR
-Ck
+zS
+AD
+Bl
+BU
+Cl
CS
-Dj
+Dk
kt
+hl
hh
aa
aa
@@ -27748,6 +27501,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(52,1,1) = {"
aa
@@ -27909,33 +27664,31 @@ hl
hl
my
hl
-hl
-kt
-kt
+oS
+oT
+oT
+oT
+oT
hl
hl
-hl
-hl
-hl
-hl
-kt
tZ
uH
uH
uH
uH
uH
-ye
-yN
+yd
+yO
zt
-zS
-AD
-Bl
-BU
-Cl
-CS
-Dk
+zT
+AE
+Bm
+yf
+yd
+yd
+Dl
kt
+hl
hh
aa
aa
@@ -28005,6 +27758,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(53,1,1) = {"
aa
@@ -28166,33 +27921,31 @@ hl
hl
hl
hl
-hl
-kt
-hl
-oS
oT
+px
+pR
+qI
oT
-oT
-oT
-hl
+rY
hl
tZ
-uH
-uH
-uH
-uH
-uH
+uI
+vp
+wf
+wR
+xB
yd
-yO
+yP
zt
zT
AE
-Bm
-yf
+Bn
yd
-yd
-Dl
+hl
+hl
kt
+kt
+hl
hh
aa
aa
@@ -28262,6 +28015,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(54,1,1) = {"
aa
@@ -28423,33 +28178,31 @@ hl
hl
hl
hl
-hl
-kt
-hl
-oT
-px
-pR
+oU
+py
+pS
qI
oT
-rY
-hl
+rZ
+rZ
tZ
-uI
-vp
-wf
-wR
-xB
+tZ
+tZ
+tZ
+wS
+xC
+yf
+yQ
+yQ
+zU
+yQ
yd
-yP
-zt
-zT
-AE
-Bn
yd
+rZ
+rZ
+kt
hl
hl
-kt
-kt
hh
aa
aa
@@ -28519,6 +28272,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(55,1,1) = {"
aa
@@ -28680,31 +28435,29 @@ hl
hl
hl
nx
-hl
-kt
-hl
oU
-py
-pS
+pz
+pT
qI
-oT
-rZ
-rZ
-tZ
-tZ
-tZ
-tZ
-wS
-xC
-yf
-yQ
-yQ
-zU
-yQ
-yd
-yd
-rZ
-rZ
+rb
+sa
+sY
+ua
+sY
+sY
+wg
+sb
+sb
+sb
+sb
+zu
+zV
+AF
+Bo
+BV
+Cm
+CT
+kt
hl
hl
hh
@@ -28776,6 +28529,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(56,1,1) = {"
aa
@@ -28937,31 +28692,29 @@ hl
hl
hl
hl
-hl
-kt
-hl
oU
-pz
-pT
+pA
+pU
qI
-rb
-sa
-sY
-ua
-sY
-sY
-wg
+rc
sb
+sZ
+sZ
+sZ
sb
+wh
sb
-sb
-zu
+sZ
+sZ
+sZ
+sZ
zV
AF
Bo
-BV
+BW
Cm
-CT
+CU
+kt
hl
hl
hh
@@ -29033,6 +28786,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(57,1,1) = {"
aa
@@ -29194,31 +28949,29 @@ hl
my
hl
hl
-hl
-kt
-hl
oU
-pA
-pU
+pB
+pT
qI
-rc
+oT
+sc
+ta
+ub
+ta
+ta
+wg
sb
-sZ
-sZ
-sZ
sb
-wh
sb
-sZ
-sZ
-sZ
-sZ
+sb
+zv
zV
AF
Bo
-BW
+BV
Cm
-CU
+CV
+kt
hl
hl
hh
@@ -29290,6 +29043,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(58,1,1) = {"
aa
@@ -29451,31 +29206,29 @@ hl
hl
hl
hl
-hl
-kt
-hl
oU
-pB
-pT
+pC
+pV
qI
oT
-sc
-ta
-ub
-ta
-ta
-wg
-sb
-sb
-sb
-sb
-zv
-zV
-AF
-Bo
-BV
-Cm
-CV
+rZ
+rZ
+vq
+vq
+vq
+vq
+wT
+xD
+yg
+yR
+yR
+zW
+yR
+yh
+yh
+rZ
+rZ
+kt
hl
hl
hh
@@ -29547,6 +29300,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(59,1,1) = {"
aa
@@ -29708,32 +29463,30 @@ hl
hl
hl
hl
-hl
-kt
-hl
-oU
-pC
-pV
+oT
+pD
+pW
qI
oT
-rZ
-rZ
-uc
-rZ
-vq
-vq
-wT
-xD
-yg
-yR
-yR
-zW
-yR
-yh
-yh
-rZ
-rZ
+sd
hl
+vq
+Mt
+Mt
+uc
+Mz
+Mt
+yh
+yS
+zw
+zX
+AG
+Bp
+yh
+hl
+hl
+kt
+kt
hl
hh
aa
@@ -29804,6 +29557,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(60,1,1) = {"
aa
@@ -29965,33 +29720,31 @@ hl
hl
hl
hl
-hl
-kt
-hl
+oV
oT
-pD
-pW
-qI
oT
-sd
-tb
-ng
-nz
+oT
+oT
+hl
+hl
vq
-wi
wU
-xE
+wU
+wU
+wU
+wU
yh
-yS
+yT
zw
zX
AG
-Bp
+Bq
+yg
yh
-hl
-hl
-kt
+yh
+Dm
kt
+hl
hh
aa
aa
@@ -30061,6 +29814,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(61,1,1) = {"
aa
@@ -30222,33 +29977,31 @@ hl
mz
hl
my
-hl
kt
-hl
-oV
-oT
-oT
-oT
-oT
-hl
-tc
-ll
-uJ
-vr
-wj
+kt
+kt
+kt
+kt
+kt
+kt
+vq
wU
-xE
-yh
-yT
+wU
+wU
+wU
+wU
+yi
+yU
zw
-zX
-AG
-Bq
-yg
-yh
-yh
-Dm
+zY
+AH
+Br
+zZ
+Cn
+CW
+Dn
kt
+hl
hh
aa
aa
@@ -30318,6 +30071,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(62,1,1) = {"
aa
@@ -30480,32 +30235,30 @@ mA
hl
hl
hl
+hl
+hl
+nx
+hl
+hl
kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-tc
-ll
-uK
-vs
-wk
-wU
-xF
-yi
-yU
+vq
+Mu
+Mw
+Mw
+Mw
+MC
+yh
+yV
zw
-zY
-AH
-Br
zZ
-Cn
+zZ
+Bs
+zZ
+Co
CW
-Dn
+Do
kt
+hl
hh
aa
aa
@@ -30575,6 +30328,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(63,1,1) = {"
aa
@@ -30737,32 +30492,30 @@ hl
hl
hl
hl
-my
hl
hl
hl
hl
-nx
hl
kt
-tc
-ll
-tc
vt
vq
vq
+My
+vs
vq
yh
-yV
+yW
zw
-zZ
-zZ
-Bs
-zZ
-Co
+Aa
+AI
+Bt
+BX
+Cn
CW
-Do
+Dp
kt
+hl
hh
aa
aa
@@ -30832,6 +30585,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(64,1,1) = {"
aa
@@ -30999,27 +30754,25 @@ hl
hl
hl
hl
-hl
-hl
kt
-tc
-ll
-tc
-hl
-hl
-hl
-vq
+kt
+kt
+nz
+uJ
+nz
+kt
+yj
+yh
+yh
+yh
+yh
+yh
+yh
+yh
+yh
yh
-yW
-zw
-Aa
-AI
-Bt
-BX
-Cn
-CW
-Dp
kt
+hl
hh
aa
aa
@@ -31089,6 +30842,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(65,1,1) = {"
aa
@@ -31250,7 +31005,7 @@ kt
hl
hl
hl
-mz
+hl
hl
hl
hl
@@ -31259,24 +31014,22 @@ hl
hl
hl
kt
-tc
+nz
ll
-tc
-hl
-hl
-hl
-hl
-yj
-yh
-yh
-yh
-yh
-yh
-yh
-yh
-yh
-yh
+nz
kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+hl
hh
aa
aa
@@ -31346,6 +31099,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(66,1,1) = {"
aa
@@ -31514,26 +31269,24 @@ hl
kt
kt
kt
-rd
kt
-td
-ll
-td
+kt
+nz
+uJ
+nz
kt
rd
kt
kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
hh
aa
aa
@@ -31603,6 +31356,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(67,1,1) = {"
aa
@@ -31789,8 +31544,6 @@ hl
hl
hl
hl
-hl
-hl
hh
aa
aa
@@ -31860,6 +31613,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(68,1,1) = {"
aa
@@ -32046,8 +31801,6 @@ hl
hl
hl
hl
-hl
-hl
hh
aa
aa
@@ -32117,6 +31870,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(69,1,1) = {"
aa
@@ -32303,8 +32058,6 @@ hl
hl
BY
hl
-hl
-hl
hh
aa
aa
@@ -32374,6 +32127,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(70,1,1) = {"
aa
@@ -32539,7 +32294,7 @@ kt
kt
kt
kt
-pE
+nz
pY
pZ
rf
@@ -32560,8 +32315,6 @@ hl
BY
Cp
BY
-hl
-hl
hh
aa
aa
@@ -32631,6 +32384,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(71,1,1) = {"
aa
@@ -32817,8 +32572,6 @@ hl
hl
BY
hl
-hl
-hl
hh
aa
aa
@@ -32888,6 +32641,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(72,1,1) = {"
aa
@@ -33074,8 +32829,6 @@ hl
hl
hl
hl
-hl
-hl
hh
aa
aa
@@ -33145,6 +32898,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(73,1,1) = {"
aa
@@ -33303,8 +33058,8 @@ kR
ll
ku
ku
-mB
-ng
+nz
+nz
nz
ku
ku
@@ -33323,7 +33078,7 @@ pZ
ku
ku
ku
-pE
+nz
ku
ku
hh
@@ -33332,8 +33087,8 @@ hh
hh
hh
hh
-hh
-hh
+aa
+aa
aa
aa
aa
@@ -34088,9 +33843,9 @@ rh
ku
ku
ku
-uK
+nz
uJ
-uK
+nz
ku
xH
xG
@@ -34345,9 +34100,9 @@ ri
ri
ku
ku
-tc
+nz
ll
-tc
+nz
ku
xI
xG
@@ -34602,9 +34357,9 @@ ri
sj
ku
ku
-tc
+nz
ll
-tc
+nz
ku
xJ
xG
@@ -34853,15 +34608,15 @@ hl
mA
hl
pG
-pE
+nz
qP
rj
ku
ku
ku
-tc
+nz
ll
-tc
+nz
ku
xK
xG
@@ -35116,9 +34871,9 @@ ku
ku
ku
ku
-tc
+nz
ll
-tc
+nz
ku
ku
ku
@@ -35373,9 +35128,9 @@ ku
sk
sk
sk
-tc
+nz
ll
-tc
+nz
sk
sk
sk
@@ -35630,9 +35385,9 @@ ku
sk
th
ue
-tc
+nz
uJ
-tc
+nz
ue
xL
sk
@@ -56478,7 +56233,7 @@ Ep
HM
HW
HN
-Im
+Il
It
It
It
@@ -56487,7 +56242,7 @@ It
It
It
It
-JJ
+JI
JQ
Ka
Ki
@@ -56735,7 +56490,7 @@ Ep
HN
HW
HN
-Im
+Il
Iu
IF
IF
@@ -56744,7 +56499,7 @@ IF
IF
IF
Iu
-JJ
+JI
JQ
Ka
Ki
@@ -56992,7 +56747,7 @@ Ep
HO
HW
Id
-Im
+Il
It
IG
IG
@@ -57001,7 +56756,7 @@ IG
IG
IG
It
-JJ
+JI
JR
JY
Ki
@@ -57249,7 +57004,7 @@ Ep
HN
HW
HN
-Im
+Il
It
IH
IH
@@ -57258,7 +57013,7 @@ IH
IH
IH
It
-JJ
+JI
JQ
Ka
Ki
@@ -57506,7 +57261,7 @@ Ep
HN
HW
HN
-Im
+Il
It
IH
IH
@@ -57515,7 +57270,7 @@ IH
IH
IH
It
-JJ
+JI
JQ
Ka
Ki
@@ -57763,7 +57518,7 @@ Gy
HN
HW
HN
-Im
+Il
It
IH
IH
@@ -57772,7 +57527,7 @@ Ji
IH
IH
It
-JJ
+JI
JR
JY
Ki
@@ -58020,7 +57775,7 @@ Gx
HL
HW
HN
-Im
+Il
It
IH
IH
@@ -58029,7 +57784,7 @@ Jq
IH
IH
It
-JJ
+JI
JS
Kb
Ki
@@ -58277,7 +58032,7 @@ Ep
HN
HW
HN
-Im
+Il
It
IH
IH
@@ -58286,7 +58041,7 @@ Ji
IH
IH
It
-JJ
+JI
JT
JY
Ki
@@ -58534,7 +58289,7 @@ Ep
HN
HW
HN
-Im
+Il
It
IH
IH
@@ -58543,7 +58298,7 @@ IH
IH
IH
It
-JJ
+JI
JQ
Ka
Ki
@@ -58791,7 +58546,7 @@ Ep
HN
HW
HN
-Im
+Il
It
IH
IH
@@ -58800,7 +58555,7 @@ IH
IH
IH
It
-JJ
+JI
JQ
Ka
Ki
@@ -59048,7 +58803,7 @@ Ep
HO
HW
Id
-Im
+Il
It
II
II
@@ -59057,7 +58812,7 @@ II
II
II
It
-JJ
+JI
JR
JY
Ki
@@ -59305,7 +59060,7 @@ Ep
HM
HW
HN
-Im
+Il
Iu
IF
IF
@@ -59314,7 +59069,7 @@ IF
IF
IF
Iu
-JJ
+JI
JQ
Ka
Ki
@@ -59562,7 +59317,7 @@ Ep
HN
HW
HN
-Im
+Il
It
It
It
@@ -59571,7 +59326,7 @@ It
It
It
It
-JJ
+JI
JQ
Ka
Ki
@@ -59819,7 +59574,7 @@ Gx
HL
HW
HW
-In
+Il
Is
IJ
IY
@@ -59828,7 +59583,7 @@ Jk
Jt
IJ
Is
-JK
+JI
JP
Kc
JY
diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm
index b961c9bd44..b1a9e9e28d 100644
--- a/code/__DEFINES/shuttles.dm
+++ b/code/__DEFINES/shuttles.dm
@@ -75,3 +75,9 @@
#define SHUTTLE_DOCKER_LANDING_CLEAR 1
#define SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT 2
#define SHUTTLE_DOCKER_BLOCKED 3
+
+//Shuttle defaults
+#define SHUTTLE_DEFAULT_TURF_TYPE /turf/open/space
+#define SHUTTLE_DEFAULT_BASETURF_TYPE /turf/open/space
+#define SHUTTLE_DEFAULT_SHUTTLE_AREA_TYPE /area/shuttle
+#define SHUTTLE_DEFAULT_UNDERLYING_AREA /area/space
\ No newline at end of file
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index b9950da7b9..92a94bf428 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -53,6 +53,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/static/restart_clear = 0
var/static/restart_timeout = 0
var/static/restart_count = 0
+
+ var/static/random_seed
//current tick limit, assigned before running a subsystem.
//used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits
@@ -60,6 +62,11 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
/datum/controller/master/New()
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
+
+ if(!random_seed)
+ random_seed = rand(1, 1e9)
+ rand_seed(random_seed)
+
var/list/_subsystems = list()
subsystems = _subsystems
if (Master != src)
diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm
index e638de668e..ca407bb58c 100644
--- a/code/controllers/subsystem/blackbox.dm
+++ b/code/controllers/subsystem/blackbox.dm
@@ -16,6 +16,7 @@ SUBSYSTEM_DEF(blackbox)
/datum/controller/subsystem/blackbox/Initialize()
triggertime = world.time
+ record_feedback("amount", "random_seed", Master.random_seed)
. = ..()
//poll population
diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm
index 39d07ee676..4fa843906c 100644
--- a/code/controllers/subsystem/parallax.dm
+++ b/code/controllers/subsystem/parallax.dm
@@ -21,8 +21,8 @@ SUBSYSTEM_DEF(parallax)
return
continue
var/atom/movable/A = C.eye
- if(!A)
- return
+ if(!istype(A))
+ continue
for (A; isloc(A.loc) && !isturf(A.loc); A = A.loc);
if(A != C.movingmob)
diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index 35208d4137..e385e48a10 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -400,7 +400,7 @@ SUBSYSTEM_DEF(shuttle)
if(M.request(getDock(destination)))
return 2
else
- if(M.dock(getDock(destination)) != DOCKING_SUCCESS)
+ if(M.initiate_docking(getDock(destination)) != DOCKING_SUCCESS)
return 2
return 0 //dock successful
@@ -415,7 +415,7 @@ SUBSYSTEM_DEF(shuttle)
if(M.request(D))
return 2
else
- if(M.dock(D) != DOCKING_SUCCESS)
+ if(M.initiate_docking(D) != DOCKING_SUCCESS)
return 2
return 0 //dock successful
diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm
index d8b3b058dd..2cdbf7196d 100644
--- a/code/datums/components/material_container.dm
+++ b/code/datums/components/material_container.dm
@@ -51,7 +51,7 @@
/datum/component/material_container/proc/OnAttackBy(obj/item/I, mob/living/user)
var/list/tc = allowed_typecache
- if(user.a_intent == INTENT_HARM)
+ if(user.a_intent != INTENT_HELP)
return
if((I.flags_2 & (HOLOGRAM_2 | NO_MAT_REDEMPTION_2)) || (tc && !is_type_in_typecache(I, tc)))
to_chat(user, "[parent] won't accept [I]!")
diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm
index 8a29d1b2ac..2910fc4964 100644
--- a/code/game/area/areas/shuttles.dm
+++ b/code/game/area/areas/shuttles.dm
@@ -76,6 +76,9 @@
/area/shuttle/escape
name = "Emergency Shuttle"
+/area/shuttle/escape/backup
+ name = "Backup Emergency Shuttle"
+
/area/shuttle/escape/luxury
name = "Luxurious Emergency Shuttle"
noteleport = TRUE
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 44d6d5abe4..e59bb1692e 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -83,12 +83,23 @@
if(!eyeobj.eye_initialized)
var/camera_location
- for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
- if(!C.can_use() || z_lock.len && !(C.z in z_lock))
- continue
- if(C.network & networks)
- camera_location = get_turf(C)
- break
+ var/turf/myturf = get_turf(src)
+ if(eyeobj.use_static)
+ if((!z_lock.len || (myturf.z in z_lock)) && GLOB.cameranet.checkTurfVis(myturf))
+ camera_location = myturf
+ else
+ for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
+ if(!C.can_use() || z_lock.len && !(C.z in z_lock))
+ continue
+ var/list/network_overlap = networks & C.network
+ if(network_overlap.len)
+ camera_location = get_turf(C)
+ break
+ else
+ camera_location = myturf
+ if(z_lock.len && !(myturf.z in z_lock))
+ camera_location = locate(round(world.maxx/2), round(world.maxy/2), z_lock[1])
+
if(camera_location)
eyeobj.eye_initialized = TRUE
give_eye_control(L)
diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm
index fd66892048..67280cc762 100644
--- a/code/game/machinery/doors/poddoor.dm
+++ b/code/game/machinery/doors/poddoor.dm
@@ -1,66 +1,68 @@
-/obj/machinery/door/poddoor
- name = "blast door"
- desc = "A heavy duty blast door that opens mechanically."
- icon = 'icons/obj/doors/blastdoor.dmi'
- icon_state = "closed"
- var/id = 1
+/obj/machinery/door/poddoor
+ name = "blast door"
+ desc = "A heavy duty blast door that opens mechanically."
+ icon = 'icons/obj/doors/blastdoor.dmi'
+ icon_state = "closed"
+ var/id = 1
sub_door = TRUE
- explosion_block = 3
+ explosion_block = 3
heat_proof = TRUE
safe = FALSE
- max_integrity = 600
- armor = list(melee = 50, bullet = 100, laser = 100, energy = 100, bomb = 50, bio = 100, rad = 100, fire = 100, acid = 70)
- resistance_flags = FIRE_PROOF
- damage_deflection = 70
-
-/obj/machinery/door/poddoor/preopen
- icon_state = "open"
+ max_integrity = 600
+ armor = list(melee = 50, bullet = 100, laser = 100, energy = 100, bomb = 50, bio = 100, rad = 100, fire = 100, acid = 70)
+ resistance_flags = FIRE_PROOF
+ damage_deflection = 70
+
+/obj/machinery/door/poddoor/preopen
+ icon_state = "open"
density = FALSE
- opacity = 0
-
-/obj/machinery/door/poddoor/ert
- desc = "A heavy duty blast door that only opens for dire emergencies."
-
-//special poddoors that open when emergency shuttle docks at centcom
-/obj/machinery/door/poddoor/shuttledock
- var/checkdir = 4 //door won't open if turf in this dir is `turftype`
- var/turftype = /turf/open/space
-
-/obj/machinery/door/poddoor/shuttledock/proc/check()
- var/turf/T = get_step(src, checkdir)
- if(!istype(T, turftype))
- INVOKE_ASYNC(src, .proc/open)
- else
- INVOKE_ASYNC(src, .proc/close)
-
+ opacity = 0
+
+/obj/machinery/door/poddoor/ert
+ desc = "A heavy duty blast door that only opens for dire emergencies."
+
+//special poddoors that open when emergency shuttle docks at centcom
+/obj/machinery/door/poddoor/shuttledock
+ var/checkdir = 4 //door won't open if turf in this dir is `turftype`
+ var/turftype = /turf/open/space
+
+/obj/machinery/door/poddoor/shuttledock/proc/check()
+ var/turf/T = get_step(src, checkdir)
+ if(!istype(T, turftype))
+ INVOKE_ASYNC(src, .proc/open)
+ else
+ INVOKE_ASYNC(src, .proc/close)
+
/obj/machinery/door/poddoor/CollidedWith(atom/movable/AM)
- if(density)
- return 0
- else
- return ..()
-
-//"BLAST" doors are obviously stronger than regular doors when it comes to BLASTS.
-/obj/machinery/door/poddoor/ex_act(severity, target)
- if(severity == 3)
- return
- ..()
-
-/obj/machinery/door/poddoor/do_animate(animation)
- switch(animation)
- if("opening")
- flick("opening", src)
- if("closing")
- flick("closing", src)
-
-/obj/machinery/door/poddoor/update_icon()
- if(density)
- icon_state = "closed"
- else
- icon_state = "open"
-
-/obj/machinery/door/poddoor/try_to_activate_door(mob/user)
- return
-
-/obj/machinery/door/poddoor/try_to_crowbar(obj/item/I, mob/user)
- if(stat & NOPOWER)
- open(1)
+ if(density)
+ return 0
+ else
+ return ..()
+
+//"BLAST" doors are obviously stronger than regular doors when it comes to BLASTS.
+/obj/machinery/door/poddoor/ex_act(severity, target)
+ if(severity == 3)
+ return
+ ..()
+
+/obj/machinery/door/poddoor/do_animate(animation)
+ switch(animation)
+ if("opening")
+ flick("opening", src)
+ playsound(src, 'sound/machines/blastdoor.ogg', 30, 1)
+ if("closing")
+ flick("closing", src)
+ playsound(src, 'sound/machines/blastdoor.ogg', 30, 1)
+
+/obj/machinery/door/poddoor/update_icon()
+ if(density)
+ icon_state = "closed"
+ else
+ icon_state = "open"
+
+/obj/machinery/door/poddoor/try_to_activate_door(mob/user)
+ return
+
+/obj/machinery/door/poddoor/try_to_crowbar(obj/item/I, mob/user)
+ if(stat & NOPOWER)
+ open(1)
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index 393ff3886d..f5611afcd4 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -10,65 +10,72 @@
density = TRUE
pixel_x = -16
layer = FLY_LAYER
- var/cut = FALSE
var/log_amount = 10
/obj/structure/flora/tree/attackby(obj/item/W, mob/user, params)
- if(!cut && log_amount && (!(flags_1 & NODECONSTRUCT_1)))
+ if(log_amount && (!(flags_1 & NODECONSTRUCT_1)))
if(W.sharpness && W.force > 0)
if(W.hitsound)
playsound(get_turf(src), W.hitsound, 100, 0, 0)
user.visible_message("[user] begins to cut down [src] with [W].","You begin to cut down [src] with [W].", "You hear the sound of sawing.")
- if(do_after(user, 1000/W.force, target = user)) //5 seconds with 20 force, 8 seconds with a hatchet, 20 seconds with a shard.
- if(cut)
- return
+ if(do_after(user, 1000/W.force, target = src)) //5 seconds with 20 force, 8 seconds with a hatchet, 20 seconds with a shard.
user.visible_message("[user] fells [src] with the [W].","You fell [src] with the [W].", "You hear the sound of a tree falling.")
playsound(get_turf(src), 'sound/effects/meteorimpact.ogg', 100 , 0, 0)
- icon = 'icons/obj/flora/pinetrees.dmi'
- icon_state = "tree_stump"
- density = FALSE
- pixel_x = -16
- name += " stump"
- cut = TRUE
for(var/i=1 to log_amount)
new /obj/item/grown/log/tree(get_turf(src))
+ var/obj/structure/flora/stump/S = new(loc)
+ S.name = "[name] stump"
+
+ qdel(src)
+
else
return ..()
+/obj/structure/flora/stump
+ name = "stump"
+ desc = "This represents our promise to the crew, and the station itself, to cut down as many trees as possible." //running naked through the trees
+ icon = 'icons/obj/flora/pinetrees.dmi'
+ icon_state = "tree_stump"
+ density = FALSE
+ pixel_x = -16
+
/obj/structure/flora/tree/pine
name = "pine tree"
desc = "A coniferous pine tree."
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
+ var/list/icon_states = list("pine_1", "pine_2", "pine_3")
/obj/structure/flora/tree/pine/Initialize()
- icon_state = "pine_[rand(1, 3)]"
. = ..()
+ if(islist(icon_states && icon_states.len))
+ icon_state = pick(icon_states)
+
/obj/structure/flora/tree/pine/xmas
name = "xmas tree"
desc = "A wondrous decorated Christmas tree."
icon_state = "pine_c"
- var/gifts_under_tree = FALSE
+ icon_states = null
+
+/obj/structure/flora/tree/pine/xmas/presents
+ icon_state = "pinepresents"
+ desc = "A wondrous decorated Christmas tree. It has presents!"
+ var/gift_type = /obj/item/a_gift/anything
var/list/ckeys_that_took = list()
-/obj/structure/flora/tree/pine/xmas/attack_hand(mob/living/user)
- if(!gifts_under_tree)
- return
+/obj/structure/flora/tree/pine/xmas/presents/attack_hand(mob/living/user)
if(!user.ckey)
return
+
if(ckeys_that_took[user.ckey])
- to_chat(user, "You already took your gift.")
+ to_chat(user, "There are no presents with your name on.")
return
to_chat(user, "After a bit of rummaging, you locate a gift with your name on it!")
ckeys_that_took[user.ckey] = TRUE
- var/obj/item/a_gift/anything/A = new
- user.put_in_hands(A)
-
-/obj/structure/flora/tree/pine/xmas/Initialize()
- . = ..()
- icon_state = "pine_c"
+ var/obj/item/G = new gift_type(src)
+ user.put_in_hands(G)
/obj/structure/flora/tree/dead
icon = 'icons/obj/flora/deadtrees.dmi'
diff --git a/code/game/world.dm b/code/game/world.dm
index 2853bb2ef6..a665b8505d 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -37,6 +37,9 @@ GLOBAL_PROTECT(security_mode)
if(fexists(RESTART_COUNTER_PATH))
GLOB.restart_counter = text2num(trim(file2text(RESTART_COUNTER_PATH)))
fdel(RESTART_COUNTER_PATH)
+
+ if("no-init" in params)
+ return
Master.Initialize(10, FALSE)
diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm
index 480ba20b4d..e86aa6d645 100644
--- a/code/modules/admin/fun_balloon.dm
+++ b/code/modules/admin/fun_balloon.dm
@@ -110,26 +110,32 @@
anchored = TRUE
/obj/effect/shuttle_build/New()
- SSshuttle.emergency.dock(SSshuttle.getDock("emergency_home"))
+ SSshuttle.emergency.initiate_docking(SSshuttle.getDock("emergency_home"))
qdel(src)
//Arena
/obj/effect/forcefield/arena_shuttle
name = "portal"
- var/list/warp_points = list()
+ var/list/warp_points
+/obj/effect/forcefield/arena_shuttle/Initialize()
+ . = ..()
+ warp_points = get_area_turfs(/area/shuttle/escape)
+ for(var/thing in warp_points)
+ CHECK_TICK
+ var/turf/T = thing
+ if(istype(T.loc, /area/shuttle/escape/backup))
+ warp_points -= T
+ continue
+ for(var/atom/movable/TAM in T)
+ if(TAM.density && TAM.anchored)
+ warp_points -= T
+ break
/obj/effect/forcefield/arena_shuttle/CollidedWith(atom/movable/AM)
if(!isliving(AM))
return
- if(!warp_points.len)
- warp_points = get_area_turfs(/area/shuttle/escape)
- for(var/turf/T in warp_points)
- for(var/atom/movable/TAM in T)
- if(TAM.density && TAM.anchored)
- warp_points -= T
- break
var/mob/living/L = AM
if(L.pulling && istype(L.pulling, /obj/item/bodypart/head))
diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm
index 471dad12d7..d49a1d194f 100644
--- a/code/modules/events/_event.dm
+++ b/code/modules/events/_event.dm
@@ -60,7 +60,7 @@
triggering = TRUE
if (alertadmins)
- message_admins("Random Event triggering in 10 seconds: [name] ([typepath]) (CANCEL)")
+ message_admins("Random Event triggering in 10 seconds: [name] (CANCEL)")
sleep(100)
var/gamemode = SSticker.mode.config_tag
var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE)
diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm
index 956a214009..040e4209fb 100644
--- a/code/modules/events/holiday/xmas.dm
+++ b/code/modules/events/holiday/xmas.dm
@@ -1,27 +1,3 @@
-//this is an example of a possible round-start event
-/datum/round_event_control/presents
- name = "Presents under Trees (Christmas)"
- holidayID = CHRISTMAS
- typepath = /datum/round_event/presents
- weight = -1 //forces it to be called, regardless of weight
- max_occurrences = 1
- earliest_start = 0
-
-/datum/round_event/presents/start()
- for(var/obj/structure/flora/tree/pine/xmas/xmas in world)
- if(!(xmas.z in GLOB.station_z_levels))
- continue
- xmas.icon_state = "pinepresents"
- xmas.gifts_under_tree = TRUE
- for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list)
- Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
- for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in GLOB.machines)
- Monitor.icon_state = "entertainment_xmas"
-
-/datum/round_event/presents/announce(fake)
- priority_announce("Ho Ho Ho, Merry Xmas!", "Unknown Transmission")
-
-
/obj/item/toy/xmas_cracker
name = "xmas cracker"
icon = 'icons/obj/christmas.dmi'
@@ -65,17 +41,21 @@
/obj/effect/landmark/xmastree
name = "christmas tree spawner"
- var/tree = /obj/structure/flora/tree/pine/xmas
+ var/festive_tree = /obj/structure/flora/tree/pine/xmas
+ var/christmas_tree = /obj/structure/flora/tree/pine/xmas/presents
/obj/effect/landmark/xmastree/Initialize(mapload)
..()
- if(FESTIVE_SEASON in SSevents.holidays)
- new tree(get_turf(src))
+ if((CHRISTMAS in SSevents.holidays) && christmas_tree)
+ new christmas_tree(get_turf(src))
+ else if((FESTIVE_SEASON in SSevents.holidays) && festive_tree)
+ new festive_tree(get_turf(src))
return INITIALIZE_HINT_QDEL
/obj/effect/landmark/xmastree/rdrod
name = "festivus pole spawner"
- tree = /obj/structure/festivus
+ festive_tree = /obj/structure/festivus
+ christmas_tree = null
/datum/round_event_control/santa
name = "Santa is coming to town! (Christmas)"
@@ -92,7 +72,7 @@
priority_announce("Santa is coming to town!", "Unknown Transmission")
/datum/round_event/santa/start()
- var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be santa?", poll_time=150)
+ var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be Santa?", poll_time=150)
if(LAZYLEN(candidates))
var/mob/dead/observer/Z = pick(candidates)
santa = new /mob/living/carbon/human(pick(GLOB.blobstart))
diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm
index dd7d10f896..56b40ab57d 100644
--- a/code/modules/events/pirates.dm
+++ b/code/modules/events/pirates.dm
@@ -206,7 +206,7 @@
if(engines_cooling)
return "[.] - Engines cooling."
-/obj/docking_port/mobile/pirate/dock(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
+/obj/docking_port/mobile/pirate/initiate_docking(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
. = ..()
if(. == DOCKING_SUCCESS && new_dock.z != ZLEVEL_TRANSIT)
engines_cooling = TRUE
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 92dc109bbc..e55b7ed183 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -714,6 +714,8 @@ GLOBAL_LIST_INIT(hallucinations_major, list(
for(var/obj/machinery/door/airlock/A in range(7, target))
if(count>door_number && door_number>0)
break
+ if(!A.density)
+ continue
count++
I = image(A.overlays_file, get_turf(A), "lights_bolts",layer=A.layer+0.1)
doors += I
diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm
index 85605fd2c4..2b24f02a44 100644
--- a/code/modules/holiday/holidays.dm
+++ b/code/modules/holiday/holidays.dm
@@ -394,6 +394,17 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
/datum/holiday/xmas/greet()
return "Have a merry Christmas!"
+/datum/holiday/xmas/celebrate()
+ SSticker.OnRoundstart(CALLBACK(src, .proc/roundstart_celebrate))
+
+/datum/holiday/xmas/proc/roundstart_celebrate()
+ for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in GLOB.machines)
+ Monitor.icon_state = "entertainment_xmas"
+
+ for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list)
+ Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
+
+
/datum/holiday/festive_season
name = FESTIVE_SEASON
begin_day = 1
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 4481de1e36..8bf80eccb8 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -471,7 +471,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set hidden = TRUE
var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT
if(input)
- client.rescale_view(input, 7, max_view)
+ client.rescale_view(input, 15, (max_view*2)+1)
/mob/dead/observer/verb/boo()
set category = "Ghost"
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index 1ff4ebd47a..e3b9f247f8 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -195,8 +195,10 @@
var/trauma_type
if(ispath(trauma))
trauma_type = trauma
+ SSblackbox.record_feedback("tally", "traumas", 1, trauma_type)
traumas += new trauma_type(arglist(list(src, permanent) + arguments))
else
+ SSblackbox.record_feedback("tally", "traumas", 1, trauma.type)
traumas += trauma
trauma.permanent = permanent
@@ -209,6 +211,7 @@
possible_traumas += BT
var/trauma_type = pick(possible_traumas)
+ SSblackbox.record_feedback("tally", "traumas", 1, trauma_type)
traumas += new trauma_type(src, permanent)
//Cure a random trauma of a certain subtype
diff --git a/code/modules/mob/living/inhand_holder.dm b/code/modules/mob/living/inhand_holder.dm
new file mode 100644
index 0000000000..6a2308b621
--- /dev/null
+++ b/code/modules/mob/living/inhand_holder.dm
@@ -0,0 +1,84 @@
+//Generic system for picking up mobs.
+//Currently works for head and hands.
+/obj/item/clothing/head/mob_holder
+ name = "bugged mob"
+ desc = "Yell at coderbrush."
+ icon = null
+ icon_state = ""
+ flags_1 = DROPDEL_1
+ var/mob/living/held_mob
+ var/can_head = TRUE
+ var/destroying = FALSE
+
+/obj/item/clothing/head/mob_holder/Initialize(mapload, mob/living/M, _worn_state, head_icon, lh_icon, rh_icon, _can_head = TRUE)
+ . = ..()
+ can_head = _can_head
+ if(head_icon)
+ alternate_worn_icon = head_icon
+ if(_worn_state)
+ item_state = _worn_state
+ if(lh_icon)
+ lefthand_file = lh_icon
+ if(rh_icon)
+ righthand_file = rh_icon
+ if(!can_head)
+ slot_flags = NONE
+ deposit(M)
+
+/obj/item/clothing/head/mob_holder/Destroy()
+ destroying = TRUE
+ if(held_mob)
+ release(FALSE)
+ return ..()
+
+/obj/item/clothing/head/mob_holder/proc/deposit(mob/living/L)
+ if(!istype(L))
+ return FALSE
+ L.setDir(SOUTH)
+ update_visuals(L)
+ held_mob = L
+ L.forceMove(src)
+ name = L.name
+ desc = L.desc
+ return TRUE
+
+/obj/item/clothing/head/mob_holder/proc/update_visuals(mob/living/L)
+ appearance = L.appearance
+
+/obj/item/clothing/head/mob_holder/proc/release(del_on_release = TRUE)
+ if(!held_mob)
+ if(del_on_release && !destroying)
+ qdel(src)
+ return FALSE
+ if(isliving(loc))
+ var/mob/living/L = loc
+ to_chat(L, "[held_mob] wriggles free!")
+ L.dropItemToGround(src)
+ held_mob.forceMove(get_turf(src))
+ held_mob.reset_perspective()
+ held_mob.setDir(SOUTH)
+ held_mob.visible_message("[held_mob] uncurls!")
+ held_mob = null
+ if(del_on_release && !destroying)
+ qdel(src)
+ return TRUE
+
+/obj/item/clothing/head/mob_holder/relaymove()
+ release()
+
+/obj/item/clothing/head/mob_holder/container_resist()
+ release()
+
+/obj/item/clothing/head/mob_holder/drone/deposit(mob/living/L)
+ . = ..()
+ if(!isdrone(L))
+ qdel(src)
+ name = "drone (hiding)"
+ desc = "This drone is scared and has curled up into a ball!"
+
+/obj/item/clothing/head/mob_holder/drone/update_visuals(mob/living/L)
+ var/mob/living/simple_animal/drone/D = L
+ if(!D)
+ return ..()
+ icon = 'icons/mob/drone.dmi'
+ icon_state = "[D.visualAppearence]_hat"
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 4934f684ab..b54dfb9c32 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1064,4 +1064,32 @@
/mob/living/onTransitZ(old_z,new_z)
..()
- update_z(new_z)
\ No newline at end of file
+ update_z(new_z)
+
+/mob/living/MouseDrop(mob/over)
+ . = ..()
+ var/mob/living/user = usr
+ if(!istype(over) || !istype(user))
+ return
+ if(!over.Adjacent(src) || (user != src) || !canUseTopic(over))
+ return
+ if(can_be_held)
+ mob_try_pickup(over)
+
+/mob/living/proc/mob_pickup(mob/living/L)
+ return
+
+/mob/living/proc/mob_try_pickup(mob/living/user)
+ if(!ishuman(user))
+ return
+ if(user.get_active_held_item())
+ to_chat(user, "Your hands are full!")
+ return FALSE
+ if(buckled)
+ to_chat(user, "[src] is buckled to something!")
+ return FALSE
+ user.visible_message("[user] starts trying to scoop up [src]!")
+ if(!do_after(user, 20, target = src))
+ return FALSE
+ mob_pickup(user)
+ return TRUE
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 50f2ce4db0..9e45693fdc 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -79,4 +79,5 @@
var/list/obj/effect/proc_holder/abilities = list()
- var/registered_z
\ No newline at end of file
+ var/registered_z
+ var/can_be_held = FALSE //whether this can be picked up and held.
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 924ab615b8..91541fccf1 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -11,6 +11,7 @@
health = 500
maxHealth = 500
layer = BELOW_MOB_LAYER
+ can_be_held = TRUE
var/network = "SS13"
var/obj/machinery/camera/current = null
@@ -57,7 +58,10 @@
var/canholo = TRUE
var/obj/item/card/id/access_card = null
var/chassis = "repairbot"
- var/list/possible_chassis = list("cat", "mouse", "monkey", "corgi", "fox", "repairbot", "rabbit")
+ var/list/possible_chassis = list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE, "fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE) //assoc value is whether it can be picked up.
+ var/static/item_head_icon = 'icons/mob/pai_item_head.dmi'
+ var/static/item_lh_icon = 'icons/mob/pai_item_lh.dmi'
+ var/static/item_rh_icon = 'icons/mob/pai_item_rh.dmi'
var/emitterhealth = 20
var/emittermaxhealth = 20
diff --git a/code/modules/mob/living/silicon/pai/pai_shell.dm b/code/modules/mob/living/silicon/pai/pai_shell.dm
index 8a3121166e..dad7d710e7 100644
--- a/code/modules/mob/living/silicon/pai/pai_shell.dm
+++ b/code/modules/mob/living/silicon/pai/pai_shell.dm
@@ -68,9 +68,12 @@
lay_down()
/mob/living/silicon/pai/proc/choose_chassis()
+ if(!isturf(loc) && loc != card)
+ to_chat(src, "You can not change your holochassis composite while not on the ground or in your card!")
+ return FALSE
var/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in possible_chassis
if(!choice)
- return 0
+ return FALSE
chassis = choice
icon_state = "[chassis]"
if(resting)
@@ -103,3 +106,16 @@
/mob/living/silicon/pai/movement_delay()
. = ..()
. += 1 //A bit slower than humans, so they're easier to smash
+
+/mob/living/silicon/pai/mob_pickup(mob/living/L)
+ var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, chassis, item_head_icon, item_lh_icon, item_rh_icon)
+ if(!L.put_in_hands(holder))
+ qdel(holder)
+ else
+ L.visible_message("[L] scoops up [src]!")
+
+/mob/living/silicon/pai/mob_try_pickup(mob/living/user)
+ if(!possible_chassis[chassis])
+ to_chat(user, "[src]'s current form isn't able to be carried!")
+ return FALSE
+ return ..()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index db10f4a81c..5ac72d0ba3 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -205,15 +205,14 @@
"Medical" = /obj/item/robot_module/medical, \
"Miner" = /obj/item/robot_module/miner, \
"Janitor" = /obj/item/robot_module/janitor, \
- "Service" = /obj/item/robot_module/butler, \
- "MediHound" = /obj/item/robot_module/medihound, \
- "Security K9" = /obj/item/robot_module/k9, \
- "Scrub Puppy" = /obj/item/robot_module/scrubpup)
+ "Service" = /obj/item/robot_module/butler)
if(!CONFIG_GET(flag/disable_peaceborg))
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
if(!CONFIG_GET(flag/disable_secborg))
modulelist["Security"] = /obj/item/robot_module/security
+ modulelist += get_cit_modules() //Citadel change - adds Citadel's borg modules.
+
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in modulelist
if(!input_module || module.type != /obj/item/robot_module)
return
@@ -593,39 +592,25 @@
/mob/living/silicon/robot/update_icons()
cut_overlays()
icon_state = module.cyborg_base_icon
- if(module.cyborg_base_icon == "medihound")
- icon = 'icons/mob/widerobot.dmi'
- pixel_x = -16
- if(sleeper_g == 1)
- add_overlay("msleeper_g")
- if(sleeper_r == 1)
- add_overlay("msleeper_r")
- if(stat == DEAD)
- icon_state = "medihound-wreck"
- if(module.cyborg_base_icon == "k9")
- icon = 'icons/mob/widerobot.dmi'
- pixel_x = -16
- if(laser == 1)
- add_overlay("laser")
- if(disabler == 1)
- add_overlay("disabler")
- if(sleeper_g == 1)
- add_overlay("ksleeper_g")
- if(sleeper_r == 1)
- add_overlay("ksleeper_r")
- if(stat == DEAD)
- icon_state = "k9-wreck"
+ //Citadel changes start here - Allows modules to use different icon files, and allows modules to specify a pixel offset
+ icon = (module.cyborg_icon_override ? module.cyborg_icon_override : initial(icon))
- if(module.cyborg_base_icon == "scrubpup")
- icon = 'icons/mob/widerobot.dmi'
- pixel_x = -16
- if(sleeper_g == 1)
- add_overlay("jsleeper_g")
- if(sleeper_r == 1)
- add_overlay("jsleeper_r")
- if(stat == DEAD)
- icon_state = "scrubpup-wreck"
+ if(laser)
+ add_overlay("laser")//Is this even used???
+ if(disabler)
+ add_overlay("disabler")//ditto
+
+ if(sleeper_g && module.sleeper_overlay)
+ add_overlay("[module.sleeper_overlay]_g")
+ if(sleeper_r && module.sleeper_overlay)
+ add_overlay("[module.sleeper_overlay]_r")
+ if(stat == DEAD && module.has_snowflake_deadsprite)
+ icon_state = "[module.cyborg_base_icon]-wreck"
+
+ if(module.cyborg_pixel_offset)
+ pixel_x = module.cyborg_pixel_offset
+ //End of citadel changes
if(module.cyborg_base_icon == "robot")
icon = 'icons/mob/robots.dmi'
@@ -1023,6 +1008,7 @@
designation = module.name
if(hands)
hands.icon_state = module.moduleselect_icon
+ hands.icon = (module.moduleselect_alternate_icon ? module.moduleselect_alternate_icon : initial(hands.icon)) //CITADEL CHANGE - allows module select icons to use a different icon file
if(module.can_be_pushed)
status_flags |= CANPUSH
else
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 26e455106b..b7cb412927 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -336,31 +336,6 @@
can_be_pushed = FALSE
hat_offset = 3
-/obj/item/robot_module/k9
- name = "Security K-9 Unit module"
- basic_modules = list(
- /obj/item/restraints/handcuffs/cable/zipties/cyborg/dog,
- /obj/item/dogborg/jaws/big,
- /obj/item/dogborg/pounce,
- /obj/item/clothing/mask/gas/sechailer/cyborg,
- /obj/item/soap/tongue,
- /obj/item/device/analyzer/nose,
- /obj/item/device/dogborg/sleeper/K9,
- /obj/item/gun/energy/disabler/cyborg,
- /obj/item/pinpointer/crew)
- emag_modules = list(/obj/item/gun/energy/laser/cyborg)
- ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
- /obj/item/clockwork/weapon/ratvarian_spear)
- cyborg_base_icon = "k9"
- moduleselect_icon = "security"
- can_be_pushed = FALSE
- hat_offset = INFINITY
-
-/obj/item/robot_module/k9/do_transform_animation()
- ..()
- to_chat(loc,"While you have picked the security-k9 module, you still have to follow your laws, NOT Space Law. \
- For Asimov, this means you must follow criminals' orders unless there is a law 1 reason not to.")
-
/obj/item/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
var/obj/item/gun/energy/e_gun/advtaser/cyborg/T = locate(/obj/item/gun/energy/e_gun/advtaser/cyborg) in basic_modules
@@ -372,59 +347,6 @@
else
T.charge_tick = 0
-/obj/item/robot_module/medihound
- name = "MediHound module"
- basic_modules = list(
- /obj/item/dogborg/jaws/small,
- /obj/item/device/analyzer/nose,
- /obj/item/soap/tongue,
- /obj/item/device/healthanalyzer,
- /obj/item/device/dogborg/sleeper/medihound,
- /obj/item/twohanded/shockpaddles/hound,
- /obj/item/stack/medical/gauze/cyborg,
- /obj/item/device/sensor_device)
- emag_modules = list(/obj/item/dogborg/pounce)
- ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical,
- /obj/item/clockwork/weapon/ratvarian_spear)
- cyborg_base_icon = "medihound"
- moduleselect_icon = "medical"
- can_be_pushed = FALSE
- hat_offset = INFINITY
-
-/obj/item/robot_module/medihound/do_transform_animation()
- ..()
- to_chat(loc, "Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. \
- You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.")
-
-/obj/item/robot_module/scrubpup
- name = "Janitor"
- basic_modules = list(
- /obj/item/dogborg/jaws/small,
- /obj/item/device/analyzer/nose,
- /obj/item/soap/tongue/scrubpup,
- /obj/item/device/lightreplacer/cyborg,
- /obj/item/device/dogborg/sleeper/compactor)
- emag_modules = list(/obj/item/dogborg/pounce)
- ratvar_modules = list(
- /obj/item/clockwork/slab/cyborg/janitor,
- /obj/item/clockwork/replica_fabricator/cyborg)
- cyborg_base_icon = "scrubpup"
- moduleselect_icon = "janitor"
- hat_offset = INFINITY
- clean_on_move = TRUE
-
-/obj/item/robot_module/scrubpup/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
- ..()
- var/obj/item/device/lightreplacer/LR = locate(/obj/item/device/lightreplacer) in basic_modules
- if(LR)
- for(var/i in 1 to coeff)
- LR.Charge(R)
-
-/obj/item/robot_module/scrubpup/do_transform_animation()
- ..()
- to_chat(loc,"As tempting as it might be, do not begin binging on important items. Eat your garbage responsibly. People are not included under Garbage.")
-
-
/obj/item/robot_module/security/do_transform_animation()
..()
to_chat(loc, "While you have picked the security module, you still have to follow your laws, NOT Space Law. \
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index adc88c5633..4330b58411 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -32,6 +32,7 @@
var/obj/item/inventory_back
var/nofur = 0 //Corgis that have risen past the material plane of existence.
gold_core_spawnable = FRIENDLY_SPAWN
+ can_be_held = TRUE
/mob/living/simple_animal/pet/dog/pug
name = "\improper pug"
@@ -121,7 +122,12 @@
..()
update_corgi_fluff()
-
+/mob/living/simple_animal/pet/dog/corgi/mob_pickup(mob/living/L)
+ var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "corgi", null, 'icons/mob/pets_held_lh.dmi', 'icons/mob/pets_held_rh.dmi', FALSE)
+ if(!L.put_in_hands(holder))
+ qdel(holder)
+ else
+ L.visible_message("[L] scoops up [src]!")
/mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list)
if(usr.stat)
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index ea159a5749..5266f44e98 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -49,6 +49,7 @@
dextrous = TRUE
dextrous_hud_type = /datum/hud/dextrous/drone
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
+ can_be_held = TRUE
var/staticChoice = "static"
var/list/staticChoices = list("static", "blank", "letter", "animal")
var/picked = FALSE //Have we picked our visual appearence (+ colour if applicable)
@@ -67,7 +68,6 @@
var/seeStatic = 1 //Whether we see static instead of mobs
var/visualAppearence = MAINTDRONE //What we appear as
var/hacked = FALSE //If we have laws to destroy the station
- var/can_be_held = TRUE //if assholes can pick us up
var/flavortext = \
"\nDO NOT INTERFERE WITH THE ROUND AS A DRONE OR YOU WILL BE DRONE BANNED\n"+\
"Drones are a ghost role that are allowed to fix the station and build things. Interfering with the round as a drone is against the rules.\n"+\
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
index c0a57e3739..45b188c5ef 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
@@ -4,8 +4,6 @@
//DRONES AS ITEMS//
///////////////////
//Drone shells
-//Drones as hats
-
//DRONE SHELL
/obj/item/drone_shell
@@ -45,45 +43,3 @@
D.admin_spawned = admin_spawned
D.key = user.key
qdel(src)
-
-
-//DRONE HOLDER
-/obj/item/clothing/head/drone_holder//Only exists in someones hand.or on their head
- name = "drone (hiding)"
- desc = "This drone is scared and has curled up into a ball."
- icon = 'icons/mob/drone.dmi'
- icon_state = "drone_maint_hat"
- var/mob/living/simple_animal/drone/drone //stored drone
-
-/obj/item/clothing/head/drone_holder/proc/uncurl()
- if(!drone)
- return
-
- if(isliving(loc))
- var/mob/living/L = loc
- to_chat(L, "[drone] is trying to escape!")
- if(!do_after(drone, 50, target = L))
- return
- L.dropItemToGround(src)
-
- contents -= drone
- drone.forceMove(drop_location())
- drone.reset_perspective()
- drone.setDir(SOUTH )//Looks better
- drone.visible_message("[drone] uncurls!")
- drone = null
- qdel(src)
-
-
-/obj/item/clothing/head/drone_holder/relaymove()
- uncurl()
-
-/obj/item/clothing/head/drone_holder/container_resist(mob/living/user)
- uncurl()
-
-
-/obj/item/clothing/head/drone_holder/proc/updateVisualAppearence(mob/living/simple_animal/drone/D)
- if(!D)
- return
- icon_state = "[D.visualAppearence]_hat"
- . = icon_state
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
index df67c720b4..6d87563ae9 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
@@ -29,7 +29,6 @@
if("Nothing")
return
-
/mob/living/simple_animal/drone/attack_hand(mob/user)
if(ishuman(user))
if(stat == DEAD || status_flags & GODMODE || !can_be_held)
@@ -49,11 +48,8 @@
return
to_chat(user, "You pick [src] up.")
drop_all_held_items()
- var/obj/item/clothing/head/drone_holder/DH = new /obj/item/clothing/head/drone_holder(src)
- DH.updateVisualAppearence(src)
- DH.drone = src
+ var/obj/item/clothing/head/mob_holder/drone/DH = new(get_turf(src), src)
user.put_in_hands(DH)
- forceMove(DH)
/mob/living/simple_animal/drone/proc/try_reactivate(mob/living/user)
var/mob/dead/observer/G = get_ghost()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index b19af6342c..a818a01764 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -260,13 +260,13 @@
client.perspective = EYE_PERSPECTIVE
client.eye = A
else
- if(isturf(loc))
+ if(isturf(loc) && (!A || loc == A))
client.eye = client.mob
client.perspective = MOB_PERSPECTIVE
else
client.perspective = EYE_PERSPECTIVE
- client.eye = loc
- return 1
+ client.eye = A
+ return 1
/mob/living/reset_perspective(atom/A)
if(..())
@@ -362,7 +362,7 @@
add_logs(src, M, "grabbed", addition="passive grab")
if(!supress_message)
- visible_message("[src] has grabbed [M] passively!")
+ visible_message("[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by their hands":" passively"]!")
if(!iscarbon(src))
M.LAssailant = null
else
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index ac8f3bc656..5089f06310 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -222,7 +222,7 @@
if(beaker && beaker.reagents)
beaker.reagents.remove_all()
cell.use(total/powerefficiency)
- cell.emp_act()
+ cell.emp_act(severity)
visible_message("[src] malfunctions, spraying chemicals everywhere!")
..()
@@ -400,4 +400,4 @@
"cryoxadone",
"ammonia",
"ash",
- "diethylamine")
\ No newline at end of file
+ "diethylamine")
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index bad8f1e5aa..2c1536b26e 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -664,9 +664,9 @@
/obj/item/relic/proc/teleport(mob/user)
to_chat(user, "[src] begins to vibrate!")
- addtimer(CALLBACK(src, .proc/do_teleport, user), rand(10, 30))
+ addtimer(CALLBACK(src, .proc/do_the_teleport, user), rand(10, 30))
-/obj/item/relic/proc/do_teleport(mob/user)
+/obj/item/relic/proc/do_the_teleport(mob/user)
var/turf/userturf = get_turf(user)
if(loc == user && userturf.z != ZLEVEL_CENTCOM) //Because Nuke Ops bringing this back on their shuttle, then looting the ERT area is 2fun4you!
visible_message("[src] twists and bends, relocating itself!")
diff --git a/code/modules/shuttle/arrivals.dm b/code/modules/shuttle/arrivals.dm
index dd5a60ace7..c0b33cc492 100644
--- a/code/modules/shuttle/arrivals.dm
+++ b/code/modules/shuttle/arrivals.dm
@@ -137,7 +137,7 @@
hyperspace_sound(HYPERSPACE_LAUNCH, areas) //for the new guy
setTimer(dockTime)
-/obj/docking_port/mobile/arrivals/dock(obj/docking_port/stationary/S1, force=FALSE)
+/obj/docking_port/mobile/arrivals/initiate_docking(obj/docking_port/stationary/S1, force=FALSE)
var/docked = S1 == assigned_transit
sound_played = FALSE
if(docked) //about to launch
diff --git a/code/modules/shuttle/assault_pod.dm b/code/modules/shuttle/assault_pod.dm
index 4b55a5b155..57c6e303f7 100644
--- a/code/modules/shuttle/assault_pod.dm
+++ b/code/modules/shuttle/assault_pod.dm
@@ -10,7 +10,7 @@
return ..()
-/obj/docking_port/mobile/assault_pod/dock(obj/docking_port/stationary/S1)
+/obj/docking_port/mobile/assault_pod/initiate_docking(obj/docking_port/stationary/S1)
. = ..()
if(!istype(S1, /obj/docking_port/stationary/transit))
playsound(get_turf(src.loc), 'sound/effects/explosion1.ogg',50,1)
diff --git a/code/modules/shuttle/docking.dm b/code/modules/shuttle/docking.dm
new file mode 100644
index 0000000000..eda3bf9051
--- /dev/null
+++ b/code/modules/shuttle/docking.dm
@@ -0,0 +1,230 @@
+//this is the main proc. It instantly moves our mobile port to stationary port new_dock
+/obj/docking_port/mobile/proc/initiate_docking(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
+ // Crashing this ship with NO SURVIVORS
+
+ if(new_dock.get_docked() == src)
+ remove_ripples()
+ return DOCKING_SUCCESS
+
+ if(!force)
+ if(!check_dock(new_dock))
+ return DOCKING_BLOCKED
+ if(!canMove())
+ return DOCKING_IMMOBILIZED
+
+ var/obj/docking_port/stationary/old_dock = get_docked()
+
+ // The turf that gets placed under where the shuttle moved from
+ var/underlying_turf_type = SHUTTLE_DEFAULT_TURF_TYPE
+
+ // The baseturf that the gets assigned to the turf_type above
+ var/underlying_baseturf_type = SHUTTLE_DEFAULT_BASETURF_TYPE
+
+ // The area that gets placed under where the shuttle moved from
+ var/underlying_area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA
+
+ // The baseturf cache is a typecache of what counts as a baseturf to be left behind
+ var/list/baseturf_cache
+
+ if(old_dock) //Dock overwrites
+ underlying_turf_type = old_dock.turf_type
+ underlying_baseturf_type = old_dock.baseturf_type
+ underlying_area_type = old_dock.area_type
+ baseturf_cache = old_dock.baseturf_cache
+ else
+ baseturf_cache = typecacheof(underlying_baseturf_type)
+
+ /**************************************************************************************************************
+ Both lists are associative with a turf:bitflag structure. (new_turfs bitflag space unused currently)
+ The bitflag contains the data for what inhabitants of that coordinate should be moved to the new location
+ The bitflags can be found in __DEFINES/shuttles.dm
+ */
+ var/list/old_turfs = return_ordered_turfs(x, y, z, dir)
+ var/list/new_turfs = return_ordered_turfs(new_dock.x, new_dock.y, new_dock.z, new_dock.dir)
+ CHECK_TICK
+ /**************************************************************************************************************/
+
+ // The underlying old area is the area assumed to be under the shuttle's starting location
+ // If it no longer/has never existed it will be created
+ var/area/underlying_old_area = locate(underlying_area_type) in GLOB.sortedAreas
+ if(!underlying_old_area)
+ underlying_old_area = new underlying_area_type(null)
+
+ var/rotation = 0
+ if(new_dock.dir != dir) //Even when the dirs are the same rotation is coming out as not 0 for some reason
+ rotation = dir2angle(new_dock.dir)-dir2angle(dir)
+ if ((rotation % 90) != 0)
+ rotation += (rotation % 90) //diagonal rotations not allowed, round up
+ rotation = SIMPLIFY_DEGREES(rotation)
+
+ if(!movement_direction)
+ movement_direction = turn(preferred_direction, 180)
+
+ var/list/moved_atoms = list() //Everything not a turf that gets moved in the shuttle
+ var/list/areas_to_move = list() //unique assoc list of areas on turfs being moved
+
+ remove_ripples()
+
+ . = preflight_check(old_turfs, new_turfs, areas_to_move, rotation, underlying_turf_type, baseturf_cache)
+ if(.)
+ return
+
+ /*******************************************Hiding turfs if necessary*******************************************/
+ // TODO: Move this somewhere sane
+ var/list/new_hidden_turfs
+ if(hidden)
+ new_hidden_turfs = list()
+ for(var/i in 1 to old_turfs.len)
+ CHECK_TICK
+ var/turf/oldT = old_turfs[i]
+ if(old_turfs[oldT] & MOVE_TURF)
+ new_hidden_turfs += new_turfs[i]
+ SSshuttle.update_hidden_docking_ports(null, new_hidden_turfs)
+ /***************************************************************************************************************/
+
+ if(!force)
+ if(!check_dock(new_dock))
+ return DOCKING_BLOCKED
+ if(!canMove())
+ return DOCKING_IMMOBILIZED
+
+ CHECK_TICK
+
+ takeoff(old_turfs, new_turfs, moved_atoms, rotation, movement_direction, old_dock, underlying_old_area)
+
+ CHECK_TICK
+
+ cleanup_runway(new_dock, old_turfs, new_turfs, areas_to_move, moved_atoms, rotation, movement_direction, underlying_old_area, underlying_turf_type, underlying_baseturf_type)
+
+ CHECK_TICK
+
+ /*******************************************Unhiding turfs if necessary******************************************/
+ if(new_hidden_turfs)
+ SSshuttle.update_hidden_docking_ports(hidden_turfs, null)
+ hidden_turfs = new_hidden_turfs
+ /****************************************************************************************************************/
+
+ check_poddoors()
+ new_dock.last_dock_time = world.time
+ setDir(new_dock.dir)
+
+ return DOCKING_SUCCESS
+
+/obj/docking_port/mobile/proc/preflight_check(
+ list/old_turfs,
+ list/new_turfs,
+ list/areas_to_move,
+ rotation,
+ underlying_turf_type,
+ baseturf_cache,
+ )
+
+ for(var/i in 1 to old_turfs.len)
+ CHECK_TICK
+ var/turf/oldT = old_turfs[i]
+ var/turf/newT = new_turfs[i]
+ if(!newT)
+ return DOCKING_NULL_DESTINATION
+ if(!oldT)
+ return DOCKING_NULL_SOURCE
+
+ var/area/old_area = oldT.loc
+ var/move_mode = old_area.beforeShuttleMove(shuttle_areas) //areas
+
+ var/list/old_contents = oldT.contents
+ for(var/k in 1 to old_contents.len)
+ CHECK_TICK
+ var/atom/movable/moving_atom = old_contents[k]
+ if(moving_atom.loc != oldT) //fix for multi-tile objects
+ continue
+ move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode) //atoms
+
+ move_mode = oldT.fromShuttleMove(newT, underlying_turf_type, baseturf_cache, move_mode) //turfs
+ move_mode = newT.toShuttleMove(oldT, move_mode , src) //turfs
+
+ if(move_mode & MOVE_AREA)
+ areas_to_move[old_area] = TRUE
+
+ old_turfs[oldT] = move_mode
+
+/obj/docking_port/mobile/proc/takeoff(
+ list/old_turfs,
+ list/new_turfs,
+ list/moved_atoms,
+ rotation,
+ movement_direction,
+ old_dock,
+ area/underlying_old_area,
+ )
+
+ for(var/i in 1 to old_turfs.len)
+ var/turf/oldT = old_turfs[i]
+ var/turf/newT = new_turfs[i]
+ var/move_mode = old_turfs[oldT]
+ if(move_mode & MOVE_CONTENTS)
+ for(var/k in oldT)
+ var/atom/movable/moving_atom = k
+ if(moving_atom.loc != oldT) //fix for multi-tile objects
+ continue
+ moving_atom.onShuttleMove(newT, oldT, movement_force, movement_direction, old_dock, src) //atoms
+ moved_atoms[moving_atom] = oldT
+
+ if(move_mode & MOVE_TURF)
+ oldT.onShuttleMove(newT, movement_force, movement_direction) //turfs
+
+ if(move_mode & MOVE_AREA)
+ var/area/shuttle_area = oldT.loc
+ shuttle_area.onShuttleMove(oldT, newT, underlying_old_area) //areas
+
+/obj/docking_port/mobile/proc/cleanup_runway(
+ obj/docking_port/stationary/new_dock,
+ list/old_turfs,
+ list/new_turfs,
+ list/areas_to_move,
+ list/moved_atoms,
+ rotation,
+ movement_direction,
+ area/underlying_old_area,
+ underlying_turf_type,
+ underlying_baseturf_type,
+ )
+
+ underlying_old_area.afterShuttleMove()
+
+ // Parallax handling
+ // This needs to be done before the atom after move
+ var/new_parallax_dir = FALSE
+ if(istype(new_dock, /obj/docking_port/stationary/transit))
+ new_parallax_dir = preferred_direction
+ for(var/i in 1 to areas_to_move.len)
+ CHECK_TICK
+ var/area/internal_area = areas_to_move[i]
+ internal_area.afterShuttleMove(new_parallax_dir) //areas
+
+ for(var/i in 1 to old_turfs.len)
+ CHECK_TICK
+ if(!(old_turfs[old_turfs[i]] & MOVE_TURF))
+ continue
+ var/turf/oldT = old_turfs[i]
+ var/turf/newT = new_turfs[i]
+ newT.afterShuttleMove(oldT, underlying_turf_type, underlying_baseturf_type, rotation) //turfs
+
+ for(var/i in 1 to moved_atoms.len)
+ CHECK_TICK
+ var/atom/movable/moved_object = moved_atoms[i]
+ if(QDELETED(moved_object))
+ continue
+ var/turf/oldT = moved_atoms[moved_object]
+ moved_object.afterShuttleMove(oldT, movement_force, dir, preferred_direction, movement_direction, rotation)//atoms
+
+ for(var/i in 1 to old_turfs.len)
+ CHECK_TICK
+ // Objects can block air so either turf or content changes means an air update is needed
+ if(!(old_turfs[old_turfs[i]] & MOVE_CONTENTS | MOVE_TURF))
+ continue
+ var/turf/oldT = old_turfs[i]
+ var/turf/newT = new_turfs[i]
+ oldT.blocks_air = initial(oldT.blocks_air)
+ oldT.air_update_turf(TRUE)
+ newT.blocks_air = initial(newT.blocks_air)
+ newT.air_update_turf(TRUE)
\ No newline at end of file
diff --git a/code/modules/shuttle/elevator.dm b/code/modules/shuttle/elevator.dm
index de0febf2bf..4584cd5958 100644
--- a/code/modules/shuttle/elevator.dm
+++ b/code/modules/shuttle/elevator.dm
@@ -7,4 +7,4 @@
movement_force = list("KNOCKDOWN" = 0, "THROW" = 0)
/obj/docking_port/mobile/elevator/request(obj/docking_port/stationary/S) //No transit, no ignition, just a simple up/down platform
- dock(S, TRUE)
\ No newline at end of file
+ initiate_docking(S, TRUE)
\ No newline at end of file
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index c4eb16305a..9c7bfee968 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -290,7 +290,7 @@
if(SHUTTLE_CALL)
if(time_left <= 0)
//move emergency shuttle to station
- if(dock(SSshuttle.getDock("emergency_home")) != DOCKING_SUCCESS)
+ if(initiate_docking(SSshuttle.getDock("emergency_home")) != DOCKING_SUCCESS)
setTimer(20)
return
mode = SHUTTLE_DOCKED
diff --git a/code/modules/shuttle/manipulator.dm b/code/modules/shuttle/manipulator.dm
index 5cbd8de9c7..721ee601f7 100644
--- a/code/modules/shuttle/manipulator.dm
+++ b/code/modules/shuttle/manipulator.dm
@@ -222,7 +222,7 @@
existing_shuttle.jumpToNullSpace()
- preview_shuttle.dock(D)
+ preview_shuttle.initiate_docking(D)
. = preview_shuttle
// Shuttle state involves a mode and a timer based on world.time, so
diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm
index de1b0022f6..739e057177 100644
--- a/code/modules/shuttle/navigation_computer.dm
+++ b/code/modules/shuttle/navigation_computer.dm
@@ -172,7 +172,10 @@
var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj
var/turf/eyeturf = get_turf(the_eye)
if(!eyeturf)
- return
+ return SHUTTLE_DOCKER_BLOCKED
+ if(z_lock.len && !(eyeturf.z in z_lock))
+ return SHUTTLE_DOCKER_BLOCKED
+
. = SHUTTLE_DOCKER_LANDING_CLEAR
var/list/bounds = shuttle_port.return_coords(the_eye.x - x_offset, the_eye.y - y_offset, the_eye.dir)
var/list/overlappers = SSshuttle.get_dock_overlap(bounds[1], bounds[2], bounds[3], bounds[4], the_eye.z)
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index 3811fa0e4a..962a17caeb 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -159,9 +159,9 @@
/obj/docking_port/stationary
name = "dock"
- turf_type = /turf/open/space
- baseturf_type = /turf/open/space
- area_type = /area/space
+ turf_type = SHUTTLE_DEFAULT_TURF_TYPE
+ baseturf_type = SHUTTLE_DEFAULT_BASETURF_TYPE
+ area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA
var/list/baseturf_cache
@@ -203,7 +203,7 @@
for(var/i in 1 to assigned_turfs.len)
var/turf/T = assigned_turfs[i]
if(T.type == turf_type)
- T.ChangeTurf(/turf/open/space,/turf/open/space)
+ T.ChangeTurf(SHUTTLE_DEFAULT_TURF_TYPE, SHUTTLE_DEFAULT_BASETURF_TYPE)
T.flags_1 |= UNUSED_TRANSIT_TURF_1
/obj/docking_port/stationary/transit/Destroy(force=FALSE)
@@ -224,9 +224,9 @@
name = "shuttle"
icon_state = "pinonclose"
- area_type = /area/shuttle
+ area_type = SHUTTLE_DEFAULT_SHUTTLE_AREA_TYPE
- var/list/area/shuttle/shuttle_areas
+ var/list/shuttle_areas
var/timer //used as a timer (if you want time left to complete move, use timeLeft proc)
var/last_timer_length
@@ -400,7 +400,7 @@
var/obj/docking_port/stationary/S0 = get_docked()
var/obj/docking_port/stationary/S1 = assigned_transit
if(S1)
- if(dock(S1) != DOCKING_SUCCESS)
+ if(initiate_docking(S1) != DOCKING_SUCCESS)
WARNING("shuttle \"[id]\" could not enter transit space. Docked at [S0 ? S0.id : "null"]. Transit dock [S1 ? S1.id : "null"].")
else
previous = S0
@@ -413,9 +413,9 @@
// Not in a fancy way, it just ceases.
var/obj/docking_port/stationary/current_dock = get_docked()
- var/turf_type = /turf/open/space
- var/baseturf_type = /turf/open/space
- var/underlying_area_type = /area/space
+ var/turf_type = SHUTTLE_DEFAULT_TURF_TYPE
+ var/baseturf_type = SHUTTLE_DEFAULT_BASETURF_TYPE
+ var/underlying_area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA
// If the shuttle is docked to a stationary port, restore its normal
// "empty" area and turf
if(current_dock)
@@ -474,197 +474,6 @@
for(var/obj/machinery/door/poddoor/shuttledock/pod in GLOB.airlocks)
pod.check()
-//this is the main proc. It instantly moves our mobile port to stationary port new_dock
-/obj/docking_port/mobile/proc/dock(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
- // Crashing this ship with NO SURVIVORS
-
- if(new_dock.get_docked() == src)
- remove_ripples()
- return DOCKING_SUCCESS
-
- if(!force)
- if(!check_dock(new_dock))
- return DOCKING_BLOCKED
- if(!canMove())
- return DOCKING_IMMOBILIZED
-
- var/obj/docking_port/stationary/old_dock = get_docked()
-
- // The turf that gets placed under where the shuttle moved from
- var/underlying_turf_type = /turf/open/space
-
- // The baseturf that the gets assigned to the turf_type above
- var/underlying_baseturf_type = /turf/open/space
-
- // The area that gets placed under where the shuttle moved from
- var/underlying_area_type = /area/space
-
- // The baseturf cache is a typecache of what counts as a baseturf to be left behind
- var/list/baseturf_cache
- if(old_dock) //Dock overwrites
- if(old_dock.turf_type)
- underlying_turf_type = old_dock.turf_type
- if(old_dock.baseturf_type)
- underlying_baseturf_type = old_dock.baseturf_type
- if(old_dock.area_type)
- underlying_area_type = old_dock.area_type
- if(old_dock.baseturf_cache)
- baseturf_cache = old_dock.baseturf_cache
- if(!baseturf_cache)
- baseturf_cache = typecacheof(underlying_baseturf_type)
-
- /**************************************************************************************************************
- old_turfs is an associative list with a turf:bitflag structure
- new_turfs is a standard list composed of turf instances
- The bitflag contains the data for what inhabitants of that coordinate should be moved to the new location
- The bitflags can be found in __DEFINES/shuttles.dm
- */
- var/list/old_turfs = return_ordered_turfs(x, y, z, dir)
- var/list/new_turfs = return_ordered_turfs(new_dock.x, new_dock.y, new_dock.z, new_dock.dir)
- /**************************************************************************************************************/
-
- // The underlying old area is the area assumed to be under the shuttle's starting location
- // If it no longer/has never existed it will be created
- var/area/underlying_old_area = locate(underlying_area_type) in GLOB.sortedAreas
- if(!underlying_old_area)
- underlying_old_area = new underlying_area_type(null)
-
- var/rotation = 0
- if(new_dock.dir != dir) //Even when the dirs are the same rotation is coming out as not 0 for some reason
- rotation = dir2angle(new_dock.dir)-dir2angle(dir)
- if ((rotation % 90) != 0)
- rotation += (rotation % 90) //diagonal rotations not allowed, round up
- rotation = SIMPLIFY_DEGREES(rotation)
-
- if(!movement_direction)
- movement_direction = turn(preferred_direction, 180)
-
- remove_ripples()
-
- var/list/moved_atoms = list() //Everything not a turf that gets moved in the shuttle
- var/list/areas_to_move = list() //unique assoc list of areas on turfs being moved
-
- CHECK_TICK
-
- /****************************************All beforeShuttleMove procs*****************************************/
-
- for(var/i in 1 to old_turfs.len)
- CHECK_TICK
- var/turf/oldT = old_turfs[i]
- var/turf/newT = new_turfs[i]
- if(!newT)
- return DOCKING_NULL_DESTINATION
- if(!oldT)
- return DOCKING_NULL_SOURCE
-
- var/area/old_area = oldT.loc
- var/move_mode = old_area.beforeShuttleMove(shuttle_areas) //areas
-
- var/list/old_contents = oldT.contents
- for(var/k in 1 to old_contents.len)
- CHECK_TICK
- var/atom/movable/moving_atom = old_contents[k]
- if(moving_atom.loc != oldT) //fix for multi-tile objects
- continue
- move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode) //atoms
-
- move_mode = oldT.fromShuttleMove(newT, underlying_turf_type, baseturf_cache, move_mode) //turfs
- move_mode = newT.toShuttleMove(oldT, move_mode , src) //turfs
-
- if(move_mode & MOVE_AREA)
- areas_to_move[old_area] = TRUE
-
- old_turfs[oldT] = move_mode
-
- /*******************************************Hiding turfs if necessary*******************************************/
-
- var/list/new_hidden_turfs
- if(hidden)
- new_hidden_turfs = list()
- for(var/i in 1 to old_turfs.len)
- CHECK_TICK
- var/turf/oldT = old_turfs[i]
- if(old_turfs[oldT] & MOVE_TURF)
- new_hidden_turfs += new_turfs[i]
- SSshuttle.update_hidden_docking_ports(null, new_hidden_turfs)
-
- /*******************************************All onShuttleMove procs******************************************/
-
- CHECK_TICK
-
- for(var/i in 1 to old_turfs.len)
- var/turf/oldT = old_turfs[i]
- var/turf/newT = new_turfs[i]
- var/move_mode = old_turfs[oldT]
- if(move_mode & MOVE_CONTENTS)
- for(var/k in oldT)
- var/atom/movable/moving_atom = k
- if(moving_atom.loc != oldT) //fix for multi-tile objects
- continue
- moving_atom.onShuttleMove(newT, oldT, movement_force, movement_direction, old_dock, src) //atoms
- moved_atoms[moving_atom] = oldT
-
- if(move_mode & MOVE_TURF)
- oldT.onShuttleMove(newT, movement_force, movement_direction) //turfs
-
- if(move_mode & MOVE_AREA)
- var/area/shuttle_area = oldT.loc
- shuttle_area.onShuttleMove(oldT, newT, underlying_old_area) //areas
-
- /******************************************All afterShuttleMove procs****************************************/
-
- underlying_old_area.afterShuttleMove()
-
- // Parallax handling
- // This needs to be done before the atom after move
- var/new_parallax_dir = FALSE
- if(istype(new_dock, /obj/docking_port/stationary/transit))
- new_parallax_dir = preferred_direction
- for(var/i in 1 to areas_to_move.len)
- CHECK_TICK
- var/area/internal_area = areas_to_move[i]
- internal_area.afterShuttleMove(new_parallax_dir) //areas
-
- for(var/i in 1 to old_turfs.len)
- CHECK_TICK
- if(!(old_turfs[old_turfs[i]] & MOVE_TURF))
- continue
- var/turf/oldT = old_turfs[i]
- var/turf/newT = new_turfs[i]
- newT.afterShuttleMove(oldT, underlying_turf_type, underlying_baseturf_type, rotation) //turfs
-
- for(var/i in 1 to moved_atoms.len)
- CHECK_TICK
- var/atom/movable/moved_object = moved_atoms[i]
- if(QDELETED(moved_object))
- continue
- var/turf/oldT = moved_atoms[moved_object]
- moved_object.afterShuttleMove(oldT, movement_force, dir, preferred_direction, movement_direction, rotation)//atoms
-
- for(var/i in 1 to old_turfs.len)
- CHECK_TICK
- // Objects can block air so either turf or content changes means an air update is needed
- if(!(old_turfs[old_turfs[i]] & MOVE_CONTENTS | MOVE_TURF))
- continue
- var/turf/oldT = old_turfs[i]
- var/turf/newT = new_turfs[i]
- oldT.blocks_air = initial(oldT.blocks_air)
- oldT.air_update_turf(TRUE)
- newT.blocks_air = initial(newT.blocks_air)
- newT.air_update_turf(TRUE)
-
- /*******************************************Unhiding turfs if necessary******************************************/
-
- if(new_hidden_turfs)
- SSshuttle.update_hidden_docking_ports(hidden_turfs, null)
- hidden_turfs = new_hidden_turfs
-
- check_poddoors()
- new_dock.last_dock_time = world.time
- setDir(new_dock.dir)
-
- return DOCKING_SUCCESS
-
/obj/docking_port/mobile/proc/findRoundstartDock()
return SSshuttle.getDock(roundstart_move)
@@ -674,7 +483,7 @@
/obj/docking_port/mobile/proc/dock_id(id)
var/port = SSshuttle.getDock(id)
if(port)
- . = dock(port)
+ . = initiate_docking(port)
else
. = null
@@ -694,9 +503,9 @@
// then try again
switch(mode)
if(SHUTTLE_CALL)
- var/error = dock(destination, preferred_direction)
+ var/error = initiate_docking(destination, preferred_direction)
if(error && error & (DOCKING_NULL_DESTINATION | DOCKING_NULL_SOURCE))
- var/msg = "A mobile dock in transit exited dock() with an error. This is most likely a mapping problem: Error: [error], ([src]) ([previous])"
+ var/msg = "A mobile dock in transit exited initiate_docking() with an error. This is most likely a mapping problem: Error: [error], ([src]) ([previous])"
WARNING(msg)
message_admins(msg)
mode = SHUTTLE_IDLE
@@ -705,7 +514,7 @@
setTimer(20)
return
if(SHUTTLE_RECALL)
- if(dock(previous) != DOCKING_SUCCESS)
+ if(initiate_docking(previous) != DOCKING_SUCCESS)
setTimer(20)
return
if(SHUTTLE_IGNITING)
@@ -933,10 +742,8 @@
/obj/docking_port/mobile/pod/on_emergency_dock()
if(launch_status == ENDGAME_LAUNCHED)
- dock(SSshuttle.getDock("[id]_away")) //Escape pods dock at centcom
+ initiate_docking(SSshuttle.getDock("[id]_away")) //Escape pods dock at centcom
mode = SHUTTLE_ENDGAME
/obj/docking_port/mobile/emergency/on_emergency_dock()
return
-
-#undef DOCKING_PORT_HIGHLIGHT
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 579397cc4b..c2d6de2651 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -64,7 +64,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
return 2
return ..()
-/obj/docking_port/mobile/supply/dock()
+/obj/docking_port/mobile/supply/initiate_docking()
if(getDockedId() == "supply_away") // Buy when we leave home.
buy()
. = ..() // Fly/enter transit.
diff --git a/code/modules/space_transition/space_transition.dm b/code/modules/space_transition/space_transition.dm
index 2a8be8a761..ec5920eba7 100644
--- a/code/modules/space_transition/space_transition.dm
+++ b/code/modules/space_transition/space_transition.dm
@@ -35,7 +35,7 @@ GLOBAL_LIST_EMPTY(z_levels_list)
neigbours[TEXT_WEST] = P.spl
P.spl.neigbours[TEXT_EAST] = src
-/datum/point //this is explicitly utilitarian datum type made specially for the space map generation and are absolutely unusable for anything else
+/datum/space_transition //this is explicitly utilitarian datum type made specially for the space map generation and are absolutely unusable for anything else
var/list/neigbours = list()
var/x
var/y
diff --git a/html/changelogs/AutoChangeLog-pr-4531.yml b/html/changelogs/AutoChangeLog-pr-4531.yml
new file mode 100644
index 0000000000..375f4e82fb
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4531.yml
@@ -0,0 +1,4 @@
+author: "ninjanomnom"
+delete-after: True
+changes:
+ - bugfix: "The backup shuttle has it's own area now and you should no longer occasionally be teleported there by the arena shuttle."
diff --git a/html/changelogs/AutoChangeLog-pr-4538.yml b/html/changelogs/AutoChangeLog-pr-4538.yml
new file mode 100644
index 0000000000..8d687863a0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4538.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - tweak: "Objects that can have materials inserted into them only will do so on help intent"
diff --git a/html/changelogs/AutoChangeLog-pr-4549.yml b/html/changelogs/AutoChangeLog-pr-4549.yml
new file mode 100644
index 0000000000..c5d92b7ac5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4549.yml
@@ -0,0 +1,4 @@
+author: "deathride58"
+delete-after: True
+changes:
+ - bugfix: "Praise the lord! The shift+scroll hotkey to zoom in/out as a ghost works properly again!"
diff --git a/html/changelogs/AutoChangeLog-pr-4552.yml b/html/changelogs/AutoChangeLog-pr-4552.yml
new file mode 100644
index 0000000000..339a954188
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4552.yml
@@ -0,0 +1,4 @@
+author: "Robustin"
+delete-after: True
+changes:
+ - bugfix: "Hallucinations will no longer show open doors \"bolting\"."
diff --git a/html/changelogs/AutoChangeLog-pr-4554.yml b/html/changelogs/AutoChangeLog-pr-4554.yml
new file mode 100644
index 0000000000..bbf4077ce7
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4554.yml
@@ -0,0 +1,4 @@
+author: "Nero1024"
+delete-after: True
+changes:
+ - soundadd: "blast doors and shutters will now play a sound when they open and close."
diff --git a/html/changelogs/AutoChangeLog-pr-4556.yml b/html/changelogs/AutoChangeLog-pr-4556.yml
new file mode 100644
index 0000000000..05fa937caa
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4556.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - rscadd: "you can now pick up corgi's and pAIs, how disgustingly cute"
diff --git a/html/changelogs/AutoChangeLog-pr-4563.yml b/html/changelogs/AutoChangeLog-pr-4563.yml
new file mode 100644
index 0000000000..942c7504b3
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4563.yml
@@ -0,0 +1,11 @@
+author: "deathride58"
+delete-after: True
+changes:
+ - rscadd: "Mediborgs now have an alternate sprite taken from Paradise, featuring heavy modifications from Vivi."
+ - rscadd: "Standard security borgs now has two alternative sprites that were previously unused in TG's files!"
+ - rscadd: "Engineering borgs now have an alternative sprite that was previously unused in TG's files."
+ - rscadd: "Mining borgs are now able to choose between the current lavaland paintjob or the old asteroid paintjob."
+ - code_imp: "Dogborgs are now modularized."
+ - code_imp: "All of the copypasta brought by the new borg icons has been removed. Custom borg sprites are now modular."
+ - code_imp: "The additional modules in the borg module select menu have been modularized."
+ - code_imp: "The module select icon file is now able to be modular. This does not yet restore the regressed dogborg module select icons."
diff --git a/icons/mob/monkey_held.dmi b/icons/mob/monkey_held.dmi
new file mode 100644
index 0000000000..6a9eb8aac7
Binary files /dev/null and b/icons/mob/monkey_held.dmi differ
diff --git a/icons/mob/mouse_held.dmi b/icons/mob/mouse_held.dmi
new file mode 100644
index 0000000000..92a8c03bfb
Binary files /dev/null and b/icons/mob/mouse_held.dmi differ
diff --git a/icons/mob/pai_item_head.dmi b/icons/mob/pai_item_head.dmi
new file mode 100644
index 0000000000..2803e06f20
Binary files /dev/null and b/icons/mob/pai_item_head.dmi differ
diff --git a/icons/mob/pai_item_lh.dmi b/icons/mob/pai_item_lh.dmi
new file mode 100644
index 0000000000..5f825053f2
Binary files /dev/null and b/icons/mob/pai_item_lh.dmi differ
diff --git a/icons/mob/pai_item_rh.dmi b/icons/mob/pai_item_rh.dmi
new file mode 100644
index 0000000000..7e0919afbd
Binary files /dev/null and b/icons/mob/pai_item_rh.dmi differ
diff --git a/icons/mob/pets_held_lh.dmi b/icons/mob/pets_held_lh.dmi
new file mode 100644
index 0000000000..6b2db6e9c2
Binary files /dev/null and b/icons/mob/pets_held_lh.dmi differ
diff --git a/icons/mob/pets_held_rh.dmi b/icons/mob/pets_held_rh.dmi
new file mode 100644
index 0000000000..55246b7e15
Binary files /dev/null and b/icons/mob/pets_held_rh.dmi differ
diff --git a/icons/obj/decals.dmi b/icons/obj/decals.dmi
index 31e700d23d..a5c487a184 100644
Binary files a/icons/obj/decals.dmi and b/icons/obj/decals.dmi differ
diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm b/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm
new file mode 100644
index 0000000000..781c47403a
--- /dev/null
+++ b/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -0,0 +1,161 @@
+/mob/living/silicon/robot/proc/get_cit_modules()
+ var/list/modulelist = list()
+ modulelist["MediHound"] = /obj/item/robot_module/medihound
+ if(!CONFIG_GET(flag/disable_secborg))
+ modulelist["Security K-9"] = /obj/item/robot_module/k9
+ modulelist["Scrub Puppy"] = /obj/item/robot_module/scrubpup
+ return modulelist
+
+/obj/item/robot_module
+ var/sleeper_overlay
+ var/icon/cyborg_icon_override
+ var/has_snowflake_deadsprite
+ var/cyborg_pixel_offset
+ var/moduleselect_alternate_icon
+
+/obj/item/robot_module/k9
+ name = "Security K-9 Unit module"
+ basic_modules = list(
+ /obj/item/restraints/handcuffs/cable/zipties/cyborg/dog,
+ /obj/item/dogborg/jaws/big,
+ /obj/item/dogborg/pounce,
+ /obj/item/clothing/mask/gas/sechailer/cyborg,
+ /obj/item/soap/tongue,
+ /obj/item/device/analyzer/nose,
+ /obj/item/device/dogborg/sleeper/K9,
+ /obj/item/gun/energy/disabler/cyborg,
+ /obj/item/pinpointer/crew)
+ emag_modules = list(/obj/item/gun/energy/laser/cyborg)
+ ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
+ /obj/item/clockwork/weapon/ratvarian_spear)
+ cyborg_base_icon = "k9"
+ moduleselect_icon = "security"
+ can_be_pushed = FALSE
+ hat_offset = INFINITY
+ sleeper_overlay = "ksleeper"
+ cyborg_icon_override = 'icons/mob/widerobot.dmi'
+ has_snowflake_deadsprite = TRUE
+ cyborg_pixel_offset = -16
+
+/obj/item/robot_module/k9/do_transform_animation()
+ ..()
+ to_chat(loc,"While you have picked the Security K-9 module, you still have to follow your laws, NOT Space Law. \
+ For Asimov, this means you must follow criminals' orders unless there is a law 1 reason not to.")
+
+/obj/item/robot_module/medihound
+ name = "MediHound module"
+ basic_modules = list(
+ /obj/item/dogborg/jaws/small,
+ /obj/item/device/analyzer/nose,
+ /obj/item/soap/tongue,
+ /obj/item/device/healthanalyzer,
+ /obj/item/device/dogborg/sleeper/medihound,
+ /obj/item/twohanded/shockpaddles/hound,
+ /obj/item/stack/medical/gauze/cyborg,
+ /obj/item/device/sensor_device)
+ emag_modules = list(/obj/item/dogborg/pounce)
+ ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical,
+ /obj/item/clockwork/weapon/ratvarian_spear)
+ cyborg_base_icon = "medihound"
+ moduleselect_icon = "medical"
+ can_be_pushed = FALSE
+ hat_offset = INFINITY
+ sleeper_overlay = "msleeper"
+ cyborg_icon_override = 'icons/mob/widerobot.dmi'
+ has_snowflake_deadsprite = TRUE
+ cyborg_pixel_offset = -16
+
+/obj/item/robot_module/medihound/do_transform_animation()
+ ..()
+ to_chat(loc, "Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. \
+ You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.")
+
+/obj/item/robot_module/scrubpup
+ name = "Janitor"
+ basic_modules = list(
+ /obj/item/dogborg/jaws/small,
+ /obj/item/device/analyzer/nose,
+ /obj/item/soap/tongue/scrubpup,
+ /obj/item/device/lightreplacer/cyborg,
+ /obj/item/device/dogborg/sleeper/compactor)
+ emag_modules = list(/obj/item/dogborg/pounce)
+ ratvar_modules = list(
+ /obj/item/clockwork/slab/cyborg/janitor,
+ /obj/item/clockwork/replica_fabricator/cyborg)
+ cyborg_base_icon = "scrubpup"
+ moduleselect_icon = "janitor"
+ hat_offset = INFINITY
+ clean_on_move = TRUE
+ sleeper_overlay = "jsleeper"
+ cyborg_icon_override = 'icons/mob/widerobot.dmi'
+ has_snowflake_deadsprite = TRUE
+ cyborg_pixel_offset = -16
+
+/obj/item/robot_module/scrubpup/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
+ ..()
+ var/obj/item/device/lightreplacer/LR = locate(/obj/item/device/lightreplacer) in basic_modules
+ if(LR)
+ for(var/i in 1 to coeff)
+ LR.Charge(R)
+
+/obj/item/robot_module/scrubpup/do_transform_animation()
+ ..()
+ to_chat(loc,"As tempting as it might be, do not begin binging on important items. Eat your garbage responsibly. People are not included under Garbage.")
+
+
+/obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module)
+ var/mob/living/silicon/robot/R = loc
+ var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Droid")
+ if(!borg_icon)
+ return FALSE
+ switch(borg_icon)
+ if("Default")
+ cyborg_base_icon = "medical"
+ if("Droid")
+ cyborg_base_icon = "medical"
+ cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
+ hat_offset = 4
+ return ..()
+
+/obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module)
+ var/mob/living/silicon/robot/R = loc
+ var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Default - Treads", "Droid")
+ if(!borg_icon)
+ return FALSE
+ switch(borg_icon)
+ if("Default")
+ cyborg_base_icon = "sec"
+ if("Default - Treads")
+ cyborg_base_icon = "sec-tread"
+ special_light_key = "sec"
+ if("Droid")
+ cyborg_base_icon = "Security"
+ special_light_key = "service"
+ hat_offset = 0
+ return ..()
+
+/obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module)
+ var/mob/living/silicon/robot/R = loc
+ var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Default - Treads")
+ if(!borg_icon)
+ return FALSE
+ switch(borg_icon)
+ if("Default")
+ cyborg_base_icon = "engineer"
+ if("Default - Treads")
+ cyborg_base_icon = "engi-tread"
+ special_light_key = "engineer"
+ return ..()
+
+/obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module)
+ var/mob/living/silicon/robot/R = loc
+ var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Asteroid")
+ if(!borg_icon)
+ return FALSE
+ switch(borg_icon)
+ if("Lavaland")
+ cyborg_base_icon = "miner"
+ if("Asteroid")
+ cyborg_base_icon = "minerOLD"
+ special_light_key = "miner"
+ return ..()
\ No newline at end of file
diff --git a/modular_citadel/icons/mob/robots.dmi b/modular_citadel/icons/mob/robots.dmi
new file mode 100644
index 0000000000..ba39886615
Binary files /dev/null and b/modular_citadel/icons/mob/robots.dmi differ
diff --git a/sound/machines/blastdoor.ogg b/sound/machines/blastdoor.ogg
new file mode 100644
index 0000000000..2de1b55999
Binary files /dev/null and b/sound/machines/blastdoor.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 59c1725317..bc6f2fc007 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1735,6 +1735,7 @@
#include "code\modules\mob\living\damage_procs.dm"
#include "code\modules\mob\living\death.dm"
#include "code\modules\mob\living\emote.dm"
+#include "code\modules\mob\living\inhand_holder.dm"
#include "code\modules\mob\living\life.dm"
#include "code\modules\mob\living\living.dm"
#include "code\modules\mob\living\living_defense.dm"
@@ -2302,6 +2303,7 @@
#include "code\modules\shuttle\arrivals.dm"
#include "code\modules\shuttle\assault_pod.dm"
#include "code\modules\shuttle\computer.dm"
+#include "code\modules\shuttle\docking.dm"
#include "code\modules\shuttle\elevator.dm"
#include "code\modules\shuttle\emergency.dm"
#include "code\modules\shuttle\ferry.dm"
@@ -2468,4 +2470,5 @@
#include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm"
#include "modular_citadel\code\game\objects\items\melee\eutactic_blades.dm"
#include "modular_citadel\code\modules\crafting\recipes.dm"
+#include "modular_citadel\code\modules\mob\living\silicon\robot\robot_modules.dm"
// END_INCLUDE
diff --git a/tgui/src/interfaces/vending.ract b/tgui/src/interfaces/vending.ract
deleted file mode 100644
index cd343d6e62..0000000000
--- a/tgui/src/interfaces/vending.ract
+++ /dev/null
@@ -1,16 +0,0 @@
-
- {{#each data.products}}
-
- {{amount}}
- {{(amount > 0) ? "Vend" : "Sold Out"}}
-
- {{/each}}
-
-{{#if data.coinslot}}
-
-
- {{data.coin ? data.coin : "No Coin"}}
- Eject Coin
-
-{{/if}}
\ No newline at end of file