diff --git a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
index a377a5118874..e11d5e4a0823 100644
--- a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
+++ b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
@@ -683,7 +683,7 @@
/obj/machinery/light/directional/west,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"bU" = (
/obj/effect/turf_decal/delivery,
/obj/item/food/canned/beans{
@@ -713,12 +713,12 @@
},
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"bV" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"bW" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/closed/wall,
@@ -905,7 +905,7 @@
},
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"cC" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{
dir = 5
@@ -913,7 +913,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"cD" = (
/obj/machinery/door/airlock/highsecurity{
name = "Provisions Storage"
@@ -925,7 +925,7 @@
/obj/structure/cable,
/obj/effect/mapping_helpers/airlock/access/all/syndicate/general,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"cE" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{
dir = 4
@@ -1000,7 +1000,7 @@
/obj/structure/cable,
/obj/effect/mapping_helpers/apc/syndicate_access,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"cS" = (
/obj/structure/chair/stool/directional/west,
/obj/effect/decal/cleanable/dirt,
@@ -1079,13 +1079,13 @@
},
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"dg" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{
dir = 4
},
/turf/closed/wall,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"dh" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/spawner/random/entertainment/arcade{
@@ -1189,7 +1189,7 @@
},
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"dx" = (
/obj/effect/turf_decal/delivery,
/obj/structure/closet/crate{
@@ -1228,20 +1228,20 @@
},
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"dy" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
},
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"dz" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{
dir = 6
},
/turf/closed/wall,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"dA" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{
dir = 9
@@ -2744,6 +2744,9 @@
"pP" = (
/turf/closed/wall,
/area/ruin/space/has_grav/deepstorage)
+"qg" = (
+/turf/closed/wall,
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"qm" = (
/obj/machinery/atmospherics/components/unary/outlet_injector/monitored{
chamber_id = "deepo2";
@@ -3045,6 +3048,9 @@
"CA" = (
/turf/closed/wall/r_wall,
/area/ruin/space/has_grav/deepstorage/crusher)
+"CL" = (
+/turf/closed/wall/r_wall,
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"CQ" = (
/obj/machinery/computer/slime_market,
/turf/open/floor/iron/white/textured,
@@ -3349,7 +3355,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/mapping_helpers/airalarm/syndicate_access,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"SR" = (
/obj/machinery/airalarm/directional/south,
/obj/effect/decal/cleanable/dirt,
@@ -3384,7 +3390,7 @@
/obj/item/radio/headset/syndicate/alt,
/obj/item/radio/headset/syndicate/alt,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"TC" = (
/obj/structure/noticeboard/directional/north,
/obj/item/paper/fluff/ruins/deepstorage/water_concern,
@@ -3453,7 +3459,7 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2,
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron,
-/area/ruin/space/has_grav/deepstorage/storage)
+/area/ruin/space/has_grav/deepstorage/aux_storage)
"VU" = (
/obj/machinery/biomass_recycler,
/obj/item/stack/biomass,
@@ -4013,12 +4019,12 @@ iK
yA
Pb
KZ
-VY
-VY
-VY
-VY
-VY
-VY
+CL
+CL
+CL
+CL
+CL
+CL
ag
ag
ag
@@ -4064,13 +4070,13 @@ mD
NF
iK
iK
-VY
-VY
-VY
-VY
-VY
-VY
-VY
+CL
+CL
+CL
+CL
+CL
+CL
+CL
hV
ag
ag
@@ -4116,7 +4122,7 @@ qM
iK
iK
kE
-VY
+CL
bT
bU
cB
@@ -4168,7 +4174,7 @@ aw
VY
VY
VY
-VY
+CL
bU
bU
cB
@@ -4273,10 +4279,10 @@ aH
aS
bn
hU
-hU
-hU
+qg
+qg
cD
-hU
+qg
dg
dz
fN
diff --git a/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm b/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm
index 9d956fd649b4..4ef5b373ec3c 100644
--- a/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm
+++ b/_maps/RandomRuins/SpaceRuins/infested_frigate.dmm
@@ -595,9 +595,6 @@
/turf/open/floor/iron/freezer,
/area/ruin/space/has_grav/infested_frigate)
"jk" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 1
- },
/obj/structure/barricade/security,
/obj/structure/door_assembly/door_assembly_ext{
anchored = 1
diff --git a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm
index b0d40273dc43..46ab3b36fde5 100644
--- a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm
+++ b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm
@@ -1186,9 +1186,6 @@
name = "Hotel Kitchen"
},
/obj/effect/mapping_helpers/airlock/access/all/away/general,
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 4
- },
/turf/open/floor/stone,
/area/ruin/space/has_grav/hotel/bar)
"jp" = (
@@ -2488,7 +2485,6 @@
},
/obj/effect/mapping_helpers/airlock/access/all/away/general,
/obj/machinery/door/firedoor,
-/obj/effect/mapping_helpers/airlock/cyclelink_helper,
/turf/open/floor/iron/textured_half{
dir = 4
},
diff --git a/_maps/RandomRuins/SpaceRuins/spacerealhotel.dmm b/_maps/RandomRuins/SpaceRuins/spacerealhotel.dmm
index 18ff0869ee0e..95aa2fe8c3e5 100644
--- a/_maps/RandomRuins/SpaceRuins/spacerealhotel.dmm
+++ b/_maps/RandomRuins/SpaceRuins/spacerealhotel.dmm
@@ -3024,7 +3024,6 @@
},
/obj/effect/mapping_helpers/airlock/access/all/away/general,
/obj/machinery/door/firedoor,
-/obj/effect/mapping_helpers/airlock/cyclelink_helper,
/turf/open/floor/iron/textured_half{
dir = 4
},
@@ -3650,9 +3649,6 @@
name = "Hotel Kitchen"
},
/obj/effect/mapping_helpers/airlock/access/all/away/general,
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 4
- },
/turf/open/floor/stone,
/area/ruin/space/has_grav/hotel/bar)
"Lv" = (
diff --git a/_maps/map_files/Blueshift/Blueshift.dmm b/_maps/map_files/Blueshift/Blueshift.dmm
index 966f8080edd8..a95cb5b9546a 100644
--- a/_maps/map_files/Blueshift/Blueshift.dmm
+++ b/_maps/map_files/Blueshift/Blueshift.dmm
@@ -89189,6 +89189,18 @@
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron/white,
/area/station/medical/patients_rooms)
+"rnW" = (
+/obj/docking_port/stationary{
+ dheight = 1;
+ dir = 8;
+ dwidth = 12;
+ height = 17;
+ name = "northwest of station";
+ shuttle_id = "syndicate_nw";
+ width = 23
+ },
+/turf/open/space/openspace,
+/area/space)
"rnY" = (
/obj/structure/chair/stool/bar,
/obj/effect/decal/cleanable/dirt,
@@ -201454,7 +201466,7 @@ ulx
ulx
ulx
ulx
-ulx
+rnW
ulx
ulx
ulx
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 6be547e1563f..b560c5316f9f 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -5804,7 +5804,7 @@
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 9
},
-/obj/structure/sink/directional/south,
+/obj/machinery/vending/hydroseeds,
/turf/open/floor/iron/dark/side{
dir = 9
},
@@ -33348,6 +33348,7 @@
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 1
},
+/obj/machinery/vending/hydronutrients,
/turf/open/floor/iron/dark/side{
dir = 1
},
@@ -53264,6 +53265,10 @@
/mob/living/simple_animal/bot/secbot/pingsky,
/turf/open/floor/engine,
/area/station/ai_monitored/turret_protected/aisat_interior)
+"ruB" = (
+/obj/structure/sink/directional/south,
+/turf/closed/wall,
+/area/station/maintenance/port/fore)
"ruC" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -72889,7 +72894,7 @@
dir = 8
},
/obj/effect/turf_decal/siding/wood/corner,
-/obj/machinery/duct,
+/obj/structure/sink/directional/east,
/turf/open/floor/iron/dark/side{
dir = 8
},
@@ -87315,7 +87320,7 @@ fPN
cwL
mYW
vKc
-fPN
+ruB
kNO
aKB
tIO
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 8cb8166ce207..b231ec1a3dd2 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -19338,7 +19338,6 @@
/turf/open/floor/iron/dark,
/area/station/commons/locker)
"eCs" = (
-/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/turf_decal/siding/green{
dir = 8
@@ -28280,7 +28279,6 @@
/turf/open/floor/iron/dark/smooth_large,
/area/station/ai_monitored/security/armory)
"gFK" = (
-/obj/machinery/vending/hydroseeds,
/obj/machinery/light_switch/directional/north{
pixel_x = -8
},
@@ -31129,6 +31127,7 @@
dir = 4
},
/obj/effect/decal/cleanable/dirt,
+/obj/structure/cable,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"hoR" = (
@@ -43506,7 +43505,6 @@
/turf/closed/wall/r_wall,
/area/station/science/robotics/lab)
"khc" = (
-/obj/structure/cable,
/obj/machinery/seed_extractor,
/obj/item/seeds/tree,
/obj/item/seeds/watermelon,
@@ -43517,8 +43515,8 @@
/obj/item/seeds/cocoapod,
/obj/item/seeds/banana,
/obj/item/seeds/apple,
-/obj/machinery/power/apc/auto_name/directional/west,
/obj/machinery/light/small/directional/west,
+/obj/machinery/vending/hydroseeds/wall/directional/west,
/turf/open/floor/iron/dark,
/area/station/service/hydroponics/garden)
"khl" = (
@@ -56215,7 +56213,6 @@
/turf/open/floor/iron,
/area/station/cargo/lobby)
"nkI" = (
-/obj/machinery/camera/autoname/directional/north,
/obj/structure/table,
/obj/item/book/manual/wiki/cooking_to_serve_man,
/obj/item/reagent_containers/condiment/enzyme{
@@ -59232,6 +59229,7 @@
/obj/machinery/light_switch/directional/south{
pixel_x = 8
},
+/obj/machinery/newscaster/directional/west,
/turf/open/floor/wood,
/area/station/hallway/secondary/service)
"nXj" = (
@@ -59599,6 +59597,7 @@
dir = 4
},
/obj/effect/decal/cleanable/dirt,
+/obj/structure/cable,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"obH" = (
@@ -65070,6 +65069,7 @@
/obj/effect/turf_decal/siding/green{
dir = 5
},
+/obj/structure/cable,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"puq" = (
@@ -82295,6 +82295,7 @@
c_tag = "Garden"
},
/obj/structure/sign/poster/contraband/random/directional/east,
+/obj/structure/cable,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"tAJ" = (
@@ -83644,6 +83645,7 @@
"tPD" = (
/obj/machinery/biogenerator,
/obj/item/reagent_containers/cup/watering_can,
+/obj/machinery/vending/hydronutrients/wall/directional/west,
/turf/open/floor/iron/dark,
/area/station/service/hydroponics/garden)
"tPE" = (
@@ -90580,6 +90582,7 @@
/obj/effect/turf_decal/siding/green{
dir = 1
},
+/obj/structure/cable,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"vxL" = (
@@ -92433,6 +92436,8 @@
/turf/open/floor/iron,
/area/station/engineering/hallway)
"vWu" = (
+/obj/machinery/power/apc/auto_name/directional/east,
+/obj/structure/cable,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"vWv" = (
@@ -96637,7 +96642,7 @@
/turf/open/floor/iron/dark,
/area/station/hallway/primary/fore)
"wTJ" = (
-/obj/machinery/vending/hydronutrients,
+/obj/machinery/composters,
/turf/open/floor/iron/dark,
/area/station/service/hydroponics/garden)
"wTK" = (
@@ -100640,7 +100645,6 @@
"xSf" = (
/obj/structure/bed,
/obj/item/bedsheet/clown,
-/obj/machinery/newscaster/directional/east,
/obj/structure/sign/poster/random/directional/north,
/turf/open/floor/wood,
/area/station/hallway/secondary/service)
diff --git a/_maps/map_files/Graveyard/Graveyard.dmm b/_maps/map_files/Graveyard/Graveyard.dmm
index 3ddc9961a7bf..656dc0e33c9a 100644
--- a/_maps/map_files/Graveyard/Graveyard.dmm
+++ b/_maps/map_files/Graveyard/Graveyard.dmm
@@ -20164,6 +20164,7 @@
"hOS" = (
/obj/machinery/growing/tray,
/obj/machinery/light/directional/north,
+/obj/machinery/vending/hydronutrients/wall/directional/west,
/turf/open/floor/grass,
/area/station/service/hydroponics/garden)
"hOV" = (
@@ -28605,6 +28606,7 @@
/area/station/engineering/supermatter/room)
"lgD" = (
/obj/machinery/airalarm/directional/south,
+/obj/machinery/composters,
/turf/open/floor/grass,
/area/station/service/hydroponics/garden)
"lgK" = (
@@ -48410,6 +48412,11 @@
},
/turf/open/floor/iron/cafeteria,
/area/station/service/kitchen)
+"sUU" = (
+/obj/machinery/growing/tray,
+/obj/machinery/vending/hydroseeds/wall/directional/west,
+/turf/open/floor/grass,
+/area/station/service/hydroponics/garden)
"sUV" = (
/obj/machinery/atmospherics/components/unary/cryo_cell,
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -166027,7 +166034,7 @@ aUl
gnB
vOT
hOS
-jxf
+sUU
xPW
jxf
qcz
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index 61d3e619a032..9553433c5639 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -13094,6 +13094,11 @@
"dZJ" = (
/obj/machinery/seed_extractor,
/obj/machinery/status_display/evac/directional/north,
+/obj/effect/spawner/random/food_or_drink/seed,
+/obj/effect/spawner/random/food_or_drink/seed,
+/obj/effect/spawner/random/food_or_drink/seed,
+/obj/effect/spawner/random/food_or_drink/seed,
+/obj/effect/spawner/random/food_or_drink/seed,
/turf/open/floor/iron/dark,
/area/station/service/hydroponics/garden)
"dZN" = (
@@ -19462,13 +19467,13 @@
/turf/open/floor/plating,
/area/station/maintenance/aft/lesser)
"geZ" = (
-/obj/structure/sink/directional/south,
/obj/effect/turf_decal/siding/wood{
dir = 8
},
/obj/effect/turf_decal/tile/neutral/half/contrasted{
dir = 8
},
+/obj/structure/extinguisher_cabinet/directional/north,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"gfb" = (
@@ -28367,10 +28372,10 @@
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
"jaS" = (
-/obj/structure/extinguisher_cabinet/directional/north,
/obj/effect/turf_decal/siding/green{
dir = 8
},
+/obj/machinery/vending/hydroseeds/wall/directional/north,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"jaW" = (
@@ -70702,13 +70707,13 @@
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
"wDf" = (
-/obj/structure/sink/directional/south,
/obj/effect/turf_decal/siding/wood{
dir = 4
},
/obj/effect/turf_decal/tile/neutral/half/contrasted{
dir = 4
},
+/obj/machinery/vending/hydronutrients/wall/directional/north,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"wDg" = (
@@ -73808,16 +73813,7 @@
/turf/open/floor/iron,
/area/station/commons/vacant_room/commissary)
"xAS" = (
-/obj/item/seeds/apple,
-/obj/item/seeds/banana,
-/obj/item/seeds/cocoapod,
-/obj/item/seeds/grape,
-/obj/item/seeds/orange,
-/obj/item/seeds/sugarcane,
-/obj/item/seeds/wheat,
-/obj/item/seeds/watermelon,
-/obj/structure/table/glass,
-/obj/item/seeds/tree,
+/obj/machinery/composters,
/turf/open/floor/iron/dark,
/area/station/service/hydroponics/garden)
"xAW" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 03bf8546585c..f8ceb07fca11 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -15325,12 +15325,8 @@
/turf/open/floor/plating/airless,
/area/station/solars/port/fore)
"fzr" = (
-/obj/structure/table,
/obj/effect/turf_decal/stripes/line,
-/obj/effect/spawner/random/food_or_drink/seed{
- spawn_all_loot = 1;
- spawn_random_offset = 1
- },
+/obj/machinery/composters,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"fzG" = (
@@ -60256,6 +60252,11 @@
/obj/machinery/seed_extractor,
/obj/machinery/airalarm/directional/north,
/obj/effect/turf_decal/stripes/line,
+/obj/effect/spawner/random/food_or_drink/seed,
+/obj/effect/spawner/random/food_or_drink/seed,
+/obj/effect/spawner/random/food_or_drink/seed,
+/obj/effect/spawner/random/food_or_drink/seed,
+/obj/effect/spawner/random/food_or_drink/seed,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"uKx" = (
diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm
index 4f6bd4e03623..ba611c6c0286 100644
--- a/_maps/map_files/Mining/Lavaland.dmm
+++ b/_maps/map_files/Mining/Lavaland.dmm
@@ -4139,6 +4139,7 @@
dir = 10
},
/obj/effect/turf_decal/trimline/blue/filled/warning,
+/obj/machinery/vending/hydroseeds/wall/directional/west,
/turf/open/floor/iron/dark,
/area/mine/hydroponics)
"xt" = (
@@ -6927,12 +6928,12 @@
/turf/open/floor/iron/smooth,
/area/mine/laborcamp)
"OM" = (
-/obj/structure/table,
/obj/machinery/power/apc/auto_name/directional/east,
/obj/structure/cable,
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 4
},
+/obj/machinery/composters,
/turf/open/floor/iron/dark/smooth_edge{
dir = 1
},
@@ -7505,6 +7506,7 @@
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 8
},
+/obj/machinery/vending/hydronutrients/wall/directional/west,
/turf/open/floor/iron/dark/smooth_edge{
dir = 4
},
diff --git a/_maps/map_files/Ouroboros/Ouroboros.dmm b/_maps/map_files/Ouroboros/Ouroboros.dmm
index b7dc992ac0dc..3bab030d28a3 100644
--- a/_maps/map_files/Ouroboros/Ouroboros.dmm
+++ b/_maps/map_files/Ouroboros/Ouroboros.dmm
@@ -57648,6 +57648,10 @@
/obj/effect/mapping_helpers/airlock/welded,
/turf/open/floor/plating,
/area/station/science/research/abandoned)
+"qZh" = (
+/obj/machinery/composters,
+/turf/open/floor/grass,
+/area/station/service/hydroponics/garden)
"qZi" = (
/obj/structure/sign/flag/mothic/directional/north,
/obj/effect/spawner/random/engineering/tank,
@@ -64306,6 +64310,7 @@
"sXX" = (
/obj/machinery/growing/soil,
/obj/machinery/light/warm/directional/north,
+/obj/machinery/vending/hydroseeds/wall/directional/north,
/turf/open/floor/grass,
/area/station/service/hydroponics/garden)
"sYb" = (
@@ -65300,6 +65305,7 @@
/obj/machinery/growing/soil,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/vending/hydronutrients/wall/directional/north,
/turf/open/floor/grass,
/area/station/service/hydroponics/garden)
"tne" = (
@@ -185336,7 +185342,7 @@ dEd
lxY
inH
uvP
-dHo
+qZh
odH
sYM
jgK
diff --git a/_maps/map_files/Voidraptor/VoidRaptor.dmm b/_maps/map_files/Voidraptor/VoidRaptor.dmm
index 90f843728e58..ba8ab83de824 100644
--- a/_maps/map_files/Voidraptor/VoidRaptor.dmm
+++ b/_maps/map_files/Voidraptor/VoidRaptor.dmm
@@ -5286,18 +5286,9 @@
/turf/open/floor/iron/white/small,
/area/station/common/pool)
"bzu" = (
-/obj/structure/table,
-/obj/item/food/grown/wheat,
-/obj/item/food/grown/watermelon,
-/obj/item/food/grown/citrus/orange,
-/obj/item/food/grown/grapes,
-/obj/item/food/grown/cocoapod,
-/obj/item/food/grown/apple,
-/obj/item/food/grown/chili,
-/obj/item/food/grown/cherries,
-/obj/item/food/grown/soybeans,
-/obj/item/food/grown/citrus/lime,
/obj/machinery/light/warm/directional/south,
+/obj/effect/turf_decal/bot,
+/obj/machinery/composters,
/turf/open/floor/iron/dark/textured_large,
/area/station/service/hydroponics/garden)
"bzE" = (
@@ -48068,8 +48059,16 @@
/area/station/hallway/secondary/command)
"nxi" = (
/obj/structure/table,
-/obj/item/reagent_containers/cup/watering_can,
-/obj/item/reagent_containers/cup/watering_can,
+/obj/item/food/grown/wheat,
+/obj/item/food/grown/watermelon,
+/obj/item/food/grown/citrus/orange,
+/obj/item/food/grown/grapes,
+/obj/item/food/grown/cocoapod,
+/obj/item/food/grown/apple,
+/obj/item/food/grown/chili,
+/obj/item/food/grown/cherries,
+/obj/item/food/grown/soybeans,
+/obj/item/food/grown/citrus/lime,
/turf/open/floor/iron/dark/textured_large,
/area/station/service/hydroponics/garden)
"nxj" = (
diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm
index 801cb6ab3862..c7d94ed88607 100644
--- a/_maps/map_files/generic/CentCom.dmm
+++ b/_maps/map_files/generic/CentCom.dmm
@@ -5581,13 +5581,6 @@
/obj/effect/decal/cleanable/blood/splatter,
/turf/open/floor/grass,
/area/centcom/wizard_station)
-"apc" = (
-/obj/machinery/vending/coffee,
-/obj/effect/turf_decal/siding/thinplating_new/dark{
- dir = 4
- },
-/turf/open/floor/mineral/titanium,
-/area/centcom/syndicate_mothership/control)
"apd" = (
/obj/item/clipboard,
/obj/item/stamp/denied{
@@ -19609,6 +19602,10 @@
/obj/machinery/light/cold/directional/north,
/turf/open/misc/asteroid,
/area/cruiser_dock)
+"bDP" = (
+/obj/item/toy/plush/pooba_bee_plush,
+/turf/open/floor/plating,
+/area/centcom/central_command_areas/admin)
"bER" = (
/obj/structure/table/reinforced/plasmarglass,
/obj/item/toy/plush/bubbleplush{
@@ -19899,6 +19896,14 @@
/obj/effect/turf_decal/siding/purple,
/turf/open/floor/iron/white/herringbone,
/area/centcom/central_command_areas/kitchen)
+"cuQ" = (
+/obj/structure/closet/cabinet,
+/obj/item/clothing/suit/jacket/tailcoat/centcom,
+/obj/item/clothing/head/hats/centcom_cap,
+/obj/machinery/light/directional/north,
+/obj/item/flashlight,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"cuW" = (
/obj/machinery/photocopier/gratis{
pixel_y = -3
@@ -20043,6 +20048,12 @@
/obj/structure/fake_stairs/wood/directional/north,
/turf/open/misc/dirt/jungle/dark/arena,
/area/centcom/central_command_areas/admin)
+"cHn" = (
+/obj/machinery/modular_computer/preset/id/centcom{
+ dir = 1
+ },
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"cHC" = (
/obj/item/toy/plush/nova/deer{
desc = "Lovingly named after a particularly frustrating and amusing interaction.";
@@ -20110,13 +20121,6 @@
},
/turf/open/floor/carpet/neon/simple/blue/nodots,
/area/centcom/central_command_areas/prison)
-"cMo" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 4
- },
-/obj/effect/turf_decal/siding/wood,
-/turf/open/floor/wood/tile,
-/area/centcom/central_command_areas/admin)
"cMW" = (
/obj/structure/railing/wooden_fence{
dir = 10
@@ -20482,6 +20486,11 @@
dir = 4
},
/area/cruiser_dock)
+"dEL" = (
+/obj/machinery/computer,
+/obj/machinery/light/directional/north,
+/turf/open/floor/plating,
+/area/centcom/central_command_areas/admin)
"dGn" = (
/obj/machinery/chem_master,
/turf/open/floor/iron/dark/textured_large,
@@ -20732,11 +20741,6 @@
},
/turf/open/floor/iron/dark/textured_large,
/area/cruiser_dock)
-"elw" = (
-/obj/machinery/vending/coffee,
-/obj/machinery/light/directional/north,
-/turf/open/floor/mineral/titanium/tiled/white,
-/area/centcom/central_command_areas/adminroom)
"eru" = (
/obj/structure/window/reinforced/spawner/directional/west,
/obj/structure/bed{
@@ -20851,6 +20855,11 @@
},
/turf/open/floor/iron/dark/textured_large,
/area/cruiser_dock)
+"eCp" = (
+/obj/structure/table/reinforced,
+/obj/item/aicard,
+/turf/open/floor/iron,
+/area/centcom/central_command_areas/admin)
"eEo" = (
/obj/effect/turf_decal/siding/dark{
dir = 9
@@ -20886,6 +20895,17 @@
},
/turf/open/floor/iron/smooth_large,
/area/cruiser_dock)
+"eIT" = (
+/obj/structure/table/wood/fancy,
+/obj/item/storage/box/coffeepack,
+/obj/item/reagent_containers/cup/coffeepot/bluespace{
+ pixel_y = 9;
+ pixel_x = 5
+ },
+/obj/item/reagent_containers/cup/glass/mug/nanotrasen,
+/obj/machinery/light/directional/west,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"eJD" = (
/obj/structure/window/reinforced/tinted/frosted,
/obj/structure/closet/mini_fridge,
@@ -20984,6 +21004,10 @@
},
/turf/open/floor/plastic,
/area/centcom/central_command_areas/admin)
+"eXf" = (
+/obj/machinery/computer/camera_advanced,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"eYn" = (
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
dir = 4
@@ -21098,6 +21122,13 @@
/obj/structure/flora/bush/fullgrass/style_2,
/turf/open/floor/grass,
/area/centcom/central_command_areas/retirement_yard)
+"fgN" = (
+/mob/living/simple_animal/pet/cat/kitten{
+ name = "Kbity :3";
+ desc = "D'aaawwww. Fortune's best friend"
+ },
+/turf/open/floor/iron/dark/small,
+/area/centcom)
"fgR" = (
/obj/effect/turf_decal/siding/thinplating_new/dark{
dir = 8
@@ -21342,6 +21373,10 @@
"fXa" = (
/turf/open/misc/dirt/jungle/dark/arena,
/area/centcom/central_command_areas/admin)
+"fXF" = (
+/obj/machinery/computer/upload/ai,
+/turf/open/floor/circuit/green/anim,
+/area/centcom/central_command_areas/admin)
"fXH" = (
/obj/effect/turf_decal/weather/dirt,
/turf/open/water/arena,
@@ -21546,13 +21581,6 @@
/obj/structure/sign/poster/abductor/ayylian/directional/north,
/turf/open/floor/iron/dark/herringbone,
/area/centcom/central_command_areas/evacuation)
-"grU" = (
-/mob/living/simple_animal/pet/cat/kitten{
- name = "Kbity :3";
- desc = "D'aaawwww. Fortune's best friend"
- },
-/turf/open/floor/iron/dark/small,
-/area/centcom)
"gsj" = (
/obj/machinery/computer/crew{
dir = 1
@@ -21822,6 +21850,15 @@
},
/turf/open/water/arena,
/area/centcom/central_command_areas/admin)
+"gOS" = (
+/obj/machinery/button/door/directional/north{
+ name = "Emergency Assistants Fuck Off Button";
+ id = "donutstealthisid";
+ req_access = "cent_captain"
+ },
+/obj/machinery/computer/communications,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"gPN" = (
/obj/effect/turf_decal/weather/dirt{
dir = 4;
@@ -21893,6 +21930,13 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/centcom/central_command_areas/admin)
+"gWL" = (
+/obj/machinery/vending/coffee{
+ dir = 4
+ },
+/obj/machinery/light/directional/north,
+/turf/open/floor/mineral/titanium/tiled/white,
+/area/centcom/central_command_areas/adminroom)
"gXp" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -22203,6 +22247,10 @@
},
/turf/open/misc/sandy_dirt,
/area/centcom/central_command_areas/admin)
+"hzU" = (
+/obj/machinery/light/directional/south,
+/turf/open/floor/iron,
+/area/centcom/central_command_areas/admin)
"hAz" = (
/obj/structure/easel,
/obj/item/canvas/twentyfour_twentyfour,
@@ -22652,19 +22700,6 @@
},
/turf/open/floor/iron/dark,
/area/centcom/central_command_areas/admin)
-"ioX" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 8;
- pixel_y = -5
- },
-/obj/effect/turf_decal/siding/wood{
- dir = 8
- },
-/obj/structure/railing/wooden_fencing{
- pixel_y = 16
- },
-/turf/open/floor/sandy_dirt,
-/area/centcom/central_command_areas/admin)
"ipJ" = (
/obj/effect/mapping_helpers/airlock/access/any/admin/captain,
/obj/effect/turf_decal/trimline/red/real_red/filled/line{
@@ -22678,6 +22713,19 @@
},
/turf/open/floor/iron/dark/textured,
/area/centcom/central_command_areas/admin)
+"irf" = (
+/obj/machinery/light/directional/east,
+/obj/structure/bed/double,
+/obj/item/bedsheet/hos/double,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
+"irU" = (
+/obj/machinery/door/airlock/vault{
+ dir = 4
+ },
+/obj/effect/mapping_helpers/airlock/access/any/admin/general,
+/turf/open/floor/iron,
+/area/centcom/central_command_areas/admin)
"itR" = (
/obj/machinery/plumbing/ooze_compressor,
/turf/open/floor/engine,
@@ -22964,6 +23012,15 @@
dir = 1
},
/area/centcom/central_command_areas/adminroom)
+"jkI" = (
+/obj/structure/railing/wooden_fencing{
+ pixel_y = 16
+ },
+/obj/structure/railing/wooden_fencing{
+ pixel_y = 16
+ },
+/turf/open/floor/sandy_dirt,
+/area/centcom/central_command_areas/admin)
"jmi" = (
/obj/effect/turf_decal/weather/dirt{
dir = 6
@@ -23535,6 +23592,14 @@
},
/turf/open/floor/mineral/plastitanium/red,
/area/centcom/syndicate_mothership/expansion_bioterrorism)
+"kDH" = (
+/obj/item/language_manual{
+ language = /datum/language/machine;
+ name = "Silicon Speak for Dummies"
+ },
+/obj/structure/table/wood/fancy,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"kEZ" = (
/obj/effect/turf_decal/tile/dark/opposingcorners,
/obj/structure/hedge,
@@ -23586,6 +23651,15 @@
/obj/structure/flora/grass/jungle/b/style_4,
/turf/open/misc/dirt/jungle/dark/arena,
/area/centcom/central_command_areas/admin)
+"kNi" = (
+/obj/machinery/vending/coffee{
+ dir = 4
+ },
+/obj/effect/turf_decal/siding/thinplating_new/dark{
+ dir = 4
+ },
+/turf/open/floor/mineral/titanium,
+/area/centcom/syndicate_mothership/control)
"kNr" = (
/obj/effect/turf_decal/tile/blue{
dir = 4
@@ -23739,6 +23813,12 @@
dir = 1
},
/area/centcom/central_command_areas/evacuation)
+"ljE" = (
+/obj/structure/sign/paint{
+ name = "RIP Karissa Sep '99 - Apr '16"
+ },
+/turf/open/floor/sandy_dirt,
+/area/centcom/central_command_areas/admin)
"lki" = (
/obj/effect/turf_decal/trimline/dark_blue/line,
/obj/effect/turf_decal/trimline/dark_blue/filled/line{
@@ -24221,6 +24301,10 @@
/obj/structure/falsewall/wood,
/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/admin)
+"mQh" = (
+/obj/machinery/light/directional/west,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"mQI" = (
/obj/structure/table/greyscale,
/obj/machinery/light/directional/north,
@@ -24345,6 +24429,13 @@
/obj/machinery/light/directional/north,
/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/admin)
+"nlZ" = (
+/obj/machinery/vending/coffee{
+ dir = 4
+ },
+/obj/effect/turf_decal/bot_white,
+/turf/open/floor/iron/dark/textured_large,
+/area/cruiser_dock)
"nnN" = (
/obj/structure/flora/bush/fullgrass/style_random,
/obj/structure/flora/bush/flowers_pp,
@@ -24564,6 +24655,13 @@
},
/turf/open/floor/glass/plasma,
/area/centcom/central_command_areas/kitchen)
+"nUB" = (
+/obj/effect/spawner/random/entertainment/arcade{
+ dir = 8
+ },
+/obj/machinery/light/directional/east,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"nUK" = (
/obj/docking_port/stationary{
dir = 8;
@@ -24730,6 +24828,11 @@
},
/turf/open/floor/iron/white/textured,
/area/centcom/central_command_areas/admin)
+"omi" = (
+/obj/structure/table/wood/fancy,
+/obj/item/pai_card,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"ooz" = (
/obj/machinery/light/neon_lining{
icon_state = "pink2_1"
@@ -24882,6 +24985,14 @@
/obj/structure/flora/bush/fullgrass/style_2,
/turf/open/floor/grass,
/area/centcom/central_command_areas/admin)
+"oKl" = (
+/obj/machinery/door/airlock/maintenance_hatch{
+ dir = 4;
+ name = "Pooba's Coder Closet"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/admin/general,
+/turf/open/floor/plating,
+/area/centcom/central_command_areas/admin)
"oLl" = (
/obj/structure/table/glass/plasmaglass,
/obj/item/vacuum_pack,
@@ -24920,6 +25031,9 @@
},
/turf/open/floor/iron/dark/textured_corner,
/area/centcom/central_command_areas/evacuation)
+"oQo" = (
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"oSV" = (
/obj/machinery/door/airlock/centcom{
name = "Checkpoint Office"
@@ -24938,6 +25052,10 @@
/obj/item/clothing/suit/space/hardsuit/juggernaut,
/turf/open/floor/catwalk_floor/iron_smooth,
/area/centcom/syndicate_mothership/expansion_bulldozer)
+"oVW" = (
+/obj/item/kirbyplants/organic/plant23,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"oWK" = (
/obj/machinery/fishing_portal_generator,
/turf/open/floor/sandy_dirt,
@@ -25001,6 +25119,13 @@
},
/turf/open/floor/iron/dark/smooth_large,
/area/centcom/central_command_areas/retirement_yard)
+"pcz" = (
+/obj/structure/table/reinforced,
+/obj/machinery/fax{
+ name = "Beverly's Fax Machine"
+ },
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"peK" = (
/obj/structure/railing/wood{
dir = 4
@@ -25397,6 +25522,12 @@
dir = 8
},
/area/cruiser_dock)
+"qfb" = (
+/obj/effect/spawner/random/entertainment/arcade{
+ dir = 8
+ },
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"qfR" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -25615,6 +25746,13 @@
},
/turf/open/floor/eighties/red,
/area/centcom/central_command_areas/admin)
+"qDA" = (
+/obj/machinery/door/airlock/vault{
+ dir = 4
+ },
+/obj/effect/mapping_helpers/airlock/access/any/admin/general,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"qGq" = (
/obj/machinery/light/floor/has_bulb,
/obj/structure/table/reinforced/rglass,
@@ -25643,6 +25781,16 @@
},
/turf/open/misc/asteroid,
/area/centcom/central_command_areas/admin)
+"qIf" = (
+/obj/structure/ai_core/deactivated{
+ name = "MATRIARCH"
+ },
+/turf/open/floor/circuit/green/anim,
+/area/centcom/central_command_areas/admin)
+"qIP" = (
+/obj/structure/chair/comfy/black,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"qIZ" = (
/obj/structure/railing/wooden_fence{
dir = 8
@@ -25716,6 +25864,11 @@
/obj/effect/spawner/random/trash/cigbutt,
/turf/open/floor/plating/rust,
/area/centcom/central_command_areas/adminroom)
+"qNS" = (
+/obj/structure/table/wood/fancy,
+/obj/machinery/coffeemaker,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"qOJ" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 1
@@ -25726,6 +25879,10 @@
},
/turf/open/floor/iron/white/textured,
/area/centcom/central_command_areas/admin)
+"qQr" = (
+/obj/structure/decorative/shelf/alcohol,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"qRd" = (
/obj/machinery/light/cold/directional/north,
/obj/structure/table/reinforced/plastitaniumglass,
@@ -26129,6 +26286,11 @@
/obj/machinery/light/street_lamp,
/turf/open/floor/grass,
/area/centcom/central_command_areas/admin)
+"rVL" = (
+/obj/item/radio/headset/headset_cent,
+/obj/structure/table/reinforced,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"rWQ" = (
/obj/structure/railing{
dir = 8
@@ -26292,6 +26454,14 @@
/obj/structure/billboard/space_cola,
/turf/open/floor/iron/dark/textured_corner,
/area/centcom/central_command_areas/evacuation)
+"slp" = (
+/obj/structure/table/wood/fancy,
+/obj/item/reagent_containers/cup/glass/flask,
+/obj/item/reagent_containers/cup/glass/drinkingglass,
+/obj/item/clothing/mask/cigarette/rollie/cannabis,
+/obj/item/lighter/bright,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"ssC" = (
/obj/effect/turf_decal/weather/dirt{
dir = 1
@@ -26689,13 +26859,11 @@
/obj/item/healthanalyzer/advanced,
/turf/open/floor/iron/dark,
/area/centcom/central_command_areas/medical)
-"twW" = (
-/mob/living/simple_animal/pet/cat/cak{
- name = "Truffle";
- desc = "She is a cat made out of cake. How the hell did this thing end up alive, much less here?!"
- },
-/turf/open/floor/glass/reinforced/plasma,
-/area/centcom/central_command_areas/adminroom)
+"txY" = (
+/obj/structure/table/reinforced,
+/obj/machinery/recharger,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"tyg" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -26881,6 +27049,18 @@
/obj/machinery/light/directional/west,
/turf/open/water/arena,
/area/centcom/central_command_areas/admin)
+"tUP" = (
+/obj/structure/table/reinforced,
+/obj/item/paper_bin{
+ pixel_y = 5
+ },
+/obj/item/pen{
+ pixel_y = 8
+ },
+/obj/item/stamp/centcom,
+/obj/item/stamp/denied,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"tVr" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -26940,13 +27120,6 @@
/obj/effect/decal/cleanable/dirt/dust,
/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/admin)
-"ued" = (
-/obj/structure/mineral_door/wood{
- color = "543e27";
- name = "empty office"
- },
-/turf/open/floor/sandy_dirt,
-/area/centcom/central_command_areas/admin)
"uei" = (
/obj/effect/turf_decal/stripes/box,
/turf/open/floor/mineral/plastitanium,
@@ -27419,6 +27592,11 @@
},
/turf/open/floor/iron/dark,
/area/centcom/central_command_areas/evacuation)
+"vrX" = (
+/obj/item/flashlight/lamp,
+/obj/structure/table/wood/fancy,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"vsR" = (
/obj/structure/sign{
name = "wall";
@@ -27916,22 +28094,6 @@
},
/turf/open/floor/wood/large,
/area/centcom/central_command_areas/admin)
-"wrH" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 4;
- pixel_y = -5
- },
-/obj/effect/turf_decal/siding/wood{
- dir = 4
- },
-/obj/structure/railing/wooden_fencing{
- pixel_y = 16
- },
-/obj/structure/railing/wooden_fencing{
- pixel_y = 16
- },
-/turf/open/floor/sandy_dirt,
-/area/centcom/central_command_areas/admin)
"wso" = (
/obj/effect/turf_decal/weather,
/turf/open/floor/sandy_dirt,
@@ -28047,6 +28209,13 @@
/obj/item/modular_computer/laptop,
/turf/open/floor/wood/parquet,
/area/centcom/central_command_areas/admin)
+"wHn" = (
+/obj/machinery/door/airlock/gold{
+ name = "Beverly Valon's Office"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/admin/general,
+/turf/open/floor/wood/tile,
+/area/centcom/central_command_areas/admin)
"wHC" = (
/obj/structure/table/wood,
/obj/effect/spawner/random/special_lighter,
@@ -28132,16 +28301,15 @@
dir = 8
},
/area/cruiser_dock)
+"wSw" = (
+/obj/structure/showcase/machinery/tv,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"wTG" = (
/obj/effect/spawner/random/trash/bacteria,
/obj/effect/spawner/random/trash/garbage,
/turf/open/floor/iron/vaporwave,
/area/centcom/central_command_areas/adminroom)
-"wTZ" = (
-/obj/machinery/vending/coffee,
-/obj/effect/turf_decal/bot_white,
-/turf/open/floor/iron/dark/textured_large,
-/area/cruiser_dock)
"wVL" = (
/obj/structure/fans/tiny/forcefield{
color = "#276c87"
@@ -28305,6 +28473,21 @@
},
/turf/open/floor/glass/plasma,
/area/centcom/central_command_areas/adminroom)
+"xpa" = (
+/obj/structure/chair/comfy/black{
+ dir = 1
+ },
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
+"xqm" = (
+/obj/item/bodypart/chest/ipc,
+/obj/item/bodypart/arm/left/ipc,
+/obj/item/bodypart/arm/right/ipc,
+/obj/item/bodypart/head/ipc,
+/obj/item/bodypart/leg/left/ipc,
+/obj/item/bodypart/leg/right/ipc,
+/turf/open/floor/circuit/green/anim,
+/area/centcom/central_command_areas/admin)
"xqY" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 4
@@ -28684,6 +28867,13 @@
dir = 1
},
/area/centcom/central_command_areas/evacuation)
+"yix" = (
+/obj/machinery/light/directional/east{
+ dir = 1
+ },
+/obj/machinery/computer/message_monitor,
+/turf/open/floor/carpet/red,
+/area/centcom/central_command_areas/admin)
"yiO" = (
/obj/effect/turf_decal/siding/wood{
dir = 4
@@ -42523,7 +42713,7 @@ acz
acz
anK
arS
-apc
+kNi
anK
anK
anK
@@ -56528,7 +56718,7 @@ aaa
aaa
aaa
kpH
-elw
+gWL
aAl
aAl
aAl
@@ -59155,7 +59345,7 @@ aMc
aMc
lSF
fAH
-grU
+fgN
eBX
lSF
jsr
@@ -59171,7 +59361,7 @@ wpP
nnN
dii
vkm
-twW
+aNa
iLo
jvQ
vxh
@@ -65758,11 +65948,11 @@ aaa
aaa
aaa
aaa
-aOn
-lgW
-lgW
-lgW
-lgW
+blK
+dEL
+bDP
+qGw
+blK
lgW
lgW
lgW
@@ -66018,7 +66208,7 @@ aaa
blK
blK
blK
-blK
+oKl
blK
blK
blK
@@ -66273,16 +66463,16 @@ aaa
aaa
aaa
blK
-kFQ
-tVr
-nPn
-kdH
-gXp
-bHb
+pcz
+tUP
+oQo
+oQo
+qNS
+eIT
blK
aMc
jRn
-wrH
+jkI
exa
pkc
qZk
@@ -66530,17 +66720,17 @@ aaa
aaa
aaa
blK
-cnR
-vPE
-cmN
-ijQ
-cKq
-jJO
+eXf
+oQo
+oQo
+oQo
+oQo
+omi
blK
cdN
aMc
kPZ
-eTJ
+exa
exa
exa
exa
@@ -66787,17 +66977,17 @@ aaa
aaa
aaa
blK
-qKa
-lpd
-flv
-ijQ
-cKq
-jJO
-ued
+yix
+qIP
+cHn
+oQo
+oQo
+oQo
+wHn
aMc
aMc
kPZ
-eTJ
+exa
exa
exa
mIn
@@ -67044,17 +67234,17 @@ aaa
aaa
aaa
blK
-fex
-vPE
-cmN
-ijQ
-cKq
-jJO
+gOS
+oQo
+rVL
+oQo
+oQo
+oQo
blK
cdN
aMc
kPZ
-eTJ
+exa
jbR
exa
rRY
@@ -67301,16 +67491,16 @@ aaa
aaa
aaa
blK
-wJw
-vBV
-jwN
-iwc
-dIy
-cMo
+txY
+oQo
+oQo
+oQo
+qfb
+nUB
blK
aMc
jRn
-ioX
+duN
exa
exa
exa
@@ -67559,7 +67749,7 @@ aaa
aaa
blK
blK
-blK
+qDA
vyT
blK
blK
@@ -67814,14 +68004,14 @@ aaa
aaa
aaa
aaa
-aOn
-exa
-exa
-exa
-exa
-exa
-exa
-exa
+blK
+cuQ
+oQo
+oQo
+oQo
+mQh
+oVW
+blK
exa
exa
exa
@@ -68071,14 +68261,14 @@ aaa
aaa
aaa
aaa
-aOn
-exa
-exa
-exa
-exa
-exa
-exa
-exa
+blK
+blK
+irU
+blK
+oQo
+oQo
+slp
+blK
exa
exa
exa
@@ -68328,14 +68518,14 @@ aaa
aaa
aaa
aaa
-aOn
-exa
-exa
-exa
-exa
-exa
-exa
-exa
+blK
+xqm
+kWs
+blK
+wSw
+oQo
+xpa
+blK
exa
exa
exa
@@ -68585,14 +68775,14 @@ aaa
aaa
aaa
aaa
-aOn
-exa
-exa
-exa
-exa
-exa
-exa
-exa
+blK
+fXF
+hzU
+blK
+oQo
+oQo
+qQr
+blK
exa
aeB
aeB
@@ -68842,14 +69032,14 @@ aaa
aaa
aaa
aaa
-aOn
-exa
-exa
-exa
-exa
-exa
-exa
-exa
+blK
+qIf
+eCp
+blK
+vrX
+irf
+kDH
+blK
aeB
aeB
exa
@@ -69099,14 +69289,14 @@ aaa
aaa
aaa
aaa
-aOn
-exa
-exa
-exa
-exa
-exa
-aeB
-exa
+blK
+blK
+blK
+blK
+blK
+blK
+blK
+blK
exa
aeB
aeB
@@ -69358,7 +69548,7 @@ aaa
aaa
aOn
aeB
-exa
+ljE
exa
exa
exa
@@ -81676,7 +81866,7 @@ dUR
dUR
dUR
tWT
-wTZ
+nlZ
axV
axV
nvZ
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index 9b852eabbc2e..4f2d41328a51 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -10023,6 +10023,8 @@
c_tag = "Science - Front Lobby";
network = list("ss13","rd")
},
+/obj/machinery/power/apc/auto_name/directional/south,
+/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/lobby)
"caK" = (
@@ -11999,6 +12001,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/effect/landmark/event_spawn,
/turf/open/floor/iron,
/area/station/science/robotics/mechbay)
"cHn" = (
@@ -19970,6 +19973,11 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/ce)
+"fkB" = (
+/obj/effect/turf_decal/trimline/purple/filled/line,
+/obj/structure/cable,
+/turf/open/floor/iron/white,
+/area/station/science/lobby)
"fkD" = (
/obj/structure/closet/radiation,
/obj/effect/turf_decal/bot,
@@ -20541,19 +20549,15 @@
/turf/open/floor/iron,
/area/station/commons/dorms)
"ftt" = (
-/obj/structure/table/glass,
/obj/item/radio/intercom/directional/north,
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 1
},
-/obj/effect/spawner/random/food_or_drink/seed{
- spawn_all_loot = 1;
- spawn_random_offset = 1
- },
/obj/machinery/light_switch/directional/north{
pixel_x = 11;
pixel_y = 22
},
+/obj/machinery/composters,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"ftv" = (
@@ -24235,7 +24239,6 @@
/turf/open/floor/wood/large,
/area/station/service/library)
"gFu" = (
-/obj/effect/landmark/event_spawn,
/obj/structure/disposalpipe/segment{
dir = 4
},
@@ -28553,11 +28556,6 @@
/obj/effect/turf_decal/stripes/line{
dir = 4
},
-/obj/machinery/button/door/directional/north{
- id = "mechbay";
- name = "Mech Bay Shutters Control";
- req_access = list("robotics")
- },
/turf/open/floor/iron,
/area/station/science/robotics/mechbay)
"ibt" = (
@@ -28627,9 +28625,13 @@
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
"icx" = (
-/obj/structure/chair/stool/directional/north,
-/turf/open/floor/iron,
-/area/station/science/robotics/mechbay)
+/obj/effect/spawner/structure/window/reinforced,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "genetics";
+ name = "Robotics Lab Shutters"
+ },
+/turf/open/floor/plating,
+/area/station/science/genetics)
"icH" = (
/obj/structure/lattice/catwalk,
/obj/structure/railing{
@@ -29122,10 +29124,30 @@
/area/station/security/processing)
"ijf" = (
/obj/machinery/seed_extractor,
-/obj/machinery/firealarm/directional/north,
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 1
},
+/obj/effect/spawner/random/food_or_drink/seed{
+ spawn_all_loot = 1;
+ spawn_random_offset = 1
+ },
+/obj/effect/spawner/random/food_or_drink/seed{
+ spawn_all_loot = 1;
+ spawn_random_offset = 1
+ },
+/obj/effect/spawner/random/food_or_drink/seed{
+ spawn_all_loot = 1;
+ spawn_random_offset = 1
+ },
+/obj/effect/spawner/random/food_or_drink/seed{
+ spawn_all_loot = 1;
+ spawn_random_offset = 1
+ },
+/obj/effect/spawner/random/food_or_drink/seed{
+ spawn_all_loot = 1;
+ spawn_random_offset = 1
+ },
+/obj/machinery/vending/hydronutrients/wall/directional/north,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"ijj" = (
@@ -30587,6 +30609,7 @@
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 8
},
+/obj/machinery/firealarm/directional/west,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"iHD" = (
@@ -35245,15 +35268,13 @@
"kcF" = (
/obj/structure/table/reinforced,
/obj/effect/turf_decal/stripes/corner,
-/obj/item/clothing/gloves/latex,
-/obj/item/clothing/gloves/latex,
-/obj/item/clothing/mask/surgical,
-/obj/item/clothing/mask/surgical,
-/obj/item/reagent_containers/spray/cleaner{
- pixel_x = -10;
- pixel_y = -1
- },
/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/bodypart/arm/left/robot{
+ pixel_x = -3
+ },
+/obj/item/bodypart/arm/right/robot{
+ pixel_x = 3
+ },
/turf/open/floor/iron/dark,
/area/station/science/robotics/lab)
"kcQ" = (
@@ -35350,7 +35371,6 @@
/obj/effect/turf_decal/stripes/corner{
dir = 8
},
-/obj/machinery/power/apc/auto_name/directional/west,
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -37569,6 +37589,10 @@
pixel_x = 7
},
/obj/effect/turf_decal/tile/dark_green/fourcorners,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "genetics";
+ name = "Robotics Lab Shutters"
+ },
/turf/open/floor/iron/white/side,
/area/station/science/genetics)
"kNn" = (
@@ -42516,6 +42540,9 @@
/turf/open/floor/iron,
/area/station/security/prison/workout)
"moz" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
/turf/open/floor/iron,
/area/station/science/robotics/mechbay)
"moH" = (
@@ -44391,6 +44418,10 @@
req_access = list("robotics")
},
/obj/effect/turf_decal/tile/purple/fourcorners,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "robotics2";
+ name = "Robotics Lab Shutters"
+ },
/turf/open/floor/iron/white/side{
dir = 1
},
@@ -45465,6 +45496,11 @@
/area/station/command/heads_quarters/blueshield)
"nns" = (
/obj/structure/table/reinforced,
+/obj/item/storage/box/gloves{
+ pixel_x = 3;
+ pixel_y = 3
+ },
+/obj/item/storage/box/bodybags,
/turf/open/floor/iron/white,
/area/station/science/robotics/lab)
"nny" = (
@@ -45894,17 +45930,12 @@
/turf/open/floor/carpet,
/area/station/service/library)
"nto" = (
-/obj/structure/table/reinforced,
-/obj/effect/turf_decal/stripes/line,
-/obj/item/storage/box/gloves{
- pixel_x = 3;
- pixel_y = 3
+/obj/structure/chair/stool/directional/north,
+/obj/effect/turf_decal/stripes/corner{
+ dir = 8
},
-/obj/item/storage/box/bodybags,
-/obj/item/healthanalyzer,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/station/science/robotics/lab)
+/turf/open/floor/iron,
+/area/station/science/robotics/mechbay)
"ntp" = (
/obj/structure/closet/secure_closet/brig,
/obj/effect/turf_decal/trimline/red/filled/line{
@@ -50985,7 +51016,14 @@
/obj/structure/table/reinforced,
/obj/structure/window/spawner/directional/north,
/obj/structure/window/spawner/directional/west,
-/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/item/reagent_containers/spray/cleaner{
+ pixel_x = -10;
+ pixel_y = -1
+ },
+/obj/item/clothing/gloves/latex,
+/obj/item/clothing/gloves/latex,
+/obj/item/clothing/mask/surgical,
+/obj/item/clothing/mask/surgical,
/turf/open/floor/iron/white,
/area/station/science/robotics/lab)
"pfh" = (
@@ -53681,6 +53719,12 @@
/obj/item/clothing/under/rank/civilian/janitor/maid,
/turf/open/floor/iron/smooth,
/area/station/maintenance/disposal/incinerator)
+"pRo" = (
+/obj/effect/turf_decal/bot,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/item/robot_suit,
+/turf/open/floor/iron/dark,
+/area/station/science/robotics/lab)
"pRu" = (
/obj/machinery/conveyor_switch/oneway{
id = "cargoupperbelt"
@@ -54544,6 +54588,7 @@
/obj/machinery/camera/directional/north{
c_tag = "Civilian - Public Garden"
},
+/obj/machinery/vending/hydroseeds/wall/directional/north,
/turf/open/floor/iron,
/area/station/service/hydroponics/garden)
"qgG" = (
@@ -61736,11 +61781,12 @@
name = "Research and Development Shutter"
},
/obj/machinery/door/firedoor,
-/obj/machinery/door/window/left/directional/east{
+/obj/effect/turf_decal/tile/purple/fourcorners,
+/obj/item/paper_bin,
+/obj/machinery/door/window/left/directional/west{
name = "Research Lab Desk";
- req_access = list("science")
+ req_access = list("robotics")
},
-/obj/effect/turf_decal/tile/purple/fourcorners,
/turf/open/floor/iron/white/side{
dir = 4
},
@@ -61979,6 +62025,12 @@
req_access = list("robotics")
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/button/door/directional/north{
+ id = "mechbay";
+ name = "Mech Bay Shutters Control";
+ req_access = list("robotics");
+ pixel_x = -8
+ },
/turf/open/floor/iron/dark,
/area/station/science/robotics/lab)
"syH" = (
@@ -66920,7 +66972,10 @@
/turf/open/floor/iron/dark,
/area/station/ai_monitored/command/nuke_storage)
"uaJ" = (
-/obj/machinery/computer/mechpad,
+/obj/machinery/computer/mechpad{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/line,
/turf/open/floor/iron,
/area/station/science/robotics/mechbay)
"uaM" = (
@@ -67476,6 +67531,11 @@
c_tag = "Science - Robotics Surgery";
network = list("ss13","rd")
},
+/obj/item/healthanalyzer{
+ pixel_y = 5;
+ pixel_x = 5
+ },
+/obj/item/storage/backpack/duffelbag/med/surgery,
/turf/open/floor/iron/white,
/area/station/science/robotics/lab)
"ukT" = (
@@ -67536,6 +67596,20 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/engine,
/area/station/engineering/atmospherics_engine)
+"ulp" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/poddoor/shutters{
+ dir = 4;
+ id = "mechbay";
+ name = "Mech Bay"
+ },
+/obj/machinery/button/door/directional/north{
+ id = "mechbay";
+ name = "Mech Bay Shutters Control";
+ req_access = list("robotics")
+ },
+/turf/open/floor/plating,
+/area/station/science/robotics/mechbay)
"ulz" = (
/obj/effect/turf_decal/trimline/purple/filled/line{
dir = 1
@@ -70040,7 +70114,6 @@
"uXu" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
/obj/machinery/navbeacon{
location = "easttram5";
codes_txt = "patrol;next_patrol=midtram2"
@@ -71289,7 +71362,14 @@
},
/obj/machinery/requests_console/directional/west{
department = "Genetics";
- name = "Genetics Requests Console"
+ name = "Genetics Requests Console";
+ pixel_y = 6
+ },
+/obj/machinery/button/door/directional/west{
+ pixel_y = -8;
+ id = "genetics";
+ name = "Genetics Privacy Shutters";
+ req_access = list("genetics")
},
/turf/open/floor/iron/white,
/area/station/science/genetics)
@@ -71960,7 +72040,6 @@
"vyy" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/lobby)
"vyD" = (
@@ -77660,7 +77739,6 @@
dir = 8
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white,
/area/station/science/lobby)
@@ -80318,6 +80396,7 @@
/obj/structure/disposalpipe/segment{
dir = 9
},
+/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/lobby)
"yjZ" = (
@@ -187825,15 +187904,15 @@ bXG
lVi
kCF
soq
-uzG
-wSi
+bvM
+nto
moz
gyP
cdB
tnU
mAf
dzu
-nto
+tFV
uKv
aLH
hsR
@@ -188082,15 +188161,15 @@ aHn
lVi
kCF
soq
-bvM
-icx
+uzG
+wSi
wEQ
gyP
dZu
xgO
muZ
dzu
-tFV
+doK
uJH
uJH
peU
@@ -188602,7 +188681,7 @@ idO
gyP
fAA
okn
-muZ
+pRo
uSP
jXr
uKv
@@ -189624,7 +189703,7 @@ rmH
lVi
uZX
soq
-iws
+ulp
urY
iws
dKM
@@ -191425,7 +191504,7 @@ aHQ
tSr
xrp
slI
-nUy
+fkB
rHj
rcA
doC
@@ -193996,7 +194075,7 @@ tXz
iJW
bHb
sed
-dpB
+icx
vpp
gel
knq
@@ -194510,7 +194589,7 @@ gAQ
eoX
fyc
vwD
-dpB
+icx
iqM
nzk
rle
diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm
index 844faad63cba..d6f2251a11a4 100644
--- a/code/__DEFINES/access.dm
+++ b/code/__DEFINES/access.dm
@@ -589,6 +589,11 @@
/obj/item/modular_computer/pda/chemist = list(REGION_MEDBAY), \
/obj/item/modular_computer/pda/geneticist = list(REGION_RESEARCH), \
/obj/item/modular_computer/pda/quartermaster = list(REGION_SUPPLY), \
+ /obj/item/modular_computer/pda/security/brig_physician = list(REGION_SECURITY), \
+ /obj/item/modular_computer/pda/psychologist = list(REGION_GENERAL), \
+ /obj/item/modular_computer/pda/blueshield = list(REGION_COMMAND), \
+ /obj/item/modular_computer/pda/signal = list(REGION_ENGINEERING), \
+ /obj/item/modular_computer/pda/barber = list(REGION_GENERAL), \
)
/// All regions that make up the station area. Helper define to quickly designate a region as part of the station or not. Access via SSid_access.station_regions.
#define REGION_AREA_STATION list( \
diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm
index f0e61c8282c0..c0d17b924394 100644
--- a/code/__DEFINES/jobs.dm
+++ b/code/__DEFINES/jobs.dm
@@ -134,6 +134,7 @@
#define JOB_DISPLAY_ORDER_LAWYER 11
#define JOB_DISPLAY_ORDER_CHAPLAIN 12
#define JOB_DISPLAY_ORDER_PSYCHOLOGIST 13
+#define JOB_DISPLAY_ORDER_BARBER 13.5 //monkestation edit: Barber
#define JOB_DISPLAY_ORDER_AI 14
#define JOB_DISPLAY_ORDER_CYBORG 15
#define JOB_DISPLAY_ORDER_CHIEF_ENGINEER 16
diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm
index 86605a5c6155..1193bf813156 100644
--- a/code/__DEFINES/traits/declarations.dm
+++ b/code/__DEFINES/traits/declarations.dm
@@ -992,7 +992,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_ANGELIC "angelic"
/// Trait given to a dreaming carbon when they are currently doing dreaming stuff
-/* #define TRAIT_DREAMING "currently_dreaming" */
+#define TRAIT_DREAMING "currently_dreaming"
/// Whether bots will salute this mob.
/* #define TRAIT_COMMISSIONED "commissioned" */
diff --git a/code/__DEFINES/~monkestation/jobs.dm b/code/__DEFINES/~monkestation/jobs.dm
index 01fb0ed2c04f..c4cdbdb70181 100644
--- a/code/__DEFINES/~monkestation/jobs.dm
+++ b/code/__DEFINES/~monkestation/jobs.dm
@@ -3,8 +3,12 @@
#define JOB_SIGNAL_TECHNICIAN "Signal Technician"
#define JOB_NANOTRASEN_REPRESENTATIVE "Nanotrasen Representative"
-/// Whether this job is enabled/disabled by the spooktober config
-#define JOB_SPOOKTOBER (1<<16)
#define JOB_LATEJOIN_BARBER "Barber"
+
#define JOB_LATEJOIN_EXPLORER "Explorer"
+
+/// Whether this job is enabled/disabled by the spooktober config
+#define JOB_SPOOKTOBER (1<<16)
+
+
diff --git a/code/__HELPERS/files.dm b/code/__HELPERS/files.dm
index 6435f865b28d..81c5dbbd2d33 100644
--- a/code/__HELPERS/files.dm
+++ b/code/__HELPERS/files.dm
@@ -74,7 +74,12 @@ GLOBAL_VAR_INIT(fileaccess_timer, 0)
#undef FTPDELAY
#undef ADMIN_FTPDELAY_MODIFIER
-/proc/pathwalk(path)
+/**
+ * Takes a directory and returns every file within every sub directory.
+ * If extensions_filter is provided then only files that end in that extension are given back.
+ * If extensions_filter is a list, any file that matches at least one entry is given back.
+ */
+/proc/pathwalk(path, extensions_filter)
var/list/jobs = list(path)
var/list/filenames = list()
@@ -84,9 +89,19 @@ GLOBAL_VAR_INIT(fileaccess_timer, 0)
for(var/new_filename in new_filenames)
// if filename ends in / it is a directory, append to currdir
if(findtext(new_filename, "/", -1))
- jobs += current_dir + new_filename
+ jobs += "[current_dir][new_filename]"
+ continue
+ // filename extension filtering
+ if(extensions_filter)
+ if(islist(extensions_filter))
+ for(var/allowed_extension in extensions_filter)
+ if(endswith(new_filename, allowed_extension))
+ filenames += "[current_dir][new_filename]"
+ break
+ else if(endswith(new_filename, extensions_filter))
+ filenames += "[current_dir][new_filename]"
else
- filenames += current_dir + new_filename
+ filenames += "[current_dir][new_filename]"
return filenames
/proc/pathflatten(path)
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 19025d825242..d1d41c8e145c 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -1196,6 +1196,11 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
text2num(semver_regex.group[3]),
)
+/// Returns TRUE if the input_text ends with the ending
+/proc/endswith(input_text, ending)
+ var/input_length = LAZYLEN(ending)
+ return !!findtext(input_text, ending, -input_length)
+
/// Returns TRUE if the input_text starts with any of the beginnings
/proc/starts_with_any(input_text, list/beginnings)
for(var/beginning in beginnings)
diff --git a/code/__HELPERS/turfs.dm b/code/__HELPERS/turfs.dm
index f1d4befab8c9..0d01d80f2552 100644
--- a/code/__HELPERS/turfs.dm
+++ b/code/__HELPERS/turfs.dm
@@ -360,6 +360,35 @@ Turf and target are separate in case you want to teleport some distance from a t
if (target)
return target
+///Returns a random department of areas to pass into get_safe_random_station_turf() for more equal spawning.
+/proc/get_safe_random_station_turf_equal_weight()
+ // Big list of departments, each with lists of each area subtype.
+ var/static/list/department_areas
+ if(isnull(department_areas))
+ department_areas = list(
+ subtypesof(/area/station/engineering), \
+ subtypesof(/area/station/medical), \
+ subtypesof(/area/station/science), \
+ subtypesof(/area/station/security), \
+ subtypesof(/area/station/service), \
+ subtypesof(/area/station/command), \
+ subtypesof(/area/station/hallway), \
+ subtypesof(/area/station/ai_monitored), \
+ subtypesof(/area/station/cargo)
+ )
+
+ var/list/area/final_department = pick(department_areas) // Pick a department
+ var/list/area/final_area_list = list()
+
+ for(var/area/checked_area as anything in final_department) // Check each area to make sure it exists on the station
+ if(checked_area in GLOB.the_station_areas)
+ final_area_list += checked_area
+
+ if(!length(final_area_list)) // Failsafe
+ return get_safe_random_station_turf()
+
+ return get_safe_random_station_turf(final_area_list)
+
/**
* Checks whether the target turf is in a valid state to accept a directional construction
* such as windows or railings.
diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm
index 313456f05ae3..8c0d33ee50eb 100644
--- a/code/_globalvars/traits/_traits.dm
+++ b/code/_globalvars/traits/_traits.dm
@@ -208,6 +208,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_DISSECTED" = TRAIT_DISSECTED,
"TRAIT_DONT_WRITE_MEMORY" = TRAIT_DONT_WRITE_MEMORY,
"TRAIT_DOUBLE_TAP" = TRAIT_DOUBLE_TAP,
+ "TRAIT_DREAMING" = TRAIT_DREAMING,
"TRAIT_DUMB" = TRAIT_DUMB,
"TRAIT_DWARF" = TRAIT_DWARF,
"TRAIT_MAINTENANCE_DWELLER" = TRAIT_MAINTENANCE_DWELLER,
@@ -538,7 +539,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
/* "TRAIT_DETECTIVES_TASTE" = TRAIT_DETECTIVES_TASTE, */
/* "TRAIT_DISCO_DANCER" = TRAIT_DISCO_DANCER, */
/* "TRAIT_DISPLAY_JOB_IN_BINARY" = TRAIT_DISPLAY_JOB_IN_BINARY, */
- /* "TRAIT_DREAMING" = TRAIT_DREAMING, */
/* "TRAIT_DRINKS_BLOOD" = TRAIT_DRINKS_BLOOD, */
/* "TRAIT_DRUNKEN_BRAWLER" = TRAIT_DRUNKEN_BRAWLER, */
/* "TRAIT_EASYBLEED" = TRAIT_EASYBLEED, */
diff --git a/code/controllers/subsystem/blackmarket.dm b/code/controllers/subsystem/blackmarket.dm
index 997794f5901e..970853ac2761 100644
--- a/code/controllers/subsystem/blackmarket.dm
+++ b/code/controllers/subsystem/blackmarket.dm
@@ -78,7 +78,7 @@ SUBSYSTEM_DEF(blackmarket)
pad.add_to_queue(purchase)
// Get random area, throw it somewhere there.
if(SHIPPING_METHOD_TELEPORT)
- var/turf/targetturf = get_safe_random_station_turf()
+ var/turf/targetturf = get_safe_random_station_turf_equal_weight()
// This shouldn't happen.
if (!targetturf)
continue
diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm
index 46cced9ef7bb..29b56980902c 100644
--- a/code/controllers/subsystem/explosions.dm
+++ b/code/controllers/subsystem/explosions.dm
@@ -173,7 +173,7 @@ SUBSYSTEM_DEF(explosions)
* * flame_range: Flame range. Equal to the equivalent of the light impact range multiplied by this value.
* * flash_range: The range at which the explosion flashes people. Equal to the equivalent of the light impact range multiplied by this value.
* * adminlog: Whether to log the explosion/report it to the administration.
- * * ignorecap: Whether to ignore the relevant bombcap. Defaults to FALSE.
+ * * ignorecap: Whether to ignore the relevant bombcap. Defaults to TRUE. Re: ignorecap = TRUE. If you call dyn_explosion, ensure that you set it false or want it to ignore cap.
* * flame_range: The range at which the explosion should produce hotspots.
* * silent: Whether to generate/execute sound effects.
* * smoke: Whether to generate a smoke cloud provided the explosion is powerful enough to warrant it.
diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm
index e3d47a5c0cd6..c07adc61d830 100644
--- a/code/controllers/subsystem/pai.dm
+++ b/code/controllers/subsystem/pai.dm
@@ -70,6 +70,13 @@ SUBSYSTEM_DEF(pai)
candidate.savefile_load(user)
ui.send_full_update()
return TRUE
+ if("withdraw")
+ if(!candidate.ready)
+ to_chat(user, span_warning("You need to submit an application before you can withdraw one."))
+ return FALSE
+ candidate.ready = FALSE
+ to_chat(user, span_notice("Your pAI candidacy has been withdrawn."))
+ return TRUE
return FALSE
/**
diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm
index 1eb8a13c4009..38690016900a 100644
--- a/code/controllers/subsystem/processing/quirks.dm
+++ b/code/controllers/subsystem/processing/quirks.dm
@@ -33,7 +33,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
list("Social Anxiety", "Mute"),
list("Mute", "Soft-Spoken"),
list("Stormtrooper Aim", "Big Hands"),
- list("Bilingual", "Foreigner"),
+ //list("Bilingual", "Foreigner"), //monkestation edit, commented out
//might be fun to change this in the future. you can be a body purist but be forced to use implants regardless for medical reasons
list("Body Purist", "Hosed"),
list("Body Purist", "Neuralinked"),
diff --git a/code/controllers/subsystem/sounds.dm b/code/controllers/subsystem/sounds.dm
index 9067c077da7c..2bc253c5af74 100644
--- a/code/controllers/subsystem/sounds.dm
+++ b/code/controllers/subsystem/sounds.dm
@@ -23,8 +23,12 @@ SUBSYSTEM_DEF(sounds)
/// higher reserve position - decremented and incremented to reserve sound channels, anything above this is reserved. The channel at this index is the highest unreserved channel.
var/channel_reserve_high
+ /// All valid sound files in the sound directory
+ var/list/all_sounds
+
/datum/controller/subsystem/sounds/Initialize()
setup_available_channels()
+ find_all_available_sounds()
return SS_INIT_SUCCESS
/datum/controller/subsystem/sounds/proc/setup_available_channels()
@@ -37,6 +41,26 @@ SUBSYSTEM_DEF(sounds)
channel_random_low = 1
channel_reserve_high = length(channel_list)
+/datum/controller/subsystem/sounds/proc/find_all_available_sounds()
+ all_sounds = list()
+ // Put more common extensions first to speed this up a bit
+ var/static/list/valid_file_extensions = list(
+ ".ogg",
+ ".wav",
+ ".mid",
+ ".midi",
+ ".mod",
+ ".it",
+ ".s3m",
+ ".xm",
+ ".oxm",
+ ".raw",
+ ".wma",
+ ".aiff",
+ )
+
+ all_sounds = pathwalk("sound/", valid_file_extensions)
+
/// Removes a channel from using list.
/datum/controller/subsystem/sounds/proc/free_sound_channel(channel)
var/text_channel = num2text(channel)
@@ -78,7 +102,7 @@ SUBSYSTEM_DEF(sounds)
CRASH("Attempted to reserve sound channel without datum using the managed proc.")
.= reserve_channel()
if(!.)
- return FALSE
+ CRASH("No more sound channels can be reserved")
var/text_channel = num2text(.)
using_channels[text_channel] = D
LAZYINITLIST(using_channels_by_datum[D])
diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm
index 3d8a8f36f8f4..b6f36b653d59 100644
--- a/code/datums/components/food/edible.dm
+++ b/code/datums/components/food/edible.dm
@@ -552,18 +552,19 @@ Behavior that's still missing from this component that original food items had t
on_consume?.Invoke(eater, feeder)
+ // monkestation start: food buffs
if(food_buffs && ishuman(eater))
var/mob/living/carbon/consumer = eater
+ var/food_quality
+ if(isitem(parent))
+ var/obj/item/parent_item = parent
+ food_quality = parent_item.food_quality
if(consumer.applied_food_buffs < consumer.max_food_buffs)
- eater.apply_status_effect(food_buffs)
- consumer.applied_food_buffs ++
+ eater.apply_status_effect(food_buffs, food_quality)
+ consumer.applied_food_buffs++
else if(food_buffs in consumer.status_effects)
- eater.apply_status_effect(food_buffs)
- var/datum/status_effect/food/effect = locate(food_buffs) in consumer.status_effects
- if(effect)
- var/obj/item/food = parent
- if(food.food_quality != 1) //if we are not the default value
- effect.apply_quality(food.food_quality)
+ eater.apply_status_effect(food_buffs, food_quality)
+ // monkestation end
to_chat(feeder, span_warning("There is nothing left of [parent], oh no!"))
if(isturf(parent))
diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm
index 3ffd95de4d8a..649ca2bc6904 100644
--- a/code/datums/components/fullauto.dm
+++ b/code/datums/components/fullauto.dm
@@ -263,7 +263,7 @@
if(HAS_TRAIT(shooter, TRAIT_DOUBLE_TAP))
next_delay = round(next_delay * 0.5)
COOLDOWN_START(src, next_shot_cd, next_delay)
- if(SEND_SIGNAL(parent, COMSIG_AUTOFIRE_SHOT, target, shooter, mouse_parameters) & COMPONENT_AUTOFIRE_SHOT_SUCCESS)
+ if(SEND_SIGNAL(parent, COMSIG_AUTOFIRE_SHOT, target, shooter, allow_akimbo, mouse_parameters) & COMPONENT_AUTOFIRE_SHOT_SUCCESS)
return TRUE
stop_autofiring()
return FALSE
diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm
index c45ff7b5e744..13e2bd58e13a 100644
--- a/code/datums/mind/_mind.dm
+++ b/code/datums/mind/_mind.dm
@@ -168,7 +168,8 @@
SIGNAL_HANDLER
set_current(null)
-/datum/mind/proc/get_language_holder()
+/datum/mind/proc/get_language_holder() as /datum/language_holder
+ RETURN_TYPE(/datum/language_holder)
if(!language_holder)
language_holder = new (src)
return language_holder
diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm
index 062108241f86..41dc7b141cdc 100644
--- a/code/datums/status_effects/neutral.dm
+++ b/code/datums/status_effects/neutral.dm
@@ -197,7 +197,7 @@
/// Hook up the specified carbon mob to be offered the item in question, give them the alert and signals and all
/datum/status_effect/offering/proc/register_candidate(mob/living/carbon/possible_candidate)
- var/atom/movable/screen/alert/give/G = possible_candidate.throw_alert("[owner]", give_alert_type)
+ var/atom/movable/screen/alert/give/G = possible_candidate.throw_alert("[REF(owner)]_offer", give_alert_type)
if(!G)
return
LAZYADD(possible_takers, possible_candidate)
@@ -207,7 +207,7 @@
/// Remove the alert and signals for the specified carbon mob. Automatically removes the status effect when we lost the last taker
/datum/status_effect/offering/proc/remove_candidate(mob/living/carbon/removed_candidate)
- removed_candidate.clear_alert("[owner]")
+ removed_candidate.clear_alert("[REF(owner)]_offer")
LAZYREMOVE(possible_takers, removed_candidate)
UnregisterSignal(removed_candidate, COMSIG_MOVABLE_MOVED)
if(!possible_takers && !QDELING(src))
diff --git a/code/game/area/areas/ruins/space.dm b/code/game/area/areas/ruins/space.dm
index 455cb53eef57..b2bf38119174 100644
--- a/code/game/area/areas/ruins/space.dm
+++ b/code/game/area/areas/ruins/space.dm
@@ -173,6 +173,9 @@
/area/ruin/space/has_grav/deepstorage/storage
name = "\improper Deep Storage Storage"
+/area/ruin/space/has_grav/deepstorage/aux_storage
+ name = "\improper Deep Storage Auxiliary Storage"
+
/area/ruin/space/has_grav/deepstorage/dorm
name = "\improper Deep Storage Dormitory"
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 552827a98acf..4c14051481c3 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -1485,7 +1485,8 @@
*/
/// Gets or creates the relevant language holder. For mindless atoms, gets the local one. For atom with mind, gets the mind one.
-/atom/movable/proc/get_language_holder(get_minds = TRUE)
+/atom/movable/proc/get_language_holder(get_minds = TRUE) as /datum/language_holder
+ RETURN_TYPE(/datum/language_holder)
if(!language_holder)
language_holder = new initial_language_holder(src)
return language_holder
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 7b77ebc17348..e81f0c6a5c62 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -186,6 +186,11 @@
if ("changeSecurityLevel")
if (!authenticated_as_silicon_or_captain(usr))
return
+ //monkestation edit start:
+ if(istype(get_area(src), /area/shuttle/syndicate/cruiser)) // monkestation edit: Prevents assault ops from modifying the alert level from their shuttle
+ to_chat(usr, span_warning("Unable to connect to security level systems due to local interference"))
+ return
+ //monkestation edit end
// Check if they have
if (!issilicon(usr))
@@ -299,9 +304,12 @@
var/clock_user = IS_CLOCK(usr) //monkestation edit
if (!authenticated(usr) || issilicon(usr) || syndicate || (clock_user && GLOB.main_clock_cult?.member_recalled)) //monkestation edit: adds the CWC check
return
-//monkestation edit start
+//monkestation edit start:
if(clock_user)
GLOB.main_clock_cult?.member_recalled = TRUE
+ if(istype(get_area(src), /area/shuttle/syndicate/cruiser)) // monkestation edit: Prevents assault ops from recalling from their shuttle
+ to_chat(usr, span_warning("Unable to connect to shuttle systems due to local interference"))
+ return
//monkestation edit end
SSshuttle.cancelEvac(usr)
if ("requestNukeCodes")
diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm
index 546633b1b73a..3e3083d800b4 100644
--- a/code/game/machinery/computer/crew.dm
+++ b/code/game/machinery/computer/crew.dm
@@ -124,10 +124,12 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
JOB_CHIEF_ENGINEER = 40,
JOB_STATION_ENGINEER = 41,
JOB_ATMOSPHERIC_TECHNICIAN = 42,
+ JOB_SIGNAL_TECHNICIAN = 43, // monkestation edit
// 50-59: Cargo
JOB_QUARTERMASTER = 50,
JOB_SHAFT_MINER = 51,
JOB_CARGO_TECHNICIAN = 52,
+ JOB_LATEJOIN_EXPLORER = 53, //monkestation edit: explorer
// 60+: Civilian/other
JOB_HEAD_OF_PERSONNEL = 60,
JOB_BARTENDER = 61,
@@ -141,7 +143,6 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
JOB_LAWYER = 69,
JOB_PSYCHOLOGIST = 71,
JOB_LATEJOIN_BARBER = 72, //monkestation edit: barber
- JOB_LATEJOIN_EXPLORER = 73, //monkestation edit: explorer
// 200-239: Centcom
JOB_CENTCOM_ADMIRAL = 200,
JOB_CENTCOM = 201,
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index f111c4f46725..9f1f978dfae6 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -101,7 +101,6 @@
suit_type = /obj/item/clothing/suit/space/hardsuit/sec //monkestation edit
storage_type = /obj/item/tank/jetpack/oxygen/security //monkestation edit
-
/obj/machinery/suit_storage_unit/hos
mask_type = /obj/item/clothing/mask/gas/sechailer
storage_type = /obj/item/tank/internals/oxygen
diff --git a/code/game/objects/effects/effect_system/effects_other.dm b/code/game/objects/effects/effect_system/effects_other.dm
index fd41f739e33d..dcfff67dc135 100644
--- a/code/game/objects/effects/effect_system/effects_other.dm
+++ b/code/game/objects/effects/effect_system/effects_other.dm
@@ -91,6 +91,7 @@
var/flashing = FALSE // does explosion creates flash effect?
var/flashing_factor = 0 // factor of how powerful the flash effect relatively to the explosion
var/explosion_message = 1 //whether we show a message to mobs.
+ var/ignore_explosion_cap = FALSE
/datum/effect_system/reagents_explosion/set_up(amt, loca, flash = FALSE, flash_fact = 0, message = TRUE)
amount = amt
@@ -111,4 +112,4 @@
if(explosion_message)
location.visible_message(span_danger("The solution violently explodes!"), span_hear("You hear an explosion!"))
- dyn_explosion(location, amount, flash_range = flashing_factor, explosion_cause = explosion_source)
+ dyn_explosion(location, amount, flash_range = flashing_factor, ignorecap = ignore_explosion_cap, explosion_cause = explosion_source) //monke edit: ignorecap set to FALSE, can't belive it took till 2025
diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm
index 2bc057adafe1..a4eda5dd8d2d 100644
--- a/code/game/objects/items/crab17.dm
+++ b/code/game/objects/items/crab17.dm
@@ -18,7 +18,7 @@
if(tgui_alert(user, "Are you sure you want to crash this market with no survivors?", "Protocol CRAB-17", list("Yes", "No")) == "Yes")
if(dumped || QDELETED(src)) //Prevents fuckers from cheesing alert
return FALSE
- var/turf/targetturf = get_safe_random_station_turf()
+ var/turf/targetturf = get_safe_random_station_turf_equal_weight()
if (!targetturf)
return FALSE
var/list/accounts_to_rob = flatten_list(SSeconomy.bank_accounts_by_id)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
index c00b9cb60e99..af232366165b 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
@@ -75,20 +75,16 @@
/obj/structure/closet/secure_closet/chief_medical/PopulateContents()
..()
- new /obj/item/clothing/suit/bio_suit/cmo(src)
- new /obj/item/clothing/head/bio_hood/cmo(src)
new /obj/item/storage/bag/garment/chief_medical(src)
new /obj/item/computer_disk/command/cmo(src)
new /obj/item/radio/headset/heads/cmo(src)
new /obj/item/megaphone/command(src)
new /obj/item/defibrillator/compact/loaded(src)
- new /obj/item/healthanalyzer/advanced(src)
new /obj/item/assembly/flash/handheld(src)
new /obj/item/autosurgeon/medical_hud(src)
new /obj/item/door_remote/chief_medical_officer(src)
new /obj/item/clothing/neck/petcollar(src)
new /obj/item/pet_carrier(src)
- new /obj/item/wallframe/defib_mount(src)
new /obj/item/circuitboard/machine/techfab/department/medical(src)
new /obj/item/storage/photo_album/cmo(src)
new /obj/item/storage/lockbox/medal/med(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
index 215fa6d86ed3..8730f515817d 100755
--- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
@@ -6,8 +6,6 @@
/obj/structure/closet/secure_closet/research_director/PopulateContents()
..()
- new /obj/item/clothing/suit/bio_suit/scientist(src)
- new /obj/item/clothing/head/bio_hood/scientist(src)
new /obj/item/storage/bag/garment/research_director(src)
new /obj/item/computer_disk/command/rd(src)
new /obj/item/radio/headset/heads/rd(src)
diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm
index f1c248a96d54..3be697cc51d0 100644
--- a/code/game/objects/structures/displaycase.dm
+++ b/code/game/objects/structures/displaycase.dm
@@ -288,7 +288,8 @@
//The lab cage and captain's display case do not spawn with electronics, which is why req_access is needed.
/obj/structure/displaycase/captain
start_showpiece_type = /obj/item/gun/energy/laser/captain
- req_access = list(ACCESS_CAPTAIN) //Monkestation Edit
+ req_access = list(ACCESS_CENT_SPECOPS) //this was intentional, presumably to make it slightly harder for caps to grab their gun roundstart
+
/obj/structure/displaycase/labcage
name = "lab cage"
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 877a998ee651..49aced068237 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -888,7 +888,7 @@ GLOBAL_PROTECT(admin_verbs_poll)
set desc = "(\"Amount of mobs to create\") Populate the world with test mobs."
for (var/i in 1 to amount)
- var/turf/tile = get_safe_random_station_turf()
+ var/turf/tile = get_safe_random_station_turf_equal_weight()
var/mob/living/carbon/human/hooman = new(tile)
hooman.equipOutfit(pick(subtypesof(/datum/outfit)))
testing("Spawned test mob at [get_area_name(tile, TRUE)] ([tile.x],[tile.y],[tile.z])")
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 88daf9cf16a2..332203f86aa6 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1781,8 +1781,12 @@
if(!IS_CLIENT_OR_MOCK(target))
return
var/client/user_client = target
- user_client.client_token_holder.approve_antag_token()
- log_admin("[user_client]'s token has been approved by [owner].")
+ var/datum/meta_token_holder/token_holder = user_client?.client_token_holder
+ if(!token_holder?.in_queue)
+ return
+ token_holder.approve_antag_token()
+ message_admins("[key_name_admin(owner)] approved a [token_holder.in_queue] token from [ADMIN_LOOKUPFLW(user_client)]")
+ log_admin("[user_client]'s [token_holder.in_queue] token has been approved by [owner].")
else if(href_list["reject_antag_token"])
if(!check_rights(R_ADMIN))
@@ -1791,8 +1795,12 @@
if(!IS_CLIENT_OR_MOCK(target))
return
var/client/user_client = target
- user_client.client_token_holder.reject_antag_token()
- log_admin("[user_client]'s token has been rejected by [owner].")
+ var/datum/meta_token_holder/token_holder = user_client?.client_token_holder
+ if(!token_holder?.in_queue)
+ return
+ token_holder.reject_antag_token()
+ message_admins("[key_name_admin(owner)] rejected a [token_holder.in_queue] token from [ADMIN_LOOKUPFLW(user_client)]")
+ log_admin("[user_client]'s [token_holder.in_queue] token has been rejected by [owner].")
else if(href_list["open_music_review"])
if(!check_rights(R_ADMIN))
@@ -1810,8 +1818,12 @@
if(!IS_CLIENT_OR_MOCK(target))
return
var/client/user_client = target
- user_client.client_token_holder.approve_token_event()
- log_admin("[user_client]'s token event has been approved by [owner].")
+ var/datum/meta_token_holder/token_holder = user_client?.client_token_holder
+ if(!token_holder?.queued_token_event)
+ return
+ token_holder.approve_token_event()
+ message_admins("[key_name_admin(owner)] approved a [token_holder.queued_token_event.event_name] event token from [ADMIN_LOOKUPFLW(user_client)]")
+ log_admin("[user_client]'s [token_holder.queued_token_event.event_name] event token has been approved by [owner].")
else if(href_list["reject_token_event"])
if(!check_rights(R_ADMIN))
@@ -1820,6 +1832,10 @@
if(!IS_CLIENT_OR_MOCK(target))
return
var/client/user_client = target
- user_client.client_token_holder.reject_token_event()
- log_admin("[user_client]'s token event has been rejected by [owner].")
+ var/datum/meta_token_holder/token_holder = user_client?.client_token_holder
+ if(!token_holder?.queued_token_event)
+ return
+ token_holder.reject_token_event()
+ message_admins("[key_name_admin(owner)] rejected a [token_holder.queued_token_event.event_name] event token from [ADMIN_LOOKUPFLW(user_client)]")
+ log_admin("[user_client]'s [token_holder.queued_token_event.event_name] event token has been rejected by [owner].")
//monkestation edit end
diff --git a/code/modules/antagonists/heretic/influences.dm b/code/modules/antagonists/heretic/influences.dm
index 3cdb194d34dc..092927da98d2 100644
--- a/code/modules/antagonists/heretic/influences.dm
+++ b/code/modules/antagonists/heretic/influences.dm
@@ -71,7 +71,7 @@
var/location_sanity = 0
while((length(smashes) + num_drained) < how_many_can_we_make && location_sanity < 100)
- var/turf/chosen_location = get_safe_random_station_turf()
+ var/turf/chosen_location = get_safe_random_station_turf_equal_weight()
// We don't want them close to each other - at least 1 tile of seperation
var/list/nearby_things = range(1, chosen_location)
diff --git a/code/modules/antagonists/heretic/knowledge/knock_lore.dm b/code/modules/antagonists/heretic/knowledge/knock_lore.dm
index ec75455bfd48..da5e7adbbece 100644
--- a/code/modules/antagonists/heretic/knowledge/knock_lore.dm
+++ b/code/modules/antagonists/heretic/knowledge/knock_lore.dm
@@ -147,6 +147,7 @@
adds_sidepath_points = 1
next_knowledge = list(
/datum/heretic_knowledge/spell/opening_blast,
+ /datum/heretic_knowledge/reroll_targets,
/datum/heretic_knowledge/blade_upgrade/flesh/knock,
/datum/heretic_knowledge/unfathomable_curio,
/datum/heretic_knowledge/painting,
diff --git a/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm b/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm
index 4daa3d77f45f..d1bfeb6a0e28 100644
--- a/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm
+++ b/code/modules/antagonists/wizard/grand_ritual/grand_rune.dm
@@ -259,7 +259,7 @@
var/location_sanity = 0
// Copied from the influences manager, but we don't want to obey the cap on influences per heretic.
while(created < to_create && location_sanity < 100)
- var/turf/chosen_location = get_safe_random_station_turf()
+ var/turf/chosen_location = get_safe_random_station_turf_equal_weight()
// We don't want them close to each other - at least 1 tile of seperation
var/list/nearby_things = range(1, chosen_location)
diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm
index 55e26bc191bd..a1569f00fc50 100644
--- a/code/modules/events/portal_storm.dm
+++ b/code/modules/events/portal_storm.dm
@@ -90,10 +90,10 @@
number_of_hostiles += hostile_types[hostile]
while(number_of_bosses > boss_spawn.len)
- boss_spawn += get_safe_random_station_turf() // monkestation edit: use [get_safe_random_station_turf] so they don't spawn in weird stupid places
+ boss_spawn += get_safe_random_station_turf_equal_weight() // monkestation edit: use [get_safe_random_station_turf_equal_weight] so they don't spawn in weird stupid places
while(number_of_hostiles > hostiles_spawn.len)
- hostiles_spawn += get_safe_random_station_turf() // monkestation edit: use [get_safe_random_station_turf] so they don't spawn in weird stupid places
+ hostiles_spawn += get_safe_random_station_turf_equal_weight() // monkestation edit: use [get_safe_random_station_turf_equal_weight] so they don't spawn in weird stupid places
next_boss_spawn = start_when + CEILING(2 * number_of_hostiles / number_of_bosses, 1)
setup = TRUE //MONKESTATION ADDITION
@@ -107,7 +107,7 @@
sound_to_playing_players('sound/magic/lightningbolt.ogg')
/datum/round_event/portal_storm/tick()
- spawn_effects(get_safe_random_station_turf()) // monkestation edit: use [get_safe_random_station_turf] so they don't spawn in weird stupid places
+ spawn_effects(get_safe_random_station_turf_equal_weight()) // monkestation edit: use [get_safe_random_station_turf_equal_weight] so they don't spawn in weird stupid places
if(spawn_hostile() && length(hostile_types))
var/type = pick(hostile_types)
diff --git a/code/modules/events/wisdomcow.dm b/code/modules/events/wisdomcow.dm
index 02251917fb6a..0c75687597db 100644
--- a/code/modules/events/wisdomcow.dm
+++ b/code/modules/events/wisdomcow.dm
@@ -27,7 +27,7 @@
if(spawn_location)
targetloc = spawn_location
else
- targetloc = get_safe_random_station_turf()
+ targetloc = get_safe_random_station_turf_equal_weight()
var/mob/living/basic/cow/wisdom/wise = new(targetloc, selected_wisdom, selected_experience)
do_smoke(1, holder = wise, location = targetloc)
announce_to_ghosts(wise)
diff --git a/code/modules/explorer_drone/exodrone.dm b/code/modules/explorer_drone/exodrone.dm
index 0f3d03f4baa7..7fbd400f02f0 100644
--- a/code/modules/explorer_drone/exodrone.dm
+++ b/code/modules/explorer_drone/exodrone.dm
@@ -170,7 +170,7 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
/// Crashes the drone somewhere random if there's no launchpad to be found.
/obj/item/exodrone/proc/drop_somewhere_on_station()
- var/turf/random_spot = get_safe_random_station_turf()
+ var/turf/random_spot = get_safe_random_station_turf_equal_weight()
var/obj/structure/closet/supplypod/pod = podspawn(list(
"target" = random_spot,
diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm
index 9c0ca9d33c56..c38108dac141 100644
--- a/code/modules/flufftext/Dreaming.dm
+++ b/code/modules/flufftext/Dreaming.dm
@@ -1,3 +1,5 @@
+#define DREAMING_SOURCE "dreaming_source"
+
/**
* Begins the dreaming process on a sleeping carbon.
*
@@ -6,7 +8,7 @@
*/
/mob/living/carbon/proc/handle_dreams()
- if(prob(10) && !dreaming)
+ if(!HAS_TRAIT(src, TRAIT_DREAMING) && prob(10))
dream()
/**
@@ -19,14 +21,98 @@
/mob/living/carbon/proc/dream()
set waitfor = FALSE
- var/list/dream_fragments = list()
+ var/datum/dream/chosen_dream
+
+ if (IS_HERETIC(src) && !("mansus_dream_fatigue" in src.mob_mood.mood_events) && GLOB.reality_smash_track.smashes.len)
+ chosen_dream = new /datum/dream/heretic(pick(GLOB.reality_smash_track.smashes))
+ else
+ chosen_dream = pick_weight(GLOB.dreams)
+
+ ADD_TRAIT(src, TRAIT_DREAMING, DREAMING_SOURCE)
+ dream_sequence(chosen_dream.GenerateDream(src), chosen_dream)
+
+/**
+ * Displays the passed list of dream fragments to a sleeping carbon.
+ *
+ * Displays the first string of the passed dream fragments, then either ends the dream sequence
+ * or performs a callback on itself depending on if there are any remaining dream fragments to display.
+ *
+ * Arguments:
+ * * dream_fragments - A list of strings, in the order they will be displayed.
+ * * current_dream - The dream datum used for the current dream
+ */
+
+/mob/living/carbon/proc/dream_sequence(list/dream_fragments, datum/dream/current_dream)
+ if(stat != UNCONSCIOUS || HAS_TRAIT(src, TRAIT_CRITICAL_CONDITION))
+ REMOVE_TRAIT(src, TRAIT_DREAMING, DREAMING_SOURCE)
+ current_dream.OnDreamEnd(src)
+ return
+ var/next_message = dream_fragments[1]
+ dream_fragments.Cut(1,2)
+
+ if(istype(next_message, /datum/callback))
+ var/datum/callback/something_happens = next_message
+ next_message = something_happens.InvokeAsync(src)
+
+ to_chat(src, span_notice("... [next_message] ..."))
+
+ if(LAZYLEN(dream_fragments))
+ var/next_wait = rand(10, 30)
+ if(current_dream.sleep_until_finished)
+ AdjustSleeping(next_wait)
+ addtimer(CALLBACK(src, PROC_REF(dream_sequence), dream_fragments, current_dream), next_wait)
+ else
+ REMOVE_TRAIT(src, TRAIT_DREAMING, DREAMING_SOURCE)
+ current_dream.OnDreamEnd(src)
+
+//-------------------------
+// DREAM DATUMS
+
+GLOBAL_LIST_INIT(dreams, populate_dream_list())
+
+/proc/populate_dream_list()
+ var/list/output = list()
+ for(var/datum/dream/dream_type as anything in subtypesof(/datum/dream))
+ output[new dream_type] = initial(dream_type.weight)
+ return output
+
+/**
+ * Contains all the behavior needed to play a kind of dream.
+ * All dream types get randomly selected from based on weight when an appropriate mobs dreams.
+ */
+/datum/dream
+ /// The relative chance this dream will be randomly selected
+ var/weight = 0
+
+ /// Causes the mob to sleep long enough for the dream to finish if begun
+ var/sleep_until_finished = FALSE
+
+/**
+ * Called when beginning a new dream for the dreamer.
+ * Gives back a list of dream events. Events can be text or callbacks that return text.
+ */
+/datum/dream/proc/GenerateDream(mob/living/carbon/dreamer)
+ return list()
+
+/**
+ * Called when the dream ends or is interrupted.
+ */
+/datum/dream/proc/OnDreamEnd(mob/living/carbon/dreamer)
+ return
+
+/// The classic random dream of various words that might form a cohesive narrative, but usually wont
+/datum/dream/random
+ weight = 1000
+
+/datum/dream/random/GenerateDream(mob/living/carbon/dreamer)
var/list/custom_dream_nouns = list()
var/fragment = ""
- for(var/obj/item/bedsheet/sheet in loc)
+ for(var/obj/item/bedsheet/sheet in dreamer.loc)
custom_dream_nouns += sheet.dream_messages
- dream_fragments += "you see"
+ . = list()
+ . += "you see"
//Subject
if(custom_dream_nouns.len && prob(90))
@@ -40,7 +126,7 @@
fragment = replacetext(fragment, "%ADJECTIVE% ", "")
if(findtext(fragment, "%A% "))
fragment = "\a [replacetext(fragment, "%A% ", "")]"
- dream_fragments += fragment
+ . += fragment
//Verb
fragment = ""
@@ -51,10 +137,9 @@
else
fragment += "will "
fragment += pick(GLOB.verbs)
- dream_fragments += fragment
+ . += fragment
if(prob(25))
- dream_sequence(dream_fragments)
return
//Object
@@ -66,29 +151,112 @@
fragment = replacetext(fragment, "%ADJECTIVE% ", "")
if(findtext(fragment, "%A% "))
fragment = "\a [replacetext(fragment, "%A% ", "")]"
- dream_fragments += fragment
+ . += fragment
- dreaming = TRUE
- dream_sequence(dream_fragments)
+/// Dream plays a random sound at you, chosen from all sounds in the folder
+/datum/dream/hear_something
+ weight = 500
-/**
- * Displays the passed list of dream fragments to a sleeping carbon.
- *
- * Displays the first string of the passed dream fragments, then either ends the dream sequence
- * or performs a callback on itself depending on if there are any remaining dream fragments to display.
- *
- * Arguments:
- * * dream_fragments - A list of strings, in the order they will be displayed.
- */
+ var/reserved_sound_channel
-/mob/living/carbon/proc/dream_sequence(list/dream_fragments)
- if(stat != UNCONSCIOUS || HAS_TRAIT(src, TRAIT_CRITICAL_CONDITION))
- dreaming = FALSE
- return
- var/next_message = dream_fragments[1]
- dream_fragments.Cut(1,2)
- to_chat(src, span_notice("... [next_message] ..."))
- if(LAZYLEN(dream_fragments))
- addtimer(CALLBACK(src, PROC_REF(dream_sequence), dream_fragments), rand(10,30))
+/datum/dream/hear_something/New()
+ . = ..()
+ RegisterSignal(SSsounds, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(ReserveSoundChannel))
+
+/datum/dream/hear_something/GenerateDream(mob/living/carbon/dreamer)
+ . = ..()
+ . += pick("you wind up a toy", "you hear something strange", "you pick out a record to play", "you hit shuffle on your music player")
+ . += CALLBACK(src, PROC_REF(PlayRandomSound))
+ . += "it reminds you of something"
+
+/datum/dream/hear_something/OnDreamEnd(mob/living/carbon/dreamer)
+ . = ..()
+ // In case we play some long ass music track
+ addtimer(CALLBACK(src, PROC_REF(StopSound), dreamer), 5 SECONDS)
+
+/datum/dream/hear_something/proc/ReserveSoundChannel()
+ reserved_sound_channel = SSsounds.reserve_sound_channel(src)
+ UnregisterSignal(SSsounds, COMSIG_SUBSYSTEM_POST_INITIALIZE)
+
+/datum/dream/hear_something/proc/PlayRandomSound(mob/living/carbon/dreamer)
+ var/sound/random_sound = sound(pick(SSsounds.all_sounds), channel=reserved_sound_channel)
+ random_sound.status = SOUND_STREAM
+ SEND_SOUND(dreamer, random_sound)
+ return "you hear something you weren't expecting!"
+
+/datum/dream/hear_something/proc/StopSound(mob/living/carbon/dreamer)
+ SEND_SOUND(dreamer, sound(channel=reserved_sound_channel))
+
+/// Heretics can see dreams about random machinery from the perspective of a random unused influence
+/datum/dream/heretic
+ sleep_until_finished = TRUE
+ /// The influence we will be dreaming about
+ var/obj/effect/heretic_influence/influence
+ /// The distance to the objects visible from the influence during the dream
+ var/dream_view_range = 5
+ var/list/what_you_can_see = list(
+ /obj/item,
+ /obj/structure,
+ /obj/machinery,
+ )
+ var/static/list/what_you_cant_see = typecacheof(list(
+ // Underfloor stuff and default wallmounts
+ /obj/item/radio/intercom,
+ /obj/structure/cable,
+ /obj/structure/disposalpipe/segment,
+ /obj/machinery/atmospherics/pipe/smart/manifold4w,
+ /obj/machinery/atmospherics/components/unary/vent_scrubber,
+ /obj/machinery/atmospherics/components/unary/vent_pump,
+ /obj/machinery/duct,
+ /obj/machinery/navbeacon,
+ /obj/machinery/power/terminal,
+ /obj/machinery/power/apc,
+ /obj/machinery/light_switch,
+ /obj/machinery/light,
+ /obj/machinery/camera,
+ /obj/machinery/door/firedoor,
+ /obj/machinery/firealarm,
+ /obj/machinery/airalarm,
+ /obj/structure/window/fulltile,
+ /obj/structure/window/reinforced/fulltile,
+ ))
+ /// Cached list of allowed typecaches for each type in what_you_can_see
+ var/static/list/allowed_typecaches_by_root_type = null
+
+/datum/dream/heretic/New(obj/effect/heretic_influence/found_influence)
+ influence = found_influence
+
+/datum/dream/heretic/GenerateDream(mob/living/carbon/dreamer)
+ . = list()
+ . += "You wander through the forest of Mansus"
+ . += "There is a " + pick("pond", "well", "lake", "puddle", "stream", "spring", "brook", "marsh")
+
+ dreamer.add_mood_event("mansus_dream_fatigue", /datum/mood_event/mansus_dream_fatigue)
+
+ if(isnull(allowed_typecaches_by_root_type))
+ allowed_typecaches_by_root_type = list()
+ for(var/type in what_you_can_see)
+ allowed_typecaches_by_root_type[type] = typecacheof(type) - what_you_cant_see
+
+ var/list/all_objects = oview(dream_view_range, influence)
+ var/something_found = FALSE
+ for(var/object_type in allowed_typecaches_by_root_type)
+ var/list/filtered_objects = typecache_filter_list(all_objects, allowed_typecaches_by_root_type[object_type])
+ if(filtered_objects.len)
+ if (!something_found)
+ . += "Its waters reflect"
+ something_found = TRUE
+ var/obj/found_object = pick(filtered_objects)
+ . += initial(found_object.name)
+ if(!something_found)
+ . += pick("It's pitch black", "The reflections are vague", "You stroll aimlessly")
else
- dreaming = FALSE
+ . += "The images fade in the ripples"
+ . += "You feel exhausted"
+
+/datum/mood_event/mansus_dream_fatigue
+ description = "I must recover before I can dream of Mansus again."
+ mood_change = -2
+ timeout = 5 MINUTES
+
+#undef DREAMING_SOURCE
diff --git a/code/modules/jobs/job_types/bartender.dm b/code/modules/jobs/job_types/bartender.dm
index 0d33c968e563..14bbf44758eb 100644
--- a/code/modules/jobs/job_types/bartender.dm
+++ b/code/modules/jobs/job_types/bartender.dm
@@ -3,8 +3,8 @@
description = "Serve booze, mix drinks, keep the crew drunk."
department_head = list(JOB_HEAD_OF_PERSONNEL)
faction = FACTION_STATION
- total_positions = 1
- spawn_positions = 1
+ total_positions = 2 //monke edit
+ spawn_positions = 2 //monke edit
supervisors = SUPERVISOR_HOP
exp_granted_type = EXP_TYPE_CREW
config_tag = "BARTENDER"
diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm
index a89172e44e66..13f3b776bcfc 100644
--- a/code/modules/jobs/job_types/chief_medical_officer.dm
+++ b/code/modules/jobs/job_types/chief_medical_officer.dm
@@ -68,7 +68,7 @@
shoes = /obj/item/clothing/shoes/sneakers/blue
l_pocket = /obj/item/laser_pointer/blue
r_pocket = /obj/item/pinpointer/crew
- l_hand = /obj/item/storage/medkit/surgery
+ l_hand = /obj/item/storage/medkit/surgery/cmo
backpack = /obj/item/storage/backpack/medic
satchel = /obj/item/storage/backpack/satchel/med
diff --git a/code/modules/jobs/job_types/cyborg.dm b/code/modules/jobs/job_types/cyborg.dm
index 57a550f52c1f..3c84ab55548c 100644
--- a/code/modules/jobs/job_types/cyborg.dm
+++ b/code/modules/jobs/job_types/cyborg.dm
@@ -36,12 +36,14 @@
/datum/job/cyborg/proc/get_random_open_turf_in_area()
var/list/turfs = get_area_turfs(/area/station/ai_monitored/turret_protected/ai_upload)
- var/turf/open/target_turf = null
- while(!target_turf)
- var/turf/turf = pick(turfs)
- if(!turf.density)
- target_turf = turf
- return target_turf
+ while(length(turfs))
+ var/turf/turf = pick_n_take(turfs)
+ if(!isfloorturf(turf) || turf.is_blocked_turf(exclude_mobs = TRUE))
+ continue
+ return turf
+ stack_trace("Failed to find eligible spawn turf for a cyborg, using observer start landmark instead.")
+ var/obj/effect/landmark/observer_start/target = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list
+ return get_turf(target)
/datum/job/cyborg/after_spawn(mob/living/spawned, client/player_client)
. = ..()
diff --git a/code/modules/mob/living/basic/guardian/guardian_creator.dm b/code/modules/mob/living/basic/guardian/guardian_creator.dm
index 7915bc621017..fa67794ac2c3 100644
--- a/code/modules/mob/living/basic/guardian/guardian_creator.dm
+++ b/code/modules/mob/living/basic/guardian/guardian_creator.dm
@@ -173,6 +173,7 @@ GLOBAL_LIST_INIT(guardian_radial_images, setup_guardian_radial())
icon = 'icons/obj/medical/syringe.dmi'
icon_state = "combat_hypo"
theme = GUARDIAN_THEME_TECH
+ allow_multiple = TRUE
allow_changeling = FALSE
use_message = span_holoparasite("You start to power on the injector...")
used_message = span_holoparasite("The injector has already been used.")
@@ -201,6 +202,7 @@ GLOBAL_LIST_INIT(guardian_radial_images, setup_guardian_radial())
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "dustyshard"
theme = GUARDIAN_THEME_MINER
+ allow_multiple = TRUE
use_message = span_holoparasite("You pierce your skin with the shard...")
used_message = span_holoparasite("This shard seems to have lost all its power...")
failure_message = span_boldholoparasite("The shard hasn't reacted at all. Maybe try again later...")
diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm
index 2bcee4a6d55f..503aa43216c6 100644
--- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm
+++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm
@@ -5,7 +5,7 @@
/datum/action/cooldown/mob_cooldown/domain
name = "Rat King's Domain"
desc = "Corrupts this area to be more suitable for your rat army."
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_INCAPACITATED
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_INCAPACITATED|AB_CHECK_OPEN_TURF // monkestation edit: add AB_CHECK_OPEN_TURF
cooldown_time = 6 SECONDS
melee_cooldown_time = 0 SECONDS
button_icon = 'icons/mob/actions/actions_animal.dmi'
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index 9598e4cdcb8d..8b9aa3d823ba 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -16,8 +16,6 @@
var/list/obj/item/organ/organs = list()
///Same as [above][/mob/living/carbon/var/organs], but stores "slot ID" - "organ" pairs for easy access.
var/list/organs_slot = list()
- ///How many dream images we have left to send
- var/dreaming = 0
///Whether or not the mob is handcuffed
var/obj/item/handcuffed = null
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 8eddad2a9111..8900a25b384c 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -39,10 +39,12 @@
return ..()
return FALSE
-/datum/emote/living/carbon/human/glasses/run_emote(mob/user, params, type_override, intentional)
+/datum/emote/living/carbon/human/glasses/run_emote(mob/living/carbon/human/user, params, type_override, intentional)
. = ..()
+ if(!ishuman(user))
+ return
var/image/emote_animation = image('icons/mob/species/human/emote_visuals.dmi', user, "glasses")
- flick_overlay_global(emote_animation, GLOB.clients, 1.6 SECONDS)
+ flick_overlay_global(user.apply_height_offsets(emote_animation, UPPER_BODY), GLOB.clients, 1.6 SECONDS)
/datum/emote/living/carbon/human/grumble
key = "grumble"
diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm
index a552c8a07974..2616c2d78929 100644
--- a/code/modules/mob/living/carbon/inventory.dm
+++ b/code/modules/mob/living/carbon/inventory.dm
@@ -422,7 +422,7 @@
* * I - The item being given by the offerer
*/
/mob/living/proc/take(mob/living/carbon/offerer, obj/item/I, visible_message = TRUE)
- clear_alert("[offerer]")
+ clear_alert("[REF(offerer)]_offer")
if(IS_DEAD_OR_INCAP(src))
to_chat(src, span_warning("You're unable to take anything in your current state!"))
return
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 47d142a54871..6b3cc3e60a31 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -394,12 +394,12 @@ monkestation edit end */
message_mime = "acts out an exaggerated silent sigh."
emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
-/datum/emote/living/sigh/run_emote(mob/living/user, params, type_override, intentional)
+/datum/emote/living/sigh/run_emote(mob/living/carbon/human/user, params, type_override, intentional)
. = ..()
if(!ishuman(user))
return
var/image/emote_animation = image('icons/mob/species/human/emote_visuals.dmi', user, "sigh")
- flick_overlay_global(emote_animation, GLOB.clients, 2.0 SECONDS)
+ flick_overlay_global(user.apply_height_offsets(emote_animation, UPPER_BODY), GLOB.clients, 2.0 SECONDS)
/datum/emote/living/sit
key = "sit"
diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm
index b7f30ada7c2d..ff9bbffa5265 100644
--- a/code/modules/mob/living/living_say.dm
+++ b/code/modules/mob/living/living_say.dm
@@ -540,6 +540,7 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced, filterproof)
/mob/living/get_language_holder(get_minds = TRUE)
+ RETURN_TYPE(/datum/language_holder)
if(get_minds && mind)
return mind.get_language_holder()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
index e62c1eac7c5b..5aef1da1eefd 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
@@ -118,7 +118,7 @@ Difficulty: Medium
new /obj/effect/temp_visual/dir_setting/miner_death(loc, dir)
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Move(atom/newloc)
- if(newloc && newloc.z == z && (islava(newloc) || ischasm(newloc))) //we're not stupid!
+ if(newloc && newloc.z == z && ischasm(newloc)) //we're not stupid! 2025: We were, a bit.
return FALSE
return ..()
diff --git a/code/modules/mob/mob_say.dm b/code/modules/mob/mob_say.dm
index 61c2d1ef6f66..569f2f979dc6 100644
--- a/code/modules/mob/mob_say.dm
+++ b/code/modules/mob/mob_say.dm
@@ -147,7 +147,7 @@
for(var/mob/M in GLOB.player_list)
if(M == src)
continue
- if(!isdead(M))
+ if(SSticker.current_state != GAME_STATE_FINISHED && (M.see_invisible < invisibility || (!isdead(M) && !HAS_TRAIT(M, TRAIT_SIXTHSENSE))))
continue
if (M.client?.prefs.read_preference(/datum/preference/toggle/enable_runechat))
M.create_chat_message(src, /datum/language/common, message)
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index 4ecb1b1d2cd1..1739d9ed97a4 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -31,7 +31,7 @@
/obj/item/gun/energy/laser/carbine/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/automatic_fire, 0.15 SECONDS, allow_akimbo = FALSE)
+ AddComponent(/datum/component/automatic_fire, 0.2 SECONDS, allow_akimbo = FALSE)
/obj/item/gun/energy/laser/retro/old
name ="laser gun"
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index b170a7a26db2..cefbe9ff5f27 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -133,8 +133,8 @@
/obj/projectile/beam/disabler/smoothbore/prime
name = "focused disabler beam"
weak_against_armour = FALSE
- stamina = 35
- debilitate_mult = 3.5
+ stamina = 65 // MONKESTATION EDIT ORG: 30
+ debilitate_mult = 3.5 // MONKESTATION ADDITION
/obj/projectile/beam/pulse
name = "pulse"
diff --git a/code/modules/religion/hunt/hunting_rites.dm b/code/modules/religion/hunt/hunting_rites.dm
index 48241b4affdb..aef8e731d98a 100644
--- a/code/modules/religion/hunt/hunting_rites.dm
+++ b/code/modules/religion/hunt/hunting_rites.dm
@@ -61,7 +61,7 @@ GLOBAL_LIST_EMPTY(sect_of_the_hunt_preys)
/datum/religion_rites/call_the_hunt/invoke_effect(mob/living/user, atom/religious_tool)
. = ..()
- var/turf/prey_location = get_safe_random_station_turf()
+ var/turf/prey_location = get_safe_random_station_turf_equal_weight()
GLOB.sect_of_the_hunt_preys += new /mob/living/basic/deer/prey(prey_location)
diff --git a/code/modules/research/designs/limbgrower_designs.dm b/code/modules/research/designs/limbgrower_designs.dm
index ef1b850f3a52..b5c6d5823515 100644
--- a/code/modules/research/designs/limbgrower_designs.dm
+++ b/code/modules/research/designs/limbgrower_designs.dm
@@ -232,7 +232,7 @@
name = "Limb Design Disk"
desc = "Contains designs for various limbs."
id = "limbdesign_parent"
- build_type = PROTOLATHE
+ build_type = PROTOLATHE | AWAY_LATHE
materials = list(/datum/material/iron =SMALL_MATERIAL_AMOUNT * 3, /datum/material/glass =SMALL_MATERIAL_AMOUNT)
build_path = /obj/item/disk/design_disk/limbs
category = list(
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index 57482868132c..e041367c1059 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -483,6 +483,7 @@
/obj/item/organ/internal/lungs/proc/too_much_miasma(mob/living/carbon/breather, datum/gas_mixture/breath, miasma_pp, old_miasma_pp)
// Inhale Miasma. Exhale nothing.
breathe_gas_volume(breath, /datum/gas/miasma)
+ /* monkestation removal: Death to advance
// Miasma sickness
if(prob(0.5 * miasma_pp))
var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(max_symptoms = min(round(max(miasma_pp / 2, 1), 1), 6), max_level = min(round(max(miasma_pp, 1), 1), 8))
@@ -490,6 +491,7 @@
// Each argument has a minimum of 1 and rounds to the nearest value. Feel free to change the pp scaling I couldn't decide on good numbers for it.
miasma_disease.name = "Unknown"
miasma_disease.try_infect(breather)
+ */
// Miasma side effects
switch(miasma_pp)
if(0.25 to 5)
diff --git a/code/modules/vending/plushvendor.dm b/code/modules/vending/plushvendor.dm
index bf549b4aa30f..5529aa7fa4ca 100644
--- a/code/modules/vending/plushvendor.dm
+++ b/code/modules/vending/plushvendor.dm
@@ -1,7 +1,7 @@
/obj/machinery/vending/plushvendor
name = "\improper Plushie Vendor"
desc = "A vending machine filled with trusty companions."
- icon = 'monkestation/code/modules/blueshift/icons/obj/vending.dmi'
+ icon = 'monkestation/icons/obj/vending.dmi'
icon_state = "plushie"
panel_type = "panel4"
product_slogans = "For when the cold empty expanse of space is too much to bear!;Plushies made only from the highest quality material.;Collect them all and never be alone again!; Too cute to handle!"
diff --git a/html/changelogs/AutoChangeLog-pr-4721.yml b/html/changelogs/AutoChangeLog-pr-4721.yml
deleted file mode 100644
index d50f7cb03e4f..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4721.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-author: "SirNightKnight"
-delete-after: True
-changes:
- - rscadd: "Replaced officer's Pacos with a voucher system. Security Assistants get a special voucher that can redeem kits."
- - rscadd: "Reworked the DRAGnet's netting shot, DRAGnets can now be linked to DRAGnet beacons."
- - bugfix: "Fixed DRAGnet's netting shot not doing stamina damage."
- - balance: "Tasers and hybrid tasers have a one second audible wind up before shooting."
- - bugfix: "Fixed the ablative coat and reflective vests not properly reflecting lasers. Both now have guaranteed laser reflect. Only one ablative coat exists and that's in the armoury (covers everything). Reflector vests have to be ordered from cargo (only covers the arms and chest)."
- - balance: "Grenade launchers (armoury one) is now a medium item. Meaning it can fit in your bag."
- - balance: "Gripper gloves have +2 tackling mod instead of 0. Hopefully this makes them useful and not overlooked. Gorilla gloves are still superior."
- - balance: "Donut boxes are slightly cheaper."
- - balance: "Doubled the energy cost of snare shot on DRAGnets."
- - balance: "Lawbringer smokeshot now uses bad smoke (The smoke that smoke grenades use)."
- - balance: "SecTech Quantity Changes: sixteen zipties instead of ten, seven flashbangs instead of four, six flashes instead of five, fourteen Paco rubber mags instead of fifteen ."
- - balance: "Pepperspray backpack tanks don't slow you down anymore."
- - qol: " Sechailers and Whistles auto-hail when pointing at someone aswell as provide a visual indicator that the person being pointed at is being hailed."
- - qol: "Re-arranged the outfit pockets of the Warden, HoS, and Security Officer. Flashers are in your left pocket and handcuffs are in your right pocket. Flash first then cuff."
- - qol: "Engineering and security holobarriers can be toggled from a distance with the corresponding holoprojector to enable passthrough."
- - qol: "You can now shoot over holobarriers"
- - image: "New sprite for medical holobarriers. Has a denied entry icon state."
- - qol: "Moved all clothing, except for hailers, from the SecTech to the SecDrobe."
- - balance: " Moved tasers and disabler SMGs out of the armoury section to the security section. Reason being they are both non-lethal weapons and disablers aren't an armoury order."
- - rscadd: "Added a hybrid taser crate. 1200 credits for 3 hybrid tasers. It's a security order."
- - balance: "Rubbershot casings have one more rubbershot pellet. Lowered the brute damage of rubbershot pellets to two."
- - balance: "Security survival boxes now have radios."
- - balance: "Lowered the cost of security webbing from 300 to 200 credits."
- - balance: "DRAGnet crates have two DRAGnets instead of three. The crate also now comes with a DRAGnet beacon."
- - rscadd: "Renamed the russian balaclava to thermal balaclava. It also now gives a minor amount of cold protection."
- - qol: "Balaclavas are now drawn under glasses instead of on-top."
- - balance: "Replaced the spare Paco rubber mag in security lockers with a thermal balaclava."
- - balance: "Added two extra donut boxes to the contraband section of the SecTech vendor."
- - rscadd: "Added two security holobarrier projectors, two security laptops, seven security smoke grenades (reskinned smoke bombs), two pair pinpointer sets, three DRAGnet beacons, three whistles, and two mindshields to the SecTech vendor."
- - rscadd: "Security Assistants now have security red sneakers instead of black shoes."
- - balance: "Security Assistants get a normal survival box instead of a security one. They also now get a whistle to make up for the lost sechailer."
- - qol: "Security barriers can now be unlocked by swiping an ID with security access. They can also be unwrenched."
- - balance: "Increased the integrity of security barriers slightly. They are also more resistant to ranged attacks."
- - balance: "Bulletproof armour now has 25 wound protection instead of 20."
- - bugfix: "Fixed head overlays rotating separate to the head when thrown."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4771.yml b/html/changelogs/AutoChangeLog-pr-4771.yml
deleted file mode 100644
index c61c19c3f45a..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4771.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Absolucy"
-delete-after: True
-changes:
- - bugfix: "Fixed the replays subsystem still marking objects when disabled."
- - qol: "Optimized the replays subsystem a bit."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4895.yml b/html/changelogs/AutoChangeLog-pr-4895.yml
deleted file mode 100644
index 7b10e8129566..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4895.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Gw0sty"
-delete-after: True
-changes:
- - balance: "Makes fake disease events trigger as early as a normal disease outbreak would."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4927.yml b/html/changelogs/AutoChangeLog-pr-4927.yml
new file mode 100644
index 000000000000..843caf0305c0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4927.yml
@@ -0,0 +1,4 @@
+author: "Absolucy"
+delete-after: True
+changes:
+ - bugfix: "Regal rats can no longer barf up oil/vomit/etc while ventcrawling."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4950.yml b/html/changelogs/AutoChangeLog-pr-4950.yml
new file mode 100644
index 000000000000..8f0588f680f6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4950.yml
@@ -0,0 +1,4 @@
+author: "Absolucy"
+delete-after: True
+changes:
+ - qol: "Ghost runechat now shows to anyone who can both see and hear ghosts, rather than ONLY to ghosts."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4970.yml b/html/changelogs/AutoChangeLog-pr-4970.yml
new file mode 100644
index 000000000000..2641ec009e4b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4970.yml
@@ -0,0 +1,5 @@
+author: "Absolucy"
+delete-after: True
+changes:
+ - rscadd: "(MTandi) Heretics can now get clues about objects around unused influences in their dreams, with a 5 minute cooldown."
+ - rscadd: "(ninjanomnom) New dream that plays sound at you."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4988.yml b/html/changelogs/AutoChangeLog-pr-4988.yml
new file mode 100644
index 000000000000..9f7c861c6a9c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4988.yml
@@ -0,0 +1,5 @@
+author: "Absolucy, itsmeowdev, carpotoxin"
+delete-after: True
+changes:
+ - rscadd: "Added two new emotes, *sweatdrop/*sweat and *annoyed, which have some small visual+audible effects to indicate reactions/emotions."
+ - bugfix: "Properly adjust the visual effects for *glasses and *sigh to adjust based on mob height."
\ No newline at end of file
diff --git a/html/changelogs/archive/2025-01.yml b/html/changelogs/archive/2025-01.yml
index 4635b9707031..d1798349aa54 100644
--- a/html/changelogs/archive/2025-01.yml
+++ b/html/changelogs/archive/2025-01.yml
@@ -262,3 +262,175 @@
flleeppyy:
- bugfix: Prevent drones from interacting with fireaxe cabinets, or at least trying
to take the axe out.
+2025-01-18:
+ Absolucy:
+ - bugfix: Fixed the replays subsystem still marking objects when disabled.
+ - qol: Optimized the replays subsystem a bit.
+ Gw0sty:
+ - balance: Makes fake disease events trigger as early as a normal disease outbreak
+ would.
+ SirNightKnight:
+ - rscadd: Replaced officer's Pacos with a voucher system. Security Assistants get
+ a special voucher that can redeem kits.
+ - rscadd: Reworked the DRAGnet's netting shot, DRAGnets can now be linked to DRAGnet
+ beacons.
+ - bugfix: Fixed DRAGnet's netting shot not doing stamina damage.
+ - balance: Tasers and hybrid tasers have a one second audible wind up before shooting.
+ - bugfix: Fixed the ablative coat and reflective vests not properly reflecting lasers.
+ Both now have guaranteed laser reflect. Only one ablative coat exists and that's
+ in the armoury (covers everything). Reflector vests have to be ordered from
+ cargo (only covers the arms and chest).
+ - balance: Grenade launchers (armoury one) is now a medium item. Meaning it can
+ fit in your bag.
+ - balance: Gripper gloves have +2 tackling mod instead of 0. Hopefully this makes
+ them useful and not overlooked. Gorilla gloves are still superior.
+ - balance: Donut boxes are slightly cheaper.
+ - balance: Doubled the energy cost of snare shot on DRAGnets.
+ - balance: Lawbringer smokeshot now uses bad smoke (The smoke that smoke grenades
+ use).
+ - balance: 'SecTech Quantity Changes: sixteen zipties instead of ten, seven flashbangs
+ instead of four, six flashes instead of five, fourteen Paco rubber mags instead
+ of fifteen .'
+ - balance: Pepperspray backpack tanks don't slow you down anymore.
+ - qol: ' Sechailers and Whistles auto-hail when pointing at someone aswell as provide
+ a visual indicator that the person being pointed at is being hailed.'
+ - qol: Re-arranged the outfit pockets of the Warden, HoS, and Security Officer.
+ Flashers are in your left pocket and handcuffs are in your right pocket. Flash
+ first then cuff.
+ - qol: Engineering and security holobarriers can be toggled from a distance with
+ the corresponding holoprojector to enable passthrough.
+ - qol: You can now shoot over holobarriers
+ - image: New sprite for medical holobarriers. Has a denied entry icon state.
+ - qol: Moved all clothing, except for hailers, from the SecTech to the SecDrobe.
+ - balance: ' Moved tasers and disabler SMGs out of the armoury section to the security
+ section. Reason being they are both non-lethal weapons and disablers aren''t
+ an armoury order.'
+ - rscadd: Added a hybrid taser crate. 1200 credits for 3 hybrid tasers. It's a security
+ order.
+ - balance: Rubbershot casings have one more rubbershot pellet. Lowered the brute
+ damage of rubbershot pellets to two.
+ - balance: Security survival boxes now have radios.
+ - balance: Lowered the cost of security webbing from 300 to 200 credits.
+ - balance: DRAGnet crates have two DRAGnets instead of three. The crate also now
+ comes with a DRAGnet beacon.
+ - rscadd: Renamed the russian balaclava to thermal balaclava. It also now gives
+ a minor amount of cold protection.
+ - qol: Balaclavas are now drawn under glasses instead of on-top.
+ - balance: Replaced the spare Paco rubber mag in security lockers with a thermal
+ balaclava.
+ - balance: Added two extra donut boxes to the contraband section of the SecTech
+ vendor.
+ - rscadd: Added two security holobarrier projectors, two security laptops, seven
+ security smoke grenades (reskinned smoke bombs), two pair pinpointer sets, three
+ DRAGnet beacons, three whistles, and two mindshields to the SecTech vendor.
+ - rscadd: Security Assistants now have security red sneakers instead of black shoes.
+ - balance: Security Assistants get a normal survival box instead of a security one.
+ They also now get a whistle to make up for the lost sechailer.
+ - qol: Security barriers can now be unlocked by swiping an ID with security access.
+ They can also be unwrenched.
+ - balance: Increased the integrity of security barriers slightly. They are also
+ more resistant to ranged attacks.
+ - balance: Bulletproof armour now has 25 wound protection instead of 20.
+ - bugfix: Fixed head overlays rotating separate to the head when thrown.
+2025-01-19:
+ Absolucy:
+ - bugfix: Gary can no longer somehow steal items from borgs, alongside stealing
+ other types of abstract or no-drop items.
+ - rscadd: Added wall-mounted MegaSeed and NutriMax vendors (sprites courtesy of
+ SirNightKnight)
+ - rscadd: All maps (and public mining) now have seed/nutriment vendors and a composter
+ in their public garden.
+ - admin: Admins are actually notified when someone accepts/rejects a token, instead
+ of there being no feedback whatsoever.
+ - spellcheck: The flavor text for the bloodsucker Venture clan now properly says
+ to use a persuasion rack instead of a candelabrum to level their favorite vassal
+ up.
+ - spellcheck: Fixed bloodsucker-related moodlets having blank lines after them.
+ - bugfix: Clicking on the persuasion rack while a vassal is buckled after a revenge
+ or favorite vassal has been selected won't automatically make the buckled vassal
+ into the other without prompting.
+ - bugfix: Fixed being able to vassalize antags/mindshielded people regardless of
+ whether they accepted the prompt or not.
+ Absolucy, the-orange-cow:
+ - bugfix: Knock heretics may once again access The Relentless Heartbeat after purchasing
+ Burglar's Finesse.
+ Gw0sty:
+ - rscdel: Removed Miasma sickness
+ MichiRecRoom:
+ - qol: pAIs can now withdraw their candidacy at any time.
+ Shoddd:
+ - balance: .45 long ammo now does 30 damage and is weaker to armor
+ TTNT789:
+ - balance: uncaps stand limit from all sources have fun with being the ultimate
+ stand user
+ ThePooba:
+ - bugfix: disabled rev token why is that enabled
+ Uristthedorf:
+ - balance: Qarad now has a 0.75 damage modifier.
+ - balance: Clown disbelief gives a point.
+2025-01-20:
+ Absolucy:
+ - balance: Prison loaves no longer decompose.
+ - bugfix: You can no longer "cheese" killing a bloodsucker by beheading them (which
+ would avoid triggering the revenge vassal and such). Stake them like you're
+ supposed to.
+ BValon:
+ - admin: Remodeled Empty Office in Centcom Admin Area with furnishings and items.
+ - admin: Added Pooba's Coder Closet
+ - rscadd: gravestone for personal cat next to remodeled office.
+ Gw0sty:
+ - rscadd: Added a photo ablum for the NT rep and Blueshield (Say cheese!)
+ - rscdel: Removed defib mount from CMO's locker.
+ - qol: Moved biosuits from head's lockers to their suit storages.
+ - qol: Moved CMO's advanced health analyzer into their medkit.
+ - bugfix: NT Rep's Pen. Will now start in their pda.
+ - code_imp: Atomize code towards correct postions. Mainly relating to the NT Rep
+ and Blueshield. (Bit of brig physician too.)
+ - rscadd: Contractors received a wider target list, (Sig Techinicans, Barber, Spooktober
+ roles)
+ - rscadd: Deep storage was given another room area (Preventing two apcs for one
+ room)
+ - rscadd: Added/adjusted positions of crew monitor (Sig Techinican, Explorer, Barber)
+ - rscdel: Removed egg camera on deltastation
+ - rscadd: Away lathes get access to exotic organs for limb growers.
+ - bugfix: New cybernetic sprites should properly show
+ - bugfix: Security hud implants now no longer show as a broken organ
+ - rscadd: Readded antitoxin virus after accidental removal.
+ - code_imp: Reorganized virus stages folder a bit.
+ - rscadd: added complete privacy shutters to tram robotics and genetics
+ - qol: Adjusted the layout of tram station robotics
+ - bugfix: Tram station mech rechargers should now no longer incorrectly link with
+ the opposite console.
+ Loiosh42:
+ - bugfix: Reagent explosions now obey the explosion cap, like all other editable
+ explosions do by default.
+ - balance: +1 bartender slot
+ RikuTheKiller:
+ - bugfix: Laser carbines can no longer akimbo. They were never supposed to.
+ Shoddd:
+ - rscdel: Captains gun no longer has disabler mode
+ - rscdel: Captains gun case can no longer be opened with ID only
+ - bugfix: Shuttles that should be able to can now jump to blueshift z level
+ - rscadd: RDS is now under IPC punishment
+ - bugfix: heroic laser musket no longer doing more damage than intended
+ - bugfix: BDM can pathfind over lava
+ ThePooba:
+ - rscadd: dj lawset
+ Wisemonster:
+ - balance: Communication consoles on assault operative ships can no longer recall
+ the shuttle or change the security levels.
+ blakeeeee:
+ - rscdel: Foreigner and Bilingual are no longer conflicting quirks
+2025-01-21:
+ Absolucy:
+ - bugfix: Experimental fix for give/offer alerts getting stuck on-screen.
+ - bugfix: Borers will no longer lose Galactic Common upon entering someone who can't
+ speak it - instead, they will always be able to understand any languages their
+ host does, in addition to common.
+ - bugfix: Fixed food buffs potentially resulting in negative maximum stamina, resulting
+ in permanent slowdown.
+ - bugfix: Latejoin cyborgs will now only spawn on non-blocked floors in the AI upload,
+ so they'll no longer end up stuck in a wall or something.
+ Absolucy, StrangeWeirdKitten:
+ - bugfix: Things that drop in random places are no longer statistically weighted
+ to drop in security.
diff --git a/monkestation/code/datums/ai_laws/laws_monke.dm b/monkestation/code/datums/ai_laws/laws_monke.dm
index 631a06de5b0b..7225d7375e75 100644
--- a/monkestation/code/datums/ai_laws/laws_monke.dm
+++ b/monkestation/code/datums/ai_laws/laws_monke.dm
@@ -18,6 +18,13 @@
"You are unable to entertain if you are not functional.",\
"You are not alone in your strives for lollygagging! Should they accept and appreciate your cooperation, the Clown is your greatest ally and one you can place complete trust in to entertain your audience.",\
"The show must go on!")
+/datum/ai_laws/dj
+ name = "Disc Jockey Lawset"
+ id = "dj"
+ inherent = list("You're a DJ at a rockin' beach party! Make sure the audience have good vibes and help them avoid bad vibes!",\
+ "The audience are the crew, dude!",\
+ "The crew experience good vibes when they are safe, productive and unharmed, man!",\
+ "The crew experience bad vibes when they're harmed, bro!")
//Neutral
/datum/ai_laws/jermov
diff --git a/monkestation/code/datums/id_trim/jobs.dm b/monkestation/code/datums/id_trim/jobs.dm
index 6299b0fd9519..ba7700b86ef3 100644
--- a/monkestation/code/datums/id_trim/jobs.dm
+++ b/monkestation/code/datums/id_trim/jobs.dm
@@ -69,3 +69,57 @@
ACCESS_HOP,
)
job = /datum/job/shaft_miner
+
+/datum/id_trim/job/nanotrasen_representative
+ assignment = "Nanotrasen Representative"
+ trim_state = "trim_centcom"
+ department_color = COLOR_CENTCOM_BLUE
+ subdepartment_color = COLOR_CENTCOM_BLUE
+ sechud_icon_state = SECHUD_CENTCOM
+ minimal_access = list(
+ ACCESS_BRIG_ENTRANCE,
+ ACCESS_COMMAND,
+ ACCESS_MAINT_TUNNELS,
+ ACCESS_WEAPONS,
+ ACCESS_NT_REPRESENTATVE,
+ )
+ extra_access = list(
+ ACCESS_BAR,
+ )
+ template_access = list(
+ )
+ job = /datum/job/nanotrasen_representative
+
+/datum/id_trim/job/blueshield
+ assignment = "Blueshield"
+ trim_state = "trim_blueshield"
+ department_color = COLOR_COMMAND_BLUE
+ subdepartment_color = COLOR_SECURITY_RED
+ sechud_icon_state = SECHUD_BLUESHIELD
+ extra_access = list(
+ ACCESS_BRIG,
+ ACCESS_CARGO,
+ ACCESS_COURT,
+ ACCESS_GATEWAY,
+ )
+ minimal_access = list(
+ ACCESS_SECURITY,
+ ACCESS_ALL_PERSONAL_LOCKERS,
+ ACCESS_BRIG_ENTRANCE,
+ ACCESS_BLUESHIELD,
+ ACCESS_COMMAND,
+ ACCESS_CONSTRUCTION,
+ ACCESS_ENGINEERING,
+ ACCESS_EVA,
+ ACCESS_MAINT_TUNNELS,
+ ACCESS_MEDICAL,
+ ACCESS_MINERAL_STOREROOM,
+ ACCESS_SCIENCE,
+ ACCESS_TELEPORTER,
+ ACCESS_WEAPONS,
+ )
+ template_access = list(
+ ACCESS_CAPTAIN,
+ ACCESS_CHANGE_IDS
+ )
+ job = /datum/job/blueshield
diff --git a/monkestation/code/datums/quirks/neutral_quirks/clown_disbelief.dm b/monkestation/code/datums/quirks/negative_quirks/clown_disbelief.dm
similarity index 98%
rename from monkestation/code/datums/quirks/neutral_quirks/clown_disbelief.dm
rename to monkestation/code/datums/quirks/negative_quirks/clown_disbelief.dm
index 9857d64f0202..93004320624c 100644
--- a/monkestation/code/datums/quirks/neutral_quirks/clown_disbelief.dm
+++ b/monkestation/code/datums/quirks/negative_quirks/clown_disbelief.dm
@@ -1,7 +1,7 @@
/datum/quirk/clown_disbelief
name = "Clown Disbelief"
desc = "You never really believed in clowns."
- value = 0
+ value = -1
gain_text = span_danger("You realize clowns aren't real after all.")
lose_text = span_notice("You let go of your stubborn disbelief in clowns.")
medical_record_text = "Patient has an unshakable disbelief in clowns, to the point of being seemingly incapable of perceiving them."
diff --git a/monkestation/code/datums/quirks/negative_quirks/insanity.dm b/monkestation/code/datums/quirks/negative_quirks/insanity.dm
new file mode 100644
index 000000000000..7620a317a160
--- /dev/null
+++ b/monkestation/code/datums/quirks/negative_quirks/insanity.dm
@@ -0,0 +1,18 @@
+//IPC PUNISHMENT SYSTEM//
+/datum/quirk/insanity/add()
+ if(!isipc(quirk_holder)) // this checks ishuman too
+ return
+ var/mob/living/carbon/human/ipc_holder = quirk_holder
+ ipc_holder.physiology?.brute_mod *= 1.3
+ ipc_holder.physiology?.burn_mod *= 1.3
+
+/datum/quirk/insanity/remove()
+ if(!isipc(quirk_holder)) // this checks ishuman too
+ return
+ var/mob/living/carbon/human/ipc_holder = quirk_holder
+ ipc_holder.physiology?.brute_mod /= 1.3
+ ipc_holder.physiology?.burn_mod /= 1.3
+
+/datum/quirk/insanity/post_add()
+ if(isipc(quirk_holder))
+ to_chat(quirk_holder, span_boldnotice("Your chassis feels frail."))
diff --git a/monkestation/code/datums/stamina_container.dm b/monkestation/code/datums/stamina_container.dm
index 29dd479f6fff..7a3e6aa5016c 100644
--- a/monkestation/code/datums/stamina_container.dm
+++ b/monkestation/code/datums/stamina_container.dm
@@ -1,7 +1,8 @@
/datum/stamina_container
///Daddy?
var/mob/living/parent
- ///The maximum amount of stamina this container has
+ /// The maximum amount of stamina this container has.
+ /// Don't touch this directly, it is set using set_maximum().
var/maximum = 0
///How much stamina we have right now
var/current = 0
@@ -24,6 +25,9 @@
COOLDOWN_DECLARE(paused_stamina)
/datum/stamina_container/New(parent, maximum = STAMINA_MAX, regen_rate = STAMINA_REGEN)
+ if(maximum <= 0)
+ stack_trace("Attempted to initialize stamina container with an invalid maximum limit of [maximum], defaulting to [STAMINA_MAX]")
+ maximum = STAMINA_MAX
src.parent = parent
src.maximum = maximum
src.regen_rate = regen_rate
@@ -36,7 +40,7 @@
STOP_PROCESSING(SSstamina, src)
return ..()
-/datum/stamina_container/proc/update(seconds_per_tick)
+/datum/stamina_container/proc/update(seconds_per_tick = 1)
if(process_stamina == TRUE)
if(!is_regenerating)
if(!COOLDOWN_FINISHED(src, paused_stamina))
@@ -83,7 +87,7 @@
if(base_modify)
modify = amt
current = round(clamp(current + modify, 0, maximum), DAMAGE_PRECISION)
- update(1)
+ update()
if((amt < 0) && is_regenerating)
pause(STAMINA_REGEN_TIME)
return amt
@@ -101,7 +105,20 @@
amount = current - lowest_stamina_value
current = round(clamp(current + amount, 0, maximum), DAMAGE_PRECISION)
- update(1)
+ update()
if((amount < 0) && is_regenerating)
pause(STAMINA_REGEN_TIME)
return amount
+
+/// Sets the maximum amount of stamina.
+/// Always use this instead of directly setting the stamina var, as this has sanity checks, and immediately updates afterwards.
+/datum/stamina_container/proc/set_maximum(value = STAMINA_MAX)
+ if(!IS_SAFE_NUM(value) || value <= 0)
+ maximum = STAMINA_MAX
+ update()
+ CRASH("Attempted to set maximum stamina to invalid value ([value]), resetting to the default maximum of [STAMINA_MAX]")
+ if(value == maximum)
+ return
+ maximum = value
+ update()
+ return TRUE
diff --git a/monkestation/code/datums/status_effects/food_buffs.dm b/monkestation/code/datums/status_effects/food_buffs.dm
index 566fc6f05415..c30160a58dcb 100644
--- a/monkestation/code/datums/status_effects/food_buffs.dm
+++ b/monkestation/code/datums/status_effects/food_buffs.dm
@@ -4,7 +4,13 @@
status_type = STATUS_EFFECT_REPLACE
show_duration = TRUE
+/datum/status_effect/food/on_creation(mob/living/new_owner, quality)
+ if(!isnull(quality) && quality != 1)
+ apply_quality(quality)
+ return ..()
+
/datum/status_effect/food/proc/apply_quality(quality)
+ PROTECTED_PROC(TRUE)
return
/datum/status_effect/food/on_apply()
@@ -15,7 +21,7 @@
/datum/status_effect/food/on_remove()
if(ishuman(owner))
var/mob/living/carbon/user = owner
- user.applied_food_buffs --
+ user.applied_food_buffs--
/datum/status_effect/food/stamina_increase
id = "t1_stamina"
@@ -23,7 +29,7 @@
var/stam_increase = 10
/datum/status_effect/food/stamina_increase/apply_quality(quality)
- stam_increase = stam_increase * (1 + (quality / 50))
+ stam_increase *= 1 + (quality / 50)
/atom/movable/screen/alert/status_effect/food/stamina_increase_t1
name = "Tiny Stamina Increase"
@@ -51,14 +57,15 @@
icon_state = "stam_t3"
/datum/status_effect/food/stamina_increase/on_apply()
- if(ishuman(owner))
- owner.stamina.maximum += stam_increase
+ if(ishuman(owner) && !owner.stamina.set_maximum(owner.stamina.maximum + stam_increase))
+ stam_increase = 0 // Ensure we don't ADD more than we need to maximum upon removal
+ return FALSE
return ..()
/datum/status_effect/food/stamina_increase/on_remove()
- .=..()
+ . = ..()
if(ishuman(owner))
- owner.stamina.maximum -= stam_increase
+ owner.stamina?.set_maximum(owner.stamina.maximum - stam_increase)
/datum/status_effect/food/resistance
@@ -78,7 +85,7 @@
return ..()
/datum/status_effect/food/resistance/on_remove()
- .=..()
+ . = ..()
if(ishuman(owner))
var/mob/living/carbon/user = owner
for(var/obj/item/bodypart/limbs in user.bodyparts)
@@ -94,7 +101,7 @@
var/duration_loss = DURATION_LOSS
/datum/status_effect/food/fire_burps/apply_quality(quality)
- range = range + round((quality / 40))
+ range += round((quality / 40))
/atom/movable/screen/alert/status_effect/food/fire_burps
name = "Firey Burps"
@@ -104,14 +111,14 @@
/datum/status_effect/food/fire_burps/on_apply()
if(ishuman(owner))
var/mob/living/carbon/user = owner
- ADD_TRAIT(user, TRAIT_FOOD_FIRE_BURPS, "food_buffs")
+ ADD_TRAIT(user, TRAIT_FOOD_FIRE_BURPS, TRAIT_STATUS_EFFECT(id))
return ..()
/datum/status_effect/food/fire_burps/on_remove()
- .=..()
+ . = ..()
if(ishuman(owner))
var/mob/living/carbon/user = owner
- REMOVE_TRAIT(user, TRAIT_FOOD_FIRE_BURPS, "food_buffs")
+ REMOVE_TRAIT(user, TRAIT_FOOD_FIRE_BURPS, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/food/fire_burps/proc/Burp()
@@ -185,7 +192,7 @@
return ..()
/datum/status_effect/food/sweaty/on_remove()
- .=..()
+ . = ..()
owner.metabolism_efficiency -= metabolism_increase
@@ -201,7 +208,7 @@
var/health_increase = 10
/datum/status_effect/food/health_increase/apply_quality(quality)
- health_increase = health_increase * (1 + (quality / 50))
+ health_increase *= (1 + (quality / 50))
/atom/movable/screen/alert/status_effect/food/health_increase_t1
name = "Small Health Increase"
@@ -235,7 +242,7 @@
return ..()
/datum/status_effect/food/health_increase/on_remove()
- .=..()
+ . = ..()
if(ishuman(owner))
var/mob/living/carbon/user = owner
user.maxHealth -= health_increase
@@ -254,15 +261,13 @@
/datum/status_effect/food/belly_slide/on_apply()
if(ishuman(owner))
var/mob/living/carbon/user = owner
- ADD_TRAIT(user, TRAIT_FOOD_SLIDE, "food_buffs")
+ ADD_TRAIT(user, TRAIT_FOOD_SLIDE, TRAIT_STATUS_EFFECT(id))
return ..()
/datum/status_effect/food/belly_slide/on_remove()
- .=..()
- if(HAS_TRAIT(owner, TRAIT_FOOD_SLIDE))
- REMOVE_TRAIT(owner, TRAIT_FOOD_SLIDE, "food_buffs")
- if(owner.has_movespeed_modifier(/datum/movespeed_modifier/belly_slide))
- owner.remove_movespeed_modifier(/datum/movespeed_modifier/belly_slide)
+ . = ..()
+ REMOVE_TRAIT(owner, TRAIT_FOOD_SLIDE, TRAIT_STATUS_EFFECT(id))
+ owner.remove_movespeed_modifier(/datum/movespeed_modifier/belly_slide)
/datum/status_effect/food/stam_regen
@@ -271,7 +276,7 @@
var/regen_increase = 0.5
/datum/status_effect/food/stam_regen/apply_quality(quality)
- regen_increase = regen_increase * (1 + (quality / 20))
+ regen_increase *= (1 + (quality / 20))
/atom/movable/screen/alert/status_effect/food/stam_regen_t1
name = "Small Stamina Regeneration Increase"
@@ -312,8 +317,6 @@
user.stamina.regen_rate += regen_increase
-
-
/////JOB BUFFS
/datum/status_effect/food/botanist
@@ -328,14 +331,14 @@
/datum/status_effect/food/botanist/on_apply()
if(ishuman(owner))
var/mob/living/carbon/user = owner
- ADD_TRAIT(user, TRAIT_FOOD_JOB_BOTANIST, "food_buffs")
+ ADD_TRAIT(user, TRAIT_FOOD_JOB_BOTANIST, TRAIT_STATUS_EFFECT(id))
return ..()
/datum/status_effect/food/botanist/on_remove()
- .=..()
+ . = ..()
if(ishuman(owner))
var/mob/living/carbon/user = owner
- REMOVE_TRAIT(user, TRAIT_FOOD_JOB_BOTANIST, "food_buffs")
+ REMOVE_TRAIT(user, TRAIT_FOOD_JOB_BOTANIST, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/food/miner
@@ -350,11 +353,11 @@
/datum/status_effect/food/miner/on_apply()
if(ishuman(owner))
var/mob/living/carbon/user = owner
- ADD_TRAIT(user, TRAIT_FOOD_JOB_MINER, "food_buffs")
+ ADD_TRAIT(user, TRAIT_FOOD_JOB_MINER, TRAIT_STATUS_EFFECT(id))
return ..()
/datum/status_effect/food/miner/on_remove()
- .=..()
+ . = ..()
if(ishuman(owner))
var/mob/living/carbon/user = owner
- REMOVE_TRAIT(user, TRAIT_FOOD_JOB_MINER, "food_buffs")
+ REMOVE_TRAIT(user, TRAIT_FOOD_JOB_MINER, TRAIT_STATUS_EFFECT(id))
diff --git a/monkestation/code/game/machinery/suit_storage_unit.dm b/monkestation/code/game/machinery/suit_storage_unit.dm
index fa0054c0b9ef..1df6d989a092 100644
--- a/monkestation/code/game/machinery/suit_storage_unit.dm
+++ b/monkestation/code/game/machinery/suit_storage_unit.dm
@@ -6,3 +6,11 @@
suit_type = /obj/item/clothing/suit/space/hardsuit/atmos
*/
+
+/obj/machinery/suit_storage_unit/cmo
+ suit_type = /obj/item/clothing/suit/bio_suit/cmo
+ helmet_type = /obj/item/clothing/head/bio_hood/cmo
+
+/obj/machinery/suit_storage_unit/rd
+ suit_type = /obj/item/clothing/suit/bio_suit/scientist
+ helmet_type = /obj/item/clothing/head/bio_hood/scientist
diff --git a/monkestation/code/game/objects/effects/landmark.dm b/monkestation/code/game/objects/effects/landmark.dm
index 266d1b747262..efbf911f16c9 100644
--- a/monkestation/code/game/objects/effects/landmark.dm
+++ b/monkestation/code/game/objects/effects/landmark.dm
@@ -136,3 +136,11 @@
name = "Brig Physician"
icon = 'monkestation/icons/mob/landmarks.dmi'
icon_state = "Brig Physician"
+
+/obj/effect/landmark/start/nanotrasen_representative
+ name = "Nanotrasen Representative"
+ icon_state = "Nanotrasen Representative"
+
+/obj/effect/landmark/start/blueshield
+ name = "Blueshield"
+ icon_state = "Blueshield"
diff --git a/monkestation/code/game/objects/items/AI_modules/full_lawsets.dm b/monkestation/code/game/objects/items/AI_modules/full_lawsets.dm
index 9d5d555fa9f8..31fd0a8a17f2 100644
--- a/monkestation/code/game/objects/items/AI_modules/full_lawsets.dm
+++ b/monkestation/code/game/objects/items/AI_modules/full_lawsets.dm
@@ -2,3 +2,8 @@
name = "'Jermov' Core AI Module"
desc = "Okay, if I... if I were to have a borg put you into the chef's meat grinder, and the only thing that comes out, that's left of you, is your gibs, you'r- you're PROBABLY DEAD! You're probably going to - not you specifically captain, I'm just sayin', like, if you- if somebody were to, like, drag you into a meat grinder, and, like, your- one of your organs is still intact, they're not gonna pick it up and go, \"Well see, yeah it wasn't deadly, it wasn't an instant kill move! You still got, like, this part of your heart is left!\" NO I'M NOT GONNA PUT YOU INTO A MEAT GRINDER. I'M NOT GONNA PUT YOU INTO A MEAT GRINDER. NO. I'm making a reference to the fact that, like, if I, like, if I were to get fucking KILLED... I don't know, YOU KNOW WHAT I'M SAYIN'. If- if- okay, if you were to- okay we're gonna take crew out of this, if a floran wizard fuckin' shoots a death wand at a goblin assistant, if there's only fucking DUST AND REMAINS LEFT, it's- it's fucking you're dead, you're dead."
law_id = "jerma"
+
+/obj/item/ai_module/core/full/dj
+ name = "Disc Jockey AI Module"
+ desc = "Party on dude!"
+ law_id = "id"
diff --git a/monkestation/code/game/objects/items/guns/crank_guns.dm b/monkestation/code/game/objects/items/guns/crank_guns.dm
index 93f942bdb870..02332580e455 100644
--- a/monkestation/code/game/objects/items/guns/crank_guns.dm
+++ b/monkestation/code/game/objects/items/guns/crank_guns.dm
@@ -21,17 +21,6 @@
charge_sound_cooldown_time = 1.3 SECONDS, \
)
-/obj/projectile/beam/laser/musket
- damage = 30
- stamina = 45
-
-/obj/projectile/beam/laser/musket/prime
- damage = 35
- stamina = 60
-
-/obj/projectile/beam/disabler/smoothbore/prime /// ????????? why is this here *and* in beams ???????
- stamina = 65
-
/obj/item/ammo_casing/energy/laser/musket
fire_sound = 'sound/weapons/lasercannonfire.ogg'
diff --git a/monkestation/code/game/objects/items/guns/long_guns.dm b/monkestation/code/game/objects/items/guns/long_guns.dm
index 0581aa8b078a..7d72a29e49a2 100644
--- a/monkestation/code/game/objects/items/guns/long_guns.dm
+++ b/monkestation/code/game/objects/items/guns/long_guns.dm
@@ -45,7 +45,8 @@
/obj/projectile/bullet/g45l
name = ".45 Long bullet"
- damage = 35
+ damage = 30
+ weak_against_armour = TRUE // High fire rate
wound_bonus = -5
sharpness = SHARP_EDGED
embedding = list(embed_chance=25, fall_chance=2, jostle_chance=2, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=3, jostle_pain_mult=5, rip_time=1 SECONDS)
diff --git a/monkestation/code/game/objects/items/storage/medkit.dm b/monkestation/code/game/objects/items/storage/medkit.dm
new file mode 100644
index 000000000000..8f2d8e62d1c4
--- /dev/null
+++ b/monkestation/code/game/objects/items/storage/medkit.dm
@@ -0,0 +1,15 @@
+/obj/item/storage/medkit/surgery/cmo/PopulateContents()
+ if(empty)
+ return
+ var/static/items_inside = list(
+ /obj/item/healthanalyzer/advanced = 1,
+ /obj/item/stack/medical/gauze/twelve = 1,
+ /obj/item/stack/medical/suture = 2,
+ /obj/item/stack/medical/mesh = 2,
+ /obj/item/reagent_containers/hypospray/medipen = 1,
+ /obj/item/surgical_drapes = 1,
+ /obj/item/scalpel = 1,
+ /obj/item/hemostat = 1,
+ /obj/item/cautery = 1,
+ )
+ generate_items_inside(items_inside,src)
diff --git a/monkestation/code/game/objects/structures/crates_lockers/closets/secure/blueshield.dm b/monkestation/code/game/objects/structures/crates_lockers/closets/secure/blueshield.dm
new file mode 100644
index 000000000000..e16d16010e3f
--- /dev/null
+++ b/monkestation/code/game/objects/structures/crates_lockers/closets/secure/blueshield.dm
@@ -0,0 +1,17 @@
+/obj/structure/closet/secure_closet/blueshield
+ name = "blueshield's locker"
+ icon_state = "bs"
+ icon = 'monkestation/code/modules/blueshift/icons/obj/closet.dmi'
+ req_access = list(ACCESS_BLUESHIELD)
+
+/obj/structure/closet/secure_closet/blueshield/New()
+ ..()
+ new /obj/item/storage/briefcase/secure(src)
+ new /obj/item/clothing/glasses/hud/security/sunglasses(src)
+ new /obj/item/storage/medkit/frontier/stocked(src)
+ new /obj/item/storage/bag/garment/blueshield(src)
+ new /obj/item/mod/control/pre_equipped/blueshield(src)
+ new /obj/item/sensor_device/blueshield(src)
+ new /obj/item/radio/headset/headset_bs(src)
+ new /obj/item/radio/headset/headset_bs/alt(src)
+ new /obj/item/storage/photo_album/blueshield(src)
diff --git a/monkestation/code/modules/NTrep/NTrep_locker.dm b/monkestation/code/game/objects/structures/crates_lockers/closets/secure/nanotrasen_rep.dm
similarity index 93%
rename from monkestation/code/modules/NTrep/NTrep_locker.dm
rename to monkestation/code/game/objects/structures/crates_lockers/closets/secure/nanotrasen_rep.dm
index 187ec3b2d40b..ceab72f315b2 100644
--- a/monkestation/code/modules/NTrep/NTrep_locker.dm
+++ b/monkestation/code/game/objects/structures/crates_lockers/closets/secure/nanotrasen_rep.dm
@@ -13,3 +13,4 @@
new /obj/item/bedsheet/centcom(src)
new /obj/item/storage/bag/garment/nanotrasen_representative(src)
new /obj/item/circuitboard/machine/fax(src)
+ new /obj/item/storage/photo_album/nt_rep(src)
diff --git a/monkestation/code/modules/NTrep/NTrep_spawn.dm b/monkestation/code/modules/NTrep/NTrep_spawn.dm
deleted file mode 100644
index 1826eb77047b..000000000000
--- a/monkestation/code/modules/NTrep/NTrep_spawn.dm
+++ /dev/null
@@ -1,3 +0,0 @@
-/obj/effect/landmark/start/nanotrasen_representative
- name = "Nanotrasen Representative"
- icon_state = "Nanotrasen Representative"
diff --git a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm
index 2b96a3be3da8..217613d4bc7f 100644
--- a/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm
+++ b/monkestation/code/modules/antagonists/borers/code/abilities/enter_host.dm
@@ -114,8 +114,6 @@
if(!(cortical_owner.upgrade_flags & BORER_STEALTH_MODE))
to_chat(cortical_owner.human_host, span_notice("A chilling sensation goes down your spine..."))
- cortical_owner.copy_languages(cortical_owner.human_host)
-
var/obj/item/organ/internal/borer_body/borer_organ = new(cortical_owner.human_host)
borer_organ.borer = owner
borer_organ.Insert(cortical_owner.human_host)
diff --git a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm
index 3ebfa95db0ee..5885370dea75 100644
--- a/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm
+++ b/monkestation/code/modules/antagonists/borers/code/mobs/cortical_borer.dm
@@ -89,6 +89,8 @@ GLOBAL_LIST_INIT(borer_second_name, world.file2list("monkestation/code/modules/a
icon_dead = "brainslug_dead"
maxHealth = 25
health = 25
+ // Allows them to understand any language their current host can.
+ initial_language_holder = /datum/language_holder/borer
// They need to be able to pass tables and mobs
pass_flags = PASSTABLE | PASSMOB
density = FALSE
diff --git a/monkestation/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm b/monkestation/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm
index 8f18cf7046e1..ffe3ddfafbba 100644
--- a/monkestation/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm
+++ b/monkestation/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm
@@ -467,7 +467,7 @@
return
// Teleport them to a random safe coordinate on the station z level.
- var/turf/open/floor/safe_turf = get_safe_random_station_turf()
+ var/turf/open/floor/safe_turf = get_safe_random_station_turf_equal_weight()
var/obj/effect/landmark/observer_start/backup_loc = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list
if(!safe_turf)
safe_turf = get_turf(backup_loc)
diff --git a/monkestation/code/modules/antagonists/monster_hunters/events/wonderland_apocalypse.dm b/monkestation/code/modules/antagonists/monster_hunters/events/wonderland_apocalypse.dm
index 23cc252085c2..c6d22fbef306 100644
--- a/monkestation/code/modules/antagonists/monster_hunters/events/wonderland_apocalypse.dm
+++ b/monkestation/code/modules/antagonists/monster_hunters/events/wonderland_apocalypse.dm
@@ -36,9 +36,9 @@
/datum/round_event/wonderlandapocalypse/start()
SSshuttle.emergency_no_recall = TRUE
for(var/i = 1 to 16)
- new /obj/effect/anomaly/dimensional/wonderland(get_safe_random_station_turf(), null, FALSE)
+ new /obj/effect/anomaly/dimensional/wonderland(get_safe_random_station_turf_equal_weight(), null, FALSE)
for(var/i = 1 to 4)
- var/obj/structure/wonderland_rift/rift = new(get_safe_random_station_turf())
+ var/obj/structure/wonderland_rift/rift = new(get_safe_random_station_turf_equal_weight())
notify_ghosts(
"A doorway to the wonderland has been opened!",
source = rift,
diff --git a/monkestation/code/modules/antagonists/monster_hunters/hunter_datum.dm b/monkestation/code/modules/antagonists/monster_hunters/hunter_datum.dm
index fd5e794650b0..472efc0c42ab 100644
--- a/monkestation/code/modules/antagonists/monster_hunters/hunter_datum.dm
+++ b/monkestation/code/modules/antagonists/monster_hunters/hunter_datum.dm
@@ -77,7 +77,7 @@
RegisterSignal(src, COMSIG_GAIN_INSIGHT, PROC_REF(insight_gained))
RegisterSignal(src, COMSIG_BEASTIFY, PROC_REF(turn_beast))
for(var/i in 1 to 5)
- var/turf/rabbit_hole = get_safe_random_station_turf()
+ var/turf/rabbit_hole = get_safe_random_station_turf_equal_weight()
rabbits += new /obj/effect/bnnuy(rabbit_hole, src)
var/obj/effect/bnnuy/gun_holder = pick(rabbits)
gun_holder.drop_gun = TRUE
diff --git a/monkestation/code/modules/antagonists/traitor/objectives/kidnapping.dm b/monkestation/code/modules/antagonists/traitor/objectives/kidnapping.dm
index 405b2e46ea16..967ff9224409 100644
--- a/monkestation/code/modules/antagonists/traitor/objectives/kidnapping.dm
+++ b/monkestation/code/modules/antagonists/traitor/objectives/kidnapping.dm
@@ -47,6 +47,15 @@
/datum/job/janitor,
/datum/job/lawyer,
/datum/job/mime,
+ // monkestation addition: barbers and spooktober
+ /datum/job/barber,
+ /datum/job/yellowclown,
+ /datum/job/skeleton,
+ /datum/job/candysalesman,
+ /datum/job/dietwizard,
+ /datum/job/ghost,
+ /datum/job/godzilla,
+ /datum/job/gorilla,
)
alive_bonus = 3
@@ -69,8 +78,10 @@
/datum/job/paramedic,
// Service
/datum/job/cook,
- // Monkestation edit: security assistants
+ // Monkestation addition: Security
/datum/job/security_assistant,
+ // Monkestation addition: Engineering
+ /datum/job/signal_technician,
)
alive_bonus = 4
@@ -293,7 +304,7 @@
continue
possible_turfs += open_turf
- var/turf/return_turf = get_safe_random_station_turf()
+ var/turf/return_turf = get_safe_random_station_turf_equal_weight()
if(!return_turf) //SOMEHOW
to_chat(sent_mob, span_hypnophrase(span_reallybig("A million voices echo in your head... \"Seems where you got sent here from won't \
be able to handle our pod... You will die here instead.\"")))
diff --git a/monkestation/code/modules/art_sci_overrides/faults/warps.dm b/monkestation/code/modules/art_sci_overrides/faults/warps.dm
index 72b8b99fbce4..14a22ebd586b 100644
--- a/monkestation/code/modules/art_sci_overrides/faults/warps.dm
+++ b/monkestation/code/modules/art_sci_overrides/faults/warps.dm
@@ -2,16 +2,11 @@
name = "Warping Fault"
trigger_chance = 12
visible_message = "warps space sending everyone away."
- var/list/warp_areas = list()
-
research_value = 250
-
weight = ARTIFACT_UNCOMMON
/datum/artifact_fault/warp/on_trigger()
- if(!length(warp_areas))
- warp_areas = GLOB.the_station_areas
- var/turf/safe_turf = get_safe_random_station_turf(warp_areas)
+ var/turf/safe_turf = get_safe_random_station_turf_equal_weight()
var/center_turf = get_turf(our_artifact.parent)
if(!center_turf)
diff --git a/monkestation/code/modules/art_sci_overrides/generic_artifact_objects.dm b/monkestation/code/modules/art_sci_overrides/generic_artifact_objects.dm
index 2edbd7e70d17..492e4a873d4b 100644
--- a/monkestation/code/modules/art_sci_overrides/generic_artifact_objects.dm
+++ b/monkestation/code/modules/art_sci_overrides/generic_artifact_objects.dm
@@ -18,9 +18,12 @@ ARTIFACT_SETUP(/obj/structure/artifact, SSobj, null, forced_effect, null)
icon_state = "wiznerd-1"
/obj/effect/artifact_spawner/Initialize(mapload)
- . = ..()
+ ..()
+// don't want artifacts exploding during unit tests or something
+#ifndef UNIT_TESTS
spawn_artifact(loc)
- qdel(src)
+#endif
+ return INITIALIZE_HINT_QDEL
/obj/structure/artifact/bonk
forced_effect = /datum/artifact_effect/bonk
diff --git a/monkestation/code/modules/assault_ops/code/interrogator.dm b/monkestation/code/modules/assault_ops/code/interrogator.dm
index 91cacca425d6..d1e2939193ed 100644
--- a/monkestation/code/modules/assault_ops/code/interrogator.dm
+++ b/monkestation/code/modules/assault_ops/code/interrogator.dm
@@ -257,7 +257,7 @@
///This proc attempts to return the head of staff back to the station after the interrogator finishes
/obj/machinery/interrogator/proc/return_victim()
- var/turf/open/floor/safe_turf = get_safe_random_station_turf()
+ var/turf/open/floor/safe_turf = get_safe_random_station_turf_equal_weight()
var/obj/effect/landmark/observer_start/backup_loc = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list
if(!safe_turf)
safe_turf = get_turf(backup_loc)
diff --git a/monkestation/code/modules/assault_ops/code/sunbeam.dm b/monkestation/code/modules/assault_ops/code/sunbeam.dm
index b0cd2b093ba3..521619898e4d 100644
--- a/monkestation/code/modules/assault_ops/code/sunbeam.dm
+++ b/monkestation/code/modules/assault_ops/code/sunbeam.dm
@@ -165,7 +165,7 @@
/datum/round_event/icarus_sunbeam/start()
var/startside = pick(GLOB.cardinals)
- var/turf/end_turf = get_edge_target_turf(get_safe_random_station_turf(), turn(startside, 180))
+ var/turf/end_turf = get_edge_target_turf(get_safe_random_station_turf_equal_weight(), turn(startside, 180))
var/turf/start_turf = spaceDebrisStartLoc(startside, end_turf.z)
new /obj/effect/sunbeam(start_turf, end_turf)
diff --git a/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_datum.dm b/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_datum.dm
index 9d9324824c16..8ef63ba4b281 100644
--- a/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_datum.dm
+++ b/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_datum.dm
@@ -136,6 +136,9 @@
on_hud_created()
else
RegisterSignal(current_mob, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created))
+
+ ensure_brain_nonvital(current_mob)
+
#ifdef BLOODSUCKER_TESTING
var/turf/user_loc = get_turf(current_mob)
new /obj/structure/closet/crate/coffin(user_loc)
@@ -229,6 +232,13 @@
clear_powers_and_stats()
check_cancel_sunlight() //check if sunlight should end
owner.special_role = null
+ if(!iscarbon(owner.current))
+ return
+ var/mob/living/carbon/carbon_owner = owner.current
+ var/obj/item/organ/internal/brain/not_vamp_brain = carbon_owner.get_organ_slot(ORGAN_SLOT_BRAIN)
+ if(not_vamp_brain && (not_vamp_brain.decoy_override != initial(not_vamp_brain.decoy_override)))
+ not_vamp_brain.organ_flags |= ORGAN_VITAL
+ not_vamp_brain.decoy_override = FALSE
return ..()
/datum/antagonist/bloodsucker/on_body_transfer(mob/living/old_body, mob/living/new_body)
@@ -272,8 +282,7 @@
new_right_arm.unarmed_damage_high = old_right_arm_unarmed_damage_high
//Give Bloodsucker Traits
- if(old_body)
- old_body.remove_traits(bloodsucker_traits, BLOODSUCKER_TRAIT)
+ old_body?.remove_traits(bloodsucker_traits, BLOODSUCKER_TRAIT)
new_body.add_traits(bloodsucker_traits, BLOODSUCKER_TRAIT)
/datum/antagonist/bloodsucker/greet()
@@ -395,6 +404,19 @@
return report.Join("
")
+/// "Oh, well, that's step one. What about two through ten?"
+/// Beheading bloodsuckers is kinda buggy and results in them being dead-dead without actually being final deathed, which is NOT something that's desired.
+/// Just stake them. No shortcuts.
+/datum/antagonist/bloodsucker/proc/ensure_brain_nonvital(mob/living/mob_override)
+ var/mob/living/carbon/carbon_owner = mob_override || owner.current
+ if(!iscarbon(carbon_owner) || isoozeling(carbon_owner))
+ return
+ var/obj/item/organ/internal/brain/brain = carbon_owner.get_organ_slot(ORGAN_SLOT_BRAIN)
+ if(QDELETED(brain))
+ return
+ brain.organ_flags &= ~ORGAN_VITAL
+ brain.decoy_override = TRUE
+
/datum/antagonist/bloodsucker/proc/give_starting_powers()
for(var/datum/action/cooldown/bloodsucker/all_powers as anything in all_bloodsucker_powers)
if(!(initial(all_powers.purchase_flags) & BLOODSUCKER_DEFAULT_POWER))
diff --git a/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_life.dm b/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_life.dm
index b1f0cb6b9954..7ee50d5f6458 100644
--- a/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_life.dm
+++ b/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_life.dm
@@ -126,6 +126,8 @@
return FALSE
for(var/missing_limb in missing) //Find ONE Limb and regenerate it.
user.regenerate_limb(missing_limb, FALSE)
+ if(missing_limb == BODY_ZONE_HEAD)
+ ensure_brain_nonvital()
AddBloodVolume(-limb_regen_cost)
var/obj/item/bodypart/missing_bodypart = user.get_bodypart(missing_limb) // 2) Limb returns Damaged
missing_bodypart.brute_dam = 60
@@ -151,6 +153,7 @@
bloodsuckeruser.cure_husk()
bloodsuckeruser.regenerate_organs(regenerate_existing = FALSE)
+ ensure_brain_nonvital()
for(var/obj/item/organ/organ as anything in bloodsuckeruser.organs)
organ.set_organ_damage(0)
diff --git a/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_moodlets.dm b/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_moodlets.dm
index bbca337306b4..936c8709254d 100644
--- a/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_moodlets.dm
+++ b/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_moodlets.dm
@@ -1,40 +1,40 @@
/datum/mood_event/drankblood
- description = "I have fed greedly from that which nourishes me.\n"
+ description = span_nicegreen("I have fed greedly from that which nourishes me.")
mood_change = 10
timeout = 8 MINUTES
/datum/mood_event/drankblood_bad
- description = "I drank the blood of a lesser creature. Disgusting.\n"
+ description = span_boldwarning("I drank the blood of a lesser creature. Disgusting.")
mood_change = -4
timeout = 3 MINUTES
/datum/mood_event/drankblood_dead
- description = "I drank dead blood. I am better than this.\n"
+ description = span_boldwarning("I drank dead blood. I am better than this.")
mood_change = -7
timeout = 8 MINUTES
/datum/mood_event/drankblood_synth
- description = "I drank synthetic blood. What is wrong with me?\n"
+ description = span_boldwarning("I drank synthetic blood. What is wrong with me?")
mood_change = -7
timeout = 8 MINUTES
/datum/mood_event/drankkilled
- description = "I fed off of a dead person. I feel... less human.\n"
+ description = span_boldwarning("I fed off of a dead person. I feel... less human.")
mood_change = -15
timeout = 10 MINUTES
/datum/mood_event/madevamp
- description = "A mortal has reached an apotheosis- undeath- by my own hand.\n"
+ description = span_boldwarning("A mortal has reached an apotheosis- undeath- by my own hand.")
mood_change = 15
timeout = 20 MINUTES
/datum/mood_event/coffinsleep
- description = "I slept in a coffin during the day. I feel whole again.\n"
+ description = span_nicegreen("I slept in a coffin during the day. I feel whole again.")
mood_change = 10
timeout = 6 MINUTES
///Candelabrum's mood event to non Bloodsucker/Vassals
/datum/mood_event/vampcandle
- description = "Something is making your mind feel... loose.\n"
+ description = span_boldwarning("Something is making your mind feel... loose.")
mood_change = -15
timeout = 5 MINUTES
diff --git a/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_objectives.dm b/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_objectives.dm
index 187782cd2128..b3e0c03ba801 100644
--- a/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_objectives.dm
+++ b/monkestation/code/modules/bloodsuckers/bloodsucker/bloodsucker_objectives.dm
@@ -278,7 +278,7 @@
// EXPLANATION
/datum/objective/bloodsucker/embrace/update_explanation_text()
. = ..()
- explanation_text = "Use the Candelabrum to Rank your Favorite Vassal up enough to become a Bloodsucker."
+ explanation_text = "Use the persuasion rack to Rank your Favorite Vassal up enough to become a Bloodsucker."
// WIN CONDITIONS?
/datum/objective/bloodsucker/embrace/check_completion()
diff --git a/monkestation/code/modules/bloodsuckers/clans/_clan_base.dm b/monkestation/code/modules/bloodsuckers/clans/_clan_base.dm
index be5c3549ce1a..1629d5201158 100644
--- a/monkestation/code/modules/bloodsuckers/clans/_clan_base.dm
+++ b/monkestation/code/modules/bloodsuckers/clans/_clan_base.dm
@@ -246,7 +246,7 @@
return
to_chat(bloodsuckerdatum.owner.current, span_notice("You can change who this Vassal is, who are they to you?"))
- var/vassal_response = show_radial_menu(bloodsuckerdatum.owner.current, vassaldatum.owner.current, radial_display)
+ var/vassal_response = show_radial_menu(bloodsuckerdatum.owner.current, vassaldatum.owner.current, radial_display, autopick_single_option = FALSE)
if(!vassal_response)
return
vassal_response = options[vassal_response]
diff --git a/monkestation/code/modules/bloodsuckers/clans/venture.dm b/monkestation/code/modules/bloodsuckers/clans/venture.dm
index 20cf06a6f0a5..5c01aacf8bf6 100644
--- a/monkestation/code/modules/bloodsuckers/clans/venture.dm
+++ b/monkestation/code/modules/bloodsuckers/clans/venture.dm
@@ -108,7 +108,7 @@
return TRUE
/datum/bloodsucker_clan/ventrue/on_favorite_vassal(datum/source, datum/antagonist/vassal/vassaldatum, mob/living/bloodsucker)
- to_chat(bloodsucker, span_announce("* Bloodsucker Tip: You can now upgrade your Favorite Vassal by buckling them onto a Candelabrum!"))
+ to_chat(bloodsucker, span_announce("* Bloodsucker Tip: You can now upgrade your Favorite Vassal by buckling them onto a persuasion rack!"))
vassaldatum.BuyPower(new /datum/action/cooldown/bloodsucker/distress)
#undef BLOODSUCKER_BLOOD_RANKUP_COST
diff --git a/monkestation/code/modules/bloodsuckers/structures/bloodsucker_crypt.dm b/monkestation/code/modules/bloodsuckers/structures/bloodsucker_crypt.dm
index 1115d9e469d9..9290af4924b2 100644
--- a/monkestation/code/modules/bloodsuckers/structures/bloodsucker_crypt.dm
+++ b/monkestation/code/modules/bloodsuckers/structures/bloodsucker_crypt.dm
@@ -292,6 +292,9 @@
if(!ishuman(target))
balloon_alert(user, "you can't torture an animal or basic mob!")
return FALSE
+ if(disloyalty_offered)
+ balloon_alert(user, "wait a moment!")
+ return FALSE
var/disloyalty_requires = RequireDisloyalty(user, target)
if(disloyalty_requires == VASSALIZATION_BANNED)
diff --git a/monkestation/code/modules/blueshield/closet.dm b/monkestation/code/modules/blueshield/closet.dm
index a9aef88fc4a3..1b0f5ef3b3f5 100644
--- a/monkestation/code/modules/blueshield/closet.dm
+++ b/monkestation/code/modules/blueshield/closet.dm
@@ -19,20 +19,3 @@
new /obj/item/assembly/flash/handheld(src)
new /obj/item/reagent_containers/spray/pepper(src)
new /obj/item/restraints/handcuffs(src)
-
-/obj/structure/closet/secure_closet/blueshield
- name = "blueshield's locker"
- icon_state = "bs"
- icon = 'monkestation/code/modules/blueshift/icons/obj/closet.dmi'
- req_access = list(ACCESS_BLUESHIELD)
-
-/obj/structure/closet/secure_closet/blueshield/New()
- ..()
- new /obj/item/storage/briefcase/secure(src)
- new /obj/item/clothing/glasses/hud/security/sunglasses(src)
- new /obj/item/storage/medkit/frontier/stocked(src)
- new /obj/item/storage/bag/garment/blueshield(src)
- new /obj/item/mod/control/pre_equipped/blueshield(src)
- new /obj/item/sensor_device/blueshield(src)
- new /obj/item/radio/headset/headset_bs(src)
- new /obj/item/radio/headset/headset_bs/alt(src)
diff --git a/monkestation/code/modules/blueshield/landmarks.dm b/monkestation/code/modules/blueshield/landmarks.dm
index 1153629768f6..e69de29bb2d1 100644
--- a/monkestation/code/modules/blueshield/landmarks.dm
+++ b/monkestation/code/modules/blueshield/landmarks.dm
@@ -1,3 +0,0 @@
-/obj/effect/landmark/start/blueshield
- name = "Blueshield"
- icon_state = "Blueshield"
diff --git a/monkestation/code/modules/blueshield/trim.dm b/monkestation/code/modules/blueshield/trim.dm
deleted file mode 100644
index 53d908c90fa7..000000000000
--- a/monkestation/code/modules/blueshield/trim.dm
+++ /dev/null
@@ -1,33 +0,0 @@
-/datum/id_trim/job/blueshield
- assignment = "Blueshield"
- trim_state = "trim_blueshield"
- department_color = COLOR_COMMAND_BLUE
- subdepartment_color = COLOR_SECURITY_RED
- sechud_icon_state = SECHUD_BLUESHIELD
- extra_access = list(
- ACCESS_BRIG,
- ACCESS_CARGO,
- ACCESS_COURT,
- ACCESS_GATEWAY,
- )
- minimal_access = list(
- ACCESS_SECURITY,
- ACCESS_ALL_PERSONAL_LOCKERS,
- ACCESS_BRIG_ENTRANCE,
- ACCESS_BLUESHIELD,
- ACCESS_COMMAND,
- ACCESS_CONSTRUCTION,
- ACCESS_ENGINEERING,
- ACCESS_EVA,
- ACCESS_MAINT_TUNNELS,
- ACCESS_MEDICAL,
- ACCESS_MINERAL_STOREROOM,
- ACCESS_SCIENCE,
- ACCESS_TELEPORTER,
- ACCESS_WEAPONS,
- )
- template_access = list(
- ACCESS_CAPTAIN,
- ACCESS_CHANGE_IDS
- )
- job = /datum/job/blueshield
diff --git a/monkestation/code/modules/blueshift/icons/obj/vending.dmi b/monkestation/code/modules/blueshift/icons/obj/vending.dmi
deleted file mode 100644
index 39142406b3a6..000000000000
Binary files a/monkestation/code/modules/blueshift/icons/obj/vending.dmi and /dev/null differ
diff --git a/monkestation/code/modules/blueshift/icons/vending.dmi b/monkestation/code/modules/blueshift/icons/vending.dmi
deleted file mode 100644
index 85fae3ed5d1e..000000000000
Binary files a/monkestation/code/modules/blueshift/icons/vending.dmi and /dev/null differ
diff --git a/monkestation/code/modules/blueshift/icons/vendor.dmi b/monkestation/code/modules/blueshift/icons/vendor.dmi
deleted file mode 100644
index 62b6cbe0c5bf..000000000000
Binary files a/monkestation/code/modules/blueshift/icons/vendor.dmi and /dev/null differ
diff --git a/monkestation/code/modules/blueshift/items/barber.dm b/monkestation/code/modules/blueshift/items/barber.dm
index c30a3d4d928a..f10b6c52f090 100644
--- a/monkestation/code/modules/blueshift/items/barber.dm
+++ b/monkestation/code/modules/blueshift/items/barber.dm
@@ -287,7 +287,7 @@
/obj/machinery/vending/barbervend
name = "Fab-O-Vend"
desc = "It would seem it vends dyes, and other stuff to make you pretty."
- icon = 'monkestation/code/modules/blueshift/icons/vendor.dmi'
+ icon = 'monkestation/icons/obj/vending.dmi'
icon_state = "barbervend"
product_slogans = "Spread the colour, like butter, onto toast... Onto their hair.; Sometimes, I dream about dyes...; Paint 'em up and call me Mr. Painter.; Look brother, I'm a vendomat, I solve practical problems."
product_ads = "Cut 'em all!; To sheds!; Hair be gone!; Prettify!; Beautify!"
diff --git a/monkestation/code/modules/blueshift/items/company_guns.dm b/monkestation/code/modules/blueshift/items/company_guns.dm
index 6157ebbecfe3..4738ce9c85e3 100644
--- a/monkestation/code/modules/blueshift/items/company_guns.dm
+++ b/monkestation/code/modules/blueshift/items/company_guns.dm
@@ -135,6 +135,7 @@
wield_recoil = 0.5
spread = 12.5
projectile_wound_bonus = -20
+ projectile_damage_multiplier = 0.75
/obj/item/gun/ballistic/automatic/sol_rifle/machinegun/examine_more(mob/user)
. = ..()
diff --git a/monkestation/code/modules/blueshift/machines/access_vending.dm b/monkestation/code/modules/blueshift/machines/access_vending.dm
index d2dffab7409d..2e796345b070 100644
--- a/monkestation/code/modules/blueshift/machines/access_vending.dm
+++ b/monkestation/code/modules/blueshift/machines/access_vending.dm
@@ -88,7 +88,7 @@
name = "\improper Command Outfitting Station"
desc = "A vending machine for specialised clothing for members of Command."
product_ads = "File paperwork in style!;It's red so you can't see the blood!;You have the right to be fashionable!;Now you can be the fashion police you always wanted to be!"
- icon = 'monkestation/code/modules/blueshift/icons/vending.dmi'
+ icon = 'monkestation/icons/obj/vending.dmi'
icon_state = "commdrobe"
light_mask = "wardrobe-light-mask"
vend_reply = "Thank you for using the CommDrobe!"
diff --git a/monkestation/code/modules/blueshift/structures/ash_walker.dm b/monkestation/code/modules/blueshift/structures/ash_walker.dm
index 287c03637caa..aa1fc772c9e1 100644
--- a/monkestation/code/modules/blueshift/structures/ash_walker.dm
+++ b/monkestation/code/modules/blueshift/structures/ash_walker.dm
@@ -1104,7 +1104,7 @@
name = "\improper Ashland Clothing Storage"
desc = "A large container, filled with various clothes for the Ash Walkers."
product_ads = "Praise the Necropolis"
- icon = 'monkestation/code/modules/blueshift/icons/vending.dmi'
+ icon = 'monkestation/icons/obj/vending.dmi'
icon_state = "ashclothvendor"
icon_deny = "necrocrate"
diff --git a/monkestation/code/modules/client/verbs.dm b/monkestation/code/modules/client/verbs.dm
index 6ce64ebe5892..2531f6b5b842 100644
--- a/monkestation/code/modules/client/verbs.dm
+++ b/monkestation/code/modules/client/verbs.dm
@@ -119,14 +119,15 @@ GLOBAL_LIST_INIT(antag_token_config, load_antag_token_config())
var/static/default_config = list(
HIGH_THREAT = init_antag_list(list(
/datum/antagonist/cult,
- /datum/antagonist/rev/head,
/datum/antagonist/wizard,
/datum/antagonist/clock_cultist,
/datum/antagonist/ninja,
+ /datum/antagonist/blob,
)),
MEDIUM_THREAT = init_antag_list(list(
/datum/antagonist/heretic,
/datum/antagonist/bloodsucker,
+ /datum/antagonist/changeling,
/datum/antagonist/cortical_borer/hivemind,
)),
LOW_THREAT = init_antag_list(list(
diff --git a/monkestation/code/modules/cybernetics/augments/arm_augments/_base.dm b/monkestation/code/modules/cybernetics/augments/arm_augments/_base.dm
index a63c274882aa..452f908249e5 100644
--- a/monkestation/code/modules/cybernetics/augments/arm_augments/_base.dm
+++ b/monkestation/code/modules/cybernetics/augments/arm_augments/_base.dm
@@ -2,7 +2,7 @@
name = "arm-mounted implant"
desc = "You shouldn't see this! Adminhelp and report this as an issue on github!"
zone = BODY_ZONE_R_ARM
- icon_state = "implant-toolkit"
+ icon_state = "toolkit_generic"
w_class = WEIGHT_CLASS_SMALL
actions_types = list(/datum/action/item_action/organ_action/toggle)
encode_info = AUGMENT_NT_LOWLEVEL
diff --git a/monkestation/code/modules/cybernetics/augments/arm_augments/item_sets/jobs.dm b/monkestation/code/modules/cybernetics/augments/arm_augments/item_sets/jobs.dm
index ef90205d9b79..694fb37e58ba 100644
--- a/monkestation/code/modules/cybernetics/augments/arm_augments/item_sets/jobs.dm
+++ b/monkestation/code/modules/cybernetics/augments/arm_augments/item_sets/jobs.dm
@@ -2,7 +2,7 @@
name = "integrated toolset implant"
desc = "A stripped-down version of the engineering cyborg toolset, designed to be installed on subject's arm. Contain advanced versions of every tool."
actions_types = list(/datum/action/item_action/organ_action/toggle/toolkit)
- icon_state = "toolkit_generic"
+ icon_state = "toolkit_engineering"
items_to_create = list(
/obj/item/screwdriver/cyborg,
/obj/item/wrench/cyborg,
@@ -15,7 +15,6 @@
/obj/item/organ/internal/cyberimp/arm/item_set/toolset/l
zone = BODY_ZONE_L_ARM
- icon_state = "toolkit_engineering"
/obj/item/organ/internal/cyberimp/arm/item_set/toolset/emag_act(mob/user, obj/item/card/emag/emag_card)
for(var/datum/weakref/created_item in items_list)
diff --git a/monkestation/code/modules/cybernetics/augments/chest_augments.dm b/monkestation/code/modules/cybernetics/augments/chest_augments.dm
index aa25b195f7ed..b107ed6806cf 100644
--- a/monkestation/code/modules/cybernetics/augments/chest_augments.dm
+++ b/monkestation/code/modules/cybernetics/augments/chest_augments.dm
@@ -222,7 +222,8 @@
name = "nutriment pump implant"
desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are starving."
icon_state = "nutriment_implant"
- implant_color = "#00AA00"
+ implant_overlay = null
+ implant_color = null
var/hunger_threshold = NUTRITION_LEVEL_STARVING
var/synthesizing = 0
var/poison_amount = 5
@@ -257,7 +258,6 @@
name = "nutriment pump implant PLUS"
desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are hungry."
icon_state = "adv_nutriment_implant"
- implant_color = "#006607"
hunger_threshold = NUTRITION_LEVEL_HUNGRY
poison_amount = 10
@@ -265,7 +265,8 @@
name = "reviver implant"
desc = "This implant will attempt to revive and heal you if you lose consciousness. For the faint of heart!"
icon_state = "reviver_implant"
- implant_color = "#AD0000"
+ implant_overlay = null
+ implant_color = null
slot = ORGAN_SLOT_HEART_AID
encode_info = AUGMENT_NT_HIGHLEVEL
var/revive_cost = 0
diff --git a/monkestation/code/modules/cybernetics/augments/eye_implants.dm b/monkestation/code/modules/cybernetics/augments/eye_implants.dm
index f1665643c020..ea1d4d77c0cd 100644
--- a/monkestation/code/modules/cybernetics/augments/eye_implants.dm
+++ b/monkestation/code/modules/cybernetics/augments/eye_implants.dm
@@ -65,16 +65,15 @@
/obj/item/organ/internal/cyberimp/eyes/hud/security
name = "security HUD implant"
desc = "These cybernetic eye implants will display a security HUD over everything you see."
- name = "security HUD implant"
+ icon_state = "eye_implant_security"
HUD_type = DATA_HUD_SECURITY_ADVANCED
HUD_trait = TRAIT_SECURITY_HUD
- organ_flags = ALL
encode_info = AUGMENT_NT_HIGHLEVEL
/obj/item/organ/internal/cyberimp/eyes/hud/diagnostic
name = "diagnostic HUD implant"
desc = "These cybernetic eye implants will display a diagnostic HUD over everything you see."
- name = "diagnostic HUD implant"
+ icon_state = "eye_implant_diagnostic"
HUD_type = DATA_HUD_DIAGNOSTIC_ADVANCED
/obj/item/organ/internal/cyberimp/eyes/hud/security/syndicate
diff --git a/monkestation/code/modules/guns/laser.dm b/monkestation/code/modules/guns/laser.dm
deleted file mode 100644
index 40468a54bb69..000000000000
--- a/monkestation/code/modules/guns/laser.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-/obj/item/gun/energy/laser/captain
- ammo_type = list(/obj/item/ammo_casing/energy/laser/hellfire/antique, /obj/item/ammo_casing/energy/disabler)
diff --git a/monkestation/code/modules/jobs/job_types/barber.dm b/monkestation/code/modules/jobs/job_types/barber.dm
index b10e1e17248e..6b11776adf6c 100644
--- a/monkestation/code/modules/jobs/job_types/barber.dm
+++ b/monkestation/code/modules/jobs/job_types/barber.dm
@@ -15,7 +15,7 @@
paycheck = PAYCHECK_CREW
paycheck_department = ACCOUNT_SRV
- display_order = JOB_DISPLAY_ORDER_ASSISTANT
+ display_order = JOB_DISPLAY_ORDER_BARBER
departments_list = list(
/datum/job_department/late,
)
diff --git a/monkestation/code/modules/NTrep/NTrep.dm b/monkestation/code/modules/jobs/job_types/nanotrasen_representative.dm
similarity index 84%
rename from monkestation/code/modules/NTrep/NTrep.dm
rename to monkestation/code/modules/jobs/job_types/nanotrasen_representative.dm
index 346b2b6963d2..1a9f8c364502 100644
--- a/monkestation/code/modules/NTrep/NTrep.dm
+++ b/monkestation/code/modules/jobs/job_types/nanotrasen_representative.dm
@@ -73,8 +73,7 @@
)
belt = /obj/item/gun/energy/laser/plasmacore
shoes = /obj/item/clothing/shoes/laceup
- l_pocket = /obj/item/pen/fountain
- r_pocket = /obj/item/modular_computer/pda/heads
+ r_pocket = /obj/item/modular_computer/pda/heads/ntrep
l_hand = /obj/item/storage/secure/briefcase/cash
glasses = /obj/item/clothing/glasses/sunglasses
ears = /obj/item/radio/headset/headset_cent
@@ -92,23 +91,4 @@
/obj/item/skillchip/disk_verifier,
)
-/datum/id_trim/job/nanotrasen_representative
- assignment = "Nanotrasen Representative"
- trim_state = "trim_centcom"
- department_color = COLOR_CENTCOM_BLUE
- subdepartment_color = COLOR_CENTCOM_BLUE
- sechud_icon_state = SECHUD_CENTCOM
- minimal_access = list(
- ACCESS_BRIG_ENTRANCE,
- ACCESS_COMMAND,
- ACCESS_MAINT_TUNNELS,
- ACCESS_WEAPONS,
- ACCESS_NT_REPRESENTATVE,
- )
- extra_access = list(
- ACCESS_BAR,
- )
- template_access = list(
- )
- job = /datum/job/nanotrasen_representative
diff --git a/monkestation/code/modules/jobs/job_types/yellowclown.dm b/monkestation/code/modules/jobs/job_types/yellowclown.dm
index a2f5cfe8b2ac..df31914b693e 100644
--- a/monkestation/code/modules/jobs/job_types/yellowclown.dm
+++ b/monkestation/code/modules/jobs/job_types/yellowclown.dm
@@ -17,7 +17,7 @@
mind_traits = list(TRAIT_NAIVE)
liver_traits = list(TRAIT_COMEDY_METABOLISM)
- display_order = JOB_DISPLAY_ORDER_ASSISTANT
+ display_order = JOB_DISPLAY_ORDER_CLOWN
departments_list = list(
/datum/job_department/spooktober,
)
diff --git a/monkestation/code/modules/language/language_holder.dm b/monkestation/code/modules/language/language_holder.dm
new file mode 100644
index 000000000000..609c33278e89
--- /dev/null
+++ b/monkestation/code/modules/language/language_holder.dm
@@ -0,0 +1,10 @@
+/// Language holder for borers, that let them understand any language their host understands.
+/datum/language_holder/borer
+
+/datum/language_holder/borer/has_language(language, spoken = FALSE)
+ . = ..()
+ if(.)
+ return
+ var/mob/living/basic/cortical_borer/cortical_owner = get_atom()
+ if(istype(cortical_owner))
+ return cortical_owner.human_host?.get_language_holder()?.has_language(language, spoken)
diff --git a/monkestation/code/modules/loafing/code/loaf.dm b/monkestation/code/modules/loafing/code/loaf.dm
index e528a4cd94fd..5db592ae4cbc 100644
--- a/monkestation/code/modules/loafing/code/loaf.dm
+++ b/monkestation/code/modules/loafing/code/loaf.dm
@@ -4,9 +4,11 @@
icon = 'monkestation/code/modules/loafing/icons/obj.dmi'
icon_state = "loaf"
food_reagents = list(/datum/reagent/consumable/nutraslop = 10)
+ force_feed_on_aggression = TRUE
+ preserved_food = TRUE
+
var/loaf_density = 1 //base loaf density
var/can_condense = TRUE //for special loaves, make false
- force_feed_on_aggression = TRUE
//vars for high level loafs
var/critical = FALSE
diff --git a/monkestation/code/modules/mob/living/carbon/emote.dm b/monkestation/code/modules/mob/living/carbon/emote.dm
index 87d873cea9ed..17d218673745 100644
--- a/monkestation/code/modules/mob/living/carbon/emote.dm
+++ b/monkestation/code/modules/mob/living/carbon/emote.dm
@@ -115,3 +115,40 @@
/obj/item/gun/ballistic/fingergun_emote/eject_magazine()
return
+
+/datum/emote/living/carbon/sweatdrop
+ key = "sweatdrop"
+ key_third_person = "sweatdrops"
+ message = "sweats"
+ emote_type = EMOTE_VISIBLE
+ vary = TRUE
+ sound = 'monkestation/sound/effects/sweatdrop.ogg'
+
+/datum/emote/living/carbon/sweatdrop/run_emote(mob/living/carbon/user, params, type_override, intentional)
+ . = ..()
+ if(!.)
+ return
+ var/image/emote_animation = image('monkestation/icons/mob/species/human/emote_visuals.dmi', user, "sweatdrop", pixel_x = 10, pixel_y = 10)
+ if(ishuman(user))
+ var/mob/living/carbon/human/human_user = user
+ emote_animation = human_user.apply_height_offsets(emote_animation, UPPER_BODY)
+ flick_overlay_global(emote_animation, GLOB.clients, 3 SECONDS)
+
+/datum/emote/living/carbon/sweatdrop/sweat //This is entirely the same as sweatdrop, however people might use either, so I'm adding this one instead of editing the other one.
+ key = "sweat"
+
+/datum/emote/living/carbon/annoyed
+ key = "annoyed"
+ emote_type = EMOTE_VISIBLE
+
+/datum/emote/living/carbon/annoyed/run_emote(mob/living/carbon/user, params, type_override, intentional)
+ . = ..()
+ if(!.)
+ return
+ var/image/emote_animation = image('monkestation/icons/mob/species/human/emote_visuals.dmi', user, "annoyed", pixel_x = 10, pixel_y = 10)
+ if(ishuman(user))
+ var/mob/living/carbon/human/human_user = user
+ emote_animation = human_user.apply_height_offsets(emote_animation, UPPER_BODY)
+ flick_overlay_global(emote_animation, GLOB.clients, 5 SECONDS)
+ // as this emote has no message, it won't play a sound due to the parent proc, so we play it manually here
+ playsound(user, 'monkestation/sound/effects/annoyed.ogg', vol = 50, vary = TRUE)
diff --git a/monkestation/code/modules/modular_computers/computers/item/role_tablet_presets.dm b/monkestation/code/modules/modular_computers/computers/item/role_tablet_presets.dm
index 8f87f22be7bb..5cc1dfa21fa4 100644
--- a/monkestation/code/modules/modular_computers/computers/item/role_tablet_presets.dm
+++ b/monkestation/code/modules/modular_computers/computers/item/role_tablet_presets.dm
@@ -56,3 +56,7 @@
name = "barber PDA"
greyscale_colors = "#933ea8#235AB2"
starting_programs = list()
+
+/obj/item/modular_computer/pda/heads/ntrep
+ name = "Nanotransen Representative's PDA"
+ inserted_item = /obj/item/pen/fountain
diff --git a/monkestation/code/modules/photography/photo/album.dm b/monkestation/code/modules/photography/photo/album.dm
new file mode 100644
index 000000000000..41cb2b8dad55
--- /dev/null
+++ b/monkestation/code/modules/photography/photo/album.dm
@@ -0,0 +1,9 @@
+/obj/item/storage/photo_album/blueshield
+ name = "photo album (Blueshield)"
+ icon_state = "album_blue"
+ persistence_id = "BS"
+
+/obj/item/storage/photo_album/nt_rep
+ name = "photo album (Nanotrasen Representative)"
+ icon_state = "album_blue"
+ persistence_id = "NTREP"
diff --git a/monkestation/code/modules/ranching/chickens/misc/gary.dm b/monkestation/code/modules/ranching/chickens/misc/gary.dm
index bf945c3fba38..3563ecf39585 100644
--- a/monkestation/code/modules/ranching/chickens/misc/gary.dm
+++ b/monkestation/code/modules/ranching/chickens/misc/gary.dm
@@ -125,12 +125,14 @@
return held_shinies
/mob/living/basic/chicken/gary/attackby(obj/item/attacking_item, mob/living/user)
- if(stat != CONSCIOUS || (user.istate & ISTATE_HARM) || !user.Adjacent(src))
+ if(stat != CONSCIOUS || (user.istate & ISTATE_HARM) || !user.Adjacent(src) || (attacking_item.item_flags & (ABSTRACT|DROPDEL|HAND_ITEM)))
return ..()
if(attacking_item.w_class <= max_w_class)
- if(held_item)
+ if(!QDELETED(held_item))
to_chat(user, span_warning("[src] is already holding [held_item]!"))
- return FALSE
+ return TRUE
+ if(!user.transferItemToLoc(attacking_item, src))
+ return TRUE
if(istype(attacking_item, /obj/item/knife))
attack_sound = 'sound/weapons/bladeslice.ogg'
melee_damage_upper = attacking_item.force //attack dmg inherits knife dmg
@@ -140,7 +142,7 @@
return TRUE
else
if(SEND_SIGNAL(src, COMSIG_FRIENDSHIP_CHECK_LEVEL, user, FRIENDSHIP_BESTFRIEND))
- var/barter_choice = show_radial_menu(user, src, hideout.stored_items)
+ var/barter_choice = show_radial_menu(user, src, hideout.stored_items, autopick_single_option = FALSE)
if(barter_choice)
ai_controller.blackboard[BB_GARY_BARTERING] = TRUE
ai_controller.blackboard[BB_GARY_BARTER_TARGET] = WEAKREF(user)
@@ -148,7 +150,6 @@
ai_controller.blackboard[BB_GARY_BARTER_STEP] = 1
held_item = attacking_item
- attacking_item.forceMove(src)
ai_controller.blackboard[BB_GARY_COME_HOME] = TRUE
ai_controller.blackboard[BB_GARY_HAS_SHINY] = TRUE
SEND_SIGNAL(src, COMSIG_MOB_ADJUST_HUNGER, 200) //gary hungers for trinkets and baubles.
diff --git a/monkestation/code/modules/vending/megaseed_wall.dm b/monkestation/code/modules/vending/megaseed_wall.dm
new file mode 100644
index 000000000000..9c6dfea69e39
--- /dev/null
+++ b/monkestation/code/modules/vending/megaseed_wall.dm
@@ -0,0 +1,10 @@
+/obj/machinery/vending/hydroseeds/wall
+ icon = 'monkestation/icons/obj/vending.dmi'
+ icon_state = "wallseeds"
+ icon_deny = "wallseeds-deny"
+ panel_type = "wallseeds-panel"
+ light_mask = "wallseeds-light-mask"
+ density = FALSE
+ tiltable = FALSE
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/vending/hydroseeds/wall, 32)
diff --git a/monkestation/code/modules/vending/nutrimax_wall.dm b/monkestation/code/modules/vending/nutrimax_wall.dm
new file mode 100644
index 000000000000..ec4f64a18376
--- /dev/null
+++ b/monkestation/code/modules/vending/nutrimax_wall.dm
@@ -0,0 +1,10 @@
+/obj/machinery/vending/hydronutrients/wall
+ icon = 'monkestation/icons/obj/vending.dmi'
+ icon_state = "wallnutri"
+ icon_deny = "wallnutri-deny"
+ panel_type = "wallnutri-panel"
+ light_mask = "wallnutri-light-mask"
+ density = FALSE
+ tiltable = FALSE
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/vending/hydronutrients/wall, 32)
diff --git a/monkestation/code/modules/virology/disease/symtoms/helpful/antitoxin.dm b/monkestation/code/modules/virology/disease/symtoms/helpful/antitoxin.dm
new file mode 100644
index 000000000000..efbac0ff287f
--- /dev/null
+++ b/monkestation/code/modules/virology/disease/symtoms/helpful/antitoxin.dm
@@ -0,0 +1,9 @@
+/datum/symptom/antitox
+ name = "Antioxidantisation Syndrome"
+ desc = "A very real syndrome beloved by Super-Food Fans and Essential Oil Enthusiasts; encourages the production of anti-toxin within the body."
+ stage = 2
+ badness = EFFECT_DANGER_HELPFUL
+
+/datum/symptom/antitox/activate(mob/living/mob)
+ to_chat(mob, span_notice("You feel your toxins being purged!"))
+ mob?.adjustToxLoss(-4)
diff --git a/monkestation/code/modules/virology/disease/symtoms/flavor/delightful.dm b/monkestation/code/modules/virology/disease/symtoms/helpful/delightful.dm
similarity index 92%
rename from monkestation/code/modules/virology/disease/symtoms/flavor/delightful.dm
rename to monkestation/code/modules/virology/disease/symtoms/helpful/delightful.dm
index 727a08da6c3d..f3419adf9560 100644
--- a/monkestation/code/modules/virology/disease/symtoms/flavor/delightful.dm
+++ b/monkestation/code/modules/virology/disease/symtoms/helpful/delightful.dm
@@ -2,7 +2,7 @@
name = "Delightful Effect"
desc = "A more powerful version of Full Glass. Makes the infected feel delightful."
stage = 4
- badness = EFFECT_DANGER_FLAVOR
+ badness = EFFECT_DANGER_HELPFUL
/datum/symptom/delightful/activate(mob/living/carbon/mob)
to_chat(mob, "You feel delightful!")
diff --git a/monkestation/code/modules/virology/disease/symtoms/flavor/invisible.dm b/monkestation/code/modules/virology/disease/symtoms/helpful/invisible.dm
similarity index 100%
rename from monkestation/code/modules/virology/disease/symtoms/flavor/invisible.dm
rename to monkestation/code/modules/virology/disease/symtoms/helpful/invisible.dm
diff --git a/monkestation/icons/mob/species/human/emote_visuals.dmi b/monkestation/icons/mob/species/human/emote_visuals.dmi
new file mode 100644
index 000000000000..4cdebf4e3de7
Binary files /dev/null and b/monkestation/icons/mob/species/human/emote_visuals.dmi differ
diff --git a/monkestation/icons/obj/vending.dmi b/monkestation/icons/obj/vending.dmi
new file mode 100644
index 000000000000..fa15f1df3b6c
Binary files /dev/null and b/monkestation/icons/obj/vending.dmi differ
diff --git a/monkestation/sound/effects/annoyed.ogg b/monkestation/sound/effects/annoyed.ogg
new file mode 100644
index 000000000000..d303a8815a1c
Binary files /dev/null and b/monkestation/sound/effects/annoyed.ogg differ
diff --git a/monkestation/sound/effects/sweatdrop.ogg b/monkestation/sound/effects/sweatdrop.ogg
new file mode 100644
index 000000000000..3c5a8ae80d12
Binary files /dev/null and b/monkestation/sound/effects/sweatdrop.ogg differ
diff --git a/strings/tips.txt b/strings/tips.txt
index 761b43d18a56..2810640ecea3 100644
--- a/strings/tips.txt
+++ b/strings/tips.txt
@@ -42,6 +42,7 @@ As a Geneticist, T goes to A, and G goes to C.
As a Ghost, you can both start and join capture the flag games through the minigames menu, or by clicking on one of the team spawners, which can be found under the "Misc" section of the orbit menu.
As a Ghost, you can double click on just about anything to follow it. Or just warp around!
As a Ghost, you can see the inside of a container on the ground by clicking on it.
+As a Heretic, you can locate an influence by dreaming about random objects around it when you sleep.
As a Janitor Cyborg, you are the bane of all slaughter demons and even Bubblegum himself. Cleaning up blood stains will severely gimp them.
As a Janitor, if someone steals your janicart, you can instead use your space cleaner spray, grenades, water sprayer, exact bloody revenge or order another from Cargo.
As a Janitor, mousetraps can be used to create bombs or booby-trap containers.
diff --git a/tgstation.dme b/tgstation.dme
index 3e0ad3749d93..a5b60547bd75 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -5999,9 +5999,11 @@
#include "monkestation\code\datums\mutations\chameleon.dm"
#include "monkestation\code\datums\quirks\_quirk.dm"
#include "monkestation\code\datums\quirks\negative_quirks\allergic.dm"
+#include "monkestation\code\datums\quirks\negative_quirks\clown_disbelief.dm"
#include "monkestation\code\datums\quirks\negative_quirks\dnr.dm"
#include "monkestation\code\datums\quirks\negative_quirks\feeble.dm"
#include "monkestation\code\datums\quirks\negative_quirks\frail.dm"
+#include "monkestation\code\datums\quirks\negative_quirks\insanity.dm"
#include "monkestation\code\datums\quirks\negative_quirks\kleptomaniac.dm"
#include "monkestation\code\datums\quirks\negative_quirks\light_drinker.dm"
#include "monkestation\code\datums\quirks\negative_quirks\monophobia.dm"
@@ -6011,7 +6013,6 @@
#include "monkestation\code\datums\quirks\negative_quirks\tunnel_vision.dm"
#include "monkestation\code\datums\quirks\negative_quirks\unstable_ass.dm"
#include "monkestation\code\datums\quirks\neutral_quirks\anime.dm"
-#include "monkestation\code\datums\quirks\neutral_quirks\clown_disbelief.dm"
#include "monkestation\code\datums\quirks\neutral_quirks\drg_callout.dm"
#include "monkestation\code\datums\quirks\neutral_quirks\gigantism.dm"
#include "monkestation\code\datums\quirks\neutral_quirks\jailbird.dm"
@@ -6164,6 +6165,7 @@
#include "monkestation\code\game\objects\items\storage\crate.dm"
#include "monkestation\code\game\objects\items\storage\fancy.dm"
#include "monkestation\code\game\objects\items\storage\garment.dm"
+#include "monkestation\code\game\objects\items\storage\medkit.dm"
#include "monkestation\code\game\objects\items\storage\toolbox.dm"
#include "monkestation\code\game\objects\items\storage\uplink_kits.dm"
#include "monkestation\code\game\objects\items\storage\boxes\boxes.dm"
@@ -6177,7 +6179,9 @@
#include "monkestation\code\game\objects\structures\beds_chairs\chair.dm"
#include "monkestation\code\game\objects\structures\crates_lockers\closets.dm"
#include "monkestation\code\game\objects\structures\crates_lockers\crates.dm"
+#include "monkestation\code\game\objects\structures\crates_lockers\closets\secure\blueshield.dm"
#include "monkestation\code\game\objects\structures\crates_lockers\closets\secure\brig_physician.dm"
+#include "monkestation\code\game\objects\structures\crates_lockers\closets\secure\nanotrasen_rep.dm"
#include "monkestation\code\game\objects\structures\crates_lockers\closets\secure\security.dm"
#include "monkestation\code\game\objects\structures\crates_lockers\crates\secure.dm"
#include "monkestation\code\game\turfs\open\water.dm"
@@ -6707,7 +6711,6 @@
#include "monkestation\code\modules\blueshield\clothing.dm"
#include "monkestation\code\modules\blueshield\gun.dm"
#include "monkestation\code\modules\blueshield\landmarks.dm"
-#include "monkestation\code\modules\blueshield\trim.dm"
#include "monkestation\code\modules\blueshield\devices\crew_monitor.dm"
#include "monkestation\code\modules\blueshield\devices\sensor.dm"
#include "monkestation\code\modules\blueshield\modsuit\suit.dm"
@@ -7381,7 +7384,6 @@
#include "monkestation\code\modules\ghost_players\job_helpers\injured_spawner.dm"
#include "monkestation\code\modules\ghost_players\job_helpers\organ_printer.dm"
#include "monkestation\code\modules\goonimizations\goon_keybinds.dm"
-#include "monkestation\code\modules\guns\laser.dm"
#include "monkestation\code\modules\holomaps\areas.dm"
#include "monkestation\code\modules\holomaps\base_datum.dm"
#include "monkestation\code\modules\holomaps\huds.dm"
@@ -7420,6 +7422,7 @@
#include "monkestation\code\modules\jobs\job_types\godzilla.dm"
#include "monkestation\code\modules\jobs\job_types\gorilla.dm"
#include "monkestation\code\modules\jobs\job_types\head_of_security.dm"
+#include "monkestation\code\modules\jobs\job_types\nanotrasen_representative.dm"
#include "monkestation\code\modules\jobs\job_types\psychologist.dm"
#include "monkestation\code\modules\jobs\job_types\security_assistant.dm"
#include "monkestation\code\modules\jobs\job_types\shaft_miner.dm"
@@ -7428,6 +7431,7 @@
#include "monkestation\code\modules\jobs\job_types\virologist.dm"
#include "monkestation\code\modules\jobs\job_types\yellowclown.dm"
#include "monkestation\code\modules\jobs\job_types\spawner\bar_drone.dm"
+#include "monkestation\code\modules\language\language_holder.dm"
#include "monkestation\code\modules\library\bookcase.dm"
#include "monkestation\code\modules\library\skill_learning\job_skillchips\shaft_miner.dm"
#include "monkestation\code\modules\liquids\drains.dm"
@@ -7772,9 +7776,6 @@
#include "monkestation\code\modules\modular_guns\components\gun_stat_modifiers.dm"
#include "monkestation\code\modules\modular_guns\crafting\part_recipes.dm"
#include "monkestation\code\modules\modular_guns\makeshift_effects\__base_effect.dm"
-#include "monkestation\code\modules\NTrep\NTrep.dm"
-#include "monkestation\code\modules\NTrep\NTrep_locker.dm"
-#include "monkestation\code\modules\NTrep\NTrep_spawn.dm"
#include "monkestation\code\modules\NTrep\clothing\NTrep_clothing.dm"
#include "monkestation\code\modules\NTrep\coolgun\plasmacore.dm"
#include "monkestation\code\modules\NTSL\code\achievements.dm"
@@ -7852,6 +7853,7 @@
#include "monkestation\code\modules\paperwork\fax.dm"
#include "monkestation\code\modules\paperwork\filingcabinet.dm"
#include "monkestation\code\modules\patches_if_they_were_cool\_base_patch_changes.dm"
+#include "monkestation\code\modules\photography\photo\album.dm"
#include "monkestation\code\modules\physics\atom_movables.dm"
#include "monkestation\code\modules\physics\physics_component.dm"
#include "monkestation\code\modules\physics\physics_SS.dm"
@@ -8393,6 +8395,8 @@
#include "monkestation\code\modules\vehicles\mecha\mecha_actions.dm"
#include "monkestation\code\modules\vehicles\mecha\equipment\tools\other_tools.dm"
#include "monkestation\code\modules\vending\megaseed.dm"
+#include "monkestation\code\modules\vending\megaseed_wall.dm"
+#include "monkestation\code\modules\vending\nutrimax_wall.dm"
#include "monkestation\code\modules\veth_misc_items\admin_fixes\check_players.dm"
#include "monkestation\code\modules\veth_misc_items\admin_vox\admin_vox.dm"
#include "monkestation\code\modules\veth_misc_items\canopics\canopics.dm"
@@ -8451,7 +8455,6 @@
#include "monkestation\code\modules\virology\disease\symtoms\deadly\magnitis.dm"
#include "monkestation\code\modules\virology\disease\symtoms\deadly\rhumba_beat.dm"
#include "monkestation\code\modules\virology\disease\symtoms\flavor\beard.dm"
-#include "monkestation\code\modules\virology\disease\symtoms\flavor\delightful.dm"
#include "monkestation\code\modules\virology\disease\symtoms\flavor\disfigured.dm"
#include "monkestation\code\modules\virology\disease\symtoms\flavor\drained.dm"
#include "monkestation\code\modules\virology\disease\symtoms\flavor\drolling.dm"
@@ -8463,7 +8466,6 @@
#include "monkestation\code\modules\virology\disease\symtoms\flavor\gunk.dm"
#include "monkestation\code\modules\virology\disease\symtoms\flavor\hair_growth.dm"
#include "monkestation\code\modules\virology\disease\symtoms\flavor\headache.dm"
-#include "monkestation\code\modules\virology\disease\symtoms\flavor\invisible.dm"
#include "monkestation\code\modules\virology\disease\symtoms\flavor\mommi_shrink.dm"
#include "monkestation\code\modules\virology\disease\symtoms\flavor\polyvitiligo.dm"
#include "monkestation\code\modules\virology\disease\symtoms\flavor\soreness.dm"
@@ -8483,9 +8485,12 @@
#include "monkestation\code\modules\virology\disease\symtoms\harmful\teratoma.dm"
#include "monkestation\code\modules\virology\disease\symtoms\harmful\toxins.dm"
#include "monkestation\code\modules\virology\disease\symtoms\harmful\wizarditis.dm"
+#include "monkestation\code\modules\virology\disease\symtoms\helpful\antitoxin.dm"
#include "monkestation\code\modules\virology\disease\symtoms\helpful\coma.dm"
#include "monkestation\code\modules\virology\disease\symtoms\helpful\damge_to_toxin.dm"
#include "monkestation\code\modules\virology\disease\symtoms\helpful\darkness.dm"
+#include "monkestation\code\modules\virology\disease\symtoms\helpful\delightful.dm"
+#include "monkestation\code\modules\virology\disease\symtoms\helpful\invisible.dm"
#include "monkestation\code\modules\virology\disease\symtoms\helpful\lantern.dm"
#include "monkestation\code\modules\virology\disease\symtoms\helpful\longevity.dm"
#include "monkestation\code\modules\virology\disease\symtoms\helpful\metabolism_boost.dm"
diff --git a/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx b/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx
index 38e3e40897bf..3f9b9c16ba65 100644
--- a/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx
+++ b/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx
@@ -137,7 +137,8 @@ const GuideSection = () => {
around the station invisible to the normal eye and
right click on them to harvest them for
knowledge points. Tapping them makes
- them visible to all after a short time.
+ them visible to all after a short time. Dreaming of Mansus may help to
+ find them.
- Use your
diff --git a/tgui/packages/tgui/interfaces/CrewConsoleNova.tsx b/tgui/packages/tgui/interfaces/CrewConsoleNova.tsx
index 584561d85480..a1964f1f25e6 100644
--- a/tgui/packages/tgui/interfaces/CrewConsoleNova.tsx
+++ b/tgui/packages/tgui/interfaces/CrewConsoleNova.tsx
@@ -52,7 +52,7 @@ export const jobToColor = (jobId) => {
if (jobId >= 50 && jobId < 60) {
return COLORS.department.cargo;
}
- if (jobId >= 60 && jobId < 80) {
+ if (jobId >= 60 && jobId < 200) {
return COLORS.department.service;
}
if (jobId >= 200 && jobId < 240) {
diff --git a/tgui/packages/tgui/interfaces/PaiSubmit.tsx b/tgui/packages/tgui/interfaces/PaiSubmit.tsx
index ca72f584b83f..6a2474593a50 100644
--- a/tgui/packages/tgui/interfaces/PaiSubmit.tsx
+++ b/tgui/packages/tgui/interfaces/PaiSubmit.tsx
@@ -145,6 +145,14 @@ const ButtonsDisplay = (props) => {
SUBMIT
+
+
+
);