diff --git a/_maps/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/RandomRuins/SpaceRuins/oldstation.dmm
index 20f1d530ec3..94738b9eac0 100644
--- a/_maps/RandomRuins/SpaceRuins/oldstation.dmm
+++ b/_maps/RandomRuins/SpaceRuins/oldstation.dmm
@@ -153,12 +153,6 @@
/obj/structure/alien/egg/burst,
/turf/open/floor/iron/dark,
/area/ruin/space/ancientstation/delta/ai)
-"aQ" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/table,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron,
-/area/ruin/space/ancientstation/charlie/bridge)
"aS" = (
/obj/structure/sign/poster/official/nanotrasen_logo,
/turf/closed/wall,
@@ -2461,15 +2455,6 @@
/obj/structure/sign/poster/official/work_for_a_future,
/turf/closed/wall/rust,
/area/ruin/space/ancientstation/charlie/dorms)
-"kN" = (
-/obj/structure/table,
-/obj/item/crowbar,
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/light/small/directional/west,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/spawner/random/decoration/glowstick,
-/turf/open/floor/iron,
-/area/ruin/space/ancientstation/charlie/dorms)
"kO" = (
/obj/effect/turf_decal/stripes/line{
dir = 9
@@ -3878,6 +3863,16 @@
/obj/structure/chair,
/turf/open/floor/iron/white/textured,
/area/ruin/space/ancientstation/delta/proto)
+"sq" = (
+/obj/structure/table,
+/obj/item/crowbar,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/decoration/glowstick,
+/obj/structure/mirror/directional/west,
+/obj/item/clothing/neck/link_scryer/loaded/charlie,
+/turf/open/floor/iron,
+/area/ruin/space/ancientstation/charlie/dorms)
"ss" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
@@ -4744,6 +4739,16 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/ruin/space/ancientstation/delta/rnd)
+"yN" = (
+/obj/structure/table,
+/obj/item/crowbar,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/light/small/directional/west,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/spawner/random/decoration/glowstick,
+/obj/item/clothing/neck/link_scryer/loaded/charlie,
+/turf/open/floor/iron,
+/area/ruin/space/ancientstation/charlie/dorms)
"yQ" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/window/plasma/spawner/directional/south,
@@ -5472,6 +5477,14 @@
/obj/effect/mapping_helpers/airalarm/away_general_access,
/turf/open/floor/iron,
/area/ruin/space/ancientstation/beta/hall)
+"Ej" = (
+/obj/machinery/light/small/directional/south,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/storage/box/lights/mixed,
+/turf/open/floor/plating{
+ initial_gas_mix = "co2=6;o2=16;n2=82;TEMP=293.15"
+ },
+/area/ruin/space/ancientstation/delta/hall)
"El" = (
/obj/effect/decal/cleanable/dirt,
/obj/item/shard,
@@ -6697,15 +6710,6 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
/area/ruin/space/ancientstation/beta/supermatter)
-"Mt" = (
-/obj/structure/table,
-/obj/item/crowbar,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/spawner/random/decoration/glowstick,
-/obj/structure/mirror/directional/west,
-/turf/open/floor/iron,
-/area/ruin/space/ancientstation/charlie/dorms)
"Mu" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/space_heater,
@@ -8116,6 +8120,13 @@
/obj/effect/decal/cleanable/glass,
/turf/open/floor/engine/airless,
/area/ruin/space/ancientstation/beta/supermatter)
+"Xf" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/table,
+/obj/effect/decal/cleanable/dirt,
+/obj/item/clothing/neck/link_scryer/loaded/charlie,
+/turf/open/floor/iron,
+/area/ruin/space/ancientstation/charlie/bridge)
"Xj" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
@@ -8459,14 +8470,6 @@
/obj/machinery/light/small/broken/directional/east,
/turf/open/floor/iron/dark,
/area/ruin/space/ancientstation/delta/ai)
-"YV" = (
-/obj/machinery/light/small/directional/south,
-/obj/effect/decal/cleanable/dirt,
-/obj/item/storage/box/lights/mixed,
-/turf/open/floor/plating{
- initial_gas_mix = "co2=6;o2=16;n2=82;TEMP=293.15"
- },
-/area/ruin/space/ancientstation/delta/hall)
"YW" = (
/turf/open/floor/iron/textured_half,
/area/ruin/space/ancientstation/beta/supermatter)
@@ -12217,8 +12220,8 @@ aG
nk
mz
gZ
-kN
-Mt
+yN
+sq
mz
nk
nk
@@ -12254,7 +12257,7 @@ aa
aS
wl
bg
-aQ
+Xf
aI
ba
bk
@@ -12652,7 +12655,7 @@ AA
ax
aW
aI
-aQ
+Xf
bm
qr
aS
@@ -13851,7 +13854,7 @@ Gz
Lx
LH
Bu
-YV
+Ej
Gz
JR
Gz
diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm
index 6c90502b936..f259824cd29 100644
--- a/_maps/map_files/Birdshot/birdshot.dmm
+++ b/_maps/map_files/Birdshot/birdshot.dmm
@@ -674,6 +674,14 @@
/obj/structure/marker_beacon/jade,
/turf/open/space/basic,
/area/space/nearstation)
+"ans" = (
+/obj/structure/cable,
+/obj/machinery/firealarm/directional/east,
+/obj/effect/turf_decal/siding/corner{
+ dir = 4
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"anv" = (
/obj/structure/lattice/catwalk,
/obj/structure/railing/corner{
@@ -990,6 +998,10 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron,
/area/station/engineering/atmos/storage/gas)
+"auC" = (
+/obj/machinery/hydroponics/soil,
+/turf/open/misc/sandy_dirt,
+/area/station/science/cytology)
"auG" = (
/obj/structure/chair{
dir = 1
@@ -2242,14 +2254,6 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron/dark,
/area/station/engineering/supermatter/room)
-"aUm" = (
-/obj/structure/cable,
-/obj/machinery/firealarm/directional/east,
-/obj/effect/turf_decal/siding/corner{
- dir = 4
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"aUA" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark/smooth_edge,
@@ -7555,15 +7559,6 @@
},
/turf/open/floor/iron/dark/corner,
/area/station/engineering/break_room)
-"cYD" = (
-/obj/item/kirbyplants/random,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/structure/closet/crate/trashcart/filled,
-/turf/open/floor/iron,
-/area/station/hallway/secondary/recreation)
"cYE" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -7614,10 +7609,6 @@
/obj/machinery/firealarm/directional/north,
/turf/open/floor/iron/dark,
/area/station/engineering/main)
-"cZN" = (
-/obj/effect/turf_decal/siding,
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"dah" = (
/obj/structure/disposalpipe/segment,
/obj/effect/turf_decal/tile/dark_red/half/contrasted{
@@ -9230,10 +9221,6 @@
},
/turf/open/floor/iron/smooth,
/area/station/engineering/atmos)
-"dEU" = (
-/obj/machinery/hydroponics/soil,
-/turf/open/misc/sandy_dirt,
-/area/station/science/cytology)
"dFn" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -9530,6 +9517,11 @@
/obj/structure/sign/poster/official/random/directional/north,
/turf/open/floor/iron,
/area/station/engineering/break_room)
+"dLm" = (
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/closet/crate/mod,
+/turf/open/floor/iron/white,
+/area/station/science/robotics/augments)
"dLn" = (
/obj/structure/chair/office,
/turf/open/floor/iron/dark/herringbone,
@@ -18867,16 +18859,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
/area/station/maintenance/starboard/greater)
-"gYr" = (
-/obj/structure/table/glass,
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/airalarm/directional/north,
-/obj/item/food/pizzaslice/moldy/bacteria{
- pixel_x = -4;
- pixel_y = 2
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"gYy" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -20505,12 +20487,6 @@
"hzm" = (
/turf/closed/wall/rust,
/area/station/cargo/miningoffice)
-"hzq" = (
-/obj/structure/disposalpipe/segment,
-/obj/machinery/airalarm/directional/west,
-/obj/effect/spawner/random/trash/moisture_trap,
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"hzI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -20840,12 +20816,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/smooth,
/area/station/hallway/secondary/command)
-"hFs" = (
-/obj/structure/cable,
-/obj/machinery/holopad,
-/obj/effect/turf_decal/siding/corner,
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"hFx" = (
/turf/open/floor/iron/chapel{
dir = 1
@@ -24202,10 +24172,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/fore/lesser)
-"iRH" = (
-/obj/structure/closet/crate/trashcart/filled,
-/turf/open/floor/plating,
-/area/station/maintenance/starboard/fore)
"iSb" = (
/obj/structure/frame/computer{
dir = 1
@@ -25063,22 +25029,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/textured_half,
/area/station/hallway/primary/aft)
-"jif" = (
-/obj/item/mod/core/standard{
- pixel_x = -4
- },
-/obj/item/mod/core/standard{
- pixel_x = 4
- },
-/obj/item/mod/core/standard{
- pixel_y = 4
- },
-/obj/structure/closet/crate/science{
- name = "MOD core crate"
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/white,
-/area/station/science/robotics/augments)
"jig" = (
/obj/effect/turf_decal/stripes/white/line{
dir = 9
@@ -30720,18 +30670,6 @@
},
/turf/open/space/basic,
/area/space/nearstation)
-"lgh" = (
-/obj/effect/turf_decal/box/corners{
- dir = 4
- },
-/obj/effect/turf_decal/box/corners{
- dir = 1
- },
-/obj/machinery/plumbing/growing_vat{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/station/science/cytology)
"lgj" = (
/obj/structure/chair/sofa/bench{
dir = 8
@@ -35962,6 +35900,10 @@
/obj/machinery/airalarm/directional/west,
/turf/open/floor/iron,
/area/station/security/processing)
+"mXd" = (
+/obj/structure/closet/crate/trashcart/filled,
+/turf/open/floor/plating,
+/area/station/maintenance/starboard/fore)
"mXo" = (
/obj/machinery/atmospherics/pipe/smart/manifold/general/visible{
dir = 1
@@ -38696,6 +38638,16 @@
/obj/machinery/camera/autoname/directional/north,
/turf/open/floor/iron/white,
/area/station/science/cytology)
+"nXe" = (
+/obj/structure/table/glass,
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/airalarm/directional/north,
+/obj/item/food/pizzaslice/moldy/bacteria{
+ pixel_x = -4;
+ pixel_y = 2
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"nXt" = (
/obj/effect/turf_decal/tile/yellow/full,
/obj/structure/table/reinforced,
@@ -38713,6 +38665,15 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/showroomfloor,
/area/station/commons/toilet/restrooms)
+"nXE" = (
+/obj/structure/disposalpipe/segment{
+ dir = 6
+ },
+/obj/effect/decal/cleanable/cobweb,
+/obj/item/radio/intercom/directional/north,
+/obj/item/kirbyplants/fern,
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"nXP" = (
/obj/machinery/airalarm/directional/east,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -40041,6 +40002,16 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/atmos)
+"oyz" = (
+/obj/effect/turf_decal/box/corners,
+/obj/effect/turf_decal/box/corners{
+ dir = 8
+ },
+/obj/machinery/plumbing/input{
+ dir = 8
+ },
+/turf/open/floor/engine,
+/area/station/science/cytology)
"oyA" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -40983,6 +40954,13 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/commons/storage/tools)
+"oRd" = (
+/obj/structure/cable,
+/obj/effect/turf_decal/siding{
+ dir = 4
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"oRm" = (
/obj/effect/landmark/atmospheric_sanity/ignore_area,
/turf/closed/mineral/random/stationside,
@@ -42925,16 +42903,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/security/tram)
-"pzK" = (
-/obj/effect/turf_decal/box/corners,
-/obj/effect/turf_decal/box/corners{
- dir = 8
- },
-/obj/machinery/plumbing/input{
- dir = 8
- },
-/turf/open/floor/engine,
-/area/station/science/cytology)
"pzL" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window/reinforced,
@@ -43622,6 +43590,12 @@
/obj/effect/turf_decal/delivery/red,
/turf/open/floor/iron/white/small,
/area/station/medical/medbay/central)
+"pKL" = (
+/obj/structure/disposalpipe/segment,
+/obj/machinery/airalarm/directional/west,
+/obj/effect/spawner/random/trash/moisture_trap,
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"pKR" = (
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
dir = 4
@@ -48017,6 +47991,18 @@
/obj/structure/barricade/wooden/crude,
/turf/open/floor/plating,
/area/station/maintenance/hallway/abandoned_recreation)
+"rdk" = (
+/obj/effect/turf_decal/box/corners{
+ dir = 4
+ },
+/obj/effect/turf_decal/box/corners{
+ dir = 1
+ },
+/obj/machinery/plumbing/growing_vat{
+ dir = 4
+ },
+/turf/open/floor/engine,
+/area/station/science/cytology)
"rdo" = (
/obj/structure/window/spawner/directional/west,
/obj/structure/flora/bush/jungle/a/style_random,
@@ -49299,6 +49285,15 @@
/obj/machinery/light/floor,
/turf/open/floor/wood/large,
/area/station/service/hydroponics/garden/monastery)
+"rzC" = (
+/obj/item/kirbyplants/random,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/structure/closet/crate/trashcart/filled,
+/turf/open/floor/iron,
+/area/station/hallway/secondary/recreation)
"rzG" = (
/obj/structure/disposalpipe/segment,
/obj/effect/turf_decal/tile/dark_red/half/contrasted{
@@ -63882,6 +63877,12 @@
/obj/effect/spawner/structure/window/reinforced/tinted,
/turf/open/floor/plating,
/area/station/hallway/secondary/recreation)
+"wkJ" = (
+/obj/structure/cable,
+/obj/machinery/holopad,
+/obj/effect/turf_decal/siding/corner,
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"wla" = (
/turf/open/floor/iron/chapel,
/area/station/maintenance/starboard/greater)
@@ -65546,15 +65547,6 @@
/obj/machinery/power/apc/auto_name/directional/north,
/turf/open/floor/iron/dark,
/area/station/medical/medbay/lobby)
-"wLS" = (
-/obj/structure/disposalpipe/segment{
- dir = 6
- },
-/obj/effect/decal/cleanable/cobweb,
-/obj/item/radio/intercom/directional/north,
-/obj/item/kirbyplants/fern,
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"wLZ" = (
/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
/obj/effect/decal/cleanable/dirt,
@@ -65882,6 +65874,10 @@
},
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
+"wQL" = (
+/obj/effect/turf_decal/siding,
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"wQP" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -68834,13 +68830,6 @@
"xFe" = (
/turf/closed/wall,
/area/station/security/lockers)
-"xFk" = (
-/obj/structure/cable,
-/obj/effect/turf_decal/siding{
- dir = 4
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"xFw" = (
/obj/effect/turf_decal/tile/dark_red/opposingcorners,
/obj/structure/chair/sofa/bench{
@@ -112068,7 +112057,7 @@ yjK
xpE
xMT
xQJ
-cYD
+rzC
qrR
sid
xbg
@@ -113352,7 +113341,7 @@ mjf
mFh
noB
xQJ
-gYr
+nXe
ovg
rRU
wBI
@@ -113866,12 +113855,12 @@ mjF
mGp
vUz
qNn
-wLS
+nXE
owm
sXi
bfe
sXi
-hzq
+pKL
mEL
vbK
sfq
@@ -114890,14 +114879,14 @@ kNI
xXT
oOv
vwd
-iRH
+mXd
xau
rsL
qhh
ghC
-hFs
-xFk
-aUm
+wkJ
+oRd
+ans
xfu
xbT
snJ
@@ -115152,8 +115141,8 @@ xau
rsL
xSe
miz
-cZN
-dEU
+wQL
+auC
wJL
ppQ
tTp
@@ -115665,8 +115654,8 @@ rsL
mIh
rsL
xTO
-lgh
-pzK
+rdk
+oyz
xPj
wJL
sHX
@@ -116214,7 +116203,7 @@ eQn
vnf
wML
rrt
-jif
+dLm
ryy
boW
sYa
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 5e73a0680f5..f795d1a2931 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -9785,17 +9785,6 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos/hfr_room)
-"cqZ" = (
-/obj/machinery/status_display/evac/directional/west,
-/obj/effect/turf_decal/stripes/line{
- dir = 9
- },
-/obj/effect/turf_decal/tile/purple{
- dir = 1
- },
-/obj/machinery/hydroponics/constructable,
-/turf/open/floor/iron/white,
-/area/station/science/xenobiology)
"crd" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -49415,6 +49404,18 @@
/obj/machinery/holopad,
/turf/open/floor/iron/large,
/area/station/security/checkpoint/medical/medsci)
+"mqA" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/requests_console/directional/north{
+ department = "Robotics";
+ name = "Robotics Requests Console"
+ },
+/obj/effect/mapping_helpers/requests_console/ore_update,
+/obj/effect/mapping_helpers/requests_console/supplies,
+/obj/machinery/light/cold/directional/north,
+/obj/structure/closet/crate/mod,
+/turf/open/floor/iron,
+/area/station/science/robotics/lab)
"mqG" = (
/obj/structure/filingcabinet/medical,
/obj/effect/turf_decal/bot,
@@ -83267,6 +83268,17 @@
/obj/item/clothing/head/costume/cardborg,
/turf/open/floor/wood,
/area/station/service/theater/abandoned)
+"uOF" = (
+/obj/machinery/status_display/evac/directional/west,
+/obj/effect/turf_decal/stripes/line{
+ dir = 9
+ },
+/obj/effect/turf_decal/tile/purple{
+ dir = 1
+ },
+/obj/machinery/hydroponics/constructable,
+/turf/open/floor/iron/white,
+/area/station/science/xenobiology)
"uOH" = (
/obj/effect/spawner/random/trash/caution_sign,
/turf/open/floor/plating,
@@ -87773,29 +87785,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/ai_upload)
-"vWV" = (
-/obj/structure/closet/crate/science{
- anchored = 1
- },
-/obj/item/mod/core/standard{
- pixel_x = -4
- },
-/obj/item/mod/core/standard{
- pixel_x = 4
- },
-/obj/item/mod/core/standard{
- pixel_y = 4
- },
-/obj/effect/turf_decal/bot,
-/obj/machinery/requests_console/directional/north{
- department = "Robotics";
- name = "Robotics Requests Console"
- },
-/obj/effect/mapping_helpers/requests_console/ore_update,
-/obj/effect/mapping_helpers/requests_console/supplies,
-/obj/machinery/light/cold/directional/north,
-/turf/open/floor/iron,
-/area/station/science/robotics/lab)
"vXh" = (
/obj/structure/chair/stool/directional/north,
/obj/effect/turf_decal/tile/red/diagonal_centre,
@@ -121356,7 +121345,7 @@ eRr
pTC
sXy
fpt
-cqZ
+uOF
sPk
fBQ
tVl
@@ -129048,7 +129037,7 @@ wdb
wdb
muk
khb
-vWV
+mqA
aPz
fHr
cfO
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index 02fcad19844..8525ffb9718 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -23741,6 +23741,11 @@
/obj/structure/chair/stool/bar/directional/east,
/turf/open/floor/stone,
/area/station/commons/lounge)
+"hzV" = (
+/obj/structure/lattice/catwalk,
+/obj/machinery/smartfridge/petri/preloaded,
+/turf/open/openspace,
+/area/station/science/xenobiology)
"hzY" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -33849,22 +33854,6 @@
/obj/effect/turf_decal/tile/yellow/half/contrasted,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
-"kKI" = (
-/obj/item/mod/core/standard{
- pixel_x = -4
- },
-/obj/item/mod/core/standard{
- pixel_x = 4
- },
-/obj/item/mod/core/standard{
- pixel_y = 4
- },
-/obj/structure/table,
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 1
- },
-/turf/open/floor/iron/white,
-/area/station/science/robotics/lab)
"kKL" = (
/turf/closed/wall,
/area/station/maintenance/starboard/fore)
@@ -34973,6 +34962,13 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/department/electrical)
+"lcj" = (
+/obj/effect/turf_decal/tile/red/half/contrasted{
+ dir = 1
+ },
+/obj/structure/closet/crate/mod,
+/turf/open/floor/iron/white,
+/area/station/science/robotics/lab)
"lck" = (
/obj/machinery/gateway/centerstation,
/turf/open/floor/iron/dark/smooth_large,
@@ -43672,11 +43668,6 @@
/obj/effect/turf_decal/siding/yellow,
/turf/open/floor/iron,
/area/station/engineering/atmos)
-"nSh" = (
-/obj/structure/lattice/catwalk,
-/obj/machinery/smartfridge/petri/preloaded,
-/turf/open/openspace,
-/area/station/science/xenobiology)
"nSk" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -250596,7 +250587,7 @@ bCL
ofr
sBx
hfc
-nSh
+hzV
adY
tmR
sZF
@@ -252094,7 +252085,7 @@ rNQ
lso
aop
yar
-kKI
+lcj
rIU
rCX
lWc
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 6cdbc99eb49..3beea5b99cc 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -282,6 +282,35 @@
/obj/structure/window/spawner/directional/north,
/turf/open/floor/iron/dark,
/area/station/engineering/atmos)
+"agN" = (
+/obj/structure/table/glass,
+/obj/item/radio/intercom/directional/west,
+/obj/machinery/camera/directional/west{
+ c_tag = "Xenobiology Lab - Fore";
+ network = list("ss13","rd","xeno")
+ },
+/obj/machinery/light/directional/west,
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/purple/half/contrasted{
+ dir = 8
+ },
+/obj/item/reagent_containers/cup/beaker/large{
+ pixel_x = -6;
+ pixel_y = 22
+ },
+/obj/item/reagent_containers/cup/beaker{
+ pixel_x = 4;
+ pixel_y = 17
+ },
+/obj/item/food/tofu{
+ pixel_y = 6
+ },
+/obj/item/food/tofu,
+/obj/item/food/tofu{
+ pixel_y = -6
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"agQ" = (
/obj/structure/table/reinforced,
/obj/machinery/door/window/left/directional/west{
@@ -2385,13 +2414,6 @@
},
/turf/open/floor/plating,
/area/station/cargo/storage)
-"aTh" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/structure/window/reinforced/spawner/directional/south,
-/turf/open/floor/iron/dark/textured_large,
-/area/station/science/cytology)
"aTi" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -3296,13 +3318,6 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
-"biD" = (
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/machinery/plumbing/input{
- dir = 8
- },
-/turf/open/floor/iron/dark/textured_large,
-/area/station/science/cytology)
"biF" = (
/obj/structure/window/spawner/directional/north,
/turf/open/floor/iron/dark,
@@ -3792,6 +3807,18 @@
/obj/item/clothing/mask/cigarette/pipe,
/turf/open/floor/wood,
/area/station/commons/lounge)
+"bqJ" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/turf_decal/siding/purple/corner{
+ dir = 4
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"bqX" = (
/turf/closed/wall/r_wall,
/area/station/medical/chemistry)
@@ -4203,14 +4230,6 @@
/obj/effect/turf_decal/tile/yellow/half/contrasted,
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
-"bxF" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/structure/table/glass,
-/obj/structure/microscope,
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"bxX" = (
/obj/structure/flora/bush/ferny/style_random,
/obj/structure/flora/bush/fullgrass/style_random,
@@ -5066,6 +5085,19 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
/area/station/maintenance/port/aft)
+"bOL" = (
+/obj/machinery/button/door/directional/south{
+ id = "roboticsprivacy2";
+ name = "Robotics Privacy Control";
+ req_access = list("robotics")
+ },
+/obj/structure/closet/crate/mod,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark,
+/area/station/science/robotics/lab)
"bPa" = (
/obj/machinery/computer/security/qm{
dir = 4
@@ -5553,6 +5585,21 @@
/obj/machinery/atmospherics/components/trinary/filter,
/turf/open/floor/plating,
/area/station/maintenance/starboard/greater)
+"bXs" = (
+/obj/structure/table/glass,
+/obj/item/stack/sheet/mineral/plasma{
+ pixel_y = 4
+ },
+/obj/item/reagent_containers/dropper{
+ pixel_y = -4
+ },
+/obj/structure/cable,
+/obj/machinery/light_switch/directional/west,
+/obj/effect/turf_decal/tile/purple/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"bXO" = (
/turf/closed/indestructible/riveted{
desc = "A wall impregnated with Fixium, able to withstand massive explosions with ease";
@@ -6882,15 +6929,6 @@
/obj/effect/mapping_helpers/airlock/access/all/medical/general,
/turf/open/floor/iron/white,
/area/station/medical/abandoned)
-"czf" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/machinery/plumbing/growing_vat{
- dir = 4
- },
-/turf/open/floor/iron/dark/textured_large,
-/area/station/science/cytology)
"czs" = (
/obj/structure/easel,
/obj/effect/mapping_helpers/broken_floor,
@@ -7517,16 +7555,6 @@
/obj/effect/turf_decal/tile/brown/anticorner/contrasted,
/turf/open/floor/iron,
/area/station/cargo/sorting)
-"cOM" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/machinery/camera/directional/west{
- c_tag = "Cytology Lab - Worklab";
- network = list("ss13","rd","xeno")
- },
-/turf/open/floor/iron/dark/textured_large,
-/area/station/science/cytology)
"cON" = (
/obj/structure/table,
/obj/item/pai_card,
@@ -7981,23 +8009,6 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron,
/area/station/science/robotics/mechbay)
-"cXl" = (
-/obj/machinery/door_buttons/access_button{
- idDoor = "xeno_airlock_interior";
- idSelf = "xeno_airlock_control";
- name = "Access Button";
- pixel_x = 29;
- pixel_y = -8;
- req_access = list("xenobiology")
- },
-/obj/machinery/firealarm/directional/north,
-/obj/effect/turf_decal/stripes/line{
- dir = 5
- },
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
-/obj/item/soap,
-/turf/open/floor/iron/white,
-/area/station/science/xenobiology/hallway)
"cXw" = (
/obj/machinery/holopad,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -8364,30 +8375,6 @@
/obj/machinery/vending/wardrobe/law_wardrobe,
/turf/open/floor/wood,
/area/station/service/lawoffice)
-"deH" = (
-/obj/machinery/button/door/directional/south{
- id = "roboticsprivacy2";
- name = "Robotics Privacy Control";
- req_access = list("robotics")
- },
-/obj/item/mod/core/standard{
- pixel_x = -4
- },
-/obj/item/mod/core/standard{
- pixel_x = 4
- },
-/obj/item/mod/core/standard{
- pixel_y = 4
- },
-/obj/structure/closet/crate/science{
- name = "MOD core crate"
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/station/science/robotics/lab)
"deO" = (
/obj/effect/spawner/random/maintenance,
/obj/structure/disposalpipe/segment{
@@ -11715,6 +11702,15 @@
/obj/structure/grille,
/turf/closed/wall/r_wall,
/area/station/engineering/atmos)
+"eoZ" = (
+/obj/effect/turf_decal/stripes/corner{
+ dir = 4
+ },
+/obj/effect/turf_decal/siding/purple{
+ dir = 8
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"epv" = (
/obj/structure/table,
/obj/item/hand_labeler{
@@ -12485,13 +12481,6 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron,
/area/station/engineering/atmos/storage/gas)
-"eEE" = (
-/obj/structure/chair/office/light{
- dir = 8
- },
-/obj/effect/turf_decal/siding/purple/corner,
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"eEG" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -15112,13 +15101,6 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/wood,
/area/station/command/corporate_showroom)
-"fEG" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/machinery/light/small/directional/east,
-/turf/open/floor/iron/dark/textured_large,
-/area/station/science/cytology)
"fEK" = (
/turf/closed/wall,
/area/station/medical/medbay/central)
@@ -17600,12 +17582,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"gAC" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/turf/open/floor/iron/dark/textured_large,
-/area/station/science/cytology)
"gAH" = (
/obj/structure/cable,
/obj/effect/turf_decal/stripes/line{
@@ -18237,12 +18213,6 @@
},
/turf/open/floor/iron/white,
/area/station/security/medical)
-"gMo" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/turf/open/floor/iron/dark/textured_large,
-/area/station/science/cytology)
"gMt" = (
/obj/machinery/atmospherics/pipe/bridge_pipe/scrubbers/visible{
dir = 4
@@ -19379,6 +19349,21 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"hjw" = (
+/obj/structure/table/glass,
+/obj/item/book/manual/wiki/cytology{
+ pixel_x = -4;
+ pixel_y = 4
+ },
+/obj/item/biopsy_tool{
+ pixel_x = 8;
+ pixel_y = 2
+ },
+/obj/effect/turf_decal/siding/purple{
+ dir = 4
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"hjx" = (
/obj/effect/turf_decal/tile/yellow/half/contrasted,
/obj/machinery/status_display/ai/directional/south,
@@ -25052,21 +25037,6 @@
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
-"jfp" = (
-/obj/structure/table/glass,
-/obj/item/book/manual/wiki/cytology{
- pixel_x = -4;
- pixel_y = 4
- },
-/obj/item/biopsy_tool{
- pixel_x = 8;
- pixel_y = 2
- },
-/obj/effect/turf_decal/siding/purple{
- dir = 4
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"jfr" = (
/obj/structure/cable,
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -25314,6 +25284,20 @@
},
/turf/open/floor/iron,
/area/station/science/xenobiology)
+"jjm" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/holopad,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/purple/fourcorners,
+/obj/effect/turf_decal/siding/purple/corner{
+ dir = 1
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"jjn" = (
/obj/effect/turf_decal/stripes/line,
/obj/structure/cable,
@@ -25408,6 +25392,23 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/turf/open/floor/iron/dark/textured,
/area/station/medical/cryo)
+"jkX" = (
+/obj/machinery/door_buttons/access_button{
+ idDoor = "xeno_airlock_interior";
+ idSelf = "xeno_airlock_control";
+ name = "Access Button";
+ pixel_x = 29;
+ pixel_y = -8;
+ req_access = list("xenobiology")
+ },
+/obj/machinery/firealarm/directional/north,
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/obj/item/soap,
+/turf/open/floor/iron/white,
+/area/station/science/xenobiology/hallway)
"jld" = (
/obj/structure/chair/stool/directional/west,
/turf/open/floor/iron,
@@ -25801,6 +25802,15 @@
/obj/effect/turf_decal/tile/yellow/fourcorners,
/turf/open/floor/iron/white,
/area/station/medical/pharmacy)
+"jsi" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/siding/purple/corner{
+ dir = 8
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"jsj" = (
/obj/machinery/shower/directional/west,
/obj/structure/extinguisher_cabinet/directional/north,
@@ -26757,6 +26767,12 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/cargo/sorting)
+"jHX" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/turf/open/floor/iron/dark/textured_large,
+/area/station/science/cytology)
"jIg" = (
/obj/structure/table,
/obj/item/storage/belt/utility,
@@ -29322,6 +29338,13 @@
/obj/machinery/incident_display/delam/directional/north,
/turf/open/floor/iron/dark,
/area/station/engineering/main)
+"kCr" = (
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/plumbing/input{
+ dir = 8
+ },
+/turf/open/floor/iron/dark/textured_large,
+/area/station/science/cytology)
"kCt" = (
/obj/machinery/status_display/door_timer{
id = "Cell 2";
@@ -34417,6 +34440,13 @@
},
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
+"myr" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/structure/window/reinforced/spawner/directional/south,
+/turf/open/floor/iron/dark/textured_large,
+/area/station/science/cytology)
"myB" = (
/obj/structure/chair,
/obj/structure/cable,
@@ -34482,15 +34512,6 @@
/obj/structure/window/spawner/directional/south,
/turf/open/floor/iron/white,
/area/station/security/prison/mess)
-"mzn" = (
-/obj/effect/turf_decal/stripes/corner{
- dir = 4
- },
-/obj/effect/turf_decal/siding/purple{
- dir = 8
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"mzs" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -34999,11 +35020,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"mHn" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/obj/effect/turf_decal/siding/purple,
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"mHy" = (
/obj/structure/rack,
/turf/open/floor/plating,
@@ -36231,21 +36247,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark,
/area/station/security/execution/education)
-"ncr" = (
-/obj/structure/table/glass,
-/obj/item/stack/sheet/mineral/plasma{
- pixel_y = 4
- },
-/obj/item/reagent_containers/dropper{
- pixel_y = -4
- },
-/obj/structure/cable,
-/obj/machinery/light_switch/directional/west,
-/obj/effect/turf_decal/tile/purple/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"ncv" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/hoop{
@@ -38047,6 +38048,13 @@
/obj/machinery/power/apc/auto_name/directional/south,
/turf/open/floor/iron,
/area/station/security/prison/garden)
+"nHG" = (
+/obj/structure/chair/office/light{
+ dir = 8
+ },
+/obj/effect/turf_decal/siding/purple/corner,
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"nIj" = (
/obj/structure/easel,
/turf/open/floor/plating,
@@ -39267,12 +39275,6 @@
/obj/effect/mapping_helpers/airlock/access/all/service/hydroponics,
/turf/open/floor/iron,
/area/station/service/hydroponics)
-"odP" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 5
- },
-/turf/open/floor/iron/dark/textured_large,
-/area/station/science/cytology)
"oet" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 1
@@ -39351,21 +39353,6 @@
/obj/machinery/airalarm/directional/south,
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
-"ogx" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/tile/purple/half/contrasted{
- dir = 4
- },
-/obj/effect/turf_decal/siding/purple{
- dir = 1
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"ogL" = (
/obj/structure/mirror/directional/north,
/obj/structure/sink/directional/south,
@@ -39999,6 +39986,16 @@
},
/turf/open/floor/iron,
/area/station/cargo/miningoffice)
+"oue" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 9
+ },
+/obj/item/plunger{
+ pixel_y = 20;
+ pixel_x = -7
+ },
+/turf/open/floor/iron/dark/textured_large,
+/area/station/science/cytology)
"ouj" = (
/obj/structure/bed/roller,
/obj/structure/bed/roller,
@@ -40133,35 +40130,6 @@
/obj/structure/closet/secure_closet/hop,
/turf/open/floor/wood,
/area/station/command/heads_quarters/hop)
-"ovQ" = (
-/obj/structure/table/glass,
-/obj/item/radio/intercom/directional/west,
-/obj/machinery/camera/directional/west{
- c_tag = "Xenobiology Lab - Fore";
- network = list("ss13","rd","xeno")
- },
-/obj/machinery/light/directional/west,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/purple/half/contrasted{
- dir = 8
- },
-/obj/item/reagent_containers/cup/beaker/large{
- pixel_x = -6;
- pixel_y = 22
- },
-/obj/item/reagent_containers/cup/beaker{
- pixel_x = 4;
- pixel_y = 17
- },
-/obj/item/food/tofu{
- pixel_y = 6
- },
-/obj/item/food/tofu,
-/obj/item/food/tofu{
- pixel_y = -6
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"ovX" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden,
/turf/closed/wall/r_wall,
@@ -41226,6 +41194,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/primary/fore)
+"oQk" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/obj/machinery/light/small/directional/east,
+/turf/open/floor/iron/dark/textured_large,
+/area/station/science/cytology)
"oQx" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/suit_storage_unit/industrial/loader,
@@ -42447,6 +42422,11 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet,
/area/station/command/bridge)
+"ppC" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/hydroponics/soil,
+/turf/open/floor/grass,
+/area/station/science/cytology)
"ppG" = (
/obj/structure/table/glass,
/obj/effect/turf_decal/tile/blue/fourcorners,
@@ -43703,16 +43683,6 @@
},
/turf/open/floor/iron/dark/corner,
/area/station/engineering/atmos/storage/gas)
-"pLp" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 9
- },
-/obj/item/plunger{
- pixel_y = 20;
- pixel_x = -7
- },
-/turf/open/floor/iron/dark/textured_large,
-/area/station/science/cytology)
"pLs" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -44678,18 +44648,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/port)
-"qez" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/siding/purple/corner{
- dir = 4
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"qeJ" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/door/firedoor,
@@ -50983,6 +50941,10 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"sri" = (
+/obj/machinery/duct,
+/turf/open/floor/iron/dark/textured_large,
+/area/station/science/cytology)
"srk" = (
/obj/structure/sign/warning/electric_shock,
/turf/closed/wall/r_wall,
@@ -52032,6 +51994,15 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/engineering/supermatter)
+"sKf" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/plumbing/growing_vat{
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured_large,
+/area/station/science/cytology)
"sKs" = (
/obj/structure/closet/bombcloset/security,
/obj/effect/turf_decal/tile/red/half/contrasted{
@@ -52444,6 +52415,11 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
/area/station/maintenance/port)
+"sRa" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/obj/effect/turf_decal/siding/purple,
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"sRf" = (
/obj/effect/turf_decal/plaque{
icon_state = "L11"
@@ -53796,6 +53772,12 @@
/obj/structure/window/reinforced/spawner/directional/west,
/turf/open/floor/engine,
/area/station/science/xenobiology)
+"toR" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/iron/dark/textured_large,
+/area/station/science/cytology)
"toV" = (
/obj/machinery/portable_atmospherics/canister/nitrous_oxide,
/obj/effect/turf_decal/bot,
@@ -54152,6 +54134,21 @@
/obj/effect/spawner/random/structure/grille,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"twu" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/purple/half/contrasted{
+ dir = 4
+ },
+/obj/effect/turf_decal/siding/purple{
+ dir = 1
+ },
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"twy" = (
/obj/effect/turf_decal/siding/purple,
/turf/open/floor/iron/dark,
@@ -54238,6 +54235,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/service/hydroponics)
+"tyj" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/iron/dark/textured_large,
+/area/station/science/cytology)
"tyy" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -63002,10 +63005,6 @@
/obj/machinery/light/small/directional/south,
/turf/open/floor/carpet,
/area/station/commons/dorms)
-"wvM" = (
-/obj/machinery/duct,
-/turf/open/floor/iron/dark/textured_large,
-/area/station/science/cytology)
"wvP" = (
/obj/machinery/iv_drip,
/obj/machinery/airalarm/directional/north,
@@ -63432,20 +63431,6 @@
/obj/machinery/digital_clock/directional/north,
/turf/open/floor/wood,
/area/station/service/library)
-"wEc" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/holopad,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/tile/purple/fourcorners,
-/obj/effect/turf_decal/siding/purple/corner{
- dir = 1
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"wEf" = (
/obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/plasma_output{
dir = 1
@@ -64143,6 +64128,16 @@
/obj/structure/window/spawner/directional/west,
/turf/open/floor/grass,
/area/station/service/hydroponics/garden)
+"wRL" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/machinery/camera/directional/west{
+ c_tag = "Cytology Lab - Worklab";
+ network = list("ss13","rd","xeno")
+ },
+/turf/open/floor/iron/dark/textured_large,
+/area/station/science/cytology)
"wRP" = (
/obj/effect/turf_decal/trimline/brown/filled/corner{
dir = 8
@@ -64834,6 +64829,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white,
/area/station/science/research)
+"xfm" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/structure/table/glass,
+/obj/structure/microscope,
+/turf/open/floor/iron/white,
+/area/station/science/cytology)
"xfx" = (
/obj/structure/table/glass,
/obj/item/stack/medical/mesh,
@@ -66263,11 +66266,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/carpet,
/area/station/command/heads_quarters/captain/private)
-"xDl" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/hydroponics/soil,
-/turf/open/floor/grass,
-/area/station/science/cytology)
"xDu" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -66671,15 +66669,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
-"xMG" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/effect/turf_decal/siding/purple/corner{
- dir = 8
- },
-/turf/open/floor/iron/white,
-/area/station/science/cytology)
"xML" = (
/obj/structure/cable,
/turf/open/floor/wood,
@@ -97566,7 +97555,7 @@ uBy
kiy
qDy
reL
-deH
+bOL
eut
kwy
gwf
@@ -109650,7 +109639,7 @@ aaa
aaa
aaa
wmL
-cXl
+jkX
frs
dFo
wmL
@@ -110163,8 +110152,8 @@ oMA
oMA
oMA
eYu
-ovQ
-ncr
+agN
+bXs
tLc
juH
pJA
@@ -110415,14 +110404,14 @@ lMJ
aaa
aaa
uaR
-pLp
-cOM
-gMo
-aTh
-bxF
-eEE
-jfp
-qez
+oue
+wRL
+tyj
+myr
+xfm
+nHG
+hjw
+bqJ
hzL
wNO
tml
@@ -110672,14 +110661,14 @@ dxK
aaa
aaa
oMA
-czf
-wvM
-wvM
-biD
+sKf
+sri
+sri
+kCr
tsy
-mHn
-xDl
-ogx
+sRa
+ppC
+twu
mKD
hxY
nae
@@ -110929,14 +110918,14 @@ lMJ
aaa
aaa
uaR
-odP
-fEG
-gAC
-gAC
+jHX
+oQk
+toR
+toR
syV
-xMG
-mzn
-wEc
+jsi
+eoZ
+jjm
nui
wWV
onD
diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm
index 79719c699a2..e5020b55d4e 100644
--- a/_maps/map_files/NorthStar/north_star.dmm
+++ b/_maps/map_files/NorthStar/north_star.dmm
@@ -13784,17 +13784,6 @@
/obj/machinery/light/directional/west,
/turf/open/misc/dirt/jungle,
/area/station/security/prison/garden)
-"dAu" = (
-/obj/structure/table,
-/obj/item/plate,
-/obj/item/knife/plastic{
- pixel_x = 16
- },
-/obj/item/food/donkpocket/warm/berry{
- pixel_y = 7
- },
-/turf/open/floor/iron/kitchen,
-/area/station/command/heads_quarters/rd)
"dAB" = (
/obj/structure/closet/firecloset,
/turf/open/floor/iron/smooth_large,
@@ -17124,6 +17113,14 @@
},
/turf/open/floor/plating,
/area/station/maintenance/floor1/starboard/fore)
+"eur" = (
+/obj/effect/mapping_helpers/airlock/access/any/supply/mining,
+/obj/machinery/door/airlock/multi_tile/public/glass{
+ name = "Xenoflora"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/textured_large,
+/area/station/cargo/miningdock)
"euu" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
@@ -18906,6 +18903,14 @@
/obj/machinery/light/directional/north,
/turf/open/floor/wood/tile,
/area/station/command/heads_quarters/captain/private)
+"eVs" = (
+/obj/effect/turf_decal/tile/purple/opposingcorners,
+/obj/machinery/computer/security/telescreen/rd{
+ pixel_x = -30
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron/white,
+/area/station/command/heads_quarters/rd)
"eVN" = (
/obj/structure/grille/broken,
/obj/effect/decal/cleanable/dirt,
@@ -20842,6 +20847,12 @@
/obj/structure/sign/poster/official/random/directional/north,
/turf/open/floor/iron/dark,
/area/station/hallway/floor2/fore)
+"fAQ" = (
+/obj/structure/cable,
+/turf/open/floor/iron/dark/side{
+ dir = 1
+ },
+/area/station/hallway/secondary/exit)
"fAT" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -46425,6 +46436,16 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/catwalk_floor,
/area/station/maintenance/floor4/starboard)
+"mfY" = (
+/obj/machinery/light/small/directional/west,
+/obj/machinery/camera/directional/west{
+ c_tag = "Command - Research Director's Quarters #1"
+ },
+/obj/effect/baseturf_helper/reinforced_plating/ceiling,
+/obj/machinery/newscaster/directional/west,
+/obj/item/kirbyplants/random/dead/research_director,
+/turf/open/floor/iron/large,
+/area/station/command/heads_quarters/rd)
"mge" = (
/obj/effect/turf_decal/trimline/blue/line{
dir = 4
@@ -55820,16 +55841,6 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/mineral/silver,
/area/station/service/chapel)
-"oAF" = (
-/obj/machinery/light/small/directional/west,
-/obj/machinery/camera/directional/west{
- c_tag = "Command - Research Director's Quarters #1"
- },
-/obj/effect/baseturf_helper/reinforced_plating/ceiling,
-/obj/machinery/newscaster/directional/west,
-/obj/item/kirbyplants/random/dead/research_director,
-/turf/open/floor/iron/large,
-/area/station/command/heads_quarters/rd)
"oAH" = (
/obj/effect/turf_decal/trimline/blue/filled/warning{
dir = 8
@@ -65517,12 +65528,6 @@
},
/turf/open/floor/glass/reinforced,
/area/station/service/library)
-"rdZ" = (
-/obj/structure/cable,
-/turf/open/floor/iron/dark/side{
- dir = 1
- },
-/area/station/hallway/secondary/exit)
"rec" = (
/obj/structure/cable,
/turf/open/floor/iron/dark/side{
@@ -66083,14 +66088,6 @@
/obj/machinery/computer/records/medical,
/turf/open/floor/iron/dark/textured,
/area/station/medical/paramedic)
-"rmg" = (
-/obj/effect/mapping_helpers/airlock/access/any/supply/mining,
-/obj/machinery/door/airlock/multi_tile/public/glass{
- name = "Xenoflora"
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/textured_large,
-/area/station/cargo/miningdock)
"rmm" = (
/obj/structure/table,
/obj/machinery/camera/autoname/directional/north,
@@ -66821,19 +66818,6 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/pod/light,
/area/station/maintenance/floor2/port/fore)
-"rwV" = (
-/obj/structure/rack,
-/obj/item/mod/core/standard{
- pixel_x = 4;
- pixel_y = -4
- },
-/obj/item/mod/core/standard,
-/obj/item/mod/core/standard{
- pixel_x = -4;
- pixel_y = 4
- },
-/turf/open/floor/iron/dark/smooth_large,
-/area/station/science/robotics/lab)
"rwY" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/modular_computer/preset/civilian{
@@ -71927,14 +71911,6 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/service/library/lounge)
-"sTm" = (
-/obj/effect/turf_decal/tile/purple/opposingcorners,
-/obj/machinery/computer/security/telescreen/rd{
- pixel_x = -30
- },
-/obj/item/kirbyplants/random,
-/turf/open/floor/iron/white,
-/area/station/command/heads_quarters/rd)
"sTq" = (
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plating,
@@ -81209,6 +81185,10 @@
},
/turf/open/floor/iron/dark,
/area/station/science/ordnance/testlab)
+"voZ" = (
+/obj/structure/closet/crate/mod,
+/turf/open/floor/iron/dark/smooth_large,
+/area/station/science/robotics/lab)
"vpa" = (
/obj/item/kirbyplants/random,
/turf/open/floor/iron/dark,
@@ -91284,6 +91264,17 @@
/obj/machinery/camera/autoname/directional/east,
/turf/open/floor/wood/tile,
/area/station/service/chapel/office)
+"xRh" = (
+/obj/structure/table,
+/obj/item/plate,
+/obj/item/knife/plastic{
+ pixel_x = 16
+ },
+/obj/item/food/donkpocket/warm/berry{
+ pixel_y = 7
+ },
+/turf/open/floor/iron/kitchen,
+/area/station/command/heads_quarters/rd)
"xRk" = (
/obj/structure/frame/computer{
dir = 8
@@ -107280,7 +107271,7 @@ eSX
ylE
qiy
hhx
-rdZ
+fAQ
bfX
tqx
svs
@@ -123710,7 +123701,7 @@ cwG
qly
pEv
pnr
-rmg
+eur
tQf
qzm
gtX
@@ -186409,7 +186400,7 @@ hge
hge
hge
oiO
-sTm
+eVs
pKO
aiN
jDc
@@ -202378,7 +202369,7 @@ bpA
bfs
cVT
jXc
-rwV
+voZ
lcv
lcv
bHU
@@ -253232,7 +253223,7 @@ qVO
plz
bYJ
rWT
-oAF
+mfY
vQs
rWT
lEo
@@ -254261,7 +254252,7 @@ hUT
iHm
rWT
rWT
-dAu
+xRh
iHm
kgT
qrd
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index 5a09ecb0485..debe5cc38e4 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -5421,10 +5421,6 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/dark,
/area/station/science/xenobiology)
-"aLW" = (
-/obj/machinery/hydroponics/soil,
-/turf/open/floor/grass,
-/area/station/science/xenobiology)
"aMc" = (
/obj/machinery/atmospherics/components/trinary/mixer/flipped{
dir = 1
@@ -6526,14 +6522,6 @@
},
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat_interior)
-"bef" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/siding/purple{
- dir = 8
- },
-/turf/open/floor/iron/white,
-/area/station/science/xenobiology)
"bej" = (
/obj/machinery/newscaster/directional/north,
/obj/effect/turf_decal/trimline/green/filled/line,
@@ -7770,21 +7758,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/command/nuke_storage)
-"bEI" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/machinery/button/door/directional/east{
- id = "cytologysecure1";
- name = "Secure Pen Lockdown"
- },
-/obj/machinery/light/directional/north,
-/obj/item/soap{
- pixel_y = 2
- },
-/obj/structure/table/glass,
-/turf/open/floor/iron/dark,
-/area/station/science/xenobiology)
"bEM" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 10
@@ -21505,6 +21478,13 @@
/obj/machinery/light/directional/east,
/turf/open/floor/iron,
/area/station/cargo/miningdock)
+"gFm" = (
+/obj/machinery/light/small/directional/west,
+/obj/machinery/plumbing/input{
+ dir = 8
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"gFt" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/structure/cable,
@@ -23672,6 +23652,13 @@
dir = 1
},
/area/station/hallway/secondary/service)
+"hwQ" = (
+/obj/effect/turf_decal/box/red,
+/obj/machinery/plumbing/growing_vat{
+ dir = 4
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"hyE" = (
/obj/structure/table/glass,
/obj/item/book/manual/wiki/security_space_law{
@@ -26214,27 +26201,6 @@
},
/turf/open/floor/catwalk_floor,
/area/station/maintenance/port/central)
-"ixu" = (
-/obj/structure/closet/crate/science{
- name = "MOD core crate"
- },
-/obj/item/mod/core/standard{
- pixel_x = -4
- },
-/obj/item/mod/core/standard{
- pixel_x = -4
- },
-/obj/item/mod/core/standard{
- pixel_x = -4
- },
-/obj/structure/noticeboard/directional/north,
-/obj/machinery/camera/directional/north{
- c_tag = "Science - Robotics";
- network = list("ss13","rd")
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/station/science/robotics/lab)
"ixC" = (
/obj/machinery/computer/upload/ai{
dir = 8
@@ -28304,15 +28270,6 @@
},
/turf/open/floor/iron/dark,
/area/station/cargo/drone_bay)
-"jiT" = (
-/obj/machinery/airalarm/directional/west,
-/obj/machinery/camera/directional/west{
- c_tag = "Science - Cytology West";
- network = list("ss13","rd","xeno")
- },
-/obj/machinery/hydroponics/soil,
-/turf/open/floor/grass,
-/area/station/science/xenobiology)
"jjl" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/disposalpipe/segment{
@@ -30327,17 +30284,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/grimy,
/area/station/hallway/secondary/entry)
-"jTi" = (
-/obj/effect/turf_decal/trimline/neutral/warning,
-/obj/structure/table/reinforced,
-/obj/item/table_clock{
- pixel_y = 8
- },
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/item/storage/backpack/duffelbag/med/surgery,
-/obj/structure/window/reinforced/spawner/directional/west,
-/turf/open/floor/iron/dark,
-/area/station/medical/morgue)
"jTC" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -32018,6 +31964,21 @@
"kvt" = (
/turf/closed/wall,
/area/station/science/genetics)
+"kvO" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/button/door/directional/east{
+ id = "cytologysecure1";
+ name = "Secure Pen Lockdown"
+ },
+/obj/machinery/light/directional/north,
+/obj/item/soap{
+ pixel_y = 2
+ },
+/obj/structure/table/glass,
+/turf/open/floor/iron/dark,
+/area/station/science/xenobiology)
"kwe" = (
/obj/structure/ladder,
/turf/open/floor/iron/grimy,
@@ -40447,6 +40408,18 @@
},
/turf/open/floor/iron/stairs/right,
/area/station/hallway/secondary/construction/engineering)
+"nsK" = (
+/obj/effect/turf_decal/trimline/purple/filled/corner{
+ dir = 8
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/siding/purple{
+ dir = 8
+ },
+/turf/open/floor/iron/white,
+/area/station/science/xenobiology)
"nti" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -41784,6 +41757,13 @@
"nSI" = (
/turf/closed/wall/r_wall,
/area/station/commons/vacant_room/commissary)
+"nSR" = (
+/obj/machinery/light/small/directional/east,
+/obj/machinery/plumbing/input{
+ dir = 8
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"nSV" = (
/obj/effect/turf_decal/trimline/red/filled/corner{
dir = 1
@@ -42833,13 +42813,6 @@
},
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
-"okW" = (
-/obj/machinery/light/small/directional/east,
-/obj/machinery/plumbing/input{
- dir = 8
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"olc" = (
/obj/structure/table/wood,
/obj/item/camera_film{
@@ -43920,14 +43893,6 @@
},
/turf/closed/wall/r_wall,
/area/station/science/xenobiology)
-"oKW" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/siding/purple/corner{
- dir = 8
- },
-/turf/open/floor/iron/white,
-/area/station/science/xenobiology)
"oKZ" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -47561,6 +47526,15 @@
/obj/structure/lattice/catwalk,
/turf/open/space/basic,
/area/station/solars/starboard/fore)
+"pZM" = (
+/obj/machinery/airalarm/directional/west,
+/obj/machinery/camera/directional/west{
+ c_tag = "Science - Cytology West";
+ network = list("ss13","rd","xeno")
+ },
+/obj/machinery/hydroponics/soil,
+/turf/open/floor/grass,
+/area/station/science/xenobiology)
"pZW" = (
/turf/closed/wall,
/area/station/maintenance/port/central)
@@ -47752,6 +47726,17 @@
},
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
+"qdO" = (
+/obj/effect/turf_decal/trimline/neutral/warning,
+/obj/structure/table/reinforced,
+/obj/item/table_clock{
+ pixel_y = 8
+ },
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/item/storage/backpack/duffelbag/med/surgery,
+/obj/structure/window/reinforced/spawner/directional/west,
+/turf/open/floor/iron/dark,
+/area/station/medical/morgue)
"qdY" = (
/obj/effect/turf_decal/siding/thinplating{
dir = 10
@@ -51697,6 +51682,24 @@
/obj/effect/turf_decal/trimline/purple/filled/line,
/turf/open/floor/iron/white,
/area/station/science/ordnance/office)
+"rzt" = (
+/obj/structure/rack,
+/obj/item/storage/box/gloves{
+ pixel_x = -4;
+ pixel_y = 8
+ },
+/obj/item/storage/box/masks{
+ pixel_x = 4;
+ pixel_y = 4
+ },
+/obj/item/wrench,
+/obj/item/knife/kitchen,
+/obj/effect/turf_decal/siding/purple,
+/obj/effect/turf_decal/trimline/purple/filled/line{
+ dir = 8
+ },
+/turf/open/floor/iron/white,
+/area/station/science/xenobiology)
"rzO" = (
/obj/structure/chair,
/obj/machinery/airalarm/directional/north,
@@ -53510,6 +53513,14 @@
},
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
+"sjT" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/siding/purple/corner{
+ dir = 8
+ },
+/turf/open/floor/iron/white,
+/area/station/science/xenobiology)
"skb" = (
/obj/machinery/disposal/bin,
/obj/effect/turf_decal/trimline/brown/filled/line{
@@ -54632,6 +54643,19 @@
},
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat_interior)
+"sEx" = (
+/obj/effect/turf_decal/trimline/purple/filled/line{
+ dir = 8
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/firealarm/directional/west,
+/obj/effect/turf_decal/siding/purple/corner{
+ dir = 1
+ },
+/turf/open/floor/iron/white,
+/area/station/science/xenobiology)
"sEV" = (
/obj/machinery/computer/monitor{
dir = 8
@@ -56139,19 +56163,6 @@
"tes" = (
/turf/open/floor/glass/reinforced,
/area/station/command/heads_quarters/rd)
-"tez" = (
-/obj/effect/turf_decal/trimline/purple/filled/line{
- dir = 8
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/firealarm/directional/west,
-/obj/effect/turf_decal/siding/purple/corner{
- dir = 1
- },
-/turf/open/floor/iron/white,
-/area/station/science/xenobiology)
"teM" = (
/obj/effect/turf_decal/trimline/neutral/filled/corner,
/obj/effect/turf_decal/trimline/neutral/filled/corner{
@@ -56711,6 +56722,16 @@
/obj/machinery/light/directional/west,
/turf/open/floor/iron,
/area/station/escapepodbay)
+"tpr" = (
+/obj/structure/noticeboard/directional/north,
+/obj/machinery/camera/directional/north{
+ c_tag = "Science - Robotics";
+ network = list("ss13","rd")
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/structure/closet/crate/mod,
+/turf/open/floor/iron/dark,
+/area/station/science/robotics/lab)
"tpB" = (
/obj/machinery/door/airlock/maintenance_hatch{
name = "Chapel Maintenance Hatch"
@@ -63714,13 +63735,6 @@
},
/turf/open/floor/iron,
/area/station/service/janitor)
-"vEA" = (
-/obj/effect/turf_decal/box/red,
-/obj/machinery/plumbing/growing_vat{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"vEK" = (
/obj/machinery/medical_kiosk,
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -66473,13 +66487,6 @@
/obj/effect/turf_decal/siding/thinplating/dark,
/turf/open/floor/iron/white,
/area/station/science/research)
-"wFD" = (
-/obj/machinery/light/small/directional/west,
-/obj/machinery/plumbing/input{
- dir = 8
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"wFR" = (
/obj/effect/turf_decal/trimline/neutral/filled/line,
/obj/structure/sign/gym/mirrored{
@@ -66937,24 +66944,6 @@
/obj/machinery/newscaster/directional/north,
/turf/open/floor/iron,
/area/station/security/checkpoint/escape)
-"wPe" = (
-/obj/structure/rack,
-/obj/item/storage/box/gloves{
- pixel_x = -4;
- pixel_y = 8
- },
-/obj/item/storage/box/masks{
- pixel_x = 4;
- pixel_y = 4
- },
-/obj/item/wrench,
-/obj/item/knife/kitchen,
-/obj/effect/turf_decal/siding/purple,
-/obj/effect/turf_decal/trimline/purple/filled/line{
- dir = 8
- },
-/turf/open/floor/iron/white,
-/area/station/science/xenobiology)
"wPj" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/turf/open/floor/engine,
@@ -67214,6 +67203,10 @@
},
/turf/open/floor/glass/reinforced,
/area/station/science/research)
+"wXi" = (
+/obj/machinery/hydroponics/soil,
+/turf/open/floor/grass,
+/area/station/science/xenobiology)
"wXx" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -67589,18 +67582,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/security/prison/safe)
-"xfh" = (
-/obj/effect/turf_decal/trimline/purple/filled/corner{
- dir = 8
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/siding/purple{
- dir = 8
- },
-/turf/open/floor/iron/white,
-/area/station/science/xenobiology)
"xft" = (
/obj/machinery/duct,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -67622,6 +67603,14 @@
"xfH" = (
/turf/open/floor/glass,
/area/station/commons/lounge)
+"xfL" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/siding/purple{
+ dir = 8
+ },
+/turf/open/floor/iron/white,
+/area/station/science/xenobiology)
"xfN" = (
/obj/structure/cable/layer1,
/obj/effect/turf_decal/trimline/yellow/arrow_ccw{
@@ -172501,7 +172490,7 @@ hiZ
wTP
sFA
uKP
-jTi
+qdO
qfS
gNN
whz
@@ -179181,7 +179170,7 @@ gYp
mlC
wjQ
gyP
-ixu
+tpr
eeE
muZ
gSF
@@ -179979,8 +179968,8 @@ aaa
aaa
aaa
qVr
-wFD
-vEA
+gFm
+hwQ
soq
abM
abM
@@ -180751,9 +180740,9 @@ qVr
qVr
jMs
tsg
-wPe
-jiT
-aLW
+rzt
+pZM
+wXi
soq
vqe
soq
@@ -181008,10 +180997,10 @@ qVr
gYw
cHY
aLR
-oKW
-bef
-xfh
-tez
+sjT
+xfL
+nsK
+sEx
vPC
qVr
aaa
@@ -182805,7 +182794,7 @@ qVr
qVr
qVr
qVr
-bEI
+kvO
cZH
pWw
uMu
@@ -183577,8 +183566,8 @@ aaa
aaa
aaa
qVr
-okW
-vEA
+nSR
+hwQ
qVr
aaa
aaa
diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm
index 2e305427f88..dd5b38113d3 100644
--- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm
+++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm
@@ -108,6 +108,10 @@
#define COMSIG_CARBON_BLOCK_EAT (1 << 0)
///Called when a carbon vomits : (distance, force)
#define COMSIG_CARBON_VOMITED "carbon_vomited"
+///Called from apply_overlay(cache_index, overlay)
+#define COMSIG_CARBON_APPLY_OVERLAY "carbon_apply_overlay"
+///Called from remove_overlay(cache_index, overlay)
+#define COMSIG_CARBON_REMOVE_OVERLAY "carbon_remove_overlay"
// /mob/living/carbon/human signals
diff --git a/code/__DEFINES/mod.dm b/code/__DEFINES/mod.dm
index e98230a8f3b..e0b7d6ff4a3 100644
--- a/code/__DEFINES/mod.dm
+++ b/code/__DEFINES/mod.dm
@@ -43,5 +43,13 @@
#define MOD_ICON_OVERRIDE "mod_icon_override"
#define MOD_WORN_ICON_OVERRIDE "mod_worn_icon_override"
+//Defines for MODlink frequencies
+#define MODLINK_FREQ_NANOTRASEN "NT"
+#define MODLINK_FREQ_SYNDICATE "SYND"
+#define MODLINK_FREQ_CHARLIE "CHRL"
+#define MODLINK_FREQ_CENTCOM "CC"
+
/// Global list of all /datum/mod_theme
GLOBAL_LIST_INIT(mod_themes, setup_mod_themes())
+/// Global list of all ids associated to a /datum/mod_link instance
+GLOBAL_LIST_EMPTY(mod_link_ids)
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 5c2e7ece5c5..5dcb3252f63 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -573,6 +573,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Mobs with this trait do care about a few grisly things, such as digging up graves. They also really do not like bringing people back to life or tending wounds, but love autopsies and amputations.
#define TRAIT_MORBID "morbid"
+/// Whether or not the user is in a MODlink call, prevents making more calls
+#define TRAIT_IN_CALL "in_call"
+
// METABOLISMS
// Various jobs on the station have historically had better reactions
// to various drinks and foodstuffs. Security liking donuts is a classic
@@ -760,7 +763,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_CUSTOM_TAP_SOUND "no_tap_sound"
/// Makes the feedback message when someone else is putting this item on you more noticeable
#define TRAIT_DANGEROUS_OBJECT "dangerous_object"
-// determines whether or not objects are haunted and teleport/attack randomly
+/// determines whether or not objects are haunted and teleport/attack randomly
#define TRAIT_HAUNTED "haunted"
//quirk traits
diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm
index 32e18e5d146..07239ca07c5 100644
--- a/code/__DEFINES/vv.dm
+++ b/code/__DEFINES/vv.dm
@@ -98,6 +98,7 @@
#define VV_HK_EDIT_FILTERS "edit_filters"
#define VV_HK_EDIT_PARTICLES "edit_particles"
#define VV_HK_EDIT_COLOR_MATRIX "edit_color_matrix"
+#define VV_HK_TEST_MATRIXES "test_matrixes"
#define VV_HK_ADD_AI "add_ai"
#define VV_HK_ARMOR_MOD "mod_obj_armor"
diff --git a/code/datums/actions/items/toggles.dm b/code/datums/actions/items/toggles.dm
index be145702d35..f0fcfb9783e 100644
--- a/code/datums/actions/items/toggles.dm
+++ b/code/datums/actions/items/toggles.dm
@@ -103,3 +103,7 @@
/datum/action/item_action/flip
name = "Flip"
+
+/datum/action/item_action/call_link
+ name = "Call MODlink"
+
diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm
index edeb52bda04..6ee4eaddd3f 100644
--- a/code/datums/chatmessage.dm
+++ b/code/datums/chatmessage.dm
@@ -193,7 +193,7 @@
/datum/chatmessage/proc/finish_image_generation(mheight, atom/target, mob/owner, complete_text, lifespan)
var/rough_time = REALTIMEOFDAY
approx_lines = max(1, mheight / CHAT_MESSAGE_APPROX_LHEIGHT)
-
+ var/starting_height = target.maptext_height
// Translate any existing messages upwards, apply exponential decay factors to timers
message_loc = isturf(target) ? target : get_atom_on_turf(target)
if (owned_by.seen_messages)
@@ -208,7 +208,12 @@
// When choosing to update the remaining time we have to be careful not to update the
// scheduled time once the EOL has been executed.
if (time_spent >= time_before_fade)
- animate(m.message, pixel_y = m.message.pixel_y + mheight, time = CHAT_MESSAGE_SPAWN_TIME, flags = ANIMATION_PARALLEL)
+ if(m.message.pixel_y < starting_height)
+ var/max_height = m.message.pixel_y + m.approx_lines * CHAT_MESSAGE_APPROX_LHEIGHT - starting_height
+ if(max_height > 0)
+ animate(m.message, pixel_y = m.message.pixel_y + max_height, time = CHAT_MESSAGE_SPAWN_TIME, flags = ANIMATION_PARALLEL)
+ else if(mheight + starting_height >= m.message.pixel_y)
+ animate(m.message, pixel_y = m.message.pixel_y + mheight, time = CHAT_MESSAGE_SPAWN_TIME, flags = ANIMATION_PARALLEL)
continue
var/remaining_time = time_before_fade * (CHAT_MESSAGE_EXP_DECAY ** idx++) * (CHAT_MESSAGE_HEIGHT_DECAY ** combined_height)
@@ -225,7 +230,12 @@
animate(alpha = 0, time = CHAT_MESSAGE_EOL_FADE)
// We run this after the alpha animate, because we don't want to interrup it, but also don't want to block it by running first
// Sooo instead we do this. bit messy but it fuckin works
- animate(m.message, pixel_y = m.message.pixel_y + mheight, time = CHAT_MESSAGE_SPAWN_TIME, flags = ANIMATION_PARALLEL)
+ if(m.message.pixel_y < starting_height)
+ var/max_height = m.message.pixel_y + m.approx_lines * CHAT_MESSAGE_APPROX_LHEIGHT - starting_height
+ if(max_height > 0)
+ animate(m.message, pixel_y = m.message.pixel_y + max_height, time = CHAT_MESSAGE_SPAWN_TIME, flags = ANIMATION_PARALLEL)
+ else if(mheight + starting_height >= m.message.pixel_y)
+ animate(m.message, pixel_y = m.message.pixel_y + mheight, time = CHAT_MESSAGE_SPAWN_TIME, flags = ANIMATION_PARALLEL)
// Reset z index if relevant
if (current_z_idx >= CHAT_LAYER_MAX_Z)
@@ -236,7 +246,7 @@
SET_PLANE_EXPLICIT(message, RUNECHAT_PLANE, message_loc)
message.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA | KEEP_APART
message.alpha = 0
- message.pixel_y = target.maptext_height
+ message.pixel_y = starting_height
message.pixel_x = -target.base_pixel_x
message.maptext_width = CHAT_MESSAGE_WIDTH
message.maptext_height = mheight * 1.25 // We add extra because some characters are superscript, like actions
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 8fe57dca07e..2e0352a05fa 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -1298,6 +1298,7 @@
VV_DROPDOWN_OPTION(VV_HK_TRIGGER_EXPLOSION, "Explosion")
VV_DROPDOWN_OPTION(VV_HK_EDIT_FILTERS, "Edit Filters")
VV_DROPDOWN_OPTION(VV_HK_EDIT_COLOR_MATRIX, "Edit Color as Matrix")
+ VV_DROPDOWN_OPTION(VV_HK_TEST_MATRIXES, "Test Matrices")
VV_DROPDOWN_OPTION(VV_HK_ADD_AI, "Add AI controller")
VV_DROPDOWN_OPTION(VV_HK_ARMOR_MOD, "Modify Armor")
if(greyscale_colors)
@@ -1381,7 +1382,7 @@
ai_controller = new result(src)
if(href_list[VV_HK_MODIFY_TRANSFORM] && check_rights(R_VAREDIT))
- var/result = input(usr, "Choose the transformation to apply","Transform Mod") as null|anything in list("Scale","Translate","Rotate")
+ var/result = input(usr, "Choose the transformation to apply","Transform Mod") as null|anything in list("Scale","Translate","Rotate","Shear")
var/matrix/M = transform
if(!result)
return
@@ -1398,6 +1399,12 @@
if(isnull(x) || isnull(y))
return
transform = M.Translate(x,y)
+ if("Shear")
+ var/x = input(usr, "Choose x mod","Transform Mod") as null|num
+ var/y = input(usr, "Choose y mod","Transform Mod") as null|num
+ if(isnull(x) || isnull(y))
+ return
+ transform = M.Shear(x,y)
if("Rotate")
var/angle = input(usr, "Choose angle to rotate","Transform Mod") as null|num
if(isnull(angle))
@@ -1440,12 +1447,13 @@
vv_auto_rename(newname)
if(href_list[VV_HK_EDIT_FILTERS] && check_rights(R_VAREDIT))
- var/client/C = usr.client
- C?.open_filter_editor(src)
+ usr.client?.open_filter_editor(src)
if(href_list[VV_HK_EDIT_COLOR_MATRIX] && check_rights(R_VAREDIT))
- var/client/C = usr.client
- C?.open_color_matrix_editor(src)
+ usr.client?.open_color_matrix_editor(src)
+
+ if(href_list[VV_HK_TEST_MATRIXES] && check_rights(R_VAREDIT))
+ usr.client?.open_matrix_tester(src)
/atom/vv_get_header()
. = ..()
@@ -1632,7 +1640,7 @@
/atom/proc/multitool_act_secondary(mob/living/user, obj/item/tool)
return
-///Check if the multitool has an item in it's data buffer
+///Check if an item supports a data buffer (is a multitool)
/atom/proc/multitool_check_buffer(user, obj/item/multitool, silent = FALSE)
if(!istype(multitool, /obj/item/multitool))
if(user && !silent)
@@ -2131,16 +2139,18 @@
// Now we're gonna do a scanline effect
// Gonna take this atom and give it a render target, then use it as a source for a filter
// (We use an atom because it seems as if setting render_target on an MA is just invalid. I hate this engine)
- var/static/atom/movable/scanline
- if(!scanline)
- scanline = new(null)
- scanline.icon = 'icons/effects/effects.dmi'
- scanline.icon_state = "scanline"
- // * so it doesn't render
- scanline.render_target = "*HoloScanline"
+ var/atom/movable/scanline = new(null)
+ scanline.icon = 'icons/effects/effects.dmi'
+ scanline.icon_state = "scanline"
+ scanline.appearance_flags |= RESET_TRANSFORM
+ // * so it doesn't render
+ var/static/uid_scan = 0
+ scanline.render_target = "*HoloScanline [uid_scan]"
+ uid_scan++
// Now we add it as a filter, and overlay the appearance so the render source is always around
add_filter("HOLO: Scanline", 2, alpha_mask_filter(render_source = scanline.render_target))
add_overlay(scanline)
+ qdel(scanline)
// Annd let's make the sucker emissive, so it glows in the dark
if(!render_target)
var/static/uid = 0
diff --git a/code/game/machinery/botlaunchpad.dm b/code/game/machinery/botlaunchpad.dm
index f6fd5843244..f1c85a293c7 100644
--- a/code/game/machinery/botlaunchpad.dm
+++ b/code/game/machinery/botlaunchpad.dm
@@ -26,7 +26,7 @@
if(!multitool_check_buffer(user, tool))
return
var/obj/item/multitool/multitool = tool
- multitool.buffer = src
+ multitool.set_buffer(src)
to_chat(user, span_notice("You save the data in the [multitool.name]'s buffer."))
return TOOL_ACT_TOOLTYPE_SUCCESS
diff --git a/code/game/machinery/computer/atmos_computers/_air_sensor.dm b/code/game/machinery/computer/atmos_computers/_air_sensor.dm
index a34ffedac0b..faef0370ad0 100644
--- a/code/game/machinery/computer/atmos_computers/_air_sensor.dm
+++ b/code/game/machinery/computer/atmos_computers/_air_sensor.dm
@@ -91,7 +91,7 @@
if(istype(multi_tool.buffer, /obj/machinery/atmospherics/components/unary/outlet_injector))
var/obj/machinery/atmospherics/components/unary/outlet_injector/input = multi_tool.buffer
inlet_id = input.id_tag
- multi_tool.buffer = null
+ multi_tool.set_buffer(null)
balloon_alert(user, "connected to input")
else if(istype(multi_tool.buffer, /obj/machinery/atmospherics/components/unary/vent_pump))
@@ -105,11 +105,11 @@
output.external_pressure_bound = 0
//finally assign it to this sensor
outlet_id = output.id_tag
- multi_tool.buffer = null
+ multi_tool.set_buffer(null)
balloon_alert(user, "connected to output")
else
- multi_tool.buffer = src
+ multi_tool.set_buffer(src)
balloon_alert(user, "added to multitool buffer")
return TRUE
diff --git a/code/game/machinery/computer/launchpad_control.dm b/code/game/machinery/computer/launchpad_control.dm
index 4023192c90c..5590297c54a 100644
--- a/code/game/machinery/computer/launchpad_control.dm
+++ b/code/game/machinery/computer/launchpad_control.dm
@@ -66,7 +66,7 @@
if(M.buffer && istype(M.buffer, /obj/machinery/launchpad))
if(LAZYLEN(launchpads) < maximum_pads)
launchpads |= M.buffer
- M.buffer = null
+ M.set_buffer(null)
to_chat(user, span_notice("You upload the data from the [W.name]'s buffer."))
else
to_chat(user, span_warning("[src] cannot handle any more connections!"))
diff --git a/code/game/machinery/computer/mechlaunchpad.dm b/code/game/machinery/computer/mechlaunchpad.dm
index c89bbab7fa0..106f87f1788 100644
--- a/code/game/machinery/computer/mechlaunchpad.dm
+++ b/code/game/machinery/computer/mechlaunchpad.dm
@@ -100,11 +100,11 @@
if(buffered_pad in mechpads)
remove_pad(buffered_pad)
connect_launchpad(buffered_pad)
- multitool.buffer = null
+ multitool.set_buffer(null)
to_chat(user, span_notice("You connect the console to the pad with data from the [multitool.name]'s buffer."))
else
add_pad(buffered_pad)
- multitool.buffer = null
+ multitool.set_buffer(null)
to_chat(user, span_notice("You upload the data from the [multitool.name]'s buffer."))
return TRUE
diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm
index 10a46502537..f3f463bcae7 100644
--- a/code/game/machinery/launch_pad.dm
+++ b/code/game/machinery/launch_pad.dm
@@ -77,7 +77,7 @@
if(!multitool_check_buffer(user, I))
return
var/obj/item/multitool/M = I
- M.buffer = src
+ M.set_buffer(src)
to_chat(user, span_notice("You save the data in the [I.name]'s buffer."))
return 1
diff --git a/code/game/machinery/mechlaunchpad.dm b/code/game/machinery/mechlaunchpad.dm
index 10f5ab66903..54cda76f989 100644
--- a/code/game/machinery/mechlaunchpad.dm
+++ b/code/game/machinery/mechlaunchpad.dm
@@ -36,7 +36,7 @@
if(!multitool_check_buffer(user, tool))
return
var/obj/item/multitool/multitool = tool
- multitool.buffer = src
+ multitool.set_buffer(src)
to_chat(user, span_notice("You save the data in the [multitool.name]'s buffer."))
return TRUE
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index 4e65f957d79..b19a8032e7d 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -350,7 +350,7 @@ DEFINE_BITFIELD(turret_flags, list(
if(!multitool_check_buffer(user, I))
return
var/obj/item/multitool/M = I
- M.buffer = src
+ M.set_buffer(src)
to_chat(user, span_notice("You add [src] to multitool buffer."))
else
return ..()
diff --git a/code/game/machinery/porta_turret/portable_turret_cover.dm b/code/game/machinery/porta_turret/portable_turret_cover.dm
index 2ff41a17283..89f41386691 100644
--- a/code/game/machinery/porta_turret/portable_turret_cover.dm
+++ b/code/game/machinery/porta_turret/portable_turret_cover.dm
@@ -65,7 +65,7 @@
if(!multitool_check_buffer(user, I))
return
var/obj/item/multitool/M = I
- M.buffer = parent_turret
+ M.set_buffer(parent_turret)
to_chat(user, span_notice("You add [parent_turret] to multitool buffer."))
return
return ..()
diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm
index 11a4a2ef10c..a855c2d5523 100644
--- a/code/game/machinery/quantum_pad.dm
+++ b/code/game/machinery/quantum_pad.dm
@@ -62,7 +62,7 @@
if(!multitool_check_buffer(user, I))
return
var/obj/item/multitool/M = I
- M.buffer = src
+ M.set_buffer(src)
to_chat(user, span_notice("You save the data in [I]'s buffer. It can now be saved to pads with closed panels."))
return TRUE
else if(I.tool_behaviour == TOOL_MULTITOOL)
diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm
index 8b19a4f70df..f3d5f8d8352 100644
--- a/code/game/machinery/telecomms/machine_interactions.dm
+++ b/code/game/machinery/telecomms/machine_interactions.dm
@@ -153,10 +153,10 @@
var/obj/machinery/telecomms/T = heldmultitool.buffer
. = add_new_link(T, operator)
if("buffer")
- heldmultitool.buffer = src
+ heldmultitool.set_buffer(src)
. = TRUE
if("flush")
- heldmultitool.buffer = null
+ heldmultitool.set_buffer(null)
. = TRUE
add_act(action, params)
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index 5ee4c702cf2..93fbafeb43d 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -185,13 +185,13 @@
return
var/obj/item/multitool/M = W
if(panel_open)
- M.buffer = src
+ M.set_buffer(src)
to_chat(user, span_notice("You download the data to the [W.name]'s buffer."))
else
if(M.buffer && istype(M.buffer, /obj/machinery/teleport/station) && M.buffer != src)
if(linked_stations.len < efficiency)
linked_stations.Add(M.buffer)
- M.buffer = null
+ M.set_buffer(null)
to_chat(user, span_notice("You upload the data from the [W.name]'s buffer."))
else
to_chat(user, span_alert("This station can't hold more information, try to use better parts."))
diff --git a/code/game/objects/items/botpad_remote.dm b/code/game/objects/items/botpad_remote.dm
index 70a74ad3be6..49c49e8cb73 100644
--- a/code/game/objects/items/botpad_remote.dm
+++ b/code/game/objects/items/botpad_remote.dm
@@ -40,7 +40,7 @@
connected_botpad = buffered_remote
connected_botpad.connected_remote = src
connected_botpad.id = id
- multitool.buffer = null
+ multitool.set_buffer(null)
to_chat(user, span_notice("You connect the controller to the pad with data from the [multitool.name]'s buffer."))
else
to_chat(user, span_warning("Unable to upload!"))
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index 94307336b9b..76b003ce76a 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -30,7 +30,7 @@
custom_premium_price = PAYCHECK_COMMAND * 3
toolspeed = 1
usesound = 'sound/weapons/empty.ogg'
- var/obj/machinery/buffer // simple machine buffer for device linkage
+ var/datum/buffer // simple machine buffer for device linkage
var/mode = 0
/obj/item/multitool/examine(mob/user)
@@ -41,6 +41,17 @@
user.visible_message(span_suicide("[user] puts the [src] to [user.p_their()] chest. It looks like [user.p_theyre()] trying to pulse [user.p_their()] heart off!"))
return OXYLOSS//theres a reason it wasn't recommended by doctors
+/obj/item/multitool/proc/set_buffer(datum/buffer)
+ if(buffer)
+ UnregisterSignal(buffer, COMSIG_QDELETING)
+ if(QDELETED(buffer))
+ return
+ src.buffer = buffer
+ RegisterSignal(buffer, COMSIG_QDELETING, PROC_REF(on_buffer_del))
+
+/obj/item/multitool/proc/on_buffer_del(datum/source)
+ SIGNAL_HANDLER
+ buffer = null
// Syndicate device disguised as a multitool; it will turn red when an AI camera is nearby.
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 502a114838d..277c9dda7ac 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -298,6 +298,18 @@
icon_state = "scicrate"
base_icon_state = "scicrate"
+/obj/structure/closet/crate/mod
+ name = "MOD crate"
+ icon_state = "scicrate"
+ base_icon_state = "scicrate"
+
+/obj/structure/closet/crate/mod/PopulateContents()
+ ..()
+ for(var/i in 1 to 3)
+ new /obj/item/mod/core/standard(src)
+ for(var/i in 1 to 2)
+ new /obj/item/clothing/neck/link_scryer(src)
+
/obj/structure/closet/crate/solarpanel_small
name = "budget solar panel crate"
icon_state = "engi_e_crate"
diff --git a/code/modules/admin/view_variables/nobody_wants_to_learn_matrix_math.dm b/code/modules/admin/view_variables/nobody_wants_to_learn_matrix_math.dm
new file mode 100644
index 00000000000..872bd27d627
--- /dev/null
+++ b/code/modules/admin/view_variables/nobody_wants_to_learn_matrix_math.dm
@@ -0,0 +1,80 @@
+
+/**
+ * ## nobody wants to learn matrix math!
+ *
+ * More than just a completely true statement, this datum is created as a tgui interface
+ * allowing you to modify each vector until you know what you're doing.
+ * Much like filteriffic, 'nobody wants to learn matrix math' is meant for developers like you and I
+ * to implement interesting matrix transformations without the hassle if needing to know... algebra? Damn, i'm stupid.
+ */
+/datum/nobody_wants_to_learn_matrix_math
+ var/atom/target
+ var/matrix/testing_matrix
+
+/datum/nobody_wants_to_learn_matrix_math/New(atom/target)
+ src.target = target
+ testing_matrix = matrix(target.transform)
+
+/datum/nobody_wants_to_learn_matrix_math/Destroy(force, ...)
+ QDEL_NULL(testing_matrix)
+ return ..()
+
+/datum/nobody_wants_to_learn_matrix_math/ui_state(mob/user)
+ return GLOB.admin_state
+
+/datum/nobody_wants_to_learn_matrix_math/ui_close(mob/user)
+ qdel(src)
+
+/datum/nobody_wants_to_learn_matrix_math/ui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "MatrixMathTester")
+ ui.open()
+
+/datum/nobody_wants_to_learn_matrix_math/ui_data()
+ var/list/data = list()
+ data["matrix_a"] = testing_matrix.a
+ data["matrix_b"] = testing_matrix.b
+ data["matrix_c"] = testing_matrix.c
+ data["matrix_d"] = testing_matrix.d
+ data["matrix_e"] = testing_matrix.e
+ data["matrix_f"] = testing_matrix.f
+ data["pixelated"] = target.appearance_flags & PIXEL_SCALE
+ return data
+
+/datum/nobody_wants_to_learn_matrix_math/ui_act(action, list/params)
+ . = ..()
+ if(.)
+ return
+
+ switch(action)
+ if("change_var")
+ var/matrix_var_name = params["var_name"]
+ var/matrix_var_value = params["var_value"]
+ if(testing_matrix.vv_edit_var(matrix_var_name, matrix_var_value) == FALSE)
+ to_chat(src, "Your edit was rejected by the object. This is a bug with the matrix tester, not your fault, so report it on github.", confidential = TRUE)
+ return
+ set_transform()
+ if("scale")
+ testing_matrix.Scale(params["x"], params["y"])
+ set_transform()
+ if("translate")
+ testing_matrix.Translate(params["x"], params["y"])
+ set_transform()
+ if("shear")
+ testing_matrix.Shear(params["x"], params["y"])
+ set_transform()
+ if("turn")
+ testing_matrix.Turn(params["angle"])
+ set_transform()
+ if("toggle_pixel")
+ target.appearance_flags ^= PIXEL_SCALE
+
+/datum/nobody_wants_to_learn_matrix_math/proc/set_transform()
+ animate(target, transform = testing_matrix, time = 0.5 SECONDS)
+ testing_matrix = matrix(target.transform)
+
+/client/proc/open_matrix_tester(atom/in_atom)
+ if(holder)
+ var/datum/nobody_wants_to_learn_matrix_math/matrix_tester = new(in_atom)
+ matrix_tester.ui_interact(mob)
diff --git a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
index a99735a2d5c..0966984c671 100644
--- a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
+++ b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
@@ -183,7 +183,7 @@
. = ..()
if (istype(I))
to_chat(user, span_notice("You register [src] in [I]s buffer."))
- I.buffer = src
+ I.set_buffer(src)
return TRUE
/obj/machinery/piratepad/screwdriver_act_secondary(mob/living/user, obj/item/screwdriver/screw)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/bluespace_sender.dm b/code/modules/atmospherics/machinery/components/unary_devices/bluespace_sender.dm
index 1febca39269..d4977eb6454 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/bluespace_sender.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/bluespace_sender.dm
@@ -122,7 +122,7 @@ GLOBAL_LIST_EMPTY_TYPED(bluespace_senders, /obj/machinery/atmospherics/component
/obj/machinery/atmospherics/components/unary/bluespace_sender/multitool_act(mob/living/user, obj/item/item)
var/obj/item/multitool/multitool = item
- multitool.buffer = src
+ multitool.set_buffer(src)
to_chat(user, span_notice("You store linkage information in [item]'s buffer."))
return TRUE
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
index 33de80ffbaf..269091d4bdf 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
@@ -48,12 +48,12 @@
if(istype(multi_tool.buffer, /obj/machinery/air_sensor))
var/obj/machinery/air_sensor/sensor = multi_tool.buffer
sensor.inlet_id = id_tag
- multi_tool.buffer = null
+ multi_tool.set_buffer(null)
balloon_alert(user, "input linked to sensor")
return TOOL_ACT_TOOLTYPE_SUCCESS
balloon_alert(user, "saved in buffer")
- multi_tool.buffer = src
+ multi_tool.set_buffer(src)
return TOOL_ACT_TOOLTYPE_SUCCESS
/obj/machinery/atmospherics/components/unary/outlet_injector/CtrlClick(mob/user)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
index 9b05e3d868e..7ca3b1fc580 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
@@ -58,12 +58,12 @@
if(istype(multi_tool.buffer, /obj/machinery/air_sensor))
var/obj/machinery/air_sensor/sensor = multi_tool.buffer
sensor.outlet_id = id_tag
- multi_tool.buffer = null
+ multi_tool.set_buffer(null)
balloon_alert(user, "output linked to sensor")
return TOOL_ACT_TOOLTYPE_SUCCESS
balloon_alert(user, "saved in buffer")
- multi_tool.buffer = src
+ multi_tool.set_buffer(src)
return TOOL_ACT_TOOLTYPE_SUCCESS
/obj/machinery/atmospherics/components/unary/vent_pump/Destroy()
diff --git a/code/modules/clothing/spacesuits/specialops.dm b/code/modules/clothing/spacesuits/specialops.dm
index 77c49c96d3a..3634066e72f 100644
--- a/code/modules/clothing/spacesuits/specialops.dm
+++ b/code/modules/clothing/spacesuits/specialops.dm
@@ -6,7 +6,7 @@
icon_state = "beret_badge"
inhand_icon_state = null
greyscale_colors = "#397F3F#FFCE5B"
-
+ clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT
flags_inv = 0
armor_type = /datum/armor/space_beret
strip_delay = 130
diff --git a/code/modules/food_and_drinks/machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/machinery/monkeyrecycler.dm
index 71039e9019b..5bb772c7398 100644
--- a/code/modules/food_and_drinks/machinery/monkeyrecycler.dm
+++ b/code/modules/food_and_drinks/machinery/monkeyrecycler.dm
@@ -99,5 +99,5 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
. = ..()
if(istype(I))
to_chat(user, span_notice("You log [src] in the multitool's buffer."))
- I.buffer = src
+ I.set_buffer(src)
return TRUE
diff --git a/code/modules/jobs/job_types/research_director.dm b/code/modules/jobs/job_types/research_director.dm
index 8a3071f21a9..abd2a2c6bd0 100644
--- a/code/modules/jobs/job_types/research_director.dm
+++ b/code/modules/jobs/job_types/research_director.dm
@@ -82,5 +82,6 @@
suit_store = /obj/item/tank/internals/oxygen
back = /obj/item/mod/control/pre_equipped/research
suit = null
+ head = null
mask = /obj/item/clothing/mask/breath
internals_slot = ITEM_SLOT_SUITSTORE
diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm
index b06188fb2c6..07b4c714915 100644
--- a/code/modules/mining/machine_silo.dm
+++ b/code/modules/mining/machine_silo.dm
@@ -183,7 +183,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
. = ..()
if (istype(I))
to_chat(user, span_notice("You log [src] in the multitool's buffer."))
- I.buffer = src
+ I.set_buffer(src)
return TRUE
/**
diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm
index 1635c5c2fa3..537f6cab99d 100644
--- a/code/modules/mining/machine_stacking.dm
+++ b/code/modules/mining/machine_stacking.dm
@@ -26,7 +26,7 @@
if(!multitool_check_buffer(user, I))
return
var/obj/item/multitool/M = I
- M.buffer = src
+ M.set_buffer(src)
to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
return TRUE
diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm
index 104480d502f..31429c28aaa 100644
--- a/code/modules/mob/living/carbon/carbon_update_icons.dm
+++ b/code/modules/mob/living/carbon/carbon_update_icons.dm
@@ -75,12 +75,14 @@
/mob/living/carbon/proc/apply_overlay(cache_index)
if((. = overlays_standing[cache_index]))
add_overlay(.)
+ SEND_SIGNAL(src, COMSIG_CARBON_APPLY_OVERLAY, cache_index, .)
/mob/living/carbon/proc/remove_overlay(cache_index)
var/I = overlays_standing[cache_index]
if(I)
cut_overlay(I)
overlays_standing[cache_index] = null
+ SEND_SIGNAL(src, COMSIG_CARBON_REMOVE_OVERLAY, cache_index, I)
//used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body.
/mob/living/carbon/human/proc/update_mutant_bodyparts(force_update = FALSE) // SKYRAT EDIT CHANGE
diff --git a/code/modules/mod/mod_activation.dm b/code/modules/mod/mod_activation.dm
index 37083aeb2c1..3fca395e4b7 100644
--- a/code/modules/mod/mod_activation.dm
+++ b/code/modules/mod/mod_activation.dm
@@ -163,6 +163,7 @@
if(!module.active || (module.allow_flags & MODULE_ALLOW_INACTIVE))
continue
module.on_deactivation(display_message = FALSE)
+ mod_link.end_call()
activating = TRUE
to_chat(wearer, span_notice("MODsuit [active ? "shutting down" : "starting up"]."))
@@ -233,17 +234,15 @@
if (!seal && wearer?.invalid_internals())
wearer.cutoff_internals()
-/// Finishes the suit's activation, starts processing
+/// Finishes the suit's activation
/obj/item/mod/control/proc/finish_activation(on)
active = on
if(active)
for(var/obj/item/mod/module/module as anything in modules)
module.on_suit_activation()
- START_PROCESSING(SSobj, src)
else
for(var/obj/item/mod/module/module as anything in modules)
module.on_suit_deactivation()
- STOP_PROCESSING(SSobj, src)
update_speed()
update_icon_state()
wearer.update_clothing(slot_flags)
diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm
index 5cce89f1511..573cee3531a 100644
--- a/code/modules/mod/mod_control.dm
+++ b/code/modules/mod/mod_control.dm
@@ -85,6 +85,10 @@
var/obj/item/mod/module/selected_module
/// AI or pAI mob inhabiting the MOD.
var/mob/living/silicon/ai_assistant
+ /// The MODlink datum, letting us call people from the suit.
+ var/datum/mod_link/mod_link
+ /// The starting MODlink frequency, overridden on subtypes that want it to be something.
+ var/starting_frequency = null
/// Delay between moves as AI.
var/static/movedelay = 0
/// Cooldown for AI moves.
@@ -142,10 +146,10 @@
for(var/obj/item/mod/module/module as anything in theme.inbuilt_modules)
module = new module(src)
install(module)
+ START_PROCESSING(SSobj, src)
/obj/item/mod/control/Destroy()
- if(active)
- STOP_PROCESSING(SSobj, src)
+ STOP_PROCESSING(SSobj, src)
for(var/obj/item/mod/module/module as anything in modules)
uninstall(module, deleting = TRUE)
for(var/obj/item/part as anything in mod_parts)
@@ -174,6 +178,7 @@
if(core)
QDEL_NULL(core)
QDEL_NULL(wires)
+ QDEL_NULL(mod_link)
return ..()
/obj/item/mod/control/atom_destruction(damage_flag)
@@ -220,6 +225,7 @@
. += span_notice("You could install a pAI with a pAI card.") // SKYRAT EDIT CHANGE - ORIGINAL: . += span_notice("You could install an AI or pAI using their storage card.")
else if(isAI(ai_assistant))
. += span_notice("You could remove [ai_assistant] with an intellicard.")
+ . += span_notice("You could copy/set link frequency with a multitool.")
. += span_notice("You could examine it more thoroughly...")
/obj/item/mod/control/examine_more(mob/user)
@@ -229,13 +235,17 @@
/obj/item/mod/control/process(seconds_per_tick)
if(seconds_electrified > MACHINE_NOT_ELECTRIFIED)
seconds_electrified--
+ if(mod_link.link_call)
+ subtract_charge((DEFAULT_CHARGE_DRAIN * 0.25) * seconds_per_tick)
+ if(!active)
+ return
if(!get_charge() && active && !activating)
power_off()
- return PROCESS_KILL
+ return
var/malfunctioning_charge_drain = 0
if(malfunctioning)
malfunctioning_charge_drain = rand(1,20)
- subtract_charge((charge_drain + malfunctioning_charge_drain)*seconds_per_tick)
+ subtract_charge((charge_drain + malfunctioning_charge_drain) * seconds_per_tick)
update_charge_alert()
for(var/obj/item/mod/module/module as anything in modules)
if(malfunctioning && module.active && SPT_PROB(5, seconds_per_tick))
@@ -506,6 +516,7 @@
retract(null, part)
if(active)
finish_activation(on = FALSE)
+ mod_link?.end_call()
var/mob/old_wearer = wearer
unset_wearer()
old_wearer.temporarilyRemoveItemFromInventory(src)
@@ -600,6 +611,10 @@
QDEL_LIST_ASSOC_VAL(old_module.pinned_to)
old_module.mod = null
+/// Intended for callbacks, don't use normally, just get wearer by itself.
+/obj/item/mod/control/proc/get_wearer()
+ return wearer
+
/obj/item/mod/control/proc/update_access(mob/user, obj/item/card/id/card)
if(!allowed(user))
balloon_alert(user, "insufficient access!")
diff --git a/code/modules/mod/mod_link.dm b/code/modules/mod/mod_link.dm
new file mode 100644
index 00000000000..6c462718b3e
--- /dev/null
+++ b/code/modules/mod/mod_link.dm
@@ -0,0 +1,520 @@
+/proc/make_link_visual_generic(datum/mod_link/mod_link, proc_path)
+ var/mob/living/user = mod_link.get_user_callback.Invoke()
+ var/obj/effect/overlay/link_visual = new()
+ link_visual.name = "holocall ([mod_link.id])"
+ link_visual.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ LAZYADD(mod_link.holder.update_on_z, link_visual)
+ link_visual.appearance_flags |= KEEP_TOGETHER
+ link_visual.makeHologram(0.75)
+ mod_link.visual_overlays = user.overlays - user.active_thinking_indicator
+ link_visual.add_overlay(mod_link.visual_overlays)
+ mod_link.visual = link_visual
+ mod_link.holder.become_hearing_sensitive(REF(mod_link))
+ mod_link.holder.RegisterSignals(user, list(COMSIG_CARBON_APPLY_OVERLAY, COMSIG_CARBON_REMOVE_OVERLAY), proc_path)
+ return link_visual
+
+/proc/get_link_visual_generic(datum/mod_link/mod_link, atom/movable/visuals, proc_path)
+ var/mob/living/user = mod_link.get_user_callback.Invoke()
+ playsound(mod_link.holder, 'sound/machines/terminal_processing.ogg', 50, vary = TRUE)
+ visuals.add_overlay(mutable_appearance('icons/effects/effects.dmi', "static_base", TURF_LAYER))
+ visuals.add_overlay(mutable_appearance('icons/effects/effects.dmi', "modlink", ABOVE_ALL_MOB_LAYER))
+ visuals.add_filter("crop_square", 1, alpha_mask_filter(icon = icon('icons/effects/effects.dmi', "modlink_filter")))
+ visuals.maptext_height = 6
+ visuals.alpha = 0
+ user.vis_contents += visuals
+ visuals.forceMove(user)
+ animate(visuals, 0.5 SECONDS, alpha = 255)
+ var/datum/callback/setdir_callback = CALLBACK(mod_link.holder, proc_path)
+ setdir_callback.Invoke(user, user.dir, user.dir)
+ mod_link.holder.RegisterSignal(mod_link.holder.loc, COMSIG_ATOM_DIR_CHANGE, proc_path)
+
+/proc/delete_link_visual_generic(datum/mod_link/mod_link)
+ var/mob/living/user = mod_link.get_user_callback.Invoke()
+ playsound(mod_link.get_other().holder, 'sound/machines/terminal_processing.ogg', 50, vary = TRUE, frequency = -1)
+ LAZYREMOVE(mod_link.holder.update_on_z, mod_link.visual)
+ mod_link.holder.lose_hearing_sensitivity(REF(mod_link))
+ mod_link.holder.UnregisterSignal(user, list(COMSIG_CARBON_APPLY_OVERLAY, COMSIG_CARBON_REMOVE_OVERLAY, COMSIG_ATOM_DIR_CHANGE))
+ QDEL_NULL(mod_link.visual)
+
+/proc/on_user_set_dir_generic(datum/mod_link/mod_link, newdir)
+ var/atom/other_visual = mod_link.get_other().visual
+ if(!newdir) //can sometimes be null or 0
+ return
+ other_visual.setDir(SOUTH)
+ other_visual.pixel_x = 0
+ other_visual.pixel_y = 0
+ var/matrix/new_transform = matrix()
+ if(newdir & NORTH)
+ other_visual.pixel_y = 13
+ other_visual.layer = BELOW_MOB_LAYER
+ SET_PLANE_IMPLICIT(other_visual, GAME_PLANE_FOV_HIDDEN)
+ if(newdir & SOUTH)
+ other_visual.pixel_y = -24
+ other_visual.layer = ABOVE_ALL_MOB_LAYER
+ SET_PLANE_IMPLICIT(other_visual, GAME_PLANE_UPPER_FOV_HIDDEN)
+ new_transform.Scale(-1, 1)
+ new_transform.Translate(-1, 0)
+ if(newdir & EAST)
+ other_visual.pixel_x = 14
+ other_visual.layer = BELOW_MOB_LAYER
+ SET_PLANE_IMPLICIT(other_visual, GAME_PLANE_FOV_HIDDEN)
+ new_transform.Shear(0.5, 0)
+ new_transform.Scale(0.65, 1)
+ if(newdir & WEST)
+ other_visual.pixel_x = -14
+ other_visual.layer = BELOW_MOB_LAYER
+ SET_PLANE_IMPLICIT(other_visual, GAME_PLANE_FOV_HIDDEN)
+ new_transform.Shear(-0.5, 0)
+ new_transform.Scale(0.65, 1)
+ other_visual.transform = new_transform
+
+/obj/item/mod/control/Initialize(mapload, datum/mod_theme/new_theme, new_skin, obj/item/mod/core/new_core)
+ . = ..()
+ mod_link = new(
+ src,
+ starting_frequency,
+ CALLBACK(src, PROC_REF(get_wearer)),
+ CALLBACK(src, PROC_REF(can_call)),
+ CALLBACK(src, PROC_REF(make_link_visual)),
+ CALLBACK(src, PROC_REF(get_link_visual)),
+ CALLBACK(src, PROC_REF(delete_link_visual))
+ )
+
+/obj/item/mod/control/multitool_act_secondary(mob/living/user, obj/item/multitool/tool)
+ if(!multitool_check_buffer(user, tool))
+ return
+ var/tool_frequency = null
+ if(istype(tool.buffer, /datum/mod_link))
+ var/datum/mod_link/buffer_link = tool.buffer
+ tool_frequency = buffer_link.frequency
+ if(!tool_frequency && mod_link.frequency)
+ tool.set_buffer(mod_link)
+ else if(tool_frequency && !mod_link.frequency)
+ mod_link.frequency = tool_frequency
+ else if(tool_frequency && mod_link.frequency)
+ var/response = tgui_alert(user, "Would you like to copy or imprint the frequency?", "MODlink Frequency", list("Copy", "Imprint"))
+ if(!user.is_holding(tool))
+ return
+ switch(response)
+ if("Copy")
+ tool.set_buffer(mod_link)
+ if("Imprint")
+ mod_link.frequency = tool_frequency
+
+/obj/item/mod/control/proc/can_call()
+ return wearer && wearer.stat < DEAD
+
+/obj/item/mod/control/proc/make_link_visual()
+ return make_link_visual_generic(mod_link, PROC_REF(on_overlay_change))
+
+/obj/item/mod/control/proc/get_link_visual(atom/movable/visuals)
+ return get_link_visual_generic(mod_link, visuals, PROC_REF(on_wearer_set_dir))
+
+/obj/item/mod/control/proc/delete_link_visual()
+ return delete_link_visual_generic(mod_link)
+
+/obj/item/mod/control/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods, message_range)
+ . = ..()
+ if(speaker != wearer && speaker != ai_assistant)
+ return
+ mod_link.visual.say(raw_message, sanitize = FALSE, message_range = 2)
+
+/obj/item/mod/control/proc/on_overlay_change(atom/source, cache_index, overlay)
+ SIGNAL_HANDLER
+ addtimer(CALLBACK(src, PROC_REF(update_link_visual)), 1 TICKS, TIMER_UNIQUE)
+
+/obj/item/mod/control/proc/update_link_visual()
+ if(QDELETED(mod_link.link_call))
+ return
+ mod_link.visual.cut_overlay(mod_link.visual_overlays)
+ mod_link.visual_overlays = wearer.overlays - wearer.active_thinking_indicator
+ mod_link.visual.add_overlay(mod_link.visual_overlays)
+
+/obj/item/mod/control/proc/on_wearer_set_dir(atom/source, dir, newdir)
+ SIGNAL_HANDLER
+ on_user_set_dir_generic(mod_link, newdir)
+
+/obj/item/clothing/neck/link_scryer
+ name = "\improper MODlink scryer"
+ desc = "An intricate piece of machinery that creates a holographic video call with another MODlink-compatible device. Essentially a video necklace."
+ icon_state = "modlink"
+ actions_types = list(/datum/action/item_action/call_link)
+ /// The installed power cell.
+ var/obj/item/stock_parts/cell/cell
+ /// The MODlink datum we operate.
+ var/datum/mod_link/mod_link
+ /// Initial frequency of the MODlink.
+ var/starting_frequency = "NT"
+ /// An additional name tag for the scryer, seen as "MODlink scryer - [label]"
+ var/label
+
+/obj/item/clothing/neck/link_scryer/Initialize(mapload)
+ . = ..()
+ mod_link = new(
+ src,
+ starting_frequency,
+ CALLBACK(src, PROC_REF(get_user)),
+ CALLBACK(src, PROC_REF(can_call)),
+ CALLBACK(src, PROC_REF(make_link_visual)),
+ CALLBACK(src, PROC_REF(get_link_visual)),
+ CALLBACK(src, PROC_REF(delete_link_visual))
+ )
+ START_PROCESSING(SSobj, src)
+
+/obj/item/clothing/neck/link_scryer/Destroy()
+ QDEL_NULL(cell)
+ QDEL_NULL(mod_link)
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/item/clothing/neck/link_scryer/examine(mob/user)
+ . = ..()
+ if(cell)
+ . += span_notice("The battery charge reads [cell.percent()]%. Right-click with an empty hand to remove it.")
+ else
+ . += span_notice("It is missing a battery, one can be installed by clicking with a power cell on it.")
+ . += span_notice("The MODlink ID is [mod_link.id], frequency is [mod_link.frequency]. Right-click with multitool to copy/imprint frequency.")
+ . += span_notice("Use in hand to set name.")
+
+/obj/item/clothing/neck/link_scryer/equipped(mob/living/user, slot)
+ . = ..()
+ if(slot != ITEM_SLOT_NECK)
+ mod_link?.end_call()
+
+/obj/item/clothing/neck/link_scryer/dropped(mob/living/user)
+ . = ..()
+ mod_link?.end_call()
+
+/obj/item/clothing/neck/link_scryer/attack_self(mob/user, modifiers)
+ var/new_label = reject_bad_text(tgui_input_text(user, "Change the visible name", "Set Name", label, MAX_NAME_LEN))
+ if(!new_label)
+ balloon_alert(user, "invalid name!")
+ return
+ label = new_label
+ balloon_alert(user, "name set")
+ update_name()
+
+/obj/item/clothing/neck/link_scryer/process(seconds_per_tick)
+ if(!mod_link.link_call)
+ return
+ cell.use(min(20 * seconds_per_tick, cell.charge))
+
+/obj/item/clothing/neck/link_scryer/attackby(obj/item/attacked_by, mob/user, params)
+ . = ..()
+ if(cell || !istype(attacked_by, /obj/item/stock_parts/cell))
+ return
+ if(!user.transferItemToLoc(attacked_by, src))
+ return
+ cell = attacked_by
+ balloon_alert(user, "installed [cell.name]")
+
+/obj/item/clothing/neck/link_scryer/update_name(updates)
+ . = ..()
+ name = "[initial(name)][label ? " - [label]" : ""]"
+
+/obj/item/clothing/neck/link_scryer/Exited(atom/movable/gone, direction)
+ . = ..()
+ if(gone == cell)
+ cell = null
+
+/obj/item/clothing/neck/link_scryer/attack_hand_secondary(mob/user, list/modifiers)
+ if(!cell)
+ return SECONDARY_ATTACK_CONTINUE_CHAIN
+ balloon_alert(user, "removed [cell.name]")
+ user.put_in_hands(cell)
+ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+
+/obj/item/clothing/neck/link_scryer/multitool_act_secondary(mob/living/user, obj/item/multitool/tool)
+ if(!multitool_check_buffer(user, tool))
+ return
+ var/tool_frequency = null
+ if(istype(tool.buffer, /datum/mod_link))
+ var/datum/mod_link/buffer_link = tool.buffer
+ tool_frequency = buffer_link.frequency
+ if(!tool_frequency && mod_link.frequency)
+ tool.set_buffer(mod_link)
+ else if(tool_frequency && !mod_link.frequency)
+ mod_link.frequency = tool_frequency
+ else if(tool_frequency && mod_link.frequency)
+ var/response = tgui_alert(user, "Would you like to copy or imprint the frequency?", "MODlink Frequency", list("Copy", "Imprint"))
+ switch(response)
+ if("Copy")
+ tool.set_buffer(mod_link)
+ if("Imprint")
+ mod_link.frequency = tool_frequency
+
+/obj/item/clothing/neck/link_scryer/worn_overlays(mutable_appearance/standing, isinhands)
+ . = ..()
+ if(!QDELETED(mod_link.link_call))
+ . += mutable_appearance('icons/mob/clothing/neck.dmi', "modlink_active")
+
+/obj/item/clothing/neck/link_scryer/ui_action_click(mob/user)
+ if(mod_link.link_call)
+ mod_link.end_call()
+ else
+ call_link(user, mod_link)
+
+/obj/item/clothing/neck/link_scryer/proc/get_user()
+ var/mob/living/carbon/user = loc
+ return istype(user) && user.wear_neck == src ? user : null
+
+/obj/item/clothing/neck/link_scryer/proc/can_call()
+ var/mob/living/user = loc
+ return istype(user) && cell.charge && user.stat < DEAD
+
+/obj/item/clothing/neck/link_scryer/proc/make_link_visual()
+ var/mob/living/user = mod_link.get_user_callback.Invoke()
+ user.update_worn_neck()
+ return make_link_visual_generic(mod_link, PROC_REF(on_overlay_change))
+
+/obj/item/clothing/neck/link_scryer/proc/get_link_visual(atom/movable/visuals)
+ return get_link_visual_generic(mod_link, visuals, PROC_REF(on_user_set_dir))
+
+/obj/item/clothing/neck/link_scryer/proc/delete_link_visual()
+ var/mob/living/user = mod_link.get_user_callback.Invoke()
+ if(!QDELETED(user))
+ user.update_worn_neck()
+ return delete_link_visual_generic(mod_link)
+
+/obj/item/clothing/neck/link_scryer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods, message_range)
+ . = ..()
+ if(speaker != loc)
+ return
+ mod_link.visual.say(raw_message, sanitize = FALSE, message_range = 3)
+
+/obj/item/clothing/neck/link_scryer/proc/on_overlay_change(atom/source, cache_index, overlay)
+ SIGNAL_HANDLER
+ addtimer(CALLBACK(src, PROC_REF(update_link_visual)), 1 TICKS, TIMER_UNIQUE)
+
+/obj/item/clothing/neck/link_scryer/proc/update_link_visual()
+ if(QDELETED(mod_link.link_call))
+ return
+ var/mob/living/user = loc
+ mod_link.visual.cut_overlay(mod_link.visual_overlays)
+ mod_link.visual_overlays = user.overlays - user.active_thinking_indicator
+ mod_link.visual.add_overlay(mod_link.visual_overlays)
+
+/obj/item/clothing/neck/link_scryer/proc/on_user_set_dir(atom/source, dir, newdir)
+ SIGNAL_HANDLER
+ on_user_set_dir_generic(mod_link, newdir)
+
+/obj/item/clothing/neck/link_scryer/loaded/Initialize(mapload)
+ . = ..()
+ cell = new /obj/item/stock_parts/cell/high(src)
+
+/obj/item/clothing/neck/link_scryer/loaded/charlie
+ starting_frequency = MODLINK_FREQ_CHARLIE
+
+/// A MODlink datum, used to handle unique functions that will be used in the MODlink call.
+/datum/mod_link
+ /// The frequency of the MODlink. You can only call other MODlinks on the same frequency.
+ var/frequency
+ /// The unique ID of the MODlink.
+ var/id = ""
+ /// The atom that holds the MODlink.
+ var/atom/movable/holder
+ /// A reference to the visuals generated by the MODlink.
+ var/atom/movable/visual
+ /// A list of all overlays of the user, copied everytime they have an overlay change.
+ var/list/visual_overlays = list()
+ /// A reference to the call between two MODlinks.
+ var/datum/mod_link_call/link_call
+ /// A callback that returns the user of the MODlink.
+ var/datum/callback/get_user_callback
+ /// A callback that returns whether the MODlink can currently call.
+ var/datum/callback/can_call_callback
+ /// A callback that returns the visuals of the MODlink.
+ var/datum/callback/make_visual_callback
+ /// A callback that receives the visuals of the other MODlink.
+ var/datum/callback/get_visual_callback
+ /// A callback that deletes the visuals of the MODlink.
+ var/datum/callback/delete_visual_callback
+
+/datum/mod_link/New(
+ atom/holder,
+ frequency,
+ datum/callback/get_user_callback,
+ datum/callback/can_call_callback,
+ datum/callback/make_visual_callback,
+ datum/callback/get_visual_callback,
+ datum/callback/delete_visual_callback
+)
+ var/attempts = 0
+ var/digits_to_make = 3
+ do
+ if(attempts == 10)
+ attempts = 0
+ digits_to_make++
+ id = ""
+ for(var/i in 1 to digits_to_make)
+ id += num2text(rand(0,9))
+ attempts++
+ while(GLOB.mod_link_ids[id])
+ GLOB.mod_link_ids[id] = src
+ src.frequency = frequency
+ src.holder = holder
+ src.get_user_callback = get_user_callback
+ src.can_call_callback = can_call_callback
+ src.make_visual_callback = make_visual_callback
+ src.get_visual_callback = get_visual_callback
+ src.delete_visual_callback = delete_visual_callback
+ RegisterSignal(holder, COMSIG_QDELETING, PROC_REF(on_holder_delete))
+
+/datum/mod_link/Destroy()
+ GLOB.mod_link_ids -= id
+ if(link_call)
+ end_call()
+ return ..()
+
+/datum/mod_link/proc/get_other()
+ RETURN_TYPE(/datum/mod_link)
+ if(!link_call)
+ return
+ return link_call.caller == src ? link_call.receiver : link_call.caller
+
+/datum/mod_link/proc/call_link(datum/mod_link/called, mob/user)
+ if(!frequency)
+ return
+ if(!istype(called))
+ holder.balloon_alert(user, "invalid target!")
+ return
+ var/mob/living/link_user = get_user_callback.Invoke()
+ if(!link_user)
+ return
+ if(HAS_TRAIT(link_user, TRAIT_IN_CALL))
+ holder.balloon_alert(user, "user already in call!")
+ return
+ var/mob/living/link_target = called.get_user_callback.Invoke()
+ if(!link_target)
+ holder.balloon_alert(user, "invalid target!")
+ return
+ if(HAS_TRAIT(link_target, TRAIT_IN_CALL))
+ holder.balloon_alert(user, "target already in call!")
+ return
+ if(!can_call_callback.Invoke() || !called.can_call_callback.Invoke())
+ holder.balloon_alert(user, "can't call!")
+ return
+ link_target.playsound_local(get_turf(called.holder), 'sound/weapons/ring.ogg', 15, vary = TRUE)
+ var/atom/movable/screen/alert/modlink_call/alert = link_target.throw_alert("[REF(src)]_modlink", /atom/movable/screen/alert/modlink_call)
+ alert.desc = "[holder] ([id]) is calling you! Left-click this to accept the call. Right-click to deny it."
+ alert.caller_ref = WEAKREF(src)
+ alert.receiver_ref = WEAKREF(called)
+ alert.user_ref = WEAKREF(user)
+
+/datum/mod_link/proc/end_call()
+ QDEL_NULL(link_call)
+
+/datum/mod_link/proc/on_holder_delete(atom/source)
+ SIGNAL_HANDLER
+ qdel(src)
+
+/// A MODlink call datum, used to handle the call between two MODlinks.
+/datum/mod_link_call
+ /// The MODlink that is calling.
+ var/datum/mod_link/caller
+ /// The MODlink that is being called.
+ var/datum/mod_link/receiver
+
+/datum/mod_link_call/New(datum/mod_link/caller, datum/mod_link/receiver)
+ caller.link_call = src
+ receiver.link_call = src
+ src.caller = caller
+ src.receiver = receiver
+ var/mob/living/caller_mob = caller.get_user_callback.Invoke()
+ ADD_TRAIT(caller_mob, TRAIT_IN_CALL, REF(src))
+ var/mob/living/receiver_mob = receiver.get_user_callback.Invoke()
+ ADD_TRAIT(receiver_mob, TRAIT_IN_CALL, REF(src))
+ make_visuals()
+ START_PROCESSING(SSprocessing, src)
+
+/datum/mod_link_call/Destroy()
+ var/mob/living/caller_mob = caller.get_user_callback.Invoke()
+ if(!QDELETED(caller_mob))
+ REMOVE_TRAIT(caller_mob, TRAIT_IN_CALL, REF(src))
+ var/mob/living/receiver_mob = receiver.get_user_callback.Invoke()
+ if(!QDELETED(receiver_mob))
+ REMOVE_TRAIT(receiver_mob, TRAIT_IN_CALL, REF(src))
+ STOP_PROCESSING(SSprocessing, src)
+ clear_visuals()
+ caller.link_call = null
+ receiver.link_call = null
+ return ..()
+
+/datum/mod_link_call/process(seconds_per_tick)
+ if(can_continue_call())
+ return
+ qdel(src)
+
+/datum/mod_link_call/proc/can_continue_call()
+ return caller.frequency == receiver.frequency && caller.can_call_callback.Invoke() && receiver.can_call_callback.Invoke()
+
+/datum/mod_link_call/proc/make_visuals()
+ var/caller_visual = caller.make_visual_callback.Invoke()
+ var/receiver_visual = receiver.make_visual_callback.Invoke()
+ caller.get_visual_callback.Invoke(receiver_visual)
+ receiver.get_visual_callback.Invoke(caller_visual)
+
+/datum/mod_link_call/proc/clear_visuals()
+ caller.delete_visual_callback.Invoke()
+ receiver.delete_visual_callback.Invoke()
+
+/proc/call_link(mob/user, datum/mod_link/calling_link)
+ if(!calling_link.frequency)
+ return
+ var/list/callers = list()
+ for(var/id in GLOB.mod_link_ids)
+ var/datum/mod_link/link = GLOB.mod_link_ids[id]
+ if(link.frequency != calling_link.frequency)
+ continue
+ if(link == calling_link)
+ continue
+ if(!link.can_call_callback.Invoke())
+ continue
+ callers["[link.holder] ([id])"] = id
+ if(!length(callers))
+ calling_link.holder.balloon_alert(user, "no targets on freq [calling_link.frequency]!")
+ return
+ var/chosen_link = tgui_input_list(user, "Choose ID to call from [calling_link.frequency] frequency", "MODlink", callers)
+ if(!chosen_link)
+ return
+ calling_link.call_link(GLOB.mod_link_ids[callers[chosen_link]], user)
+
+/atom/movable/screen/alert/modlink_call
+ name = "MODlink Call Incoming"
+ desc = "Someone is calling you! Left-click this to accept the call. Right-click to deny it."
+ icon_state = "called"
+ timeout = 10 SECONDS
+ var/end_message = "call timed out!"
+ /// A weak reference to the MODlink that is calling.
+ var/datum/weakref/caller_ref
+ /// A weak reference to the MODlink that is being called.
+ var/datum/weakref/receiver_ref
+ /// A weak reference to the mob that is calling.
+ var/datum/weakref/user_ref
+
+/atom/movable/screen/alert/modlink_call/Click(location, control, params)
+ . = ..()
+ if(usr != owner)
+ return
+ var/datum/mod_link/caller = caller_ref.resolve()
+ var/datum/mod_link/receiver = receiver_ref.resolve()
+ if(!caller || !receiver)
+ return
+ if(caller.link_call || receiver.link_call)
+ return
+ var/list/modifiers = params2list(params)
+ if(LAZYACCESS(modifiers, RIGHT_CLICK))
+ end_message = "call denied!"
+ owner.clear_alert("[REF(caller)]_modlink")
+ return
+ end_message = "call accepted"
+ new /datum/mod_link_call(caller, receiver)
+ owner.clear_alert("[REF(caller)]_modlink")
+
+/atom/movable/screen/alert/modlink_call/Destroy()
+ var/mob/living/user = user_ref?.resolve()
+ var/datum/mod_link/caller = caller_ref?.resolve()
+ if(!user || !caller)
+ return ..()
+ caller.holder.balloon_alert(user, end_message)
+ return ..()
diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm
index 512dd143d57..521dd6f0240 100644
--- a/code/modules/mod/mod_theme.dm
+++ b/code/modules/mod/mod_theme.dm
@@ -306,7 +306,7 @@
the bare essentials, geared far more for environmental hazards than combat against fauna; however, \
this gives way to incredible protection against corrosives and thermal protection good enough for \
both casual backstroking through molten magma and romantic walks through arctic terrain. \
- Instead, the suit is capable of using its' anomalous properties to attract and \
+ Instead, the suit is capable of using its anomalous properties to attract and \
carefully distribute layers of ash or ice across the surface; these layers are ablative, but incredibly strong. \
Lastly, the suit is capable of compressing and shrinking the mass of the wearer, as well as \
rearranging its own constitution, to allow them to fit upright in a sphere form that can \
@@ -1437,7 +1437,7 @@
/datum/mod_theme/responsory
name = "responsory"
- desc = "A high-speed rescue suit by Nanotrasen, intended for its' emergency response teams."
+ desc = "A high-speed rescue suit by Nanotrasen, intended for its emergency response teams."
extended_desc = "A streamlined suit of Nanotrasen design, these sleek black suits are only worn by \
elite emergency response personnel to help save the day. While the slim and nimble design of the suit \
cuts the ceramics and ablatives in it down, dropping the protection, \
diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm
index e820525ff9a..75ab14a77f1 100644
--- a/code/modules/mod/mod_types.dm
+++ b/code/modules/mod/mod_types.dm
@@ -1,4 +1,5 @@
/obj/item/mod/control/pre_equipped
+ starting_frequency = MODLINK_FREQ_NANOTRASEN
/// The skin we apply to the suit, defaults to the default_skin of the theme.
var/applied_skin
/// The MOD core we apply to the suit.
@@ -196,6 +197,7 @@
/obj/item/mod/control/pre_equipped/traitor
theme = /datum/mod_theme/syndicate
+ starting_frequency = MODLINK_FREQ_SYNDICATE
applied_cell = /obj/item/stock_parts/cell/super
applied_modules = list(
/obj/item/mod/module/storage/syndicate,
@@ -213,6 +215,7 @@
/obj/item/mod/control/pre_equipped/traitor_elite
theme = /datum/mod_theme/elite
+ starting_frequency = MODLINK_FREQ_SYNDICATE
applied_cell = /obj/item/stock_parts/cell/bluespace
applied_modules = list(
/obj/item/mod/module/storage/syndicate,
@@ -229,6 +232,7 @@
/obj/item/mod/control/pre_equipped/nuclear
theme = /datum/mod_theme/syndicate
+ starting_frequency = MODLINK_FREQ_SYNDICATE
applied_cell = /obj/item/stock_parts/cell/hyper
req_access = list(ACCESS_SYNDICATE)
applied_modules = list(
@@ -248,6 +252,7 @@
/obj/item/mod/control/pre_equipped/elite
theme = /datum/mod_theme/elite
+ starting_frequency = MODLINK_FREQ_SYNDICATE
applied_cell = /obj/item/stock_parts/cell/bluespace
req_access = list(ACCESS_SYNDICATE)
applied_modules = list(
@@ -280,6 +285,7 @@
/obj/item/mod/control/pre_equipped/infiltrator
theme = /datum/mod_theme/infiltrator
+ starting_frequency = MODLINK_FREQ_SYNDICATE
applied_cell = /obj/item/stock_parts/cell/super
applied_modules = list(
/obj/item/mod/module/emp_shield,
@@ -291,6 +297,7 @@
/obj/item/mod/control/pre_equipped/interdyne
theme = /datum/mod_theme/interdyne
+ starting_frequency = MODLINK_FREQ_SYNDICATE
applied_cell = /obj/item/stock_parts/cell/super
applied_modules = list(
/obj/item/mod/module/defibrillator/combat,
@@ -304,6 +311,7 @@
/obj/item/mod/control/pre_equipped/enchanted
theme = /datum/mod_theme/enchanted
+ starting_frequency = null
applied_core = /obj/item/mod/core/infinite
applied_modules = list(
/obj/item/mod/module/storage/large_capacity,
@@ -313,6 +321,7 @@
/obj/item/mod/control/pre_equipped/ninja
theme = /datum/mod_theme/ninja
+ starting_frequency = null
applied_cell = /obj/item/stock_parts/cell/ninja
applied_modules = list(
/obj/item/mod/module/storage,
@@ -334,6 +343,7 @@
/obj/item/mod/control/pre_equipped/prototype
theme = /datum/mod_theme/prototype
+ starting_frequency = MODLINK_FREQ_CHARLIE
req_access = list(ACCESS_AWAY_GENERAL)
applied_modules = list(
/obj/item/mod/module/storage,
@@ -349,6 +359,7 @@
/obj/item/mod/control/pre_equipped/responsory
theme = /datum/mod_theme/responsory
+ starting_frequency = MODLINK_FREQ_CENTCOM
applied_cell = /obj/item/stock_parts/cell/hyper
req_access = list(ACCESS_CENT_GENERAL)
applied_modules = list(
@@ -427,6 +438,7 @@
/obj/item/mod/control/pre_equipped/apocryphal
theme = /datum/mod_theme/apocryphal
+ starting_frequency = MODLINK_FREQ_CENTCOM
applied_cell = /obj/item/stock_parts/cell/bluespace
req_access = list(ACCESS_CENT_SPECOPS)
applied_modules = list(
@@ -452,6 +464,7 @@
/obj/item/mod/control/pre_equipped/corporate
theme = /datum/mod_theme/corporate
+ starting_frequency = MODLINK_FREQ_CENTCOM
applied_core = /obj/item/mod/core/infinite
req_access = list(ACCESS_CENT_SPECOPS)
applied_modules = list(
@@ -463,6 +476,7 @@
/obj/item/mod/control/pre_equipped/chrono
theme = /datum/mod_theme/chrono
+ starting_frequency = null
applied_core = /obj/item/mod/core/infinite
applied_modules = list(
/obj/item/mod/module/eradication_lock,
@@ -483,6 +497,7 @@
/obj/item/mod/control/pre_equipped/debug
theme = /datum/mod_theme/debug
+ starting_frequency = null
applied_core = /obj/item/mod/core/infinite
applied_modules = list( //one of every type of module, for testing if they all work correctly
/obj/item/mod/module/storage/bluespace,
@@ -496,6 +511,7 @@
/obj/item/mod/control/pre_equipped/administrative
theme = /datum/mod_theme/administrative
+ starting_frequency = MODLINK_FREQ_CENTCOM
applied_core = /obj/item/mod/core/infinite
applied_modules = list(
/obj/item/mod/module/storage/bluespace,
@@ -516,6 +532,7 @@
//these exist for the prefs menu
/obj/item/mod/control/pre_equipped/empty
+ starting_frequency = null
/obj/item/mod/control/pre_equipped/empty/syndicate
theme = /datum/mod_theme/syndicate
diff --git a/code/modules/mod/mod_ui.dm b/code/modules/mod/mod_ui.dm
index cbf30fe1611..06f89ddb03c 100644
--- a/code/modules/mod/mod_ui.dm
+++ b/code/modules/mod/mod_ui.dm
@@ -15,6 +15,8 @@
"ai_name" = ai_assistant?.name,
"has_pai" = ispAI(ai_assistant),
"is_ai" = ai_assistant && ai_assistant == user,
+ "link_id" = mod_link.id,
+ "link_call" = mod_link.get_other()?.id,
// Wires
"open" = open,
"seconds_electrified" = seconds_electrified,
@@ -76,10 +78,6 @@
. = ..()
if(.)
return
- if(locked && (!allowed(usr) || !ispAI(usr))) // pAIs automatically fail out of allowed()
- balloon_alert(usr, "insufficient access!")
- playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
- return
if(malfunctioning && prob(75))
balloon_alert(usr, "button malfunctions!")
return
@@ -87,6 +85,11 @@
if("lock")
locked = !locked
balloon_alert(usr, "[locked ? "locked" : "unlocked"]!")
+ if("call")
+ if(!mod_link.link_call)
+ call_link(usr, mod_link)
+ else
+ mod_link.end_call()
if("activate")
toggle_activate(usr)
if("select")
diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm
index befa61d24ec..8d62bf784cb 100644
--- a/code/modules/paperwork/ticketmachine.dm
+++ b/code/modules/paperwork/ticketmachine.dm
@@ -54,7 +54,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/ticket_machine, 32)
if(!multitool_check_buffer(user, I)) //make sure it has a data buffer
return
var/obj/item/multitool/M = I
- M.buffer = src
+ M.set_buffer(src)
to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
return TRUE
diff --git a/code/modules/plumbing/plumbers/teleporter.dm b/code/modules/plumbing/plumbers/teleporter.dm
index a003a1528b8..7b3a62c9939 100644
--- a/code/modules/plumbing/plumbers/teleporter.dm
+++ b/code/modules/plumbing/plumbers/teleporter.dm
@@ -72,7 +72,7 @@
return
var/obj/item/multitool/M = I
- M.buffer = src
+ M.set_buffer(src)
to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
return TRUE
diff --git a/code/modules/power/turbine/turbine.dm b/code/modules/power/turbine/turbine.dm
index 2888bedbd0e..fedfd42014e 100644
--- a/code/modules/power/turbine/turbine.dm
+++ b/code/modules/power/turbine/turbine.dm
@@ -421,7 +421,7 @@
//log rotor to link later to computer
balloon_alert(user, "all parts linked")
var/obj/item/multitool/multitool = tool
- multitool.buffer = src
+ multitool.set_buffer(src)
to_chat(user, span_notice("You store linkage information in [tool]'s buffer."))
//success
diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm
index a3167d28f39..a9afd6b3a08 100644
--- a/code/modules/research/designs/mechfabricator_designs.dm
+++ b/code/modules/research/designs/mechfabricator_designs.dm
@@ -1515,6 +1515,18 @@
RND_CATEGORY_MODSUITS + RND_SUBCATEGORY_MODSUITS_MISC
)
+/datum/design/modlink_scryer
+ name = "MODlink Scryer"
+ desc = "A neck-worn piece of gear that can call with another MODlink-compatible device."
+ id = "modlink_scryer"
+ build_type = MECHFAB
+ materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/gold = SMALL_MATERIAL_AMOUNT * 3, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 3)
+ construction_time = 5 SECONDS
+ build_path = /obj/item/clothing/neck/link_scryer
+ category = list(
+ RND_CATEGORY_MODSUITS + RND_SUBCATEGORY_MODSUITS_MISC
+ )
+
//MODsuit modules
/datum/design/module
diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm
index cb54716675e..7665082f698 100644
--- a/code/modules/research/server.dm
+++ b/code/modules/research/server.dm
@@ -102,7 +102,7 @@
/obj/machinery/rnd/server/multitool_act(mob/living/user, obj/item/multitool/tool)
if(!stored_research)
return
- tool.buffer = stored_research
+ tool.set_buffer(stored_research)
to_chat(user, span_notice("Stored [src]'s techweb information in [tool]."))
return TRUE
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 1b4701d6914..4a8a6305406 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -1741,6 +1741,7 @@
"mod_clamp",
"mod_drill",
"mod_orebag",
+ "modlink_scryer",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm
index eb277b9f681..9ac99c86b3c 100644
--- a/code/modules/station_goals/bsa.dm
+++ b/code/modules/station_goals/bsa.dm
@@ -56,7 +56,7 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE)
if(!multitool_check_buffer(user, I)) //make sure it has a data buffer
return
var/obj/item/multitool/M = I
- M.buffer = src
+ M.set_buffer(src)
to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
return TRUE
@@ -73,7 +73,7 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE)
if(!multitool_check_buffer(user, I)) //make sure it has a data buffer
return
var/obj/item/multitool/M = I
- M.buffer = src
+ M.set_buffer(src)
to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
return TRUE
@@ -96,11 +96,11 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE)
if(istype(M.buffer, /obj/machinery/bsa/back))
back_ref = WEAKREF(M.buffer)
to_chat(user, span_notice("You link [src] with [M.buffer]."))
- M.buffer = null
+ M.set_buffer(null)
else if(istype(M.buffer, /obj/machinery/bsa/front))
front_ref = WEAKREF(M.buffer)
to_chat(user, span_notice("You link [src] with [M.buffer]."))
- M.buffer = null
+ M.set_buffer(null)
else
to_chat(user, span_warning("[I]'s data buffer is empty!"))
return TRUE
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 4feb3a8eb54..17292014aeb 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/hud/screen_alert.dmi b/icons/hud/screen_alert.dmi
index 7cc03330969..f4911e45bc4 100755
Binary files a/icons/hud/screen_alert.dmi and b/icons/hud/screen_alert.dmi differ
diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi
index e0528491403..0750f61bd82 100644
Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ
diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi
index acd00a44889..ff7e012324a 100644
Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 3ad66afcd8c..91189e974c3 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2676,6 +2676,7 @@
#include "code\modules\admin\view_variables\mark_datum.dm"
#include "code\modules\admin\view_variables\mass_edit_variables.dm"
#include "code\modules\admin\view_variables\modify_variables.dm"
+#include "code\modules\admin\view_variables\nobody_wants_to_learn_matrix_math.dm"
#include "code\modules\admin\view_variables\particle_editor.dm"
#include "code\modules\admin\view_variables\reference_tracking.dm"
#include "code\modules\admin\view_variables\tag_datum.dm"
@@ -4623,6 +4624,7 @@
#include "code\modules\mod\mod_construction.dm"
#include "code\modules\mod\mod_control.dm"
#include "code\modules\mod\mod_core.dm"
+#include "code\modules\mod\mod_link.dm"
#include "code\modules\mod\mod_paint.dm"
#include "code\modules\mod\mod_theme.dm"
#include "code\modules\mod\mod_types.dm"
diff --git a/tgui/packages/tgui/interfaces/MODsuit.tsx b/tgui/packages/tgui/interfaces/MODsuit.tsx
index 6e737792447..593dc109bf8 100644
--- a/tgui/packages/tgui/interfaces/MODsuit.tsx
+++ b/tgui/packages/tgui/interfaces/MODsuit.tsx
@@ -35,6 +35,8 @@ type SuitStatus = {
ai_name: string;
has_pai: boolean;
is_ai: boolean;
+ link_id: string;
+ link_call: string;
};
type UserStatus = {
@@ -317,6 +319,8 @@ const SuitStatusSection = (props, context) => {
ai_name,
has_pai,
is_ai,
+ link_id,
+ link_call,
} = data.suit_status;
const { display_time, shift_time, shift_id } = data.module_custom_status;
const status = malfunctioning
@@ -377,6 +381,19 @@ const SuitStatusSection = (props, context) => {
onClick={() => act('lock')}
/>
+
+
{!!open && (
Open
diff --git a/tgui/packages/tgui/interfaces/MatrixMathTester.tsx b/tgui/packages/tgui/interfaces/MatrixMathTester.tsx
new file mode 100644
index 00000000000..aa0637b78d7
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/MatrixMathTester.tsx
@@ -0,0 +1,226 @@
+import { useBackend, useLocalState } from '../backend';
+import { Input, NumberInput, Section, Button, Table } from '../components';
+import { toFixed } from 'common/math';
+import { Window } from '../layouts';
+
+const MatrixMathTesterInput = (
+ props: { value: number; varName: string },
+ context
+) => {
+ const { act } = useBackend(context);
+ return (
+ toFixed(value, 3)}
+ width={'100%'}
+ onChange={(e, value) =>
+ act('change_var', { var_name: props.varName, var_value: value })
+ }
+ />
+ );
+};
+
+type MatrixData = {
+ matrix_a: number;
+ matrix_b: number;
+ matrix_c: number;
+ matrix_d: number;
+ matrix_e: number;
+ matrix_f: number;
+ pixelated: boolean;
+};
+
+export const MatrixMathTester = (props, context) => {
+ const { act, data } = useBackend(context);
+ const {
+ matrix_a,
+ matrix_b,
+ matrix_c,
+ matrix_d,
+ matrix_e,
+ matrix_f,
+ pixelated,
+ } = data;
+ const [scaleX, setScaleX] = useLocalState(context, 'scale_x', 1);
+ const [scaleY, setScaleY] = useLocalState(context, 'scale_y', 1);
+ const [translateX, setTranslateX] = useLocalState(context, 'translate_x', 0);
+ const [translateY, setTranslateY] = useLocalState(context, 'translate_y', 0);
+ const [shearX, setShearX] = useLocalState(context, 'shear_x', 0);
+ const [shearY, setShearY] = useLocalState(context, 'shear_y', 0);
+ const [angle, setAngle] = useLocalState(context, 'angle', 0);
+ return (
+
+
+
+
+
+
+ Action
+ X
+ Y
+
+
+
+
+
+ toFixed(value, 2)}
+ width={'100%'}
+ onChange={(e, value) => setScaleX(value)}
+ />
+
+
+ toFixed(value, 2)}
+ width={'100%'}
+ onChange={(e, value) => setScaleY(value)}
+ />
+
+
+
+
+
+
+ toFixed(value, 0)}
+ width={'100%'}
+ onChange={(e, value) => setTranslateX(value)}
+ />
+
+
+ toFixed(value, 0)}
+ width={'100%'}
+ onChange={(e, value) => setTranslateY(value)}
+ />
+
+
+
+
+
+
+ toFixed(value, 3)}
+ width={'100%'}
+ onChange={(e, value) => setShearX(value)}
+ />
+
+
+ toFixed(value, 3)}
+ width={'100%'}
+ onChange={(e, value) => setShearY(value)}
+ />
+
+
+
+
+
+
+ toFixed(value, 1)}
+ width={'100%'}
+ onChange={(e, value) => setAngle(value)}
+ />
+
+
+
+
+
+
+
+
+ );
+};