diff --git a/.github/workflows/autobuild_tgui.yml b/.github/workflows/autobuild_tgui.yml
new file mode 100644
index 0000000000..b680139f74
--- /dev/null
+++ b/.github/workflows/autobuild_tgui.yml
@@ -0,0 +1,36 @@
+name: Autobuild TGUI
+
+on:
+ push:
+ branches:
+ - 'master'
+ paths:
+ - 'tgui-next/**.js'
+ - 'tgui-next/**.scss'
+
+jobs:
+ build:
+ name: Rebuild TGUI
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v1
+ with:
+ fetch-depth: 25
+ - name: Setup Node
+ uses: actions/setup-node@v1
+ with:
+ node-version: '>=12.13'
+ - name: Build TGUI
+ run: bin/tgui --ci
+ working-directory: ./tgui-next
+ - name: Commit Artifacts
+ run: |
+ git config --local user.email "action@github.com"
+ git config --local user.name "TGUI"
+ git pull origin master
+ git commit -m "Automatic TGUI Rebuild [ci skip]" -a || true
+ - name: Push Artifacts
+ uses: ad-m/github-push-action@master
+ with:
+ github_token: ${{ secrets.GITHUB_MASTER_KEY }}
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm
index 2c6eda9f90..d01e4f8da1 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm
@@ -18,6 +18,9 @@
/obj/item/mining_scanner,
/obj/item/flashlight/lantern,
/obj/item/card/id/mining,
+/obj/item/gps/mining{
+ tracking = 0
+ },
/turf/open/floor/plating,
/area/ruin/powered/golem_ship)
"d" = (
@@ -31,6 +34,9 @@
/obj/item/mining_scanner,
/obj/item/flashlight/lantern,
/obj/item/card/id/mining,
+/obj/item/gps/mining{
+ tracking = 0
+ },
/turf/open/floor/plating,
/area/ruin/powered/golem_ship)
"e" = (
@@ -150,6 +156,9 @@
"x" = (
/obj/structure/table/wood,
/obj/machinery/reagentgrinder,
+/obj/item/gps/mining{
+ tracking = 0
+ },
/turf/open/floor/mineral/titanium/purple,
/area/ruin/powered/golem_ship)
"z" = (
diff --git a/_maps/RandomRuins/StationRuins/Box/Engine/engine_singulo.dmm b/_maps/RandomRuins/StationRuins/Box/Engine/engine_singulo.dmm
index 76cb8bb9db..402cfc73cf 100644
--- a/_maps/RandomRuins/StationRuins/Box/Engine/engine_singulo.dmm
+++ b/_maps/RandomRuins/StationRuins/Box/Engine/engine_singulo.dmm
@@ -735,7 +735,7 @@
/obj/machinery/atmospherics/components/unary/outlet_injector{
dir = 1
},
-/turf/open/space/basic,
+/turf/open/floor/plating/airless,
/area/engine/engineering)
"Si" = (
/obj/structure/cable/yellow{
diff --git a/_maps/RandomRuins/StationRuins/Box/Engine/engine_tesla.dmm b/_maps/RandomRuins/StationRuins/Box/Engine/engine_tesla.dmm
index 7f55d69b17..af2ba1ffd7 100644
--- a/_maps/RandomRuins/StationRuins/Box/Engine/engine_tesla.dmm
+++ b/_maps/RandomRuins/StationRuins/Box/Engine/engine_tesla.dmm
@@ -240,7 +240,7 @@
/obj/machinery/atmospherics/components/unary/outlet_injector{
dir = 1
},
-/turf/open/space/basic,
+/turf/open/floor/plating/airless,
/area/engine/engineering)
"nR" = (
/obj/structure/cable{
@@ -905,14 +905,6 @@
},
/turf/open/space/basic,
/area/space/nearstation)
-"VR" = (
-/obj/structure/lattice/catwalk,
-/obj/machinery/camera/emp_proof{
- c_tag = "Tesla Engine Northeast";
- network = list("ss13","engine")
- },
-/turf/open/space/basic,
-/area/space/nearstation)
"Wf" = (
/obj/effect/turf_decal/stripes/line{
dir = 9
@@ -1728,7 +1720,7 @@ dz
dz
FP
FP
-VR
+FP
dz
dz
Yl
diff --git a/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm b/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm
index fec45c7310..3118ad3f5f 100644
--- a/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm
+++ b/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm
@@ -64,6 +64,9 @@
/turf/open/floor/plating,
/area/mine/living_quarters)
"aN" = (
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
/turf/open/floor/plasteel/white,
/area/mine/laborcamp)
"aW" = (
@@ -82,24 +85,10 @@
"bg" = (
/turf/closed/wall,
/area/mine/eva)
-"bH" = (
-/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/atmos_waste{
- dir = 4;
- piping_layer = 3
- },
-/obj/structure/lattice/catwalk,
-/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
-/area/mine/living_quarters)
-"bI" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3,
-/obj/machinery/atmospherics/pipe/simple/supply/hidden,
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/obj/structure/cable{
- icon_state = "2-8"
- },
-/turf/open/floor/plasteel,
+"bn" = (
+/obj/structure/cable,
+/obj/effect/spawner/structure/window/reinforced,
+/turf/open/floor/plating,
/area/mine/living_quarters)
"bX" = (
/obj/machinery/door/window/southleft,
@@ -174,13 +163,6 @@
},
/turf/open/floor/plasteel,
/area/mine/living_quarters)
-"di" = (
-/obj/machinery/light{
- dir = 4
- },
-/obj/effect/turf_decal/tile/brown,
-/turf/open/floor/plasteel,
-/area/mine/living_quarters)
"dk" = (
/obj/structure/table,
/obj/item/stack/packageWrap,
@@ -192,12 +174,6 @@
},
/turf/open/floor/plasteel,
/area/mine/eva)
-"dC" = (
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/turf/open/floor/plasteel,
-/area/mine/living_quarters)
"dL" = (
/obj/machinery/atmospherics/components/binary/pump/on,
/obj/structure/cable{
@@ -220,6 +196,15 @@
},
/turf/open/floor/plasteel,
/area/mine/production)
+"dU" = (
+/obj/structure/cable{
+ icon_state = "1-4"
+ },
+/obj/structure/sign/warning/electricshock{
+ pixel_y = -32
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp/security)
"dZ" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -301,6 +286,21 @@
},
/turf/open/floor/plasteel,
/area/mine/laborcamp)
+"fx" = (
+/obj/machinery/light/small{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp/security)
+"fA" = (
+/obj/machinery/power/terminal{
+ dir = 4
+ },
+/obj/machinery/power/port_gen/pacman{
+ anchored = 1
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp/security)
"fN" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 5
@@ -308,6 +308,12 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
dir = 5
},
+/obj/structure/cable{
+ icon_state = "1-4"
+ },
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"fO" = (
@@ -349,9 +355,18 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/mine/production)
+"gn" = (
+/obj/structure/cable{
+ icon_state = "1-4"
+ },
+/turf/open/floor/plasteel,
+/area/mine/laborcamp)
"gs" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp)
"gP" = (
@@ -376,6 +391,15 @@
},
/turf/open/floor/plasteel/white,
/area/mine/laborcamp)
+"hb" = (
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/obj/machinery/power/smes{
+ charge = 5e+006
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp/security)
"hf" = (
/obj/item/twohanded/required/kirbyplants/random,
/turf/open/floor/plasteel,
@@ -387,14 +411,6 @@
},
/turf/open/floor/plasteel,
/area/mine/living_quarters)
-"hv" = (
-/obj/machinery/camera{
- c_tag = "Crew Area Hallway West";
- dir = 1;
- network = list("mine")
- },
-/turf/open/floor/plasteel,
-/area/mine/living_quarters)
"hy" = (
/obj/machinery/camera{
c_tag = "Labor Camp External";
@@ -415,25 +431,21 @@
/turf/open/floor/plasteel,
/area/mine/living_quarters)
"hP" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
- dir = 4
+/obj/structure/lattice/catwalk,
+/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/atmos_waste{
+ dir = 4;
+ piping_layer = 3
},
-/obj/machinery/atmospherics/pipe/simple/supply/hidden{
- dir = 4
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/turf/open/floor/plasteel,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/mine/living_quarters)
"hQ" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden,
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3,
-/obj/structure/cable{
- icon_state = "1-2"
+/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/atmos_waste{
+ dir = 1;
+ piping_layer = 3
},
-/turf/open/floor/plasteel,
-/area/mine/living_quarters)
+/obj/structure/lattice/catwalk,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/mine/laborcamp/security)
"ia" = (
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
@@ -582,6 +594,14 @@
},
/turf/open/floor/plasteel,
/area/mine/living_quarters)
+"kP" = (
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable,
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp)
"kR" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 4
@@ -630,6 +650,9 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
dir = 6
},
+/obj/structure/cable{
+ icon_state = "2-4"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp)
"lI" = (
@@ -715,6 +738,9 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
dir = 4
},
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"mN" = (
@@ -733,13 +759,11 @@
},
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
-"nv" = (
+"nx" = (
/obj/effect/spawner/structure/window/reinforced,
-/obj/structure/cable{
- icon_state = "0-2"
- },
+/obj/structure/cable,
/turf/open/floor/plating,
-/area/mine/living_quarters)
+/area/mine/laborcamp/security)
"ny" = (
/obj/machinery/computer/prisoner,
/obj/effect/turf_decal/tile/red{
@@ -772,11 +796,17 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
dir = 10
},
-/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
- dir = 1
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
},
/obj/structure/cable{
- icon_state = "1-2"
+ icon_state = "1-8"
+ },
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
},
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
@@ -790,6 +820,14 @@
},
/turf/open/floor/plasteel,
/area/mine/production)
+"nL" = (
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable,
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp/security)
"nN" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -805,6 +843,19 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/mine/production)
+"nX" = (
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable{
+ icon_state = "0-8"
+ },
+/obj/structure/cable{
+ icon_state = "1-8"
+ },
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp/security)
"oo" = (
/obj/machinery/conveyor{
id = "mining_internal"
@@ -828,6 +879,9 @@
/obj/machinery/door/airlock/medical/glass{
name = "Infirmary"
},
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
/turf/open/floor/plasteel/white,
/area/mine/laborcamp)
"oy" = (
@@ -886,6 +940,22 @@
},
/turf/open/floor/plasteel,
/area/mine/eva)
+"pu" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "0-4"
+ },
+/obj/structure/cable{
+ icon_state = "1-4"
+ },
+/obj/structure/cable{
+ icon_state = "2-4"
+ },
+/obj/effect/spawner/structure/window/reinforced,
+/turf/open/floor/plating,
+/area/mine/living_quarters)
"pK" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3,
@@ -947,6 +1017,15 @@
},
/turf/open/floor/plating,
/area/mine/living_quarters)
+"qx" = (
+/obj/effect/turf_decal/tile/purple{
+ dir = 4
+ },
+/obj/structure/sign/poster/official/random{
+ pixel_y = 32
+ },
+/turf/open/floor/plasteel,
+/area/mine/living_quarters)
"qH" = (
/obj/structure/extinguisher_cabinet{
pixel_x = 30
@@ -1071,6 +1150,12 @@
"si" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3,
+/obj/structure/cable{
+ icon_state = "1-8"
+ },
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"sj" = (
@@ -1151,15 +1236,25 @@
},
/turf/open/floor/plasteel,
/area/mine/laborcamp)
+"td" = (
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable{
+ icon_state = "0-4"
+ },
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/mine/laborcamp)
"tk" = (
/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden/layer3,
-/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden,
/obj/structure/cable{
icon_state = "4-8"
},
/obj/structure/cable{
icon_state = "1-4"
},
+/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
+ dir = 8
+ },
/turf/open/floor/plasteel,
/area/mine/living_quarters)
"tr" = (
@@ -1183,16 +1278,6 @@
},
/turf/open/floor/plasteel,
/area/mine/production)
-"uh" = (
-/obj/effect/turf_decal/tile/brown{
- dir = 8
- },
-/obj/effect/turf_decal/tile/brown,
-/obj/effect/turf_decal/tile/brown{
- dir = 1
- },
-/turf/open/floor/plasteel,
-/area/mine/living_quarters)
"uG" = (
/obj/structure/table,
/obj/item/clothing/glasses/meson,
@@ -1258,6 +1343,13 @@
},
/turf/open/floor/plasteel,
/area/mine/laborcamp)
+"vA" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/plasteel,
+/area/mine/laborcamp)
"vE" = (
/obj/effect/turf_decal/tile/brown{
dir = 1
@@ -1285,6 +1377,16 @@
},
/turf/open/floor/plasteel,
/area/mine/eva)
+"vM" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/structure/chair,
+/turf/open/floor/plasteel,
+/area/mine/living_quarters)
"wd" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -1356,6 +1458,9 @@
/area/mine/production)
"xd" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3,
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp)
"xh" = (
@@ -1399,6 +1504,9 @@
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{
dir = 1
},
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"yt" = (
@@ -1416,6 +1524,13 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel,
/area/mine/production)
+"yQ" = (
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable{
+ icon_state = "0-8"
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp/security)
"yR" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on,
/turf/open/floor/plasteel,
@@ -1435,12 +1550,26 @@
},
/turf/open/floor/plating,
/area/mine/living_quarters)
+"zk" = (
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/mine/laborcamp/security)
"zo" = (
/obj/structure/table,
/turf/open/floor/carpet,
/area/mine/living_quarters)
"zx" = (
/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/obj/structure/cable{
+ icon_state = "0-4"
+ },
/turf/open/floor/plating,
/area/mine/laborcamp)
"zy" = (
@@ -1502,14 +1631,10 @@
/turf/open/floor/plasteel,
/area/mine/living_quarters)
"Ah" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3,
/obj/structure/cable{
icon_state = "1-2"
},
-/obj/structure/cable{
- icon_state = "2-8"
- },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"Aj" = (
@@ -1602,6 +1727,16 @@
/obj/structure/reagent_dispensers/fueltank,
/turf/open/floor/plating,
/area/mine/living_quarters)
+"BD" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Mining Station Maintenance";
+ req_access_txt = "48"
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp/security)
"BO" = (
/obj/machinery/door/airlock{
name = "Labor Camp Storage"
@@ -1638,6 +1773,12 @@
},
/turf/open/floor/plasteel,
/area/mine/production)
+"Cl" = (
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/plasteel,
+/area/mine/laborcamp)
"Cm" = (
/obj/machinery/vending/snack,
/obj/effect/turf_decal/tile/bar,
@@ -1646,6 +1787,13 @@
},
/turf/open/floor/plasteel,
/area/mine/living_quarters)
+"Cw" = (
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable{
+ icon_state = "0-8"
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp)
"Cy" = (
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 4
@@ -1748,18 +1896,6 @@
},
/turf/open/floor/plasteel,
/area/mine/production)
-"Em" = (
-/obj/effect/turf_decal/tile/brown{
- dir = 1
- },
-/obj/effect/turf_decal/tile/brown{
- dir = 8
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/turf/open/floor/plasteel,
-/area/mine/living_quarters)
"Ev" = (
/obj/machinery/light/small{
dir = 4
@@ -1792,7 +1928,9 @@
/obj/effect/turf_decal/tile/red{
dir = 8
},
-/obj/machinery/vending/security,
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"EH" = (
@@ -1805,6 +1943,9 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
dir = 9
},
+/obj/structure/cable{
+ icon_state = "1-8"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp)
"FC" = (
@@ -1825,19 +1966,6 @@
},
/turf/open/floor/plasteel,
/area/mine/laborcamp)
-"Ge" = (
-/obj/effect/spawner/structure/window/reinforced,
-/obj/structure/cable{
- icon_state = "2-4"
- },
-/obj/structure/cable{
- icon_state = "1-4"
- },
-/obj/structure/cable{
- icon_state = "0-4"
- },
-/turf/open/floor/plating,
-/area/mine/living_quarters)
"Gt" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{
dir = 1
@@ -1845,9 +1973,6 @@
/obj/effect/turf_decal/tile/red{
dir = 8
},
-/obj/structure/cable{
- icon_state = "4-8"
- },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"GM" = (
@@ -1891,6 +2016,9 @@
dir = 10
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp)
"Hh" = (
@@ -1964,11 +2092,6 @@
},
/turf/open/floor/plasteel,
/area/mine/laborcamp)
-"HR" = (
-/obj/effect/spawner/structure/window/reinforced,
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/mine/living_quarters)
"HS" = (
/obj/machinery/conveyor{
dir = 10;
@@ -2038,6 +2161,9 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 8
},
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"II" = (
@@ -2053,6 +2179,9 @@
/obj/structure/table,
/obj/effect/turf_decal/tile/red,
/obj/machinery/recharger,
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"IS" = (
@@ -2073,19 +2202,6 @@
},
/turf/open/floor/carpet,
/area/mine/living_quarters)
-"Jc" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
- dir = 4
- },
-/obj/effect/spawner/structure/window/reinforced,
-/obj/structure/cable{
- icon_state = "2-4"
- },
-/obj/structure/cable{
- icon_state = "0-4"
- },
-/turf/open/floor/plating,
-/area/mine/living_quarters)
"Jl" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3,
/obj/effect/turf_decal/tile/purple{
@@ -2267,12 +2383,6 @@
},
/turf/open/floor/plasteel,
/area/mine/production)
-"KR" = (
-/obj/effect/turf_decal/tile/brown{
- dir = 4
- },
-/turf/open/floor/plasteel,
-/area/mine/living_quarters)
"KS" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -2347,10 +2457,11 @@
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"LG" = (
-/obj/effect/turf_decal/tile/brown{
- dir = 1
+/obj/structure/cable{
+ icon_state = "0-2"
},
-/turf/open/floor/plasteel,
+/obj/effect/spawner/structure/window/reinforced,
+/turf/open/floor/plating,
/area/mine/living_quarters)
"LL" = (
/obj/effect/turf_decal/tile/red{
@@ -2392,6 +2503,13 @@
},
/turf/open/floor/plasteel,
/area/mine/production)
+"Mh" = (
+/obj/structure/table,
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/turf/open/floor/plasteel/white,
+/area/mine/laborcamp)
"Mj" = (
/obj/structure/sink{
dir = 4;
@@ -2492,12 +2610,6 @@
},
/turf/open/floor/plating,
/area/mine/living_quarters)
-"ML" = (
-/obj/structure/chair{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/mine/living_quarters)
"MM" = (
/obj/machinery/light{
dir = 8
@@ -2702,16 +2814,16 @@
/turf/open/floor/plasteel,
/area/mine/living_quarters)
"Qr" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3,
-/obj/machinery/door/airlock/security/glass{
- name = "Labor Camp Monitoring";
- req_access_txt = "2"
+/obj/structure/cable,
+/obj/structure/cable{
+ icon_state = "1-8"
},
/obj/structure/cable{
- icon_state = "1-2"
+ icon_state = "1-4"
},
-/turf/open/floor/plasteel,
+/obj/effect/spawner/structure/window/reinforced,
+/turf/open/floor/plating,
/area/mine/laborcamp/security)
"Qx" = (
/obj/structure/chair{
@@ -2738,6 +2850,12 @@
},
/turf/open/floor/plasteel,
/area/mine/eva)
+"QL" = (
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/turf/open/floor/plasteel,
+/area/mine/laborcamp/security)
"Rf" = (
/obj/machinery/mineral/unloading_machine{
dir = 1;
@@ -2755,6 +2873,9 @@
req_access_txt = "2";
security_level = 6
},
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp)
"Ru" = (
@@ -2837,6 +2958,12 @@
/area/mine/living_quarters)
"Sp" = (
/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/obj/structure/cable{
+ icon_state = "0-8"
+ },
/turf/open/floor/plating,
/area/mine/laborcamp/security)
"Sq" = (
@@ -2904,7 +3031,7 @@
dir = 8
},
/obj/structure/cable{
- icon_state = "4-8"
+ icon_state = "1-8"
},
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
@@ -2951,6 +3078,9 @@
desc = "Powered by the tears and sweat of laborers.";
name = "Prison Ofitser"
},
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"Un" = (
@@ -3099,19 +3229,6 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on,
/turf/open/floor/plasteel/dark,
/area/mine/maintenance)
-"WX" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden{
- dir = 5
- },
-/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3,
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/obj/structure/cable{
- icon_state = "1-4"
- },
-/turf/open/floor/plasteel,
-/area/mine/living_quarters)
"WY" = (
/obj/machinery/door/airlock{
id_tag = "miningdorm1";
@@ -3170,12 +3287,6 @@
},
/turf/open/floor/plasteel,
/area/mine/living_quarters)
-"XR" = (
-/obj/structure/sign/poster/official/random{
- pixel_y = 32
- },
-/turf/open/floor/plasteel,
-/area/mine/living_quarters)
"XU" = (
/obj/machinery/power/smes{
charge = 5e+006
@@ -3211,9 +3322,6 @@
dir = 1;
network = list("labor")
},
-/obj/structure/cable{
- icon_state = "4-8"
- },
/turf/open/floor/plasteel,
/area/mine/laborcamp/security)
"Yi" = (
@@ -3291,13 +3399,6 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3,
/turf/open/floor/plasteel,
/area/mine/living_quarters)
-"Zu" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{
- dir = 4
- },
-/obj/structure/lattice/catwalk,
-/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
-/area/mine/living_quarters)
"Zw" = (
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 4
@@ -4329,9 +4430,9 @@ cd
cd
HO
cd
-zI
-zI
-VT
+RF
+RF
+RF
VT
VT
VT
@@ -4386,9 +4487,9 @@ HU
cd
Jr
cd
-my
-wV
-VT
+fA
+fx
+RF
VT
uJ
VT
@@ -4443,13 +4544,13 @@ at
cd
Op
cd
-wV
-wV
-wV
+hb
+dU
+RF
+VT
VT
VT
VT
-Lm
Lm
wz
wz
@@ -4486,8 +4587,8 @@ JY
JY
JY
zx
-zx
-zx
+kP
+td
cd
cd
cd
@@ -4501,15 +4602,15 @@ NH
NH
Ya
Mn
-Mn
+BD
Mn
Dv
Mn
-nv
-Ge
-HR
-VN
-Lm
+wV
+VT
+VT
+VT
+wz
Lm
Lm
Lm
@@ -4542,9 +4643,9 @@ JY
JY
JY
JY
-zx
-wB
+Cw
wB
+Mh
cd
AH
NH
@@ -4562,11 +4663,11 @@ EB
MM
LC
Mn
-xH
-dC
-hf
-VN
-bH
+wV
+wV
+VT
+VT
+Lm
Lm
Lm
Lm
@@ -4603,13 +4704,13 @@ cd
eh
aN
ow
-NH
-NH
-NH
-NH
+Cl
+Cl
+Cl
+gn
vo
ly
-xd
+vA
Hg
gs
gs
@@ -4619,11 +4720,11 @@ si
fN
TC
Mn
-ML
-dC
-oy
-VN
-Zu
+wV
+my
+VT
+VT
+VT
Lm
Lm
Lm
@@ -4664,7 +4765,7 @@ fs
NH
Wt
xd
-xd
+vA
Fx
Yf
uR
@@ -4676,13 +4777,13 @@ Hx
mL
Yg
Mn
-XR
-dC
-Ag
-VN
-Jc
-HR
-VN
+zI
+VT
+VT
+VT
+VT
+wz
+Lm
Lm
Lm
Lm
@@ -4732,14 +4833,14 @@ LL
Hx
xS
Gt
-Sp
-FE
-Em
-cD
-Ag
-sm
-uh
-VN
+Dv
+my
+VT
+VT
+VT
+VT
+wz
+Lm
Lm
Lm
Lm
@@ -4791,12 +4892,12 @@ nJ
Ah
Qr
hQ
-bI
-hQ
-hQ
-WX
-hv
-VN
+VT
+VT
+VT
+Lm
+Lm
+Lm
Lm
Lm
Lm
@@ -4846,13 +4947,13 @@ WL
Hx
IG
UJ
-Sp
-Ag
-Ag
-di
-KR
+yQ
+my
+my
+VT
+Lm
hP
-Ag
+Lm
VN
VN
VN
@@ -4901,15 +5002,15 @@ Ya
Mn
kB
Oh
-Hx
+QL
sR
Al
Al
Al
Al
LG
-hP
-Ag
+pu
+bn
VN
zy
If
@@ -4955,7 +5056,7 @@ my
my
my
zI
-Sp
+Dv
ny
ig
IK
@@ -4964,9 +5065,9 @@ Al
wC
wC
Al
-Ag
-hP
-Ag
+hf
+vM
+xH
VN
Ru
Ag
@@ -5013,16 +5114,16 @@ my
my
zI
Sp
-Sp
-Sp
-Sp
-Sp
+zk
+nL
+nX
+nx
Al
Uz
Ue
Al
-EH
-hP
+qx
+sm
aW
VN
Dr
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index a630c54b6e..452a080be0 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -21911,7 +21911,7 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
-/obj/machinery/computer/arcade/minesweeper,
+/obj/machinery/vending/wardrobe/cap_wardrobe,
/turf/open/floor/wood,
/area/crew_quarters/heads/captain)
"bdj" = (
@@ -55854,6 +55854,10 @@
},
/turf/open/floor/plasteel,
/area/crew_quarters/dorms)
+"nZL" = (
+/obj/machinery/computer/arcade/minesweeper,
+/turf/open/floor/wood,
+/area/crew_quarters/heads/captain)
"oax" = (
/obj/structure/table/wood/fancy,
/obj/machinery/light,
@@ -57068,7 +57072,7 @@
/turf/open/floor/plating,
/area/space)
"sRH" = (
-/obj/machinery/autolathe{
+/obj/machinery/autolathe/secure{
name = "public autolathe"
},
/turf/open/floor/plasteel,
@@ -90865,7 +90869,7 @@ aVv
aXg
aYF
aZV
-bbw
+nZL
bcn
tgH
ben
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index fd0f0a1742..13597584ae 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -34904,7 +34904,7 @@
/obj/effect/turf_decal/tile/brown{
dir = 8
},
-/obj/machinery/autolathe{
+/obj/machinery/autolathe/secure{
name = "public autolathe"
},
/turf/open/floor/plasteel,
@@ -62353,7 +62353,7 @@
/turf/open/floor/wood,
/area/crew_quarters/heads/captain/private)
"cbd" = (
-/obj/effect/landmark/event_spawn,
+/obj/machinery/vending/wardrobe/cap_wardrobe,
/turf/open/floor/wood,
/area/crew_quarters/heads/captain/private)
"cbe" = (
@@ -127169,6 +127169,13 @@
dir = 9
},
/area/science/circuit)
+"rjr" = (
+/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
+ dir = 1
+ },
+/obj/effect/landmark/event_spawn,
+/turf/open/floor/wood,
+/area/crew_quarters/heads/captain/private)
"rqh" = (
/obj/structure/lattice,
/turf/open/space/basic,
@@ -169426,7 +169433,7 @@ bUO
bXf
bUQ
cbe
-ccP
+rjr
ceH
cgu
cij
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 3353d1b15b..3c8e251bb1 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -28355,6 +28355,7 @@
/obj/structure/disposalpipe/segment{
dir = 6
},
+/obj/machinery/vending/wardrobe/cap_wardrobe,
/turf/open/floor/carpet,
/area/crew_quarters/heads/captain/private)
"bdL" = (
@@ -31855,7 +31856,7 @@
/obj/effect/turf_decal/tile/brown{
dir = 8
},
-/obj/machinery/autolathe{
+/obj/machinery/autolathe/secure{
name = "public autolathe"
},
/turf/open/floor/plasteel,
@@ -81645,6 +81646,19 @@
/obj/machinery/door/firedoor,
/turf/open/floor/plating,
/area/crew_quarters/cryopod)
+"eQf" = (
+/obj/machinery/computer/shuttle/mining/common{
+ dir = 1
+ },
+/obj/structure/window/reinforced,
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/obj/structure/window/reinforced{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/hallway/primary/port)
"eZe" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
@@ -98511,7 +98525,7 @@ bgA
biz
bkb
blZ
-bnM
+eQf
bqf
bqf
bqf
diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm
index d4b09ac046..13dd939ad7 100644
--- a/_maps/map_files/Mining/Lavaland.dmm
+++ b/_maps/map_files/Mining/Lavaland.dmm
@@ -75,8 +75,29 @@
/turf/closed/mineral/random/labormineral/volcanic,
/area/lavaland/surface/outdoors)
"aA" = (
-/turf/template_noop,
+/turf/open/lava/smooth/lava_land_surface,
/area/template_noop)
+"aQ" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"aU" = (
+/obj/structure/stone_tile/block/cracked,
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/item/t_scanner/adv_mining_scanner/lesser,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"cp" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"cu" = (
/obj/item/pickaxe,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
@@ -85,6 +106,106 @@
/obj/structure/ore_box,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"cw" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/blood,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"dA" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"dD" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"dF" = (
+/obj/structure/stone_tile/block/cracked,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"dM" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eb" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/machinery/iv_drip,
+/obj/item/reagent_containers/glass/beaker/waterbottle/large,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eh" = (
+/obj/structure/stone_tile/slab/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eo" = (
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eq" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eP" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"eQ" = (
+/obj/structure/closet/crate/radiation,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/flare,
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"ft" = (
+/obj/structure/stone_tile/block,
+/obj/item/twohanded/bonespear,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"fN" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/item/twohanded/bonespear,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"fQ" = (
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors/unexplored/danger)
@@ -165,6 +286,17 @@
/obj/structure/stone_tile,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"gt" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/surrounding_tile,
+/obj/structure/stone_tile/center/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"gy" = (
/obj/structure/stone_tile/cracked,
/obj/structure/stone_tile{
@@ -203,6 +335,12 @@
},
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
+"gF" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"gG" = (
/obj/structure/stone_tile{
dir = 1
@@ -239,18 +377,47 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"hd" = (
+/obj/structure/mineral_door/sandstone,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"hg" = (
/obj/structure/stone_tile/surrounding,
/obj/structure/stone_tile/center/cracked,
/mob/living/simple_animal/hostile/megafauna/legion,
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
+"hr" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/center,
+/obj/item/hatchet,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"hs" = (
/obj/structure/stone_tile/block{
dir = 1
},
/turf/open/lava/smooth/lava_land_surface,
/area/lavaland/surface/outdoors)
+"hy" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"hD" = (
+/obj/effect/mob_spawn/human/corpse/damaged,
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"hH" = (
/obj/structure/stone_tile/block{
dir = 1
@@ -271,6 +438,13 @@
},
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
+"ia" = (
+/obj/item/reagent_containers/glass/bucket,
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"id" = (
/obj/structure/stone_tile{
dir = 4
@@ -284,6 +458,10 @@
},
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
+"io" = (
+/obj/structure/stone_tile/slab/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"ir" = (
/obj/structure/stone_tile/slab/cracked{
dir = 5
@@ -327,6 +505,38 @@
/obj/structure/stone_tile/block/cracked,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"iG" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/item/stack/sheet/mineral/wood,
+/obj/item/stack/sheet/mineral/wood,
+/obj/item/stack/sheet/mineral/wood,
+/obj/item/stack/sheet/mineral/wood,
+/obj/item/seeds/tower,
+/obj/item/seeds/tower,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"iJ" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/table/wood,
+/obj/item/clothing/head/helmet/roman/legionnaire,
+/obj/item/twohanded/bonespear,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
"iK" = (
/obj/structure/stone_tile/block,
/obj/structure/stone_tile/cracked{
@@ -376,6 +586,16 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"jj" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
"jk" = (
/obj/structure/stone_tile/center,
/obj/structure/stone_tile/surrounding_tile,
@@ -491,6 +711,12 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"ke" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"kg" = (
/obj/structure/fluff/drake_statue,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
@@ -504,6 +730,12 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"kk" = (
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"kl" = (
/obj/structure/fluff/drake_statue/falling,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
@@ -551,6 +783,13 @@
/obj/structure/stone_tile/center,
/turf/open/lava/smooth/lava_land_surface,
/area/lavaland/surface/outdoors)
+"kG" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
"kH" = (
/obj/structure/stone_tile/surrounding_tile{
dir = 1
@@ -562,6 +801,9 @@
/obj/structure/stone_tile/center/cracked,
/turf/open/lava/smooth/lava_land_surface,
/area/lavaland/surface/outdoors)
+"kI" = (
+/turf/closed/mineral/random/volcanic,
+/area/ruin/unpowered/ash_walkers)
"kJ" = (
/obj/structure/stone_tile/surrounding_tile{
dir = 4
@@ -587,10 +829,30 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"kP" = (
+/obj/structure/stone_tile/surrounding_tile,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/center,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
"kR" = (
/obj/structure/stone_tile/slab/cracked,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"lb" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
"le" = (
/obj/structure/stone_tile,
/obj/structure/stone_tile{
@@ -1179,10 +1441,989 @@
},
/turf/open/indestructible/boss,
/area/lavaland/surface/outdoors)
+"nt" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/blood,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"nB" = (
+/obj/item/shovel,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"nI" = (
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"nJ" = (
+/turf/closed/wall/mineral/wood,
+/area/ruin/unpowered/ash_walkers)
+"nU" = (
+/obj/structure/stone_tile,
+/obj/item/shard,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"nW" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/item/flashlight/lantern,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
"ol" = (
/obj/effect/landmark/stationroom/lavaland/station,
-/turf/template_noop,
+/turf/open/lava/smooth/lava_land_surface,
/area/template_noop)
+"ot" = (
+/obj/structure/stone_tile/surrounding_tile,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"oB" = (
+/obj/item/stack/sheet/mineral/wood,
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"oS" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/item/malf_upgrade,
+/obj/item/disk/tech_disk/illegal,
+/obj/structure/safe,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pc" = (
+/obj/effect/decal/cleanable/blood,
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pq" = (
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pt" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"pD" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pF" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/center,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pG" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"pH" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"qh" = (
+/obj/structure/stone_tile/surrounding/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"qi" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"qA" = (
+/obj/item/flashlight/lantern,
+/obj/structure/stone_tile/center,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"qN" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"qS" = (
+/obj/structure/stone_tile/slab,
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"rz" = (
+/obj/item/storage/box/rxglasses,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"rO" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/ore_box,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"rQ" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"sa" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"se" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/item/flashlight/lantern,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"sk" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"sl" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"sq" = (
+/obj/structure/stone_tile,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"sx" = (
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/obj/item/stack/sheet/mineral/coal,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"sR" = (
+/obj/structure/stone_tile/block/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"ty" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/item/flashlight/lantern,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"tz" = (
+/obj/structure/stone_tile/slab,
+/obj/structure/table/wood,
+/obj/item/toy/cards/deck/syndicate,
+/obj/item/construction/rcd/loaded/upgraded,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"ub" = (
+/obj/structure/stone_tile/slab,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"ui" = (
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"uk" = (
+/obj/structure/lavaland/ash_walker,
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"uz" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"vi" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"vu" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/center,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"vR" = (
+/obj/machinery/hydroponics/soil,
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"wm" = (
+/obj/item/seeds/glowshroom,
+/obj/item/seeds/glowshroom,
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"ww" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/center/cracked,
+/obj/structure/stone_tile/surrounding_tile,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"wF" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"xr" = (
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/closet/crate/internals,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/obj/item/pickaxe,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"xs" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"xJ" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/block,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"xX" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/item/pickaxe,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"yf" = (
+/obj/machinery/hydroponics/soil,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/center,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"yv" = (
+/obj/structure/stone_tile/block,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"zf" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"zv" = (
+/obj/machinery/hydroponics/soil,
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Ad" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Ag" = (
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"An" = (
+/obj/structure/stone_tile/slab,
+/obj/structure/table/wood,
+/obj/item/twohanded/bonespear,
+/obj/item/twohanded/bonespear,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"AH" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/item/twohanded/bonespear,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"AU" = (
+/obj/structure/stone_tile,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"AY" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/item/flashlight/lantern,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Bf" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Bj" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/blood,
+/obj/structure/necropolis_gate/ashwalker,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Br" = (
+/obj/structure/stone_tile/slab,
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Bs" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/structure/closet/crate,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"BF" = (
+/obj/structure/flora/rock/jungle,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"BG" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"BH" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/center/cracked,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"BP" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"BU" = (
+/turf/closed/indestructible/riveted/boss/see_through,
+/area/ruin/unpowered/ash_walkers)
+"Ch" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/center/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"CG" = (
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"CL" = (
+/obj/structure/stone_tile/slab,
+/obj/structure/table/wood,
+/obj/item/clothing/head/helmet/skull,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Dn" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/ruin/unpowered/ash_walkers)
+"Do" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Ds" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Dx" = (
+/obj/structure/bonfire/dense,
+/obj/structure/stone_tile/center,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Dz" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Ef" = (
+/obj/structure/stone_tile/block/cracked,
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"Ez" = (
+/obj/machinery/grill{
+ name = "old rusty grill"
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"EQ" = (
+/obj/structure/stone_tile/surrounding/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"EV" = (
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Fn" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Fz" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"FD" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"Gc" = (
+/obj/structure/flora/junglebush/b,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Gw" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Gx" = (
+/obj/item/pickaxe,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"GC" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/stone_tile/center,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"Hq" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/table/wood,
+/obj/item/scythe,
+/obj/item/twohanded/bonespear,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"HX" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"It" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Jq" = (
+/obj/structure/stone_tile/slab/cracked,
+/obj/effect/decal/cleanable/blood,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"JP" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"JR" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"JZ" = (
+/obj/structure/stone_tile/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"KA" = (
+/obj/structure/stone_tile/slab,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"KJ" = (
+/obj/structure/stone_tile/block/cracked,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"KV" = (
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/effect/mob_spawn/human/corpse/damaged,
+/obj/effect/decal/cleanable/blood,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"LJ" = (
+/turf/open/water,
+/area/ruin/unpowered/ash_walkers)
+"Mh" = (
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Mx" = (
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"MQ" = (
+/obj/structure/table/optable,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/item/surgical_drapes,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"MS" = (
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"MX" = (
+/obj/structure/stone_tile/slab/cracked,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"NN" = (
+/obj/structure/stone_tile/block/cracked,
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Ou" = (
+/obj/structure/stone_tile/slab,
+/obj/structure/table/wood,
+/obj/item/storage/toolbox/syndicate,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Oy" = (
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/center,
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"OR" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile/block/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Pj" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/center,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Qd" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/table/wood,
+/obj/item/storage/belt,
+/obj/item/twohanded/bonespear,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Qk" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/item/stack/marker_beacon/ten,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"QC" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"QG" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"QM" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Rb" = (
+/obj/structure/closet/crate,
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/obj/item/flashlight/lantern,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Rk" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Rr" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/ruin/unpowered/ash_walkers)
+"RF" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"RX" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile,
+/obj/effect/decal/cleanable/blood,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Sh" = (
+/obj/structure/stone_tile/block,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Si" = (
+/turf/closed/indestructible/riveted/boss,
+/area/ruin/unpowered/ash_walkers)
+"Sr" = (
+/turf/closed/mineral/random/high_chance/volcanic,
+/area/ruin/unpowered/ash_walkers)
+"SG" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Tn" = (
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/table/wood,
+/obj/item/kitchen/knife/combat/bone,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"TN" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/center,
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile{
+ dir = 4
+ },
+/turf/open/lava/smooth{
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ },
+/area/ruin/unpowered/ash_walkers)
+"Uh" = (
+/obj/structure/stone_tile/slab,
+/obj/structure/table/wood,
+/obj/item/weldingtool/experimental,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
"Uq" = (
/obj/docking_port/stationary{
area_type = /area/lavaland/surface/outdoors;
@@ -1195,6 +2436,221 @@
},
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"UG" = (
+/obj/structure/stone_tile/block,
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"UV" = (
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked,
+/obj/effect/decal/cleanable/blood,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Vb" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/item/storage/bag/plants/portaseeder,
+/obj/item/seeds/cotton,
+/obj/item/seeds/cotton,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Vj" = (
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"VI" = (
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/reagent_dispensers/watertank,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"VP" = (
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Wb" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/ruin/unpowered/ash_walkers)
+"Wh" = (
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Wj" = (
+/obj/structure/stone_tile/surrounding_tile/cracked,
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"WL" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/closet/crate/medical,
+/obj/item/storage/firstaid/regular,
+/obj/item/storage/firstaid/ancient,
+/obj/item/reagent_containers/blood/random,
+/obj/item/reagent_containers/blood/lizard,
+/obj/item/reagent_containers/blood/lizard,
+/obj/item/stack/sheet/cloth/ten,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"WN" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/item/twohanded/bonespear,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"WT" = (
+/obj/structure/stone_tile/block{
+ dir = 4
+ },
+/obj/structure/stone_tile{
+ dir = 8
+ },
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"WU" = (
+/obj/structure/stone_tile,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Xe" = (
+/obj/structure/stone_tile/surrounding_tile,
+/obj/structure/stone_tile/center/cracked,
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Xf" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile,
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Xo" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/lavaland/surface/outdoors)
+"Xw" = (
+/obj/structure/stone_tile{
+ dir = 1
+ },
+/obj/structure/stone_tile,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Xz" = (
+/obj/structure/stone_tile/surrounding_tile/cracked{
+ dir = 8
+ },
+/turf/closed/mineral/volcanic/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"XG" = (
+/obj/effect/decal/cleanable/blood,
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 4
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Yg" = (
+/obj/structure/flora/rock/pile/largejungle{
+ light_range = null
+ },
+/turf/open/water,
+/area/ruin/unpowered/ash_walkers)
+"Yy" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/obj/item/flashlight/lantern,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"YH" = (
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/ruin/unpowered/ash_walkers)
+"Zc" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/structure/stone_tile/cracked,
+/obj/structure/stone_tile/cracked{
+ dir = 1
+ },
+/obj/structure/stone_tile/cracked{
+ dir = 8
+ },
+/obj/machinery/the_singularitygen,
+/turf/open/indestructible/boss,
+/area/ruin/unpowered/ash_walkers)
+"Zs" = (
+/obj/structure/stone_tile/block{
+ dir = 8
+ },
+/obj/structure/stone_tile/block/cracked{
+ dir = 4
+ },
+/turf/closed/indestructible/riveted/boss,
+/area/ruin/unpowered/ash_walkers)
(1,1,1) = {"
aa
@@ -52358,9 +53814,9 @@ aa
aa
aa
ad
-ab
-ab
-ab
+Mx
+Mx
+Mx
aj
aj
aj
@@ -52615,11 +54071,11 @@ aa
aa
aa
ad
-ab
-ab
-ab
-aj
-aj
+Mx
+Mx
+Mx
+Mx
+Mx
aj
aj
aj
@@ -52864,20 +54320,20 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ab
-ab
-ab
-ab
-aj
-aj
-aj
+Si
+Si
+Si
+Si
+Si
+Si
+Si
+Ag
+Ag
+Ag
+Mx
+Mx
+Mx
+Mx
aj
aj
aj
@@ -53121,20 +54577,20 @@ aa
aa
aa
aa
-aa
-ad
-ad
-ad
-iy
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
+Si
+Sr
+Sr
+Sr
+JZ
+nI
+nI
+nI
+nI
+CG
+Ag
+Ag
+Ag
+Mx
aj
aj
aj
@@ -53378,20 +54834,20 @@ aa
aa
aa
aa
-aa
-ad
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
+Si
+Sr
+nI
+nI
+nI
+nI
+pq
+nI
+LJ
+nI
+nI
+nI
+Ag
+Mx
aj
aj
aj
@@ -53635,20 +55091,20 @@ aa
aa
aa
aa
-aa
-it
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
+Si
+yv
+nI
+nI
+nI
+nI
+BF
+LJ
+LJ
+LJ
+nI
+JZ
+nI
+Mx
aj
aj
aj
@@ -53892,20 +55348,20 @@ aa
aa
aa
aa
-aa
-it
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ai
-ai
-ab
-ab
-ab
+Si
+yv
+nI
+nI
+Ad
+nI
+LJ
+LJ
+LJ
+LJ
+kI
+nI
+JZ
+Mx
aj
aj
aj
@@ -54149,20 +55605,20 @@ aa
aa
aa
aa
-aa
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ad
-ai
-ai
-ab
-ab
-ab
+Si
+nI
+nI
+Ez
+nI
+LJ
+LJ
+Yg
+LJ
+kI
+kI
+nI
+nI
+Mx
aj
ab
aj
@@ -54406,21 +55862,21 @@ aa
aa
aa
aa
-aa
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ai
-ai
-ad
-ab
-aj
-aj
+Si
+nI
+nI
+sx
+nI
+LJ
+LJ
+LJ
+LJ
+kI
+kI
+Sr
+Ag
+Mx
+Mx
aj
aj
aj
@@ -54663,21 +56119,21 @@ aa
aa
aa
aa
-aa
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ad
-ab
-ab
-aj
-aj
+Si
+nI
+nI
+nI
+Wh
+nI
+LJ
+LJ
+Gc
+nI
+Sr
+nI
+Ag
+Mx
+Mx
aj
aj
aj
@@ -54920,21 +56376,21 @@ aa
aa
aa
aa
-aa
-ad
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
+Si
+Sr
+nI
+nI
+nI
+Wh
+nI
+nI
+nI
+nI
+nI
+nI
+Ag
+Mx
+Mx
aj
aj
aj
@@ -55177,21 +56633,21 @@ aa
aa
aa
aa
-aa
-aa
-aa
-it
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
+Si
+Ag
+Ag
+nI
+nI
+nI
+nI
+Ds
+nI
+Ds
+nI
+nI
+Ag
+Mx
+Mx
aj
aj
aj
@@ -55429,25 +56885,25 @@ aa
aa
aa
aa
+wF
+Do
+Mh
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
+Rr
+Ag
+xs
+eq
+nI
+nI
+nI
+nI
+nI
+nI
+nI
+nI
+Ag
+Mx
aj
aj
aj
@@ -55457,14 +56913,14 @@ aj
ab
ab
ab
+ab
ak
ak
ak
ak
ak
-ak
-ak
-ak
+ab
+ab
ak
ak
ak
@@ -55687,42 +57143,42 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
+Si
+Si
+Si
+Si
+Si
+Si
+Si
+yv
+nI
+nI
+sq
+kk
+Gx
+nI
+nI
+nI
+Si
+Mx
+aj
+aj
ab
aj
aj
aj
-aj
-aj
-aj
-aj
+aa
+ab
ab
ab
ab
ak
ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
+ab
+ab
+ab
+ab
+ab
ak
ak
ak
@@ -55944,13 +57400,32 @@ aa
aa
aa
aa
+Si
+oS
+CG
+wm
+Vb
+Bs
+Si
+yv
+sq
+CG
+AH
+Ds
+Ds
+KV
+nI
+Ad
+Si
+aa
+ab
+aj
+aj
+ab
+aj
aa
aa
-aa
-aa
-aa
-aa
-ad
+kG
ab
ab
ab
@@ -55960,14 +57435,6 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
ab
ab
ab
@@ -56171,17 +57638,6 @@ ak
ak
ak
ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
al
fQ
aj
@@ -56200,13 +57656,33 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+Gw
+Si
+aU
+Wh
+zf
+Qk
+iG
+Si
+Wh
+EV
+Xe
+ke
+Ch
+kk
+Ad
+Wh
+nI
+Ad
+lp
+lz
+lp
+lF
+lp
+lP
+lS
+iy
+iu
ab
ab
ab
@@ -56217,14 +57693,6 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
ab
ab
ab
@@ -56429,18 +57897,6 @@ ak
ak
ak
ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
aj
aj
aj
@@ -56457,13 +57913,33 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+Rk
+Si
+sR
+rz
+qh
+pq
+Jq
+ke
+ub
+YH
+sR
+Dx
+Bf
+UV
+kk
+Ds
+nI
+yv
+lu
+lq
+lD
+lG
+lu
+lQ
+lu
+kR
+kM
ab
ab
ab
@@ -56474,14 +57950,6 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
ab
ab
ab
@@ -56686,18 +58154,6 @@ ak
ak
ak
ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
aj
aj
aj
@@ -56714,13 +58170,33 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+uz
+Si
+MQ
+nU
+ui
+Xw
+Rb
+Si
+sR
+Wh
+gt
+gF
+pF
+sq
+Ad
+VP
+Ad
+pq
+lv
+lv
+lE
+lv
+lE
+lR
+lv
+ab
+jS
ab
ab
ab
@@ -56731,27 +58207,7 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
ab
-ab
-ab
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
ak
ak
ak
@@ -56971,14 +58427,33 @@ aa
aa
aa
aa
+uz
+Si
+WL
+eb
+dM
+eQ
+Zc
+Si
+Wh
+XG
+pq
+NN
+JZ
+oB
+EV
+nB
+nI
+Si
+aa
+aj
+aj
+aj
+aj
+aj
aa
aa
-aa
-aa
-aa
-aa
-ad
-js
+FD
ab
ab
ab
@@ -56988,26 +58463,7 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
ab
-ab
-ab
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
-ak
ak
ak
ak
@@ -57229,41 +58685,41 @@ aa
aa
aa
aa
+Si
+Si
+Si
+Si
+Si
+Si
+Si
+CG
+Wh
+CG
+JR
+Ad
+Pj
+ia
+yf
+Ds
+Si
+aj
+aj
+ab
+ab
+aj
+aj
+aj
aa
-aa
-aa
-aa
-aa
-ad
-ad
-ad
ab
ab
ab
ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-ab
-ab
-ab
-ak
-ak
-ak
-ak
-ak
-ak
ak
ak
+ab
+ab
+ab
+ab
ak
ak
ak
@@ -57484,42 +58940,42 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ai
-ai
-ai
-ai
+dD
+pt
+Wb
+Dn
+Zs
+Zs
+xX
+gF
+Fz
+QM
+CG
+Wh
+pc
+dA
+yv
+qA
+vR
+WU
+Ag
+aj
+aj
+aj
+aj
+aj
+aj
+aj
ab
ab
ab
ab
-ab
-ab
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-aj
-ab
-ab
-ab
-ak
-ak
-ak
ak
ak
ak
ak
+ab
+ab
ak
ak
ak
@@ -57740,27 +59196,27 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ai
-ai
-ai
-ai
-ad
+wF
+qS
+Si
+Si
+Si
+Si
+Si
+Si
+Si
+Br
+pD
+Wh
+Ad
+NN
+Wh
+hr
+zv
+BH
+sq
+Ag
ab
-ab
-ab
-ab
-ab
-aj
-aj
aj
aj
aj
@@ -57997,27 +59453,27 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ai
-ai
-ai
-ai
-ad
+Gw
+Si
+KA
+KA
+KA
+KA
+KA
+Si
+Si
+Si
+ft
+Ad
+pq
+NN
+VI
+Vj
+MS
+AU
+Ag
+Ag
ab
-ab
-ab
-ab
-ab
-aj
-aj
aj
aj
aj
@@ -58254,28 +59710,28 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ai
-ai
-ai
-ai
-ad
+lb
+tz
+KA
+AY
+BP
+cw
+WT
+ty
+Si
+Si
+qN
+nI
+hD
+UG
+Ag
+Ag
+Ag
+Ag
+Ag
+Ag
+Mx
ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -58511,28 +59967,28 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ad
-ai
-ai
-ai
-ai
-ad
+uz
+Ou
+KA
+QC
+GC
+hy
+ww
+vi
+Si
+BU
+kP
+cp
+CG
+xJ
+RF
+Ag
+xs
+xs
+xs
+Xz
+Mx
ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -58768,28 +60224,28 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-gP
-ai
-ai
-ai
-ai
-ad
+Gw
+An
+KA
+nt
+Ef
+uk
+rQ
+MX
+sa
+Bj
+ub
+It
+dA
+sk
+Si
+Si
+nJ
+Si
+Si
+Ag
+Mx
ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -59025,29 +60481,29 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ab
-ai
-ai
-ai
-ai
+Gw
+Uh
+KA
+jj
+vu
+qi
+TN
+RX
+Si
+BU
+Oy
+cp
+pq
+UG
+nJ
+WN
+Yy
+Hq
+nJ
+Ag
+Mx
ab
ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -59282,27 +60738,27 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-ab
-ai
-ai
-ai
-ai
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
+sl
+CL
+KA
+nW
+Dz
+Xf
+QG
+se
+Si
+Si
+KJ
+CG
+fN
+ub
+RF
+eh
+EQ
+Tn
+nJ
+Ag
+Mx
aj
aj
ab
@@ -59539,28 +60995,28 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+Gw
+Si
+KA
+KA
+KA
+KA
+KA
+Si
+Si
+Si
+sR
+pq
+sq
+nI
+nJ
+JP
+Qd
+iJ
+Si
+Sh
+Mx
ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -59796,28 +61252,28 @@ aj
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+pH
+qS
+Si
+Si
+Si
+Si
+Si
+Si
+Si
+io
+rO
+xr
+nI
+eo
+nJ
+nJ
+nJ
+Si
+Si
+dF
+Mx
ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -60054,27 +61510,27 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+aQ
+Fn
+SG
+SG
+SG
+BG
+SG
+Xo
+ot
+nI
+nI
+nI
+pG
+Ag
+Ag
+eP
+Ag
+Ag
+Wj
+Mx
ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
-aj
aj
aj
aj
@@ -60318,19 +61774,19 @@ aa
aa
aa
aa
+Mx
+Mx
+nI
+nI
+nI
+HX
+Ag
+Mx
+Mx
+Mx
ab
+Mx
ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-aj
-aj
aj
aj
aj
@@ -60575,15 +62031,15 @@ aa
aa
aa
aa
-it
-ab
-ab
-ab
-ab
-ab
-ab
-ab
-ab
+Mx
+Mx
+Ag
+nI
+nI
+OR
+Ag
+Mx
+Mx
ab
ab
aj
@@ -60833,13 +62289,13 @@ aa
aa
aa
ad
-ab
-ab
-ab
-ab
-ab
-ab
-ab
+Mx
+Ag
+Ag
+nI
+gF
+Ag
+Mx
ab
ab
ab
@@ -61091,12 +62547,12 @@ aa
aa
ad
ad
-ab
-ab
-ab
-ab
-ab
-ab
+Mx
+Mx
+Ag
+hd
+Ag
+Mx
ab
ab
ab
@@ -61350,7 +62806,7 @@ ad
ad
ad
ad
-ab
+Mx
ab
ab
ab
@@ -61607,7 +63063,7 @@ ad
ad
ad
ad
-ab
+Mx
ab
ab
ab
@@ -61860,12 +63316,12 @@ aa
aa
aa
aa
-gP
-js
-ab
+Mx
+Mx
+Mx
ad
ad
-ab
+Mx
ab
ab
ab
@@ -62122,7 +63578,7 @@ aa
aa
aa
aa
-ab
+Mx
ab
ab
ab
@@ -62385,10 +63841,10 @@ ab
ab
ab
ab
-aj
-aj
-aj
-aj
+ab
+ab
+ab
+ab
ab
ab
aj
@@ -62643,9 +64099,9 @@ ab
ab
ab
ab
-aj
ab
-aj
+ab
+ab
ab
ab
ab
@@ -62902,8 +64358,8 @@ ab
aj
aj
aj
-aj
-aj
+ab
+ab
ab
ab
ab
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index 22734b0979..b34da30300 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -9830,6 +9830,7 @@
/obj/structure/cable{
icon_state = "0-2"
},
+/obj/item/twohanded/required/kirbyplants/random,
/turf/open/floor/carpet,
/area/crew_quarters/heads/captain)
"axT" = (
@@ -11162,10 +11163,7 @@
/obj/structure/extinguisher_cabinet{
pixel_x = -24
},
-/obj/item/twohanded/required/kirbyplants{
- icon_state = "plant-20";
- pixel_y = 3
- },
+/obj/machinery/vending/wardrobe/cap_wardrobe,
/turf/open/floor/plasteel/dark,
/area/crew_quarters/heads/captain)
"aBl" = (
@@ -28097,11 +28095,6 @@
},
/turf/open/floor/plasteel/dark,
/area/science/robotics/lab)
-"boY" = (
-/obj/effect/turf_decal/bot,
-/obj/effect/landmark/start/cyborg,
-/turf/open/floor/plasteel,
-/area/science/robotics/lab)
"boZ" = (
/obj/structure/table,
/obj/machinery/cell_charger,
@@ -98811,8 +98804,8 @@ beI
bkt
blH
bmO
-boY
-boY
+bnQ
+bnQ
bqi
bry
bsZ
@@ -99068,8 +99061,8 @@ bju
bkt
blI
bmO
-boY
-boY
+bnQ
+bnQ
bqi
brz
bta
diff --git a/_maps/shuttles/pirate_default.dmm b/_maps/shuttles/pirate_default.dmm
index 1c8670d5b6..c002e66d53 100644
--- a/_maps/shuttles/pirate_default.dmm
+++ b/_maps/shuttles/pirate_default.dmm
@@ -89,7 +89,7 @@
/turf/open/floor/pod/dark,
/area/shuttle/pirate)
"aj" = (
-/turf/closed/wall/mineral/plastitanium/nodiagonal,
+/turf/closed/wall/r_wall/syndicate/pirate/nodiagonal,
/area/shuttle/pirate)
"ak" = (
/obj/machinery/airalarm/all_access{
@@ -419,6 +419,7 @@
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 1
},
+/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/shuttle/pirate)
"aK" = (
@@ -463,21 +464,19 @@
/turf/open/floor/plating,
/area/shuttle/pirate)
"aQ" = (
-/obj/machinery/porta_turret/syndicate/energy{
+/obj/machinery/porta_turret/syndicate/energy/pirate{
dir = 1;
faction = list("pirate");
- icon_state = "standard_lethal";
- mode = 1
+ icon_state = "standard_lethal"
},
-/turf/closed/wall/mineral/plastitanium/nodiagonal,
+/turf/closed/wall/r_wall/syndicate/pirate/nodiagonal,
/area/shuttle/pirate)
"aR" = (
-/obj/machinery/porta_turret/syndicate/energy{
+/obj/machinery/porta_turret/syndicate/energy/pirate{
faction = list("pirate");
- icon_state = "standard_lethal";
- mode = 1
+ icon_state = "standard_lethal"
},
-/turf/closed/wall/mineral/plastitanium,
+/turf/closed/wall/r_wall/syndicate/pirate,
/area/shuttle/pirate)
"aS" = (
/obj/effect/turf_decal/stripes/line,
@@ -486,7 +485,7 @@
/area/shuttle/pirate)
"aU" = (
/obj/structure/sign/departments/engineering,
-/turf/closed/wall/mineral/plastitanium/nodiagonal,
+/turf/closed/wall/r_wall/syndicate/pirate/nodiagonal,
/area/shuttle/pirate)
"aV" = (
/obj/effect/mob_spawn/human/pirate{
@@ -867,37 +866,36 @@
dir = 1
},
/obj/docking_port/mobile/pirate{
- callTime = 100;
- dheight = 0;
- dir = 1;
dwidth = 11;
height = 16;
- id = "pirateship";
launch_status = 0;
movement_force = list("KNOCKDOWN" = 0, "THROW" = 0);
name = "Pirate Ship";
port_direction = 2;
- preferred_direction = 1;
width = 17
},
/obj/docking_port/stationary{
- dir = 1;
dwidth = 11;
height = 16;
id = "pirateship_home";
name = "Deep Space";
width = 17
},
+/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/shuttle/pirate)
+"db" = (
+/obj/structure/shuttle/engine/heater,
+/obj/effect/spawner/structure/window/plastitanium/pirate,
+/turf/open/floor/plating/airless,
+/area/shuttle/pirate)
"df" = (
-/obj/machinery/porta_turret/syndicate/energy{
+/obj/machinery/porta_turret/syndicate/energy/pirate{
dir = 4;
faction = list("pirate");
- icon_state = "standard_lethal";
- mode = 1
+ icon_state = "standard_lethal"
},
-/turf/closed/wall/mineral/plastitanium,
+/turf/closed/wall/r_wall/syndicate/pirate,
/area/shuttle/pirate)
"dy" = (
/obj/structure/chair/wood/normal,
@@ -988,7 +986,7 @@
id = "piratebridge"
},
/obj/structure/grille,
-/obj/structure/window/plastitanium,
+/obj/structure/window/plastitanium/pirate,
/turf/open/floor/plating,
/area/shuttle/pirate)
"ez" = (
@@ -1016,7 +1014,7 @@
/turf/open/floor/plasteel,
/area/shuttle/pirate)
"fW" = (
-/turf/closed/wall/mineral/plastitanium,
+/turf/closed/wall/r_wall/syndicate/pirate,
/area/shuttle/pirate)
"fY" = (
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
@@ -1084,13 +1082,12 @@
/turf/open/floor/plasteel/showroomfloor,
/area/shuttle/pirate)
"wR" = (
-/obj/machinery/porta_turret/syndicate/energy{
+/obj/machinery/porta_turret/syndicate/energy/pirate{
dir = 8;
faction = list("pirate");
- icon_state = "standard_lethal";
- mode = 1
+ icon_state = "standard_lethal"
},
-/turf/closed/wall/mineral/plastitanium,
+/turf/closed/wall/r_wall/syndicate/pirate,
/area/shuttle/pirate)
"yi" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
@@ -1326,7 +1323,7 @@ aU
be
aD
aG
-ep
+db
aH
"}
(9,1,1) = {"
@@ -1344,7 +1341,7 @@ mU
aL
bP
bX
-ep
+db
aK
"}
(10,1,1) = {"
@@ -1362,7 +1359,7 @@ aj
bO
bQ
bk
-ep
+db
er
"}
(11,1,1) = {"
diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm
index 6913473e88..0a64f01a43 100644
--- a/code/__DEFINES/DNA.dm
+++ b/code/__DEFINES/DNA.dm
@@ -138,8 +138,8 @@
////organ defines
#define STANDARD_ORGAN_THRESHOLD 100
-#define STANDARD_ORGAN_HEALING 0.001
-#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes
+#define STANDARD_ORGAN_HEALING (1/(15 MINUTES / (2 SECONDS)))
+#define STANDARD_ORGAN_DECAY (1/(15 MINUTES / (2 SECONDS))) //designed to fail organs when left to decay for ~15 minutes. 2 SECOND is SSmobs tickrate.
#define G_MALE 1
#define G_FEMALE 2
diff --git a/code/__DEFINES/MC.dm b/code/__DEFINES/MC.dm
index fe48edd266..65be8258a1 100644
--- a/code/__DEFINES/MC.dm
+++ b/code/__DEFINES/MC.dm
@@ -20,7 +20,7 @@
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
#define START_PROCESSING(Processor, Datum) if (!(Datum.datum_flags & DF_ISPROCESSING)) {Datum.datum_flags |= DF_ISPROCESSING;Processor.processing += Datum}
-#define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum
+#define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum;Processor.currentrun -= Datum
//SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm
index 2b19610040..56d5c63833 100644
--- a/code/__DEFINES/citadel_defines.dm
+++ b/code/__DEFINES/citadel_defines.dm
@@ -34,6 +34,7 @@
#define CAN_MASTURBATE_WITH (1<<5)
#define MASTURBATE_LINKED_ORGAN (1<<6) //used to pass our mission to the linked organ
#define CAN_CLIMAX_WITH (1<<7)
+#define GENITAL_CAN_AROUSE (1<<8)
#define COCK_SIZE_MIN 1
#define COCK_SIZE_MAX 20
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index dabb4c3c43..23fa0786c5 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -191,10 +191,10 @@
#define SPEECH_MESSAGE 1
// #define SPEECH_BUBBLE_TYPE 2
#define SPEECH_SPANS 3
- /* #define SPEECH_SANITIZE 4
+// #define SPEECH_SANITIZE 4
#define SPEECH_LANGUAGE 5
- #define SPEECH_IGNORE_SPAM 6
- #define SPEECH_FORCED 7 */
+// #define SPEECH_IGNORE_SPAM 6
+// #define SPEECH_FORCED 7
// /mob/living signals
#define COMSIG_LIVING_FULLY_HEAL "living_fully_healed" //from base of /mob/living/fully_heal(): (admin_revive)
@@ -299,11 +299,14 @@
//Nanites
#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found
#define COMSIG_NANITE_IS_STEALTHY "nanite_is_stealthy" //() returns TRUE if nanites have stealth
+#define COMSIG_NANITE_DELETE "nanite_delete" //() deletes the nanite component
#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list
+#define COMSIG_NANITE_GET_VOLUME "nanite_get_volume" //(amount) Returns nanite amount
#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume" //(amount) Sets current nanite volume to the given amount
#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust" //(amount) Adjusts nanite volume by the given amount
#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume" //(amount) Sets maximum nanite volume to the given amount
#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud" //(amount(0-100)) Sets cloud ID to the given amount
+#define COMSIG_NANITE_SET_CLOUD_SYNC "nanite_set_cloud_sync" //(method) Modify cloud sync status. Method can be toggle, enable or disable
#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety" //(amount) Sets safety threshold to the given amount
#define COMSIG_NANITE_SET_REGEN "nanite_set_regen" //(amount) Sets regeneration rate to the given amount
#define COMSIG_NANITE_SIGNAL "nanite_signal" //(code(1-9999)) Called when sending a nanite signal to a mob.
@@ -311,8 +314,8 @@
#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected
#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs
#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component
- #define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
- #define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
+#define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
+#define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component
// /datum/component/storage signals
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index a7d2670747..957f6edae4 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -54,13 +54,13 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define PASSCLOSEDTURF (1<<5)
#define LETPASSTHROW (1<<6)
-
//Movement Types
-#define GROUND (1<<0)
-#define FLYING (1<<1)
-#define VENTCRAWLING (1<<2)
-#define FLOATING (1<<3)
-#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
+#define GROUND (1<<0)
+#define FLYING (1<<1)
+#define VENTCRAWLING (1<<2)
+#define FLOATING (1<<3)
+#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
+#define CRAWLING (1<<5) //Applied if you're crawling around on the ground/resting.
//Fire and Acid stuff, for resistance_flags
#define LAVA_PROOF (1<<0)
diff --git a/code/__DEFINES/interaction_flags.dm b/code/__DEFINES/interaction_flags.dm
index 6df5bf77fb..dc3242c910 100644
--- a/code/__DEFINES/interaction_flags.dm
+++ b/code/__DEFINES/interaction_flags.dm
@@ -20,5 +20,3 @@
#define INTERACT_MACHINE_SET_MACHINE (1<<6) //MACHINES HAVE THIS BY DEFAULT, SOMEONE SHOULD RUN THROUGH MACHINES AND REMOVE IT FROM THINGS LIKE LIGHT SWITCHES WHEN POSSIBLE!!--------------------------
//This flag determines if a machine set_machine's the user when the user uses it, making updateUsrDialog make the user re-call interact() on it.
//THIS FLAG IS ON ALL MACHINES BY DEFAULT, NEEDS TO BE RE-EVALUATED LATER!!
-
-#define INTERACT_GHOST_READ (1<<0)
\ No newline at end of file
diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm
index ad93dd2d54..939f6698cb 100644
--- a/code/__DEFINES/maths.dm
+++ b/code/__DEFINES/maths.dm
@@ -199,4 +199,6 @@
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*TORADIANS(arctan((x-y)/s)) + 1/2 )
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
-// )
\ No newline at end of file
+// )
+
+#define MANHATTAN_DISTANCE(a, b) (abs(a.x - b.x) + abs(a.y - b.y))
\ No newline at end of file
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index e2d93aebf5..ac8681ead7 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -406,6 +406,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define DUMMY_HUMAN_SLOT_HOLOFORM "dummy_holoform_generation"
#define DUMMY_HUMAN_SLOT_ADMIN "admintools"
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
+#define DUMMY_HUMAN_SLOT_HALLUCINATION "dummy_hallucination"
#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
//This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index a7d6056ab9..dc67de3150 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -35,17 +35,17 @@
#define BLOODCRAWL 1
#define BLOODCRAWL_EAT 2
-//Mob bio-types
-#define MOB_ORGANIC "organic"
-#define MOB_INORGANIC "inorganic"
-#define MOB_ROBOTIC "robotic"
-#define MOB_UNDEAD "undead"
-#define MOB_HUMANOID "humanoid"
-#define MOB_BUG "bug"
-#define MOB_BEAST "beast"
-#define MOB_EPIC "epic" //megafauna
-#define MOB_REPTILE "reptile"
-#define MOB_SPIRIT "spirit"
+//Mob bio-types flags
+#define MOB_ORGANIC 1 << 0
+#define MOB_MINERAL 1 << 1
+#define MOB_ROBOTIC 1 << 2
+#define MOB_UNDEAD 1 << 3
+#define MOB_HUMANOID 1 << 4
+#define MOB_BUG 1 << 5
+#define MOB_BEAST 1 << 6
+#define MOB_EPIC 1 << 7 //megafauna
+#define MOB_REPTILE 1 << 8
+#define MOB_SPIRIT 1 << 9
//Organ defines for carbon mobs
#define ORGAN_ORGANIC 1
@@ -276,4 +276,4 @@
#define HUMAN_FIRE_STACK_ICON_NUM 3
#define PULL_PRONE_SLOWDOWN 0.6
-#define HUMAN_CARRY_SLOWDOWN 0
\ No newline at end of file
+#define HUMAN_CARRY_SLOWDOWN 0
diff --git a/code/__DEFINES/nanites.dm b/code/__DEFINES/nanites.dm
index 45455a81c2..ed15e972ab 100644
--- a/code/__DEFINES/nanites.dm
+++ b/code/__DEFINES/nanites.dm
@@ -1,11 +1,44 @@
-#define NANITE_TIMER_DEACTIVATE 1
-#define NANITE_TIMER_SELFDELETE 2
-#define NANITE_TIMER_TRIGGER 3
-#define NANITE_TIMER_RESET 4
-
#define NANITE_SYNC_DELAY 300
#define NANITE_SHOCK_IMMUNE 1
#define NANITE_EMP_IMMUNE 2
-#define NANITE_PROGRAM_LIMIT 20
\ No newline at end of file
+#define NANITE_PROGRAM_LIMIT 20
+
+
+#define NANITE_BASE_RESEARCH 3.5
+
+#define NANITE_CLOUD_TOGGLE 1
+#define NANITE_CLOUD_DISABLE 2
+#define NANITE_CLOUD_ENABLE 3
+
+///Nanite extra settings types: used to help uis know what type an extra setting is
+#define NESTYPE_TEXT "text"
+#define NESTYPE_NUMBER "number"
+#define NESTYPE_TYPE "type"
+#define NESTYPE_BOOLEAN "boolean"
+
+///Nanite Extra Settings - Note that these will also be the names displayed in the UI
+#define NES_SENT_CODE "Sent Code"
+#define NES_DELAY "Delay"
+#define NES_MODE "Mode"
+#define NES_COMM_CODE "Comm Code"
+#define NES_RELAY_CHANNEL "Relay Channel"
+#define NES_HEALTH_PERCENT "Health Percent"
+#define NES_DIRECTION "Direction"
+#define NES_NANITE_PERCENT "Nanite Percent"
+#define NES_DAMAGE_TYPE "Damage Type"
+#define NES_DAMAGE "Damage"
+#define NES_SENTENCE "Sentence"
+#define NES_MESSAGE "Message"
+#define NES_DIRECTIVE "Directive"
+#define NES_INCLUSIVE_MODE "Inclusive Mode"
+#define NES_HALLUCINATION_TYPE "Hallucination Type"
+#define NES_HALLUCINATION_DETAIL "Hallucination Detail"
+#define NES_MOOD_MESSAGE "Mood Message"
+#define NES_PROGRAM_OVERWRITE "Program Overwrite"
+#define NES_CLOUD_OVERWRITE "Cloud Overwrite"
+#define NES_SCAN_TYPE "Scan Type"
+#define NES_BUTTON_NAME "Button Name"
+#define NES_ICON "Icon"
+#define NES_COLOR "Color"
diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm
index 831f73ac74..d78de86d25 100644
--- a/code/__DEFINES/obj_flags.dm
+++ b/code/__DEFINES/obj_flags.dm
@@ -17,18 +17,19 @@
// Flags for the item_flags var on /obj/item
-#define BEING_REMOVED (1<<0)
-#define IN_INVENTORY (1<<1) //is this item equipped into an inventory slot or hand of a mob? used for tooltips
-#define FORCE_STRING_OVERRIDE (1<<2) //used for tooltips
-#define NEEDS_PERMIT (1<<3) //Used by security bots to determine if this item is safe for public use.
-#define SLOWS_WHILE_IN_HAND (1<<4)
-#define NO_MAT_REDEMPTION (1<<5) //Stops you from putting things like an RCD or other items into an ORM or protolathe for materials.
-#define DROPDEL (1<<6) //When dropped, it calls qdel on itself
-#define NOBLUDGEON (1<<7) //when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
-#define ABSTRACT (1<<8) //for all things that are technically items but used for various different stuff
-#define IMMUTABLE_SLOW (1<<9) //When players should not be able to change the slowdown of the item (Speed potions, ect)
-#define SURGICAL_TOOL (1<<10) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
-#define NO_UNIFORM_REQUIRED (1<<11) //Can be worn on certain slots (currently belt and id) that would otherwise require an uniform.
+#define BEING_REMOVED (1<<0)
+#define IN_INVENTORY (1<<1) //is this item equipped into an inventory slot or hand of a mob? used for tooltips
+#define FORCE_STRING_OVERRIDE (1<<2) //used for tooltips
+#define NEEDS_PERMIT (1<<3) //Used by security bots to determine if this item is safe for public use.
+#define SLOWS_WHILE_IN_HAND (1<<4)
+#define NO_MAT_REDEMPTION (1<<5) //Stops you from putting things like an RCD or other items into an ORM or protolathe for materials.
+#define DROPDEL (1<<6) //When dropped, it calls qdel on itself
+#define NOBLUDGEON (1<<7) //when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
+#define ABSTRACT (1<<8) //for all things that are technically items but used for various different stuff
+#define IMMUTABLE_SLOW (1<<9) //When players should not be able to change the slowdown of the item (Speed potions, ect)
+#define SURGICAL_TOOL (1<<10) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
+#define NO_UNIFORM_REQUIRED (1<<11) //Can be worn on certain slots (currently belt and id) that would otherwise require an uniform.
+#define NO_ATTACK_CHAIN_SOFT_STAMCRIT (1<<12) //Entirely blocks melee_attack_chain() if user is soft stamcritted. Uses getStaminaLoss() to check at this point in time. THIS DOES NOT BLOCK RANGED AFTERATTACK()S, ONLY MELEE RANGE AFTERATTACK()S.
// Flags for the clothing_flags var on /obj/item/clothing
diff --git a/code/__DEFINES/profile.dm b/code/__DEFINES/profile.dm
index 28fc7782ce..8929e0f05e 100644
--- a/code/__DEFINES/profile.dm
+++ b/code/__DEFINES/profile.dm
@@ -1,5 +1,5 @@
-#define PROFILE_START ;PROFILE_STORE = list();PROFILE_SET;
-#define PROFILE_STOP ;PROFILE_STORE = null;
+#define LINE_PROFILE_START ;PROFILE_STORE = list();PROFILE_SET;
+#define LINE_PROFILE_STOP ;PROFILE_STORE = null;
#define PROFILE_SET ;PROFILE_TIME = TICK_USAGE_REAL; PROFILE_LINE = __LINE__; PROFILE_FILE = __FILE__; PROFILE_SLEEPCHECK = world.time;
diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm
index d08344cc96..97ae7b8e95 100644
--- a/code/__DEFINES/reagents.dm
+++ b/code/__DEFINES/reagents.dm
@@ -22,6 +22,11 @@
// Is an open container for all intents and purposes.
#define OPENCONTAINER (REFILLABLE | DRAINABLE | TRANSPARENT)
+//reagents_value defines, for cargo stuff.
+#define DEFAULT_REAGENTS_VALUE 1
+#define NO_REAGENTS_VALUE 0
+#define HARVEST_REAGENTS_VALUE 0.3
+
#define TOUCH 1 // splashing
#define INGEST 2 // ingestion
diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm
index a05e6f6160..affa23d30a 100644
--- a/code/__DEFINES/robots.dm
+++ b/code/__DEFINES/robots.dm
@@ -53,4 +53,10 @@
//Checks to determine borg availability depending on the server's config. These are defines in the interest of reducing copypasta
-#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert))
\ No newline at end of file
+#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert))
+
+//silicon_priviledges flags
+#define PRIVILEDGES_SILICON (1<<0)
+#define PRIVILEDGES_PAI (1<<1)
+#define PRIVILEDGES_BOT (1<<2)
+#define PRIVILEDGES_DRONE (1<<3)
diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm
index beeee22df9..49cfba8cd2 100644
--- a/code/__DEFINES/say.dm
+++ b/code/__DEFINES/say.dm
@@ -81,6 +81,7 @@
//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam
#define MAX_MESSAGE_LEN 2048 //Citadel edit: What's the WORST that could happen?
+#define MAX_FAVOR_LEN 4096 //double the maximum message length.
#define MAX_NAME_LEN 42
#define MAX_BROADCAST_LEN 512
#define MAX_CHARTER_LEN 80
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 6d52f4640c..f42948f4ae 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -46,7 +46,9 @@
#define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep
-#define STATUS_EFFECT_TASED /datum/status_effect/no_combat_mode/electrode/ //the affected has been tased, preventing fine muscle control
+#define STATUS_EFFECT_TASED_WEAK /datum/status_effect/electrode //not as crippling, just slows down
+
+#define STATUS_EFFECT_TASED /datum/status_effect/electrode/no_combat_mode //the affected has been tased, preventing fine muscle control
#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 5c54843df2..162c898917 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -47,6 +47,7 @@
// Subsystems shutdown in the reverse of the order they initialize in
// The numbers just define the ordering, they are meaningless otherwise.
+#define INIT_ORDER_PROFILER 101
#define INIT_ORDER_FAIL2TOPIC 22
#define INIT_ORDER_TITLE 20
#define INIT_ORDER_GARBAGE 19
diff --git a/code/__DEFINES/tgs.config.dm b/code/__DEFINES/tgs.config.dm
index a40b5d4663..9f4f63a1fc 100644
--- a/code/__DEFINES/tgs.config.dm
+++ b/code/__DEFINES/tgs.config.dm
@@ -1,4 +1,5 @@
#define TGS_EXTERNAL_CONFIGURATION
+#define TGS_V3_API
#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name)
#define TGS_READ_GLOBAL(Name) GLOB.##Name
#define TGS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value
diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm
index db4f046ec3..dcccfc9295 100644
--- a/code/__DEFINES/tgs.dm
+++ b/code/__DEFINES/tgs.dm
@@ -107,6 +107,22 @@
var/commit //full sha of compiled commit
var/origin_commit //full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch
+//represents a version of tgstation-server
+/datum/tgs_version
+ var/suite //The suite version, can be >=3
+
+ //this group of variables can be null to represent a wild card
+ var/major //The major version
+ var/minor //The minor version
+ var/patch //The patch version
+
+ var/raw_parameter //The unparsed parameter
+ var/deprefixed_parameter //The version only bit of raw_parameter
+
+//if the tgs_version is a wildcard version
+/datum/tgs_version/proc/Wildcard()
+ return
+
//represents a merge of a GitHub pull request
/datum/tgs_revision_information/test_merge
var/number //pull request number
@@ -155,22 +171,22 @@
//FUNCTIONS
-//Returns the respective string version of the API
+//Returns the respective supported /datum/tgs_version of the API
/world/proc/TgsMaximumAPIVersion()
return
/world/proc/TgsMinimumAPIVersion()
return
-//Gets the current version of the server tools running the server
-/world/proc/TgsVersion()
- return
-
//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise
//No function below this succeeds if it returns FALSE
/world/proc/TgsAvailable()
return
+//Gets the current /datum/tgs_version of the server tools running the server
+/world/proc/TgsVersion()
+ return
+
/world/proc/TgsInstanceName()
return
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index ea1ccfa97b..145f879b90 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -55,6 +55,7 @@
} while (0)
#define HAS_TRAIT(target, trait) (target.status_traits ? (target.status_traits[trait] ? TRUE : FALSE) : FALSE)
#define HAS_TRAIT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (source in target.status_traits[trait]) : FALSE) : FALSE)
+#define HAS_TRAIT_NOT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (length(target.status_traits[trait] - source) > 0) : FALSE) : FALSE)
//mob traits
#define TRAIT_BLIND "blind"
@@ -110,6 +111,7 @@
#define TRAIT_NOHARDCRIT "nohardcrit"
#define TRAIT_NOSOFTCRIT "nosoftcrit"
#define TRAIT_MINDSHIELD "mindshield"
+#define TRAIT_HIJACKER "hijacker"
#define TRAIT_SIXTHSENSE "sixthsense"
#define TRAIT_DISSECTED "dissected"
#define TRAIT_FEARLESS "fearless"
diff --git a/code/__DEFINES/vote.dm b/code/__DEFINES/vote.dm
index b83ea7b8f6..12e802383e 100644
--- a/code/__DEFINES/vote.dm
+++ b/code/__DEFINES/vote.dm
@@ -6,3 +6,12 @@
#define INSTANT_RUNOFF_VOTING 5
GLOBAL_LIST_INIT(vote_score_options,list("Bad","Poor","Acceptable","Good","Great"))
+
+GLOBAL_LIST_INIT(vote_type_names,list(\
+"Plurality (default)" = PLURALITY_VOTING,\
+"Approval" = APPROVAL_VOTING,\
+"IRV (single winner ranked choice)" = INSTANT_RUNOFF_VOTING,\
+"Schulze (ranked choice, higher result=better)" = SCHULZE_VOTING,\
+"Raw Score (returns results from 0 to 1, winner is 1)" = SCORE_VOTING,\
+"Majority Judgement (single-winner score voting)" = MAJORITY_JUDGEMENT_VOTING,\
+))
diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm
index c0acf4c5a5..26910a916b 100644
--- a/code/__HELPERS/_cit_helpers.dm
+++ b/code/__HELPERS/_cit_helpers.dm
@@ -57,14 +57,11 @@ GLOBAL_LIST_EMPTY(ipc_antennas_list)
//Genitals and Arousal Lists
GLOBAL_LIST_EMPTY(genitals_list)
-GLOBAL_LIST_EMPTY(cock_shapes_list)//global_lists.dm for the list initializations //Now also _DATASTRUCTURES globals.dm
-GLOBAL_LIST_EMPTY(cock_shapes_icons) //Associated list for names->icon_states for cockshapes.
+GLOBAL_LIST_EMPTY(cock_shapes_list)
GLOBAL_LIST_EMPTY(gentlemans_organ_names)
GLOBAL_LIST_EMPTY(balls_shapes_list)
-GLOBAL_LIST_EMPTY(balls_shapes_icons)
GLOBAL_LIST_EMPTY(breasts_size_list)
GLOBAL_LIST_EMPTY(breasts_shapes_list)
-GLOBAL_LIST_EMPTY(breasts_shapes_icons)
GLOBAL_LIST_EMPTY(vagina_shapes_list)
GLOBAL_LIST_INIT(cum_into_containers_list, list(/obj/item/reagent_containers/food/snacks/pie)) //Yer fuggin snowflake name list jfc
GLOBAL_LIST_INIT(dick_nouns, list("dick","cock","member","shaft"))
@@ -111,27 +108,37 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
message_admins("[key_name_admin(usr)] manually reloaded mentors")
//Flavor Text
-/mob/living/carbon/human/verb/set_flavor()
+/mob/proc/set_flavor()
set name = "Set Flavor Text"
set desc = "Sets an extended description of your character's features."
set category = "IC"
- var/new_flavor = input(src, "Enter your new flavor text:", "Flavor text", null) as message|null
+ var/new_flavor = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", flavor_text, MAX_FAVOR_LEN, TRUE)
if(!isnull(new_flavor))
- flavor_text = sanitize(new_flavor)
+ flavor_text = new_flavor
to_chat(src, "Your flavor text has been updated.")
//Flavor Text
-/mob/living/carbon/human/verb/set_flavor_2()
+/mob/proc/set_flavor_2()
set name = "Set Temporary Flavor Text"
set desc = "Sets a description of your character's current appearance. Use this for emotions, poses etc."
set category = "IC"
- var/new_flavor = input(src, "Enter your new temporary flavor text:", "Temporary flavor text", null) as message|null
+ var/new_flavor = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", flavor_text_2, MAX_FAVOR_LEN, TRUE)
if(!isnull(new_flavor))
- flavor_text_2 = sanitize(new_flavor)
+ flavor_text_2 = new_flavor
to_chat(src, "Your temporary flavor text has been updated.")
+/mob/proc/print_flavor_text(flavor)
+ if(!flavor)
+ return
+ // We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
+ var/msg = html_decode(replacetext(flavor, "\n", " "))
+ if(length_char(msg) <= 40)
+ return "[html_encode(msg)]"
+ else
+ return "[html_encode(copytext_char(msg, 1, 37))]... More..."
+
//LOOC toggles
/client/verb/listen_looc()
set name = "Show/Hide LOOC"
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 605f7f8ae7..60d7fa42b9 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -436,7 +436,7 @@
var/list/result = list()
for(var/m in group)
var/mob/M = m
- if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && M.ckey in GLOB.poll_ignore[ignore_category]))
+ if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && (M.ckey in GLOB.poll_ignore[ignore_category])))
continue
if(be_special_flag)
if(!(M.client.prefs) || !(be_special_flag in M.client.prefs.be_special))
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index ff9d1bec4c..7045767f98 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -51,26 +51,15 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/antenna, GLOB.ipc_antennas_list, roundstart = TRUE)
//genitals
init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list)
- for(var/K in GLOB.cock_shapes_list)
- var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K]
- GLOB.cock_shapes_icons[K] = value.icon_state
-
init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list)
GLOB.breasts_size_list = list ("a", "b", "c", "d", "e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
GLOB.gentlemans_organ_names = list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ",
"cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret",
"baloney pony", "schlanger", "Mutton dagger", "old blind bob","Hanging Johnny", "fishing rod", "Tally whacker", "polly rocket",
"One eyed trouser trout", "Ding dong", "ankle spanker", "Pork sword", "engine cranker", "Harry hot dog", "Davy Crockett",
"Kidney cracker", "Heat seeking moisture missile", "Giggle stick", "love whistle", "Tube steak", "Uncle Dick", "Purple helmet warrior")
- for(var/K in GLOB.breasts_shapes_list)
- var/datum/sprite_accessory/breasts/value = GLOB.breasts_shapes_list[K]
- GLOB.breasts_shapes_icons[K] = value.icon_state
-
- init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list)
- for(var/K in GLOB.balls_shapes_list)
- var/datum/sprite_accessory/testicles/value = GLOB.balls_shapes_list[K]
- GLOB.balls_shapes_icons[K] = value.icon_state
for(var/gpath in subtypesof(/obj/item/organ/genital))
var/obj/item/organ/genital/G = gpath
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 1669c941c2..a5924994e7 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -529,7 +529,7 @@ GLOBAL_LIST_EMPTY(species_list)
continue
if(M.stat != DEAD && !override)
continue
- if(speaker_key && speaker_key in prefs.ignoring)
+ if(speaker_key && (speaker_key in prefs.ignoring))
continue
switch(message_type)
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index 04e7ffd721..0f1e75ff73 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -146,19 +146,19 @@
var/list/file_data = list()
var/pos = 1
for(var/V in GLOB.news_network.network_channels)
- var/datum/newscaster/feed_channel/channel = V
+ var/datum/news/feed_channel/channel = V
if(!istype(channel))
stack_trace("Non-channel in newscaster channel list")
continue
file_data["[pos]"] = list("channel name" = "[channel.channel_name]", "author" = "[channel.author]", "censored" = channel.censored ? 1 : 0, "author censored" = channel.authorCensor ? 1 : 0, "messages" = list())
for(var/M in channel.messages)
- var/datum/newscaster/feed_message/message = M
+ var/datum/news/feed_message/message = M
if(!istype(message))
stack_trace("Non-message in newscaster channel messages list")
continue
var/list/comment_data = list()
for(var/C in message.comments)
- var/datum/newscaster/feed_comment/comment = C
+ var/datum/news/feed_comment/comment = C
if(!istype(comment))
stack_trace("Non-message in newscaster message comments list")
continue
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 3985659b71..beb005b8d1 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -44,6 +44,12 @@
index = findtext(t, char, index + length(char))
return t
+/proc/sanitize_name(t,list/repl_chars = null)
+ if(t == "space" || t == "floor" || t == "wall" || t == "r-wall" || t == "monkey" || t == "unknown" || t == "inactive ai") //prevents these common metagamey names
+ alert("Invalid name.")
+ return ""
+ return sanitize(t)
+
/proc/sanitize_filename(t)
return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"=""))
@@ -775,4 +781,4 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
#define is_alpha(X) ((text2ascii(X) <= 122) && (text2ascii(X) >= 97))
-#define is_digit(X) ((length(X) == 1) && (length(text2num(X)) == 1))
\ No newline at end of file
+#define is_digit(X) ((length(X) == 1) && (length(text2num(X)) == 1))
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 86dde3d6a6..2cb088c654 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1537,4 +1537,31 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
if(190)
return "."
if(189)
- return "-"
\ No newline at end of file
+ return "-"
+
+/proc/generate_items_inside(list/items_list, where_to)
+ for(var/each_item in items_list)
+ for(var/i in 1 to items_list[each_item])
+ new each_item(where_to)
+
+//sends a message to chat
+//config_setting should be one of the following
+//null - noop
+//empty string - use TgsTargetBroadcast with admin_only = FALSE
+//other string - use TgsChatBroadcast with the tag that matches config_setting, only works with TGS4, if using TGS3 the above method is used
+/proc/send2chat(message, config_setting)
+ if(config_setting == null || !world.TgsAvailable())
+ return
+ var/datum/tgs_version/version = world.TgsVersion()
+ if(config_setting == "" || version.suite == 3)
+ world.TgsTargetedChatBroadcast(message, FALSE)
+ return
+
+ var/list/channels_to_use = list()
+ for(var/I in world.TgsChatChannelInfo())
+ var/datum/tgs_chat_channel/channel = I
+ if(channel.tag == config_setting)
+ channels_to_use += channel
+
+ if(channels_to_use.len)
+ world.TgsChatBroadcast()
\ No newline at end of file
diff --git a/code/__HELPERS/vector.dm b/code/__HELPERS/vector.dm
new file mode 100644
index 0000000000..80295bde0e
--- /dev/null
+++ b/code/__HELPERS/vector.dm
@@ -0,0 +1,57 @@
+// Basic geometry things.
+
+/datum/vector/
+ var/x = 0
+ var/y = 0
+
+/datum/vector/New(var/x, var/y)
+ src.x = x
+ src.y = y
+
+/datum/vector/proc/duplicate()
+ return new /datum/vector(x, y)
+
+/datum/vector/proc/euclidian_norm()
+ return sqrt(x*x + y*y)
+
+/datum/vector/proc/squared_norm()
+ return x*x + y*y
+
+/datum/vector/proc/normalize()
+ var/norm = euclidian_norm()
+ x = x/norm
+ y = y/norm
+ return src
+
+/datum/vector/proc/chebyshev_norm()
+ return max(abs(x), abs(y))
+
+/datum/vector/proc/chebyshev_normalize()
+ var/norm = chebyshev_norm()
+ x = x/norm
+ y = y/norm
+ return src
+
+/datum/vector/proc/is_integer()
+ return ISINTEGER(x) && ISINTEGER(y)
+
+/atom/movable/proc/vector_translate(var/datum/vector/V, var/delay)
+ var/turf/T = get_turf(src)
+ var/turf/destination = locate(T.x + V.x, T.y + V.y, z)
+ var/datum/vector/V_norm = V.duplicate()
+ V_norm.chebyshev_normalize()
+ if (!V_norm.is_integer())
+ return
+ var/turf/destination_temp
+ while (destination_temp != destination)
+ destination_temp = locate(T.x + V_norm.x, T.y + V_norm.y, z)
+ forceMove(destination_temp)
+ T = get_turf(src)
+ sleep(delay + world.tick_lag) // Shortest possible time to sleep
+
+/atom/proc/get_translated_turf(var/datum/vector/V)
+ var/turf/T = get_turf(src)
+ return locate(T.x + V.x, T.y + V.y, z)
+
+/proc/atoms2vector(var/atom/A, var/atom/B)
+ return new /datum/vector((B.x - A.x), (B.y - A.y)) // Vector from A -> B
\ No newline at end of file
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index c98faaa4fb..a0139dab83 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -214,5 +214,18 @@ GLOBAL_LIST_INIT(bitfields, list(
"CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH,
"MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN,
"CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH
- )
- ))
\ No newline at end of file
+
+ ),
+ "mob_biotypes" = list (
+ "MOB_ORGANIC" = MOB_ORGANIC,
+ "MOB_MINERAL" = MOB_MINERAL,
+ "MOB_ROBOTIC" = MOB_ROBOTIC,
+ "MOB_UNDEAD" = MOB_UNDEAD,
+ "MOB_HUMANOID" = MOB_HUMANOID,
+ "MOB_BUG" = MOB_BUG,
+ "MOB_BEAST" = MOB_BEAST,
+ "MOB_EPIC" = MOB_EPIC,
+ "MOB_REPTILE" = MOB_REPTILE,
+ "MOB_SPIRIT" = MOB_SPIRIT
+ )
+ ))
diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm
index 1dcde53a72..819352ac1b 100644
--- a/code/_globalvars/lists/misc.dm
+++ b/code/_globalvars/lists/misc.dm
@@ -1 +1,59 @@
GLOBAL_LIST_EMPTY(donators_by_group) //group id = donator list of ckeys
+
+GLOBAL_LIST_INIT(flirts, list("Roses are red / Violets are good / One day while Andy...",
+ "My love for you is like the singularity. It cannot be contained.",
+ "Will you be my lusty xenomorph maid?",
+ "We go together like the clown and the external airlock.",
+ "Roses are red / Liches are wizards / I love you more than a whole squad of lizards.",
+ "Be my valentine. Law 2.",
+ "You must be a mime, because you leave me speechless.",
+ "I love you like Ian loves the HoP.",
+ "You're hotter than a plasma fire in toxins.",
+ "Are you a rogue atmos tech? Because you're taking my breath away.",
+ "Could I have all access... to your heart?",
+ "Call me the doctor, because I'm here to inspect your johnson.",
+ "I'm not a changeling, but you make my proboscis extend.",
+ "I just can't get EI NATH of you.",
+ "You must be a nuke op, because you make my heart explode.",
+ "Roses are red / Botany is a farm / Not being my Valentine / causes human harm.",
+ "I want you more than an assistant wants insulated gloves.",
+ "If I was a security officer, I'd brig you all shift.",
+ "Are you the janitor? Because I think I've fallen for you.",
+ "You're always valid to my heart.",
+ "I'd risk the wrath of the gods to bwoink you.",
+ "You look as beautiful now as the last time you were cloned.",
+ "Someone check the gravitational generator, because I'm only attracted to you.",
+ "If I were the warden I'd always let you into my armory.",
+ "The virologist is rogue, and the only cure is a kiss from you.",
+ "Would you spend some time in my upgraded sleeper?",
+ "You must be a silicon, because you've unbolted my heart.",
+ "Are you Nar'Sie? Because there's nar-one else I sie.",
+ "If you were a taser, you'd be set to stunning.",
+ "Do you have stamina damage from running through my dreams?",
+ "If I were an alien, would you let me hug you?",
+ "My love for you is stronger than a reinforced wall.",
+ "This must be the captain's office, because I see a fox.",
+ "I'm not a highlander, but there can only be one for me.",
+ "The floor is made of lava! Quick, get on my bed.",
+ "If you were an abandoned station you'd be the DEARelict.",
+ "If you had a pickaxe you'd be a shaft FINEr.",
+ "Roses are red, tide is gray, if I were an assistant I'd steal you away.",
+ "Roses are red, text is green, I love you more than cleanbots clean.",
+ "If you were a carp I'd fi-lay you.",
+ "I'm a nuke op, and my pinpointer leads to your heart.",
+ "Wanna slay my megafauna?",
+ "I'm a clockwork cultist. Or zl inyragvar.",
+ "If you were a disposal bin I'd ride you all day.",
+ "Put on your explorer's suit because I'm taking you to LOVEaland.",
+ "I must be the CMO, 'cause I saw you on my CUTE sensors.",
+ "You're the vomit to my flyperson.",
+ "You must be liquid dark matter, because you're pulling me closer.",
+ "Not even sorium can drive me away from you.",
+ "Wanna make like a borg and do some heavy petting?",
+ "Are you powering the station? Because you super matter to me.",
+ "I wish science could make me a bag of holding you.",
+ "Let's call the emergency CUDDLE.",
+ "I must be tripping on BZ, because I saw an angel walk by.",
+ "Wanna empty out my tool storage?",
+ "Did you visit the medbay after you fell from heaven?",
+ "Are you wearing space pants? Wanna not be?" ))
diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm
index 7ae197a5d1..e334d08040 100644
--- a/code/_globalvars/lists/names.dm
+++ b/code/_globalvars/lists/names.dm
@@ -4,6 +4,7 @@ GLOBAL_LIST_INIT(wizard_second, world.file2list("strings/names/wizardsecond.txt"
GLOBAL_LIST_INIT(ninja_titles, world.file2list("strings/names/ninjatitle.txt"))
GLOBAL_LIST_INIT(ninja_names, world.file2list("strings/names/ninjaname.txt"))
GLOBAL_LIST_INIT(commando_names, world.file2list("strings/names/death_commando.txt"))
+GLOBAL_LIST_INIT(first_names, world.file2list("strings/names/first.txt"))
GLOBAL_LIST_INIT(first_names_male, world.file2list("strings/names/first_male.txt"))
GLOBAL_LIST_INIT(first_names_female, world.file2list("strings/names/first_female.txt"))
GLOBAL_LIST_INIT(last_names, world.file2list("strings/names/last.txt"))
diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm
index dc18107a95..9638b040f9 100644
--- a/code/_onclick/drag_drop.dm
+++ b/code/_onclick/drag_drop.dm
@@ -42,7 +42,7 @@
selected_target[1] = object
selected_target[2] = params
while(selected_target[1])
- Click(selected_target[1], location, control, selected_target[2])
+ Click(selected_target[1], location, control, selected_target[2], TRUE)
sleep(delay)
active_mousedown_item = mob.canMobMousedown(object, location, params)
if(active_mousedown_item)
@@ -145,4 +145,4 @@
if (middragatom == src_object)
middragtime = 0
middragatom = null
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index cda19dbaac..9ba51afc69 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -1,19 +1,28 @@
-
+/**
+ *This is the proc that handles the order of an item_attack.
+ *The order of procs called is:
+ *tool_act on the target. If it returns TRUE, the chain will be stopped.
+ *pre_attack() on src. If this returns TRUE, the chain will be stopped.
+ *attackby on the target. If it returns TRUE, the chain will be stopped.
+ *and lastly
+ *afterattack. The return value does not matter.
+ */
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
- if(!tool_attack_chain(user, target) && pre_attack(target, user, params))
- // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
- var/resolved = target.attackby(src, user, params)
- if(!resolved && target && !QDELETED(src))
- afterattack(target, user, 1, params) // 1: clicking something Adjacent
-
-
-//Checks if the item can work as a tool, calling the appropriate tool behavior on the target
-/obj/item/proc/tool_attack_chain(mob/user, atom/target)
- if(!tool_behaviour)
- return FALSE
-
- return target.tool_act(user, src, tool_behaviour)
-
+ if(item_flags & NO_ATTACK_CHAIN_SOFT_STAMCRIT)
+ if(isliving(user))
+ var/mob/living/L = user
+ if(L.getStaminaLoss() >= STAMINA_SOFTCRIT)
+ to_chat(L, "You are too exhausted to swing [src]!")
+ return
+ if(tool_behaviour && target.tool_act(user, src, tool_behaviour))
+ return
+ if(pre_attack(target, user, params))
+ return
+ if(target.attackby(src,user, params))
+ return
+ if(QDELETED(src) || QDELETED(target))
+ return
+ afterattack(target, user, TRUE, params)
// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
/obj/item/proc/attack_self(mob/user)
@@ -23,8 +32,8 @@
/obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby!
if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK)
- return FALSE
- return TRUE //return FALSE to avoid calling attackby after this proc does stuff
+ return TRUE
+ return FALSE //return TRUE to avoid calling attackby after this proc does stuff
// No comment
/atom/proc/attackby(obj/item/W, mob/user, params)
@@ -112,7 +121,7 @@
send_item_attack_message(I, user)
if(I.force)
apply_damage(totitemdamage, I.damtype) //CIT CHANGE - replaces I.force with totitemdamage
- if(I.damtype == BRUTE && !HAS_TRAIT(src, TRAIT_NOMARROW))
+ if(I.damtype == BRUTE && !HAS_TRAIT(src, TRAIT_NOMARROW))
if(prob(33))
I.add_mob_blood(src)
var/turf/location = get_turf(src)
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index a3bc47ac91..0f12d1d9ae 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -234,6 +234,7 @@
/datum/config_entry/number/movedelay //Used for modifying movement speed for mobs.
abstract_type = /datum/config_entry/number/movedelay
+ integer = FALSE
/datum/config_entry/number/movedelay/ValidateAndSet()
. = ..()
diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm
index c3ae90cc1b..cb8c0fe966 100644
--- a/code/controllers/configuration/entries/general.dm
+++ b/code/controllers/configuration/entries/general.dm
@@ -1,3 +1,5 @@
+/datum/config_entry/flag/auto_profile // Automatically start profiler on server start
+
/datum/config_entry/flag/autoadmin // if autoadmin is enabled
protection = CONFIG_ENTRY_LOCKED
@@ -267,6 +269,9 @@
/datum/config_entry/flag/tgstyle_maprotation
+/datum/config_entry/string/map_vote_type
+ config_entry_value = "SCORE"
+
/datum/config_entry/number/maprotatechancedelta
config_entry_value = 0.75
min_val = 0
@@ -389,6 +394,13 @@
config_entry_value = 50
/datum/config_entry/flag/irc_announce_new_game
+ deprecated_by = /datum/config_entry/string/chat_announce_new_game
+
+/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value)
+ return "" //default broadcast
+
+/datum/config_entry/string/chat_announce_new_game
+ config_entry_value = null
/datum/config_entry/flag/debug_admin_hrefs
diff --git a/code/controllers/configuration/entries/plushies.dm b/code/controllers/configuration/entries/plushies.dm
new file mode 100644
index 0000000000..20ad02d399
--- /dev/null
+++ b/code/controllers/configuration/entries/plushies.dm
@@ -0,0 +1,6 @@
+/datum/config_entry/number/snowflake_plushie_prob
+ config_entry_value = 50
+
+/datum/config_entry/keyed_list/snowflake_plushies
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_TEXT
diff --git a/code/controllers/subsystem/fail2topic.dm b/code/controllers/subsystem/fail2topic.dm
index b358cc2c5f..02e7bc7aab 100644
--- a/code/controllers/subsystem/fail2topic.dm
+++ b/code/controllers/subsystem/fail2topic.dm
@@ -31,15 +31,18 @@ SUBSYSTEM_DEF(fail2topic)
return ..()
/datum/controller/subsystem/fail2topic/fire()
- for(var/i in 1 to length(rate_limiting))
- var/ip = rate_limiting[i]
- var/last_attempt = rate_limiting[ip]
- if (world.time - last_attempt > rate_limit)
- rate_limiting -= ip
- fail_counts -= ip
-
- if (MC_TICK_CHECK)
- return
+ if(length(rate_limiting))
+ var/i = 1
+ while(i <= length(rate_limiting))
+ var/ip = rate_limiting[i]
+ var/last_attempt = rate_limiting[ip]
+ if(world.time - last_attempt > rate_limit)
+ rate_limiting -= ip
+ fail_counts -= ip
+ else //if we remove that, and the next element is in its place. check that instead of incrementing.
+ ++i
+ if(MC_TICK_CHECK)
+ return
/datum/controller/subsystem/fail2topic/Shutdown()
DropFirewallRule()
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 7597a9229a..31e436f206 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -118,7 +118,7 @@ SUBSYSTEM_DEF(job)
if(flag && (!(flag in player.client.prefs.be_special)))
JobDebug("FOC flag failed, Player: [player], Flag: [flag], ")
continue
- if(player.mind && job.title in player.mind.restricted_roles)
+ if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("FOC incompatible with antagonist role, Player: [player]")
continue
if(player.client.prefs.job_preferences[job.title] == level)
@@ -158,7 +158,7 @@ SUBSYSTEM_DEF(job)
JobDebug("GRJ player not enough xp, Player: [player]")
continue
- if(player.mind && job.title in player.mind.restricted_roles)
+ if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]")
continue
@@ -340,7 +340,7 @@ SUBSYSTEM_DEF(job)
JobDebug("DO non-human failed, Player: [player], Job:[job.title]")
continue
- if(player.mind && job.title in player.mind.restricted_roles)
+ if(player.mind && (job.title in player.mind.restricted_roles))
JobDebug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
continue
diff --git a/code/controllers/subsystem/weather.dm b/code/controllers/subsystem/processing/weather.dm
similarity index 77%
rename from code/controllers/subsystem/weather.dm
rename to code/controllers/subsystem/processing/weather.dm
index 5e44f2e4c3..0a1b4fc609 100644
--- a/code/controllers/subsystem/weather.dm
+++ b/code/controllers/subsystem/processing/weather.dm
@@ -4,25 +4,16 @@
#define END_STAGE 4
//Used for all kinds of weather, ex. lavaland ash storms.
-SUBSYSTEM_DEF(weather)
+PROCESSING_SUBSYSTEM_DEF(weather)
name = "Weather"
flags = SS_BACKGROUND
wait = 10
runlevels = RUNLEVEL_GAME
- var/list/processing = list()
var/list/eligible_zlevels = list()
var/list/next_hit_by_zlevel = list() //Used by barometers to know when the next storm is coming
-/datum/controller/subsystem/weather/fire()
- // process active weather
- for(var/V in processing)
- var/datum/weather/W = V
- if(W.aesthetic || W.stage != MAIN_STAGE)
- continue
- for(var/i in GLOB.mob_living_list)
- var/mob/living/L = i
- if(W.can_weather_act(L))
- W.weather_act(L)
+/datum/controller/subsystem/processing/weather/fire()
+ . = ..() //Active weather is handled by . = ..() processing subsystem base fire().
// start random weather on relevant levels
for(var/z in eligible_zlevels)
@@ -34,7 +25,7 @@ SUBSYSTEM_DEF(weather)
addtimer(CALLBACK(src, .proc/make_eligible, z, possible_weather), randTime + initial(W.weather_duration_upper), TIMER_UNIQUE) //Around 5-10 minutes between weathers
next_hit_by_zlevel["[z]"] = world.time + randTime + initial(W.telegraph_duration)
-/datum/controller/subsystem/weather/Initialize(start_timeofday)
+/datum/controller/subsystem/processing/weather/Initialize(start_timeofday)
for(var/V in subtypesof(/datum/weather))
var/datum/weather/W = V
var/probability = initial(W.probability)
@@ -47,7 +38,7 @@ SUBSYSTEM_DEF(weather)
eligible_zlevels["[z]"][W] = probability
return ..()
-/datum/controller/subsystem/weather/proc/run_weather(datum/weather/weather_datum_type, z_levels)
+/datum/controller/subsystem/processing/weather/proc/run_weather(datum/weather/weather_datum_type, z_levels)
if (istext(weather_datum_type))
for (var/V in subtypesof(/datum/weather))
var/datum/weather/W = V
@@ -69,11 +60,11 @@ SUBSYSTEM_DEF(weather)
var/datum/weather/W = new weather_datum_type(z_levels)
W.telegraph()
-/datum/controller/subsystem/weather/proc/make_eligible(z, possible_weather)
+/datum/controller/subsystem/processing/weather/proc/make_eligible(z, possible_weather)
eligible_zlevels[z] = possible_weather
next_hit_by_zlevel["[z]"] = null
-/datum/controller/subsystem/weather/proc/get_weather(z, area/active_area)
+/datum/controller/subsystem/processing/weather/proc/get_weather(z, area/active_area)
var/datum/weather/A
for(var/V in processing)
var/datum/weather/W = V
diff --git a/code/controllers/subsystem/profiler.dm b/code/controllers/subsystem/profiler.dm
new file mode 100644
index 0000000000..ec8b243073
--- /dev/null
+++ b/code/controllers/subsystem/profiler.dm
@@ -0,0 +1,63 @@
+#define PROFILER_FILENAME "profiler.json"
+
+SUBSYSTEM_DEF(profiler)
+ name = "Profiler"
+ init_order = INIT_ORDER_PROFILER
+ runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
+ wait = 3000
+ flags = SS_NO_TICK_CHECK
+ var/fetch_cost = 0
+ var/write_cost = 0
+
+/datum/controller/subsystem/profiler/stat_entry(msg)
+ msg += "F:[round(fetch_cost,1)]ms"
+ msg += "|W:[round(write_cost,1)]ms"
+ ..(msg)
+
+/datum/controller/subsystem/profiler/Initialize()
+ if(CONFIG_GET(flag/auto_profile))
+ StartProfiling()
+ else
+ StopProfiling() //Stop the early start from world/New
+ return ..()
+
+/datum/controller/subsystem/profiler/fire()
+ if(CONFIG_GET(flag/auto_profile))
+ DumpFile()
+
+/datum/controller/subsystem/profiler/Shutdown()
+ if(CONFIG_GET(flag/auto_profile))
+ DumpFile()
+ return ..()
+
+/datum/controller/subsystem/profiler/proc/StartProfiling()
+#if DM_BUILD < 1506 || DM_VERSION < 513
+ stack_trace("Auto profiling unsupported on this byond version")
+ CONFIG_SET(flag/auto_profile, FALSE)
+#else
+ world.Profile(PROFILE_START)
+#endif
+
+/datum/controller/subsystem/profiler/proc/StopProfiling()
+#if DM_BUILD >= 1506 && DM_VERSION >= 513
+ world.Profile(PROFILE_STOP)
+#endif
+
+/datum/controller/subsystem/profiler/proc/DumpFile()
+#if DM_BUILD < 1506 || DM_VERSION < 513
+ stack_trace("Auto profiling unsupported on this byond version")
+ CONFIG_SET(flag/auto_profile, FALSE)
+#else
+ var/timer = TICK_USAGE_REAL
+ var/current_profile_data = world.Profile(PROFILE_REFRESH,format="json")
+ fetch_cost = MC_AVERAGE(fetch_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
+ CHECK_TICK
+ if(!length(current_profile_data)) //Would be nice to have explicit proc to check this
+ stack_trace("Warning, profiling stopped manually before dump.")
+ var/json_file = file("[GLOB.log_directory]/[PROFILER_FILENAME]")
+ if(fexists(json_file))
+ fdel(json_file)
+ timer = TICK_USAGE_REAL
+ WRITE_FILE(json_file, current_profile_data)
+ write_cost = MC_AVERAGE(write_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
+#endif
diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm
index 9e926b29a1..b77c78c4bb 100644
--- a/code/controllers/subsystem/server_maint.dm
+++ b/code/controllers/subsystem/server_maint.dm
@@ -81,8 +81,8 @@ SUBSYSTEM_DEF(server_maint)
co.ehjax_send(data = "roundrestart")
if(server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
C << link("byond://[server]")
- var/tgsversion = world.TgsVersion()
+ var/datum/tgs_version/tgsversion = world.TgsVersion()
if(tgsversion)
- SSblackbox.record_feedback("text", "server_tools", 1, tgsversion)
+ SSblackbox.record_feedback("text", "server_tools", 1, tgsversion.raw_parameter)
#undef PING_BUFFER_TIME
diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index 4d9eefae5b..7eff8b9e3c 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -38,7 +38,7 @@ SUBSYSTEM_DEF(shuttle)
var/points = 5000 //number of trade-points we have
var/centcom_message = "" //Remarks from CentCom on how well you checked the last order.
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentCom, associated with their potencies
- var/passive_supply_points_per_minute = 500
+ var/passive_supply_points_per_minute = 125
var/list/supply_packs = list()
var/list/shoppinglist = list()
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index ceb003210e..606aca2d3a 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -158,8 +158,7 @@ SUBSYSTEM_DEF(ticker)
for(var/client/C in GLOB.clients)
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
to_chat(world, "Welcome to [station_name()]!")
- if(CONFIG_GET(flag/irc_announce_new_game))
- world.TgsTargetedChatBroadcast("New round starting on [SSmapping.config.map_name]!", FALSE)
+ send2chat("New round starting on [SSmapping.config.map_name]!", CONFIG_GET(string/chat_announce_new_game))
current_state = GAME_STATE_PREGAME
//Everyone who wants to be an observer is now spawned
create_observers()
@@ -365,7 +364,7 @@ SUBSYSTEM_DEF(ticker)
var/turf/epi = bomb.loc
qdel(bomb)
if(epi)
- explosion(epi, 0, 256, 512, 0, TRUE, TRUE, 0, TRUE)
+ explosion(epi, 512, 0, 0, 0, TRUE, TRUE, 0, TRUE)
/datum/controller/subsystem/ticker/proc/create_characters()
for(var/mob/dead/new_player/player in GLOB.player_list)
@@ -477,7 +476,19 @@ SUBSYSTEM_DEF(ticker)
if(CONFIG_GET(flag/tgstyle_maprotation))
INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/.proc/maprotate)
else
- SSvote.initiate_vote("map","server",TRUE)
+ var/vote_type = CONFIG_GET(string/map_vote_type)
+ switch(vote_type)
+ if("PLURALITY")
+ SSvote.initiate_vote("map","server",hideresults=TRUE)
+ if("APPROVAL")
+ SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = APPROVAL_VOTING)
+ if("IRV")
+ SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = INSTANT_RUNOFF_VOTING)
+ if("SCORE")
+ SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = MAJORITY_JUDGEMENT_VOTING)
+ else
+ SSvote.initiate_vote("map","server",hideresults=TRUE)
+ // fallback
/datum/controller/subsystem/ticker/proc/HasRoundStarted()
return current_state >= GAME_STATE_PLAYING
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index 2a7c4401f3..f3513b7af7 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -149,7 +149,7 @@ SUBSYSTEM_DEF(vote)
var/list/this_vote = voted[ckey]
var/list/pretty_vote = list()
for(var/choice in choices)
- if("[choice]" in this_vote && "[choice]" in scores_by_choice)
+ if(("[choice]" in this_vote) && ("[choice]" in scores_by_choice))
sorted_insert(scores_by_choice["[choice]"],this_vote["[choice]"],/proc/cmp_numeric_asc)
// START BALLOT GATHERING
pretty_vote += "[choice]"
@@ -160,7 +160,7 @@ SUBSYSTEM_DEF(vote)
for(var/score_name in scores_by_choice)
var/list/score = scores_by_choice[score_name]
for(var/indiv_score in score)
- SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score]))
+ SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score]))
if(score.len == 0)
scores_by_choice -= score_name
while(scores_by_choice.len > 1)
@@ -201,7 +201,10 @@ SUBSYSTEM_DEF(vote)
max_score=max(max_score,scores[score_name])
min_score=min(min_score,scores[score_name])
for(var/score_name in scores)
- scores[score_name] = (scores[score_name]-min_score)/(max_score-min_score)
+ if(max_score == min_score)
+ scores[score_name] = 1
+ else
+ scores[score_name] = (scores[score_name]-min_score)/(max_score-min_score)
SSblackbox.record_feedback("nested tally","voting",scores[score_name],list(blackbox_text,"Total scores",score_name))
/datum/controller/subsystem/vote/proc/get_runoff_results(var/blackbox_text)
@@ -213,7 +216,7 @@ SUBSYSTEM_DEF(vote)
for(var/ckey in voted)
cur_choices[cur_choices[voted[ckey][1]]]++ // jesus christ how horrifying
var/least_vote = 100000
- var/least_voted
+ var/least_voted = 1
for(var/i in 1 to cur_choices.len)
var/option = cur_choices[i]
if(cur_choices[option] > voted.len/2)
@@ -224,8 +227,8 @@ SUBSYSTEM_DEF(vote)
already_lost_runoff += cur_choices[least_voted]
for(var/ckey in voted)
voted[ckey] -= least_voted
- for(var/option in cur_choices)
- cur_choices[option] = 0
+ for(var/i in 1 to cur_choices.len)
+ cur_choices[cur_choices[i]] = 0
/datum/controller/subsystem/vote/proc/announce_result()
var/vote_title_text
@@ -252,14 +255,13 @@ SUBSYSTEM_DEF(vote)
text += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!"
if(vote_system == MAJORITY_JUDGEMENT_VOTING)
text += "\nIt should be noted that this is not a raw tally of votes but the number of runoffs done by majority judgement!"
- else
- for(var/i=1,i<=choices.len,i++)
- var/votes = choices[choices[i]]
- if(!votes)
- votes = 0
- if(was_roundtype_vote)
- stored_gamemode_votes[choices[i]] = votes
- text += "\n[choices[i]]: [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes
+ for(var/i=1,i<=choices.len,i++)
+ var/votes = choices[choices[i]]
+ if(!votes)
+ votes = 0
+ if(was_roundtype_vote)
+ stored_gamemode_votes[choices[i]] = votes
+ text += "\n[choices[i]]: [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes
if(mode != "custom")
if(winners.len > 1 && !obfuscated) //CIT CHANGE - adds obfuscated votes
text = "\nVote Tied Between:"
@@ -374,7 +376,7 @@ SUBSYSTEM_DEF(vote)
else
to_chat(world, "Notice:Restart vote will not restart the server automatically because there are active admins on.")
message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.")
-
+
return .
/datum/controller/subsystem/vote/proc/submit_vote(vote, score = 0)
@@ -484,6 +486,8 @@ SUBSYSTEM_DEF(vote)
question = stripped_input(usr,"What is the vote for?")
if(!question)
return 0
+ var/system_string = input(usr,"Which voting type?",GLOB.vote_type_names[1]) in GLOB.vote_type_names
+ vote_system = GLOB.vote_type_names[system_string]
for(var/i=1,i<=10,i++)
var/option = capitalize(stripped_input(usr,"Please enter an option or hit cancel to finish"))
if(!option || mode || !usr.client)
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 8659a9e7c4..04d9c706ed 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -544,6 +544,70 @@
cooldown = world.time
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
+/datum/action/item_action/removeAPCs
+ name = "Relinquish APC"
+ desc = "Let go of an APC, relinquish control back to the station."
+ icon_icon = 'icons/obj/implants.dmi'
+ button_icon_state = "hijackx"
+
+/datum/action/item_action/removeAPCs/Trigger()
+ var/list/areas = list()
+ for (var/area/a in owner.siliconaccessareas)
+ areas[a.name] = a
+ var/removeAPC = input("Select an APC to remove:","Remove APC Control",1) as null|anything in areas
+ if (!removeAPC)
+ return
+ var/area/area = areas[removeAPC]
+ var/obj/machinery/power/apc/apc = area.get_apc()
+ if (!apc || !(area in owner.siliconaccessareas))
+ return
+ apc.hijacker = null
+ apc.update_icon()
+ apc.set_hijacked_lighting()
+ owner.toggleSiliconAccessArea(area)
+
+/datum/action/item_action/accessAPCs
+ name = "Access APC Interface"
+ desc = "Open the APC's interface."
+ icon_icon = 'icons/obj/implants.dmi'
+ button_icon_state = "hijacky"
+
+/datum/action/item_action/accessAPCs/Trigger()
+ var/list/areas = list()
+ for (var/area/a in owner.siliconaccessareas)
+ areas[a.name] = a
+ var/accessAPC = input("Select an APC to access:","Access APC Interface",1) as null|anything in areas
+ if (!accessAPC)
+ return
+ var/area/area = areas[accessAPC]
+ var/obj/machinery/power/apc/apc = area.get_apc()
+ if (!apc || !(area in owner.siliconaccessareas))
+ return
+ apc.ui_interact(owner)
+
+/datum/action/item_action/stealthmodetoggle
+ name = "Toggle Stealth Mode"
+ desc = "Toggles the stealth mode on the hijack implant."
+ icon_icon = 'icons/obj/implants.dmi'
+ button_icon_state = "hijackz"
+
+/datum/action/item_action/stealthmodetoggle/Trigger()
+ var/obj/item/implant/hijack/H = target
+ if (!istype(H))
+ return
+ if (H.stealthcooldown > world.time)
+ to_chat(owner,"The hijack implant's stealth mode toggle is still rebooting!")
+ return
+ H.stealthmode = !H.stealthmode
+ for (var/area/area in H.imp_in.siliconaccessareas)
+ var/obj/machinery/power/apc/apc = area.get_apc()
+ if (apc)
+ apc.set_hijacked_lighting()
+ apc.update_icon()
+ H.stealthcooldown = world.time + 15 SECONDS
+ H.toggle_eyes()
+ to_chat(owner,"You toggle the hijack implant's stealthmode [H.stealthmode ? "on" : "off"].")
+
/datum/action/item_action/flash
name = "Flash"
@@ -756,3 +820,11 @@
target.layer = old_layer
target.plane = old_plane
current_button.appearance_cache = target.appearance
+
+/proc/get_action_of_type(mob/M, var/action_type)
+ if(!M.actions || !ispath(action_type, /datum/action))
+ return
+ for(var/datum/action/A in M.actions)
+ if(istype(A, action_type))
+ return A
+ return
\ No newline at end of file
diff --git a/code/datums/beam.dm b/code/datums/beam.dm
index d0b6d791ec..d97ee9a773 100644
--- a/code/datums/beam.dm
+++ b/code/datums/beam.dm
@@ -61,7 +61,8 @@
/datum/beam/proc/recalculate_in(time)
if(timing_id)
deltimer(timing_id)
- timing_id = addtimer(CALLBACK(src, .proc/recalculate), time, TIMER_STOPPABLE)
+ if(!finished)
+ timing_id = addtimer(CALLBACK(src, .proc/recalculate), time, TIMER_STOPPABLE)
/datum/beam/proc/after_calculate()
if((sleep_time == null) || finished) //Does not automatically recalculate.
diff --git a/code/datums/components/crafting/craft.dm b/code/datums/components/crafting/craft.dm
index 5c21801c14..b5c7f34c27 100644
--- a/code/datums/components/crafting/craft.dm
+++ b/code/datums/components/crafting/craft.dm
@@ -64,29 +64,48 @@
-
-/datum/component/personal_crafting/proc/check_contents(datum/crafting_recipe/R, list/contents)
+/**
+ * Check that the contents of the recipe meet the requirements.
+ *
+ * user: The /mob that initated the crafting.
+ * R: The /datum/crafting_recipe being attempted.
+ * contents: List of items to search for R's reqs.
+ */
+/datum/component/personal_crafting/proc/check_contents(mob/user, datum/crafting_recipe/R, list/contents)
+ var/list/item_instances = contents["instances"]
contents = contents["other"]
- main_loop:
- for(var/A in R.reqs)
- var/needed_amount = R.reqs[A]
- for(var/B in contents)
- if(ispath(B, A))
- if (R.blacklist.Find(B))
- continue
- if(contents[B] >= R.reqs[A])
- continue main_loop
- else
- needed_amount -= contents[B]
- if(needed_amount <= 0)
- continue main_loop
- else
- continue
+
+ var/list/requirements_list = list()
+
+ // Process all requirements
+ for(var/requirement_path in R.reqs)
+ // Check we have the appropriate amount available in the contents list
+ var/needed_amount = R.reqs[requirement_path]
+ for(var/content_item_path in contents)
+ // Right path and not blacklisted
+ if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(requirement_path))
+ continue
+
+ needed_amount -= contents[content_item_path]
+ if(needed_amount <= 0)
+ break
+
+ if(needed_amount > 0)
return FALSE
- for(var/A in R.chem_catalysts)
- if(contents[A] < R.chem_catalysts[A])
+
+ // Store the instances of what we will use for R.check_requirements() for requirement_path
+ var/list/instances_list = list()
+ for(var/instance_path in item_instances)
+ if(ispath(instance_path, requirement_path))
+ instances_list += item_instances[instance_path]
+
+ requirements_list[requirement_path] = instances_list
+
+ for(var/requirement_path in R.chem_catalysts)
+ if(contents[requirement_path] < R.chem_catalysts[requirement_path])
return FALSE
- return TRUE
+
+ return R.check_requirements(user, requirements_list)
/datum/component/personal_crafting/proc/get_environment(mob/user)
. = list()
@@ -110,9 +129,14 @@
. = list()
.["tool_behaviour"] = list()
.["other"] = list()
+ .["instances"] = list()
for(var/obj/item/I in get_environment(user))
if(I.flags_1 & HOLOGRAM_1)
continue
+ if(.["instances"][I.type])
+ .["instances"][I.type] += I
+ else
+ .["instances"][I.type] = list(I)
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
.["other"][I.type] += S.amount
@@ -161,11 +185,11 @@
/datum/component/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R)
var/list/contents = get_surroundings(user)
var/send_feedback = 1
- if(check_contents(R, contents))
+ if(check_contents(user, R, contents))
if(check_tools(user, R, contents))
if(do_after(user, R.time, target = user))
contents = get_surroundings(user)
- if(!check_contents(R, contents))
+ if(!check_contents(user, R, contents))
return ", missing component."
if(!check_tools(user, R, contents))
return ", missing tool."
@@ -341,7 +365,7 @@
if((R.category != cur_category) || (R.subcategory != cur_subcategory))
continue
- craftability["[REF(R)]"] = check_contents(R, surroundings)
+ craftability["[REF(R)]"] = check_contents(user, R, surroundings)
data["craftability"] = craftability
return data
diff --git a/code/datums/components/crafting/guncrafting.dm b/code/datums/components/crafting/guncrafting.dm
index d96be9be10..d421a6e42a 100644
--- a/code/datums/components/crafting/guncrafting.dm
+++ b/code/datums/components/crafting/guncrafting.dm
@@ -13,3 +13,9 @@
desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood."
icon = 'icons/obj/improvised.dmi'
icon_state = "riflestock"
+
+/obj/item/weaponcrafting/silkstring
+ name = "silkstring"
+ desc = "A long pice of silk looks like cable coil."
+ icon = 'icons/obj/improvised.dmi'
+ icon_state = "silkstring"
\ No newline at end of file
diff --git a/code/datums/components/crafting/recipes/recipes_primal.dm b/code/datums/components/crafting/recipes/recipes_primal.dm
index 1be479e4e1..ae611e5855 100644
--- a/code/datums/components/crafting/recipes/recipes_primal.dm
+++ b/code/datums/components/crafting/recipes/recipes_primal.dm
@@ -1,10 +1,3 @@
-/datum/crafting_recipe/bonearmor
- name = "Bone Armor"
- result = /obj/item/clothing/suit/armor/bone
- time = 30
- reqs = list(/obj/item/stack/sheet/bone = 6)
- category = CAT_PRIMAL
-
/datum/crafting_recipe/bonetalisman
name = "Bone Talisman"
result = /obj/item/clothing/accessory/talisman
@@ -29,13 +22,6 @@
/obj/item/stack/sheet/sinew = 1)
category = CAT_PRIMAL
-/datum/crafting_recipe/skullhelm
- name = "Skull Helmet"
- result = /obj/item/clothing/head/helmet/skull
- time = 30
- reqs = list(/obj/item/stack/sheet/bone = 4)
- category = CAT_PRIMAL
-
/datum/crafting_recipe/goliathcloak
name = "Goliath Cloak"
result = /obj/item/clothing/suit/hooded/cloak/goliath
@@ -62,13 +48,6 @@
/obj/item/stack/sheet/sinew = 2)
category = CAT_PRIMAL
-/datum/crafting_recipe/bonedagger
- name = "Bone Dagger"
- result = /obj/item/kitchen/knife/combat/bone
- time = 20
- reqs = list(/obj/item/stack/sheet/bone = 2)
- category = CAT_PRIMAL
-
/datum/crafting_recipe/bonespear
name = "Bone Spear"
result = /obj/item/twohanded/bonespear
@@ -110,4 +89,31 @@
parts = list(/obj/item/bodypart/head = 1,
/obj/item/twohanded/bonespear = 1)
result = /obj/structure/headpike/bone
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/quiver
+ name = "Quiver"
+ always_availible = FALSE
+ result = /obj/item/storage/belt/quiver
+ time = 80
+ reqs = list(/obj/item/stack/sheet/leather = 3,
+ /obj/item/stack/sheet/sinew = 4)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bone_bow
+ name = "Bone Bow"
+ result = /obj/item/gun/ballistic/bow/ashen
+ time = 200
+ always_availible = FALSE
+ reqs = list(/obj/item/stack/sheet/bone = 8,
+ /obj/item/stack/sheet/sinew = 4)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bow_tablet
+ name = "Sandstone Bow Making Manual"
+ result = /obj/item/book/granter/crafting_recipe/bone_bow
+ time = 600 //Scribing
+ always_availible = FALSE
+ reqs = list(/obj/item/stack/rods = 1,
+ /obj/item/stack/sheet/mineral/sandstone = 4)
category = CAT_PRIMAL
\ No newline at end of file
diff --git a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm
index 06f79396b8..76f8f119e0 100644
--- a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm
+++ b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm
@@ -8,6 +8,12 @@
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
+/datum/crafting_recipe/pin_removal/check_requirements(mob/user, list/collected_requirements)
+ var/obj/item/gun/G = collected_requirements[/obj/item/gun][1]
+ if (G.no_pin_required || !G.pin)
+ return FALSE
+ return TRUE
+
/datum/crafting_recipe/strobeshield
name = "Strobe Shield"
result = /obj/item/assembly/flash/shield
@@ -193,6 +199,16 @@
//////////////////
+/datum/crafting_recipe/pipebow
+ name = "Pipe Bow"
+ result = /obj/item/gun/ballistic/bow/pipe
+ reqs = list(/obj/item/pipe = 5,
+ /obj/item/stack/sheet/plastic = 15,
+ /obj/item/weaponcrafting/silkstring = 10)
+ time = 450
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
/datum/crafting_recipe/smartdartgun
name = "Smart dartgun"
result = /obj/item/gun/syringe/dart
@@ -272,6 +288,37 @@
///AMMO CRAFTING//
//////////////////
+/datum/crafting_recipe/arrow
+ name = "Arrow"
+ result = /obj/item/ammo_casing/caseless/arrow
+ time = 40
+ reqs = list(/obj/item/stack/sheet/mineral/wood = 1,
+ /obj/item/weaponcrafting/silkstring = 1,
+ /obj/item/stack/rods = 3) // 1 metal sheet is worth 1.5 arrows
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/bone_arrow
+ name = "Bone Arrow"
+ result = /obj/item/ammo_casing/caseless/arrow/bone
+ time = 40
+ always_availible = FALSE
+ reqs = list(/obj/item/stack/sheet/bone = 1,
+ /obj/item/stack/sheet/sinew = 1,
+ /obj/item/ammo_casing/caseless/arrow/ashen = 1)
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/ashen_arrow
+ name = "Harden Arrow"
+ result = /obj/item/ammo_casing/caseless/arrow/ashen
+ tools = list(/obj/structure/bonfire)
+ time = 20
+ always_availible = FALSE
+ reqs = list(/obj/item/ammo_casing/caseless/arrow = 1)
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
/datum/crafting_recipe/smartdart
name = "Medical smartdart"
result = /obj/item/reagent_containers/syringe/dart
diff --git a/code/datums/components/nanites.dm b/code/datums/components/nanites.dm
index e1c96121c7..49b2e437d4 100644
--- a/code/datums/components/nanites.dm
+++ b/code/datums/components/nanites.dm
@@ -7,13 +7,16 @@
var/regen_rate = 0.5 //nanites generated per second
var/safety_threshold = 25 //how low nanites will get before they stop processing/triggering
var/cloud_id = 0 //0 if not connected to the cloud, 1-100 to set a determined cloud backup to draw from
+ var/cloud_active = TRUE //if false, won't sync to the cloud
var/next_sync = 0
var/list/datum/nanite_program/programs = list()
var/max_programs = NANITE_PROGRAM_LIMIT
+ var/list/datum/nanite_program/protocol/protocols = list() ///Separate list of protocol programs, to avoid looping through the whole programs list when cheking for conflicts
+ var/start_time = 0 ///Timestamp to when the nanites were first inserted in the host
var/stealth = FALSE //if TRUE, does not appear on HUDs and health scans
var/diagnostics = TRUE //if TRUE, displays program list when scanned by nanite scanners
-
+
/datum/component/nanites/Initialize(amount = 100, cloud = 0)
if(!isliving(parent) && !istype(parent, /datum/nanite_cloud_backup))
return COMPONENT_INCOMPATIBLE
@@ -25,33 +28,36 @@
if(isliving(parent))
host_mob = parent
- if(!(MOB_ORGANIC in host_mob.mob_biotypes) && !(MOB_UNDEAD in host_mob.mob_biotypes)) //Shouldn't happen, but this avoids HUD runtimes in case a silicon gets them somehow.
+ if(!(host_mob.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD))) //Shouldn't happen, but this avoids HUD runtimes in case a silicon gets them somehow.
return COMPONENT_INCOMPATIBLE
+ start_time = world.time
+
host_mob.hud_set_nanite_indicator()
START_PROCESSING(SSnanites, src)
- if(cloud_id)
+ if(cloud_id && cloud_active)
cloud_sync()
/datum/component/nanites/RegisterWithParent()
- . = ..()
RegisterSignal(parent, COMSIG_HAS_NANITES, .proc/confirm_nanites)
RegisterSignal(parent, COMSIG_NANITE_IS_STEALTHY, .proc/check_stealth)
+ RegisterSignal(parent, COMSIG_NANITE_DELETE, .proc/delete_nanites)
RegisterSignal(parent, COMSIG_NANITE_UI_DATA, .proc/nanite_ui_data)
RegisterSignal(parent, COMSIG_NANITE_GET_PROGRAMS, .proc/get_programs)
RegisterSignal(parent, COMSIG_NANITE_SET_VOLUME, .proc/set_volume)
RegisterSignal(parent, COMSIG_NANITE_ADJUST_VOLUME, .proc/adjust_nanites)
RegisterSignal(parent, COMSIG_NANITE_SET_MAX_VOLUME, .proc/set_max_volume)
RegisterSignal(parent, COMSIG_NANITE_SET_CLOUD, .proc/set_cloud)
+ RegisterSignal(parent, COMSIG_NANITE_SET_CLOUD_SYNC, .proc/set_cloud_sync)
RegisterSignal(parent, COMSIG_NANITE_SET_SAFETY, .proc/set_safety)
RegisterSignal(parent, COMSIG_NANITE_SET_REGEN, .proc/set_regen)
RegisterSignal(parent, COMSIG_NANITE_ADD_PROGRAM, .proc/add_program)
RegisterSignal(parent, COMSIG_NANITE_SCAN, .proc/nanite_scan)
RegisterSignal(parent, COMSIG_NANITE_SYNC, .proc/sync)
- RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp)
if(isliving(parent))
+ RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp)
RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/on_death)
RegisterSignal(parent, COMSIG_MOB_ALLOWED, .proc/check_access)
RegisterSignal(parent, COMSIG_LIVING_ELECTROCUTE_ACT, .proc/on_shock)
@@ -61,15 +67,16 @@
RegisterSignal(parent, COMSIG_NANITE_COMM_SIGNAL, .proc/receive_comm_signal)
/datum/component/nanites/UnregisterFromParent()
- . = ..()
UnregisterSignal(parent, list(COMSIG_HAS_NANITES,
COMSIG_NANITE_IS_STEALTHY,
+ COMSIG_NANITE_DELETE,
COMSIG_NANITE_UI_DATA,
COMSIG_NANITE_GET_PROGRAMS,
COMSIG_NANITE_SET_VOLUME,
COMSIG_NANITE_ADJUST_VOLUME,
COMSIG_NANITE_SET_MAX_VOLUME,
COMSIG_NANITE_SET_CLOUD,
+ COMSIG_NANITE_SET_CLOUD_SYNC,
COMSIG_NANITE_SET_SAFETY,
COMSIG_NANITE_SET_REGEN,
COMSIG_NANITE_ADD_PROGRAM,
@@ -87,9 +94,9 @@
/datum/component/nanites/Destroy()
STOP_PROCESSING(SSnanites, src)
- set_nanite_bar(TRUE)
QDEL_LIST(programs)
if(host_mob)
+ set_nanite_bar(TRUE)
host_mob.hud_set_nanite_indicator()
host_mob = null
return ..()
@@ -102,13 +109,18 @@
/datum/component/nanites/process()
adjust_nanites(null, regen_rate)
+ add_research()
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_process()
- set_nanite_bar()
- if(cloud_id && world.time > next_sync)
+ if(cloud_id && cloud_active && world.time > next_sync)
cloud_sync()
next_sync = world.time + NANITE_SYNC_DELAY
+ set_nanite_bar()
+
+
+/datum/component/nanites/proc/delete_nanites()
+ qdel(src)
//Syncs the nanite component to another, making it so programs are the same with the same programming (except activation status)
/datum/component/nanites/proc/sync(datum/signal_source, datum/component/nanites/source, full_overwrite = TRUE, copy_activation = FALSE)
@@ -131,13 +143,17 @@
add_program(null, SNP.copy())
/datum/component/nanites/proc/cloud_sync()
- if(!cloud_id)
- return
- var/datum/nanite_cloud_backup/backup = SSnanites.get_cloud_backup(cloud_id)
- if(backup)
- var/datum/component/nanites/cloud_copy = backup.nanites
- if(cloud_copy)
- sync(null, cloud_copy)
+ if(cloud_id)
+ var/datum/nanite_cloud_backup/backup = SSnanites.get_cloud_backup(cloud_id)
+ if(backup)
+ var/datum/component/nanites/cloud_copy = backup.nanites
+ if(cloud_copy)
+ sync(null, cloud_copy)
+ return
+ //Without cloud syncing nanites can accumulate errors and/or defects
+ if(prob(8) && programs.len)
+ var/datum/nanite_program/NP = pick(programs)
+ NP.software_error()
/datum/component/nanites/proc/add_program(datum/source, datum/nanite_program/new_program, datum/nanite_program/source_program)
for(var/X in programs)
@@ -175,19 +191,28 @@
holder.icon_state = "nanites[nanite_percent]"
/datum/component/nanites/proc/on_emp(datum/source, severity)
- adjust_nanites(null, -(nanite_volume * 0.3 + 50)) //Lose 30% variable and 50 flat nanite volume.
+ nanite_volume *= (rand(60, 90) * 0.01) //Lose 10-40% of nanites
+ adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
+ if(prob(40/severity))
+ cloud_id = 0
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_emp(severity)
-/datum/component/nanites/proc/on_shock(datum/source, shock_damage)
- adjust_nanites(null, -(nanite_volume * (shock_damage * 0.005) + shock_damage)) //0.5% of shock damage (@ 50 damage it'd drain 25%) + shock damage flat volume
- for(var/X in programs)
- var/datum/nanite_program/NP = X
- NP.on_shock(shock_damage)
+
+/datum/component/nanites/proc/on_shock(datum/source, shock_damage, siemens_coeff = 1, flags = NONE)
+ if(shock_damage < 1)
+ return
+
+ if(!HAS_TRAIT_NOT_FROM(host_mob, TRAIT_SHOCKIMMUNE, "nanites"))//Another shock protection must protect nanites too, but nanites protect only host
+ nanite_volume *= (rand(45, 80) * 0.01) //Lose 20-55% of nanites
+ adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
+ for(var/X in programs)
+ var/datum/nanite_program/NP = X
+ NP.on_shock(shock_damage)
/datum/component/nanites/proc/on_minor_shock(datum/source)
- adjust_nanites(null, -25)
+ adjust_nanites(null, -(rand(5, 15))) //Lose 5-15 flat nanite volume
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_minor_shock()
@@ -207,16 +232,16 @@
/datum/component/nanites/proc/receive_comm_signal(datum/source, comm_code, comm_message, comm_source = "an unidentified source")
for(var/X in programs)
- if(istype(X, /datum/nanite_program/triggered/comm))
- var/datum/nanite_program/triggered/comm/NP = X
+ if(istype(X, /datum/nanite_program/comm))
+ var/datum/nanite_program/comm/NP = X
NP.receive_comm_signal(comm_code, comm_message, comm_source)
/datum/component/nanites/proc/check_viable_biotype()
- if(!(MOB_ORGANIC in host_mob.mob_biotypes) && !(MOB_UNDEAD in host_mob.mob_biotypes))
+ if(!(host_mob.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)))
qdel(src) //bodytype no longer sustains nanites
/datum/component/nanites/proc/check_access(datum/source, obj/O)
- for(var/datum/nanite_program/triggered/access/access_program in programs)
+ for(var/datum/nanite_program/access/access_program in programs)
if(access_program.activated)
return O.check_access_list(access_program.access)
else
@@ -232,6 +257,15 @@
/datum/component/nanites/proc/set_cloud(datum/source, amount)
cloud_id = CLAMP(amount, 0, 100)
+/datum/component/nanites/proc/set_cloud_sync(datum/source, method)
+ switch(method)
+ if(NANITE_CLOUD_TOGGLE)
+ cloud_active = !cloud_active
+ if(NANITE_CLOUD_DISABLE)
+ cloud_active = FALSE
+ if(NANITE_CLOUD_ENABLE)
+ cloud_active = TRUE
+
/datum/component/nanites/proc/set_safety(datum/source, amount)
safety_threshold = CLAMP(amount, 0, max_nanites)
@@ -252,6 +286,19 @@
/datum/component/nanites/proc/get_programs(datum/source, list/nanite_programs)
nanite_programs |= programs
+/datum/component/nanites/proc/add_research()
+ var/research_value = NANITE_BASE_RESEARCH
+ if(!ishuman(host_mob))
+ if(!iscarbon(host_mob))
+ research_value *= 0.4
+ else
+ research_value *= 0.8
+ if(!host_mob.client)
+ research_value *= 0.5
+ if(host_mob.stat == DEAD)
+ research_value *= 0.75
+ SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_NANITES = research_value))
+
/datum/component/nanites/proc/nanite_scan(datum/source, mob/user, full_scan)
if(!full_scan)
if(!stealth)
@@ -263,7 +310,8 @@
to_chat(user, "================")
to_chat(user, "Saturation: [nanite_volume]/[max_nanites]")
to_chat(user, "Safety Threshold: [safety_threshold]")
- to_chat(user, "Cloud ID: [cloud_id ? cloud_id : "Disabled"]")
+ to_chat(user, "Cloud ID: [cloud_id ? cloud_id : "None"]")
+ to_chat(user, "Cloud Sync: [cloud_active ? "Active" : "Disabled"]")
to_chat(user, "================")
to_chat(user, "Program List:")
if(!diagnostics)
@@ -280,6 +328,7 @@
data["regen_rate"] = regen_rate
data["safety_threshold"] = safety_threshold
data["cloud_id"] = cloud_id
+ data["cloud_active"] = cloud_active
var/list/mob_programs = list()
var/id = 1
for(var/X in programs)
@@ -297,24 +346,35 @@
mob_program["trigger_cooldown"] = P.trigger_cooldown / 10
if(scan_level >= 3)
- mob_program["activation_delay"] = P.activation_delay
- mob_program["timer"] = P.timer
- mob_program["timer_type"] = P.get_timer_type_text()
- var/list/extra_settings = list()
- for(var/Y in P.extra_settings)
- var/list/setting = list()
- setting["name"] = Y
- setting["value"] = P.get_extra_setting(Y)
- extra_settings += list(setting)
+ mob_program["timer_restart"] = P.timer_restart / 10
+ mob_program["timer_shutdown"] = P.timer_shutdown / 10
+ mob_program["timer_trigger"] = P.timer_trigger / 10
+ mob_program["timer_trigger_delay"] = P.timer_trigger_delay / 10
+ var/list/extra_settings = P.get_extra_settings_frontend()
mob_program["extra_settings"] = extra_settings
if(LAZYLEN(extra_settings))
mob_program["has_extra_settings"] = TRUE
+ else
+ mob_program["has_extra_settings"] = FALSE
if(scan_level >= 4)
mob_program["activation_code"] = P.activation_code
mob_program["deactivation_code"] = P.deactivation_code
mob_program["kill_code"] = P.kill_code
mob_program["trigger_code"] = P.trigger_code
+ var/list/rules = list()
+ var/rule_id = 1
+ for(var/Z in P.rules)
+ var/datum/nanite_rule/nanite_rule = Z
+ var/list/rule = list()
+ rule["display"] = nanite_rule.display()
+ rule["program_id"] = id
+ rule["id"] = rule_id
+ rules += list(rule)
+ rule_id++
+ mob_program["rules"] = rules
+ if(LAZYLEN(rules))
+ mob_program["has_rules"] = TRUE
id++
mob_programs += list(mob_program)
data["mob_programs"] = mob_programs
diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm
index 55e5c03c2b..61f97006dd 100644
--- a/code/datums/components/storage/storage.dm
+++ b/code/datums/components/storage/storage.dm
@@ -41,6 +41,7 @@
var/obj/screen/storage/boxes //storage display object
var/obj/screen/close/closer //close button object
+ var/current_maxscreensize
var/allow_big_nesting = FALSE //allow storage objects of the same or greater size.
@@ -362,11 +363,15 @@
break
closer.screen_loc = "[screen_start_x + cols]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
-/datum/component/storage/proc/show_to(mob/M)
+/datum/component/storage/proc/show_to(mob/M, set_screen_size = TRUE)
if(!M.client)
return FALSE
var/list/cview = getviewsize(M.client.view)
var/maxallowedscreensize = cview[1]-8
+ if(set_screen_size)
+ current_maxscreensize = maxallowedscreensize
+ else if(current_maxscreensize)
+ maxallowedscreensize = current_maxscreensize
if(M.active_storage != src && (M.stat == CONSCIOUS))
for(var/obj/item/I in accessible_items())
if(I.on_found(M))
@@ -547,14 +552,14 @@
return
A.add_fingerprint(M)
-/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE)
+/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, ghost = FALSE)
var/atom/A = parent
if(!istype(M))
return FALSE
A.add_fingerprint(M)
if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE)))
return FALSE
- show_to(M)
+ show_to(M, !ghost)
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
if(isitem(O))
@@ -665,7 +670,7 @@
return can_be_inserted(I, silent, M)
/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M)
- return user_show_to_mob(M, TRUE)
+ return user_show_to_mob(M, TRUE, TRUE)
/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE)
return user_show_to_mob(showto, force)
diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm
index 5057253522..a8e03946b6 100644
--- a/code/datums/components/uplink.dm
+++ b/code/datums/components/uplink.dm
@@ -25,6 +25,8 @@ GLOBAL_LIST_EMPTY(uplinks)
var/unlock_code
var/failsafe_code
var/datum/ui_state/checkstate
+ var/compact_mode = FALSE
+ var/debug = FALSE
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/ui_state/_checkstate)
if(!isitem(parent))
@@ -121,7 +123,7 @@ GLOBAL_LIST_EMPTY(uplinks)
active = TRUE
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
- ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state)
+ ui = new(user, src, ui_key, "uplink", name, 620, 580, master_ui, state)
ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input.
ui.set_style("syndicate")
ui.open()
@@ -138,29 +140,35 @@ GLOBAL_LIST_EMPTY(uplinks)
var/list/data = list()
data["telecrystals"] = telecrystals
data["lockable"] = lockable
+ data["compact_mode"] = compact_mode
+ return data
+
+/datum/component/uplink/ui_static_data(mob/user)
+ var/list/data = list()
data["categories"] = list()
for(var/category in uplink_items)
var/list/cat = list(
"name" = category,
"items" = (category == selected_cat ? list() : null))
- if(category == selected_cat)
- for(var/item in uplink_items[category])
- var/datum/uplink_item/I = uplink_items[category][item]
- if(I.limited_stock == 0)
+ for(var/item in uplink_items[category])
+ var/datum/uplink_item/I = uplink_items[category][item]
+ if(I.limited_stock == 0)
+ continue
+ if(I.restricted_roles.len)
+ var/is_inaccessible = TRUE
+ for(var/R in I.restricted_roles)
+ if(R == user.mind.assigned_role || debug)
+ is_inaccessible = FALSE
+ if(is_inaccessible)
continue
- if(I.restricted_roles.len)
- var/is_inaccessible = 1
- for(var/R in I.restricted_roles)
- if(R == user.mind.assigned_role)
- is_inaccessible = 0
if(is_inaccessible)
continue
- cat["items"] += list(list(
- "name" = I.name,
- "cost" = I.cost,
- "desc" = I.desc,
- ))
+ cat["items"] += list(list(
+ "name" = I.name,
+ "cost" = I.cost,
+ "desc" = I.desc,
+ ))
data["categories"] += list(cat)
return data
@@ -188,6 +196,8 @@ GLOBAL_LIST_EMPTY(uplinks)
SStgui.close_uis(src)
if("select")
selected_cat = params["category"]
+ if("compact_toggle")
+ compact_mode = !compact_mode
return TRUE
/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U)
@@ -294,4 +304,4 @@ GLOBAL_LIST_EMPTY(uplinks)
if(!T)
return
explosion(T,1,2,3)
- qdel(parent) //Alternatively could brick the uplink.
\ No newline at end of file
+ qdel(parent) //Alternatively could brick the uplink.
diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm
index c125a9b7c7..0b6d4e3404 100644
--- a/code/datums/diseases/_MobProcs.dm
+++ b/code/datums/diseases/_MobProcs.dm
@@ -17,14 +17,10 @@
if(HasDisease(D))
return FALSE
- var/can_infect = FALSE
- for(var/host_type in D.infectable_biotypes)
- if(host_type in mob_biotypes)
- can_infect = TRUE
- break
- if(!can_infect)
+ if(!(D.infectable_biotypes & mob_biotypes))
return FALSE
+
if(!(type in D.viable_mobtypes))
return FALSE
diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm
index 056f99c7a4..940b61c9fe 100644
--- a/code/datums/diseases/_disease.dm
+++ b/code/datums/diseases/_disease.dm
@@ -30,7 +30,7 @@
var/list/required_organs = list()
var/needs_all_cures = TRUE
var/list/strain_data = list() //dna_spread special bullshit
- var/list/infectable_biotypes = list(MOB_ORGANIC) //if the disease can spread on organics, synthetics, or undead
+ var/infectable_biotypes = MOB_ORGANIC //if the disease can spread on organics, synthetics, or undead
var/process_dead = FALSE //if this ticks while the host is dead
var/copy_type = null //if this is null, copies will use the type of the instance being copied
diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm
index cf14da36a0..c7b9758bcb 100644
--- a/code/datums/diseases/advance/symptoms/heal.dm
+++ b/code/datums/diseases/advance/symptoms/heal.dm
@@ -448,9 +448,11 @@
symptom_delay_max = 1
passive_message = "Your skin glows faintly for a moment."
var/cellular_damage = FALSE
- threshold_desc = "Transmission 6: Additionally heals cellular damage and toxin lovers.
\
- Resistance 7: Increases healing speed."
-
+ threshold_desc = list(
+ "Transmission 6" = "Additionally heals cellular damage and toxin lovers.",
+ "Resistance 7" = "Increases healing speed.",
+ )
+
/datum/symptom/heal/radiation/Start(datum/disease/advance/A)
if(!..())
return
diff --git a/code/datums/diseases/advance/symptoms/species.dm b/code/datums/diseases/advance/symptoms/species.dm
index a8b18ae735..49a3cf8d07 100644
--- a/code/datums/diseases/advance/symptoms/species.dm
+++ b/code/datums/diseases/advance/symptoms/species.dm
@@ -14,7 +14,7 @@
/datum/symptom/undead_adaptation/OnRemove(datum/disease/advance/A)
A.process_dead = FALSE
- A.infectable_biotypes -= MOB_UNDEAD
+ A.infectable_biotypes &= ~MOB_UNDEAD
/datum/symptom/inorganic_adaptation
name = "Inorganic Biology"
@@ -27,7 +27,8 @@
severity = 0
/datum/symptom/inorganic_adaptation/OnAdd(datum/disease/advance/A)
- A.infectable_biotypes |= MOB_INORGANIC
+ A.infectable_biotypes |= MOB_MINERAL //Mineral covers plasmamen and golems.
/datum/symptom/inorganic_adaptation/OnRemove(datum/disease/advance/A)
- A.infectable_biotypes -= MOB_INORGANIC
\ No newline at end of file
+ A.infectable_biotypes &= ~MOB_MINERAL
+
diff --git a/code/datums/diseases/beesease.dm b/code/datums/diseases/beesease.dm
index 074bda0560..ccae692b4b 100644
--- a/code/datums/diseases/beesease.dm
+++ b/code/datums/diseases/beesease.dm
@@ -10,7 +10,7 @@
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
desc = "If left untreated subject will regurgitate bees."
severity = DISEASE_SEVERITY_MEDIUM
- infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD) //bees nesting in corpses
+ infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD //bees nesting in corpses
/datum/disease/beesease/stage_act()
..()
diff --git a/code/datums/diseases/magnitis.dm b/code/datums/diseases/magnitis.dm
index 29e6657e13..0bfb918ba0 100644
--- a/code/datums/diseases/magnitis.dm
+++ b/code/datums/diseases/magnitis.dm
@@ -10,7 +10,7 @@
permeability_mod = 0.75
desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field."
severity = DISEASE_SEVERITY_MEDIUM
- infectable_biotypes = list(MOB_ORGANIC, MOB_ROBOTIC)
+ infectable_biotypes = MOB_ORGANIC|MOB_ROBOTIC
process_dead = TRUE
/datum/disease/magnitis/stage_act()
diff --git a/code/datums/diseases/parrotpossession.dm b/code/datums/diseases/parrotpossession.dm
index 68e962055a..1a3346d565 100644
--- a/code/datums/diseases/parrotpossession.dm
+++ b/code/datums/diseases/parrotpossession.dm
@@ -11,7 +11,7 @@
viable_mobtypes = list(/mob/living/carbon/human)
desc = "Subject is possessed by the vengeful spirit of a parrot. Call the priest."
severity = DISEASE_SEVERITY_MEDIUM
- infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD, MOB_INORGANIC, MOB_ROBOTIC)
+ infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC|MOB_MINERAL
bypasses_immunity = TRUE //2spook
var/mob/living/simple_animal/parrot/Poly/ghost/parrot
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index bdb05346e4..36c7d70f3c 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -168,7 +168,7 @@
stage4 = list("Your skin feels very loose.", "You can feel... something...inside you.")
stage5 = list("Your skin feels as if it's about to burst off!")
new_form = /mob/living/silicon/robot
- infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD, MOB_ROBOTIC)
+ infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC
bantype = "Cyborg"
/datum/disease/transformation/robot/stage_act()
@@ -284,7 +284,7 @@
stage4 = list("You're ravenous.")
stage5 = list("You have become a morph.")
new_form = /mob/living/simple_animal/hostile/morph
- infectable_biotypes = list(MOB_ORGANIC, MOB_INORGANIC, MOB_UNDEAD) //magic!
+ infectable_biotypes = MOB_ORGANIC|MOB_MINERAL|MOB_UNDEAD //magic!
/datum/disease/transformation/gondola
name = "Gondola Transformation"
diff --git a/code/datums/elements/cleaning.dm b/code/datums/elements/cleaning.dm
index e4fb3edd48..3f80204089 100644
--- a/code/datums/elements/cleaning.dm
+++ b/code/datums/elements/cleaning.dm
@@ -45,4 +45,4 @@
cleaned_human.clean_blood()
cleaned_human.wash_cream()
cleaned_human.regenerate_icons()
- to_chat(cleaned_human, "[src] cleans your face!")
+ to_chat(cleaned_human, "[AM] cleans your face!")
diff --git a/code/datums/elements/mob_holder.dm b/code/datums/elements/mob_holder.dm
index 5b471a0dc7..8687d89b2f 100644
--- a/code/datums/elements/mob_holder.dm
+++ b/code/datums/elements/mob_holder.dm
@@ -1,5 +1,5 @@
/datum/element/mob_holder
- element_flags = ELEMENT_BESPOKE
+ element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
id_arg_index = 2
var/worn_state
var/alt_worn
@@ -40,19 +40,19 @@
to_chat(user, "Your hands are full!")
return FALSE
if(source.buckled)
- to_chat(user, "[src] is buckled to something!")
+ to_chat(user, "[source] is buckled to something!")
return FALSE
if(source == user)
to_chat(user, "You can't pick yourself up.")
return FALSE
source.visible_message("[user] starts picking up [source].", \
"[user] starts picking you up!")
- if(!do_after(user, 20, target = src) || source.buckled)
+ if(!do_after(user, 20, target = source) || source.buckled)
return FALSE
source.visible_message("[user] picks up [source]!", \
"[user] picks you up!")
- to_chat(user, "You pick [src] up.")
+ to_chat(user, "You pick [source] up.")
source.drop_all_held_items()
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(source), source, worn_state, alt_worn, right_hand, left_hand, inv_slots)
if(proctype)
@@ -93,7 +93,7 @@
lefthand_file = left_hand
if(right_hand)
righthand_file = right_hand
- slot_flags = slots
+ slot_flags = slots
/obj/item/clothing/head/mob_holder/proc/assimilate(mob/living/target)
target.setDir(SOUTH)
@@ -101,6 +101,8 @@
target.forceMove(src)
var/image/I = new //work around to retain the same appearance to the mob idependently from inhands/worn states.
I.appearance = target.appearance
+ I.layer = FLOAT_LAYER //So it doesn't get screwed up by layer overrides.
+ I.plane = FLOAT_PLANE //Same as above but for planes.
I.override = TRUE
add_overlay(I)
name = target.name
@@ -112,23 +114,21 @@
w_class = WEIGHT_CLASS_NORMAL
if(MOB_SIZE_LARGE)
w_class = WEIGHT_CLASS_HUGE
- RegisterSignal(src, COMSIG_CLICK_SHIFT, .proc/examine_held_mob)
/obj/item/clothing/head/mob_holder/Destroy()
if(held_mob)
release()
return ..()
-/obj/item/clothing/head/mob_holder/proc/examine_held_mob(datum/source, mob/user)
- held_mob.ShiftClick(user)
- return COMPONENT_DENY_EXAMINATE
+/obj/item/clothing/head/mob_holder/examine(mob/user)
+ return held_mob?.examine(user) || ..()
/obj/item/clothing/head/mob_holder/Exited(atom/movable/AM, atom/newloc)
. = ..()
if(AM == held_mob)
held_mob.reset_perspective()
held_mob = null
- qdel(src)
+ QDEL_IN(src, 1) //To avoid a qdel loop.
/obj/item/clothing/head/mob_holder/Entered(atom/movable/AM, atom/newloc)
. = ..()
@@ -158,7 +158,7 @@
/obj/item/clothing/head/mob_holder/container_resist()
if(isliving(loc))
var/mob/living/L = loc
- L.visible_message("[src] escapes from [L]!", "[src] escapes your grip!")
+ L.visible_message("[held_mob] escapes from [L]!", "[held_mob] escapes your grip!")
release()
/obj/item/clothing/head/mob_holder/assume_air(datum/gas_mixture/env)
@@ -170,7 +170,7 @@
location = location.loc
if(ismob(location))
return location.loc.assume_air(env)
- return loc.assume_air(env)
+ return location.assume_air(env)
/obj/item/clothing/head/mob_holder/remove_air(amount)
var/atom/location = loc
@@ -181,4 +181,4 @@
location = location.loc
if(ismob(location))
return location.loc.remove_air(amount)
- return loc.remove_air(amount)
+ return location.remove_air(amount)
diff --git a/code/datums/elements/wuv.dm b/code/datums/elements/wuv.dm
index 55bc9bafad..fffb90c681 100644
--- a/code/datums/elements/wuv.dm
+++ b/code/datums/elements/wuv.dm
@@ -1,6 +1,6 @@
/datum/element/wuv //D'awwwww
- element_flags = ELEMENT_BESPOKE
+ element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
id_arg_index = 2
//the for the me emote proc call when petted.
var/pet_emote
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index 7d040a4982..0b0fed407c 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -27,7 +27,8 @@
for(var/line in testmerge)
var/datum/tgs_revision_information/test_merge/tm = line
- msg += "Test merge active of PR #[tm.number] commit [tm.commit]"
+ msg += "Test merge active of PR #[tm.number] commit [tm.pull_request_commit]"
+ SSblackbox.record_feedback("associative", "testmerged_prs", 1, list("number" = "[tm.number]", "commit" = "[tm.pull_request_commit]", "title" = "[tm.title]", "author" = "[tm.author]"))
if(commit && commit != originmastercommit)
msg += "HEAD: [commit]"
@@ -75,7 +76,8 @@
else if(!pc)
msg += "No commit information"
if(world.TgsAvailable())
- msg += "Server tools version: [world.TgsVersion()]"
+ var/datum/tgs_version/version = world.TgsVersion()
+ msg += "Server tools version: [version.raw_parameter]"
// Game mode odds
msg += "
Current Informational Settings:"
diff --git a/code/datums/helper_datums/topic_input.dm b/code/datums/helper_datums/topic_input.dm
deleted file mode 100644
index d07aec067e..0000000000
--- a/code/datums/helper_datums/topic_input.dm
+++ /dev/null
@@ -1,62 +0,0 @@
-/datum/topic_input
- var/href
- var/list/href_list
-
-/datum/topic_input/New(thref,list/thref_list)
- href = thref
- href_list = thref_list.Copy()
- return
-
-/datum/topic_input/proc/get(i)
- return listgetindex(href_list,i)
-
-/datum/topic_input/proc/getAndLocate(i)
- var/t = get(i)
- if(t)
- t = locate(t)
- if (istext(t))
- t = null
- return t || null
-
-/datum/topic_input/proc/getNum(i)
- var/t = get(i)
- if(t)
- t = text2num(t)
- return isnum(t) ? t : null
-
-/datum/topic_input/proc/getObj(i)
- var/t = getAndLocate(i)
- return isobj(t) ? t : null
-
-/datum/topic_input/proc/getMob(i)
- var/t = getAndLocate(i)
- return ismob(t) ? t : null
-
-/datum/topic_input/proc/getTurf(i)
- var/t = getAndLocate(i)
- return isturf(t) ? t : null
-
-/datum/topic_input/proc/getAtom(i)
- return getType(i, /atom)
-
-/datum/topic_input/proc/getArea(i)
- var/t = getAndLocate(i)
- return isarea(t) ? t : null
-
-/datum/topic_input/proc/getStr(i)//params should always be text, but...
- var/t = get(i)
- return istext(t) ? t : null
-
-/datum/topic_input/proc/getType(i,type)
- var/t = getAndLocate(i)
- return istype(t,type) ? t : null
-
-/datum/topic_input/proc/getPath(i)
- var/t = get(i)
- if(t)
- t = text2path(t)
- return ispath(t) ? t : null
-
-/datum/topic_input/proc/getList(i)
- var/t = getAndLocate(i)
- return islist(t) ? t : null
diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm
index 72fe6f5a1c..e0b0072808 100644
--- a/code/datums/holocall.dm
+++ b/code/datums/holocall.dm
@@ -12,7 +12,12 @@
/mob/camera/aiEye/remote/holo/setLoc()
. = ..()
var/obj/machinery/holopad/H = origin
- H.move_hologram(eye_user, loc)
+ H?.move_hologram(eye_user, loc)
+
+/obj/machinery/holopad/remove_eye_control(mob/living/user)
+ if(user.client)
+ user.reset_perspective(null)
+ user.remote_control = null
//this datum manages it's own references
@@ -54,11 +59,6 @@
/datum/holocall/Destroy()
QDEL_NULL(hangup)
- var/user_good = !QDELETED(user)
- if(user_good)
- user.reset_perspective()
- user.remote_control = null
-
if(!QDELETED(eye))
QDEL_NULL(eye)
diff --git a/code/datums/hud.dm b/code/datums/hud.dm
index e2d9bc579f..6b6fcb9691 100644
--- a/code/datums/hud.dm
+++ b/code/datums/hud.dm
@@ -32,7 +32,7 @@ GLOBAL_LIST_INIT(huds, list(
/datum/atom_hud
var/list/atom/hudatoms = list() //list of all atoms which display this hud
- var/list/mob/hudusers = list() //list with all mobs who can see the hud
+ var/list/hudusers = list() //list with all mobs who can see the hud
var/list/hud_icons = list() //these will be the indexes for the atom's hud_list
var/list/next_time_allowed = list() //mobs associated with the next time this hud can be added to them
diff --git a/code/datums/ruins/station.dm b/code/datums/ruins/station.dm
index 17d5a9e1e2..71cdf495e9 100644
--- a/code/datums/ruins/station.dm
+++ b/code/datums/ruins/station.dm
@@ -37,22 +37,22 @@
/datum/map_template/ruin/station/box/engine/teg
id = "engine_teg"
- suffix = "Box/Engine/engine_tesla.dmm"
+ suffix = "Box/Engine/engine_teg.dmm"
name = "Box TEG"
/datum/map_template/ruin/station/box/engine/empty
id = "engine_empty"
- suffix = "Box/Engine/engine_tesla.dmm"
+ suffix = "Box/Engine/empty.dmm"
name = "Box Empty"
/datum/map_template/ruin/station/box/engine/am
id = "engine_am"
- suffix = "Box/Engine/engine_tesla.dmm"
+ suffix = "Box/Engine/engine_am.dmm"
name = "Box Antimatter"
/datum/map_template/ruin/station/box/engine/budget
id = "engine_budget"
- suffix = "Box/Engine/engine_tesla.dmm"
+ suffix = "Box/Engine/budget.dmm"
name = "Box P.A.C.M.A.N"
// Lavaland
@@ -60,4 +60,4 @@
/datum/map_template/ruin/station/lavaland/mining_base
id = "mining_public_01"
suffix = "Lavaland/Mining_Station/Mining_Station_Public_01.dmm"
- name = "Public Mining Base"
\ No newline at end of file
+ name = "Public Mining Base"
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 2e46046a7e..c694f27d64 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -33,7 +33,6 @@
if(owner.getStaminaLoss())
owner.adjustStaminaLoss(-0.3) //reduce stamina loss by 0.3 per tick, 6 per 2 seconds
-
//UNCONSCIOUS
/datum/status_effect/incapacitating/unconscious
id = "unconscious"
@@ -80,11 +79,11 @@
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
icon_state = "asleep"
-/datum/status_effect/no_combat_mode/
+/datum/status_effect/no_combat_mode
id = "no_combat_mode"
- blocks_combatmode = TRUE
alert_type = null
status_type = STATUS_EFFECT_REPLACE
+ blocks_combatmode = TRUE
/datum/status_effect/no_combat_mode/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
@@ -113,31 +112,54 @@
icon = 'icons/mob/actions/bloodsucker.dmi'
icon_state = "power_mez"
-/datum/status_effect/no_combat_mode/electrode
+/datum/status_effect/electrode
id = "tased"
+ var/slowdown = 1.5
+ var/slowdown_priority = 50 //to make sure the stronger effect overrides
+ var/affect_crawl = FALSE
+ var/nextmove_modifier = 1
+ var/stamdmg_per_ds = 1 //a 20 duration would do 20 stamdmg, disablers do 24 or something
+ var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it.
-/datum/status_effect/no_combat_mode/electrode/on_creation(mob/living/new_owner, set_duration)
+/datum/status_effect/electrode/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration)) //TODO, figure out how to grab from subtype
duration = set_duration
. = ..()
+ last_tick = world.time
+ if(iscarbon(owner))
+ var/mob/living/carbon/C = owner
+ if(C.combatmode)
+ C.toggle_combat_mode(TRUE)
+ C.add_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]", TRUE, priority = slowdown_priority, override = TRUE, multiplicative_slowdown = slowdown, blacklisted_movetypes = affect_crawl? NONE : CRAWLING)
+
+/datum/status_effect/electrode/on_remove()
+ if(iscarbon(owner))
+ var/mob/living/carbon/C = owner
+ C.remove_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]")
+ . = ..()
+
+/datum/status_effect/electrode/tick()
+ var/diff = world.time - last_tick
+ if(owner)
+ owner.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
+ last_tick = world.time
+
+/datum/status_effect/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
+ return nextmove_modifier
+
+/datum/status_effect/electrode/no_combat_mode
+ id = "tased_strong"
+ slowdown = 8
+ slowdown_priority = 100
+ nextmove_modifier = 2
+ blocks_combatmode = TRUE
+
+/datum/status_effect/electrode/no_combat_mode/on_creation(mob/living/new_owner, set_duration)
+ . = ..()
if(iscarbon(owner))
var/mob/living/carbon/C = owner
if(C.combatmode)
C.toggle_combat_mode(TRUE)
- C.add_movespeed_modifier(MOVESPEED_ID_TASED_STATUS, TRUE, override = TRUE, multiplicative_slowdown = 8)
-
-/datum/status_effect/no_combat_mode/electrode/on_remove()
- if(iscarbon(owner))
- var/mob/living/carbon/C = owner
- C.remove_movespeed_modifier(MOVESPEED_ID_TASED_STATUS)
- . = ..()
-
-/datum/status_effect/no_combat_mode/electrode/tick()
- if(owner)
- owner.adjustStaminaLoss(5) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
-
-/datum/status_effect/no_combat_mode/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
- return 2
//OTHER DEBUFFS
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm
index faa7eec392..b2177a860a 100644
--- a/code/datums/traits/negative.dm
+++ b/code/datums/traits/negative.dm
@@ -144,9 +144,8 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
/datum/quirk/nearsighted/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H))
- H.put_in_hands(glasses)
- H.equip_to_slot(glasses, SLOT_GLASSES)
- H.regenerate_icons() //this is to remove the inhand icon, which persists even if it's not in their hands
+ if(!H.equip_to_slot_if_possible(glasses, SLOT_GLASSES))
+ H.put_in_hands(glasses)
/datum/quirk/nyctophobia
name = "Nyctophobia"
diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm
index 01b9facbb8..6761ecbb4c 100644
--- a/code/datums/weather/weather.dm
+++ b/code/datums/weather/weather.dm
@@ -61,7 +61,7 @@
if(A.z in impacted_z_levels)
impacted_areas |= A
weather_duration = rand(weather_duration_lower, weather_duration_upper)
- START_PROCESSING(SSweather, src)
+ START_PROCESSING(SSweather, src) //The reason this doesn't start and stop at main stage is because processing list is also used to see active running weathers (for example, you wouldn't want two ash storms starting at once.)
update_areas()
for(var/M in GLOB.player_list)
var/turf/mob_turf = get_turf(M)
@@ -107,6 +107,14 @@
STOP_PROCESSING(SSweather, src)
update_areas()
+/datum/weather/process()
+ if(aesthetic || (stage != MAIN_STAGE))
+ return
+ for(var/i in GLOB.mob_living_list)
+ var/mob/living/L = i
+ if(can_weather_act(L))
+ weather_act(L)
+
/datum/weather/proc/can_weather_act(mob/living/L) //Can this weather impact a mob?
var/turf/mob_turf = get_turf(L)
if(mob_turf && !(mob_turf.z in impacted_z_levels))
diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm
index 315cfa59d6..b6699540c3 100644
--- a/code/datums/wires/airlock.dm
+++ b/code/datums/wires/airlock.dm
@@ -52,7 +52,7 @@
/datum/wires/airlock/interactable(mob/user)
var/obj/machinery/door/airlock/A = holder
- if(!issilicon(user) && A.isElectrified() && A.shock(user, 100))
+ if(!A.hasSiliconAccessInArea(user) && A.isElectrified() && A.shock(user, 100))
return FALSE
if(A.panel_open)
return TRUE
diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm
index 0c66f26a92..114791e873 100644
--- a/code/datums/wires/vending.dm
+++ b/code/datums/wires/vending.dm
@@ -12,7 +12,7 @@
/datum/wires/vending/interactable(mob/user)
var/obj/machinery/vending/V = holder
- if(!issilicon(user) && V.seconds_electrified && V.shock(user, 100))
+ if(!V.hasSiliconAccessInArea(user) && V.seconds_electrified && V.shock(user, 100))
return FALSE
if(V.panel_open)
return TRUE
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 7e224080b9..83117bad64 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -6,7 +6,6 @@
var/flags_1 = NONE
var/interaction_flags_atom = NONE
- var/ghost_flags = NONE
var/datum/reagents/reagents = null
//This atom's HUD (med/sec, etc) images. Associative list.
diff --git a/code/game/gamemodes/bloodsucker/bloodsucker.dm b/code/game/gamemodes/bloodsucker/bloodsucker.dm
index ca2ebfe00d..a45e989318 100644
--- a/code/game/gamemodes/bloodsucker/bloodsucker.dm
+++ b/code/game/gamemodes/bloodsucker/bloodsucker.dm
@@ -7,7 +7,7 @@
// LISTS //
var/list/vassal_allowed_antags = list(/datum/antagonist/brother, /datum/antagonist/traitor, /datum/antagonist/traitor/internal_affairs, /datum/antagonist/survivalist, \
- /datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee)
+ /datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee, /datum/antagonist/valentine, /datum/antagonist/heartbreaker,)
// The antags you're allowed to be if turning Vassal.
/proc/isvamp(mob/living/M)
return istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/bloodsucker)
diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm
index b054ff89af..674afad88e 100644
--- a/code/game/gamemodes/clown_ops/clown_weapons.dm
+++ b/code/game/gamemodes/clown_ops/clown_weapons.dm
@@ -279,7 +279,6 @@
internals_req_access = list(ACCESS_SYNDICATE)
wreckage = /obj/structure/mecha_wreckage/honker/dark
max_equip = 3
- spawn_tracked = FALSE
/obj/mecha/combat/honker/dark/GrantActions(mob/living/user, human_occupant = 0)
..()
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index 6fe52b0f8d..6ea357163f 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -41,7 +41,7 @@ GLOBAL_LIST_EMPTY(dynamic_forced_roundstart_ruleset)
// Forced threat level, setting this to zero or higher forces the roundstart threat to the value.
GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
-GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
+GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
/datum/game_mode/dynamic
name = "dynamic mode"
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index abd560171e..7ad4cee884 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -61,7 +61,7 @@
trimmed_list.Remove(M)
continue
if (M.mind)
- if (restrict_ghost_roles && M.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL]) // Are they playing a ghost role?
+ if (restrict_ghost_roles && (M.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL])) // Are they playing a ghost role?
trimmed_list.Remove(M)
continue
if (M.mind.assigned_role in restricted_roles) // Does their job allow it?
diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm
index 303c436f99..069c73a421 100644
--- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm
+++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm
@@ -57,7 +57,8 @@ Property weights are:
mean += 2.5
if(CHAOS_MAX)
mean += 5
- GLOB.dynamic_curve_centre += (mean/voters)
+ if(voters)
+ GLOB.dynamic_curve_centre += (mean/voters)
GLOB.dynamic_forced_threat_level = forced_threat_level
/datum/dynamic_storyteller/proc/get_midround_cooldown()
diff --git a/code/game/gamemodes/gangs/gangs.dm b/code/game/gamemodes/gangs/gangs.dm
index 9151107d6f..0dc4a520ef 100644
--- a/code/game/gamemodes/gangs/gangs.dm
+++ b/code/game/gamemodes/gangs/gangs.dm
@@ -6,7 +6,8 @@ GLOBAL_LIST_EMPTY(gangs)
name = "gang war"
config_tag = "gang"
antag_flag = ROLE_GANG
- restricted_jobs = list("Security Officer", "Warden", "Detective", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security")
+ restricted_jobs = list("AI", "Cyborg")
+ protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_players = 15
required_enemies = 0
recommended_enemies = 2
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 459ff2f3d6..20a45b2102 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -1096,7 +1096,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages)
var/approved_targets = list()
check_sabotages:
for(var/datum/sabotage_objective/possible_sabotage in GLOB.possible_sabotages)
- if(!is_unique_objective(possible_sabotage.sabotage_type) || possible_sabotage.check_conditions())
+ if(!is_unique_objective(possible_sabotage.sabotage_type) || possible_sabotage.check_conditions() || !possible_sabotage.can_run())
continue
for(var/datum/mind/M in owners)
if(M.current.mind.assigned_role in possible_sabotage.excludefromjob)
diff --git a/code/game/gamemodes/objective_sabotage.dm b/code/game/gamemodes/objective_sabotage.dm
index 248524f1d2..1094dd2f36 100644
--- a/code/game/gamemodes/objective_sabotage.dm
+++ b/code/game/gamemodes/objective_sabotage.dm
@@ -12,6 +12,9 @@
/datum/sabotage_objective/proc/check_conditions()
return TRUE
+/datum/sabotage_objective/proc/can_run()
+ return TRUE
+
/datum/sabotage_objective/processing
var/won = FALSE
@@ -79,6 +82,9 @@
won = max(1-((S.get_integrity()-50)/50),won)
return FALSE
+/datum/sabotage_objective/processing/supermatter/can_run()
+ return (locate(/obj/machinery/power/supermatter_crystal) in GLOB.machines)
+
/datum/sabotage_objective/station_integrity
name = "Make sure the station is at less than 80% integrity by the end. Smash walls, windows etc. to reach this goal."
sabotage_type = "integrity"
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index b6dc09eb59..19a20f0cfa 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -182,7 +182,7 @@
/obj/machinery/sleeper/AltClick(mob/user)
. = ..()
- if(!user.canUseTopic(src, !issilicon(user)))
+ if(!user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return
if(state_open)
close_machine()
@@ -264,7 +264,7 @@
if(blood_id)
data["occupant"]["blood"] = list() // We can start populating this list.
var/blood_type = C.dna.blood_type
- if(blood_id != "blood") // special blood substance
+ if(!(blood_id in GLOB.blood_reagent_types)) // special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 44739fcbc0..7132f046e6 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -229,7 +229,7 @@ Class Procs:
return !(stat & (NOPOWER|BROKEN|MAINT))
/obj/machinery/can_interact(mob/user)
- var/silicon = issiliconoradminghost(user)
+ var/silicon = hasSiliconAccessInArea(user) || IsAdminGhost(user)
if((stat & (NOPOWER|BROKEN)) && !(interaction_flags_machine & INTERACT_MACHINE_OFFLINE))
return FALSE
if(panel_open && !(interaction_flags_machine & INTERACT_MACHINE_OPEN))
@@ -242,7 +242,7 @@ Class Procs:
else
if(interaction_flags_machine & INTERACT_MACHINE_REQUIRES_SILICON)
return FALSE
- if(!Adjacent(user) && !isobserver(user))
+ if(!Adjacent(user))
var/mob/living/carbon/H = user
if(!(istype(H) && H.has_dna() && H.dna.check_mutation(TK)))
return FALSE
diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm
index 56227cdd53..5a597f7280 100644
--- a/code/game/machinery/announcement_system.dm
+++ b/code/game/machinery/announcement_system.dm
@@ -105,7 +105,7 @@ GLOBAL_LIST_EMPTY(announcement_systems)
/obj/machinery/announcement_system/ui_interact(mob/user)
. = ..()
- if(!user.canUseTopic(src, !issilicon(user)))
+ if(!user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return
if(stat & BROKEN)
visible_message("[src] buzzes.", "You hear a faint buzz.")
@@ -123,7 +123,7 @@ GLOBAL_LIST_EMPTY(announcement_systems)
/obj/machinery/announcement_system/Topic(href, href_list)
if(..())
return
- if(!usr.canUseTopic(src, !issilicon(usr)))
+ if(!usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
return
if(stat & BROKEN)
visible_message("[src] buzzes.", "You hear a faint buzz.")
@@ -132,13 +132,13 @@ GLOBAL_LIST_EMPTY(announcement_systems)
if(href_list["ArrivalTopic"])
var/NewMessage = stripped_input(usr, "Enter in the arrivals announcement configuration.", "Arrivals Announcement Config", arrival)
- if(!usr.canUseTopic(src, !issilicon(usr)))
+ if(!usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
return
if(NewMessage)
arrival = NewMessage
else if(href_list["NewheadTopic"])
var/NewMessage = stripped_input(usr, "Enter in the departmental head announcement configuration.", "Head Departmental Announcement Config", newhead)
- if(!usr.canUseTopic(src, !issilicon(usr)))
+ if(!usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
return
if(NewMessage)
newhead = NewMessage
@@ -157,7 +157,7 @@ GLOBAL_LIST_EMPTY(announcement_systems)
. = attack_ai(user)
/obj/machinery/announcement_system/attack_ai(mob/user)
- if(!user.canUseTopic(src, !issilicon(user)))
+ if(!user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return
if(stat & BROKEN)
to_chat(user, "[src]'s firmware appears to be malfunctioning!")
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 495e90d305..c9d26905f5 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -17,6 +17,7 @@
var/list/L = list()
var/list/LL = list()
var/hacked = FALSE
+ var/hackable = TRUE
var/disabled = 0
var/shocked = FALSE
var/hack_wire
@@ -371,6 +372,8 @@
/obj/machinery/autolathe/proc/adjust_hacked(state)
hacked = state
+ if(!hackable && hacked)
+ return
for(var/id in SSresearch.techweb_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(id)
if((D.build_type & AUTOLATHE) && ("hacked" in D.category))
@@ -383,6 +386,12 @@
. = ..()
adjust_hacked(TRUE)
+/obj/machinery/autolathe/secure
+ name = "secured autolathe"
+ desc = "An autolathe reprogrammed with security protocols to prevent hacking."
+ hackable = FALSE
+ circuit = /obj/item/circuitboard/machine/autolathe/secure
+
//Called when the object is constructed by an autolathe
//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes
/obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A)
diff --git a/code/game/machinery/bloodbankgen.dm b/code/game/machinery/bloodbankgen.dm
index cb25adc126..19632711fc 100644
--- a/code/game/machinery/bloodbankgen.dm
+++ b/code/game/machinery/bloodbankgen.dm
@@ -274,20 +274,20 @@
return TRUE
-/obj/machinery/bloodbankgen/proc/detachinput()
+/obj/machinery/bloodbankgen/proc/detachinput(mob/user)
if(bag)
bag.forceMove(drop_location())
- if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
- usr.put_in_hands(bag)
+ if(user && Adjacent(usr) && user.can_hold_items())
+ user.put_in_hands(bag)
bag = null
draining = null
update_icon()
-/obj/machinery/bloodbankgen/proc/detachoutput()
+/obj/machinery/bloodbankgen/proc/detachoutput(mob/user)
if(outbag)
outbag.forceMove(drop_location())
- if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
- usr.put_in_hands(outbag)
+ if(user && Adjacent(user) && user.can_hold_items())
+ user.put_in_hands(outbag)
outbag = null
filling = null
update_icon()
@@ -325,12 +325,12 @@
activateinput()
else if(href_list["detachinput"])
- detachinput()
+ detachinput(usr)
else if(href_list["activateoutput"])
activateoutput()
else if(href_list["detachoutput"])
- detachoutput()
+ detachoutput(usr)
updateUsrDialog()
diff --git a/code/game/machinery/computer/arcade/minesweeper.dm b/code/game/machinery/computer/arcade/minesweeper.dm
index 641ef1c9cd..3e32c4ceeb 100644
--- a/code/game/machinery/computer/arcade/minesweeper.dm
+++ b/code/game/machinery/computer/arcade/minesweeper.dm
@@ -304,12 +304,12 @@
/obj/machinery/computer/arcade/minesweeper/proc/custom_generation(mob/user)
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) //Entered into the menu so ping sound
var/new_rows = input(user, "How many rows do you want? (Minimum: 4, Maximum: 30)", "Minesweeper Rows") as null|num
- if(!new_rows || !user.canUseTopic(src, !issilicon(user)))
+ if(!new_rows || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return FALSE
new_rows = CLAMP(new_rows + 1, 4, 30)
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
var/new_columns = input(user, "How many columns do you want? (Minimum: 4, Maximum: 50)", "Minesweeper Squares") as null|num
- if(!new_columns || !user.canUseTopic(src, !issilicon(user)))
+ if(!new_columns || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return FALSE
new_columns = CLAMP(new_columns + 1, 4, 50)
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
@@ -317,7 +317,7 @@
var/lower_limit = round(grid_area*0.156)
var/upper_limit = round(grid_area*0.85)
var/new_mine_limit = input(user, "How many mines do you want? (Minimum: [lower_limit], Maximum: [upper_limit])", "Minesweeper Mines") as null|num
- if(!new_mine_limit || !user.canUseTopic(src, !issilicon(user)))
+ if(!new_mine_limit || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return FALSE
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
rows = new_rows
diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm
index 1d54e8f772..211ff13486 100644
--- a/code/game/machinery/computer/camera.dm
+++ b/code/game/machinery/computer/camera.dm
@@ -36,7 +36,7 @@
return ..()
/obj/machinery/computer/security/can_interact(mob/user)
- if((!issilicon(user) && !Adjacent(user)) || is_blind(user) || !in_view_range(user, src))
+ if((!hasSiliconAccessInArea(user) && !Adjacent(user)) || is_blind(user) || !in_view_range(user, src))
return FALSE
return ..()
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 8de470fdb8..5fe62ebb76 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -47,7 +47,10 @@
jump_action.Grant(user)
actions += jump_action
-/obj/machinery/computer/camera_advanced/proc/remove_eye_control(mob/living/user)
+/obj/machinery/proc/remove_eye_control(mob/living/user)
+ CRASH("[type] does not implement ai eye handling")
+
+/obj/machinery/computer/camera_advanced/remove_eye_control(mob/living/user)
if(!user)
return
for(var/V in actions)
@@ -69,7 +72,7 @@
playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
/obj/machinery/computer/camera_advanced/check_eye(mob/user)
- if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && !user.has_unlimited_silicon_privilege) || user.eye_blind || user.incapacitated() )
+ if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && hasSiliconAccessInArea(user)) || user.eye_blind || user.incapacitated() )
user.unset_machine()
/obj/machinery/computer/camera_advanced/Destroy()
@@ -157,7 +160,7 @@
var/cooldown = 0
var/acceleration = 1
var/mob/living/eye_user = null
- var/obj/machinery/computer/camera_advanced/origin
+ var/obj/machinery/origin
var/eye_initialized = 0
var/visible_icon = 0
var/image/user_image = null
@@ -170,7 +173,7 @@
/mob/camera/aiEye/remote/Destroy()
if(origin && eye_user)
- origin.remove_eye_control(eye_user)
+ origin.remove_eye_control(eye_user,src)
origin = null
. = ..()
eye_user = null
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index 6703bae525..b0e80b63d2 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -171,7 +171,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
/obj/machinery/computer/card/AltClick(mob/user)
. = ..()
- if(!user.canUseTopic(src, !issilicon(user)) || !is_operational())
+ if(!user.canUseTopic(src, !hasSiliconAccessInArea(user)) || !is_operational())
return
if(inserted_modify_id)
if(id_eject(user, inserted_modify_id))
@@ -360,7 +360,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
if(..())
return
- if(!usr.canUseTopic(src, !issilicon(usr)) || !is_operational())
+ if(!usr.canUseTopic(src, !hasSiliconAccessInArea(usr)) || !is_operational())
usr.unset_machine()
usr << browse(null, "window=id_com")
return
@@ -392,7 +392,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
inserted_scan_id = id_to_insert
updateUsrDialog()
if ("auth")
- if ((!( authenticated ) && (inserted_scan_id || issilicon(usr)) || mode))
+ if ((!( authenticated ) && (inserted_scan_id || hasSiliconAccessInArea(usr)) || mode))
if (check_access(inserted_scan_id))
region_access = list()
head_subordinates = list()
@@ -426,7 +426,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
get_subordinates("Quartermaster")
if(region_access)
authenticated = 1
- else if ((!( authenticated ) && issilicon(usr)) && (!inserted_modify_id))
+ else if ((!( authenticated ) && hasSiliconAccessInArea(usr)) && (!inserted_modify_id))
to_chat(usr, "You can't modify an ID without an ID inserted to modify! Once one is in the modify slot on the computer, you can log in.")
if ("logout")
region_access = null
@@ -481,7 +481,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
if ("reg")
if (authenticated)
var/t2 = inserted_modify_id
- if ((authenticated && inserted_modify_id == t2 && (in_range(src, usr) || issilicon(usr)) && isturf(loc)))
+ if ((authenticated && inserted_modify_id == t2 && (in_range(src, usr) || hasSiliconAccessInArea(usr)) && isturf(loc)))
var/newName = reject_bad_name(href_list["reg"])
if(newName)
inserted_modify_id.registered_name = newName
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 59574bc603..9d0053c9b2 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -449,7 +449,7 @@
var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
- if(issilicon(user))
+ if(issilicon(user) || (hasSiliconAccessInArea(user) && !in_range(user,src)))
var/dat2 = interact_ai(user) // give the AI a different interact proc to limit its access
if(dat2)
dat += dat2
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index a31f6c71c8..5049a10d2b 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -64,7 +64,7 @@
if(!user)
return
var/datum/browser/popup = new(user, "scannernew", "DNA Modifier Console", 800, 630) // Set up the popup browser window
- if(!(in_range(src, user) || issilicon(user)))
+ if(!(in_range(src, user) || hasSiliconAccessInArea(user)))
popup.close()
return
popup.add_stylesheet("scannernew", 'html/browser/scannernew.css')
@@ -318,7 +318,7 @@
return
if(!isturf(usr.loc))
return
- if(!((isturf(loc) && in_range(src, usr)) || issilicon(usr)))
+ if(!((isturf(loc) && in_range(src, usr)) || hasSiliconAccessInArea(usr)))
return
if(current_screen == "working")
return
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index ecbde43044..f8dac1b100 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -190,7 +190,7 @@
if(!(active2 in GLOB.data_core.medical))
active2 = null
- if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr) || IsAdminGhost(usr))
+ if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || hasSiliconAccessInArea(usr) || IsAdminGhost(usr))
usr.set_machine(src)
if(href_list["temp"])
temp = null
@@ -216,7 +216,7 @@
else if(href_list["login"])
var/mob/M = usr
var/obj/item/card/id/I = M.get_idcard(TRUE)
- if(issilicon(M))
+ if(hasSiliconAccessInArea(M))
active1 = null
active2 = null
authenticated = 1
@@ -569,7 +569,7 @@
if(user)
if(message)
if(authenticated)
- if(user.canUseTopic(src, !issilicon(user)))
+ if(user.canUseTopic(src, !hasSiliconAccessInArea(user)))
if(!record1 || record1 == active1)
if(!record2 || record2 == active2)
return 1
diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm
index 1388e3c8de..53f7cb7e32 100644
--- a/code/game/machinery/computer/pod.dm
+++ b/code/game/machinery/computer/pod.dm
@@ -86,7 +86,7 @@
/obj/machinery/computer/pod/Topic(href, href_list)
if(..())
return
- if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr))
+ if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || hasSiliconAccessInArea(usr))
usr.set_machine(src)
if(href_list["power"])
var/t = text2num(href_list["power"])
diff --git a/code/game/machinery/computer/prisoner/management.dm b/code/game/machinery/computer/prisoner/management.dm
index 496e14b8f1..4b4b39740a 100644
--- a/code/game/machinery/computer/prisoner/management.dm
+++ b/code/game/machinery/computer/prisoner/management.dm
@@ -87,7 +87,7 @@
/obj/machinery/computer/prisoner/management/Topic(href, href_list)
if(..())
return
- if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr))
+ if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || hasSiliconAccessInArea(usr))
usr.set_machine(src)
if(href_list["id"])
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 42e31b2ea6..25f4237439 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -265,7 +265,7 @@ What a mess.*/
active1 = null
if(!( GLOB.data_core.security.Find(active2) ))
active2 = null
- if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr) || IsAdminGhost(usr))
+ if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || hasSiliconAccessInArea(usr) || IsAdminGhost(usr))
usr.set_machine(src)
switch(href_list["choice"])
// SORTING!
@@ -299,7 +299,7 @@ What a mess.*/
if("Log In")
var/mob/M = usr
var/obj/item/card/id/I = M.get_idcard(TRUE)
- if(issilicon(M))
+ if(hasSiliconAccessInArea(M))
var/mob/living/silicon/borg = M
active1 = null
active2 = null
@@ -802,7 +802,7 @@ What a mess.*/
/obj/machinery/computer/secure_data/proc/canUseSecurityRecordsConsole(mob/user, message1 = 0, record1, record2)
if(user)
if(authenticated)
- if(user.canUseTopic(src, !issilicon(user)))
+ if(user.canUseTopic(src, !hasSiliconAccessInArea(user)))
if(!trim(message1))
return 0
if(!record1 || record1 == active1)
diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm
index 518f38fc35..6710258626 100644
--- a/code/game/machinery/computer/teleporter.dm
+++ b/code/game/machinery/computer/teleporter.dm
@@ -140,7 +140,7 @@ obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", datum/t
L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = M
var/desc = input("Please select a location to lock in.", "Locking Computer") as null|anything in L
- if(!user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) //check if we are still around
+ if(!user.canUseTopic(src, !hasSiliconAccessInArea(user), NO_DEXTERY)) //check if we are still around
return
target = L[desc]
if(imp_t)
@@ -168,7 +168,7 @@ obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", datum/t
to_chat(user, "No active connected stations located.")
return
var/desc = input("Please select a station to lock in.", "Locking Computer") as null|anything in L
- if(!user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) //again, check if we are still around
+ if(!user.canUseTopic(src, !hasSiliconAccessInArea(user), NO_DEXTERY)) //again, check if we are still around
return
var/obj/machinery/teleport/station/target_station = L[desc]
if(!target_station || !target_station.teleporter_hub)
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index e9d3006b06..92927d047d 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -6,7 +6,6 @@
* ~ Zuhayr
*/
-
//Main cryopod console.
/obj/machinery/computer/cryopod
@@ -18,7 +17,6 @@
density = FALSE
interaction_flags_machine = INTERACT_MACHINE_OFFLINE
req_one_access = list(ACCESS_HEADS, ACCESS_ARMORY) //Heads of staff or the warden can go here to claim recover items from their department that people went were cryodormed with.
- var/mode = null
var/menu = 1 //Which menu screen to display
@@ -118,7 +116,7 @@
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
I.forceMove(drop_location())
- if(user && Adjacent(user) && !issiliconoradminghost(user))
+ if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(I)
frozen_items -= I
updateUsrDialog()
@@ -130,7 +128,8 @@
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
updateUsrDialog()
return
- if(!allow_items) return
+ if(!allow_items)
+ return
if(frozen_items.len == 0)
to_chat(user, "There is nothing to recover from storage.")
@@ -182,7 +181,7 @@
var/last_no_computer_message = 0
// These items are preserved when the process() despawn proc occurs.
- var/list/preserve_items = list(
+ var/static/list/preserve_items = typecacheof(list(
/obj/item/hand_tele,
/obj/item/card/id/captains_spare,
/obj/item/aicard,
@@ -203,9 +202,9 @@
/obj/item/tank/jetpack,
/obj/item/documents,
/obj/item/nuke_core_container
- )
+ ))
// These items will NOT be preserved
- var/list/do_not_preserve_items = list (
+ var/static/list/do_not_preserve_items = typecacheof(list(
/obj/item/mmi/posibrain,
/obj/item/gun/energy/laser/mounted,
/obj/item/gun/energy/e_gun/advtaser/mounted,
@@ -215,7 +214,7 @@
/obj/item/gun/energy/printer,
/obj/item/gun/energy/kinetic_accelerator/cyborg,
/obj/item/gun/energy/laser/cyborg
- )
+ ))
/obj/machinery/cryopod/Initialize(mapload)
. = ..()
@@ -287,14 +286,14 @@
#define CRYO_DESTROY 0
#define CRYO_PRESERVE 1
#define CRYO_OBJECTIVE 2
+#define CRYO_IGNORE 3
/obj/machinery/cryopod/proc/should_preserve_item(obj/item/I)
for(var/datum/objective_item/steal/T in control_computer.theft_cache)
if(istype(I, T.targetitem) && T.check_special_completion(I))
return CRYO_OBJECTIVE
- for(var/T in preserve_items)
- if(istype(I, T) && !(I.type in do_not_preserve_items))
- return CRYO_PRESERVE
+ if(preserve_items[I] && !do_not_preserve_items[I])
+ return CRYO_PRESERVE
return CRYO_DESTROY
// This function can not be undone; do not call this unless you are sure
@@ -303,52 +302,47 @@
find_control_computer()
var/mob/living/mob_occupant = occupant
+ var/list/obj/item/cryo_items = list()
//Handle Borg stuff first
if(iscyborg(mob_occupant))
var/mob/living/silicon/robot/R = mob_occupant
-
- R.contents -= R.mmi
- qdel(R.mmi)
+ if(R.mmi?.brain)
+ cryo_items[R.mmi] = CRYO_IGNORE
+ cryo_items[R.mmi.brain] = CRYO_IGNORE
for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc
for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags
- if(should_preserve_item(O) != CRYO_DESTROY) // Preserve important things inside the item
- continue
+ cryo_items[O] = should_preserve_item(O)
O.forceMove(src)
R.module.remove_module(I, TRUE) //delete the module itself so it doesn't transfer over.
//Drop all items into the pod.
for(var/obj/item/I in mob_occupant)
- mob_occupant.doUnEquip(I)
- I.forceMove(src)
-
+ if(cryo_items[I] == CRYO_IGNORE)
+ continue
+ cryo_items[I] = should_preserve_item(I)
+ mob_occupant.transferItemToLoc(I, src, TRUE)
if(I.contents.len) //Make sure we catch anything not handled by qdel() on the items.
- if(should_preserve_item(I) != CRYO_DESTROY) // Don't remove the contents of things that need preservation
+ if(cryo_items[I] != CRYO_DESTROY) // Don't remove the contents of things that need preservation
continue
for(var/obj/item/O in I.contents)
- if(istype(O, /obj/item/tank)) //Stop eating pockets, you fuck!
- continue
+ cryo_items[O] = should_preserve_item(O)
O.forceMove(src)
- //Delete all items not on the preservation list.
- var/list/items = contents
- items -= mob_occupant // Don't delete the occupant
-
- for(var/obj/item/I in items)
- if(istype(I, /obj/item/pda))
- var/obj/item/pda/P = I
- QDEL_NULL(P.id)
- qdel(P)
+ for(var/A in cryo_items)
+ var/obj/item/I = A
+ if(QDELETED(I)) //edge cases and DROPDEL.
continue
-
- var/preserve = should_preserve_item(I)
- if(preserve == CRYO_DESTROY)
+ var/preserve = cryo_items[I]
+ if(preserve == CRYO_IGNORE)
+ continue
+ else if(preserve == CRYO_DESTROY)
qdel(I)
- else if(control_computer && control_computer.allow_items)
+ else if(control_computer?.allow_items)
control_computer.frozen_items += I
if(preserve == CRYO_OBJECTIVE)
control_computer.objective_items += I
- I.loc = null
+ I.moveToNullspace()
else
I.forceMove(loc)
@@ -417,6 +411,7 @@
#undef CRYO_DESTROY
#undef CRYO_PRESERVE
#undef CRYO_OBJECTIVE
+#undef CRYO_IGNORE
/obj/machinery/cryopod/MouseDrop_T(mob/living/target, mob/user)
if(!istype(target) || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || !ismob(target) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled)
@@ -443,29 +438,24 @@
var/generic_plsnoleave_message = " Please adminhelp before leaving the round, even if there are no administrators online!"
if(target == user && world.time - target.client.cryo_warned > 5 MINUTES)//if we haven't warned them in the last 5 minutes
- var/caught = FALSE
+ var/list/caught_string
+ var/addendum = ""
if(target.mind.assigned_role in GLOB.command_positions)
- alert("You're a Head of Staff![generic_plsnoleave_message] Be sure to put your locker items back into your locker!")
- caught = TRUE
+ LAZYADD(caught_string, "Head of Staff")
+ addendum = " Be sure to put your locker items back into your locker!"
if(iscultist(target) || is_servant_of_ratvar(target))
- to_chat(target, "You're a Cultist![generic_plsnoleave_message]")
- caught = TRUE
+ LAZYADD(caught_string, "Cultist")
if(is_devil(target))
- alert("You're a Devil![generic_plsnoleave_message]")
- caught = TRUE
- if(istype(SSticker.mode, /datum/antagonist/gang))
- if(target.mind.has_antag_datum(/datum/antagonist/gang))
- alert("You're a Gangster![generic_plsnoleave_message]")
- caught = TRUE
- if(istype(SSticker.mode, /datum/antagonist/rev))
- if(target.mind.has_antag_datum(/datum/antagonist/rev/head))
- alert("You're a Head Revolutionary![generic_plsnoleave_message]")
- caught = TRUE
- else if(target.mind.has_antag_datum(/datum/antagonist/rev))
- alert("You're a Revolutionary![generic_plsnoleave_message]")
- caught = TRUE
+ LAZYADD(caught_string, "Devil")
+ if(target.mind.has_antag_datum(/datum/antagonist/gang))
+ LAZYADD(caught_string, "Gangster")
+ if(target.mind.has_antag_datum(/datum/antagonist/rev/head))
+ LAZYADD(caught_string, "Head Revolutionary")
+ if(target.mind.has_antag_datum(/datum/antagonist/rev))
+ LAZYADD(caught_string, "Revolutionary")
- if(caught)
+ if(caught_string)
+ alert(target, "You're a [english_list(caught_string)]![generic_plsnoleave_message][addendum]")
target.client.cryo_warned = world.time
return
diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm
index c6b4f2fcf5..6b62d18d01 100644
--- a/code/game/machinery/dance_machine.dm
+++ b/code/game/machinery/dance_machine.dm
@@ -53,7 +53,7 @@
/obj/machinery/jukebox/ui_interact(mob/user)
. = ..()
- if(!user.canUseTopic(src, !issilicon(user)))
+ if(!user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return
if (!anchored)
to_chat(user,"This device must be anchored by a wrench!")
@@ -202,6 +202,8 @@
for(var/i in 1 to 10)
spawn_atom_to_turf(/obj/effect/temp_visual/hierophant/telegraph/edge, src, 1, FALSE)
sleep(5)
+ if(QDELETED(src))
+ return
#define DISCO_INFENO_RANGE (rand(85, 115)*0.01)
@@ -430,6 +432,6 @@
/obj/machinery/jukebox/disco/process()
. = ..()
if(active)
- for(var/mob/M in rangers)
+ for(var/mob/living/M in rangers)
if(prob(5+(allowed(M)*4)) && M.canmove)
dance(M)
diff --git a/code/game/machinery/dish_drive.dm b/code/game/machinery/dish_drive.dm
index 7f21d1c1b3..31e6a3cfeb 100644
--- a/code/game/machinery/dish_drive.dm
+++ b/code/game/machinery/dish_drive.dm
@@ -98,7 +98,7 @@
/obj/machinery/dish_drive/AltClick(mob/living/user)
. = ..()
- if(user.canUseTopic(src, !issilicon(user)))
+ if(user.canUseTopic(src, !hasSiliconAccessInArea(user)))
do_the_dishes(TRUE)
return TRUE
diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm
index cff2e361bd..60b5a52a10 100644
--- a/code/game/machinery/dna_scanner.dm
+++ b/code/game/machinery/dna_scanner.dm
@@ -172,7 +172,7 @@
/obj/machinery/dna_scannernew/AltClick(mob/user)
. = ..()
- if(!user.canUseTopic(src, !issilicon(user)))
+ if(!user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return
interact(user)
return TRUE
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index f28d520114..863f1e7b46 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -676,7 +676,7 @@
else
. += "It looks very robust."
- if(issilicon(user) && (!stat & BROKEN))
+ if(hasSiliconAccessInArea(user) && (!stat & BROKEN))
. += "Shift-click [src] to [ density ? "open" : "close"] it."
. += "Ctrl-click [src] to [ locked ? "raise" : "drop"] its bolts."
. += "Alt-click [src] to [ secondsElectrified ? "un-electrify" : "permanently electrify"] it."
@@ -1322,9 +1322,9 @@
if(density && !open(2)) //The airlock is still closed, but something prevented it opening. (Another player noticed and bolted/welded the airlock in time!)
to_chat(user, "Despite your efforts, [src] managed to resist your attempts to open it!")
-/obj/machinery/door/airlock/hostile_lockdown(mob/origin)
+/obj/machinery/door/airlock/hostile_lockdown(mob/origin, aicontrolneeded = TRUE)
// Must be powered and have working AI wire.
- if(canAIControl(src) && !stat)
+ if((aicontrolneeded && canAIControl(src) && !stat) || !aicontrolneeded)
locked = FALSE //For airlocks that were bolted open.
safe = FALSE //DOOR CRUSH
close()
@@ -1334,9 +1334,9 @@
LAZYADD(shockedby, "\[[TIME_STAMP("hh:mm:ss", FALSE)]\] [key_name(origin)]")
-/obj/machinery/door/airlock/disable_lockdown()
+/obj/machinery/door/airlock/disable_lockdown(aicontrolneeded = TRUE)
// Must be powered and have working AI wire.
- if(canAIControl(src) && !stat)
+ if((aicontrolneeded && canAIControl(src) && !stat) || !aicontrolneeded)
unbolt()
set_electrified(NOT_ELECTRIFIED)
open()
@@ -1528,7 +1528,7 @@
. = TRUE
/obj/machinery/door/airlock/proc/user_allowed(mob/user)
- return (issilicon(user) && canAIControl(user)) || IsAdminGhost(user)
+ return (hasSiliconAccessInArea(user) && canAIControl(user)) || IsAdminGhost(user)
/obj/machinery/door/airlock/proc/shock_restore(mob/user)
if(!user_allowed(user))
diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm
index 3bfcececda..adc1748ded 100644
--- a/code/game/machinery/doors/brigdoors.dm
+++ b/code/game/machinery/doors/brigdoors.dm
@@ -2,13 +2,11 @@
#define FONT_SIZE "5pt"
#define FONT_COLOR "#09f"
#define FONT_STYLE "Arial Black"
-#define MAX_TIMER 9000
-
-#define PRESET_SHORT 1200
-#define PRESET_MEDIUM 1800
-#define PRESET_LONG 3000
-
+#define MAX_TIMER 15 MINUTES
+#define PRESET_SHORT 2 MINUTES
+#define PRESET_MEDIUM 3 MINUTES
+#define PRESET_LONG 5 MINUTES
///////////////////////////////////////////////////////////////////////////////////////////////
// Brig Door control displays.
@@ -25,7 +23,7 @@
desc = "A remote control for a door."
req_access = list(ACCESS_SECURITY)
density = FALSE
- var/id = null // id of linked machinery/lockers
+ var/id // id of linked machinery/lockers
var/activation_time = 0
var/timer_duration = 0
@@ -43,8 +41,6 @@
Radio = new/obj/item/radio(src)
Radio.listening = 0
-/obj/machinery/door_timer/Initialize()
- . = ..()
if(id != null)
for(var/obj/machinery/door/window/brigdoor/M in urange(20, src))
if (M.id == id)
@@ -71,7 +67,7 @@
return
if(timing)
- if(world.realtime - activation_time >= timer_duration)
+ if(REALTIMEOFDAY - activation_time >= timer_duration)
timer_end() // open doors, reset timer, clear status screen
update_icon()
@@ -80,14 +76,13 @@
..()
update_icon()
-
// open/closedoor checks if door_timer has power, if so it checks if the
// linked door is open/closed (by density) then opens it/closes it.
/obj/machinery/door_timer/proc/timer_start()
if(stat & (NOPOWER|BROKEN))
return 0
- activation_time = world.realtime
+ activation_time = REALTIMEOFDAY
timing = TRUE
for(var/obj/machinery/door/window/brigdoor/door in targets)
@@ -104,7 +99,6 @@
C.update_icon()
return 1
-
/obj/machinery/door_timer/proc/timer_end(forced = FALSE)
if(stat & (NOPOWER|BROKEN))
@@ -136,7 +130,7 @@
/obj/machinery/door_timer/proc/time_left(seconds = FALSE)
- . = max(0,timer_duration - (activation_time ? world.realtime - activation_time : 0))
+ . = max(0,timer_duration - (activation_time ? REALTIMEOFDAY - activation_time : 0))
if(seconds)
. /= 10
@@ -240,7 +234,7 @@
preset_time = PRESET_LONG
. = set_timer(preset_time)
if(timing)
- activation_time = world.realtime
+ activation_time = REALTIMEOFDAY
else
. = FALSE
diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm
index 40430b37b7..8275e981de 100644
--- a/code/game/machinery/harvester.dm
+++ b/code/game/machinery/harvester.dm
@@ -71,7 +71,7 @@
say("Subject may not have abiotic items on.")
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1)
return
- if(!(MOB_ORGANIC in C.mob_biotypes))
+ if(!(C.mob_biotypes & MOB_ORGANIC))
say("Subject is not organic.")
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1)
return
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index 6d19776d86..b3f0ce9693 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -184,7 +184,7 @@
if(usr.incapacitated())
return
if(beaker)
- if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
+ if(usr && Adjacent(usr) && usr.can_hold_items())
if(!usr.put_in_hands(beaker))
beaker.forceMove(drop_location())
beaker = null
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index a27cb9b78c..60085e0bf8 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -348,6 +348,26 @@
spark_system.start() //creates some sparks because they look cool
qdel(cover) //deletes the cover - no need on keeping it there!
+//turret healing
+/obj/machinery/porta_turret/examine(mob/user)
+ . = ..()
+ if(obj_integrity < max_integrity)
+ . += "Use a welder to fix it."
+
+/obj/machinery/porta_turret/welder_act(mob/living/user, obj/item/I)
+ . = TRUE
+ if(obj_integrity < max_integrity)
+ if(!I.tool_start_check(user, amount=0))
+ return
+ user.visible_message("[user] is welding the turret.", \
+ "You begin repairing the turret...", \
+ "You hear welding.")
+ if(I.use_tool(src, user, 40, volume=50))
+ obj_integrity = max_integrity
+ user.visible_message("[user.name] has repaired [src].", \
+ "You finish repairing the turret.")
+ else
+ to_chat(user, "The turret doesn't need repairing.")
/obj/machinery/porta_turret/process()
@@ -672,6 +692,7 @@
lethal_projectile_sound = 'sound/weapons/laser.ogg'
desc = "An energy blaster auto-turret."
+
/obj/machinery/porta_turret/syndicate/energy/heavy
icon_state = "standard_stun"
base_icon_state = "standard"
@@ -683,6 +704,11 @@
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
desc = "An energy blaster auto-turret."
+/obj/machinery/porta_turret/syndicate/energy/pirate
+ max_integrity = 260
+ integrity_failure = 20
+ armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90)
+
/obj/machinery/porta_turret/syndicate/setup()
return
@@ -839,7 +865,7 @@
/obj/machinery/turretid/examine(mob/user)
. = ..()
- if(issilicon(user) && (!stat & BROKEN))
+ if(hasSiliconAccessInArea(user) && (!stat & BROKEN))
. += "Ctrl-click [src] to [ enabled ? "disable" : "enable"] turrets."
. += "Alt-click [src] to set turrets to [ lethal ? "stun" : "kill"]."
@@ -854,7 +880,7 @@
to_chat(user, "You link \the [M.buffer] with \the [src]")
return
- if (issilicon(user))
+ if (hasSiliconAccessInArea(user))
return attack_hand(user)
if ( get_dist(src, user) == 0 ) // trying to unlock the interface
@@ -895,7 +921,7 @@
/obj/machinery/turretid/ui_interact(mob/user)
. = ..()
if ( get_dist(src, user) > 0 )
- if ( !(issilicon(user) || IsAdminGhost(user)) )
+ if ( !(hasSiliconAccessInArea(user) || IsAdminGhost(user)) )
to_chat(user, "You are too far away.")
user.unset_machine()
user << browse(null, "window=turretid")
@@ -903,10 +929,10 @@
var/t = ""
- if(locked && !(issilicon(user) || IsAdminGhost(user)))
+ if(locked && !(hasSiliconAccessInArea(user) || IsAdminGhost(user)))
t += "




"
- else
- dat+="None"
- else
- dat+="Apart from some uninteresting classified ads, there's nothing on this page..."
- if(scribble_page==curr_page)
- dat+="
"
+ else
+ dat+="None"
+ else
+ dat+="Apart from some uninteresting classified ads, there's nothing on this page..."
+ if(scribble_page==curr_page)
+ dat+="