diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 2df370e6ea..7a38745e0e 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -6,10 +6,10 @@
/code/__DEFINES/clockcult.dm @ChangelingRain
/code/datums/antagonists/datum_clockcult.dm @ChangelingRain
-/code/game/gamemodes/blob/* @ChangelingRain
-/code/game/gamemodes/clock_cult/* @ChangelingRain
-/code/game/gamemodes/miniantags/revenant* @ChangelingRain
-/code/game/objects/effects/temporary_visuals/* @ChangelingRain
+/code/game/gamemodes/blob/ @ChangelingRain
+/code/game/gamemodes/clock_cult/ @ChangelingRain
+/code/game/gamemodes/miniantags/revenant/ @ChangelingRain
+/code/game/objects/effects/temporary_visuals/ @ChangelingRain
/code/modules/reagents/chemistry/reagents/blob_reagents.dm @ChangelingRain
# Cyberboss
@@ -22,26 +22,26 @@
/code/controllers/subsystem/mapping.dm @Cyberboss
/code/controllers/globals.dm @Cyberboss
/code/datums/helper_datums/getrev.dm @Cyberboss
-/code/datums/components/* @Cyberboss
+/code/datums/components/ @Cyberboss
/code/datums/map_config.dm @Cyberboss
/code/datums/forced_movement.dm @Cyberboss
/code/datums/holocall.dm @Cyberboss
/code/modules/admin/verbs/adminhelp.dm @Cyberboss
/code/modules/admin/verbs/adminpm.dm @Cyberboss
-/code/modules/server_tools/* @Cyberboss
-/code/modules/mapping/* @Cyberboss
+/code/modules/server_tools/ @Cyberboss
+/code/modules/mapping/ @Cyberboss
# duncathan
/code/__DEFINES/atmospherics.dm @duncathan
/code/controllers/subsystem/air.dm @duncathan
-/code/modules/atmospherics/* @duncathan
+/code/modules/atmospherics/ @duncathan
# Jordie0608
-/SQL/* @Jordie0608
+/SQL/ @Jordie0608
/code/controllers/subsystem/dbcore.dm @Jordie0608
-/tools/SQLAlertEmail/* @Jordie0608
+/tools/SQLAlertEmail/ @Jordie0608
# MrStonedOne
@@ -57,10 +57,10 @@
# ninjanomnom
/code/controllers/subsystem/shuttle.dm @ninjanomnom
-/code/modules/shuttle/* @ninjanomnom
+/code/modules/shuttle/ @ninjanomnom
# ShizCalev
-/_maps/* @ShizCalev
-/icons/* @ShizCalev
-/sound/* @ShizCalev
+/_maps/ @ShizCalev
+/icons/ @ShizCalev
+/sound/ @ShizCalev
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 10f60767bb..949f1c4c44 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,9 +1,9 @@
-[Directions]: # (If you discovered this issue from playing tgstation hosted servers
+[Round ID]: # (If you discovered this issue from playing tgstation hosted servers:)
+[Round ID]: # (**INCLUDE THE ROUND ID**)
+[Round ID]: # (It can be found in the Status panel or retrieved from https://atlantaned.space/statbus/round.php ! The round id let's us look up valuable information and logs for the round the bug happened.)
+[Testmerges]: # (If you believe the issue to be caused by a test merge [OOC tab -> Show Server Revision], report it in the pull request's comment section instead.)
-INCLUDE THE ROUND ID
+[Reproduction]: # (Explain your issue in detail, including the steps to reproduce it. Issues without proper reproduction steps or explanation are open to being ignored/closed by maintainers.)
-
-from the Status panel or retrieve it from https://atlantaned.space/statbus/round.php ! If you believe the issue to be caused by a test merge [OOC tab -> Show Server Revision], report it in the pull request's comment section instead. Explain your issue in detail, including the steps to reproduce it.)
-
-[For Admins]: # (Oddities induced by var-edits and other admin tools are not necessarily bugs. Verify that your issues occur under regular circumstances before reporting them.)
+[For Admins]: # (Oddities induced by var-edits and other admin tools are not necessarily bugs. Verify that your issues occur under regular circumstances before reporting them.)
\ No newline at end of file
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 335393adac..12b9c297fc 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -8973,14 +8973,14 @@
/area/maintenance/port/fore)
"avT" = (
/obj/docking_port/stationary{
- dheight = 9;
- dir = 2;
- dwidth = 5;
- height = 24;
+ dheight = 1;
+ dir = 8;
+ dwidth = 12;
+ height = 17;
id = "syndicate_ne";
name = "northeast of station";
turf_type = /turf/open/space;
- width = 18
+ width = 23
},
/turf/open/space,
/area/space/nearstation)
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 2852c76257..05a68f83ac 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -3322,14 +3322,14 @@
/area/construction/mining/aux_base)
"agO" = (
/obj/docking_port/stationary{
- dheight = 9;
- dir = 2;
- dwidth = 5;
- height = 24;
+ dheight = 1;
+ dir = 8;
+ dwidth = 12;
+ height = 17;
id = "syndicate_ne";
name = "northeast of station";
turf_type = /turf/open/space;
- width = 18
+ width = 23
},
/turf/open/space,
/area/space/nearstation)
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 8ed9acf09f..e31bb2fc08 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -80597,14 +80597,14 @@
/area/shuttle/abandoned)
"EDa" = (
/obj/docking_port/stationary{
- dheight = 9;
- dir = 2;
- dwidth = 5;
- height = 24;
+ dheight = 1;
+ dir = 8;
+ dwidth = 12;
+ height = 17;
id = "syndicate_nw";
name = "northwest of station";
turf_type = /turf/open/space;
- width = 18
+ width = 23
},
/turf/open/space/basic,
/area/space/nearstation)
diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm
index bbf998aaba..7eade308ce 100644
--- a/_maps/map_files/Mining/Lavaland.dmm
+++ b/_maps/map_files/Mining/Lavaland.dmm
@@ -111,6 +111,7 @@
/obj/item/pickaxe,
/obj/item/device/flashlight,
/obj/item/clothing/glasses/meson,
+/obj/item/device/mining_scanner,
/turf/open/floor/plasteel,
/area/mine/laborcamp)
"av" = (
@@ -119,6 +120,7 @@
/obj/item/device/flashlight,
/obj/item/pickaxe,
/obj/item/clothing/glasses/meson,
+/obj/item/device/mining_scanner,
/turf/open/floor/plasteel,
/area/mine/laborcamp)
"aw" = (
@@ -21563,7 +21565,7 @@ am
am
am
am
-ao
+ai
ab
ab
ab
@@ -22070,7 +22072,7 @@ am
am
am
am
-ao
+ai
ab
ab
ai
@@ -22854,7 +22856,7 @@ ab
ab
ab
ab
-ao
+ai
ab
ab
ab
@@ -24644,7 +24646,7 @@ am
am
am
am
-ao
+ai
ab
ab
ab
@@ -24901,7 +24903,7 @@ am
am
am
am
-ao
+ai
ab
ab
ab
@@ -25178,7 +25180,7 @@ ab
ab
ab
ab
-ao
+ai
am
am
ai
@@ -25422,7 +25424,7 @@ ab
ab
ab
ai
-ao
+ai
ab
ab
ab
@@ -25672,7 +25674,7 @@ am
am
am
am
-ao
+ai
ab
ab
ab
@@ -25956,7 +25958,7 @@ am
am
am
am
-ao
+ai
ab
ab
ab
@@ -26199,7 +26201,7 @@ ab
ab
ab
ab
-ao
+ai
am
am
am
@@ -26213,7 +26215,7 @@ am
am
am
am
-ao
+ai
ab
ab
ab
@@ -26972,7 +26974,7 @@ ab
ab
ab
ab
-ao
+ai
am
am
am
@@ -28511,7 +28513,7 @@ ab
ab
ab
ai
-ao
+ai
ab
ab
ab
@@ -29021,7 +29023,7 @@ ab
ab
ab
ab
-ao
+ai
ab
ab
ai
@@ -29030,13 +29032,13 @@ am
am
am
am
-ao
+ai
ab
ab
ab
ab
-ao
-ao
+ai
+ai
ab
ab
ab
@@ -29278,8 +29280,8 @@ ab
ab
ab
ab
-ao
-ao
+ai
+ai
ab
ai
am
@@ -30060,8 +30062,8 @@ ab
ab
ab
ab
-ao
-ao
+ai
+ai
ab
ab
ab
@@ -30573,7 +30575,7 @@ ai
ai
ab
ab
-ao
+ai
am
am
am
diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm
index ffda1f471d..4fc42569fa 100644
--- a/_maps/map_files/OmegaStation/OmegaStation.dmm
+++ b/_maps/map_files/OmegaStation/OmegaStation.dmm
@@ -34669,14 +34669,14 @@
/area/space/nearstation)
"sws" = (
/obj/docking_port/stationary{
- dheight = 9;
- dir = 2;
- dwidth = 5;
- height = 24;
+ dheight = 1;
+ dir = 8;
+ dwidth = 12;
+ height = 17;
id = "syndicate_sw";
name = "southwest of station";
turf_type = /turf/open/space;
- width = 18
+ width = 23
},
/turf/open/space,
/area/space/nearstation)
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index 7eb9a7ac7a..54e01bc923 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -3137,14 +3137,14 @@
/area/maintenance/department/crew_quarters/dorms)
"ajA" = (
/obj/docking_port/stationary{
- dheight = 9;
- dir = 2;
- dwidth = 5;
- height = 24;
+ dheight = 1;
+ dir = 8;
+ dwidth = 12;
+ height = 17;
id = "syndicate_ne";
name = "northeast of station";
turf_type = /turf/open/space;
- width = 18
+ width = 23
},
/turf/open/space,
/area/space/nearstation)
diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm
index 27198fe072..804e2c7a9a 100644
--- a/_maps/map_files/generic/CentCom.dmm
+++ b/_maps/map_files/generic/CentCom.dmm
@@ -7568,11 +7568,16 @@
},
/area/shuttle/syndicate/hallway)
"uc" = (
-/obj/machinery/porta_turret/syndicate{
- dir = 4
+/obj/structure/chair{
+ dir = 4;
+ name = "tactical chair"
},
-/turf/closed/wall/mineral/plastitanium,
-/area/shuttle/syndicate/hallway)
+/obj/effect/turf_decal/bot_white,
+/obj/machinery/light{
+ dir = 8
+ },
+/turf/open/floor/plasteel/dark,
+/area/shuttle/syndicate/airlock)
"ud" = (
/obj/machinery/door/poddoor/shutters{
id = "nukeop_ready";
@@ -14641,6 +14646,125 @@
},
/turf/open/floor/plasteel,
/area/tdome/arena)
+"Mt" = (
+/obj/structure/chair{
+ dir = 4;
+ name = "tactical chair"
+ },
+/obj/effect/turf_decal/bot_white,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/syndicate/airlock)
+"Mu" = (
+/obj/structure/table/reinforced,
+/obj/item/storage/toolbox/syndicate,
+/obj/item/crowbar/red,
+/obj/effect/turf_decal/stripes/line{
+ dir = 9
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/syndicate/airlock)
+"Mv" = (
+/obj/structure/chair{
+ dir = 4;
+ name = "tactical chair"
+ },
+/obj/effect/turf_decal/bot_white,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/syndicate/airlock)
+"Mw" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/syndicate/airlock)
+"Mx" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/syndicate/airlock)
+"My" = (
+/obj/docking_port/stationary{
+ area_type = /area/syndicate_mothership;
+ baseturf_type = /turf/open/floor/plating/asteroid/snow;
+ dheight = 1;
+ dir = 8;
+ dwidth = 12;
+ height = 17;
+ id = "syndicate_away";
+ name = "syndicate recon outpost";
+ turf_type = /turf/open/floor/plating/asteroid/snow;
+ width = 23
+ },
+/obj/machinery/door/poddoor{
+ id = "smindicate";
+ name = "outer blast door"
+ },
+/obj/machinery/button/door{
+ id = "smindicate";
+ name = "external door control";
+ pixel_x = 0;
+ pixel_y = 26;
+ req_access_txt = "150"
+ },
+/obj/docking_port/mobile{
+ dheight = 1;
+ dir = 8;
+ dwidth = 12;
+ height = 17;
+ hidden = 1;
+ id = "syndicate";
+ movement_force = list("KNOCKDOWN" = 0, "THROW" = 0);
+ name = "syndicate infiltrator";
+ port_direction = 4;
+ roundstart_move = null;
+ width = 23
+ },
+/obj/structure/fans/tiny,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/syndicate/airlock)
+"Mz" = (
+/turf/open/floor/plasteel/dark,
+/area/shuttle/syndicate/airlock)
+"MA" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/syndicate/airlock)
+"MB" = (
+/obj/structure/chair{
+ dir = 4;
+ name = "tactical chair"
+ },
+/obj/effect/turf_decal/bot_white,
+/turf/open/floor/plasteel/dark,
+/area/shuttle/syndicate/airlock)
+"MC" = (
+/obj/structure/rack,
+/obj/item/clothing/suit/space/syndicate/black/red,
+/obj/item/clothing/head/helmet/space/syndicate/black/red,
+/obj/effect/turf_decal/bot_white,
+/obj/effect/turf_decal/stripes/line{
+ dir = 10
+ },
+/turf/open/floor/mineral/plastitanium,
+/area/shuttle/syndicate/airlock)
+"MD" = (
+/obj/effect/light_emitter{
+ set_cap = 1;
+ set_luminosity = 4
+ },
+/obj/structure/sign/securearea{
+ desc = "A warning sign which reads 'FOURTH WALL'.";
+ name = "\improper FOURTH WALL";
+ pixel_x = -32
+ },
+/turf/open/floor/plating/asteroid/snow/airless,
+/area/syndicate_mothership)
(1,1,1) = {"
aa
@@ -26361,38 +26485,38 @@ hl
hl
hl
hh
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
-aa
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
+hh
aa
aa
aa
@@ -26617,41 +26741,41 @@ hl
hl
hl
hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+kt
+MD
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+hl
hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
-hh
+aa
+aa
aa
aa
aa
@@ -26887,27 +27011,25 @@ hl
hl
hl
hl
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+yc
+yd
+yd
+yd
+yd
+yd
+yd
+yd
+yd
+yd
+kt
hl
-hl
-hl
-hl
-hl
-hl
-hl
-we
-hl
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
hh
aa
aa
@@ -26977,6 +27099,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(49,1,1) = {"
aa
@@ -27144,27 +27268,25 @@ hl
hl
hl
hl
-hl
-hl
-hl
-kt
kt
+tY
+tZ
+tZ
+tZ
+tZ
+tZ
+yd
+yL
+zs
+yL
+AC
+Bj
+BT
+Cj
+CS
+Di
kt
hl
-hl
-hl
-hl
-yc
-yd
-yd
-yd
-yd
-yd
-yd
-yd
-yd
-yd
-kt
hh
aa
aa
@@ -27234,6 +27356,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(50,1,1) = {"
aa
@@ -27401,27 +27525,25 @@ hl
hl
hl
hl
-hl
-hl
-hl
-hl
-tY
-tZ
-tZ
-tZ
-tZ
-tZ
-yd
-yL
-zs
-yL
-AC
-Bj
-BT
-Cj
-CS
-Di
kt
+tZ
+uG
+vo
+vo
+vo
+xA
+yd
+yM
+zt
+zR
+zR
+Bk
+zR
+Ck
+CS
+Dj
+kt
+hl
hh
aa
aa
@@ -27491,6 +27613,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(51,1,1) = {"
aa
@@ -27652,33 +27776,31 @@ hl
hl
hl
hl
-hl
-hl
-hl
-hl
-hl
-hl
-hl
-hl
-hl
+kt
+kt
+kt
+kt
+kt
+kt
kt
tZ
-uG
-vo
-vo
-vo
-xA
-yd
-yM
+uH
+uH
+uH
+uH
+uH
+ye
+yN
zt
-zR
-zR
-Bk
-zR
-Ck
+zS
+AD
+Bl
+BU
+Cl
CS
-Dj
+Dk
kt
+hl
hh
aa
aa
@@ -27748,6 +27870,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(52,1,1) = {"
aa
@@ -27909,33 +28033,31 @@ hl
hl
my
hl
-hl
-kt
-kt
+oS
+oT
+oT
+oT
+oT
hl
hl
-hl
-hl
-hl
-hl
-kt
tZ
uH
uH
uH
uH
uH
-ye
-yN
+yd
+yO
zt
-zS
-AD
-Bl
-BU
-Cl
-CS
-Dk
+zT
+AE
+Bm
+yf
+yd
+yd
+Dl
kt
+hl
hh
aa
aa
@@ -28005,6 +28127,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(53,1,1) = {"
aa
@@ -28166,33 +28290,31 @@ hl
hl
hl
hl
-hl
-kt
-hl
-oS
oT
+px
+pR
+qI
oT
-oT
-oT
-hl
+rY
hl
tZ
-uH
-uH
-uH
-uH
-uH
+uI
+vp
+wf
+wR
+xB
yd
-yO
+yP
zt
zT
AE
-Bm
-yf
+Bn
yd
-yd
-Dl
+hl
+hl
kt
+kt
+hl
hh
aa
aa
@@ -28262,6 +28384,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(54,1,1) = {"
aa
@@ -28423,33 +28547,31 @@ hl
hl
hl
hl
-hl
-kt
-hl
-oT
-px
-pR
+oU
+py
+pS
qI
oT
-rY
-hl
+rZ
+rZ
tZ
-uI
-vp
-wf
-wR
-xB
+tZ
+tZ
+tZ
+wS
+xC
+yf
+yQ
+yQ
+zU
+yQ
yd
-yP
-zt
-zT
-AE
-Bn
yd
+rZ
+rZ
+kt
hl
hl
-kt
-kt
hh
aa
aa
@@ -28519,6 +28641,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(55,1,1) = {"
aa
@@ -28680,31 +28804,29 @@ hl
hl
hl
nx
-hl
-kt
-hl
oU
-py
-pS
+pz
+pT
qI
-oT
-rZ
-rZ
-tZ
-tZ
-tZ
-tZ
-wS
-xC
-yf
-yQ
-yQ
-zU
-yQ
-yd
-yd
-rZ
-rZ
+rb
+sa
+sY
+ua
+sY
+sY
+wg
+sb
+sb
+sb
+sb
+zu
+zV
+AF
+Bo
+BV
+Cm
+CT
+kt
hl
hl
hh
@@ -28776,6 +28898,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(56,1,1) = {"
aa
@@ -28937,31 +29061,29 @@ hl
hl
hl
hl
-hl
-kt
-hl
oU
-pz
-pT
+pA
+pU
qI
-rb
-sa
-sY
-ua
-sY
-sY
-wg
+rc
sb
+sZ
+sZ
+sZ
sb
+wh
sb
-sb
-zu
+sZ
+sZ
+sZ
+sZ
zV
AF
Bo
-BV
+BW
Cm
-CT
+CU
+kt
hl
hl
hh
@@ -29033,6 +29155,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(57,1,1) = {"
aa
@@ -29194,31 +29318,29 @@ hl
my
hl
hl
-hl
-kt
-hl
oU
-pA
-pU
+pB
+pT
qI
-rc
+oT
+sc
+ta
+ub
+ta
+ta
+wg
sb
-sZ
-sZ
-sZ
sb
-wh
sb
-sZ
-sZ
-sZ
-sZ
+sb
+zv
zV
AF
Bo
-BW
+BV
Cm
-CU
+CV
+kt
hl
hl
hh
@@ -29290,6 +29412,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(58,1,1) = {"
aa
@@ -29451,31 +29575,29 @@ hl
hl
hl
hl
-hl
-kt
-hl
oU
-pB
-pT
+pC
+pV
qI
oT
-sc
-ta
-ub
-ta
-ta
-wg
-sb
-sb
-sb
-sb
-zv
-zV
-AF
-Bo
-BV
-Cm
-CV
+rZ
+rZ
+rZ
+rZ
+vq
+vq
+wT
+xD
+yg
+yR
+yR
+zW
+yR
+yh
+yh
+rZ
+rZ
+kt
hl
hl
hh
@@ -29547,6 +29669,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(59,1,1) = {"
aa
@@ -29708,32 +29832,30 @@ hl
hl
hl
hl
-hl
-kt
-hl
-oU
-pC
-pV
+oT
+pD
+pW
qI
oT
-rZ
-rZ
-uc
-rZ
-vq
-vq
-wT
-xD
-yg
-yR
-yR
-zW
-yR
-yh
-yh
-rZ
-rZ
+sd
hl
+vq
+Mt
+Mv
+uc
+Mz
+MB
+yh
+yS
+zw
+zX
+AG
+Bp
+yh
+hl
+hl
+kt
+kt
hl
hh
aa
@@ -29804,6 +29926,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(60,1,1) = {"
aa
@@ -29965,33 +30089,31 @@ hl
hl
hl
hl
-hl
-kt
-hl
+oV
oT
-pD
-pW
-qI
oT
-sd
-tb
-ng
-nz
+oT
+oT
+hl
+hl
vq
-wi
wU
-xE
+wU
+wU
+wU
+wU
yh
-yS
+yT
zw
zX
AG
-Bp
+Bq
+yg
yh
-hl
-hl
-kt
+yh
+Dm
kt
+hl
hh
aa
aa
@@ -30061,6 +30183,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(61,1,1) = {"
aa
@@ -30222,33 +30346,31 @@ hl
mz
hl
my
-hl
kt
-hl
-oV
-oT
-oT
-oT
-oT
-hl
-tc
-ll
-uJ
-vr
-wj
+kt
+kt
+kt
+kt
+kt
+kt
+vq
wU
-xE
-yh
-yT
+wU
+wU
+wU
+wU
+yi
+yU
zw
-zX
-AG
-Bq
-yg
-yh
-yh
-Dm
+zY
+AH
+Br
+zZ
+Cn
+CW
+Dn
kt
+hl
hh
aa
aa
@@ -30318,6 +30440,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(62,1,1) = {"
aa
@@ -30480,32 +30604,30 @@ mA
hl
hl
hl
+hl
+hl
+nx
+hl
+hl
kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-tc
-ll
-uK
-vs
-wk
-wU
-xF
-yi
-yU
+vq
+Mu
+Mw
+Mx
+MA
+MC
+yh
+yV
zw
-zY
-AH
-Br
zZ
-Cn
+zZ
+Bs
+zZ
+Co
CW
-Dn
+Do
kt
+hl
hh
aa
aa
@@ -30575,6 +30697,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(63,1,1) = {"
aa
@@ -30737,32 +30861,30 @@ hl
hl
hl
hl
-my
hl
hl
hl
hl
-nx
hl
kt
-tc
-ll
-tc
-vt
+yj
vq
vq
+My
+vs
vq
yh
-yV
+yW
zw
-zZ
-zZ
-Bs
-zZ
-Co
+Aa
+AI
+Bt
+BX
+Cn
CW
-Do
+Dp
kt
+hl
hh
aa
aa
@@ -30832,6 +30954,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(64,1,1) = {"
aa
@@ -30999,27 +31123,25 @@ hl
hl
hl
hl
-hl
-hl
kt
-tc
-ll
-tc
-hl
-hl
-hl
-vq
+kt
+kt
+uK
+uJ
+uK
+kt
+yj
+yh
+yh
+yh
+yh
+yh
+yh
+yh
+yh
yh
-yW
-zw
-Aa
-AI
-Bt
-BX
-Cn
-CW
-Dp
kt
+hl
hh
aa
aa
@@ -31089,6 +31211,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(65,1,1) = {"
aa
@@ -31250,7 +31374,7 @@ kt
hl
hl
hl
-mz
+hl
hl
hl
hl
@@ -31262,21 +31386,19 @@ kt
tc
ll
tc
-hl
-hl
-hl
-hl
-yj
-yh
-yh
-yh
-yh
-yh
-yh
-yh
-yh
-yh
kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+kt
+hl
hh
aa
aa
@@ -31346,6 +31468,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(66,1,1) = {"
aa
@@ -31514,26 +31638,24 @@ hl
kt
kt
kt
-rd
kt
-td
-ll
-td
+kt
+tc
+uJ
+tc
kt
rd
kt
kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
-kt
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
+hl
hh
aa
aa
@@ -31603,6 +31725,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(67,1,1) = {"
aa
@@ -31789,8 +31913,6 @@ hl
hl
hl
hl
-hl
-hl
hh
aa
aa
@@ -31860,6 +31982,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(68,1,1) = {"
aa
@@ -32046,8 +32170,6 @@ hl
hl
hl
hl
-hl
-hl
hh
aa
aa
@@ -32117,6 +32239,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(69,1,1) = {"
aa
@@ -32303,8 +32427,6 @@ hl
hl
BY
hl
-hl
-hl
hh
aa
aa
@@ -32374,6 +32496,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(70,1,1) = {"
aa
@@ -32560,8 +32684,6 @@ hl
BY
Cp
BY
-hl
-hl
hh
aa
aa
@@ -32631,6 +32753,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(71,1,1) = {"
aa
@@ -32817,8 +32941,6 @@ hl
hl
BY
hl
-hl
-hl
hh
aa
aa
@@ -32888,6 +33010,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(72,1,1) = {"
aa
@@ -33074,8 +33198,6 @@ hl
hl
hl
hl
-hl
-hl
hh
aa
aa
@@ -33145,6 +33267,8 @@ aa
aa
aa
aa
+aa
+aa
"}
(73,1,1) = {"
aa
@@ -33332,8 +33456,8 @@ hh
hh
hh
hh
-hh
-hh
+aa
+aa
aa
aa
aa
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index 965ee51502..8b3e74b96e 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -22,7 +22,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define ON_BORDER_1 512 // item has priority to check when entering or leaving
#define NOSLIP_1 1024 //prevents from slipping on wet floors, in space etc
-#define CLEAN_ON_MOVE_1 2048
+#define _UNUSED_1 2048
// BLOCK_GAS_SMOKE_EFFECT_1 only used in masks at the moment.
#define BLOCK_GAS_SMOKE_EFFECT_1 4096 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm
index a23f050c13..543ac4badf 100644
--- a/code/__DEFINES/stat.dm
+++ b/code/__DEFINES/stat.dm
@@ -10,17 +10,29 @@
//mob disabilities stat
-#define BLIND 1
-#define MUTE 2
-#define DEAF 4
-#define NEARSIGHT 8
-#define FAT 32
-#define HUSK 64
-#define NOCLONE 128
-#define CLUMSY 256
-#define DUMB 512
-#define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE
-#define PACIFISM 2048
+#define BLIND "blind"
+#define MUTE "mute"
+#define DEAF "deaf"
+#define NEARSIGHT "nearsighted"
+#define FAT "fat"
+#define HUSK "husk"
+#define NOCLONE "noclone"
+#define CLUMSY "clumsy"
+#define DUMB "dumb"
+#define MONKEYLIKE "monkeylike" //sets IsAdvancedToolUser to FALSE
+#define PACIFISM "pacifism"
+
+// common disability sources
+#define EYE_DAMAGE "eye_damage"
+#define GENETIC_MUTATION "genetic"
+#define STATUE_MUTE "statue"
+#define CHANGELING_DRAIN "drain"
+#define OBESITY "obesity"
+#define MAGIC_DISABILITY "magic"
+#define STASIS_MUTE "stasis"
+#define GENETICS_SPELL "genetics_spell"
+#define TRAUMA_DISABILITY "trauma"
+
// bitflags for machine stat variable
#define BROKEN 1
diff --git a/code/datums/actions/beam_rifle.dm b/code/datums/actions/beam_rifle.dm
new file mode 100644
index 0000000000..783b93fbdb
--- /dev/null
+++ b/code/datums/actions/beam_rifle.dm
@@ -0,0 +1,12 @@
+
+/datum/action/item_action/zoom_speed_action
+ name = "Toggle Zooming Speed"
+ icon_icon = 'icons/mob/actions/actions_spells.dmi'
+ button_icon_state = "projectile"
+ background_icon_state = "bg_tech"
+
+/datum/action/item_action/zoom_lock_action
+ name = "Switch Zoom Mode"
+ icon_icon = 'icons/mob/actions/actions_items.dmi'
+ button_icon_state = "zoom_mode"
+ background_icon_state = "bg_tech"
diff --git a/code/datums/actions/flightsuit.dm b/code/datums/actions/flightsuit.dm
index 3e78fa5332..cf249fed31 100644
--- a/code/datums/actions/flightsuit.dm
+++ b/code/datums/actions/flightsuit.dm
@@ -1,5 +1,3 @@
-
-
/datum/action/item_action/flightsuit
icon_icon = 'icons/mob/actions/actions_flightsuit.dmi'
diff --git a/code/datums/antagonists/changeling.dm b/code/datums/antagonists/changeling.dm
index 4f8af2dc8a..031e08738f 100644
--- a/code/datums/antagonists/changeling.dm
+++ b/code/datums/antagonists/changeling.dm
@@ -223,7 +223,7 @@
if(verbose)
to_chat(user, "[target] is not compatible with our biology.")
return
- if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
+ if((target.has_disability(NOCLONE)) || (target.has_disability(NOCLONE)))
if(verbose)
to_chat(user, "DNA of [target] is ruined beyond usability!")
return
diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm
index 7c2ba20a62..d5ccc71ef9 100644
--- a/code/datums/brain_damage/mild.dm
+++ b/code/datums/brain_damage/mild.dm
@@ -42,7 +42,7 @@
lose_text = "You feel smart again."
/datum/brain_trauma/mild/dumbness/on_gain()
- owner.disabilities |= DUMB
+ owner.add_disability(DUMB, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/mild/dumbness/on_life()
@@ -54,7 +54,7 @@
..()
/datum/brain_trauma/mild/dumbness/on_lose()
- owner.disabilities &= ~DUMB
+ owner.remove_disability(DUMB, TRAUMA_DISABILITY)
owner.derpspeech = 0
..()
diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm
index ceda917713..a138073040 100644
--- a/code/datums/brain_damage/severe.dm
+++ b/code/datums/brain_damage/severe.dm
@@ -12,17 +12,11 @@
lose_text = "You suddenly remember how to speak."
/datum/brain_trauma/severe/mute/on_gain()
- owner.disabilities |= MUTE
- ..()
-
-//no fiddling with genetics to get out of this one
-/datum/brain_trauma/severe/mute/on_life()
- if(!(owner.disabilities & MUTE))
- on_gain()
+ owner.add_disability(MUTE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/mute/on_lose()
- owner.disabilities &= ~MUTE
+ owner.remove_disability(MUTE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/aphasia
@@ -56,17 +50,11 @@
lose_text = "Your vision returns."
/datum/brain_trauma/severe/blindness/on_gain()
- owner.become_blind()
- ..()
-
-//no fiddling with genetics to get out of this one
-/datum/brain_trauma/severe/blindness/on_life()
- if(!(owner.disabilities & BLIND))
- on_gain()
+ owner.become_blind(TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/blindness/on_lose()
- owner.cure_blind()
+ owner.cure_blind(TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/paralysis
@@ -132,7 +120,7 @@
stress -= 4
/datum/brain_trauma/severe/monophobia/proc/check_alone()
- if(owner.disabilities & BLIND)
+ if(owner.has_disability(BLIND))
return TRUE
for(var/mob/M in oview(owner, 7))
if(!isliving(M)) //ghosts ain't people
@@ -194,11 +182,26 @@
lose_text = "You feel in control of your hands again."
/datum/brain_trauma/severe/discoordination/on_gain()
- owner.disabilities |= MONKEYLIKE
+ owner.add_disability(MONKEYLIKE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/discoordination/on_lose()
- owner.disabilities &= ~MONKEYLIKE
+ owner.remove_disability(MONKEYLIKE, TRAUMA_DISABILITY)
+ ..()
+
+/datum/brain_trauma/severe/pacifism
+ name = "Traumatic Non-Violence"
+ desc = "Patient is extremely unwilling to harm others in violent ways."
+ scan_desc = "pacific syndrome"
+ gain_text = "You feel oddly peaceful."
+ lose_text = "You no longer feel compelled to not harm."
+
+/datum/brain_trauma/severe/pacifism/on_gain()
+ owner.add_disability(PACIFISM, TRAUMA_DISABILITY)
+ ..()
+
+/datum/brain_trauma/severe/pacifism/on_lose()
+ owner.remove_disability(PACIFISM, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/pacifism
diff --git a/code/datums/components/cleaning.dm b/code/datums/components/cleaning.dm
new file mode 100644
index 0000000000..5d9d5992e2
--- /dev/null
+++ b/code/datums/components/cleaning.dm
@@ -0,0 +1,40 @@
+/datum/component/cleaning
+ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
+
+/datum/component/cleaning/Initialize()
+ if(!ismovableatom(parent))
+ . = COMPONENT_INCOMPATIBLE
+ CRASH("[type] added to a [parent.type]")
+ RegisterSignal(list(COMSIG_MOVABLE_MOVED), .proc/Clean)
+
+/datum/component/cleaning/proc/Clean()
+ var/atom/movable/AM = parent
+ var/turf/tile = AM.loc
+ if(!isturf(tile))
+ return
+
+ tile.clean_blood()
+ for(var/A in tile)
+ if(is_cleanable(A))
+ qdel(A)
+ else if(istype(A, /obj/item))
+ var/obj/item/cleaned_item = A
+ cleaned_item.clean_blood()
+ else if(ishuman(A))
+ var/mob/living/carbon/human/cleaned_human = A
+ if(cleaned_human.lying)
+ if(cleaned_human.head)
+ cleaned_human.head.clean_blood()
+ cleaned_human.update_inv_head()
+ if(cleaned_human.wear_suit)
+ cleaned_human.wear_suit.clean_blood()
+ cleaned_human.update_inv_wear_suit()
+ else if(cleaned_human.w_uniform)
+ cleaned_human.w_uniform.clean_blood()
+ cleaned_human.update_inv_w_uniform()
+ if(cleaned_human.shoes)
+ cleaned_human.shoes.clean_blood()
+ cleaned_human.update_inv_shoes()
+ cleaned_human.clean_blood()
+ cleaned_human.wash_cream()
+ to_chat(cleaned_human, "[AM] cleans your face!")
diff --git a/code/datums/diseases/advance/symptoms/vision.dm b/code/datums/diseases/advance/symptoms/vision.dm
index 728dfa01d0..39d853a758 100644
--- a/code/datums/diseases/advance/symptoms/vision.dm
+++ b/code/datums/diseases/advance/symptoms/vision.dm
@@ -58,11 +58,12 @@ Bonus
M.blur_eyes(20)
M.adjust_eye_damage(5)
if(eyes.eye_damage >= 10)
- M.become_nearsighted()
+ M.become_nearsighted(EYE_DAMAGE)
if(prob(eyes.eye_damage - 10 + 1))
if(!remove_eyes)
- if(M.become_blind())
+ if(!M.has_disability(BLIND))
to_chat(M, "You go blind!")
+ M.become_blind(EYE_DAMAGE)
else
M.visible_message("[M]'s eyes fall off their sockets!", "Your eyes fall off their sockets!")
eyes.Remove(M)
@@ -111,16 +112,16 @@ Bonus
return
switch(A.stage)
if(4, 5) //basically oculine
- if(M.disabilities & BLIND)
+ if(M.has_disability(BLIND, EYE_DAMAGE))
if(prob(20))
to_chat(M, "Your vision slowly returns...")
- M.cure_blind()
- M.cure_nearsighted()
+ M.cure_blind(EYE_DAMAGE)
+ M.cure_nearsighted(EYE_DAMAGE)
M.blur_eyes(35)
- else if(M.disabilities & NEARSIGHT)
+ else if(M.has_disability(NEARSIGHT, EYE_DAMAGE))
to_chat(M, "The blackness in your peripheral vision fades.")
- M.cure_nearsighted()
+ M.cure_nearsighted(EYE_DAMAGE)
M.blur_eyes(10)
else if(M.eye_blind || M.eye_blurry)
diff --git a/code/datums/diseases/gbs.dm b/code/datums/diseases/gbs.dm
index 71e4064676..6d77acd3ae 100644
--- a/code/datums/diseases/gbs.dm
+++ b/code/datums/diseases/gbs.dm
@@ -1,6 +1,6 @@
/datum/disease/gbs
name = "GBS"
- max_stages = 5
+ max_stages = 4
spread_text = "On contact"
spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS
cure_text = "Synaptizine & Sulfur"
@@ -16,25 +16,15 @@
..()
switch(stage)
if(2)
- if(prob(45))
- affected_mob.adjustToxLoss(5)
- affected_mob.updatehealth()
- if(prob(1))
- affected_mob.emote("sneeze")
- if(3)
if(prob(5))
affected_mob.emote("cough")
- else if(prob(5))
+ if(3)
+ if(prob(5))
affected_mob.emote("gasp")
if(prob(10))
- to_chat(affected_mob, "You're starting to feel very weak...")
+ to_chat(affected_mob, "Your body hurts all over!")
if(4)
- if(prob(10))
- affected_mob.emote("cough")
- affected_mob.adjustToxLoss(5)
- affected_mob.updatehealth()
- if(5)
- to_chat(affected_mob, "Your body feels as if it's trying to rip itself open...")
+ to_chat(affected_mob, "Your body feels as if it's trying to rip itself apart!")
if(prob(50))
affected_mob.gib()
else
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index ec39bcec67..c4ccc4c1fb 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -45,6 +45,8 @@
set name = "Show Server Revision"
set desc = "Check the current server code revision"
+ if(GLOB.round_id)
+ to_chat(src, "Round ID: [GLOB.round_id]")
if(GLOB.revdata.originmastercommit)
to_chat(src, "Server revision compiled on: [GLOB.revdata.date]")
var/prefix = ""
diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm
index f3a1f53dd2..0a4309e708 100644
--- a/code/datums/martial/sleeping_carp.dm
+++ b/code/datums/martial/sleeping_carp.dm
@@ -197,7 +197,7 @@
/obj/item/twohanded/bostaff/attack(mob/target, mob/living/user)
add_fingerprint(user)
- if((CLUMSY in user.disabilities) && prob(50))
+ if((user.has_disability(CLUMSY)) && prob(50))
to_chat(user, "You club yourself over the head with [src].")
user.Knockdown(60)
if(ishuman(user))
diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm
index 170c0a2a7f..a171cf91da 100644
--- a/code/datums/mutations.dm
+++ b/code/datums/mutations.dm
@@ -8,7 +8,6 @@ GLOBAL_LIST_EMPTY(mutations_list)
GLOB.mutations_list[name] = src
/datum/mutation/human
-
var/dna_block
var/quality
var/get_chance = 100
diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm
index 23b91add58..015004eef6 100644
--- a/code/datums/mutations/body.dm
+++ b/code/datums/mutations/body.dm
@@ -85,12 +85,12 @@
/datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
- owner.disabilities |= CLUMSY
+ owner.add_disability(CLUMSY, GENETIC_MUTATION)
/datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner)
if(..())
return
- owner.disabilities &= ~CLUMSY
+ owner.remove_disability(CLUMSY, GENETIC_MUTATION)
//Tourettes causes you to randomly stand in place and shout.
@@ -124,12 +124,12 @@
/datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
- owner.disabilities |= DEAF
+ owner.add_disability(DEAF, GENETIC_MUTATION)
/datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner)
if(..())
return
- owner.disabilities &= ~DEAF
+ owner.remove_disability(DEAF, GENETIC_MUTATION)
//Monified turns you into a monkey.
diff --git a/code/datums/mutations/sight.dm b/code/datums/mutations/sight.dm
index dee26166dd..60f5d75c5e 100644
--- a/code/datums/mutations/sight.dm
+++ b/code/datums/mutations/sight.dm
@@ -7,12 +7,12 @@
/datum/mutation/human/nearsight/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
- owner.become_nearsighted()
+ owner.become_nearsighted(GENETIC_MUTATION)
/datum/mutation/human/nearsight/on_losing(mob/living/carbon/human/owner)
if(..())
return
- owner.cure_nearsighted()
+ owner.cure_nearsighted(GENETIC_MUTATION)
//Blind makes you blind. Who knew?
@@ -24,12 +24,12 @@
/datum/mutation/human/blind/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
- owner.become_blind()
+ owner.become_blind(GENETIC_MUTATION)
/datum/mutation/human/blind/on_losing(mob/living/carbon/human/owner)
if(..())
return
- owner.cure_blind()
+ owner.cure_blind(GENETIC_MUTATION)
//X-Ray Vision lets you see through walls.
diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm
index 3b4b38bbcc..dc1333024a 100644
--- a/code/datums/mutations/speech.dm
+++ b/code/datums/mutations/speech.dm
@@ -30,12 +30,12 @@
/datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
- owner.disabilities |= MUTE
+ owner.add_disability(MUTE, GENETIC_MUTATION)
/datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner)
if(..())
return
- owner.disabilities &= ~MUTE
+ owner.remove_disability(MUTE, GENETIC_MUTATION)
/datum/mutation/human/smile
diff --git a/code/datums/position_point_vector.dm b/code/datums/position_point_vector.dm
new file mode 100644
index 0000000000..635ae0bbec
--- /dev/null
+++ b/code/datums/position_point_vector.dm
@@ -0,0 +1,239 @@
+//Designed for things that need precision trajectories like projectiles.
+//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels.
+
+#define RETURN_PRECISE_POSITION(A) new /datum/position(A)
+#define RETURN_PRECISE_POINT(A) new /datum/point(A)
+
+/datum/position //For positions with map x/y/z and pixel x/y so you don't have to return lists. Could use addition/subtraction in the future I guess.
+ var/x = 0
+ var/y = 0
+ var/z = 0
+ var/pixel_x = 0
+ var/pixel_y = 0
+
+/datum/position/proc/valid()
+ return x && y && z && !isnull(pixel_x) && !isnull(pixel_y)
+
+/datum/position/New(_x = 0, _y = 0, _z = 0, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/point.
+ if(istype(_x, /datum/point))
+ var/datum/point/P = _x
+ var/turf/T = P.return_turf()
+ _x = T.x
+ _y = T.y
+ _z = T.z
+ _pixel_x = P.return_px()
+ _pixel_y = P.return_py()
+ else if(isatom(_x))
+ var/atom/A = _x
+ _x = A.x
+ _y = A.y
+ _z = A.z
+ _pixel_x = A.pixel_x
+ _pixel_y = A.pixel_y
+ x = _x
+ y = _y
+ z = _z
+ pixel_x = _pixel_x
+ pixel_y = _pixel_y
+
+/datum/position/proc/return_turf()
+ return locate(x, y, z)
+
+/datum/position/proc/return_px()
+ return pixel_x
+
+/datum/position/proc/return_py()
+ return pixel_y
+
+/datum/position/proc/return_point()
+ return new /datum/point(src)
+
+/proc/point_midpoint_points(datum/point/a, datum/point/b) //Obviously will not support multiZ calculations! Same for the two below.
+ var/datum/point/P = new
+ P.x = round(a.x + (b.x - a.x) / 2, 1)
+ P.y = round(a.y + (b.y - a.y) / 2, 1)
+ P.z = a.z
+ return P
+
+/proc/pixel_length_between_points(datum/point/a, datum/point/b)
+ return sqrt(((b.x - a.x) ** 2) + ((b.y - a.y) ** 2))
+
+/proc/angle_between_points(datum/point/a, datum/point/b)
+ return ATAN2((b.y - a.y), (b.x - a.x))
+
+/datum/point //A precise point on the map in absolute pixel locations based on world.icon_size. Pixels are FROM THE EDGE OF THE MAP!
+ var/x = 0
+ var/y = 0
+ var/z = 0
+
+/datum/point/proc/valid()
+ return x && y && z
+
+/datum/point/proc/copy_to(datum/point/p = new)
+ p.x = x
+ p.y = y
+ p.z = z
+ return p
+
+/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/position or /atom.
+ if(istype(_x, /datum/position))
+ var/datum/position/P = _x
+ _x = P.x
+ _y = P.y
+ _z = P.z
+ _pixel_x = P.pixel_x
+ _pixel_y = P.pixel_y
+ else if(istype(_x, /atom))
+ var/atom/A = _x
+ _x = A.x
+ _y = A.y
+ _z = A.z
+ _pixel_x = A.pixel_x
+ _pixel_y = A.pixel_y
+ initialize_location(_x, _y, _z, _pixel_x, _pixel_y)
+
+/datum/point/proc/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
+ if(!isnull(tile_x))
+ x = ((tile_x - 1) * world.icon_size) + world.icon_size / 2 + p_x
+ if(!isnull(tile_y))
+ y = ((tile_y - 1) * world.icon_size) + world.icon_size / 2+ p_y
+ if(!isnull(tile_z))
+ z = tile_z
+
+/datum/point/proc/return_turf()
+ return locate(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
+
+/datum/point/proc/return_coordinates() //[turf_x, turf_y, z]
+ return list(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
+
+/datum/point/proc/return_position()
+ return new /datum/position(src)
+
+/datum/point/proc/return_px()
+ return MODULUS(x, world.icon_size) - 16
+
+/datum/point/proc/return_py()
+ return MODULUS(y, world.icon_size) - 16
+
+/datum/point/proc/mapcheck()
+ . = FALSE
+ var/maxx = world.icon_size * world.maxx
+ var/maxy = world.icon_size * world.maxy
+ var/move_zx = 0
+ var/move_zy = 0
+ if(x < 0)
+ x += maxx
+ move_zx -= 1
+ if(y < 0)
+ y += maxy
+ move_zy -= 1
+ if(x > maxx)
+ x -= maxx
+ move_zx += 1
+ if(y > maxy)
+ y -= maxy
+ move_zy += 1
+ var/datum/space_level/S = GLOB.z_levels_list["[z]"]
+ if(move_zx != 0)
+ var/datum/space_level/L = S.neigbours["[move_zx < 0? WEST : EAST]"]
+ z = L.z_value
+ . = TRUE
+ if(move_zy != 0)
+ var/datum/space_level/L = S.neigbours["[move_zy < 0? SOUTH : NORTH]"]
+ z = L.z_value
+ . = TRUE
+
+/datum/point/vector
+ var/speed = 32 //pixels per iteration
+ var/iteration = 0
+ var/angle = 0
+ var/mpx = 0 //calculated x/y movement amounts to prevent having to do trig every step.
+ var/mpy = 0
+ var/starting_x = 0 //just like before, pixels from EDGE of map! This is set in initialize_location().
+ var/starting_y = 0
+ var/starting_z = 0
+
+/datum/point/vector/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0, _angle, _speed)
+ ..()
+ initialize_trajectory(_speed, _angle)
+
+/datum/point/vector/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
+ . = ..()
+ starting_x = x
+ starting_y = y
+ starting_z = z
+
+/datum/point/vector/copy_to(datum/point/vector/v = new)
+ ..(v)
+ v.speed = speed
+ v.iteration = iteration
+ v.angle = angle
+ v.mpx = mpx
+ v.mpy = mpy
+ v.starting_x = starting_x
+ v.starting_y = starting_y
+ v.starting_z = starting_z
+ return v
+
+/datum/point/vector/proc/initialize_trajectory(pixel_speed, new_angle)
+ if(!isnull(pixel_speed))
+ speed = pixel_speed
+ set_angle(new_angle)
+
+/datum/point/vector/proc/set_angle(new_angle) //calculations use "byond angle" where north is 0 instead of 90, and south is 180 instead of 270.
+ if(isnull(angle))
+ return
+ angle = new_angle
+ update_offsets()
+
+/datum/point/vector/proc/update_offsets()
+ mpx = sin(angle) * speed
+ mpy = cos(angle) * speed
+
+/datum/point/vector/proc/set_speed(new_speed)
+ if(isnull(new_speed) || speed == new_speed)
+ return
+ speed = new_speed
+ update_offsets()
+
+/datum/point/vector/proc/increment(multiplier = 1)
+ iteration++
+ x += mpx * 1
+ y += mpy * 1
+ if(mapcheck())
+ on_z_change()
+
+/datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE)
+ var/datum/point/vector/v = copy_to()
+ if(force_simulate)
+ for(var/i in 1 to amount)
+ v.increment(multiplier)
+ else
+ v.increment(multiplier * amount)
+ return v
+
+/datum/point/vector/proc/on_z_change()
+ return
+
+/datum/point/vector/processed //pixel_speed is per decisecond.
+ var/last_process = 0
+ var/last_move = 0
+ var/paused = FALSE
+
+/datum/point/vector/processed/Destroy()
+ STOP_PROCESSING(SSprojectiles, src)
+
+/datum/point/vector/processed/proc/start()
+ last_process = world.time
+ last_move = world.time
+ START_PROCESSING(SSprojectiles, src)
+
+/datum/point/vector/processed/process()
+ if(paused)
+ last_move += world.time - last_process
+ last_process = world.time
+ return
+ var/needed_time = world.time - last_move
+ last_process = world.time
+ last_move = world.time
+ increment(needed_time)
diff --git a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm
index 901a8610a6..712b3425e0 100644
--- a/code/game/alternate_appearance.dm
+++ b/code/game/alternate_appearance.dm
@@ -78,6 +78,7 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
QDEL_NULL(ghost_appearance)
/datum/atom_hud/alternate_appearance/basic/add_to_hud(atom/A)
+ LAZYINITLIST(A.hud_list)
A.hud_list[appearance_key] = theImage
. = ..()
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index ddb768488a..08568660fd 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -132,44 +132,12 @@
if (orbiting)
orbiting.Check()
- if(flags_1 & CLEAN_ON_MOVE_1)
- clean_on_move()
-
var/datum/proximity_monitor/proximity_monitor = src.proximity_monitor
if(proximity_monitor)
proximity_monitor.HandleMove()
return 1
-/atom/movable/proc/clean_on_move()
- var/turf/tile = loc
- if(isturf(tile))
- tile.clean_blood()
- for(var/A in tile)
- if(is_cleanable(A))
- qdel(A)
- else if(istype(A, /obj/item))
- var/obj/item/cleaned_item = A
- cleaned_item.clean_blood()
- else if(ishuman(A))
- var/mob/living/carbon/human/cleaned_human = A
- if(cleaned_human.lying)
- if(cleaned_human.head)
- cleaned_human.head.clean_blood()
- cleaned_human.update_inv_head()
- if(cleaned_human.wear_suit)
- cleaned_human.wear_suit.clean_blood()
- cleaned_human.update_inv_wear_suit()
- else if(cleaned_human.w_uniform)
- cleaned_human.w_uniform.clean_blood()
- cleaned_human.update_inv_w_uniform()
- if(cleaned_human.shoes)
- cleaned_human.shoes.clean_blood()
- cleaned_human.update_inv_shoes()
- cleaned_human.clean_blood()
- cleaned_human.wash_cream()
- to_chat(cleaned_human, "[src] cleans your face!")
-
/atom/movable/Destroy(force)
var/inform_admins = (flags_2 & INFORM_ADMINS_ON_RELOCATE_2)
var/stationloving = (flags_2 & STATIONLOVING_2)
diff --git a/code/game/gamemodes/changeling/powers/biodegrade.dm b/code/game/gamemodes/changeling/powers/biodegrade.dm
index dbb0e3a88a..4a34de151e 100644
--- a/code/game/gamemodes/changeling/powers/biodegrade.dm
+++ b/code/game/gamemodes/changeling/powers/biodegrade.dm
@@ -55,12 +55,14 @@
/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_handcuffs(mob/living/carbon/human/user, obj/O)
if(O && user.handcuffed == O)
user.visible_message("[O] dissolve[O.gender==PLURAL?"":"s"] into a puddle of sizzling goop.")
+ user.uncuff()
new /obj/effect/decal/cleanable/greenglow(O.drop_location())
qdel(O)
/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_straightjacket(mob/living/carbon/human/user, obj/S)
if(S && user.wear_suit == S)
user.visible_message("[S] dissolves into a puddle of sizzling goop.")
+ user.uncuff()
new /obj/effect/decal/cleanable/greenglow(S.drop_location())
qdel(S)
diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm
index 4fdd84040e..e3f486a2f1 100644
--- a/code/game/gamemodes/changeling/powers/tiny_prick.dm
+++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm
@@ -20,7 +20,7 @@
to_chat(user, "We prepare our sting, use alt+click or middle mouse button on target to sting them.")
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
changeling.chosen_sting = src
-
+
user.hud_used.lingstingdisplay.icon_state = sting_icon
user.hud_used.lingstingdisplay.invisibility = 0
@@ -28,7 +28,7 @@
to_chat(user, "We retract our sting, we can't sting anyone for now.")
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
changeling.chosen_sting = null
-
+
user.hud_used.lingstingdisplay.icon_state = null
user.hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
@@ -90,7 +90,7 @@
/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target)
if(!..())
return
- if((target.disabilities & HUSK) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
+ if((target.has_disability(HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
to_chat(user, "Our sting appears ineffective against its DNA.")
return 0
return 1
@@ -129,9 +129,11 @@
/obj/effect/proc_holder/changeling/sting/false_armblade/can_sting(mob/user, mob/target)
if(!..())
return
- if((target.disabilities & HUSK) || !target.has_dna())
- to_chat(user, "Our sting appears ineffective against its DNA.")
- return 0
+ if(isliving(target))
+ var/mob/living/L = target
+ if((L.has_disability(HUSK)) || !L.has_dna())
+ to_chat(user, "Our sting appears ineffective against its DNA.")
+ return 0
return 1
/obj/effect/proc_holder/changeling/sting/false_armblade/sting_action(mob/user, mob/target)
@@ -207,7 +209,7 @@
/obj/effect/proc_holder/changeling/sting/blind/sting_action(mob/user, mob/living/carbon/target)
add_logs(user, target, "stung", "blind sting")
to_chat(target, "Your eyes burn horrifically!")
- target.become_nearsighted()
+ target.become_nearsighted(EYE_DAMAGE)
target.blind_eyes(20)
target.blur_eyes(40)
return TRUE
diff --git a/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm b/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm
index fc734ac426..b579326fcc 100644
--- a/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm
@@ -32,7 +32,7 @@
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
if(src == H.glasses && !up)
- if(H.disabilities & BLIND)
+ if(H.has_disability(BLIND))
to_chat(H, "\"You're blind, idiot. Stop embarrassing yourself.\"")
return
if(blind_cultist(H))
@@ -51,7 +51,7 @@
to_chat(victim, "\"It looks like Nar-Sie's dogs really don't value their eyes.\"")
to_chat(victim, "Your eyes explode with horrific pain!")
victim.emote("scream")
- victim.become_blind()
+ victim.become_blind(EYE_DAMAGE)
victim.adjust_blurriness(30)
victim.adjust_blindness(30)
return TRUE
@@ -76,7 +76,7 @@
..()
if(slot != slot_glasses || up)
return
- if(user.disabilities & BLIND)
+ if(user.has_disability(BLIND))
to_chat(user, "\"You're blind, idiot. Stop embarrassing yourself.\"" )
return
if(blind_cultist(user)) //Cultists instantly go blind
@@ -115,11 +115,11 @@
var/obj/item/clothing/glasses/wraith_spectacles/WS = L.glasses
desc = "[glasses_right && !WS.up ? "":""]You are [glasses_right ? "":"not "]wearing wraith spectacles[glasses_right && !WS.up ? "!":"."]
\
You have taken [W.eye_damage_done] eye damage from them.
"
- if(L.disabilities & NEARSIGHT)
+ if(L.has_disability(NEARSIGHT))
desc += "You are nearsighted!
"
else if(glasses_right && !WS.up)
desc += "You will become nearsighted at [W.nearsight_breakpoint] eye damage.
"
- if(L.disabilities & BLIND)
+ if(L.has_disability(BLIND))
desc += "You are blind!"
else if(glasses_right && !WS.up)
desc += "You will become blind at [W.blind_breakpoint] eye damage."
@@ -142,8 +142,8 @@
apply_eye_damage(H)
else
if(GLOB.ratvar_awakens)
- H.cure_nearsighted()
- H.cure_blind()
+ H.cure_nearsighted(list(EYE_DAMAGE))
+ H.cure_blind(list(EYE_DAMAGE))
H.adjust_eye_damage(-eye_damage_done)
eye_damage_done = 0
else if(prob(50) && eye_damage_done)
@@ -153,17 +153,20 @@
qdel(src)
/datum/status_effect/wraith_spectacles/proc/apply_eye_damage(mob/living/carbon/human/H)
- if(H.disabilities & BLIND)
+ if(H.has_disability(BLIND))
return
H.adjust_eye_damage(0.5)
eye_damage_done += 0.5
if(eye_damage_done >= 20)
H.adjust_blurriness(2)
if(eye_damage_done >= nearsight_breakpoint)
- if(H.become_nearsighted())
- to_chat(H, "Your vision doubles, then trebles. Darkness begins to close in. You can't keep this up!")
+ if(!H.has_disability(NEARSIGHT))
+ to_chat(H, "Your vision doubles, then trembles. Darkness begins to close in. You can't keep this up!")
+ H.become_nearsighted(EYE_DAMAGE)
if(eye_damage_done >= blind_breakpoint)
- if(H.become_blind())
+ if(!H.has_disability(BLIND))
to_chat(H, "A piercing white light floods your vision. Suddenly, all goes dark!")
+ H.become_blind(EYE_DAMAGE)
+
if(prob(min(20, 5 + eye_damage_done)))
to_chat(H, "Your eyes continue to burn.")
diff --git a/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm
index 8416e4651d..baf149093c 100644
--- a/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm
+++ b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm
@@ -12,6 +12,7 @@
layer = FLY_LAYER
faction = list("ratvar")
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
+ var/turf/last_failed_turf
var/static/superheated_walls = 0
/mob/camera/eminence/CanPass(atom/movable/mover, turf/target)
@@ -20,7 +21,18 @@
/mob/camera/eminence/Move(NewLoc, direct)
var/OldLoc = loc
if(NewLoc && !istype(NewLoc, /turf/open/indestructible/reebe_void))
- forceMove(get_turf(NewLoc))
+ var/turf/T = get_turf(NewLoc)
+ if(T.flags_1 & NOJAUNT_1)
+ if(last_failed_turf != T)
+ T.visible_message("[T] suddenly emits a ringing sound!", ignore_mob = src)
+ playsound(T, 'sound/machines/clockcult/ark_damage.ogg', 75, FALSE)
+ last_failed_turf = T
+ to_chat(src, "This turf is consecrated and can't be crossed!")
+ return
+ if(istype(get_area(T), /area/chapel))
+ to_chat(src, "The Chapel is hallowed ground under a heretical deity, and can't be accessed!")
+ return
+ forceMove(T)
Moved(OldLoc, direct)
if(GLOB.ratvar_awakens)
for(var/turf/T in range(5, src))
diff --git a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
index c7aea3df7e..76e942037c 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
@@ -110,7 +110,7 @@
if(!(BI.resistance_flags & ON_FIRE))
BI.fire_act()
continue
- if(is_servant_of_ratvar(L) || (L.disabilities & BLIND) || L.null_rod_check())
+ if(is_servant_of_ratvar(L) || (L.has_disability(BLIND)) || L.null_rod_check())
continue
if(L.stat || L.restrained() || L.buckled || L.lying)
continue
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index ff85499029..98faeae184 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -115,7 +115,7 @@ structure_check() searches for nearby cultist structures required for the invoca
continue
if(ishuman(L))
var/mob/living/carbon/human/H = L
- if((H.disabilities & MUTE) || H.silent)
+ if((H.has_disability(MUTE)) || H.silent)
continue
if(L.stat)
continue
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 1c17893a28..9e2e889047 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -304,7 +304,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
sleep(30)
if(!owner || QDELETED(owner))
return
- priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/AI/aimalf.ogg')
+ priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/ai/aimalf.ogg')
set_security_level("delta")
var/obj/machinery/doomsday_device/DOOM = new(owner_AI)
owner_AI.nuking = TRUE
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 46f96961c9..ef307c95a0 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -524,7 +524,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
var/list/otherwise = M.GetAllContents()
for(var/obj/item/disk/tech_disk/TD in otherwise)
TD.stored_research.copy_research_to(checking)
- return checking.researched_nodes.len >= target
+ return checking.researched_nodes.len >= target_amount
/datum/objective/capture
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 44d6d5abe4..786deaa56a 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -300,6 +300,9 @@
else if(isspaceturf(T))
to_chat(user, "[prob(1) ? "Servant cannot into space." : "You can't teleport into space."]")
return
+ else if(T.flags_1 & NOJAUNT_1)
+ to_chat(user, "This tile is blessed by holy water and deflects the warp.")
+ return
var/area/AR = get_area(T)
if(!AR.clockwork_warp_allowed)
to_chat(user, "[AR.clockwork_warp_fail]")
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index 7814e05138..c4a4d118b3 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -449,7 +449,7 @@
scantemp = "Subject's brain is not responding to scanning stimuli."
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
- if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2))
+ if((mob_occupant.has_disability(NOCLONE)) && (src.scanner.scan_level < 2))
scantemp = "Subject no longer contains the fundamental materials required to create a living clone."
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
return
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index 7bbd545981..67f79f4c52 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -81,7 +81,7 @@
if(connected && connected.is_operational())
if(connected.occupant) //set occupant_status message
viable_occupant = connected.occupant
- if(viable_occupant.has_dna() && (!(RADIMMUNE in viable_occupant.dna.species.species_traits)) && (!(viable_occupant.disabilities & NOCLONE) || (connected.scan_level == 3))) //occupant is viable for dna modification
+ if(viable_occupant.has_dna() && (!(RADIMMUNE in viable_occupant.dna.species.species_traits)) && (!(viable_occupant.has_disability(NOCLONE)) || (connected.scan_level == 3))) //occupant is viable for dna modification
occupant_status += "[viable_occupant.name] => "
switch(viable_occupant.stat)
if(CONSCIOUS)
@@ -528,7 +528,7 @@
var/mob/living/carbon/viable_occupant = null
if(connected)
viable_occupant = connected.occupant
- if(!istype(viable_occupant) || !viable_occupant.dna || (viable_occupant.disabilities & NOCLONE))
+ if(!istype(viable_occupant) || !viable_occupant.dna || (viable_occupant.has_disability(NOCLONE)))
viable_occupant = null
return viable_occupant
diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm
index d1189ff8b8..29df5e4949 100644
--- a/code/game/machinery/dna_scanner.dm
+++ b/code/game/machinery/dna_scanner.dm
@@ -100,7 +100,7 @@
var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
if(istype(mob_occupant))
if(locate_computer(/obj/machinery/computer/cloning))
- if(!mob_occupant.suiciding && !(mob_occupant.disabilities & NOCLONE) && !mob_occupant.hellbound)
+ if(!mob_occupant.suiciding && !(mob_occupant.has_disability(NOCLONE)) && !mob_occupant.hellbound)
mob_occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src)
// DNA manipulators cannot operate on severed heads or brains
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 775c9dd894..3d659f104b 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -251,16 +251,13 @@
note = null
update_icon()
-/obj/machinery/door/airlock/proc/unzap() //for addtimer
- justzap = FALSE
-
/obj/machinery/door/airlock/bumpopen(mob/living/user) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite
if(!issilicon(usr))
if(isElectrified())
if(!justzap)
if(shock(user, 100))
justzap = TRUE
- addtimer(CALLBACK(src, .proc/unzap), 10)
+ addtimer(VARSET_CALLBACK(src, justzap, FALSE) , 10)
return
else
return
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 30ae436289..c7a21bf31b 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -195,7 +195,7 @@
/obj/machinery/door/emp_act(severity)
if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) )
INVOKE_ASYNC(src, .proc/open)
- if(prob(40/severity))
+ if(prob(severity*10 - 20))
if(secondsElectrified == 0)
secondsElectrified = -1
shockedby += "\[[time_stamp()]\]EM Pulse"
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index d3598d4866..427ffa119a 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -25,8 +25,8 @@
integrity_failure = 100
armor = list(melee = 20, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 70)
circuit = /obj/item/circuitboard/machine/vendor
- var/active = 1 //No sales pitches if off!
- var/vend_ready = 1 //Are we ready to vend?? Is it time??
+ var/active = TRUE //No sales pitches if off!
+ var/vend_ready = TRUE //Are we ready to vend?? Is it time??
// To be filled out at compile time
var/list/products = list() //For each, use the following pattern:
@@ -227,15 +227,15 @@
if(!allowed(user) && !emagged && scan_id)
to_chat(user, "[src]'s chef compartment blinks red: Access denied.")
req_access_txt = "0"
- return 0
+ return FALSE
req_access_txt = "0"
- return 1
+ return TRUE
/obj/machinery/vending/snack/proc/iscompartmentfull(mob/user)
if(contents.len >= 30) // no more than 30 dishes can fit inside
to_chat(user, "[src]'s chef compartment is full.")
- return 1
- return 0
+ return TRUE
+ return FALSE
/obj/machinery/vending/snack/proc/food_load(obj/item/reagent_containers/food/snacks/S)
if(dish_quants[S.name])
@@ -350,180 +350,6 @@
/obj/machinery/vending/attack_ai(mob/user)
return attack_hand(user)
-/obj/machinery/vending/attack_hand(mob/user)
- var/dat = ""
- if(panel_open && !isAI(user))
- return wires.interact(user)
- else
- if(stat & (BROKEN|NOPOWER))
- return
-
- dat += "
Select an item
"
- dat += ""
- if(product_records.len == 0)
- dat += "
No product loaded!"
- else
- var/list/display_records = product_records
- if(extended_inventory)
- display_records = product_records + hidden_records
- if(coin || bill)
- display_records = product_records + coin_records
- if((coin || bill) && extended_inventory)
- display_records = product_records + hidden_records + coin_records
- dat += "
"
- for (var/datum/data/vending_product/R in display_records)
- dat += "- "
- if(R.amount > 0)
- dat += "Vend "
- else
- dat += "Sold out "
- dat += "[sanitize(R.product_name)]:"
- dat += " [R.amount]"
- dat += "
"
- dat += "
"
- dat += "
"
- if(premium.len > 0)
- dat += "Change Return: "
- if (coin || bill)
- dat += "[(coin ? coin : "")][(bill ? bill : "")] Remove"
- else
- dat += "No money Remove"
- if(istype(src, /obj/machinery/vending/snack))
- dat += "Chef's Food Selection
"
- dat += ""
- for (var/O in dish_quants)
- if(dish_quants[O] > 0)
- var/N = dish_quants[O]
- dat += "
Dispense "
- dat += "
[capitalize(O)]: [N]"
- dat += "
"
- user.set_machine(src)
- if(seconds_electrified && !(stat & NOPOWER))
- if(shock(user, 100))
- return
-
- var/datum/browser/popup = new(user, "vending", (name))
- popup.set_content(dat)
- popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
- popup.open()
-
-
-/obj/machinery/vending/Topic(href, href_list)
- if(..())
- return
-
- if(href_list["remove_coin"])
- if(!(coin || bill))
- to_chat(usr, "There is no money in this machine.")
- return
- if(coin)
- if(!usr.get_active_held_item())
- usr.put_in_hands(coin)
- else
- coin.forceMove(get_turf(src))
- to_chat(usr, "You remove [coin] from [src].")
- coin = null
- if(bill)
- if(!usr.get_active_held_item())
- usr.put_in_hands(bill)
- else
- bill.forceMove(get_turf(src))
- to_chat(usr, "You remove [bill] from [src].")
- bill = null
-
-
- usr.set_machine(src)
-
- if((href_list["dispense"]) && (vend_ready))
- var/N = href_list["dispense"]
- if(dish_quants[N] <= 0) // Sanity check, there are probably ways to press the button when it shouldn't be possible.
- return
- vend_ready = 0
- use_power(5)
-
- dish_quants[N] = max(dish_quants[N] - 1, 0)
- for(var/obj/O in contents)
- if(O.name == N)
- O.forceMove(drop_location())
- break
- vend_ready = 1
- updateUsrDialog()
- return
-
- if((href_list["vend"]) && (vend_ready))
- if(panel_open)
- to_chat(usr, "The vending machine cannot dispense products while its service panel is open!")
- return
-
- if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
- to_chat(usr, "Access denied." )
- flick(icon_deny,src)
- return
-
- vend_ready = 0 //One thing at a time!!
-
- var/datum/data/vending_product/R = locate(href_list["vend"])
- if(!R || !istype(R) || !R.product_path)
- vend_ready = 1
- return
-
- if(R in hidden_records)
- if(!extended_inventory)
- vend_ready = 1
- return
- else if(R in coin_records)
- if(!(coin || bill))
- to_chat(usr, "You need to insert money to get this item!")
- vend_ready = 1
- return
- if(coin && coin.string_attached)
- if(prob(50))
- if(usr.put_in_hands(coin))
- to_chat(usr, "You successfully pull [coin] out before [src] could swallow it.")
- coin = null
- else
- to_chat(usr, "You couldn't pull [coin] out because your hands are full!")
- QDEL_NULL(coin)
- else
- to_chat(usr, "You weren't able to pull [coin] out fast enough, the machine ate it, string and all!")
- QDEL_NULL(coin)
- else
- QDEL_NULL(coin)
- QDEL_NULL(bill)
-
- else if (!(R in product_records))
- vend_ready = 1
- message_admins("Vending machine exploit attempted by [key_name(usr, usr.client)]!")
- return
-
- if (R.amount <= 0)
- to_chat(usr, "Sold out.")
- vend_ready = 1
- return
- else
- R.amount--
-
- if(((last_reply + 200) <= world.time) && vend_reply)
- speak(vend_reply)
- last_reply = world.time
-
- use_power(5)
- if(icon_vend) //Show the vending animation if needed
- flick(icon_vend,src)
- new R.product_path(get_turf(src))
- SSblackbox.record_feedback("nested tally", "vending_machine_usage", 1, list("[type]", "[R.product_path]"))
- vend_ready = 1
- return
-
- updateUsrDialog()
- return
-
- else if(href_list["togglevoice"] && panel_open)
- shut_up = !shut_up
-
- updateUsrDialog()
-
-
/obj/machinery/vending/process()
if(stat & (BROKEN|NOPOWER))
return
@@ -605,6 +431,96 @@
else
return FALSE
+/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
+ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
+ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "vending", name, 350, 475, master_ui, state)
+ ui.open()
+
+/obj/machinery/vending/ui_data()
+ var/list/data = list()
+ var/list/listed_products = list()
+ var/list/display_records = product_records
+ if(extended_inventory)
+ display_records += hidden_records
+ if(coin)
+ display_records += coin_records
+ for(var/key = 1 to display_records.len)
+ var/datum/data/vending_product/I = display_records[key]
+ listed_products.Add(list(list(
+ "key" = key,
+ "name" = I.product_name,
+ "color" = I.display_color,
+ "amount" = I.amount)))
+ data["products"] = listed_products
+ if(!isnull(coin))
+ data["coin"] = coin.name
+ data["coinslot"] = premium.len
+ data["canvend"] = vend_ready
+
+ return data
+
+/obj/machinery/vending/ui_act(action, params)
+ if(..())
+ return
+ if(!vend_ready)
+ return
+ switch(action)
+ if("vend")
+ if(!allowed(usr) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
+ to_chat(usr, "Access denied.")
+ flick(icon_deny,src)
+ return
+ vend_ready = FALSE
+ addtimer(VARSET_CALLBACK(src, vend_ready, TRUE), 10)
+ var/key = text2num(params["key"])
+ var/datum/data/vending_product/R = product_records[key]
+ if(R in hidden_records)
+ if(!extended_inventory)
+ return
+ else if(R in coin_records)
+ if(!coin)
+ to_chat(usr, "You need to insert a coin to get this item!")
+ return
+ if(coin.string_attached)
+ if(prob(50))
+ if(usr.put_in_hands(coin))
+ to_chat(usr, "You successfully pull [coin] out before [src] could swallow it.")
+ coin = null
+ else
+ to_chat(usr, "You couldn't pull [coin] out because your hands are full!")
+ QDEL_NULL(coin)
+ else
+ to_chat(usr, "You weren't able to pull [coin] out fast enough, the machine ate it, string and all!")
+ QDEL_NULL(coin)
+ else
+ QDEL_NULL(coin)
+ else if (!(R in product_records))
+ return
+
+
+
+ if (R.amount <= 0)
+ to_chat(usr, "Sold out.")
+ return
+ R.amount--
+ if(((last_reply + 200) <= world.time) && vend_reply)
+ speak(vend_reply)
+ last_reply = world.time
+ use_power(5)
+ if(icon_vend) //Show the vending animation if needed
+ flick(icon_vend,src)
+ new R.product_path(drop_location())
+ return TRUE
+ if("eject")
+ if(!coin)
+ to_chat(usr, "There is no coin in this machine.")
+ return
+ usr.put_in_hands(coin)
+ to_chat(usr, "You remove [coin] from [src].")
+ coin = null
+
/*
* Vending machine types
*/
@@ -1195,4 +1111,4 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
#undef STANDARD_CHARGE
#undef CONTRABAND_CHARGE
-#undef COIN_CHARGE
\ No newline at end of file
+#undef COIN_CHARGE
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index caeb1f168c..2708e78535 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -16,7 +16,7 @@
/obj/effect/landmark/start
name = "start"
- icon = 'icons/mob/screen_gen.dmi'
+ icon = 'icons/mob/landmarks.dmi'
icon_state = "x"
anchored = TRUE
var/jobspawn_override = FALSE
@@ -40,9 +40,9 @@
// START LANDMARKS FOLLOW. Don't change the names unless
// you are refactoring shitty landmark code.
-
/obj/effect/landmark/start/assistant
name = "Assistant"
+ icon_state = "Assistant"
/obj/effect/landmark/start/assistant/override
jobspawn_override = TRUE
@@ -50,102 +50,135 @@
/obj/effect/landmark/start/janitor
name = "Janitor"
+ icon_state = "Janitor"
/obj/effect/landmark/start/cargo_technician
name = "Cargo Technician"
+ icon_state = "Cargo Technician"
/obj/effect/landmark/start/bartender
name = "Bartender"
+ icon_state = "Bartender"
/obj/effect/landmark/start/clown
name = "Clown"
+ icon_state = "Clown"
/obj/effect/landmark/start/mime
name = "Mime"
+ icon_state = "Mime"
/obj/effect/landmark/start/quartermaster
name = "Quartermaster"
+ icon_state = "Quartermaster"
/obj/effect/landmark/start/atmospheric_technician
name = "Atmospheric Technician"
+ icon_state = "Atmospheric Technician"
/obj/effect/landmark/start/cook
name = "Cook"
+ icon_state = "Cook"
/obj/effect/landmark/start/shaft_miner
name = "Shaft Miner"
+ icon_state = "Shaft Miner"
/obj/effect/landmark/start/security_officer
name = "Security Officer"
+ icon_state = "Security Officer"
/obj/effect/landmark/start/botanist
name = "Botanist"
+ icon_state = "Botanist"
/obj/effect/landmark/start/head_of_security
name = "Head of Security"
-
-/obj/effect/landmark/start/ai
- name = "AI"
- delete_after_roundstart = FALSE
+ icon_state = "Head of Security"
/obj/effect/landmark/start/captain
name = "Captain"
+ icon_state = "Captain"
/obj/effect/landmark/start/detective
name = "Detective"
+ icon_state = "Detective"
/obj/effect/landmark/start/warden
name = "Warden"
+ icon_state = "Warden"
/obj/effect/landmark/start/chief_engineer
name = "Chief Engineer"
-
-/obj/effect/landmark/start/cyborg
- name = "Cyborg"
+ icon_state = "Chief Engineer"
/obj/effect/landmark/start/head_of_personnel
name = "Head of Personnel"
+ icon_state = "Head of Personnel"
/obj/effect/landmark/start/librarian
name = "Curator"
+ icon_state = "Curator"
/obj/effect/landmark/start/lawyer
name = "Lawyer"
+ icon_state = "Lawyer"
/obj/effect/landmark/start/station_engineer
name = "Station Engineer"
+ icon_state = "Station Engineer"
/obj/effect/landmark/start/medical_doctor
name = "Medical Doctor"
+ icon_state = "Medical Doctor"
/obj/effect/landmark/start/scientist
name = "Scientist"
+ icon_state = "Scientist"
/obj/effect/landmark/start/chemist
name = "Chemist"
+ icon_state = "Chemist"
/obj/effect/landmark/start/roboticist
name = "Roboticist"
+ icon_state = "Roboticist"
/obj/effect/landmark/start/research_director
name = "Research Director"
+ icon_state = "Research Director"
/obj/effect/landmark/start/geneticist
name = "Geneticist"
+ icon_state = "Geneticist"
/obj/effect/landmark/start/chief_medical_officer
name = "Chief Medical Officer"
+ icon_state = "Chief Medical Officer"
/obj/effect/landmark/start/virologist
name = "Virologist"
+ icon_state = "Virologist"
/obj/effect/landmark/start/chaplain
name = "Chaplain"
+ icon_state = "Chaplain"
+
+/obj/effect/landmark/start/cyborg
+ name = "Cyborg"
+ icon_state = "Cyborg"
+
+/obj/effect/landmark/start/ai
+ name = "AI"
+ icon_state = "AI"
+ delete_after_roundstart = FALSE
+
//Department Security spawns
/obj/effect/landmark/start/depsec
name = "department_sec"
+ icon_state = "Security Officer"
/obj/effect/landmark/start/depsec/New()
..()
diff --git a/code/game/objects/effects/temporary_visuals/projectile_beam.dm b/code/game/objects/effects/temporary_visuals/projectile_beam.dm
new file mode 100644
index 0000000000..8918dc8e27
--- /dev/null
+++ b/code/game/objects/effects/temporary_visuals/projectile_beam.dm
@@ -0,0 +1,70 @@
+/proc/generate_projectile_beam_between_points(datum/point/starting, datum/point/ending, beam_type, color, qdel_in = 5) //Do not pass z-crossing points as that will not be properly (and likely will never be properly until it's absolutely needed) supported!
+ if(!istype(starting) || !istype(ending) || !ispath(beam_type))
+ return
+ var/datum/point/midpoint = point_midpoint_points(starting, ending)
+ var/obj/effect/projectile_beam/PB = new beam_type
+ PB.apply_vars(angle_between_points(starting, ending), midpoint.return_px(), midpoint.return_py(), color, pixel_length_between_points(starting, ending) / world.icon_size, midpoint.return_turf(), 0)
+ . = PB
+ if(qdel_in)
+ QDEL_IN(PB, qdel_in)
+
+/obj/effect/projectile_beam
+ icon = 'icons/obj/projectiles.dmi'
+ layer = ABOVE_MOB_LAYER
+ anchored = TRUE
+ light_power = 1
+ light_range = 2
+ light_color = "#00ffff"
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ flags_1 = ABSTRACT_1
+ appearance_flags = 0
+
+/obj/effect/projectile_beam/singularity_pull()
+ return
+
+/obj/effect/projectile_beam/singularity_act()
+ return
+
+/obj/effect/projectile_beam/proc/scale_to(nx,ny,override=TRUE)
+ var/matrix/M
+ if(!override)
+ M = transform
+ else
+ M = new
+ M.Scale(nx,ny)
+ transform = M
+
+/obj/effect/projectile_beam/proc/turn_to(angle,override=TRUE)
+ var/matrix/M
+ if(!override)
+ M = transform
+ else
+ M = new
+ M.Turn(angle)
+ transform = M
+
+/obj/effect/projectile_beam/New(angle_override, p_x, p_y, color_override, scaling = 1)
+ if(angle_override && p_x && p_y && color_override && scaling)
+ apply_vars(angle_override, p_x, p_y, color_override, scaling)
+ return ..()
+
+/obj/effect/projectile_beam/proc/apply_vars(angle_override, p_x = 0, p_y = 0, color_override, scaling = 1, new_loc, increment = 0)
+ var/mutable_appearance/look = new(src)
+ look.pixel_x = p_x
+ look.pixel_y = p_y
+ if(color_override)
+ look.color = color_override
+ appearance = look
+ scale_to(1,scaling, FALSE)
+ turn_to(angle_override, FALSE)
+ if(!isnull(new_loc)) //If you want to null it just delete it...
+ forceMove(new_loc)
+ for(var/i in 1 to increment)
+ pixel_x += round((sin(angle_override)+16*sin(angle_override)*2), 1)
+ pixel_y += round((cos(angle_override)+16*cos(angle_override)*2), 1)
+
+/obj/effect/projectile_beam/tracer
+ icon_state = "tracer_beam"
+
+/obj/effect/projectile_beam/tracer/aiming
+ icon_state = "gbeam"
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 823a91cead..1cca673778 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -539,9 +539,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.adjust_blurriness(15)
if(M.stat != DEAD)
to_chat(M, "Your eyes start to bleed profusely!")
- if(!(M.disabilities & (NEARSIGHT | BLIND)))
- if(M.become_nearsighted())
- to_chat(M, "You become nearsighted!")
+ if(!(M.has_disability(BLIND) || M.has_disability(NEARSIGHT)))
+ to_chat(M, "You become nearsighted!")
+ M.become_nearsighted(EYE_DAMAGE)
if(prob(50))
if(M.stat != DEAD)
if(M.drop_all_held_items())
@@ -550,8 +550,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.Unconscious(20)
M.Knockdown(40)
if (prob(eyes.eye_damage - 10 + 1))
- if(M.become_blind())
- to_chat(M, "You go blind!")
+ M.become_blind(EYE_DAMAGE)
+ to_chat(M, "You go blind!")
/obj/item/clean_blood()
. = ..()
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index 25fbb49c9b..a43691cc7b 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -393,7 +393,7 @@
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/human/H)
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
- return (!H.suiciding && !(H.disabilities & NOCLONE) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
+ return (!H.suiciding && !(H.has_disability(NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
if(isliving(H.pulledby)) //CLEAR!
@@ -514,7 +514,7 @@
shock_touching(30, H)
var/failed
- if (H.suiciding || (H.disabilities & NOCLONE))
+ if (H.suiciding || (H.has_disability(NOCLONE)))
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile."
else if (H.hellbound)
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existence. Further attempts futile."
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index f656d55afd..7a40d8f3a2 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -48,7 +48,7 @@
add_fingerprint(user)
if(istype(M) && on && user.zone_selected in list("eyes", "mouth"))
- if((user.disabilities & (CLUMSY | DUMB)) && prob(50)) //too dumb to use flashlight properly
+ if((user.has_disability(CLUMSY) || user.has_disability(DUMB)) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
if(!user.IsAdvancedToolUser())
@@ -82,7 +82,7 @@
else
user.visible_message("[user] directs [src] to [M]'s eyes.", \
"You direct [src] to [M]'s eyes.")
- if(M.stat == DEAD || (M.disabilities & BLIND) || !M.flash_act(visual = 1)) //mob is dead or fully blind
+ if(M.stat == DEAD || (M.has_disability(BLIND)) || !M.flash_act(visual = 1)) //mob is dead or fully blind
to_chat(user, "[M]'s pupils don't react to the light!")
else if(M.dna && M.dna.check_mutation(XRAY)) //mob has X-RAY vision
to_chat(user, "[M]'s pupils give an eerie glow!")
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 9a60bb0edb..6e67ca886b 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -85,7 +85,7 @@ GAS ANALYZER
/obj/item/device/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user)
// Clumsiness/brain damage check
- if ((user.disabilities & (CLUMSY | DUMB)) && prob(50))
+ if ((user.has_disability(CLUMSY) || user.has_disability(DUMB)) && prob(50))
to_chat(user, "You stupidly try to analyze the floor's vitals!")
user.visible_message("[user] has analyzed the floor's vitals!")
to_chat(user, "Analyzing results for The floor:\n\tOverall status: Healthy")
@@ -181,9 +181,12 @@ GAS ANALYZER
to_chat(user, "\t==EAR STATUS==")
if(istype(ears))
var/healthy = TRUE
- if(C.disabilities & DEAF)
+ if(C.has_disability(DEAF, GENETIC_MUTATION))
healthy = FALSE
to_chat(user, "\tSubject is genetically deaf.")
+ else if(C.has_disability(DEAF))
+ healthy = FALSE
+ to_chat(user, "\tSubject is deaf.")
else
if(ears.ear_damage)
to_chat(user, "\tSubject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage.")
@@ -199,10 +202,10 @@ GAS ANALYZER
to_chat(user, "\t==EYE STATUS==")
if(istype(eyes))
var/healthy = TRUE
- if(C.disabilities & BLIND)
+ if(C.has_disability(BLIND))
to_chat(user, "\tSubject is blind.")
healthy = FALSE
- if(C.disabilities & NEARSIGHT)
+ if(C.has_disability(NEARSIGHT))
to_chat(user, "\tSubject is nearsighted.")
healthy = FALSE
if(eyes.eye_damage > 30)
diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm
index 9644d827ea..19008b43a6 100644
--- a/code/game/objects/items/dna_injector.dm
+++ b/code/game/objects/items/dna_injector.dm
@@ -31,7 +31,7 @@
/obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
prepare()
- if(M.has_dna() && !(RADIMMUNE in M.dna.species.species_traits) && !(M.disabilities & NOCLONE))
+ if(M.has_dna() && !(RADIMMUNE in M.dna.species.species_traits) && !(M.has_disability(NOCLONE)))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/datum/mutation/human/HM in remove_mutations)
@@ -313,7 +313,7 @@
to_chat(user, "You can't modify [M]'s DNA while [M.p_theyre()] dead.")
return FALSE
- if(M.has_dna() && !(M.disabilities & NOCLONE))
+ if(M.has_dna() && !(M.has_disability(NOCLONE)))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
var/endtime = world.time+duration
diff --git a/code/game/objects/items/gift.dm b/code/game/objects/items/gift.dm
index 1e3e9ccd73..0fe53f293c 100644
--- a/code/game/objects/items/gift.dm
+++ b/code/game/objects/items/gift.dm
@@ -7,6 +7,9 @@
/*
* Gifts
*/
+
+GLOBAL_LIST_EMPTY(possible_gifts)
+
/obj/item/a_gift
name = "gift"
desc = "PRESENTS!!!! eek!"
@@ -30,6 +33,14 @@
to_chat(M, "You're supposed to be spreading gifts, not opening them yourself!")
return
+ var/gift_type = get_gift_type()
+
+ qdel(src)
+ var/obj/item/I = new gift_type(M)
+ M.put_in_hands(I)
+ I.add_fingerprint(M)
+
+/obj/item/a_gift/proc/get_gift_type()
var/gift_type_list = list(/obj/item/sord,
/obj/item/storage/wallet,
/obj/item/storage/photo_album,
@@ -72,10 +83,21 @@
var/gift_type = pick(gift_type_list)
- if(!ispath(gift_type, /obj/item))
- return
+ return gift_type
- qdel(src)
- var/obj/item/I = new gift_type(M)
- M.put_in_hands(I)
- I.add_fingerprint(M)
+
+/obj/item/a_gift/anything
+ name = "christmas gift"
+ desc = "It could be anything!"
+
+/obj/item/a_gift/anything/get_gift_type()
+ if(!GLOB.possible_gifts.len)
+ var/list/gift_types_list = subtypesof(/obj/item)
+ for(var/V in gift_types_list)
+ var/obj/item/I = V
+ if((!initial(I.icon_state)) || (!initial(I.item_state)) || (initial(I.flags_1) & ABSTRACT_1))
+ gift_types_list -= V
+ GLOB.possible_gifts = gift_types_list
+ var/gift_type = pick(GLOB.possible_gifts)
+
+ return gift_type
diff --git a/code/game/objects/items/grenades/grenade.dm b/code/game/objects/items/grenades/grenade.dm
index e444ecce25..257007aba9 100644
--- a/code/game/objects/items/grenades/grenade.dm
+++ b/code/game/objects/items/grenades/grenade.dm
@@ -24,7 +24,7 @@
qdel(src)
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
- if(user.disabilities & CLUMSY && prob(50))
+ if(user.has_disability(CLUMSY) && prob(50))
to_chat(user, "Huh? How does this thing work?")
preprime(user, 5, FALSE)
return FALSE
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index 886a248c8c..1dd2b1b1de 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -26,7 +26,7 @@
/obj/item/restraints/handcuffs/attack(mob/living/carbon/C, mob/living/carbon/human/user)
if(!istype(C))
return
- if(user.disabilities & CLUMSY && prob(50))
+ if(user.has_disability(CLUMSY) && prob(50))
to_chat(user, "Uh... how do those things work?!")
apply_cuffs(user,user)
return
diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm
index 5a8fcda09b..0a9e356014 100644
--- a/code/game/objects/items/kitchen.dm
+++ b/code/game/objects/items/kitchen.dm
@@ -44,7 +44,7 @@
forkload = null
else if(user.zone_selected == "eyes")
- if(user.disabilities & CLUMSY && prob(50))
+ if(user.has_disability(CLUMSY) && prob(50))
M = user
return eyestab(M,user)
else
@@ -70,7 +70,7 @@
/obj/item/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user)
if(user.zone_selected == "eyes")
- if(user.disabilities & CLUMSY && prob(50))
+ if(user.has_disability(CLUMSY) && prob(50))
M = user
return eyestab(M,user)
else
diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm
index 6e21251b6e..6fb173b905 100644
--- a/code/game/objects/items/melee/misc.dm
+++ b/code/game/objects/items/melee/misc.dm
@@ -99,7 +99,7 @@
return ..()
add_fingerprint(user)
- if((CLUMSY in user.disabilities) && prob(50))
+ if((user.has_disability(CLUMSY)) && prob(50))
to_chat(user, "You club yourself over the head.")
user.Knockdown(60 * force)
if(ishuman(user))
diff --git a/code/game/objects/items/melee/transforming.dm b/code/game/objects/items/melee/transforming.dm
index b63c5bcefa..94f7de09bc 100644
--- a/code/game/objects/items/melee/transforming.dm
+++ b/code/game/objects/items/melee/transforming.dm
@@ -72,6 +72,6 @@
to_chat(user, "[src] [active ? "is now active":"can now be concealed"].")
/obj/item/melee/transforming/proc/clumsy_transform_effect(mob/living/user)
- if(user.disabilities & CLUMSY && prob(50))
+ if(user.has_disability(CLUMSY) && prob(50))
to_chat(user, "You accidentally cut yourself with [src], like a doofus!")
user.take_bodypart_damage(5,5)
diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm
index 57306f498c..113bc9755c 100644
--- a/code/game/objects/items/shields.dm
+++ b/code/game/objects/items/shields.dm
@@ -1,142 +1,142 @@
-/obj/item/shield
- name = "shield"
- block_chance = 50
- armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 80, acid = 70)
-
-/obj/item/shield/riot
- name = "riot shield"
- desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
- icon = 'icons/obj/items_and_weapons.dmi'
- icon_state = "riot"
- lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
- slot_flags = SLOT_BACK
- force = 10
- throwforce = 5
- throw_speed = 2
- throw_range = 3
- w_class = WEIGHT_CLASS_BULKY
- materials = list(MAT_GLASS=7500, MAT_METAL=1000)
- attack_verb = list("shoved", "bashed")
- var/cooldown = 0 //shield bash cooldown. based on world.time
-
-
-/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/melee/baton))
- if(cooldown < world.time - 25)
- user.visible_message("[user] bashes [src] with [W]!")
- playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
- cooldown = world.time
- else
- return ..()
-
-/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(attack_type == THROWN_PROJECTILE_ATTACK)
- final_block_chance += 30
- if(attack_type == LEAP_ATTACK)
- final_block_chance = 100
- return ..()
-
-/obj/item/shield/riot/roman
- name = "roman shield"
- desc = "Bears an inscription on the inside: \"Romanes venio domus\"."
- icon_state = "roman_shield"
- item_state = "roman_shield"
- lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
-
-/obj/item/shield/riot/buckler
- name = "wooden buckler"
- desc = "A medieval wooden buckler."
- icon_state = "buckler"
- item_state = "buckler"
- lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
- materials = list()
- resistance_flags = FLAMMABLE
- block_chance = 30
-
-/obj/item/shield/energy
- name = "energy combat shield"
- desc = "A shield capable of stopping most melee attacks. Protects user from almost all energy projectiles. It can be retracted, expanded, and stored anywhere."
- icon = 'icons/obj/items_and_weapons.dmi'
- icon_state = "eshield0" // eshield1 for expanded
- lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
- force = 3
- throwforce = 3
- throw_speed = 3
- throw_range = 5
- w_class = WEIGHT_CLASS_TINY
- attack_verb = list("shoved", "bashed")
- var/active = 0
-
-/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- return 0
-
-/obj/item/shield/energy/IsReflect()
- return (active)
-
-/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
- if(user.disabilities & CLUMSY && prob(50))
- to_chat(user, "You beat yourself in the head with [src].")
- user.take_bodypart_damage(5)
- active = !active
- icon_state = "eshield[active]"
-
- if(active)
- force = 10
- throwforce = 8
- throw_speed = 2
- w_class = WEIGHT_CLASS_BULKY
- playsound(user, 'sound/weapons/saberon.ogg', 35, 1)
- to_chat(user, "[src] is now active.")
- else
- force = 3
- throwforce = 3
- throw_speed = 3
- w_class = WEIGHT_CLASS_TINY
- playsound(user, 'sound/weapons/saberoff.ogg', 35, 1)
- to_chat(user, "[src] can now be concealed.")
- add_fingerprint(user)
-
-/obj/item/shield/riot/tele
- name = "telescopic shield"
- desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
- icon = 'icons/obj/items_and_weapons.dmi'
- icon_state = "teleriot0"
- lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
- slot_flags = null
- force = 3
- throwforce = 3
- throw_speed = 3
- throw_range = 4
- w_class = WEIGHT_CLASS_NORMAL
- var/active = 0
-
-/obj/item/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(active)
- return ..()
- return 0
-
-/obj/item/shield/riot/tele/attack_self(mob/living/user)
- active = !active
- icon_state = "teleriot[active]"
- playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1)
-
- if(active)
- force = 8
- throwforce = 5
- throw_speed = 2
- w_class = WEIGHT_CLASS_BULKY
- slot_flags = SLOT_BACK
- to_chat(user, "You extend \the [src].")
- else
- force = 3
- throwforce = 3
- throw_speed = 3
- w_class = WEIGHT_CLASS_NORMAL
- slot_flags = null
- to_chat(user, "[src] can now be concealed.")
- add_fingerprint(user)
+/obj/item/shield
+ name = "shield"
+ block_chance = 50
+ armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 80, acid = 70)
+
+/obj/item/shield/riot
+ name = "riot shield"
+ desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
+ icon = 'icons/obj/items_and_weapons.dmi'
+ icon_state = "riot"
+ lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
+ slot_flags = SLOT_BACK
+ force = 10
+ throwforce = 5
+ throw_speed = 2
+ throw_range = 3
+ w_class = WEIGHT_CLASS_BULKY
+ materials = list(MAT_GLASS=7500, MAT_METAL=1000)
+ attack_verb = list("shoved", "bashed")
+ var/cooldown = 0 //shield bash cooldown. based on world.time
+
+
+/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/melee/baton))
+ if(cooldown < world.time - 25)
+ user.visible_message("[user] bashes [src] with [W]!")
+ playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
+ cooldown = world.time
+ else
+ return ..()
+
+/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(attack_type == THROWN_PROJECTILE_ATTACK)
+ final_block_chance += 30
+ if(attack_type == LEAP_ATTACK)
+ final_block_chance = 100
+ return ..()
+
+/obj/item/shield/riot/roman
+ name = "roman shield"
+ desc = "Bears an inscription on the inside: \"Romanes venio domus\"."
+ icon_state = "roman_shield"
+ item_state = "roman_shield"
+ lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
+
+/obj/item/shield/riot/buckler
+ name = "wooden buckler"
+ desc = "A medieval wooden buckler."
+ icon_state = "buckler"
+ item_state = "buckler"
+ lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
+ materials = list()
+ resistance_flags = FLAMMABLE
+ block_chance = 30
+
+/obj/item/shield/energy
+ name = "energy combat shield"
+ desc = "A shield capable of stopping most melee attacks. Protects user from almost all energy projectiles. It can be retracted, expanded, and stored anywhere."
+ icon = 'icons/obj/items_and_weapons.dmi'
+ icon_state = "eshield0" // eshield1 for expanded
+ lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
+ force = 3
+ throwforce = 3
+ throw_speed = 3
+ throw_range = 5
+ w_class = WEIGHT_CLASS_TINY
+ attack_verb = list("shoved", "bashed")
+ var/active = 0
+
+/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ return 0
+
+/obj/item/shield/energy/IsReflect()
+ return (active)
+
+/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
+ if(user.has_disability(CLUMSY) && prob(50))
+ to_chat(user, "You beat yourself in the head with [src].")
+ user.take_bodypart_damage(5)
+ active = !active
+ icon_state = "eshield[active]"
+
+ if(active)
+ force = 10
+ throwforce = 8
+ throw_speed = 2
+ w_class = WEIGHT_CLASS_BULKY
+ playsound(user, 'sound/weapons/saberon.ogg', 35, 1)
+ to_chat(user, "[src] is now active.")
+ else
+ force = 3
+ throwforce = 3
+ throw_speed = 3
+ w_class = WEIGHT_CLASS_TINY
+ playsound(user, 'sound/weapons/saberoff.ogg', 35, 1)
+ to_chat(user, "[src] can now be concealed.")
+ add_fingerprint(user)
+
+/obj/item/shield/riot/tele
+ name = "telescopic shield"
+ desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
+ icon = 'icons/obj/items_and_weapons.dmi'
+ icon_state = "teleriot0"
+ lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
+ slot_flags = null
+ force = 3
+ throwforce = 3
+ throw_speed = 3
+ throw_range = 4
+ w_class = WEIGHT_CLASS_NORMAL
+ var/active = 0
+
+/obj/item/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(active)
+ return ..()
+ return 0
+
+/obj/item/shield/riot/tele/attack_self(mob/living/user)
+ active = !active
+ icon_state = "teleriot[active]"
+ playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1)
+
+ if(active)
+ force = 8
+ throwforce = 5
+ throw_speed = 2
+ w_class = WEIGHT_CLASS_BULKY
+ slot_flags = SLOT_BACK
+ to_chat(user, "You extend \the [src].")
+ else
+ force = 3
+ throwforce = 3
+ throw_speed = 3
+ w_class = WEIGHT_CLASS_NORMAL
+ slot_flags = null
+ to_chat(user, "[src] can now be concealed.")
+ add_fingerprint(user)
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 5e80353db9..cef25a0a36 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -109,7 +109,7 @@
if (recipes_sublist && recipe_list[recipes_sublist] && istype(recipe_list[recipes_sublist], /datum/stack_recipe_list))
var/datum/stack_recipe_list/srl = recipe_list[recipes_sublist]
recipe_list = srl.recipes
- var/t1 = "Amount Left: [amount]
"
+ var/t1 = "Amount Left: [get_amount()]
"
for(var/i in 1 to length(recipe_list))
var/E = recipe_list[i]
if (isnull(E))
@@ -161,8 +161,8 @@
if (href_list["sublist"] && !href_list["make"])
interact(usr, text2num(href_list["sublist"]))
if (href_list["make"])
- if (get_amount() < 1)
- qdel(src) //Never should happen
+ if (get_amount() < 1 && !is_cyborg)
+ qdel(src)
var/list/recipes_list = recipes
if (href_list["sublist"])
diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm
index ef04fc48f5..a06d1a509e 100644
--- a/code/game/objects/items/storage/book.dm
+++ b/code/game/objects/items/storage/book.dm
@@ -94,7 +94,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
to_chat(user, "You don't have the dexterity to do this!")
return
- if (user.disabilities & CLUMSY && prob(50))
+ if (user.has_disability(CLUMSY) && prob(50))
to_chat(user, "[src] slips out of your hand and hits your head.")
user.take_bodypart_damage(10)
user.Unconscious(400)
diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm
index ab82f92c2d..128a313525 100644
--- a/code/game/objects/items/stunbaton.dm
+++ b/code/game/objects/items/stunbaton.dm
@@ -108,7 +108,7 @@
add_fingerprint(user)
/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user)
- if(status && user.disabilities & CLUMSY && prob(50))
+ if(status && user.has_disability(CLUMSY) && prob(50))
user.visible_message("[user] accidentally hits themself with [src]!", \
"You accidentally hit yourself with [src]!")
user.Knockdown(stunforce*3)
diff --git a/code/game/objects/items/teleprod.dm b/code/game/objects/items/teleprod.dm
index 92e7a8e9ba..c780d32917 100644
--- a/code/game/objects/items/teleprod.dm
+++ b/code/game/objects/items/teleprod.dm
@@ -8,7 +8,7 @@
/obj/item/melee/baton/cattleprod/teleprod/attack(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit
..()
- if(status && user.disabilities & CLUMSY && prob(50))
+ if(status && user.has_disability(CLUMSY) && prob(50))
user.visible_message("[user] accidentally hits themself with [src]!", \
"You accidentally hit yourself with [src]!")
if(do_teleport(user, get_turf(user), 50))//honk honk
diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm
index 08f22b7e46..8fd37a3b38 100644
--- a/code/game/objects/items/tools/screwdriver.dm
+++ b/code/game/objects/items/tools/screwdriver.dm
@@ -75,7 +75,7 @@
return ..()
if(user.zone_selected != "eyes" && user.zone_selected != "head")
return ..()
- if(user.disabilities & CLUMSY && prob(50))
+ if(user.has_disability(CLUMSY) && prob(50))
M = user
return eyestab(M,user)
@@ -105,7 +105,7 @@
item_state = "drill"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
- materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
//done for balance reasons, making them high value for research, but harder to get
+ materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) //done for balance reasons, making them high value for research, but harder to get
force = 8 //might or might not be too high, subject to change
w_class = WEIGHT_CLASS_SMALL
throwforce = 8
diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm
index 58758668c3..293ef46197 100644
--- a/code/game/objects/items/twohanded.dm
+++ b/code/game/objects/items/twohanded.dm
@@ -302,7 +302,7 @@
unwield()
return
..()
- if(user.disabilities & CLUMSY && (wielded) && prob(40))
+ if(user.has_disability(CLUMSY) && (wielded) && prob(40))
impale(user)
return
if((wielded) && prob(50))
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index f7071cd0a5..393ff3886d 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -36,9 +36,6 @@
else
return ..()
-
-
-
/obj/structure/flora/tree/pine
name = "pine tree"
desc = "A coniferous pine tree."
@@ -53,6 +50,21 @@
name = "xmas tree"
desc = "A wondrous decorated Christmas tree."
icon_state = "pine_c"
+ var/gifts_under_tree = FALSE
+ var/list/ckeys_that_took = list()
+
+/obj/structure/flora/tree/pine/xmas/attack_hand(mob/living/user)
+ if(!gifts_under_tree)
+ return
+ if(!user.ckey)
+ return
+ if(ckeys_that_took[user.ckey])
+ to_chat(user, "You already took your gift.")
+ return
+ to_chat(user, "After a bit of rummaging, you locate a gift with your name on it!")
+ ckeys_that_took[user.ckey] = TRUE
+ var/obj/item/a_gift/anything/A = new
+ user.put_in_hands(A)
/obj/structure/flora/tree/pine/xmas/Initialize()
. = ..()
diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm
index 36233bc155..d2bee1af36 100644
--- a/code/game/objects/structures/petrified_statue.dm
+++ b/code/game/objects/structures/petrified_statue.dm
@@ -17,7 +17,7 @@
L.buckled.unbuckle_mob(L,force=1)
L.visible_message("[L]'s skin rapidly turns to marble!", "Your body freezes up! Can't... move... can't... think...")
L.forceMove(src)
- L.disabilities |= MUTE
+ L.add_disability(MUTE, STATUE_MUTE)
L.faction += "mimic" //Stops mimics from instaqdeling people in statues
L.status_flags |= GODMODE
obj_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues
@@ -59,7 +59,7 @@
if(petrified_mob)
petrified_mob.status_flags &= ~GODMODE
petrified_mob.forceMove(loc)
- petrified_mob.disabilities &= ~MUTE
+ petrified_mob.remove_disability(MUTE, STATUE_MUTE)
petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob
petrified_mob.faction -= "mimic"
petrified_mob = null
diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm
index 1ae513f847..a8ca42bff5 100644
--- a/code/game/objects/structures/reflector.dm
+++ b/code/game/objects/structures/reflector.dm
@@ -202,7 +202,7 @@
var/new_angle = WRAP(rotation_angle + norm_inc, 180, -180)
if(ISINRANGE_EX(norm_inc, -90, 90))
return FALSE
- P.Angle = new_angle
+ P.setAngle(new_angle)
return ..()
//DOUBLE
@@ -229,7 +229,7 @@
var/new_angle = WRAP(rotation_angle + norm_inc, 180, -180)
if(ISINRANGE_EX(norm_inc, -90, 90))
new_angle += 180
- P.Angle = new_angle
+ P.setAngle(new_angle)
return ..()
//BOX
@@ -251,7 +251,7 @@
anchored = TRUE
/obj/structure/reflector/box/auto_reflect(obj/item/projectile/P)
- P.Angle = rotation_angle
+ P.setAngle(rotation_angle)
return ..()
/obj/structure/reflector/ex_act()
diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm
index 3e7540cdf6..634767c98b 100644
--- a/code/game/turfs/simulated/floor/misc_floor.dm
+++ b/code/game/turfs/simulated/floor/misc_floor.dm
@@ -146,6 +146,9 @@
var/uses_overlay = TRUE
var/obj/effect/clockwork/overlay/floor/realappearence
+/turf/open/floor/clockwork/Bless() //Who needs holy blessings when you have DADDY RATVAR?
+ return
+
/turf/open/floor/clockwork/Initialize()
. = ..()
if(uses_overlay)
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 00377e4f3f..14b7ef74b5 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -61,7 +61,7 @@
new_angle_s -= 360
while(new_angle_s < -180)
new_angle_s += 360
- P.Angle = new_angle_s
+ P.setAngle(new_angle_s)
return TRUE
/turf/closed/wall/proc/dismantle_wall(devastated=0, explode=0)
diff --git a/code/game/world.dm b/code/game/world.dm
index 2853bb2ef6..39d48d28ac 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -251,3 +251,4 @@ GLOBAL_PROTECT(security_mode)
hub_password = "kMZy3U5jJHSiBQjr"
else
hub_password = "SORRYNOPASSWORD"
+
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index e2bb78c9ec..daa1d58de5 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -107,6 +107,8 @@ GLOBAL_VAR(LastAdminCalledTarget)
GLOBAL_PROTECT(LastAdminCalledTarget)
GLOBAL_VAR(LastAdminCalledProc)
GLOBAL_PROTECT(LastAdminCalledProc)
+GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
+GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/proc/WrapAdminProcCall(target, procname, list/arguments)
var/current_caller = GLOB.AdminProcCaller
@@ -114,9 +116,14 @@ GLOBAL_PROTECT(LastAdminCalledProc)
if(!ckey)
CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]")
if(current_caller && current_caller != ckey)
- to_chat(usr, "Another set of admin called procs are still running, your proc will be run after theirs finish.")
- UNTIL(!GLOB.AdminProcCaller)
- to_chat(usr, "Running your proc")
+ if(!GLOB.AdminProcCallSpamPrevention[ckey])
+ to_chat(usr, "Another set of admin called procs are still running, your proc will be run after theirs finish.")
+ GLOB.AdminProcCallSpamPrevention[ckey] = TRUE
+ UNTIL(!GLOB.AdminProcCaller)
+ to_chat(usr, "Running your proc")
+ GLOB.AdminProcCallSpamPrevention -= ckey
+ else
+ UNTIL(!GLOB.AdminProcCaller)
GLOB.LastAdminCalledProc = procname
if(target != GLOBAL_PROC)
GLOB.LastAdminCalledTargetRef = "[REF(target)]"
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 5d0c2fe833..dcb9137416 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -45,7 +45,8 @@ GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
/client/proc/manipulate_organs,
/client/proc/start_line_profiling,
/client/proc/stop_line_profiling,
- /client/proc/show_line_profiling
+ /client/proc/show_line_profiling,
+ /client/proc/create_mapping_job_icons
))
/obj/effect/debugging/mapfix_marker
@@ -265,3 +266,31 @@ GLOBAL_VAR_INIT(say_disabled, FALSE)
message_admins("[src.ckey] used 'Disable all communication verbs', killing all communication methods.")
else
message_admins("[src.ckey] used 'Disable all communication verbs', restoring all communication methods.")
+
+//This generates the icon states for job starting location landmarks.
+/client/proc/create_mapping_job_icons()
+ set name = "Generate job landmarks icons"
+ set category = "Mapping"
+ var/icon/final = icon()
+ var/mob/living/carbon/human/dummy/D = new(locate(1,1,1)) //spawn on 1,1,1 so we don't have runtimes when items are deleted
+ D.setDir(SOUTH)
+ for(var/job in subtypesof(/datum/job))
+ var/datum/job/JB = new job
+ switch(JB.title)
+ if("AI")
+ final.Insert(icon('icons/mob/ai.dmi', "ai", SOUTH, 1), "AI")
+ if("Cyborg")
+ final.Insert(icon('icons/mob/robots.dmi', "robot", SOUTH, 1), "Cyborg")
+ else
+ for(var/obj/item/I in D)
+ qdel(I)
+ randomize_human(D)
+ JB.equip(D, TRUE, FALSE)
+ COMPILE_OVERLAYS(D)
+ var/icon/I = icon(getFlatIcon(D), frame = 1)
+ final.Insert(I, JB.title)
+ qdel(D)
+ //Also add the x
+ for(var/x_number in 1 to 4)
+ final.Insert(icon('icons/mob/screen_gen.dmi', "x[x_number == 1 ? "" : x_number]"), "x[x_number == 1 ? "" : x_number]")
+ fcopy(final, "icons/mob/landmarks.dmi")
\ No newline at end of file
diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm
index 81f2c75660..8feff99df4 100644
--- a/code/modules/assembly/flash.dm
+++ b/code/modules/assembly/flash.dm
@@ -30,7 +30,7 @@
holder.update_icon()
/obj/item/device/assembly/flash/proc/clown_check(mob/living/carbon/human/user)
- if(user.disabilities & CLUMSY && prob(50))
+ if(user.has_disability(CLUMSY) && prob(50))
flash_carbon(user, user, 15, 0)
return 0
return 1
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index e8ee742e56..d1b88e68e1 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -1,142 +1,142 @@
-/obj/item/device/assembly/mousetrap
- name = "mousetrap"
- desc = "A handy little spring-loaded trap for catching pesty rodents."
- icon_state = "mousetrap"
- materials = list(MAT_METAL=100)
- attachable = 1
- var/armed = 0
-
-
-/obj/item/device/assembly/mousetrap/examine(mob/user)
- ..()
- if(armed)
- to_chat(user, "The mousetrap is armed!")
- else
- to_chat(user, "The mousetrap is not armed.")
-
-/obj/item/device/assembly/mousetrap/activate()
- if(..())
- armed = !armed
- if(!armed)
- if(ishuman(usr))
- var/mob/living/carbon/human/user = usr
- if((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY && prob(50))
- to_chat(user, "Your hand slips, setting off the trigger!")
- pulse(0)
- update_icon()
- if(usr)
- playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
-
-/obj/item/device/assembly/mousetrap/describe()
- return "The pressure switch is [armed?"primed":"safe"]."
-
-/obj/item/device/assembly/mousetrap/update_icon()
- if(armed)
- icon_state = "mousetraparmed"
- else
- icon_state = "mousetrap"
- if(holder)
- holder.update_icon()
-
-/obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
- if(!armed)
- return
- var/obj/item/bodypart/affecting = null
- if(ishuman(target))
- var/mob/living/carbon/human/H = target
- if(PIERCEIMMUNE in H.dna.species.species_traits)
- playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
- armed = 0
- update_icon()
- pulse(0)
- return 0
- switch(type)
- if("feet")
- if(!H.shoes)
- affecting = H.get_bodypart(pick("l_leg", "r_leg"))
- H.Knockdown(60)
- if("l_hand", "r_hand")
- if(!H.gloves)
- affecting = H.get_bodypart(type)
- H.Stun(60)
- if(affecting)
- if(affecting.receive_damage(1, 0))
- H.update_damage_overlays()
- else if(ismouse(target))
- var/mob/living/simple_animal/mouse/M = target
- visible_message("SPLAT!")
- M.splat()
- playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
- armed = 0
- update_icon()
- pulse(0)
-
-
-/obj/item/device/assembly/mousetrap/attack_self(mob/living/carbon/human/user)
- if(!armed)
- to_chat(user, "You arm [src].")
- else
- if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50))
- var/which_hand = "l_hand"
- if(!(user.active_hand_index % 2))
- which_hand = "r_hand"
- triggered(user, which_hand)
- user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \
- "You accidentally trigger [src]!")
- return
- to_chat(user, "You disarm [src].")
- armed = !armed
- update_icon()
- playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
-
-
-/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
- if(armed)
- if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50))
- var/which_hand = "l_hand"
- if(!(user.active_hand_index % 2))
- which_hand = "r_hand"
- triggered(user, which_hand)
- user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \
- "You accidentally trigger [src]!")
- return
- ..()
-
-
-/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj)
- if(armed)
- if(ismob(AM))
- var/mob/MM = AM
- if(!(MM.movement_type & FLYING))
- if(ishuman(AM))
- var/mob/living/carbon/H = AM
- if(H.m_intent == MOVE_INTENT_RUN)
- triggered(H)
- H.visible_message("[H] accidentally steps on [src].", \
- "You accidentally step on [src]")
- else if(ismouse(MM))
- triggered(MM)
- else if(AM.density) // For mousetrap grenades, set off by anything heavy
- triggered(AM)
- ..()
-
-
-/obj/item/device/assembly/mousetrap/on_found(mob/finder)
- if(armed)
- finder.visible_message("[finder] accidentally sets off [src], breaking their fingers.", \
- "You accidentally trigger [src]!")
- triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand")
- return 1 //end the search!
- return 0
-
-
-/obj/item/device/assembly/mousetrap/hitby(A as mob|obj)
- if(!armed)
- return ..()
- visible_message("[src] is triggered by [A].")
- triggered(null)
-
-
-/obj/item/device/assembly/mousetrap/armed
- icon_state = "mousetraparmed"
- armed = TRUE
+/obj/item/device/assembly/mousetrap
+ name = "mousetrap"
+ desc = "A handy little spring-loaded trap for catching pesty rodents."
+ icon_state = "mousetrap"
+ materials = list(MAT_METAL=100)
+ attachable = 1
+ var/armed = 0
+
+
+/obj/item/device/assembly/mousetrap/examine(mob/user)
+ ..()
+ if(armed)
+ to_chat(user, "The mousetrap is armed!")
+ else
+ to_chat(user, "The mousetrap is not armed.")
+
+/obj/item/device/assembly/mousetrap/activate()
+ if(..())
+ armed = !armed
+ if(!armed)
+ if(ishuman(usr))
+ var/mob/living/carbon/human/user = usr
+ if((user.has_disability(DUMB) || user.has_disability(CLUMSY)) && prob(50))
+ to_chat(user, "Your hand slips, setting off the trigger!")
+ pulse(0)
+ update_icon()
+ if(usr)
+ playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
+
+/obj/item/device/assembly/mousetrap/describe()
+ return "The pressure switch is [armed?"primed":"safe"]."
+
+/obj/item/device/assembly/mousetrap/update_icon()
+ if(armed)
+ icon_state = "mousetraparmed"
+ else
+ icon_state = "mousetrap"
+ if(holder)
+ holder.update_icon()
+
+/obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
+ if(!armed)
+ return
+ var/obj/item/bodypart/affecting = null
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(PIERCEIMMUNE in H.dna.species.species_traits)
+ playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
+ armed = 0
+ update_icon()
+ pulse(0)
+ return 0
+ switch(type)
+ if("feet")
+ if(!H.shoes)
+ affecting = H.get_bodypart(pick("l_leg", "r_leg"))
+ H.Knockdown(60)
+ if("l_hand", "r_hand")
+ if(!H.gloves)
+ affecting = H.get_bodypart(type)
+ H.Stun(60)
+ if(affecting)
+ if(affecting.receive_damage(1, 0))
+ H.update_damage_overlays()
+ else if(ismouse(target))
+ var/mob/living/simple_animal/mouse/M = target
+ visible_message("SPLAT!")
+ M.splat()
+ playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
+ armed = 0
+ update_icon()
+ pulse(0)
+
+
+/obj/item/device/assembly/mousetrap/attack_self(mob/living/carbon/human/user)
+ if(!armed)
+ to_chat(user, "You arm [src].")
+ else
+ if((user.has_disability(DUMB) || user.has_disability(CLUMSY)) && prob(50))
+ var/which_hand = "l_hand"
+ if(!(user.active_hand_index % 2))
+ which_hand = "r_hand"
+ triggered(user, which_hand)
+ user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \
+ "You accidentally trigger [src]!")
+ return
+ to_chat(user, "You disarm [src].")
+ armed = !armed
+ update_icon()
+ playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
+
+
+/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
+ if(armed)
+ if((user.has_disability(DUMB) || user.has_disability(CLUMSY)) && prob(50))
+ var/which_hand = "l_hand"
+ if(!(user.active_hand_index % 2))
+ which_hand = "r_hand"
+ triggered(user, which_hand)
+ user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \
+ "You accidentally trigger [src]!")
+ return
+ ..()
+
+
+/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj)
+ if(armed)
+ if(ismob(AM))
+ var/mob/MM = AM
+ if(!(MM.movement_type & FLYING))
+ if(ishuman(AM))
+ var/mob/living/carbon/H = AM
+ if(H.m_intent == MOVE_INTENT_RUN)
+ triggered(H)
+ H.visible_message("[H] accidentally steps on [src].", \
+ "You accidentally step on [src]")
+ else if(ismouse(MM))
+ triggered(MM)
+ else if(AM.density) // For mousetrap grenades, set off by anything heavy
+ triggered(AM)
+ ..()
+
+
+/obj/item/device/assembly/mousetrap/on_found(mob/finder)
+ if(armed)
+ finder.visible_message("[finder] accidentally sets off [src], breaking their fingers.", \
+ "You accidentally trigger [src]!")
+ triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand")
+ return 1 //end the search!
+ return 0
+
+
+/obj/item/device/assembly/mousetrap/hitby(A as mob|obj)
+ if(!armed)
+ return ..()
+ visible_message("[src] is triggered by [A].")
+ triggered(null)
+
+
+/obj/item/device/assembly/mousetrap/armed
+ icon_state = "mousetraparmed"
+ armed = 1
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index 29990a299b..ddb1cf5545 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -41,7 +41,7 @@
/obj/item/clothing/glasses/proc/thermal_overload()
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
- if(!(H.disabilities & BLIND))
+ if(!(H.has_disability(BLIND)))
if(H.glasses == src)
to_chat(H, "[src] overloads and blinds you!")
H.flash_act(visual = 1)
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index d83c966ff6..5c28632c89 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -13,7 +13,7 @@
var/max_severity = 3
-/datum/round_event/disease_outbreak/announce()
+/datum/round_event/disease_outbreak/announce(fake)
priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg')
/datum/round_event/disease_outbreak/setup()
@@ -33,7 +33,7 @@
var/turf/T = get_turf(H)
if(!T)
continue
- if(T.z != ZLEVEL_STATION_PRIMARY)
+ if(!(T.z in GLOB.station_z_levels))
continue
if(!H.client)
continue
@@ -51,7 +51,7 @@
var/datum/disease/D
if(!advanced_virus)
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
- if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst.
+ if(!H.dna || (H.has_disability(BLIND))) //A blindness disease would be the worst.
continue
D = new virus_type()
var/datum/disease/dnaspread/DS = D
diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm
index 2f5618714d..956a214009 100644
--- a/code/modules/events/holiday/xmas.dm
+++ b/code/modules/events/holiday/xmas.dm
@@ -1,19 +1,3 @@
-/datum/round_event_control/treevenge
- name = "Treevenge (Christmas)"
- holidayID = CHRISTMAS
- typepath = /datum/round_event/treevenge
- max_occurrences = 1
- weight = 20
-
-/datum/round_event/treevenge/start()
- for(var/obj/structure/flora/tree/pine/xmas in world)
- var/mob/living/simple_animal/hostile/tree/evil_tree = new /mob/living/simple_animal/hostile/tree(xmas.loc)
- evil_tree.icon_state = xmas.icon_state
- evil_tree.icon_living = evil_tree.icon_state
- evil_tree.icon_dead = evil_tree.icon_state
- evil_tree.icon_gib = evil_tree.icon_state
- qdel(xmas) //b-but I don't want to delete xmas...
-
//this is an example of a possible round-start event
/datum/round_event_control/presents
name = "Presents under Trees (Christmas)"
@@ -24,12 +8,11 @@
earliest_start = 0
/datum/round_event/presents/start()
- for(var/obj/structure/flora/tree/pine/xmas in world)
+ for(var/obj/structure/flora/tree/pine/xmas/xmas in world)
if(!(xmas.z in GLOB.station_z_levels))
continue
- for(var/turf/open/floor/T in orange(1,xmas))
- for(var/i=1,i<=rand(1,5),i++)
- new /obj/item/a_gift(T)
+ xmas.icon_state = "pinepresents"
+ xmas.gifts_under_tree = TRUE
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list)
Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in GLOB.machines)
@@ -98,7 +81,7 @@
name = "Santa is coming to town! (Christmas)"
holidayID = CHRISTMAS
typepath = /datum/round_event/santa
- weight = 150
+ weight = 20
max_occurrences = 1
earliest_start = 20000
diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
index 372c085adb..99a3de90e1 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
@@ -1,4 +1,3 @@
-
/obj/machinery/gibber
name = "gibber"
desc = "The name isn't descriptive enough?"
@@ -12,10 +11,10 @@
circuit = /obj/item/circuitboard/machine/gibber
var/operating = FALSE //Is it on?
- var/dirty = 0 // Does it need cleaning?
+ var/dirty = FALSE // Does it need cleaning?
var/gibtime = 40 // Time from starting until meat appears
var/meat_produced = 0
- var/ignore_clothing = 0
+ var/ignore_clothing = FALSE
/obj/machinery/gibber/Initialize()
@@ -30,7 +29,7 @@
gib_time -= 5 * M.rating
gibtime = gib_time
if(M.rating >= 2)
- ignore_clothing = 1
+ ignore_clothing = TRUE
/obj/machinery/gibber/update_icon()
cut_overlays()
@@ -61,6 +60,10 @@
to_chat(user, "It's locked and running.")
return
+ if(!anchored)
+ to_chat(user, "[src] cannot be used unless bolted to the ground.")
+ return
+
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
var/mob/living/L = user.pulling
if(!iscarbon(L))
@@ -70,12 +73,17 @@
if(C.buckled ||C.has_buckled_mobs())
to_chat(user, "[C] is attached to something!")
return
- if(C.abiotic(1) && !ignore_clothing)
- to_chat(user, "Subject may not have abiotic items on.")
- return
+
+ if(!ignore_clothing)
+ for(var/obj/item/I in C.held_items + C.get_equipped_items())
+ if(!(I.flags_1 & NODROP_1))
+ to_chat(user, "Subject may not have abiotic items on.")
+ return
user.visible_message("[user] starts to put [C] into the gibber!")
- src.add_fingerprint(user)
+
+ add_fingerprint(user)
+
if(do_after(user, gibtime, target = src))
if(C && user.pulling == C && !C.buckled && !C.has_buckled_mobs() && !occupant)
user.visible_message("[user] stuffs [C] into the gibber!")
diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm
index 388a9d6893..85605fd2c4 100644
--- a/code/modules/holiday/holidays.dm
+++ b/code/modules/holiday/holidays.dm
@@ -387,9 +387,9 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
/datum/holiday/xmas
name = CHRISTMAS
- begin_day = 23
+ begin_day = 22
begin_month = DECEMBER
- end_day = 25
+ end_day = 27
/datum/holiday/xmas/greet()
return "Have a merry Christmas!"
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 15456c1e34..dadf077c8a 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -146,7 +146,7 @@
/obj/item/reagent_containers/food/snacks/grown/on_grind()
var/nutriment = reagents.get_reagent_amount("nutriment")
- if(grind_results.len)
+ if(grind_results&&grind_results.len)
for(var/i in 1 to grind_results.len)
grind_results[grind_results[i]] = nutriment
reagents.del_reagent("nutriment")
@@ -154,7 +154,7 @@
/obj/item/reagent_containers/food/snacks/grown/on_juice()
var/nutriment = reagents.get_reagent_amount("nutriment")
- if(juice_results.len)
+ if(juice_results&&juice_results.len)
for(var/i in 1 to juice_results.len)
juice_results[juice_results[i]] = nutriment
reagents.del_reagent("nutriment")
diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm
index 805cf787f7..637c3bfcee 100644
--- a/code/modules/integrated_electronics/core/assemblies.dm
+++ b/code/modules/integrated_electronics/core/assemblies.dm
@@ -20,6 +20,8 @@
var/charge_tick = FALSE
var/charge_delay = 4
var/use_cyborg_cell = TRUE
+ max_integrity = 50
+ armor = list(melee = 50, bullet = 70, laser = 70, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 0, acid = 0)
/obj/item/device/electronic_assembly/proc/check_interactivity(mob/user)
return user.canUseTopic(src,be_close = TRUE)
@@ -30,8 +32,6 @@
START_PROCESSING(SScircuit, src)
materials[MAT_METAL] = round((max_complexity + max_components) / 4) * SScircuit.cost_multiplier
-
-
/obj/item/device/electronic_assembly/Destroy()
STOP_PROCESSING(SScircuit, src)
return ..()
@@ -273,22 +273,9 @@
/obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity)
- for(var/obj/item/integrated_circuit/input/sensor/S in assembly_components)
- if(!proximity)
- if(istype(S,/obj/item/integrated_circuit/input/sensor/ranged)||(!user))
- if(user.client)
- if(!(target in view(user.client)))
- continue
- else
- if(!(target in view(user)))
- continue
- else
- continue
- S.set_pin_data(IC_OUTPUT, 1, WEAKREF(target))
- S.check_then_do_work()
- S.scan(target)
-
- visible_message(" [user] waves [src] around [target].")
+ for(var/obj/item/integrated_circuit/input/S in assembly_components)
+ if(S.sense(target,user,proximity))
+ visible_message(" [user] waves [src] around [target].")
/obj/item/device/electronic_assembly/screwdriver_act(mob/living/user, obj/item/S)
@@ -326,8 +313,11 @@
interact(user)
return TRUE
else
+ for(var/obj/item/integrated_circuit/input/S in assembly_components)
+ S.attackby_react(I,user,user.a_intent)
return ..()
+
/obj/item/device/electronic_assembly/attack_self(mob/user)
if(!check_interactivity(user))
return
@@ -391,7 +381,6 @@
/obj/item/device/electronic_assembly/proc/get_object()
return src
-
// Returns the location to be used for dropping items.
// Same as the regular drop_location(), but with checks being run on acting_object if necessary.
/obj/item/integrated_circuit/drop_location()
@@ -406,6 +395,7 @@
/obj/item/device/electronic_assembly/default //The /default electronic_assemblys are to allow the introduction of the new naming scheme without breaking old saves.
name = "type-a electronic assembly"
+
/obj/item/device/electronic_assembly/calc
name = "type-b electronic assembly"
icon_state = "setup_small_calc"
@@ -507,4 +497,4 @@
/obj/item/device/electronic_assembly/drone/arms
name = "type-b electronic drone"
icon_state = "setup_drone_arms"
- desc = "It's a case, for building mobile electronics with. This one is armed and dangerous."
\ No newline at end of file
+ desc = "It's a case, for building mobile electronics with. This one is armed and dangerous."
diff --git a/code/modules/integrated_electronics/core/debugger.dm b/code/modules/integrated_electronics/core/debugger.dm
index ac6f5c1a1e..666fcf00d6 100644
--- a/code/modules/integrated_electronics/core/debugger.dm
+++ b/code/modules/integrated_electronics/core/debugger.dm
@@ -56,7 +56,7 @@
data_to_show = A.name
to_chat(user, "You write '[data_to_write ? data_to_show : "NULL"]' to the '[io]' pin of \the [io.holder].")
else if(io.io_type == PULSE_CHANNEL)
- io.holder.check_then_do_work(ignore_power = TRUE)
+ io.holder.check_then_do_work(io.ord,ignore_power = TRUE)
to_chat(user, "You pulse \the [io.holder]'s [io].")
io.holder.interact(user) // This is to update the UI.
diff --git a/code/modules/integrated_electronics/core/helpers.dm b/code/modules/integrated_electronics/core/helpers.dm
index e84823f201..773c4f0684 100644
--- a/code/modules/integrated_electronics/core/helpers.dm
+++ b/code/modules/integrated_electronics/core/helpers.dm
@@ -15,9 +15,9 @@
io_type_override = io_list_copy[io_entry]
if(io_type_override)
- io_list.Add(new io_type_override(src, io_entry, default_data, pin_type))
+ io_list.Add(new io_type_override(src, io_entry, default_data, pin_type,i))
else
- io_list.Add(new io_type(src, io_entry, default_data, pin_type))
+ io_list.Add(new io_type(src, io_entry, default_data, pin_type,i))
/obj/item/integrated_circuit/proc/set_pin_data(pin_type, pin_number, datum/new_data)
diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm
index 069ca4245c..0c1a2fdad5 100644
--- a/code/modules/integrated_electronics/core/integrated_circuit.dm
+++ b/code/modules/integrated_electronics/core/integrated_circuit.dm
@@ -58,6 +58,12 @@ a creative player the means to solve many problems. Circuits are held inside an
/obj/item/integrated_circuit/proc/any_examine(mob/user)
return
+/obj/item/integrated_circuit/proc/attackby_react(var/atom/movable/A,mob/user)
+ return
+
+/obj/item/integrated_circuit/proc/sense(var/atom/movable/A,mob/user,prox)
+ return
+
/obj/item/integrated_circuit/proc/check_interactivity(mob/user)
if(assembly)
return assembly.check_interactivity(user)
@@ -291,17 +297,18 @@ a creative player the means to solve many problems. Circuits are held inside an
return TRUE // Battery has enough.
return FALSE // Not enough power.
-/obj/item/integrated_circuit/proc/check_then_do_work(var/ignore_power = FALSE)
+/obj/item/integrated_circuit/proc/check_then_do_work(ord,var/ignore_power = FALSE)
if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam.
- return
+ return FALSE
if(power_draw_per_use && !ignore_power)
if(!check_power())
power_fail()
- return
+ return FALSE
next_use = world.time + cooldown_per_use
- do_work()
+ do_work(ord)
+ return TRUE
-/obj/item/integrated_circuit/proc/do_work()
+/obj/item/integrated_circuit/proc/do_work(ord)
return
/obj/item/integrated_circuit/proc/disconnect_all()
@@ -369,4 +376,3 @@ a creative player the means to solve many problems. Circuits are held inside an
return TRUE
return FALSE
-
diff --git a/code/modules/integrated_electronics/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm
index bff96b713c..528281c3b7 100644
--- a/code/modules/integrated_electronics/core/pins.dm
+++ b/code/modules/integrated_electronics/core/pins.dm
@@ -25,14 +25,16 @@ D [1]/ ||
var/list/linked = list()
var/io_type = DATA_CHANNEL
var/pin_type // IC_INPUT, IC_OUTPUT, IC_ACTIVATOR - used in saving assembly wiring
+ var/ord
-
-/datum/integrated_io/New(loc, _name, _data, _pin_type)
+/datum/integrated_io/New(loc, _name, _data, _pin_type,_ord)
name = _name
if(_data)
data = _data
if(_pin_type)
pin_type = _pin_type
+ if(_ord)
+ ord = _ord
holder = loc
@@ -148,7 +150,7 @@ D [1]/ ||
/datum/integrated_io/activate/push_data()
for(var/k in 1 to linked.len)
var/datum/integrated_io/io = linked[k]
- io.holder.check_then_do_work()
+ io.holder.check_then_do_work(io.ord)
/datum/integrated_io/proc/pull_data()
for(var/k in 1 to linked.len)
@@ -207,7 +209,7 @@ D [1]/ ||
write_data_to_pin(new_data)
/datum/integrated_io/activate/ask_for_pin_data(mob/user) // This just pulses the pin.
- holder.check_then_do_work(ignore_power = TRUE)
+ holder.check_then_do_work(ord,ignore_power = TRUE)
to_chat(user, "You pulse \the [holder]'s [src] pin.")
/datum/integrated_io/activate
diff --git a/code/modules/integrated_electronics/core/special_pins/index_pin.dm b/code/modules/integrated_electronics/core/special_pins/index_pin.dm
index 51b12a0f3a..06267eec61 100644
--- a/code/modules/integrated_electronics/core/special_pins/index_pin.dm
+++ b/code/modules/integrated_electronics/core/special_pins/index_pin.dm
@@ -1,4 +1,4 @@
-// These pins can only contain integer numbers between 1 and IC_MAX_LIST_LENGTH. Null is not allowed.
+// These pins can only contain integer numbers between 0 and IC_MAX_LIST_LENGTH. Null is allowed.
/datum/integrated_io/index
name = "index pin"
data = 1
@@ -11,10 +11,10 @@
/datum/integrated_io/index/write_data_to_pin(new_data)
if(isnull(new_data))
- new_data = 1
+ new_data = 0
if(isnum(new_data))
- data = CLAMP(round(new_data), 1, IC_MAX_LIST_LENGTH)
+ data = CLAMP(round(new_data), 0, IC_MAX_LIST_LENGTH)
holder.on_data_written()
/datum/integrated_io/index/display_pin_type()
diff --git a/code/modules/integrated_electronics/subtypes/arithmetic.dm b/code/modules/integrated_electronics/subtypes/arithmetic.dm
index 7dec779f83..e491a34a69 100644
--- a/code/modules/integrated_electronics/subtypes/arithmetic.dm
+++ b/code/modules/integrated_electronics/subtypes/arithmetic.dm
@@ -30,10 +30,9 @@
/obj/item/integrated_circuit/arithmetic/addition/do_work()
var/result = 0
for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
- I.pull_data()
- if(isnum(I.data))
- result = result + I.data
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I))
+ result += I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -56,13 +55,10 @@
return
var/result = A.data
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
- if(I == A)
- continue
- I.pull_data()
- if(isnum(I.data))
- result = result - I.data
+ for(var/k in 2 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I))
+ result -= I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -85,13 +81,10 @@
if(!isnum(A.data))
return
var/result = A.data
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
- if(I == A)
- continue
- I.pull_data()
- if(isnum(I.data))
- result = result * I.data
+ for(var/k in 2 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I))
+ result *= I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -114,13 +107,12 @@
return
var/result = A.data
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
- if(I == A)
- continue
- I.pull_data()
- if(isnum(I.data) && I.data != 0) //No runtimes here.
- result = result / I.data
+
+ for(var/k in 2 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I) && (I != 0))
+ result /= I
+
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -228,12 +220,11 @@
/obj/item/integrated_circuit/arithmetic/average/do_work()
var/result = 0
var/inputs_used = 0
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
- I.pull_data()
- if(isnum(I.data))
+ for(var/k in 2 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I))
inputs_used++
- result = result + I.data
+ result += I
if(inputs_used)
result = result / inputs_used
@@ -288,11 +279,10 @@
/obj/item/integrated_circuit/arithmetic/square_root/do_work()
var/result = 0
- for(var/k in 1 to inputs.len)
- var/datum/integrated_io/I = inputs[k]
- I.pull_data()
- if(isnum(I.data))
- result = sqrt(I.data)
+ for(var/k in 2 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(isnum(I))
+ result += sqrt(I)
set_pin_data(IC_OUTPUT, 1, result)
push_data()
diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm
index d622ea8ca9..cd9306d0da 100644
--- a/code/modules/integrated_electronics/subtypes/converters.dm
+++ b/code/modules/integrated_electronics/subtypes/converters.dm
@@ -160,10 +160,10 @@
/obj/item/integrated_circuit/converter/concatenator/do_work()
var/result = null
- for(var/datum/integrated_io/I in inputs)
- I.pull_data()
- if(!isnull(I.data))
- result = result + I.data
+ for(var/k in 1 to inputs.len)
+ var/I = get_pin_data(IC_INPUT, k)
+ if(!isnull(I))
+ result = result + I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm
index c39cfeac44..91b4b437e3 100644
--- a/code/modules/integrated_electronics/subtypes/input.dm
+++ b/code/modules/integrated_electronics/subtypes/input.dm
@@ -128,7 +128,7 @@
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
if(!istype(H)) //Invalid input
return
- if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
+ if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100
var/missing_health = H.getMaxHealth() - H.health
@@ -143,6 +143,49 @@
push_data()
activate_pin(2)
+/obj/item/integrated_circuit/input/slime_scanner
+ name = "slime_scanner"
+ desc = "A very small version of the xenobio analyser. This allows the machine to know every needed properties of slime."
+ icon_state = "medscan_adv"
+ complexity = 12
+ inputs = list("\[ target")
+ outputs = list(
+ "colour" = IC_PINTYPE_STRING,
+ "adult" = IC_PINTYPE_BOOLEAN,
+ "nutrition" = IC_PINTYPE_NUMBER,
+ "charge" = IC_PINTYPE_NUMBER,
+ "health" = IC_PINTYPE_NUMBER,
+ "possible mutation" = IC_PINTYPE_LIST,
+ "genetic destability"= IC_PINTYPE_NUMBER,
+ "slime core amount" = IC_PINTYPE_NUMBER,
+ "Growth progress" = IC_PINTYPE_NUMBER,
+ )
+ activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_RESEARCH
+ power_draw_per_use = 80
+
+/obj/item/integrated_circuit/input/slime_scanner/do_work()
+ var/mob/living/simple_animal/slime/T = get_pin_data_as_type(IC_INPUT, 1, /mob/living/simple_animal/slime)
+ if(!isslime(T)) //Invalid input
+ return
+ if(T in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
+
+ set_pin_data(IC_OUTPUT, 1, T.colour)
+ set_pin_data(IC_OUTPUT, 2, T.is_adult)
+ set_pin_data(IC_OUTPUT, 3, T.nutrition/T.get_max_nutrition())
+ set_pin_data(IC_OUTPUT, 4, T.powerlevel)
+ set_pin_data(IC_OUTPUT, 5, round(T.health/T.maxHealth,0.01)*100)
+ set_pin_data(IC_OUTPUT, 6, uniqueList(T.slime_mutation))
+ set_pin_data(IC_OUTPUT, 7, T.mutation_chance)
+ set_pin_data(IC_OUTPUT, 8, T.cores)
+ set_pin_data(IC_OUTPUT, 9, T.amount_grown/SLIME_EVOLUTION_THRESHOLD)
+
+
+ push_data()
+ activate_pin(2)
+
+
+
/obj/item/integrated_circuit/input/plant_scanner
name = "integrated plant analyzer"
desc = "A very small version of the plant analyser. This allows the machine to know all valuable params of plants in trays. \
@@ -180,7 +223,7 @@
return
for(var/i=1, i<=outputs.len, i++)
set_pin_data(IC_OUTPUT, i, null)
- if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
+ if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
if(H.myseed)
set_pin_data(IC_OUTPUT, 1, H.myseed.plantname)
set_pin_data(IC_OUTPUT, 2, H.age)
@@ -228,7 +271,7 @@
return
for(var/i=1, i<=outputs.len, i++)
set_pin_data(IC_OUTPUT, i, null)
- if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
+ if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
if(H.myseed)
for(var/datum/plant_gene/reagent/G in H.myseed.genes)
greagents.Add(G.get_name())
@@ -671,12 +714,15 @@
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 120
-/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A)
+/obj/item/integrated_circuit/input/sensor/sense(var/atom/A,mob/user,prox)
+ if(!prox)
+ return FALSE
+ if(!check_then_do_work())
+ return FALSE
var/ignore_bags = get_pin_data(IC_INPUT, 1)
if(ignore_bags)
if(istype(A, /obj/item/storage))
return FALSE
-
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
push_data()
activate_pin(1)
@@ -694,6 +740,52 @@
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 120
+/obj/item/integrated_circuit/input/sensor/ranged/sense(var/atom/A,mob/user)
+ if(!user)
+ return FALSE
+ if(user.client)
+ if(!(A in view(user.client)))
+ return FALSE
+ else
+ if(!(A in view(user)))
+ return FALSE
+ if(!check_then_do_work())
+ return FALSE
+ var/ignore_bags = get_pin_data(IC_INPUT, 1)
+ if(ignore_bags)
+ if(istype(A, /obj/item/storage))
+ return FALSE
+ set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
+ push_data()
+ activate_pin(1)
+ return TRUE
+
+/obj/item/integrated_circuit/input/objscaner
+ name = "scaner"
+ desc = "Scans and obtains a reference for any objects you use on assembly."
+ extended_desc = "If 'put down' pin is set to true, assembly will take scanned object from your hands to it's location.\
+ useful for interaction with grabber. Scaner works only with help intent."
+ icon_state = "recorder"
+ complexity = 4
+ inputs = list("put down" = IC_PINTYPE_BOOLEAN)
+ outputs = list("scanned" = IC_PINTYPE_REF)
+ activators = list("on scanned" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+ power_draw_per_use = 20
+
+/obj/item/integrated_circuit/input/objscaner/attackby_react(var/atom/A,var/mob/user,intent)
+ if(intent!=INTENT_HELP)
+ return FALSE
+ if(!check_then_do_work())
+ return FALSE
+ var/pu = get_pin_data(IC_INPUT, 1)
+ if(pu)
+ user.transferItemToLoc(A,drop_location())
+ set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
+ push_data()
+ activate_pin(1)
+ return TRUE
+
/obj/item/integrated_circuit/input/internalbm
name = "internal battery monitor"
desc = "This monitors the charge level of an internal battery."
@@ -760,3 +852,38 @@
activate_pin(2)
push_data()
return
+
+/obj/item/integrated_circuit/input/ntnetsc
+ name = "NTnet scaner"
+ desc = "This can return NTnet id of component insi given object, if there is any."
+ icon_state = "signalsc"
+ w_class = WEIGHT_CLASS_TINY
+ complexity = 2
+ inputs = list("target" = IC_PINTYPE_REF)
+ outputs = list(
+ "id" = IC_PINTYPE_STRING
+ )
+ activators = list("read" = IC_PINTYPE_PULSE_IN, "found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+ power_draw_per_use = 1
+
+/obj/item/integrated_circuit/input/ntnetsc/do_work()
+
+ var/atom/AM = get_pin_data_as_type(IC_INPUT, 1, /atom)
+ var/list/processing_list = list(AM)
+ var/datum/component/ntnet_interface/net = null
+ set_pin_data(IC_OUTPUT, 1, null)
+ while(processing_list.len && !net)
+ var/atom/A = processing_list[1]
+ processing_list.Cut(1, 2)
+ //Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed
+ //This is also why we don't need to check against assembled as we go along
+ processing_list += A.contents
+ net = A.GetComponent(/datum/component/ntnet_interface)
+ if(net)
+ set_pin_data(IC_OUTPUT, 1, net.hardware_id)
+ activate_pin(2)
+ else
+ activate_pin(3)
+ push_data()
+ return
diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm
index 627301ef10..f8e858ef94 100644
--- a/code/modules/integrated_electronics/subtypes/logic.dm
+++ b/code/modules/integrated_electronics/subtypes/logic.dm
@@ -2,7 +2,7 @@
name = "logic gate"
desc = "This tiny chip will decide for you!"
extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE."
- complexity = 3
+ complexity = 1
outputs = list("result")
activators = list("compare" = IC_PINTYPE_PULSE_IN)
category_text = "Logic"
diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm
index f32f414fbb..5099547197 100644
--- a/code/modules/integrated_electronics/subtypes/manipulation.dm
+++ b/code/modules/integrated_electronics/subtypes/manipulation.dm
@@ -155,9 +155,11 @@
if(isnum(wanted_dir.data))
if(step(assembly, wanted_dir.data))
activate_pin(2)
+ return
else
activate_pin(3)
return FALSE
+ return FALSE
/obj/item/integrated_circuit/manipulation/grenade
name = "grenade primer"
@@ -247,9 +249,14 @@
/obj/item/integrated_circuit/manipulation/plant_module/do_work()
..()
var/turf/T = get_turf(src)
- var/obj/machinery/hydroponics/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics)
- if(!istype(AM)) //Invalid input
+ var/obj/OM = get_pin_data_as_type(IC_INPUT, 1, /obj)
+ if(istype(OM,/obj/structure/spacevine) && get_pin_data(IC_INPUT, 2) == 2)
+ qdel(OM)
+ activate_pin(2)
return
+ var/obj/machinery/hydroponics/AM = OM
+ if(!istype(AM)) //Invalid input
+ return FALSE
var/mob/living/M = get_turf(AM)
if(!M.Adjacent(T))
return //Can't reach
@@ -276,6 +283,7 @@
qdel(AM.myseed)
AM.myseed = null
AM.weedlevel = 0 //Has a side effect of cleaning up those nasty weeds
+ AM.dead = 0
AM.update_icon()
else
activate_pin(2)
@@ -284,7 +292,7 @@
/obj/item/integrated_circuit/manipulation/grabber
name = "grabber"
- desc = "A circuit with it's own inventory for small/medium items, used to grab and store things."
+ desc = "A circuit with it's own inventory for tiny/small items, used to grab and store things."
icon_state = "grabber"
extended_desc = "The circuit accepts a reference to thing to be grabbed. It can store up to 10 things. Modes: 1 for grab. 0 for eject the first thing. -1 for eject all."
w_class = WEIGHT_CLASS_SMALL
@@ -307,7 +315,7 @@
var/mode = get_pin_data(IC_INPUT, 2)
if(mode == 1)
- if(check_target(AM, exclude_contents = TRUE))
+ if(check_target(AM))
if((contents.len < max_items) && (!max_w_class || AM.w_class <= max_w_class))
AM.forceMove(src)
if(mode == 0)
diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm
index 33f92c3646..0c66c3a943 100644
--- a/code/modules/integrated_electronics/subtypes/reagents.dm
+++ b/code/modules/integrated_electronics/subtypes/reagents.dm
@@ -9,6 +9,11 @@
. = ..()
if(volume)
create_reagents(volume)
+ push_vol()
+
+/obj/item/integrated_circuit/reagent/proc/push_vol()
+ set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
+ push_data()
/obj/item/integrated_circuit/reagent/smoke
name = "smoke generator"
@@ -29,7 +34,8 @@
)
activators = list(
"create smoke" = IC_PINTYPE_PULSE_IN,
- "on smoked" = IC_PINTYPE_PULSE_OUT
+ "on smoked" = IC_PINTYPE_PULSE_OUT,
+ "push ref" = IC_PINTYPE_PULSE_IN
)
spawn_flags = IC_SPAWN_RESEARCH
power_draw_per_use = 20
@@ -40,24 +46,27 @@
//reset warning only if we have reagents now
if(changetype == ADD_REAGENT)
notified = FALSE
- set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
- push_data()
+ push_vol()
-/obj/item/integrated_circuit/reagent/smoke/do_work()
- if(!reagents || (reagents.total_volume < IC_SMOKE_REAGENTS_MINIMUM_UNITS))
- return
- var/location = get_turf(src)
- var/datum/effect_system/smoke_spread/chem/S = new
- S.attach(location)
- playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
- if(S)
- S.set_up(reagents, smoke_radius, location, notified)
- if(!notified)
- notified = TRUE
- S.start()
-
- reagents.clear_reagents()
- activate_pin(2)
+/obj/item/integrated_circuit/reagent/smoke/do_work(ord)
+ switch(ord)
+ if(1)
+ if(!reagents || (reagents.total_volume < IC_SMOKE_REAGENTS_MINIMUM_UNITS))
+ return
+ var/location = get_turf(src)
+ var/datum/effect_system/smoke_spread/chem/S = new
+ S.attach(location)
+ playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
+ if(S)
+ S.set_up(reagents, smoke_radius, location, notified)
+ if(!notified)
+ notified = TRUE
+ S.start()
+ reagents.clear_reagents()
+ activate_pin(2)
+ if(3)
+ set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
+ push_data()
/obj/item/integrated_circuit/reagent/injector
name = "integrated hypo-injector"
@@ -85,7 +94,9 @@
activators = list(
"inject" = IC_PINTYPE_PULSE_IN,
"on injected" = IC_PINTYPE_PULSE_OUT,
- "on fail" = IC_PINTYPE_PULSE_OUT
+ "on fail" = IC_PINTYPE_PULSE_OUT,
+ "push ref" = IC_PINTYPE_PULSE_IN
+
)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 15
@@ -93,15 +104,8 @@
var/transfer_amount = 10
var/busy = FALSE
-/obj/item/integrated_circuit/reagent/injector/interact(mob/user)
- set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
- push_data()
- ..()
-
-
/obj/item/integrated_circuit/reagent/injector/on_reagent_change(changetype)
- set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
- push_data()
+ push_vol()
/obj/item/integrated_circuit/reagent/injector/on_data_written()
var/new_amount = get_pin_data(IC_INPUT, 2)
@@ -127,7 +131,15 @@
temp_reagents.clear_reagents()
qdel(temp_reagents)
-/obj/item/integrated_circuit/reagent/injector/do_work()
+/obj/item/integrated_circuit/reagent/injector/do_work(ord)
+ switch(ord)
+ if(1)
+ inject()
+ if(4)
+ set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
+ push_data()
+
+/obj/item/integrated_circuit/reagent/injector/proc/inject()
set waitfor = FALSE // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
var/atom/movable/acting_object = get_object()
@@ -281,17 +293,15 @@
"volume used" = IC_PINTYPE_NUMBER,
"self reference" = IC_PINTYPE_REF
)
- activators = list()
+ activators = list("push ref" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
-/obj/item/integrated_circuit/reagent/storage/interact(mob/user)
+/obj/item/integrated_circuit/reagent/storage/do_work()
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
- ..()
/obj/item/integrated_circuit/reagent/storage/on_reagent_change(changetype)
- set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
- push_data()
+ push_vol()
/obj/item/integrated_circuit/reagent/storage/cryo
name = "cryo reagent storage"
@@ -306,6 +316,7 @@
. = ..()
reagents.set_reacting(FALSE)
+
/obj/item/integrated_circuit/reagent/storage/big
name = "big reagent storage"
desc = "Stores liquid inside, and away from electrical components. Can store up to 180u."
@@ -317,6 +328,99 @@
complexity = 16
spawn_flags = IC_SPAWN_RESEARCH
+/obj/item/integrated_circuit/reagent/storage/grinder
+ name = "reagent grinder"
+ desc = "This is reagent grinder.It accepts ref to something and refines it into reagents. Can store up to 100u."
+ icon_state = "blender"
+ extended_desc = ""
+ inputs = list(
+ "target" = IC_PINTYPE_REF,
+ )
+ outputs = list(
+ "volume used" = IC_PINTYPE_NUMBER,
+ "self reference" = IC_PINTYPE_REF
+ )
+ activators = list(
+ "grind" = IC_PINTYPE_PULSE_IN,
+ "on grind" = IC_PINTYPE_PULSE_OUT,
+ "on fail" = IC_PINTYPE_PULSE_OUT,
+ "push ref" = IC_PINTYPE_PULSE_IN
+ )
+ volume = 100
+ power_draw_per_use = 150
+ complexity = 16
+ spawn_flags = IC_SPAWN_RESEARCH
+
+
+/obj/item/integrated_circuit/reagent/storage/grinder/do_work(ord)
+ switch(ord)
+ if(1)
+ grind()
+ if(4)
+ set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
+ push_data()
+
+/obj/item/integrated_circuit/reagent/storage/grinder/proc/grind()
+ if(reagents.total_volume >= reagents.maximum_volume)
+ activate_pin(3)
+ return FALSE
+ var/obj/item/I = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
+ if(istype(I)&&(I.grind_results)&&check_target(I)&&(I.on_grind(src) != -1))
+ reagents.add_reagent_list(I.grind_results)
+ if(I.reagents)
+ I.reagents.trans_to(src, I.reagents.total_volume)
+ qdel(I)
+ activate_pin(2)
+ return TRUE
+ activate_pin(3)
+ return FALSE
+
+obj/item/integrated_circuit/reagent/storage/juicer
+ name = "reagent juicer"
+ desc = "This is reagent juicer.It accepts ref to something and refines it into reagents. Can store up to 100u."
+ icon_state = "blender"
+ extended_desc = ""
+ inputs = list(
+ "target" = IC_PINTYPE_REF,
+ )
+ outputs = list(
+ "volume used" = IC_PINTYPE_NUMBER,
+ "self reference" = IC_PINTYPE_REF
+ )
+ activators = list(
+ "juice" = IC_PINTYPE_PULSE_IN,
+ "on juice" = IC_PINTYPE_PULSE_OUT,
+ "on fail" = IC_PINTYPE_PULSE_OUT,
+ "push ref" = IC_PINTYPE_PULSE_IN
+ )
+ volume = 100
+ power_draw_per_use = 150
+ complexity = 16
+ spawn_flags = IC_SPAWN_RESEARCH
+
+/obj/item/integrated_circuit/reagent/storage/juicer/do_work(ord)
+ switch(ord)
+ if(1)
+ juice()
+ if(4)
+ set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
+ push_data()
+
+/obj/item/integrated_circuit/reagent/storage/juicer/proc/juice()
+ if(reagents.total_volume >= reagents.maximum_volume)
+ activate_pin(3)
+ return FALSE
+ var/obj/item/I = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
+ if(istype(I)&&check_target(I)&&(I.juice_results)&&(I.on_juice() != -1))
+ reagents.add_reagent_list(I.juice_results)
+ qdel(I)
+ activate_pin(2)
+ return TRUE
+ activate_pin(3)
+ return FALSE
+
+
+
/obj/item/integrated_circuit/reagent/storage/scan
name = "reagent scanner"
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. On pulse this beaker will send list of contained reagents."
@@ -330,17 +434,22 @@
"list of reagents" = IC_PINTYPE_LIST
)
activators = list(
- "scan" = IC_PINTYPE_PULSE_IN
+ "scan" = IC_PINTYPE_PULSE_IN,
+ "push ref" = IC_PINTYPE_PULSE_IN
)
spawn_flags = IC_SPAWN_RESEARCH
-/obj/item/integrated_circuit/reagent/storage/scan/do_work()
- var/cont[0]
- for(var/datum/reagent/RE in reagents.reagent_list)
- cont += RE.id
- set_pin_data(IC_OUTPUT, 3, cont)
- push_data()
-
+/obj/item/integrated_circuit/reagent/storage/scan/do_work(ord)
+ switch(ord)
+ if(1)
+ var/cont[0]
+ for(var/datum/reagent/RE in reagents.reagent_list)
+ cont += RE.id
+ set_pin_data(IC_OUTPUT, 3, cont)
+ push_data()
+ if(2)
+ set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
+ push_data()
/obj/item/integrated_circuit/reagent/filter
name = "reagent filter"
@@ -394,7 +503,8 @@
if(!source.reagents || !target.reagents)
return
- if(!source.is_drainable() || !target.is_refillable())
+ // FALSE in those procs makes mobs invalid targets.
+ if(!source.is_drawable(FALSE) || !target.is_injectable(FALSE))
return
if(target.reagents.maximum_volume - target.reagents.total_volume <= 0)
@@ -410,3 +520,45 @@
activate_pin(2)
push_data()
+/obj/item/integrated_circuit/reagent/storage/heater
+ name = "chemical heater"
+ desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. Will heat or freeze reagents \
+ to target temperature, when turned on."
+ icon_state = "heater"
+ container_type = OPENCONTAINER
+ complexity = 8
+ inputs = list(
+ "target temperature" = IC_PINTYPE_NUMBER,
+ "on" = IC_PINTYPE_BOOLEAN
+ )
+ inputs_default = list("1" = 300)
+ outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF,"temperature" = IC_PINTYPE_NUMBER)
+ spawn_flags = IC_SPAWN_RESEARCH
+ var/heater_coefficient = 0.1
+
+/obj/item/integrated_circuit/reagent/storage/heater/on_data_written()
+ if(get_pin_data(IC_INPUT, 2))
+ power_draw_idle = 30
+ else
+ power_draw_idle = 0
+
+/obj/item/integrated_circuit/reagent/storage/heater/Initialize()
+ .=..()
+ START_PROCESSING(SScircuit, src)
+
+/obj/item/integrated_circuit/reagent/storage/heater/Destroy()
+ STOP_PROCESSING(SScircuit, src)
+ return ..()
+
+/obj/item/integrated_circuit/reagent/storage/heater/process()
+ if(power_draw_idle)
+ var/target_temperature = get_pin_data(IC_INPUT, 1)
+ if(reagents.chem_temp > target_temperature)
+ reagents.chem_temp += min(-1, (target_temperature - reagents.chem_temp) * heater_coefficient)
+ if(reagents.chem_temp < target_temperature)
+ reagents.chem_temp += max(1, (target_temperature - reagents.chem_temp) * heater_coefficient)
+
+ reagents.chem_temp = round(reagents.chem_temp)
+ reagents.handle_reactions()
+ set_pin_data(IC_OUTPUT, 3, reagents.chem_temp)
+ push_data()
diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm
index ec59c3cab1..37a38677b0 100644
--- a/code/modules/integrated_electronics/subtypes/smart.dm
+++ b/code/modules/integrated_electronics/subtypes/smart.dm
@@ -27,6 +27,6 @@
push_data()
return // Can't see the target.
- set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A)))
+ set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A)))
push_data()
activate_pin(2)
diff --git a/code/modules/keybindings/bindings_atom.dm b/code/modules/keybindings/bindings_atom.dm
new file mode 100644
index 0000000000..9738175d2d
--- /dev/null
+++ b/code/modules/keybindings/bindings_atom.dm
@@ -0,0 +1,18 @@
+// You might be wondering why this isn't client level. If focus is null, we don't want you to move.
+// Only way to do that is to tie the behavior into the focus's keyLoop().
+
+/atom/movable/keyLoop(client/user)
+ if(!user.keys_held["Ctrl"])
+ var/movement_dir = NONE
+ for(var/_key in user.keys_held)
+ movement_dir = movement_dir | GLOB.movement_keys[_key]
+ if(user.next_move_dir_add)
+ movement_dir |= user.next_move_dir_add
+ if(user.next_move_dir_sub)
+ movement_dir &= ~user.next_move_dir_sub
+ // Sanity checks in case you hold left and right and up to make sure you only go up
+ if((movement_dir & NORTH) && (movement_dir & SOUTH))
+ movement_dir &= ~(NORTH|SOUTH)
+ if((movement_dir & EAST) && (movement_dir & WEST))
+ movement_dir &= ~(EAST|WEST)
+ user.Move(get_step(src, movement_dir), movement_dir)
\ No newline at end of file
diff --git a/code/modules/library/soapstone.dm b/code/modules/library/soapstone.dm
index cee4665f07..fd75ba4351 100644
--- a/code/modules/library/soapstone.dm
+++ b/code/modules/library/soapstone.dm
@@ -142,7 +142,7 @@
hidden_message = newmessage
creator_name = user.real_name
creator_key = user.ckey
- realdate = world.timeofday
+ realdate = world.realtime
map = SSmapping.config.map_name
update_icon()
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 01d6de85e2..d655ed6e94 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -656,7 +656,7 @@
playsound(user, 'sound/magic/clockwork/fellowship_armory.ogg', 35, TRUE, frequency = 90000 - (active * 30000))
/obj/item/melee/transforming/cleaving_saw/clumsy_transform_effect(mob/living/user)
- if(user.disabilities & CLUMSY && prob(50))
+ if(user.has_disability(CLUMSY) && prob(50))
to_chat(user, "You accidentally cut yourself with [src], like a doofus!")
user.take_bodypart_damage(10)
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index 45f26d55c3..c1ea547b34 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -16,7 +16,7 @@
/mob/living/carbon/monkey/handle_blood()
- if(bodytemperature >= 225 && !(disabilities & NOCLONE)) //cryosleep or husked people do not pump the blood.
+ if(bodytemperature >= 225 && !(has_disability(NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
if(blood_volume < BLOOD_VOLUME_NORMAL)
blood_volume += 0.1 // regenerate blood VERY slowly
@@ -28,7 +28,7 @@
bleed_rate = 0
return
- if(bodytemperature >= 225 && !(disabilities & NOCLONE)) //cryosleep or husked people do not pump the blood.
+ if(bodytemperature >= 225 && !(has_disability(NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
if(blood_volume < BLOOD_VOLUME_NORMAL && !(NOHUNGER in dna.species.species_traits))
@@ -201,13 +201,13 @@
return "blood"
/mob/living/carbon/monkey/get_blood_id()
- if(!(disabilities & NOCLONE))
+ if(!(has_disability(NOCLONE)))
return "blood"
/mob/living/carbon/human/get_blood_id()
if(dna.species.exotic_blood)
return dna.species.exotic_blood
- else if((NOBLOOD in dna.species.species_traits) || (disabilities & NOCLONE))
+ else if((NOBLOOD in dna.species.species_traits) || (has_disability(NOCLONE)))
return
return "blood"
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index aef5489b04..b01c7c09ac 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -79,8 +79,8 @@
if(!brainmob.stored_dna)
brainmob.stored_dna = new /datum/dna/stored(brainmob)
C.dna.copy_dna(brainmob.stored_dna)
- if(L.disabilities & NOCLONE)
- brainmob.disabilities |= NOCLONE //This is so you can't just decapitate a husked guy and clone them without needing to get a new body
+ if(L.has_disability(NOCLONE))
+ brainmob.disabilities[NOCLONE] = L.disabilities[NOCLONE]
var/obj/item/organ/zombie_infection/ZI = L.getorganslot(ORGAN_SLOT_ZOMBIE)
if(ZI)
brainmob.set_species(ZI.old_species) //For if the brain is cloned
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 819ed8072f..23decdd59f 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -157,7 +157,7 @@
if(!throwable_mob.buckled)
thrown_thing = throwable_mob
stop_pulling()
- if(disabilities & PACIFISM)
+ if(has_disability(PACIFISM))
to_chat(src, "You gently let go of [throwable_mob].")
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
var/turf/end_T = get_turf(target)
@@ -170,7 +170,7 @@
thrown_thing = I
dropItemToGround(I)
- if(disabilities & PACIFISM && I.throwforce)
+ if(has_disability(PACIFISM) && I.throwforce)
to_chat(src, "You set [I] down gently on the ground.")
return
@@ -409,7 +409,7 @@
dropItemToGround(I)
var/modifier = 0
- if(disabilities & CLUMSY)
+ if(has_disability(CLUMSY))
modifier -= 40 //Clumsy people are more likely to hit themselves -Honk!
switch(rand(1,100)+modifier) //91-100=Nothing special happens
@@ -518,7 +518,7 @@
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
update_stat()
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD )
- become_husk()
+ become_husk("burn")
med_hud_set_health()
/mob/living/carbon/update_sight()
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 0bfa287a09..a6d4f3536b 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -306,11 +306,15 @@
if(eyes.eye_damage > 20)
if(prob(eyes.eye_damage - 20))
- if(become_nearsighted())
+ if(!has_disability(NEARSIGHT))
to_chat(src, "Your eyes start to burn badly!")
+ become_nearsighted(EYE_DAMAGE)
+
else if(prob(eyes.eye_damage - 25))
- if(become_blind())
+ if(!has_disability(BLIND))
to_chat(src, "You can't see anything!")
+ become_blind(EYE_DAMAGE)
+
else
to_chat(src, "Your eyes are really starting to hurt. This can't be good for you!")
if(has_bane(BANE_LIGHT))
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index 4b1afe0780..4453c33436 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -48,7 +48,7 @@
/mob/living/carbon/proc/Drain()
- become_husk()
- disabilities |= NOCLONE
+ become_husk(CHANGELING_DRAIN)
+ add_disability(NOCLONE, CHANGELING_DRAIN)
blood_volume = 0
return 1
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index e3e1271132..f0835ed7bf 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -44,7 +44,10 @@
if(mind.martial_art && mind.martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
if(prob(mind.martial_art.deflection_chance))
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
- visible_message("[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!", "You deflect the projectile!")
+ if(mind.martial_art.deflection_chance >= 100) //if they can NEVER be hit, lets clue sec in ;)
+ visible_message("[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!", "You deflect the projectile!")
+ else
+ visible_message("[src] deflects the projectile!", "You deflect the projectile!")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 0
@@ -140,8 +143,8 @@
return ..()
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
- if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling))
- vore_attack(user, pulling)
+ if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (has_disability(FAT)) && ismonkey(pulling))
+ devour_mob(pulling)
else
..()
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index d1d657652b..84da846bfd 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -91,19 +91,8 @@
return wear_id.GetID()
-/mob/living/carbon/human/abiotic(full_body = 0)
- var/abiotic_hands = FALSE
- for(var/obj/item/I in held_items)
- if(!(I.flags_1 & NODROP_1))
- abiotic_hands = TRUE
- break
- if(full_body && abiotic_hands && ((back && !(back.flags_1&NODROP_1)) || (wear_mask && !(wear_mask.flags_1&NODROP_1)) || (head && !(head.flags_1&NODROP_1)) || (shoes && !(shoes.flags_1&NODROP_1)) || (w_uniform && !(w_uniform.flags_1&NODROP_1)) || (wear_suit && !(wear_suit.flags_1&NODROP_1)) || (glasses && !(glasses.flags_1&NODROP_1)) || (ears && !(ears.flags_1&NODROP_1)) || (gloves && !(gloves.flags_1&NODROP_1)) ) )
- return TRUE
- return abiotic_hands
-
-
/mob/living/carbon/human/IsAdvancedToolUser()
- if(disabilities & MONKEYLIKE)
+ if(has_disability(MONKEYLIKE))
return FALSE
return TRUE//Humans can use guns and such
diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm
index 38dfad5787..8c913349c5 100644
--- a/code/modules/mob/living/carbon/human/interactive.dm
+++ b/code/modules/mob/living/carbon/human/interactive.dm
@@ -339,7 +339,7 @@
if(TRAITS & TRAIT_SMART)
smartness = 75
else if(TRAITS & TRAIT_DUMB)
- disabilities |= CLUMSY
+ add_disability(CLUMSY, GENETIC_MUTATION)
smartness = 25
if(TRAITS & TRAIT_MEAN)
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 4f41c2d40c..640447fc4d 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -187,7 +187,7 @@
if(G.tint)
update_tint()
if(G.vision_correction)
- if(disabilities & NEARSIGHT)
+ if(has_disability(NEARSIGHT))
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
adjust_eye_damage(0)
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 866c14242f..451fadab62 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -312,7 +312,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(!HD) //Decapitated
return
- if(H.disabilities & HUSK)
+ if(H.has_disability(HUSK))
return
var/datum/sprite_accessory/S
var/list/standing = list()
@@ -453,7 +453,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/obj/item/bodypart/head/HD = H.get_bodypart("head")
- if(HD && !(H.disabilities & HUSK))
+ if(HD && !(H.has_disability(HUSK)))
// lipstick
if(H.lip_style && (LIPS in species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[H.lip_style]", -BODY_LAYER)
@@ -724,7 +724,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(S.center)
accessory_overlay = center_image(accessory_overlay, S.dimension_x, S.dimension_y)
- if(!(H.disabilities & HUSK))
+ if(!(H.has_disability(HUSK)))
if(!forced_colour)
switch(S.color_src)
if(MUTCOLORS)
@@ -1103,16 +1103,16 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/handle_digestion(mob/living/carbon/human/H)
//The fucking FAT mutation is the dumbest shit ever. It makes the code so difficult to work with
- if(H.disabilities & FAT)//I share your pain, past coder.
+ if(H.has_disability(FAT))//I share your pain, past coder.
if(H.overeatduration < 100)
to_chat(H, "You feel fit again!")
- H.disabilities &= ~FAT
+ H.remove_disability(FAT, OBESITY)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
else
if(H.overeatduration > 500)
to_chat(H, "You suddenly feel blubbery!")
- H.disabilities |= FAT
+ H.add_disability(FAT, OBESITY)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
@@ -1269,7 +1269,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
. += (health_deficiency / 25)
if((hungry >= 70) && !flight) //Being hungry won't stop you from using flightpack controls/flapping your wings although it probably will in the wing case but who cares.
. += hungry / 50
- if(H.disabilities & FAT)
+ if(H.has_disability(FAT))
. += (1.5 - flight)
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
. += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR
@@ -1315,7 +1315,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
- if(user.disabilities & PACIFISM)
+ if(user.has_disability(PACIFISM))
to_chat(user, "You don't want to harm [target]!")
return FALSE
if(target.check_block())
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 2b86d2945d..34859a257f 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -725,7 +725,7 @@
/obj/structure/cloth_pile/proc/revive()
if(QDELETED(src) || QDELETED(cloth_golem)) //QDELETED also checks for null, so if no cloth golem is set this won't runtime
return
- if(cloth_golem.suiciding || cloth_golem.disabilities & NOCLONE)
+ if(cloth_golem.suiciding || cloth_golem.has_disability(NOCLONE))
QDEL_NULL(cloth_golem)
return
diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm
index aca6973355..cf3d676e90 100644
--- a/code/modules/mob/living/carbon/human/status_procs.dm
+++ b/code/modules/mob/living/carbon/human/status_procs.dm
@@ -11,12 +11,12 @@
amount = dna.species.spec_stun(src,amount)
return ..()
-/mob/living/carbon/human/cure_husk()
+/mob/living/carbon/human/cure_husk(list/sources)
. = ..()
if(.)
update_hair()
-/mob/living/carbon/human/become_husk()
+/mob/living/carbon/human/become_husk(source)
if(istype(dna.species, /datum/species/skeleton)) //skeletons shouldn't be husks.
cure_husk()
return
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 7264e9ad95..14f294fd90 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -609,7 +609,7 @@ generate/load female uniform sprites matching all previously decided variables
if(BP.dmg_overlay_type)
. += "-[BP.dmg_overlay_type]"
- if(disabilities & HUSK)
+ if(has_disability(HUSK))
. += "-husk"
/mob/living/carbon/human/load_limb_from_cache()
diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm
index 09d00465ee..3e6b7f3ddd 100644
--- a/code/modules/mob/living/carbon/monkey/combat.dm
+++ b/code/modules/mob/living/carbon/monkey/combat.dm
@@ -121,10 +121,8 @@
if(L == src)
return FALSE
-
- if(disabilities & PACIFISM)
+ if(has_disability(PACIFISM))
return FALSE
-
if(enemies[L])
return TRUE
diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm
index 5a4ba686b2..87058ce76d 100644
--- a/code/modules/mob/living/carbon/monkey/update_icons.dm
+++ b/code/modules/mob/living/carbon/monkey/update_icons.dm
@@ -19,7 +19,7 @@
if(!HD) //Decapitated
return
- if(disabilities & HUSK)
+ if(has_disability(HUSK))
return
var/hair_hidden = 0
diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm
index 7c40b6f144..1d5525edd9 100644
--- a/code/modules/mob/living/carbon/status_procs.dm
+++ b/code/modules/mob/living/carbon/status_procs.dm
@@ -64,43 +64,8 @@
/mob/living/carbon/set_disgust(amount)
disgust = CLAMP(amount, 0, DISGUST_LEVEL_MAXEDOUT)
-/mob/living/carbon/cure_blind()
- if(disabilities & BLIND)
- disabilities &= ~BLIND
- adjust_blindness(-1)
- return 1
-/mob/living/carbon/become_blind()
- if(!(disabilities & BLIND))
- disabilities |= BLIND
- blind_eyes(1)
- return 1
-/mob/living/carbon/cure_nearsighted()
- if(disabilities & NEARSIGHT)
- disabilities &= ~NEARSIGHT
- clear_fullscreen("nearsighted")
- return 1
-
-/mob/living/carbon/become_nearsighted()
- if(!(disabilities & NEARSIGHT))
- disabilities |= NEARSIGHT
- overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
- return 1
-
-/mob/living/carbon/cure_husk()
- if(disabilities & HUSK)
- disabilities &= ~HUSK
- status_flags &= ~DISFIGURED
- update_body()
- return 1
-
-/mob/living/carbon/become_husk()
- if(disabilities & HUSK)
- return
- disabilities |= HUSK
- status_flags |= DISFIGURED //makes them unknown
- update_body()
- return 1
+////////////////////////////////////////TRAUMAS/////////////////////////////////////////
/mob/living/carbon/proc/get_traumas()
. = list()
diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm
index 701fa0c7bc..5034abfbbe 100644
--- a/code/modules/mob/living/carbon/update_icons.dm
+++ b/code/modules/mob/living/carbon/update_icons.dm
@@ -290,7 +290,7 @@
else
. += "-robotic"
- if(disabilities & HUSK)
+ if(has_disability(HUSK))
. += "-husk"
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 3ae022cdcc..41c4572103 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -126,7 +126,7 @@
/mob/living/proc/handle_disabilities()
//Eyes
if(eye_blind) //blindness, heals slowly over time
- if(!stat && !(disabilities & BLIND))
+ if(!stat && !(has_disability(BLIND)))
eye_blind = max(eye_blind-1,0)
if(client && !eye_blind)
clear_alert("blind")
@@ -137,7 +137,7 @@
eye_blurry = max(eye_blurry-1, 0)
if(client && !eye_blurry)
clear_fullscreen("blurry")
- if(disabilities & PACIFISM && a_intent == INTENT_HARM)
+ if(has_disability(PACIFISM) && a_intent == INTENT_HARM)
to_chat(src, "You don't feel like harming anybody.")
a_intent_change(INTENT_HELP)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index fbc8e85eb4..9b47a8c66b 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -413,7 +413,6 @@
cure_nearsighted()
cure_blind()
cure_husk()
- disabilities = 0
hallucination = 0
heal_overall_damage(100000, 100000, 0, 0, 1) //heal brute and burn dmg on both organic and robotic limbs, and update health right away.
ExtinguishMob()
@@ -819,7 +818,7 @@
if(G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser())
to_chat(src, "You don't have the dexterity to do this!")
return FALSE
- if(disabilities & PACIFISM)
+ if(has_disability(PACIFISM))
to_chat(src, "You don't want to risk harming anyone!")
return FALSE
return TRUE
@@ -1064,4 +1063,4 @@
/mob/living/onTransitZ(old_z,new_z)
..()
- update_z(new_z)
\ No newline at end of file
+ update_z(new_z)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index ed07313862..4800d9fb26 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -135,11 +135,9 @@
if(!(status_flags & CANPUSH))
to_chat(user, "[src] can't be grabbed more aggressively!")
return FALSE
-
- if(user.disabilities & PACIFISM)
+ if(user.has_disability(PACIFISM))
to_chat(user, "You don't want to risk hurting [src]!")
return FALSE
-
grippedby(user)
//proc to upgrade a simple pull into a more aggressive grab.
@@ -193,10 +191,9 @@
M.Feedstop()
return // can't attack while eating!
- if(disabilities & PACIFISM)
+ if(has_disability(PACIFISM))
to_chat(M, "You don't want to hurt anyone!")
return FALSE
-
if (stat != DEAD)
add_logs(M, src, "attacked")
M.do_attack_animation(src)
@@ -210,10 +207,9 @@
M.visible_message("\The [M] [M.friendly] [src]!")
return FALSE
else
- if(M.disabilities & PACIFISM)
+ if(M.has_disability(PACIFISM))
to_chat(M, "You don't want to hurt anyone!")
return FALSE
-
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
M.do_attack_animation(src)
@@ -229,10 +225,9 @@
return FALSE
if (M.a_intent == INTENT_HARM)
- if(M.disabilities & PACIFISM)
+ if(M.has_disability(PACIFISM))
to_chat(M, "You don't want to hurt anyone!")
return FALSE
-
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
to_chat(M, "You can't bite with your mouth covered!")
return FALSE
@@ -255,10 +250,9 @@
return FALSE
else
- if(L.disabilities & PACIFISM)
+ if(L.has_disability(PACIFISM))
to_chat(L, "You don't want to hurt anyone!")
return
-
L.do_attack_animation(src)
if(prob(90))
add_logs(L, src, "attacked")
@@ -280,7 +274,7 @@
grabbedby(M)
return FALSE
if("harm")
- if(M.disabilities & PACIFISM)
+ if(M.has_disability(PACIFISM))
to_chat(M, "You don't want to hurt anyone!")
return FALSE
M.do_attack_animation(src)
@@ -370,7 +364,7 @@
//called when the mob receives a bright flash
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
- if(get_eye_protection() < intensity && (override_blindness_check || !(disabilities & BLIND)))
+ if(get_eye_protection() < intensity && (override_blindness_check || !(has_disability(BLIND))))
overlay_fullscreen("flash", type)
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
return 1
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 50f2ce4db0..6990262409 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -26,6 +26,8 @@
var/incorporeal_move = FALSE //FALSE is off, INCORPOREAL_MOVE_BASIC is normal, INCORPOREAL_MOVE_SHADOW is for ninjas
//and INCORPOREAL_MOVE_JAUNT is blocked by holy water/salt
+ var/list/disabilities = list()
+
var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them.
var/now_pushing = null //used by living/Collide() and living/PushAM() to prevent potential infinite loop.
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index b1d0484086..e21c21453a 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -285,7 +285,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return 1
/mob/living/proc/can_speak_vocal(message) //Check AFTER handling of xeno and ling channels
- if(disabilities & MUTE)
+ if(has_disability(MUTE))
return 0
if(is_muzzled())
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 4f4c364fe8..9b44c7cff3 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -1032,9 +1032,9 @@
status_flags &= ~CANPUSH
if(module.clean_on_move)
- flags_1 |= CLEAN_ON_MOVE_1
+ AddComponent(/datum/component/cleaning)
else
- flags_1 &= ~CLEAN_ON_MOVE_1
+ qdel(GetComponent(/datum/component/cleaning))
hat_offset = module.hat_offset
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index d47385efc3..79bedbe264 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -558,7 +558,7 @@ Difficulty: Very Hard
H.regenerate_limbs()
H.regenerate_organs()
H.revive(1,0)
- H.disabilities |= NOCLONE //Free revives, but significantly limits your options for reviving except via the crystal
+ H.add_disability(NOCLONE, MAGIC_DISABILITY) //Free revives, but significantly limits your options for reviving except via the crystal
H.grab_ghost(force = TRUE)
/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
@@ -719,7 +719,7 @@ Difficulty: Very Hard
if(isliving(A) && holder_animal)
var/mob/living/L = A
L.notransform = 1
- L.disabilities |= MUTE
+ L.add_disability(MUTE, STASIS_MUTE)
L.status_flags |= GODMODE
L.mind.transfer_to(holder_animal)
var/obj/effect/proc_holder/spell/targeted/exit_possession/P = new /obj/effect/proc_holder/spell/targeted/exit_possession
@@ -729,7 +729,7 @@ Difficulty: Very Hard
/obj/structure/closet/stasis/dump_contents(var/kill = 1)
STOP_PROCESSING(SSobj, src)
for(var/mob/living/L in src)
- L.disabilities &= ~MUTE
+ L.remove_disability(MUTE, STASIS_MUTE)
L.status_flags &= ~GODMODE
L.notransform = 0
if(holder_animal)
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index 3d50f03e17..0149c98a3e 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -137,3 +137,76 @@
to_chat(src, "[priority_absorb_key["self_message"]]")
priority_absorb_key["stuns_absorbed"] += amount
return TRUE
+
+/////////////////////////////////// DISABILITIES ////////////////////////////////////
+
+/mob/living/proc/add_disability(disability, source)
+ if(!disabilities[disability])
+ disabilities[disability] = list(source)
+ else
+ disabilities[disability] |= list(source)
+
+/mob/living/proc/remove_disability(disability, list/sources)
+ if(!disabilities[disability])
+ return
+
+ if(LAZYLEN(sources))
+ for(var/S in sources)
+ if(S in disabilities[disability])
+ disabilities[disability] -= S
+ else
+ disabilities[disability] = list()
+
+ if(!LAZYLEN(disabilities[disability]))
+ disabilities -= disability
+
+/mob/living/proc/has_disability(disability, list/sources)
+ if(!disabilities[disability])
+ return FALSE
+
+ . = FALSE
+
+ if(LAZYLEN(sources))
+ for(var/S in sources)
+ if(S in disabilities[disability])
+ return TRUE
+ else
+ if(LAZYLEN(disabilities[disability]))
+ return TRUE
+
+/mob/living/proc/remove_all_disabilities()
+ disabilities = list()
+
+/////////////////////////////////// DISABILITY PROCS ////////////////////////////////////
+
+/mob/living/proc/cure_blind(list/sources)
+ remove_disability(BLIND, sources)
+ if(!has_disability(BLIND))
+ adjust_blindness(-1)
+
+/mob/living/proc/become_blind(source)
+ if(!has_disability(BLIND))
+ blind_eyes(1)
+ add_disability(BLIND, source)
+
+/mob/living/proc/cure_nearsighted(list/sources)
+ remove_disability(NEARSIGHT, sources)
+ if(!has_disability(NEARSIGHT))
+ clear_fullscreen("nearsighted")
+
+/mob/living/proc/become_nearsighted(source)
+ if(!has_disability(NEARSIGHT))
+ overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
+ add_disability(NEARSIGHT, source)
+
+/mob/living/proc/cure_husk(list/sources)
+ remove_disability(HUSK, sources)
+ if(!has_disability(HUSK))
+ status_flags &= ~DISFIGURED
+ update_body()
+
+/mob/living/proc/become_husk(source)
+ if(!has_disability(HUSK))
+ status_flags |= DISFIGURED //makes them unknown
+ update_body()
+ add_disability(HUSK, source)
\ No newline at end of file
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index edbf11654b..ecbaea015f 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -32,7 +32,6 @@
var/obj/machinery/machine = null
var/other_mobs = null
- var/disabilities = 0 //Carbon
var/atom/movable/pulling = null
var/grab_state = 0
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 747d589c05..10c9a04a6e 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -285,11 +285,6 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
firstname.Find(real_name)
return firstname.match
-/mob/proc/abiotic(full_body = 0)
- for(var/obj/item/I in held_items)
- if(!(I.flags_1 & NODROP_1))
- return 1
- return 0
//change a mob's act-intent. Input the intent as a string such as "help" or use "right"/"left
/mob/verb/a_intent_change(input as text)
diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm
index 80ab6929d5..8dfadf70f5 100644
--- a/code/modules/mob/status_procs.dm
+++ b/code/modules/mob/status_procs.dm
@@ -160,8 +160,12 @@
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
else if(eye_blind)
var/blind_minimum = 0
- if((stat != CONSCIOUS && stat != SOFT_CRIT) || (disabilities & BLIND))
+ if((stat != CONSCIOUS && stat != SOFT_CRIT))
blind_minimum = 1
+ if(isliving(src))
+ var/mob/living/L = src
+ if(L.has_disability(BLIND))
+ blind_minimum = 1
eye_blind = max(eye_blind+amount, blind_minimum)
if(!eye_blind)
clear_alert("blind")
@@ -177,8 +181,12 @@
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
else if(eye_blind)
var/blind_minimum = 0
- if((stat != CONSCIOUS && stat != SOFT_CRIT) || (disabilities & BLIND))
+ if(stat != CONSCIOUS && stat != SOFT_CRIT)
blind_minimum = 1
+ if(isliving(src))
+ var/mob/living/L = src
+ if(L.has_disability(BLIND))
+ blind_minimum = 1
eye_blind = blind_minimum
if(!eye_blind)
clear_alert("blind")
@@ -227,31 +235,6 @@
/mob/proc/set_disgust(amount)
return
-/////////////////////////////////// BLIND DISABILITY ////////////////////////////////////
-
-/mob/proc/cure_blind() //when we want to cure the BLIND disability only.
- return
-
-/mob/proc/become_blind()
- return
-
-/////////////////////////////////// NEARSIGHT DISABILITY ////////////////////////////////////
-
-/mob/proc/cure_nearsighted()
- return
-
-/mob/proc/become_nearsighted()
- return
-
-
-//////////////////////////////// HUSK DISABILITY ///////////////////////////:
-
-/mob/proc/cure_husk()
- return
-
-/mob/proc/become_husk()
- return
-
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 1fb1846f4c..00fbcdc6f7 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -93,7 +93,7 @@
return
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
- if(H.disabilities & CLUMSY && prob(25))
+ if(H.has_disability(CLUMSY) && prob(25))
to_chat(H, "You cut yourself on the paper! Ahhhh! Ahhhhh!")
H.damageoverlaytemp = 9001
H.update_damage_hud()
@@ -317,7 +317,7 @@
to_chat(user, "You stamp the paper with your rubber stamp.")
if(P.is_hot())
- if(user.disabilities & CLUMSY && prob(10))
+ if(user.has_disability(CLUMSY) && prob(10))
user.visible_message("[user] accidentally ignites themselves!", \
"You miss the paper and accidentally light yourself on fire!")
user.dropItemToGround(P)
diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm
index 2d5fcc6e3a..17e2fe2a00 100644
--- a/code/modules/paperwork/paperplane.dm
+++ b/code/modules/paperwork/paperplane.dm
@@ -65,7 +65,7 @@
update_icon()
else if(P.is_hot())
- if(user.disabilities & CLUMSY && prob(10))
+ if(user.has_disability(CLUMSY) && prob(10))
user.visible_message("[user] accidentally ignites themselves!", \
"You miss [src] and accidentally light yourself on fire!")
user.dropItemToGround(P)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index ff7ed7653e..97a907031c 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -158,7 +158,7 @@
//Exclude lasertag guns from the CLUMSY check.
if(clumsy_check)
if(istype(user))
- if (user.disabilities & CLUMSY && prob(40))
+ if (user.has_disability(CLUMSY) && prob(40))
to_chat(user, "You shoot yourself in the foot with [src]!")
var/shot_leg = pick("l_leg", "r_leg")
process_fire(user,user,0,params, zone_override = shot_leg)
@@ -400,7 +400,8 @@
/obj/item/gun/dropped(mob/user)
..()
- zoom(user,FALSE)
+ if(zoomed)
+ zoom(user,FALSE)
if(azoom)
azoom.Remove(user)
if(alight)
diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm
index 563b3d9ad5..b98bdaf957 100644
--- a/code/modules/projectiles/guns/ballistic/revolver.dm
+++ b/code/modules/projectiles/guns/ballistic/revolver.dm
@@ -349,7 +349,7 @@
clumsy_check = 0
/obj/item/gun/ballistic/revolver/reverse/can_trigger_gun(mob/living/user)
- if((user.disabilities & CLUMSY) || (user.mind && user.mind.assigned_role == "Clown"))
+ if((user.has_disability(CLUMSY)) || (user.mind && user.mind.assigned_role == "Clown"))
return ..()
if(process_fire(user, user, 0, zone_override = "head"))
user.visible_message("[user] somehow manages to shoot [user.p_them()]self in the face!", "You somehow shoot yourself in the face! How the hell?!")
diff --git a/code/modules/projectiles/guns/beam_rifle.dm b/code/modules/projectiles/guns/beam_rifle.dm
index ee8036bf44..a2ea7dfb59 100644
--- a/code/modules/projectiles/guns/beam_rifle.dm
+++ b/code/modules/projectiles/guns/beam_rifle.dm
@@ -4,9 +4,6 @@
#define ZOOM_LOCK_CENTER_VIEW 2
#define ZOOM_LOCK_OFF 3
-#define ZOOM_SPEED_STEP 0
-#define ZOOM_SPEED_INSTANT 1
-
#define AUTOZOOM_PIXEL_STEP_FACTOR 48
#define AIMING_BEAM_ANGLE_CHANGE_THRESHOLD 0.1
@@ -45,7 +42,7 @@
var/lastangle = 0
var/aiming_lastangle = 0
var/mob/current_user = null
- var/obj/effect/projectile_beam/current_tracer
+ var/list/obj/effect/projectile_beam/current_tracers
var/structure_piercing = 2 //Amount * 2. For some reason structures aren't respecting this unless you have it doubled. Probably with the objects in question's Bump() code instead of this but I'll deal with this later.
var/structure_bleed_coeff = 0.7
@@ -69,9 +66,8 @@
//ZOOMING
var/zoom_current_view_increase = 0
var/zoom_target_view_increase = 10
- var/zoom_speed = ZOOM_SPEED_STEP
var/zooming = FALSE
- var/zoom_lock = ZOOM_LOCK_AUTOZOOM_FREEMOVE
+ var/zoom_lock = ZOOM_LOCK_OFF
var/zooming_angle
var/current_zoom_x = 0
var/current_zoom_y = 0
@@ -80,7 +76,6 @@
var/static/image/charged_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_charged")
var/static/image/drained_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_empty")
- var/datum/action/item_action/zoom_speed_action/zoom_speed_action
var/datum/action/item_action/zoom_lock_action/zoom_lock_action
/obj/item/gun/energy/beam_rifle/debug
@@ -103,15 +98,6 @@
. = ..()
/obj/item/gun/energy/beam_rifle/ui_action_click(owner, action)
- if(istype(action, /datum/action/item_action/zoom_speed_action))
- zoom_speed++
- if(zoom_speed > 1)
- zoom_speed = ZOOM_SPEED_STEP
- switch(zoom_speed)
- if(ZOOM_SPEED_STEP)
- to_chat(owner, "You switch [src]'s digital zoom to stepper mode.")
- if(ZOOM_SPEED_INSTANT)
- to_chat(owner, "You switch [src]'s digital zoom to instant mode.")
if(istype(action, /datum/action/item_action/zoom_lock_action))
zoom_lock++
if(zoom_lock > 3)
@@ -135,8 +121,6 @@
var/total_time = SSfastprocess.wait
if(delay_override)
total_time = delay_override
- if(zoom_speed == ZOOM_SPEED_INSTANT)
- total_time = 0
zoom_animating = total_time
animate(current_user.client, pixel_x = current_zoom_x, pixel_y = current_zoom_y , total_time, SINE_EASING, ANIMATION_PARALLEL)
zoom_animating = 0
@@ -150,18 +134,10 @@
/obj/item/gun/energy/beam_rifle/proc/handle_zooming()
if(!zooming || !check_user())
return
- if(zoom_speed == ZOOM_SPEED_INSTANT)
- current_user.client.change_view(world.view + zoom_target_view_increase)
- zoom_current_view_increase = zoom_target_view_increase
- set_autozoom_pixel_offsets_immediate(zooming_angle)
- smooth_zooming()
- return
- if(zoom_current_view_increase > zoom_target_view_increase)
- return
- zoom_current_view_increase++
- current_user.client.change_view(zoom_current_view_increase + world.view)
+ current_user.client.change_view(world.view + zoom_target_view_increase)
+ zoom_current_view_increase = zoom_target_view_increase
set_autozoom_pixel_offsets_immediate(zooming_angle)
- smooth_zooming(SSfastprocess.wait * zoom_target_view_increase * zoom_speed)
+ smooth_zooming()
/obj/item/gun/energy/beam_rifle/proc/start_zooming()
if(zoom_lock == ZOOM_LOCK_OFF)
@@ -169,8 +145,9 @@
zooming = TRUE
/obj/item/gun/energy/beam_rifle/proc/stop_zooming()
- zooming = FALSE
- reset_zooming()
+ if(zooming)
+ zooming = FALSE
+ reset_zooming()
/obj/item/gun/energy/beam_rifle/proc/reset_zooming()
if(!check_user(FALSE))
@@ -204,14 +181,14 @@
/obj/item/gun/energy/beam_rifle/Initialize()
. = ..()
+ current_tracers = list()
START_PROCESSING(SSprojectiles, src)
- zoom_speed_action = new(src)
zoom_lock_action = new(src)
/obj/item/gun/energy/beam_rifle/Destroy()
STOP_PROCESSING(SSfastprocess, src)
set_user(null)
- QDEL_NULL(current_tracer)
+ QDEL_LIST(current_tracers)
return ..()
/obj/item/gun/energy/beam_rifle/emp_act(severity)
@@ -245,6 +222,7 @@
/obj/item/gun/energy/beam_rifle/process()
if(!aiming)
+ last_process = world.time
return
check_user()
handle_zooming()
@@ -299,7 +277,7 @@
set waitfor = FALSE
aiming_time_left = aiming_time
aiming = FALSE
- QDEL_NULL(current_tracer)
+ QDEL_LIST(current_tracers)
stop_zooming()
/obj/item/gun/energy/beam_rifle/proc/set_user(mob/user)
@@ -341,7 +319,7 @@
sync_ammo()
afterattack(M.client.mouseObject, M, FALSE, M.client.mouseParams, passthrough = TRUE)
stop_aiming()
- QDEL_NULL(current_tracer)
+ QDEL_LIST(current_tracers)
return ..()
/obj/item/gun/energy/beam_rifle/afterattack(atom/target, mob/living/user, flag, params, passthrough = FALSE)
@@ -555,136 +533,103 @@
handle_impact(target)
/obj/item/projectile/beam/beam_rifle/Collide(atom/target)
- paused = TRUE
if(check_pierce(target))
permutated += target
return FALSE
if(!QDELETED(target))
cached = get_turf(target)
- paused = FALSE
. = ..()
/obj/item/projectile/beam/beam_rifle/on_hit(atom/target, blocked = FALSE)
- paused = TRUE
if(!QDELETED(target))
cached = get_turf(target)
handle_hit(target)
- paused = FALSE
. = ..()
/obj/item/projectile/beam/beam_rifle/hitscan
icon_state = ""
var/tracer_type = /obj/effect/projectile_beam/tracer
- var/starting_z
- var/starting_p_x
- var/starting_p_y
+ var/list/beam_segments //assoc list of datum/point or datum/point/vector, start = end.
var/constant_tracer = FALSE
- var/travelled_p_x = 0
- var/travelled_p_y = 0
- var/tracer_spawned = FALSE
+ var/beam_index
/obj/item/projectile/beam/beam_rifle/hitscan/Destroy()
- paused = TRUE //STOP HITTING WHEN YOU'RE ALREADY BEING DELETED!
- spawn_tracer(constant_tracer)
+ if(loc)
+ var/datum/point/pcache = trajectory.copy_to()
+ beam_segments[beam_index] = pcache
+ generate_tracers(constant_tracer)
return ..()
-/obj/item/projectile/beam/beam_rifle/hitscan/proc/spawn_tracer(put_in_rifle = FALSE)
- if(tracer_spawned)
- return
- tracer_spawned = TRUE
- //Remind me to port baystation trajectories so this shit isn't needed...
- var/pixels_travelled = round(sqrt(travelled_p_x**2 + travelled_p_y**2),1)
- var/scaling = pixels_travelled/world.icon_size
- var/midpoint_p_x = round(starting_p_x + (travelled_p_x / 2))
- var/midpoint_p_y = round(starting_p_y + (travelled_p_y / 2))
- var/tracer_px = midpoint_p_x % world.icon_size
- var/tracer_py = midpoint_p_y % world.icon_size
- var/tracer_lx = (midpoint_p_x - tracer_px) / world.icon_size
- var/tracer_ly = (midpoint_p_y - tracer_py) / world.icon_size
- var/obj/effect/projectile_beam/PB = new tracer_type(src)
- PB.apply_vars(Angle, tracer_px, tracer_py, color, scaling, locate(tracer_lx,tracer_ly,starting_z))
- if(put_in_rifle && istype(gun))
- if(gun.current_tracer)
- QDEL_NULL(gun.current_tracer)
- gun.current_tracer = PB
- else
- QDEL_IN(PB, 5)
+/obj/item/projectile/beam/beam_rifle/hitscan/Collide(atom/target)
+ var/datum/point/pcache = trajectory.copy_to()
+ . = ..()
+ if(. && !QDELETED(src)) //successful touch and not destroyed.
+ beam_segments[beam_index] = pcache
+ beam_index = pcache
+ beam_segments[beam_index] = null
-/obj/item/projectile/beam/beam_rifle/hitscan/proc/check_for_turf_edge(turf/T)
- if(!istype(T))
- return TRUE
- var/tx = T.x
- var/ty = T.y
- if(tx < 10 || tx > (world.maxx - 10) || ty < 10 || ty > (world.maxy-10))
- return TRUE
- return FALSE
+/obj/item/projectile/beam/beam_rifle/hitscan/before_z_change(turf/oldloc, turf/newloc)
+ var/datum/point/pcache = trajectory.copy_to()
+ beam_segments[beam_index] = pcache
+ beam_index = RETURN_PRECISE_POINT(newloc)
+ beam_segments[beam_index] = null
+ return ..()
+
+/obj/item/projectile/beam/beam_rifle/hitscan/proc/generate_tracers(highlander = FALSE, cleanup = TRUE)
+ set waitfor = FALSE
+ if(highlander && istype(gun))
+ QDEL_LIST(gun.current_tracers)
+ for(var/datum/point/p in beam_segments)
+ gun.current_tracers += generate_projectile_beam_between_points(p, beam_segments[p], tracer_type, color, 0)
+ else
+ for(var/datum/point/p in beam_segments)
+ generate_projectile_beam_between_points(p, beam_segments[p], tracer_type, color, 5)
+ if(cleanup)
+ QDEL_LIST(beam_segments)
+ beam_segments = null
+ QDEL_NULL(beam_index)
/obj/item/projectile/beam/beam_rifle/hitscan/fire(setAngle, atom/direct_target) //oranges didn't let me make this a var the first time around so copypasta time
- set waitfor = 0
+ set waitfor = FALSE
+ var/turf/starting = get_turf(src)
+ trajectory = new(starting.x, starting.y, starting.z, 0, 0, setAngle? setAngle : Angle, 33)
if(!log_override && firer && original)
add_logs(firer, original, "fired at", src, " [get_area(src)]")
+ fired = TRUE
if(setAngle)
Angle = setAngle
- var/next_run = world.time
- var/old_pixel_x = pixel_x
- var/old_pixel_y = pixel_y
var/safety = 0 //The code works fine, but... just in case...
var/turf/c2
- var/starting_x = loc.x
- var/starting_y = loc.y
- starting_z = loc.z
- starting_p_x = starting_x * world.icon_size + pixel_x
- starting_p_y = starting_y * world.icon_size + pixel_y
+ beam_segments = list() //initialize segment list with the list for the first segment
+ beam_index = RETURN_PRECISE_POINT(src)
+ beam_segments[beam_index] = null //record start.
+ if(spread)
+ Angle += (rand() - 0.5) * spread
while(loc)
+ if(paused || QDELETED(src))
+ return
if(++safety > (range * 3)) //If it's looping for way, way too long...
+ qdel(src)
+ stack_trace("WARNING: [type] projectile encountered infinite recursion in [__FILE__]/[__LINE__]!")
return //Kill!
- if(spread)
- Angle += (rand() - 0.5) * spread
var/matrix/M = new
M.Turn(Angle)
transform = M
- var/Pixel_x=sin(Angle)+16*sin(Angle)*2
- var/Pixel_y=cos(Angle)+16*cos(Angle)*2
- travelled_p_x += Pixel_x
- travelled_p_y += Pixel_y
- var/pixel_x_offset = old_pixel_x + Pixel_x
- var/pixel_y_offset = old_pixel_y + Pixel_y
- var/new_x = x
- var/new_y = y
- while(pixel_x_offset > 16)
- pixel_x_offset -= 32
- old_pixel_x -= 32
- new_x++// x++
- while(pixel_x_offset < -16)
- pixel_x_offset += 32
- old_pixel_x += 32
- new_x--
- while(pixel_y_offset > 16)
- pixel_y_offset -= 32
- old_pixel_y -= 32
- new_y++
- while(pixel_y_offset < -16)
- pixel_y_offset += 32
- old_pixel_y += 32
- new_y--
- pixel_x = old_pixel_x
- pixel_y = old_pixel_y
- step_towards(src, locate(new_x, new_y, z))
- next_run += max(world.tick_lag, speed)
- var/delay = next_run - world.time
- if(delay <= world.tick_lag*2)
- pixel_x = pixel_x_offset
- pixel_y = pixel_y_offset
+ trajectory.increment()
+ var/turf/T = trajectory.return_turf()
+ if(T.z != loc.z)
+ before_z_change(loc, T)
+ trajectory_ignore_forcemove = TRUE
+ forceMove(T)
+ trajectory_ignore_forcemove = FALSE
else
- animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (delay <= 3 ? delay - 1 : delay)), flags = ANIMATION_END_NOW)
- old_pixel_x = pixel_x_offset
- old_pixel_y = pixel_y_offset
+ step_towards(src, T)
+ animate(src, pixel_x = trajectory.return_px(), pixel_y = trajectory.return_py(), time = 1, flags = ANIMATION_END_NOW)
+
if(can_hit_target(original, permutated))
Collide(original)
- c2 = loc
Range()
- if(check_for_turf_edge(loc))
- spawn_tracer(constant_tracer)
+ c2 = get_turf(src)
if(istype(c2))
cached = c2
@@ -704,76 +649,3 @@
/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/on_hit()
qdel(src)
return FALSE
-
-/obj/effect/projectile_beam
- icon = 'icons/obj/projectiles.dmi'
- layer = ABOVE_MOB_LAYER
- anchored = TRUE
- light_power = 1
- light_range = 2
- light_color = "#00ffff"
- mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- flags_1 = ABSTRACT_1
- appearance_flags = 0
-
-/obj/effect/projectile_beam/proc/scale_to(nx,ny,override=TRUE)
- var/matrix/M
- if(!override)
- M = transform
- else
- M = new
- M.Scale(nx,ny)
- transform = M
-
-/obj/effect/projectile_beam/proc/turn_to(angle,override=TRUE)
- var/matrix/M
- if(!override)
- M = transform
- else
- M = new
- M.Turn(angle)
- transform = M
-
-/obj/effect/projectile_beam/New(angle_override, p_x, p_y, color_override, scaling = 1)
- if(angle_override && p_x && p_y && color_override && scaling)
- apply_vars(angle_override, p_x, p_y, color_override, scaling)
- return ..()
-
-/obj/effect/projectile_beam/proc/apply_vars(angle_override, p_x, p_y, color_override, scaling = 1, new_loc, increment = 0)
- var/mutable_appearance/look = new(src)
- look.pixel_x = p_x
- look.pixel_y = p_y
- if(color_override)
- look.color = color_override
- appearance = look
- scale_to(1,scaling, FALSE)
- turn_to(angle_override, FALSE)
- if(!isnull(new_loc)) //If you want to null it just delete it...
- forceMove(new_loc)
- for(var/i in 1 to increment)
- pixel_x += round((sin(angle_override)+16*sin(angle_override)*2), 1)
- pixel_y += round((cos(angle_override)+16*cos(angle_override)*2), 1)
-
-/obj/effect/projectile_beam/tracer
- icon_state = "tracer_beam"
-
-/obj/effect/projectile_beam/tracer/aiming
- icon_state = "gbeam"
-
-/datum/action/item_action/zoom_speed_action
- name = "Toggle Zooming Speed"
- icon_icon = 'icons/mob/actions/actions_spells.dmi'
- button_icon_state = "projectile"
- background_icon_state = "bg_tech"
-
-/datum/action/item_action/zoom_lock_action
- name = "Switch Zoom Mode"
- icon_icon = 'icons/mob/actions/actions_items.dmi'
- button_icon_state = "zoom_mode"
- background_icon_state = "bg_tech"
-
-/obj/effect/projectile_beam/singularity_pull()
- return
-
-/obj/effect/projectile_beam/singularity_act()
- return
diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm
index faf7de9010..6cbe2de450 100644
--- a/code/modules/projectiles/pins.dm
+++ b/code/modules/projectiles/pins.dm
@@ -129,7 +129,7 @@
// A gun with ultra-honk pin is useful for clown and useless for everyone else.
/obj/item/device/firing_pin/clown/ultra/pin_auth(mob/living/user)
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
- if(!(user.disabilities & CLUMSY) && !(user.mind && user.mind.assigned_role == "Clown"))
+ if(!(user.has_disability(CLUMSY)) && !(user.mind && user.mind.assigned_role == "Clown"))
return 0
return 1
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 79e2fdf903..08142f1e8d 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -31,16 +31,11 @@
var/last_projectile_move = 0
var/last_process = 0
var/time_offset = 0
- var/old_pixel_x = 0
- var/old_pixel_y = 0
- var/pixel_x_increment = 0
- var/pixel_y_increment = 0
- var/pixel_x_offset = 0
- var/pixel_y_offset = 0
- var/new_x = 0
- var/new_y = 0
+ var/datum/point/vector/trajectory
+ var/trajectory_ignore_forcemove = FALSE //instructs forceMove to NOT reset our trajectory to the new location!
var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel
+ var/pixel_speed = 33 //pixels per move - DO NOT FUCK WITH THIS UNLESS YOU ABSOLUTELY KNOW WHAT YOU ARE DOING OR UNEXPECTED THINGS /WILL/ HAPPEN!
var/Angle = 0
var/nondirectional_sprite = FALSE //Set TRUE to prevent projectiles from having their sprites rotated based on firing angle
var/spread = 0 //amount (in degrees) of projectile spread
@@ -48,6 +43,9 @@
var/ricochets = 0
var/ricochets_max = 2
var/ricochet_chance = 30
+
+ var/colliding = FALSE //pause processing..
+
var/ignore_source_check = FALSE
var/damage = 10
@@ -168,20 +166,28 @@
/obj/item/projectile/proc/vol_by_damage()
if(src.damage)
- return CLAMP((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100
+ return CLAMP((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then CLAMP the value between 30 and 100
else
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
+/obj/item/projectile/proc/on_ricochet(atom/A)
+ return
+
/obj/item/projectile/Collide(atom/A)
+ colliding = TRUE
if(check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max)
ricochets++
if(A.handle_ricochet(src))
+ on_ricochet(A)
ignore_source_check = TRUE
range = initial(range)
- return FALSE
+ return TRUE
if(firer && !ignore_source_check)
if(A == firer || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech
- loc = A.loc
+ trajectory_ignore_forcemove = TRUE
+ forceMove(get_turf(A))
+ trajectory_ignore_forcemove = FALSE
+ colliding = FALSE
return FALSE
var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations.
@@ -197,25 +203,32 @@
if(!prehit(A))
if(forcedodge)
- loc = target_turf
+ trajectory_ignore_forcemove = TRUE
+ forceMove(target_turf)
+ trajectory_ignore_forcemove = FALSE
+ colliding = FALSE
return FALSE
var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null
if(permutation == -1 || forcedodge)// the bullet passes through a dense object!
- loc = target_turf
+ trajectory_ignore_forcemove = TRUE
+ forceMove(target_turf)
+ trajectory_ignore_forcemove = FALSE
if(A)
permutated.Add(A)
+ colliding = FALSE
return FALSE
else
var/atom/alt = select_target(A)
if(alt)
if(!prehit(alt))
+ colliding = FALSE
return FALSE
alt.bullet_act(src, def_zone)
qdel(src)
+ colliding = FALSE
return TRUE
-
/obj/item/projectile/proc/select_target(atom/A) //Selects another target from a wall if we hit a wall.
if(!A || !A.density || (A.flags_1 & ON_BORDER_1) || ismob(A) || A == original) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs or machines/structures on that tile.
return
@@ -246,12 +259,30 @@
return TRUE
return FALSE
+/obj/item/projectile/proc/return_predicted_turf_after_moves(moves, forced_angle) //I say predicted because there's no telling that the projectile won't change direction/location in flight.
+ if(!trajectory && isnull(forced_angle) && isnull(Angle))
+ return FALSE
+ var/datum/point/vector/current = trajectory
+ if(!current)
+ var/turf/T = get_turf(src)
+ current = new(T.x, T.y, T.z, pixel_x, pixel_y, isnull(forced_angle)? Angle : forced_angle, pixel_speed)
+ var/datum/point/vector/v = current.return_vector_after_increments(moves)
+ return v.return_turf()
+
+/obj/item/projectile/proc/return_pathing_turfs_in_moves(moves, forced_angle)
+ var/turf/current = get_turf(src)
+ var/turf/ending = return_predicted_turf_after_moves(moves, forced_angle)
+ return getline(current, ending)
+
+/obj/item/projectile/proc/before_z_change(turf/oldloc, turf/newloc)
+ return
+
/obj/item/projectile/Process_Spacemove(var/movement_dir = 0)
return TRUE //Bullets don't drift in space
/obj/item/projectile/process()
last_process = world.time
- if(!loc || !fired)
+ if(!loc || !fired || !trajectory)
fired = FALSE
return PROCESS_KILL
if(paused || !isturf(loc))
@@ -285,73 +316,70 @@
setAngle(angle)
if(spread)
setAngle(Angle + ((rand() - 0.5) * spread))
+ var/turf/starting = get_turf(src)
if(isnull(Angle)) //Try to resolve through offsets if there's no angle set.
- var/turf/starting = get_turf(src)
+ if(isnull(xo) || isnull(yo))
+ stack_trace("WARNING: Projectile [type] deleted due to being unable to resolve a target after angle was null!")
+ qdel(src)
+ return
var/turf/target = locate(CLAMP(starting + xo, 1, world.maxx), CLAMP(starting + yo, 1, world.maxy), starting.z)
setAngle(Get_Angle(src, target))
if(!nondirectional_sprite)
var/matrix/M = new
M.Turn(Angle)
transform = M
- old_pixel_x = pixel_x
- old_pixel_y = pixel_y
+ trajectory = new(starting.x, starting.y, starting.z, 0, 0, Angle, pixel_speed)
last_projectile_move = world.time
fired = TRUE
if(!isprocessing)
START_PROCESSING(SSprojectiles, src)
+ pixel_move(1) //move it now!
/obj/item/projectile/proc/setAngle(new_angle) //wrapper for overrides.
Angle = new_angle
- return TRUE
-
-/obj/item/projectile/proc/pixel_move(moves)
if(!nondirectional_sprite)
var/matrix/M = new
M.Turn(Angle)
transform = M
+ if(trajectory)
+ trajectory.set_angle(new_angle)
+ return TRUE
- pixel_x_increment=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here
- pixel_y_increment=round((cos(Angle)+16*cos(Angle)*2), 1)
- pixel_x_offset = old_pixel_x + pixel_x_increment
- pixel_y_offset = old_pixel_y + pixel_y_increment
- new_x = x
- new_y = y
+/obj/item/projectile/forceMove(atom/target)
+ . = ..()
+ if(trajectory && !trajectory_ignore_forcemove && isturf(target))
+ trajectory.initialize_location(target.x, target.y, target.z, 0, 0)
- while(pixel_x_offset > 16)
- pixel_x_offset -= 32
- old_pixel_x -= 32
- new_x++// x++
- while(pixel_x_offset < -16)
- pixel_x_offset += 32
- old_pixel_x += 32
- new_x--
- while(pixel_y_offset > 16)
- pixel_y_offset -= 32
- old_pixel_y -= 32
- new_y++
- while(pixel_y_offset < -16)
- pixel_y_offset += 32
- old_pixel_y += 32
- new_y--
+/obj/item/projectile/proc/pixel_move(moves, trajectory_multiplier = 1)
+ if(!loc || !trajectory)
+ return
+ last_projectile_move = world.time
+ if(!nondirectional_sprite)
+ var/matrix/M = new
+ M.Turn(Angle)
+ transform = M
+ trajectory.increment(trajectory_multiplier)
+ var/turf/T = trajectory.return_turf()
+ if(T.z != loc.z)
+ before_z_change(loc, T)
+ trajectory_ignore_forcemove = TRUE
+ forceMove(T)
+ trajectory_ignore_forcemove = FALSE
+ pixel_x = trajectory.return_px()
+ pixel_y = trajectory.return_py()
+ else
+ step_towards(src, T)
+ pixel_x = trajectory.return_px() - trajectory.mpx * trajectory_multiplier
+ pixel_y = trajectory.return_py() - trajectory.mpy * trajectory_multiplier
+ animate(src, pixel_x = trajectory.return_px(), pixel_y = trajectory.return_py(), time = 1, flags = ANIMATION_END_NOW)
- step_towards(src, locate(new_x, new_y, z))
- pixel_x = old_pixel_x
- pixel_y = old_pixel_y
- animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = 1, flags = ANIMATION_END_NOW)
- old_pixel_x = pixel_x_offset
- old_pixel_y = pixel_y_offset
if(can_hit_target(original, permutated))
Collide(original)
Range()
- last_projectile_move = world.time
//Returns true if the target atom is on our current turf and above the right layer
/obj/item/projectile/proc/can_hit_target(atom/target, var/list/passthrough)
- if(target && (target.layer >= PROJECTILE_HIT_THRESHHOLD_LAYER) || ismob(target))
- if(loc == get_turf(target))
- if(!(target in passthrough))
- return TRUE
- return FALSE
+ return (target && ((target.layer >= PROJECTILE_HIT_THRESHHOLD_LAYER) || ismob(target)) && (loc == get_turf(target)) && (!(target in passthrough)))
/obj/item/projectile/proc/preparePixelProjectile(atom/target, atom/source, params, spread = 0)
var/turf/curloc = get_turf(source)
@@ -362,7 +390,8 @@
if(targloc || !params)
yo = targloc.y - curloc.y
xo = targloc.x - curloc.x
-
+ setAngle(Get_Angle(src, targloc))
+
if(isliving(source) && params)
var/list/calculated = calculate_projectile_angle_and_pixel_offsets(source, params)
p_x = calculated[2]
@@ -372,8 +401,13 @@
setAngle(calculated[1] + spread)
else
setAngle(calculated[1])
- else
+ else if(targloc)
+ yo = targloc.y - curloc.y
+ xo = targloc.x - curloc.x
setAngle(Get_Angle(src, targloc))
+ else
+ stack_trace("WARNING: Projectile [type] fired without either mouse parameters, or a target atom to aim at!")
+ qdel(src)
/proc/calculate_projectile_angle_and_pixel_offsets(mob/user, params)
var/list/mouse_control = params2list(params)
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index e3de96e0b4..0bb00f5b49 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -70,7 +70,7 @@
//nothing
if(21 to INFINITY)
if(prob(current_cycle-10))
- M.cure_nearsighted()
+ M.cure_nearsighted(list(EYE_DAMAGE))
..()
return
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index a3c0d2c034..a9f9145972 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -97,10 +97,10 @@
/datum/reagent/consumable/cooking_oil/reaction_obj(obj/O, reac_volume)
if(holder && holder.chem_temp >= fry_temperature)
- if(isitem(O))
+ if(isitem(O) && !istype(O, /obj/item/reagent_containers/food/snacks/deepfryholder))
O.loc.visible_message("[O] rapidly fries as it's splashed with hot oil! Somehow.")
- var/obj/item/reagent_containers/food/snacks/deepfryholder/F = new(O.drop_location())
- F.fry(O, volume)
+ var/obj/item/reagent_containers/food/snacks/deepfryholder/F = new(O.drop_location(), O)
+ F.fry(volume)
/datum/reagent/consumable/cooking_oil/reaction_mob(mob/living/M, method = TOUCH, reac_volume, show_message = 1, touch_protection = 0)
if(!istype(M))
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index ddb08db032..03134784a4 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -44,7 +44,7 @@
M.adjustToxLoss(-5, 0)
M.hallucination = 0
M.setBrainLoss(0)
- M.disabilities = 0
+ M.remove_all_disabilities()
M.set_blurriness(0)
M.set_blindness(0)
M.SetKnockdown(0, 0)
@@ -667,16 +667,16 @@
var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return
- if(M.disabilities & BLIND)
+ if(M.has_disability(BLIND, EYE_DAMAGE))
if(prob(20))
to_chat(M, "Your vision slowly returns...")
- M.cure_blind()
- M.cure_nearsighted()
+ M.cure_blind(EYE_DAMAGE)
+ M.cure_nearsighted(EYE_DAMAGE)
M.blur_eyes(35)
- else if(M.disabilities & NEARSIGHT)
+ else if(M.has_disability(NEARSIGHT, EYE_DAMAGE))
to_chat(M, "The blackness in your peripheral vision fades.")
- M.cure_nearsighted()
+ M.cure_nearsighted(EYE_DAMAGE)
M.blur_eyes(10)
else if(M.eye_blind || M.eye_blurry)
M.set_blindness(0)
@@ -765,7 +765,7 @@
M.visible_message("[M]'s body convulses a bit, and then falls still once more.")
return
M.visible_message("[M]'s body convulses a bit.")
- if(!M.suiciding && !(M.disabilities & NOCLONE) && !M.hellbound)
+ if(!M.suiciding && !(M.has_disability(NOCLONE)) && !M.hellbound)
if(!M)
return
if(M.notify_ghost_cloning(source = M))
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index 7bee2ef958..0a6288896a 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -141,7 +141,7 @@
taste_description = "mint"
/datum/reagent/toxin/minttoxin/on_mob_life(mob/living/M)
- if(M.disabilities & FAT)
+ if(M.has_disability(FAT))
M.gib()
return ..()
diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm
index 283ac0f35c..ee5a435a86 100644
--- a/code/modules/shuttle/syndicate.dm
+++ b/code/modules/shuttle/syndicate.dm
@@ -56,8 +56,8 @@
shuttlePortName = "custom location"
jumpto_ports = list("syndicate_ne" = 1, "syndicate_nw" = 1, "syndicate_n" = 1, "syndicate_se" = 1, "syndicate_sw" = 1, "syndicate_s" = 1)
view_range = 13
- x_offset = -4
- y_offset = -2
+ x_offset = -7
+ y_offset = -1
see_hidden = TRUE
#undef SYNDICATE_CHALLENGE_TIMER
\ No newline at end of file
diff --git a/code/modules/space_transition/space_transition.dm b/code/modules/space_transition/space_transition.dm
index 2a8be8a761..edcad9b620 100644
--- a/code/modules/space_transition/space_transition.dm
+++ b/code/modules/space_transition/space_transition.dm
@@ -19,7 +19,7 @@ GLOBAL_LIST_EMPTY(z_levels_list)
neigbours[A] = src
/datum/space_level/proc/set_neigbours(list/L)
- for(var/datum/point/P in L)
+ for(var/datum/space_transition_point/P in L)
if(P.x == xi)
if(P.y == yi+1)
neigbours[TEXT_NORTH] = P.spl
@@ -35,13 +35,13 @@ GLOBAL_LIST_EMPTY(z_levels_list)
neigbours[TEXT_WEST] = P.spl
P.spl.neigbours[TEXT_EAST] = src
-/datum/point //this is explicitly utilitarian datum type made specially for the space map generation and are absolutely unusable for anything else
+/datum/space_transition_point //this is explicitly utilitarian datum type made specially for the space map generation and are absolutely unusable for anything else
var/list/neigbours = list()
var/x
var/y
var/datum/space_level/spl
-/datum/point/New(nx, ny, list/point_grid)
+/datum/space_transition_point/New(nx, ny, list/point_grid)
if(!point_grid)
qdel(src)
return
@@ -55,7 +55,7 @@ GLOBAL_LIST_EMPTY(z_levels_list)
return
point_grid[x][y] = src
-/datum/point/proc/set_neigbours(list/grid)
+/datum/space_transition_point/proc/set_neigbours(list/grid)
var/max_X = grid.len
var/list/max_Y = grid[1]
max_Y = max_Y.len
@@ -86,13 +86,13 @@ GLOBAL_LIST_EMPTY(z_levels_list)
k++
var/list/point_grid[conf_set_len*2+1][conf_set_len*2+1]
var/list/grid = list()
- var/datum/point/P
+ var/datum/space_transition_point/P
for(var/i = 1, i<=conf_set_len*2+1, i++)
for(var/j = 1, j<=conf_set_len*2+1, j++)
- P = new/datum/point(i,j, point_grid)
+ P = new/datum/space_transition_point(i,j, point_grid)
point_grid[i][j] = P
grid.Add(P)
- for(var/datum/point/pnt in grid)
+ for(var/datum/space_transition_point/pnt in grid)
pnt.set_neigbours(point_grid)
P = point_grid[conf_set_len+1][conf_set_len+1]
var/list/possible_points = list()
diff --git a/code/modules/spells/spell_types/construct_spells.dm b/code/modules/spells/spell_types/construct_spells.dm
index ca6a534ee0..8e9b4fb1e4 100644
--- a/code/modules/spells/spell_types/construct_spells.dm
+++ b/code/modules/spells/spell_types/construct_spells.dm
@@ -209,12 +209,14 @@
to_chat(target, "A freezing darkness surrounds you...")
target.playsound_local(get_turf(target), 'sound/hallucinations/i_see_you1.ogg', 50, 1)
user.playsound_local(get_turf(user), 'sound/effects/ghost2.ogg', 50, 1)
- target.adjust_blindness(5)
+ target.become_blind("abyssal_gaze")
addtimer(CALLBACK(src, .proc/cure_blindness, target), 40)
target.bodytemperature -= 200
/obj/effect/proc_holder/spell/targeted/abyssal_gaze/proc/cure_blindness(mob/target)
- target.adjust_blindness(-5)
+ if(isliving(target))
+ var/mob/living/L = target
+ L.cure_blind(BLIND, "abyssal_gaze")
/obj/effect/proc_holder/spell/targeted/dominate
name = "Dominate"
diff --git a/code/modules/spells/spell_types/genetic.dm b/code/modules/spells/spell_types/genetic.dm
index c6945dab50..1b60800458 100644
--- a/code/modules/spells/spell_types/genetic.dm
+++ b/code/modules/spells/spell_types/genetic.dm
@@ -1,32 +1,34 @@
-/obj/effect/proc_holder/spell/targeted/genetic
- name = "Genetic"
- desc = "This spell inflicts a set of mutations and disabilities upon the target."
-
- var/disabilities = 0 //bits
- var/list/mutations = list() //mutation strings
- var/duration = 100 //deciseconds
- /*
- Disabilities
- 1st bit - ?
- 2nd bit - ?
- 3rd bit - ?
- 4th bit - ?
- 5th bit - ?
- 6th bit - ?
- */
-
-/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets,mob/user = usr)
- playMagSound()
- for(var/mob/living/carbon/target in targets)
- if(!target.dna)
- continue
- for(var/A in mutations)
- target.dna.add_mutation(A)
- target.disabilities |= disabilities
+/obj/effect/proc_holder/spell/targeted/genetic
+ name = "Genetic"
+ desc = "This spell inflicts a set of mutations and disabilities upon the target."
+
+ var/list/disabilities = list() //disabilities
+ var/list/mutations = list() //mutation strings
+ var/duration = 100 //deciseconds
+ /*
+ Disabilities
+ 1st bit - ?
+ 2nd bit - ?
+ 3rd bit - ?
+ 4th bit - ?
+ 5th bit - ?
+ 6th bit - ?
+ */
+
+/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets,mob/user = usr)
+ playMagSound()
+ for(var/mob/living/carbon/target in targets)
+ if(!target.dna)
+ continue
+ for(var/A in mutations)
+ target.dna.add_mutation(A)
+ for(var/A in disabilities)
+ target.add_disability(A, GENETICS_SPELL)
addtimer(CALLBACK(src, .proc/remove, target), duration)
/obj/effect/proc_holder/spell/targeted/genetic/proc/remove(mob/living/carbon/target)
if(!QDELETED(target))
for(var/A in mutations)
target.dna.remove_mutation(A)
- target.disabilities &= ~disabilities
+ for(var/A in disabilities)
+ target.remove_disability(A, GENETICS_SPELL)
diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm
index 790942d897..474075591f 100644
--- a/code/modules/surgery/bodyparts/bodyparts.dm
+++ b/code/modules/surgery/bodyparts/bodyparts.dm
@@ -217,7 +217,7 @@
C = owner
no_update = 0
- if(C.disabilities & HUSK)
+ if(C.has_disability(HUSK))
species_id = "husk" //overrides species_id
dmg_overlay_type = "" //no damage overlay shown when husked
should_draw_gender = FALSE
diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm
index f631400bee..464da21e44 100644
--- a/code/modules/surgery/bodyparts/head.dm
+++ b/code/modules/surgery/bodyparts/head.dm
@@ -61,7 +61,7 @@
C = owner
real_name = C.real_name
- if(C.disabilities & HUSK)
+ if(C.has_disability(HUSK))
real_name = "Unknown"
hair_style = "Bald"
facial_hair_style = "Shaved"
diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm
index c8a47d2096..00a9a99bb0 100644
--- a/code/modules/surgery/eye_surgery.dm
+++ b/code/modules/surgery/eye_surgery.dm
@@ -23,9 +23,9 @@
/datum/surgery_step/fix_eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] successfully fixes [target]'s eyes!", "You succeed in fixing [target]'s eyes.")
- target.cure_blind()
+ target.cure_blind(list(EYE_DAMAGE))
target.set_blindness(0)
- target.cure_nearsighted()
+ target.cure_nearsighted(list(EYE_DAMAGE))
target.blur_eyes(35) //this will fix itself slowly.
target.set_eye_damage(0)
return TRUE
diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm
index 488f2e81b1..ba43a5cc3b 100644
--- a/code/modules/surgery/lipoplasty.dm
+++ b/code/modules/surgery/lipoplasty.dm
@@ -4,7 +4,7 @@
possible_locs = list("chest")
/datum/surgery/lipoplasty/can_start(mob/user, mob/living/carbon/target)
- if(target.disabilities & FAT)
+ if(target.has_disability(FAT))
return 1
return 0
diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm
index 98b2a84ac0..905f9c2e1f 100644
--- a/code/modules/surgery/organs/ears.dm
+++ b/code/modules/surgery/organs/ears.dm
@@ -25,7 +25,7 @@
return
var/mob/living/carbon/C = owner
// genetic deafness prevents the body from using the ears, even if healthy
- if(C.disabilities & DEAF)
+ if(C.has_disability(DEAF))
deaf = max(deaf, 1)
else
if(C.ears && (C.ears.flags_2 & HEALS_EARS_2))
@@ -42,7 +42,7 @@
var/mob/living/carbon/C = owner
- if(iscarbon(owner) && C.disabilities & DEAF)
+ if(iscarbon(owner) && C.has_disability(DEAF))
deaf = 1
/obj/item/organ/ears/proc/adjustEarDamage(ddmg, ddeaf)
diff --git a/code/modules/vehicles/pimpin_ride.dm b/code/modules/vehicles/pimpin_ride.dm
index 3925b863ff..88524366a6 100644
--- a/code/modules/vehicles/pimpin_ride.dm
+++ b/code/modules/vehicles/pimpin_ride.dm
@@ -13,6 +13,9 @@
var/datum/component/riding/D = LoadComponent(/datum/component/riding)
D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 7), TEXT_EAST = list(-12, 7), TEXT_WEST = list( 12, 7)))
+ if(floorbuffer)
+ AddComponent(/datum/component/cleaning)
+
/obj/vehicle/ridden/janicart/Destroy()
if(mybag)
qdel(mybag)
@@ -47,7 +50,7 @@
floorbuffer = TRUE
qdel(I)
to_chat(user, "You upgrade [src] with the floor buffer.")
- flags_1 |= CLEAN_ON_MOVE_1
+ AddComponent(/datum/component/cleaning)
update_icon()
else
return ..()
diff --git a/html/changelogs/AutoChangeLog-pr-3639.yml b/html/changelogs/AutoChangeLog-pr-3639.yml
deleted file mode 100644
index 3625dfce90..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3639.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Antags are able to greentext again"
diff --git a/html/changelogs/AutoChangeLog-pr-3731.yml b/html/changelogs/AutoChangeLog-pr-3731.yml
deleted file mode 100644
index 9486c7e793..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3731.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "ninjanomnom"
-delete-after: True
-changes:
- - bugfix: "Singularity objects no longer become contaminated by radiation."
- - admin: "Removed the radiation message admin spam and moved it to an investigation log."
diff --git a/html/changelogs/AutoChangeLog-pr-3747.yml b/html/changelogs/AutoChangeLog-pr-3747.yml
deleted file mode 100644
index 46ad021439..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3747.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ACCount"
-delete-after: True
-changes:
- - tweak: "\"Tail removal\" and \"tail attachment\" surgeries are merged with \"organ manipulation\"."
diff --git a/html/changelogs/AutoChangeLog-pr-3818.yml b/html/changelogs/AutoChangeLog-pr-3818.yml
deleted file mode 100644
index 1be3ec57f4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3818.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Swindly"
-delete-after: True
-changes:
- - bugfix: "You can now cancel a cavity implant during the implanting/removing step by using drapes while holding the appropriate tool in your inactive hand. Cyborgs can cancel the surgery by using drapes alone."
diff --git a/html/changelogs/AutoChangeLog-pr-3858.yml b/html/changelogs/AutoChangeLog-pr-3858.yml
deleted file mode 100644
index 2243f683c0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3858.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "deathride58 & TGstation contributors"
-delete-after: True
-changes:
- - bugfix: "Fixed various area issues in Boxstation. The theatre no longer has an air alarm for space, and Security no longer has a line of walls with broken lighting."
- - tweak: "Added more lights to Boxstation's security"
- - rscadd: "(Upstream) Added a new white ship to Deltastation"
- - tweak: "(Upstream) Replaced the reinforced glass in Atmos' gas tanks with reinforced plasma glass"
- - tweak: "(Upstream) Atmos can no longer burn itself down via the waste loop outlet"
diff --git a/html/changelogs/AutoChangeLog-pr-3864.yml b/html/changelogs/AutoChangeLog-pr-3864.yml
deleted file mode 100644
index 2ff6cc010e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3864.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - tweak: "Cooldown on the Ripley's mining drills has been halved."
- - tweak: "The frequency of the Ripley's ore pulse has been doubled."
diff --git a/html/changelogs/AutoChangeLog-pr-3871.yml b/html/changelogs/AutoChangeLog-pr-3871.yml
deleted file mode 100644
index 910a5893eb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3871.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Bluespace shelter walls no longer smooth with non-shelter walls and windows."
diff --git a/html/changelogs/AutoChangeLog-pr-3879.yml b/html/changelogs/AutoChangeLog-pr-3879.yml
deleted file mode 100644
index 440ea3e616..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3879.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "as334"
-delete-after: True
-changes:
- - rscadd: "Pluoxium can now be formed by irradiating tiles with CO2 in the air."
- - rscadd: "Rad collectors now steadily form Tritium at a slow pace."
- - balance: "Nerfs fusion by making it slower, and produce radioactivity."
- - balance: "Noblium formation now requires significantly more energy input."
- - balance: "Tanks now melt if their temperature is above 1 Million Kelvin."
diff --git a/html/changelogs/AutoChangeLog-pr-3881.yml b/html/changelogs/AutoChangeLog-pr-3881.yml
deleted file mode 100644
index da5bf113eb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3881.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Mark9013100"
-delete-after: True
-changes:
- - tweak: "Charcoal bottles have been renamed, and have been given a more informative description."
diff --git a/html/changelogs/AutoChangeLog-pr-3884.yml b/html/changelogs/AutoChangeLog-pr-3884.yml
deleted file mode 100644
index cccc830fa8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3884.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "You can no longer delete girders, lattices, or catwalks with the RPD"
- - bugfix: "Fixes runtimes that occur when clicking girders, lattices, catwalks, or disposal pipes with the RPD in paint mode"
diff --git a/html/changelogs/AutoChangeLog-pr-3886.yml b/html/changelogs/AutoChangeLog-pr-3886.yml
deleted file mode 100644
index df6baaf9e8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3886.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Clockwork slabs no longer refer to components"
diff --git a/html/changelogs/AutoChangeLog-pr-3887.yml b/html/changelogs/AutoChangeLog-pr-3887.yml
deleted file mode 100644
index 6abe71ce5d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3887.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "DaxDupont"
-delete-after: True
-changes:
- - bugfix: "Medbots can inject from one tile away again."
diff --git a/html/changelogs/AutoChangeLog-pr-3889.yml b/html/changelogs/AutoChangeLog-pr-3889.yml
deleted file mode 100644
index 0dbe1a4a54..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3889.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "The detective and heads of staff are no longer attacked by portable turrets."
diff --git a/html/changelogs/AutoChangeLog-pr-3892.yml b/html/changelogs/AutoChangeLog-pr-3892.yml
deleted file mode 100644
index d56a3291ca..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3892.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ninjanomnom"
-delete-after: True
-changes:
- - bugfix: "Fixes ruin cable spawning and probably some other bugs"
diff --git a/html/changelogs/AutoChangeLog-pr-3900.yml b/html/changelogs/AutoChangeLog-pr-3900.yml
deleted file mode 100644
index aea022be12..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3900.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Qbopper and JJRcop"
-delete-after: True
-changes:
- - tweak: "The default internet sound volume was changed from 100 to 25. Stop complaining in OOC about your ears!"
diff --git a/html/changelogs/AutoChangeLog-pr-3901.yml b/html/changelogs/AutoChangeLog-pr-3901.yml
deleted file mode 100644
index ac91a766d7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3901.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "nicn"
-delete-after: True
-changes:
- - balance: "Damage from low pressure has been doubled."
diff --git a/html/changelogs/AutoChangeLog-pr-3908.yml b/html/changelogs/AutoChangeLog-pr-3908.yml
deleted file mode 100644
index bd69080a7d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3908.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Posters may no longer be placed on diagonal wall corners."
diff --git a/html/changelogs/AutoChangeLog-pr-3912.yml b/html/changelogs/AutoChangeLog-pr-3912.yml
deleted file mode 100644
index 85cf3a8454..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3912.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - rscadd: "Deep fryers now have sound."
- - tweak: "Deep fryers now use cooking oil, a specialized reagent that becomes highly damaging at high temperatures. You can get it from grinding soybeans and meat."
- - tweak: "Deep fryers now become more efficient with higher-level micro lasers, using less oil and frying faster."
- - tweak: "Deep fryers now slowly use oil as it fries objects, instead of all at once."
- - bugfix: "You can now correctly refill deep fryers with syringes and pills."
- - rscadd: "Microwaves have new sounds!"
diff --git a/html/changelogs/AutoChangeLog-pr-3913.yml b/html/changelogs/AutoChangeLog-pr-3913.yml
deleted file mode 100644
index c2a59fe367..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3913.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Cobby"
-delete-after: True
-changes:
- - rscadd: "The Xray now only hits the first mob it comes into contact with instead of being outright removed from the game."
diff --git a/html/changelogs/AutoChangeLog-pr-3916.yml b/html/changelogs/AutoChangeLog-pr-3916.yml
deleted file mode 100644
index e61e4d044c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3916.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Frozenguy5"
-delete-after: True
-changes:
- - bugfix: "Broken cable cuffs no longer has an invisible sprite."
diff --git a/html/changelogs/AutoChangeLog-pr-3919.yml b/html/changelogs/AutoChangeLog-pr-3919.yml
deleted file mode 100644
index ab0e21a5d3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3919.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Floyd / Qustinnus"
-delete-after: True
-changes:
- - soundadd: "Reebe now has ambience sounds"
diff --git a/html/changelogs/AutoChangeLog-pr-3920.yml b/html/changelogs/AutoChangeLog-pr-3920.yml
deleted file mode 100644
index 8111335f02..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3920.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "LetterJay"
-delete-after: True
-changes:
- - bugfix: "Flavor text can be examined again"
diff --git a/html/changelogs/AutoChangeLog-pr-3951.yml b/html/changelogs/AutoChangeLog-pr-3951.yml
deleted file mode 100644
index 6dcac4a2d3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3951.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "SpiderPsycho"
-delete-after: True
-changes:
- - rscadd: "Added insects without fuzz"
- - rscdel: "Removed fuzz"
- - tweak: "changed the name of the fuzzless sprites to insects so the character creation can call them properly."
diff --git a/html/changelogs/AutoChangeLog-pr-3959.yml b/html/changelogs/AutoChangeLog-pr-3959.yml
deleted file mode 100644
index f89f2489dd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3959.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "disable_warning wasn't getting checked and the chat was being spammed"
diff --git a/html/changelogs/AutoChangeLog-pr-3960.yml b/html/changelogs/AutoChangeLog-pr-3960.yml
deleted file mode 100644
index dd9ab1e232..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3960.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "cell chargers weren't animating properly"
diff --git a/html/changelogs/AutoChangeLog-pr-3961.yml b/html/changelogs/AutoChangeLog-pr-3961.yml
deleted file mode 100644
index 52f66a3b46..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3961.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ike709"
-delete-after: True
-changes:
- - imageadd: "Added new vent and scrubber sprites by Partheo."
diff --git a/html/changelogs/AutoChangeLog-pr-3964.yml b/html/changelogs/AutoChangeLog-pr-3964.yml
deleted file mode 100644
index 6061524af8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3964.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "Atmos scrubbers (vent and portable) can now filter any and all gases."
diff --git a/html/changelogs/AutoChangeLog-pr-3966.yml b/html/changelogs/AutoChangeLog-pr-3966.yml
deleted file mode 100644
index 40cdd5ec13..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3966.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - bugfix: "Sped up saycode to remove free lag from highpop"
diff --git a/html/changelogs/AutoChangeLog-pr-3967.yml b/html/changelogs/AutoChangeLog-pr-3967.yml
deleted file mode 100644
index 28378bcc30..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3967.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "DaxDupont"
-delete-after: True
-changes:
- - tweak: "CentCom has issued a firmware updated for the operating computers. It is no longer needed to manually refresh the procedure and patient status."
diff --git a/html/changelogs/AutoChangeLog-pr-3968.yml b/html/changelogs/AutoChangeLog-pr-3968.yml
deleted file mode 100644
index 3430a1e8cb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3968.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "JJRcop"
-delete-after: True
-changes:
- - bugfix: "Fixes changeling eggs not putting the changeling in control if the brainslug is destroyed before hatching."
diff --git a/html/changelogs/AutoChangeLog-pr-3969.yml b/html/changelogs/AutoChangeLog-pr-3969.yml
deleted file mode 100644
index 7f53c200d6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3969.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "HUDs from mechs and helmets no longer conflict with HUD glasses and no longer inappropriately remove implanted HUDs."
diff --git a/html/changelogs/AutoChangeLog-pr-3975.yml b/html/changelogs/AutoChangeLog-pr-3975.yml
deleted file mode 100644
index 450706db1f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3975.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "DaxDupont"
-delete-after: True
-changes:
- - bugfix: "Proximity sensors no longer beep when unarmed."
diff --git a/html/changelogs/AutoChangeLog-pr-3976.yml b/html/changelogs/AutoChangeLog-pr-3976.yml
deleted file mode 100644
index b3d144e1de..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3976.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Iamgoofball"
-delete-after: True
-changes:
- - spellcheck: "fixed grammar on output circuits"
diff --git a/html/changelogs/AutoChangeLog-pr-3977.yml b/html/changelogs/AutoChangeLog-pr-3977.yml
deleted file mode 100644
index a4916a713e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3977.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Iamgoofball"
-delete-after: True
-changes:
- - spellcheck: "fixes grammar on list circuits"
diff --git a/html/changelogs/AutoChangeLog-pr-3978.yml b/html/changelogs/AutoChangeLog-pr-3978.yml
deleted file mode 100644
index 0840869b16..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3978.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Iamgoofball"
-delete-after: True
-changes:
- - spellcheck: "fixes grammar on logic gate descriptions"
diff --git a/html/changelogs/AutoChangeLog-pr-3979.yml b/html/changelogs/AutoChangeLog-pr-3979.yml
deleted file mode 100644
index e9a21ef984..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3979.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Iamgoofball"
-delete-after: True
-changes:
- - bugfix: "fixes grammar on trig circuits"
diff --git a/html/changelogs/AutoChangeLog-pr-3980.yml b/html/changelogs/AutoChangeLog-pr-3980.yml
deleted file mode 100644
index 09e3ebe5ef..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3980.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "MMMiracles"
-delete-after: True
-changes:
- - balance: "Power regen on the regular tesla relay has been reduced to 50, from 150."
diff --git a/html/changelogs/AutoChangeLog-pr-3981.yml b/html/changelogs/AutoChangeLog-pr-3981.yml
deleted file mode 100644
index 0670048ed3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3981.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "nicbn"
-delete-after: True
-changes:
- - soundadd: "Now rolling beds and office chairs have a sound!"
diff --git a/html/changelogs/AutoChangeLog-pr-3983.yml b/html/changelogs/AutoChangeLog-pr-3983.yml
deleted file mode 100644
index 0e3a681757..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3983.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "oranges"
-delete-after: True
-changes:
- - rscdel: "Removed the shocker circuit"
diff --git a/html/changelogs/AutoChangeLog-pr-3988.yml b/html/changelogs/AutoChangeLog-pr-3988.yml
deleted file mode 100644
index 743551eaaa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3988.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "DaxDupont"
-delete-after: True
-changes:
- - bugfix: "Plant trays will now properly process fluorine and adjust toxins and water contents."
diff --git a/html/changelogs/AutoChangeLog-pr-3992.yml b/html/changelogs/AutoChangeLog-pr-3992.yml
deleted file mode 100644
index b60be8068c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3992.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "JJRcop"
-delete-after: True
-changes:
- - tweak: "The silicon airlock menu looks a little more like it used to."
diff --git a/html/changelogs/AutoChangeLog-pr-3993.yml b/html/changelogs/AutoChangeLog-pr-3993.yml
deleted file mode 100644
index 14c4d31514..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3993.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "purple bartender suit and apron added to clothesmates!"
- - rscadd: "long hair 3 added, check it out. both have sprites from okand!"
diff --git a/html/changelogs/AutoChangeLog-pr-3994.yml b/html/changelogs/AutoChangeLog-pr-3994.yml
deleted file mode 100644
index 2ff513ddf5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3994.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "The RPD has a shiny new UI!"
- - rscadd: "The RPD can now paint pipes as it lays them, for quicker piping projects."
diff --git a/html/changelogs/AutoChangeLog-pr-3995.yml b/html/changelogs/AutoChangeLog-pr-3995.yml
deleted file mode 100644
index 77d6c658da..0000000000
--- a/html/changelogs/AutoChangeLog-pr-3995.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-author: "ShizCalev (Upstream), WJohnston (Upstream), Okand37 (Upstream), deathride58"
-delete-after: True
-changes:
- - tweak: "(Upstream) The computers on all maps have have been updated for the latest directional sprite changes. Please report any computers facing in strange directions to your nearest mapper."
- - rscadd: "(Upstream) Updated the Test Map debugging verb to report more issues regarding APCs.
-DELTASTATION"
- - bugfix: "(Upstream) Reverted Okand37's morgue changes which broke power in the area."
- - bugfix: "(Upstream) Corrected wrong area on the Southern airlock leading into electrical maintenance.
-ALL STATIONS"
- - bugfix: "(Upstream) Corrected numerous duplicate APCs in areas which led to power issues."
- - rscdel: "(Upstream) Removes stationary docking ports for syndicate infiltrator ships on all maps. Use the docking navigator computer instead! This gives the white ship and syndicate infiltrator more room to navigate and place custom locations that are otherwise occupied by fixed shuttle landing zones that are rarely used."
- - rscadd: "(Upstream, Deltastation) Tweaked Atmospherics"
- - bugfix: "(Upstream, Deltastation) Fixed the Incinerator air injector"
- - rscadd: "(Upstream, Deltastation) Tweaked Engineering"
- - rscadd: "(Upstream, Deltastation) Added logs to the Chaplain's closet for gimmicks (bonfires)"
- - rscadd: "(Upstream, Deltastation) Tweaked Security"
- - bugfix: "(Upstream, Deltastation) Fixed medical morgue maintenance not providing radiation shielding and exterior chemistry windoor"
- - rscadd: "(Upstream, Deltastation) Bar now has a door from the backroom to the theatre stage"
- - rscadd: "(Upstream, Deltastation) Tweaked Locker Room/Dormitories"
- - bugfix: "The armory no longer has a deep frying oil vat in place of dragnets."
diff --git a/html/changelogs/AutoChangeLog-pr-4000.yml b/html/changelogs/AutoChangeLog-pr-4000.yml
deleted file mode 100644
index bfd91f572d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4000.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - imageadd: "The Nanotrasen logo on modular computers has been fixed, rejoice!"
diff --git a/html/changelogs/AutoChangeLog-pr-4001.yml b/html/changelogs/AutoChangeLog-pr-4001.yml
deleted file mode 100644
index 578f211e20..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4001.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Pizza box stacking works again."
diff --git a/html/changelogs/AutoChangeLog-pr-4005.yml b/html/changelogs/AutoChangeLog-pr-4005.yml
deleted file mode 100644
index cf136090a6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4005.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "now lists should work properly"
diff --git a/html/changelogs/AutoChangeLog-pr-4008.yml b/html/changelogs/AutoChangeLog-pr-4008.yml
deleted file mode 100644
index 6d6b7d53b8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4008.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "zennerx"
-delete-after: True
-changes:
- - bugfix: "fixed a bug that made you try and scream while unconscious due to a fire"
diff --git a/html/changelogs/AutoChangeLog-pr-4010.yml b/html/changelogs/AutoChangeLog-pr-4010.yml
deleted file mode 100644
index b413fb1671..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4010.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Kor"
-delete-after: True
-changes:
- - bugfix: "Blobbernauts will no longer spawn if a player is not selected to control it, preventing AI blobbernauts from running off the blob and to their deaths."
diff --git a/html/changelogs/AutoChangeLog-pr-4012.yml b/html/changelogs/AutoChangeLog-pr-4012.yml
deleted file mode 100644
index 18b4c3dfd2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4012.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Toriate"
-delete-after: True
-changes:
- - tweak: "Mag Pistol and Mag Rifle no longer spawn with magazines when built in protolathe"
- - balance: "Nerf guns no longer max out science in five seconds flat"
- - bugfix: "Nerf gun magazines no longer give infinite metal and glass"
diff --git a/html/changelogs/AutoChangeLog-pr-4013.yml b/html/changelogs/AutoChangeLog-pr-4013.yml
deleted file mode 100644
index 0507fafc72..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4013.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Fix some permanent-on and permanent-off bugs caused by the HUD stacking change."
diff --git a/html/changelogs/AutoChangeLog-pr-4014.yml b/html/changelogs/AutoChangeLog-pr-4014.yml
deleted file mode 100644
index 1a1698767d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4014.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Skylar Lineman, your local R&D moonlighter"
-delete-after: True
-changes:
- - rscadd: "Research has been completely overhauled into the techweb system! No more levels, the station now unlocks research \"nodes\" with research points passively generated when there is atleast one research server properly cooled, powered, and online."
- - rscadd: "R&D lab has been replaced by the departmental lathe system on the three major maps. Each department gets a lathe and possibly a circuit imprinter that only have designs assigned by that department."
- - rscadd: "The ore redemption machine has been moved into cargo bay on maps with decentralized research to prevent the hallways from becoming a free for all. Honk!"
- - balance: "You shouldn't expect balance as this is the initial merge. Please put all feedback and concerns on the forum so we can revise the system over the days, weeks, and months, to make this enjoyable for everyone. Heavily wanted are ideas of how to add more ways of generating points."
- - balance: "You can get techweb points by setting off bombs with an active science doppler array listening. The bombs have to have a theoretical radius far above maxcap to make a difference. You can only go up, not down, in radius, so you can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically scaled to prevent \"world destroyer\" bombs from instantly finishing research."
diff --git a/html/changelogs/AutoChangeLog-pr-4022.yml b/html/changelogs/AutoChangeLog-pr-4022.yml
deleted file mode 100644
index 295229de2b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4022.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "Chairs, PA parts, infrared emitters, and doppler arrays will now rotate clockwise."
diff --git a/html/changelogs/AutoChangeLog-pr-4026.yml b/html/changelogs/AutoChangeLog-pr-4026.yml
deleted file mode 100644
index 3424fdd501..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4026.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - bugfix: "Using a chameleon projector will now dismount you from any vehicles you are riding, in order to prevent wacky space glitches and being sent to a realm outside space and time."
diff --git a/html/changelogs/AutoChangeLog-pr-4027.yml b/html/changelogs/AutoChangeLog-pr-4027.yml
deleted file mode 100644
index 925f8d5256..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4027.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ike709"
-delete-after: True
-changes:
- - bugfix: "Fixed some computers facing the wrong direction."
diff --git a/html/changelogs/AutoChangeLog-pr-4028.yml b/html/changelogs/AutoChangeLog-pr-4028.yml
deleted file mode 100644
index 1af9360833..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4028.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Code by Pyko, Ported by Frozenguy5"
-delete-after: True
-changes:
- - rscadd: "Rat Kebabs and Double Rat Kebabs have been added!"
diff --git a/html/changelogs/AutoChangeLog-pr-4030.yml b/html/changelogs/AutoChangeLog-pr-4030.yml
deleted file mode 100644
index ca630fbfd8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4030.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "zennerx"
-delete-after: True
-changes:
- - tweak: "Skateboard crashes now give slight brain damage!"
- - rscadd: "Using a helmet prevents brain damage from the skateboard!"
diff --git a/html/changelogs/AutoChangeLog-pr-4031.yml b/html/changelogs/AutoChangeLog-pr-4031.yml
deleted file mode 100644
index 4907986852..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4031.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - code_imp: "Ladders have been refactored and should be far less buggy."
- - bugfix: "Jacob's ladder actually works again."
diff --git a/html/changelogs/AutoChangeLog-pr-4032.yml b/html/changelogs/AutoChangeLog-pr-4032.yml
deleted file mode 100644
index 4969c5bcaf..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4032.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "PubbyStation - Unpowered air injectors in various locations have been fixed."
diff --git a/html/changelogs/AutoChangeLog-pr-4033.yml b/html/changelogs/AutoChangeLog-pr-4033.yml
deleted file mode 100644
index effc283b83..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4033.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "MetaStation - Air injector leading out of the incinerator has been fixed"
- - bugfix: "MetaStation - Corrected a couple maintenance airlocks being powered by the wrong areas."
diff --git a/html/changelogs/AutoChangeLog-pr-4034.yml b/html/changelogs/AutoChangeLog-pr-4034.yml
deleted file mode 100644
index eff19f0cfa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4034.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "Throwing drinking glasses and cartons will now consistently cause them to break!"
diff --git a/html/changelogs/AutoChangeLog-pr-4036.yml b/html/changelogs/AutoChangeLog-pr-4036.yml
deleted file mode 100644
index 820c726cea..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4036.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "Computers will no longer rotate incorrectly when being deconstructed."
- - bugfix: "You can now rotate computer frames during construction."
diff --git a/html/changelogs/AutoChangeLog-pr-4038.yml b/html/changelogs/AutoChangeLog-pr-4038.yml
deleted file mode 100644
index 9500855d83..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4038.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "WJohnston"
-delete-after: True
-changes:
- - bugfix: "Green banded default airlocks now have extended click area like all other airlocks."
diff --git a/html/changelogs/AutoChangeLog-pr-4043.yml b/html/changelogs/AutoChangeLog-pr-4043.yml
deleted file mode 100644
index b867396350..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4043.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Francinum"
-delete-after: True
-changes:
- - tweak: "The shuttle build plate is now better sized for all stations."
diff --git a/html/changelogs/AutoChangeLog-pr-4049.yml b/html/changelogs/AutoChangeLog-pr-4049.yml
deleted file mode 100644
index f2d883ca0d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4049.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "WJohnston"
-delete-after: True
-changes:
- - imageadd: "A bunch of new turf decals for mappers to play with, coming in yellow, white, and red varieties!"
diff --git a/html/changelogs/AutoChangeLog-pr-4050.yml b/html/changelogs/AutoChangeLog-pr-4050.yml
deleted file mode 100644
index 85d49a56fe..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4050.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "Computers will no longer delete themselves when being built, whoops!"
diff --git a/html/changelogs/AutoChangeLog-pr-4051.yml b/html/changelogs/AutoChangeLog-pr-4051.yml
deleted file mode 100644
index ee3ed953c1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4051.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "ACCount"
-delete-after: True
-changes:
- - refactor: "Old integrated circuit save file format is ditched in favor of JSON. Readability, both of save files and save code, is improved greatly."
- - tweak: "Integrated circuit panels now open with screwdriver instead of crowbar, to match every single other thing on this server."
- - tweak: "Integrated circuit printer now stores up to 25 metal sheets."
- - bugfix: "Fixed integrated circuit rechargers not recharging guns properly and not updating icons."
- - bugfix: "Fixed multiple bugs in integrated circuits UIs, improved overall usability."
diff --git a/html/changelogs/AutoChangeLog-pr-4052.yml b/html/changelogs/AutoChangeLog-pr-4052.yml
deleted file mode 100644
index ad7e91b332..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4052.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "Humans missing legs or are legcuffed will no longer move slower in areas without gravity."
diff --git a/html/changelogs/AutoChangeLog-pr-4053.yml b/html/changelogs/AutoChangeLog-pr-4053.yml
deleted file mode 100644
index 9f749a63a5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4053.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Toriate"
-delete-after: True
-changes:
- - rscadd: "Added recolourable clothes"
- - tweak: "jumpsuits in mixed wardrobe replaced with recolourable clothes"
- - imageadd: "greyscaled clothing sprites for colourable clothes"
diff --git a/html/changelogs/AutoChangeLog-pr-4055.yml b/html/changelogs/AutoChangeLog-pr-4055.yml
deleted file mode 100644
index 618a46b39c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4055.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "The structures external to stations are now properly lit. Make sure you bring a flashlight."
diff --git a/html/changelogs/AutoChangeLog-pr-4059.yml b/html/changelogs/AutoChangeLog-pr-4059.yml
deleted file mode 100644
index 1742cf5805..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4059.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "psykzz"
-delete-after: True
-changes:
- - rscadd: "Added TGUI for Turbine computer"
diff --git a/html/changelogs/AutoChangeLog-pr-4060.yml b/html/changelogs/AutoChangeLog-pr-4060.yml
deleted file mode 100644
index 7846d861f4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4060.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Y0SH1 M4S73R"
-delete-after: True
-changes:
- - spellcheck: "The R&D Server's name is now improper."
- - spellcheck: "The R&D Server now has an explanation of what it does."
diff --git a/html/changelogs/AutoChangeLog-pr-4064.yml b/html/changelogs/AutoChangeLog-pr-4064.yml
deleted file mode 100644
index 90f52d39aa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4064.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "jammer312"
-delete-after: True
-changes:
- - bugfix: "fixed conjuration spells forgetting about conjured items"
diff --git a/html/changelogs/AutoChangeLog-pr-4066.yml b/html/changelogs/AutoChangeLog-pr-4066.yml
deleted file mode 100644
index 6858021004..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4066.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - code_imp: "Chasm code has been refactored to be more sane."
- - bugfix: "Building lattices over chasms no longer sometimes deletes the chasm."
diff --git a/html/changelogs/AutoChangeLog-pr-4067.yml b/html/changelogs/AutoChangeLog-pr-4067.yml
deleted file mode 100644
index 103a03d08a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4067.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "Space cats will no longer have a smashed helmet when they lay down."
diff --git a/html/changelogs/AutoChangeLog-pr-4069.yml b/html/changelogs/AutoChangeLog-pr-4069.yml
deleted file mode 100644
index c6832bbbf7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4069.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - admin: "\"ahelp\" chat command can now accept a ticket number as opposed to a ckey"
diff --git a/html/changelogs/AutoChangeLog-pr-4072.yml b/html/changelogs/AutoChangeLog-pr-4072.yml
deleted file mode 100644
index 88296b7a45..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4072.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - code_imp: "Added round id to the status world topic"
diff --git a/html/changelogs/AutoChangeLog-pr-4075.yml b/html/changelogs/AutoChangeLog-pr-4075.yml
deleted file mode 100644
index d627c00d1f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4075.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "GupGup"
-delete-after: True
-changes:
- - bugfix: "Fixes hostile mobs attacking surrounding tiles when trying to attack someone"
diff --git a/html/changelogs/AutoChangeLog-pr-4076.yml b/html/changelogs/AutoChangeLog-pr-4076.yml
deleted file mode 100644
index b40f213dd3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4076.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "XDTM"
-delete-after: True
-changes:
- - rscadd: "Added two new symptoms: one allows viruses to still work while dead, and allows infection of undead species, and one allows infection of inorganic species (such as plasmapeople or golems)."
diff --git a/html/changelogs/AutoChangeLog-pr-4077.yml b/html/changelogs/AutoChangeLog-pr-4077.yml
deleted file mode 100644
index 56e6ca4c9e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4077.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "Aliens in soft-crit will now use the correct sprite."
diff --git a/html/changelogs/AutoChangeLog-pr-4080.yml b/html/changelogs/AutoChangeLog-pr-4080.yml
deleted file mode 100644
index d10288ec03..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4080.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "MrStonedOne and Jordie"
-delete-after: True
-changes:
- - server: "As a late note, serverops be advise that mysql is no longer supported. existing mysql databases will need to be converted to mariadb"
diff --git a/html/changelogs/AutoChangeLog-pr-4084.yml b/html/changelogs/AutoChangeLog-pr-4084.yml
deleted file mode 100644
index ddd147e1e0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4084.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "The vault in boxstation now has power again."
- - bugfix: "The gravity generator in boxstation now has power again."
- - bugfix: "Various broken decals in boxstation have been fixed."
- - bugfix: "The clown and mime offices no longer have APCs pointing to the wrong areas."
- - rscadd: "Boxstation's secure cell has been readded to security."
diff --git a/html/changelogs/AutoChangeLog-pr-4095.yml b/html/changelogs/AutoChangeLog-pr-4095.yml
deleted file mode 100644
index dd5036cb59..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4095.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ACCount"
-delete-after: True
-changes:
- - rscdel: "Removed \"console screen\" stock part. Just use glass sheets instead."
diff --git a/html/changelogs/AutoChangeLog-pr-4099.yml b/html/changelogs/AutoChangeLog-pr-4099.yml
deleted file mode 100644
index ac5424fd57..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4099.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ninjanomnom"
-delete-after: True
-changes:
- - bugfix: "Custom shuttle dockers can no longer place docking regions inside other custom docker regions."
diff --git a/html/changelogs/AutoChangeLog-pr-4100.yml b/html/changelogs/AutoChangeLog-pr-4100.yml
deleted file mode 100644
index e8abc00b9e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4100.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Fix water misters being inappropriately glued to hands in some cases."
diff --git a/html/changelogs/AutoChangeLog-pr-4105.yml b/html/changelogs/AutoChangeLog-pr-4105.yml
deleted file mode 100644
index 1ce922ad64..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4105.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "More Robust Than You"
-delete-after: True
-changes:
- - tweak: "Spessmen are now smart enough to realize you don't need to turn around to pull cigarette butts"
diff --git a/html/changelogs/AutoChangeLog-pr-4106.yml b/html/changelogs/AutoChangeLog-pr-4106.yml
deleted file mode 100644
index 326d296e90..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4106.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Some misplaced decals in the Hotel brig have been corrected."
diff --git a/html/changelogs/AutoChangeLog-pr-4110.yml b/html/changelogs/AutoChangeLog-pr-4110.yml
deleted file mode 100644
index cd94f6dae7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4110.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CosmicScientist"
-delete-after: True
-changes:
- - bugfix: "bolas are back in tablecrafting!"
diff --git a/html/changelogs/AutoChangeLog-pr-4111.yml b/html/changelogs/AutoChangeLog-pr-4111.yml
deleted file mode 100644
index 1019538b17..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4111.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ninjanomnom"
-delete-after: True
-changes:
- - bugfix: "Fixes thermite burning hotter than the boiling point of stone"
diff --git a/html/changelogs/AutoChangeLog-pr-4112.yml b/html/changelogs/AutoChangeLog-pr-4112.yml
deleted file mode 100644
index 12412931b6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4112.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "AIs and cyborgs can interact with unscrewed airlocks and APCs."
diff --git a/html/changelogs/AutoChangeLog-pr-4116.yml b/html/changelogs/AutoChangeLog-pr-4116.yml
deleted file mode 100644
index 877ad76460..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4116.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Dorsisdwarf"
-delete-after: True
-changes:
- - tweak: "Catpeople are now distracted instead of debilitated"
- - rscadd: "Normal cats now go for laser pointers"
diff --git a/html/changelogs/AutoChangeLog-pr-4117.yml b/html/changelogs/AutoChangeLog-pr-4117.yml
deleted file mode 100644
index bb2c70bccc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4117.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "You can no longer buckle people to roller beds from inside of a locker."
diff --git a/html/changelogs/AutoChangeLog-pr-4121.yml b/html/changelogs/AutoChangeLog-pr-4121.yml
deleted file mode 100644
index a226595420..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4121.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "zennerx"
-delete-after: True
-changes:
- - bugfix: "Zombies don't reanimate with no head!"
diff --git a/html/changelogs/AutoChangeLog-pr-4124.yml b/html/changelogs/AutoChangeLog-pr-4124.yml
deleted file mode 100644
index e568f3e9df..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4124.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "WJohnston"
-delete-after: True
-changes:
- - bugfix: "Fixed a case where items would sometimes be placed underneath racks."
diff --git a/html/changelogs/AutoChangeLog-pr-4125.yml b/html/changelogs/AutoChangeLog-pr-4125.yml
deleted file mode 100644
index a8f5bdbe86..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4125.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - bugfix: "Hopefully fixed mesons granting the ability to hear people through walls."
diff --git a/html/changelogs/AutoChangeLog-pr-4126.yml b/html/changelogs/AutoChangeLog-pr-4126.yml
deleted file mode 100644
index 42689125e8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4126.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Cryo cells can now be properly rotated with a wrench."
diff --git a/html/changelogs/AutoChangeLog-pr-4127.yml b/html/changelogs/AutoChangeLog-pr-4127.yml
deleted file mode 100644
index b9f6abc58d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4127.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "More Robust Than You"
-delete-after: True
-changes:
- - bugfix: "Fixed cult leaders being de-culted upon election if they had a mindshield implant"
diff --git a/html/changelogs/AutoChangeLog-pr-4129.yml b/html/changelogs/AutoChangeLog-pr-4129.yml
deleted file mode 100644
index 16d3765876..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4129.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ninjanomnom"
-delete-after: True
-changes:
- - rscadd: "You can now make a new tasty traditional treat: butterdogs. Watch out, they're slippery."
diff --git a/html/changelogs/AutoChangeLog-pr-4133.yml b/html/changelogs/AutoChangeLog-pr-4133.yml
deleted file mode 100644
index 2b50fbd4ea..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4133.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-author: "XDTM"
-delete-after: True
-changes:
- - balance: "Viruses' healing symptoms have been reworked!"
- - rscdel: "All existing healing symptoms have been removed in favour of new ones."
- - rscdel: "Weight Even and Weight Gain have been removed, so hunger can be used for balancing in symptoms."
- - rscadd: "Starlight Condensation heals toxin damage if you're in space using starlight as a catalyst. Being up to two tiles away also works, as long as you can still see it, but slower."
- - rscadd: "Toxolysis (level 7) rapidly cleanses all chemicals from the body, with no exception."
- - rscadd: "Cellular Molding heals brute damage depending on your body temperature: the higher the temperature, the faster the healing. Requires above-average temperature to activate, and the speed heavily increases while on fire."
- - rscadd: "Regenerative Coma (level 8) causes the virus to send you into a deep coma when you are heavily damaged (>70 brute+burn damage). While you are unconscious, either from the virus or from other sources, the virus will heal both brute and burn damage fairly quickly. Sleeping also works, but at reduced speed."
- - rscadd: "Tissue Hydration heals burn damage if you are wet (negative fire stacks) or if you have water in your bloodstream."
- - rscadd: "Plasma Fixation (level 8) stabilizes temperature and heals burns while plasma is in your body or while standing in a plasma cloud. Does not protect from the poisoning effects of plasma."
- - rscadd: "Radioactive Resonance gives a mild constant brute and burn healing while irradiated. The healing becomes more intense if you reach higher levels of radiation, but is still less than the alternatives."
- - rscadd: "Metabolic Boost (level 7) doubles the rate at which you process chemicals, good and bad, but also increases hunger tenfold."
diff --git a/html/changelogs/AutoChangeLog-pr-4136.yml b/html/changelogs/AutoChangeLog-pr-4136.yml
deleted file mode 100644
index 0737b28919..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4136.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "ACCount"
-delete-after: True
-changes:
- - rscadd: "New integrated circuit components: list constructors/deconstructors. Useful for building lists and taking them apart."
- - bugfix: "Fixed multiple bugs in integrated circuits UIs, improved overall usability."
diff --git a/html/changelogs/AutoChangeLog-pr-4143.yml b/html/changelogs/AutoChangeLog-pr-4143.yml
deleted file mode 100644
index dc1f281cec..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4143.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - code_imp: "rejiggered botcode a little bit"
diff --git a/html/changelogs/AutoChangeLog-pr-4144.yml b/html/changelogs/AutoChangeLog-pr-4144.yml
deleted file mode 100644
index bcefc8437a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4144.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "You can make many different types of office and comfy chairs with metal"
- - tweak: "Stack menus use /datum/browser"
diff --git a/html/changelogs/AutoChangeLog-pr-4145.yml b/html/changelogs/AutoChangeLog-pr-4145.yml
deleted file mode 100644
index c7b269b20f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4145.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "improvedname"
-delete-after: True
-changes:
- - tweak: "toolbelts can now carry geiger counters"
diff --git a/html/changelogs/AutoChangeLog-pr-4149.yml b/html/changelogs/AutoChangeLog-pr-4149.yml
deleted file mode 100644
index 909fc3e1b9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4149.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "JJRcop"
-delete-after: True
-changes:
- - admin: "Fixed the Make space ninja verb."
diff --git a/html/changelogs/AutoChangeLog-pr-4150.yml b/html/changelogs/AutoChangeLog-pr-4150.yml
deleted file mode 100644
index 943af018e5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4150.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ACCount"
-delete-after: True
-changes:
- - rscdel: "Mass-spectrometers are removed. Would anyone notice if not for this changelog entry?"
diff --git a/html/changelogs/AutoChangeLog-pr-4152.yml b/html/changelogs/AutoChangeLog-pr-4152.yml
deleted file mode 100644
index df1b1cd09f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4152.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ACCount"
-delete-after: True
-changes:
- - rscdel: "\"Machine prototype\" is removed from the game."
diff --git a/html/changelogs/AutoChangeLog-pr-4155.yml b/html/changelogs/AutoChangeLog-pr-4155.yml
deleted file mode 100644
index 0f762fae2e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4155.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "AI and observer diagnostic huds will now show the astar path of all bots, and Pai bots will be given a visible path to follow when called by the AI."
diff --git a/html/changelogs/AutoChangeLog-pr-4162.yml b/html/changelogs/AutoChangeLog-pr-4162.yml
deleted file mode 100644
index be4968592e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4162.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - tweak: "The sloth no longer suspiciously moves fast when gliding between tiles."
- - balance: "The sloth's movespeed when inhabited by a player has been lowered from once every 1/5 of a second to once every second."
diff --git a/html/changelogs/AutoChangeLog-pr-4170.yml b/html/changelogs/AutoChangeLog-pr-4170.yml
deleted file mode 100644
index f54be6c190..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4170.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ninjanomnom"
-delete-after: True
-changes:
- - tweak: "Reduced the max volume of sm by 1/5th and made the upper bounds only play mid delamination."
diff --git a/html/changelogs/AutoChangeLog-pr-4171.yml b/html/changelogs/AutoChangeLog-pr-4171.yml
deleted file mode 100644
index 612f5ad379..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4171.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "psykzz"
-delete-after: True
-changes:
- - bugfix: "Fixing the broken turbine computer"
diff --git a/html/changelogs/AutoChangeLog-pr-4172.yml b/html/changelogs/AutoChangeLog-pr-4172.yml
deleted file mode 100644
index a2dac53175..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4172.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Robustin"
-delete-after: True
-changes:
- - tweak: "Damage examinations now include a \"moderate\" classification. Before minor was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 to <50, and severe is 50+."
diff --git a/html/changelogs/AutoChangeLog-pr-4175.yml b/html/changelogs/AutoChangeLog-pr-4175.yml
deleted file mode 100644
index 1eed117c43..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4175.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - imageadd: "Construct shells have a new animated sprite"
diff --git a/html/changelogs/AutoChangeLog-pr-4176.yml b/html/changelogs/AutoChangeLog-pr-4176.yml
deleted file mode 100644
index 76ccbf0925..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4176.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Toriate"
-delete-after: True
-changes:
- - rscadd: "Added Lavaknights, a new ghost role of cat people in knight armor."
- - rscadd: "Added Hypereutactic blades, NEBs on steroids."
- - tweak: "Made NEBs alt click to recolor
-wip: Added lavaknight spawners. Someone else needs to add it in to a map or ruin properly."
- - imageadd: "added sprites for hypereutactic blades"
diff --git a/html/changelogs/AutoChangeLog-pr-4177.yml b/html/changelogs/AutoChangeLog-pr-4177.yml
deleted file mode 100644
index f6e65ed068..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4177.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Robustin"
-delete-after: True
-changes:
- - balance: "Clockwork magicks will now prevent Bags of Holding from being combined on Reebe."
diff --git a/html/changelogs/AutoChangeLog-pr-4180.yml b/html/changelogs/AutoChangeLog-pr-4180.yml
deleted file mode 100644
index fb6248b653..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4180.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Robustin"
-delete-after: True
-changes:
- - bugfix: "Flashes will now burn out AFTER flashing when they fail instead of being a ticking time bomb that waits to screw you over on your next attempt."
diff --git a/html/changelogs/AutoChangeLog-pr-4182.yml b/html/changelogs/AutoChangeLog-pr-4182.yml
deleted file mode 100644
index 6d0c949e11..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4182.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Frozenguy5"
-delete-after: True
-changes:
- - tweak: "The Particle Accelerator's wires can no longer be EMP'd"
diff --git a/html/changelogs/AutoChangeLog-pr-4184.yml b/html/changelogs/AutoChangeLog-pr-4184.yml
deleted file mode 100644
index f97a70a206..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4184.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CosmicScientist"
-delete-after: True
-changes:
- - rscadd: "You can make plushies kiss one another!"
diff --git a/html/changelogs/AutoChangeLog-pr-4186.yml b/html/changelogs/AutoChangeLog-pr-4186.yml
deleted file mode 100644
index 86951d81f1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4186.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - code_imp: "Cleans up some loc assignments"
diff --git a/html/changelogs/AutoChangeLog-pr-4191.yml b/html/changelogs/AutoChangeLog-pr-4191.yml
deleted file mode 100644
index 5904f70b86..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4191.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "BeeSting12"
-delete-after: True
-changes:
- - spellcheck: "Occupand ---> Occupant on opened cryogenic pods."
- - spellcheck: "Cyrogenic ---> Cryogenic on opened cryogenic pods."
diff --git a/html/changelogs/AutoChangeLog-pr-4196.yml b/html/changelogs/AutoChangeLog-pr-4196.yml
deleted file mode 100644
index 49ab9fdbd9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4196.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "zennerx"
-delete-after: True
-changes:
- - spellcheck: "fixed some typos in the weapon firing mechanism description"
diff --git a/html/changelogs/AutoChangeLog-pr-4198.yml b/html/changelogs/AutoChangeLog-pr-4198.yml
deleted file mode 100644
index 93e2f2212a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4198.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - rscadd: "Light fixtures now turn an ominous, dim red color when they lose power, and draw from an internal power cell to maintain it until either the cell dies (usually after 10 minutes) or power is restored."
- - rscadd: "You can override emergency light functionality from an APC. You can also click on individual lights as a cyborg or AI to override them individually. Traitor AIs also have a new ability that disables emergency lights across the entire station."
diff --git a/html/changelogs/AutoChangeLog-pr-4200.yml b/html/changelogs/AutoChangeLog-pr-4200.yml
deleted file mode 100644
index a2321590c7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4200.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "You can now lay (buckle!) yourself to a bed to avoid being burnt to a crisp during \"the floor is lava\" event."
diff --git a/html/changelogs/AutoChangeLog-pr-4201.yml b/html/changelogs/AutoChangeLog-pr-4201.yml
deleted file mode 100644
index 127a8b26ed..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4201.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Robustin"
-delete-after: True
-changes:
- - tweak: "Igniting plasma statues no longer ignores ignition temperature and only creates as much plasma as was used in its creation."
diff --git a/html/changelogs/AutoChangeLog-pr-4207.yml b/html/changelogs/AutoChangeLog-pr-4207.yml
deleted file mode 100644
index 692dca99ed..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4207.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - bugfix: "You now need fuel in your welder to repair mechs."
diff --git a/html/changelogs/AutoChangeLog-pr-4209.yml b/html/changelogs/AutoChangeLog-pr-4209.yml
deleted file mode 100644
index ee1613d170..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4209.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "You can now record and replay holopad messages using holodisks."
- - rscadd: "Holodisks are printable in autolathes."
diff --git a/html/changelogs/AutoChangeLog-pr-4215.yml b/html/changelogs/AutoChangeLog-pr-4215.yml
deleted file mode 100644
index 6e4fe16805..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4215.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Dax Dupont"
-delete-after: True
-changes:
- - rscadd: "Nanotrasen is happy to announce the pinnacle in plasma research! The Disco Inferno shuttle design is the result of decades of plasma research. Burn, baby, burn!"
diff --git a/html/changelogs/AutoChangeLog-pr-4216.yml b/html/changelogs/AutoChangeLog-pr-4216.yml
deleted file mode 100644
index 8b39d4aa94..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4216.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - tweak: "Stethoscopes now inform the user if the target can be defibrillated; the user will hear a \"faint, fluttery pulse.\""
diff --git a/html/changelogs/AutoChangeLog-pr-4218.yml b/html/changelogs/AutoChangeLog-pr-4218.yml
deleted file mode 100644
index 334c16e021..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4218.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - spellcheck: "Energy values are now measured in joules. What was previously 1 unit is now 1 kJ."
diff --git a/html/changelogs/AutoChangeLog-pr-4220.yml b/html/changelogs/AutoChangeLog-pr-4220.yml
deleted file mode 100644
index 7287bee043..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4220.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - sounddel: "Reduced the volume of showers"
diff --git a/html/changelogs/AutoChangeLog-pr-4234.yml b/html/changelogs/AutoChangeLog-pr-4234.yml
deleted file mode 100644
index 3310bdb750..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4234.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Syndicate uplink implants now work again."
diff --git a/html/changelogs/AutoChangeLog-pr-4235.yml b/html/changelogs/AutoChangeLog-pr-4235.yml
deleted file mode 100644
index 35197c0edf..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4235.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Robustin"
-delete-after: True
-changes:
- - rscdel: "Reverted changes in 3d sound system that tripled the distance that sound would carry."
diff --git a/html/changelogs/AutoChangeLog-pr-4240.yml b/html/changelogs/AutoChangeLog-pr-4240.yml
deleted file mode 100644
index bb77fc8cd8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4240.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "coiax"
-delete-after: True
-changes:
- - rscadd: "Quiet areas of libraries on station have now been equipped with a
-vending machine containing suitable recreational activities."
diff --git a/html/changelogs/AutoChangeLog-pr-4241.yml b/html/changelogs/AutoChangeLog-pr-4241.yml
deleted file mode 100644
index 77a17bb5b1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4241.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "coiax"
-delete-after: True
-changes:
- - rscadd: "The drone dispenser on Metastation has been moved to the
-maintenance by Robotics."
diff --git a/html/changelogs/AutoChangeLog-pr-4243.yml b/html/changelogs/AutoChangeLog-pr-4243.yml
deleted file mode 100644
index 4971528f94..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4243.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Revenant Defile ability"
-delete-after: True
-changes:
- - bugfix: "Revenant's Defile now removes salt piles"
diff --git a/html/changelogs/AutoChangeLog-pr-4244.yml b/html/changelogs/AutoChangeLog-pr-4244.yml
deleted file mode 100644
index d1081a8801..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4244.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Dax Dupont & Alek2ander"
-delete-after: True
-changes:
- - tweak: "Binary chat messages been made more visible."
diff --git a/html/changelogs/AutoChangeLog-pr-4246.yml b/html/changelogs/AutoChangeLog-pr-4246.yml
deleted file mode 100644
index 555f050d39..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4246.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-author: "XDTM"
-delete-after: True
-changes:
- - rscadd: "Brain damage has been completely reworked!
-remove: Brain damage now no longer simply makes you dumb. Although most of its effects have been shifted into a brain trauma."
- - rscadd: "Every time you take brain damage, there's a chance you'll suffer a brain trauma. There are many variations of brain traumas, split in mild, severe, and special."
- - rscadd: "Mild brain traumas are the easiest to get, can be lightly to moderately annoying, and can be cured with mannitol and time."
- - rscadd: "Severe brain traumas are much rarer and require extensive brain damage before you have a chance to get them; they are usually very debilitating. Unlike mild traumas, they require surgery to cure. A new surgery procedure has been added for this, the aptly named Brain Surgery. It can also heal minor traumas."
- - rscadd: "Special brain traumas are rarely gained in place of Severe traumas: they are either complex or beneficial.
-However, they are also even easier to cure than mild traumas, which means that keeping these will usually mean keeping a mild trauma along with it."
- - rscadd: "Mobs can only naturally have one mild trauma and one severe or special trauma."
- - balance: "Brain damage will now kill and ruin the brain if it goes above 200. If it somehow goes above 400, the brain will melt and be destroyed completely."
- - balance: "Many brain-damaging effects have been given a damage cap, making them non-lethal."
- - rscdel: "The Unintelligible mutation has been removed and made into a brain trauma."
- - rscdel: "Brain damage no longer makes using machines a living hell."
- - rscadd: "Abductors give minor traumas to people they experiment on."
diff --git a/html/changelogs/AutoChangeLog-pr-4250.yml b/html/changelogs/AutoChangeLog-pr-4250.yml
deleted file mode 100644
index 7539b323a8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4250.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - rscadd: "Added the Eminence role to clockcult! Players can elect themselves or ghosts as the Eminence from the eminence spire structure on Reebe."
- - rscadd: "The Eminence is incorporeal and invisible, and directs the entire cult. Anything they say is heard over the Hierophant network, and they can issue commands by middle-clicking themselves or different turfs."
- - rscadd: "The Eminence also has a single-use mass recall that warps all servants to the Ark chamber."
- - rscadd: "Added traps, triggers, and brass filaments to link them. They can all be constructed from brass sheets, and do different things and trigger in different ways. Current traps include the brass skewer and steam vent, and triggers include the pressure sensor, lever, and repeater."
- - rscadd: "The Eminence can activate trap triggers by clicking on them!"
- - rscadd: "Servants can deconstruct traps instantly with a wrench."
- - rscdel: "Mending Mantra has been removed."
- - tweak: "Clockwork scriptures have been recolored and sorted based on their functions; yellow scriptures are for construction, red for offense, blue for defense, and purple for niche."
- - balance: "Servants now spawn with a PDA and black shoes to make disguise more feasible."
- - balance: "The Eminence can superheat up to 20 clockwork walls at a time. Superheated walls are immune to hulk and mech punches, but can still be broken conventionally."
- - balance: "Clockwork walls are slightly faster to build before the Ark activates, taking an extra second less."
- - bugfix: "Poly no longer continually undergoes binary fission when Ratvar is in range."
- - code_imp: "The global records alert for servants will no longer display info that doesn't affect them since the rework."
diff --git a/html/changelogs/AutoChangeLog-pr-4254.yml b/html/changelogs/AutoChangeLog-pr-4254.yml
deleted file mode 100644
index cdfa4c7c0b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4254.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - bugfix: "Games vending machines can now properly be rebuilt."
- - bugfix: "Games vending machines can now be refilled via supply crates."
- - rscadd: "Games Supply Crates have been added to the cargo console."
diff --git a/html/changelogs/AutoChangeLog-pr-4259.yml b/html/changelogs/AutoChangeLog-pr-4259.yml
deleted file mode 100644
index 7536cfa7a6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4259.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "Action buttons now remember positions where you locked."
- - tweak: "Now locking action buttons prevents them from being reset."
diff --git a/html/changelogs/AutoChangeLog-pr-4260.yml b/html/changelogs/AutoChangeLog-pr-4260.yml
deleted file mode 100644
index 1880edb973..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4260.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - rscadd: "You can now make pet carriers from the autolathe, to carry around chef meat and other small animals without having to drag them. The HoP, captain, and CMO also start with carriers in their lockers for their pets."
diff --git a/html/changelogs/AutoChangeLog-pr-4261.yml b/html/changelogs/AutoChangeLog-pr-4261.yml
deleted file mode 100644
index d7b0bcebf5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4261.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fox McCloud"
-delete-after: True
-changes:
- - tweak: "Slime blueprints can now make an area compatible with Xenobio consoles, regardless of the name of the new area"
diff --git a/html/changelogs/AutoChangeLog-pr-4264.yml b/html/changelogs/AutoChangeLog-pr-4264.yml
deleted file mode 100644
index 3a3b5c1f42..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4264.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "You now can get a medal for wasting hours talking to the secret debug tile."
- - bugfix: "Fixed runtime for the tile when poly's speech file doesn't exist."
diff --git a/html/changelogs/AutoChangeLog-pr-4266.yml b/html/changelogs/AutoChangeLog-pr-4266.yml
deleted file mode 100644
index e66348d5b4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4266.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Fixed the camera failure, race swap, cursed items, and imposter wizard random events"
- - tweak: "The cursed items event no longer nullspaces items"
diff --git a/html/changelogs/AutoChangeLog-pr-4267.yml b/html/changelogs/AutoChangeLog-pr-4267.yml
deleted file mode 100644
index 97e3a17b9a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4267.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "MrDoomBringer"
-delete-after: True
-changes:
- - imageadd: "All stations have been outfitted with brand new Smoke Machines! They have nicer sprites now!"
diff --git a/html/changelogs/AutoChangeLog-pr-4270.yml b/html/changelogs/AutoChangeLog-pr-4270.yml
deleted file mode 100644
index 06c99c93ee..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4270.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - config: "The default view range can now be defined in the config. The default is 15x15, which is simplified to 7 by BYOND. For reference, Goonstation's widescreen range is 21x15. Do note that changing this value will affect the title screen. The title screen images and the title screen area on the Centcom z-level will have to be updated if the default view range is changed."
diff --git a/html/changelogs/AutoChangeLog-pr-4272.yml b/html/changelogs/AutoChangeLog-pr-4272.yml
deleted file mode 100644
index 8bedafab45..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4272.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "coiax"
-delete-after: True
-changes:
- - rscadd: "The drone dispenser on Box Station has been moved from the Testing
-Lab to the Morgue/Robotics maintenance tunnel."
diff --git a/html/changelogs/AutoChangeLog-pr-4274.yml b/html/changelogs/AutoChangeLog-pr-4274.yml
deleted file mode 100644
index b1915f089b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4274.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Dax Dupont"
-delete-after: True
-changes:
- - bugfix: "Fixed observer chat flavor of silicon chat."
diff --git a/html/changelogs/AutoChangeLog-pr-4279.yml b/html/changelogs/AutoChangeLog-pr-4279.yml
deleted file mode 100644
index cddc887068..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4279.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Dax Dupont"
-delete-after: True
-changes:
- - bugfix: "Grilles now no longer revert to a pre-broken icon state when you hit them after they broke."
diff --git a/html/changelogs/AutoChangeLog-pr-4283.yml b/html/changelogs/AutoChangeLog-pr-4283.yml
deleted file mode 100644
index a96b866609..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4283.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - tweak: "The pAI software interface is now accessible via an action button."
diff --git a/html/changelogs/AutoChangeLog-pr-4286.yml b/html/changelogs/AutoChangeLog-pr-4286.yml
deleted file mode 100644
index 83ede8f21d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4286.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "External airlocks of the mining base and gulag are now cycle-linked."
diff --git a/html/changelogs/AutoChangeLog-pr-4287.yml b/html/changelogs/AutoChangeLog-pr-4287.yml
deleted file mode 100644
index 55bbeb05c2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4287.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "XDTM"
-delete-after: True
-changes:
- - tweak: "Instead of activating randomly on speech, Godwoken Syndrome randomly grants inspiration, causing the next message to be a Voice of God."
diff --git a/html/changelogs/AutoChangeLog-pr-4289.yml b/html/changelogs/AutoChangeLog-pr-4289.yml
deleted file mode 100644
index d0da6e0f58..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4289.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "Nanotrasen would like to remind crewmembers and especially medical personnel to stand clear of cadeavers before applying a defibrillator shock. (You get shocked if you're pulling/grabbing someone being defibbed.)"
- - tweak: "defib shock/charge sounds upped from 50% to 75%."
diff --git a/html/changelogs/AutoChangeLog-pr-4290.yml b/html/changelogs/AutoChangeLog-pr-4290.yml
deleted file mode 100644
index a7a034433f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4290.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Swindly"
-delete-after: True
-changes:
- - rscadd: "You can kill yourself with a few more items."
diff --git a/html/changelogs/AutoChangeLog-pr-4292.yml b/html/changelogs/AutoChangeLog-pr-4292.yml
deleted file mode 100644
index 14dda4b668..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4292.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - tweak: "Flickering lights will now actually flicker and not go between emergency lights and normal lighting."
diff --git a/html/changelogs/AutoChangeLog-pr-4296.yml b/html/changelogs/AutoChangeLog-pr-4296.yml
deleted file mode 100644
index 1e87a3fdaf..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4296.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - bugfix: "Emergency lights no longer stay on forever in some cases."
diff --git a/html/changelogs/AutoChangeLog-pr-4305.yml b/html/changelogs/AutoChangeLog-pr-4305.yml
deleted file mode 100644
index d6ae57f28d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4305.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "The MULEbots that the station starts with now show their ID numbers."
diff --git a/html/changelogs/AutoChangeLog-pr-4306.yml b/html/changelogs/AutoChangeLog-pr-4306.yml
deleted file mode 100644
index 0a6361f11d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4306.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Improvedname"
-delete-after: True
-changes:
- - tweak: "cats now drop their ears and tail when butchered."
diff --git a/html/changelogs/AutoChangeLog-pr-4308.yml b/html/changelogs/AutoChangeLog-pr-4308.yml
deleted file mode 100644
index 5f277e0e53..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4308.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Booze-o-mats have beer"
diff --git a/html/changelogs/AutoChangeLog-pr-4312.yml b/html/changelogs/AutoChangeLog-pr-4312.yml
deleted file mode 100644
index 8c05f5d79e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4312.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Robustin"
-delete-after: True
-changes:
- - bugfix: "Modes not in rotation have had their \"false report\" weights for the Command Report standardized"
diff --git a/html/changelogs/AutoChangeLog-pr-4313.yml b/html/changelogs/AutoChangeLog-pr-4313.yml
deleted file mode 100644
index a1124c765a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4313.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - tweak: "The white ship navigation computer now takes 10 seconds to designate a landing spot, and users can no longer see the syndicate shuttle or its custom landing location. If the white ship landing location would intersect the syndicate shuttle or its landing location, it will fail after the 10 seconds have elapsed."
diff --git a/html/changelogs/AutoChangeLog-pr-4314.yml b/html/changelogs/AutoChangeLog-pr-4314.yml
deleted file mode 100644
index e471271981..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4314.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "flightsuits should no longer disappear when you take them off involuntarily"
- - bugfix: "beam rifles actually fire striaght now"
- - bugfix: "click catchers now actually work"
- - bugfix: "you no longer see space in areas you normally can't see, instead of black. in reality you can still see space but it's faint enough that you can't tell so I'll say I fixed it."
diff --git a/html/changelogs/AutoChangeLog-pr-4315.yml b/html/changelogs/AutoChangeLog-pr-4315.yml
deleted file mode 100644
index a021f0ccc4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4315.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "Added MANY new types of airlock assembly that can be built with metal. Use metal in hand to see the new airlock assembly recipes."
- - rscadd: "Added new airlock types to the RCD and airlock painter"
- - rscadd: "Vault door assemblies can be built with 8 plasteel, high security assemblies with 6 plasteel"
- - rscadd: "Glass mineral airlocks are finally constructible. Use glass and mineral sheets on an airlock assembly in any order to make them."
- - tweak: "Glass and mineral sheets are now able to be welded out of door assemblies rather than having to deconstruct the whole thing"
- - rscdel: "Airlock painter no longer works on airlock assemblies (still works on airlocks)"
- - bugfix: "Titanium airlocks no longer have any missing overlays"
diff --git a/html/changelogs/AutoChangeLog-pr-4319.yml b/html/changelogs/AutoChangeLog-pr-4319.yml
deleted file mode 100644
index 851d5f12bc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4319.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Frozenguy5"
-delete-after: True
-changes:
- - balance: "Some hardsuits have had their melee, fire and rad armor ratings tweaked."
diff --git a/html/changelogs/AutoChangeLog-pr-4331.yml b/html/changelogs/AutoChangeLog-pr-4331.yml
deleted file mode 100644
index 04532aa4a8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4331.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Swindly"
-delete-after: True
-changes:
- - bugfix: "Swarmers can no longer deconstruct objects with living things in them."
diff --git a/html/changelogs/AutoChangeLog-pr-4338.yml b/html/changelogs/AutoChangeLog-pr-4338.yml
deleted file mode 100644
index da4fde1e23..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4338.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "You can now print telecomms equipment again."
diff --git a/html/changelogs/AutoChangeLog-pr-4339.yml b/html/changelogs/AutoChangeLog-pr-4339.yml
deleted file mode 100644
index bf7c49d3e8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4339.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Robustin"
-delete-after: True
-changes:
- - rscadd: "The blood cult revive rune will now replace the souls of braindead or inactive cultists/constructs when properly invoked. These \"revivals\" will not count toward the revive limit."
- - rscadd: "The clock cult healing rune will now replace the souls of braindead or inactive cultists/constructs when left atop the rune. These \"revivals\" will not drain the rune's energy."
diff --git a/html/changelogs/AutoChangeLog-pr-4340.yml b/html/changelogs/AutoChangeLog-pr-4340.yml
deleted file mode 100644
index 6992dc2fd8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4340.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "fixes mobs not metabolizing their reagents"
diff --git a/html/changelogs/AutoChangeLog-pr-4341.yml b/html/changelogs/AutoChangeLog-pr-4341.yml
deleted file mode 100644
index e276d3bcb8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4341.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Mark9013100"
-delete-after: True
-changes:
- - rscadd: "Medical Wardrobes now contain an additional standard and EMT labcoat."
diff --git a/html/changelogs/AutoChangeLog-pr-4344.yml b/html/changelogs/AutoChangeLog-pr-4344.yml
deleted file mode 100644
index a020f7882f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4344.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Donator items use the proper sprites when worn again."
diff --git a/html/changelogs/AutoChangeLog-pr-4346.yml b/html/changelogs/AutoChangeLog-pr-4346.yml
deleted file mode 100644
index d03954b91f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4346.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "The standard-issue PDAs are now holographic again."
diff --git a/html/changelogs/AutoChangeLog-pr-4349.yml b/html/changelogs/AutoChangeLog-pr-4349.yml
deleted file mode 100644
index 3f1bb91439..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4349.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now have the correct description."
diff --git a/html/changelogs/AutoChangeLog-pr-4350.yml b/html/changelogs/AutoChangeLog-pr-4350.yml
deleted file mode 100644
index 2116fa9fd5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4350.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Genetics will no longer have a random block completely disappear each round"
diff --git a/html/changelogs/AutoChangeLog-pr-4351.yml b/html/changelogs/AutoChangeLog-pr-4351.yml
deleted file mode 100644
index bc5cabdb55..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4351.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - bugfix: "glass shards and bananium floors no longer make a sound when \"walked\" over by a camera or a ghost"
diff --git a/html/changelogs/AutoChangeLog-pr-4353.yml b/html/changelogs/AutoChangeLog-pr-4353.yml
deleted file mode 100644
index 6fcf3e2ebe..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4353.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "All maps now have departmental lathes as they're supposed to."
- - rscadd: "Pubbystation and Omegastation now have kinkmates! This does not add them back to the rotation, though. Tell Jay to re-enable Pubby and Omega in the server's config."
- - rscadd: "Omegastation's dorms now have bolt buttons."
- - bugfix: "The table in the back of Boxstation's maint bar gambling area will no longer throw people around."
diff --git a/html/changelogs/AutoChangeLog-pr-4354.yml b/html/changelogs/AutoChangeLog-pr-4354.yml
deleted file mode 100644
index e9aa1f0f2b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4354.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - code_imp: "Tidied up some loc assignments"
diff --git a/html/changelogs/AutoChangeLog-pr-4359.yml b/html/changelogs/AutoChangeLog-pr-4359.yml
deleted file mode 100644
index 6679e4b920..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4359.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - server: "Added new admin flag, AUTOLOGIN, to control if admins start with admin powers. this defaults to on, and can be removed with -AUTOLOGIN"
- - admin: "Admins with +PERMISSION may now deadmin or readmin other admins via the permission panel."
diff --git a/html/changelogs/AutoChangeLog-pr-4361.yml b/html/changelogs/AutoChangeLog-pr-4361.yml
deleted file mode 100644
index 140a9a4fe3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4361.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Shuttles now place hyperspace ripples where they are about to land again."
diff --git a/html/changelogs/AutoChangeLog-pr-4363.yml b/html/changelogs/AutoChangeLog-pr-4363.yml
deleted file mode 100644
index fda81eb42b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4363.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "JStheguy"
-delete-after: True
-changes:
- - rscadd: "Added 10 new assembly designs to the integrated circuit printer, the difference from current designs is purely aesthetics."
- - imageadd: "Added the icons for said new assembly designs to electronic_setups.dmi, changed the current electronic mechanism and electronic machine sprites."
diff --git a/html/changelogs/AutoChangeLog-pr-4365.yml b/html/changelogs/AutoChangeLog-pr-4365.yml
deleted file mode 100644
index 165bb4d0df..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4365.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Epoc"
-delete-after: True
-changes:
- - bugfix: "Adds Cybernetic Lungs to the Cyber Organs research node"
diff --git a/html/changelogs/AutoChangeLog-pr-4372.yml b/html/changelogs/AutoChangeLog-pr-4372.yml
deleted file mode 100644
index 7c1aa4b97c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4372.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "ShizCalev"
-delete-after: True
-changes:
- - soundadd: "Revamped gun dry-firing sounds."
- - tweak: "Everyone around you will now hear when your gun goes click. You don't want to hear click when you want to hear bang!"
diff --git a/html/changelogs/AutoChangeLog-pr-4375.yml b/html/changelogs/AutoChangeLog-pr-4375.yml
deleted file mode 100644
index 2cf7f4c721..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4375.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - code_imp: "fixes the remaining loc assignments"
diff --git a/html/changelogs/AutoChangeLog-pr-4377.yml b/html/changelogs/AutoChangeLog-pr-4377.yml
deleted file mode 100644
index 5234e24f49..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4377.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - rscadd: "Grinding runed metal and brass now produces iron/blood and iron/teslium, respectively."
- - balance: "As part of some code-side improvements, the amount of reagents you get from grinding some objects might be slightly different."
- - bugfix: "Some grinding recipes that didn't work, like dead mice and glowsticks, now do."
- - bugfix: "All-In-One grinders now correctly grind up everything, instead of one thing at a time."
diff --git a/html/changelogs/AutoChangeLog-pr-4378.yml b/html/changelogs/AutoChangeLog-pr-4378.yml
deleted file mode 100644
index 22ea638655..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4378.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - imageadd: "Closet sprites changed."
diff --git a/html/changelogs/AutoChangeLog-pr-4382.yml b/html/changelogs/AutoChangeLog-pr-4382.yml
deleted file mode 100644
index 64568eb274..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4382.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - config: "Added \"$include\" directives to config files. These are recursive. Only config.txt will be default loaded if they are specified inside it"
diff --git a/html/changelogs/AutoChangeLog-pr-4383.yml b/html/changelogs/AutoChangeLog-pr-4383.yml
deleted file mode 100644
index cf9c743a03..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4383.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - code_imp: "Preliminary work on tracking cliented living mobs across Z-levels to facilitate mob AI changes later"
diff --git a/html/changelogs/AutoChangeLog-pr-4384.yml b/html/changelogs/AutoChangeLog-pr-4384.yml
deleted file mode 100644
index d7f2f90350..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4384.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "EtheoBoxxman"
-delete-after: True
-changes:
- - rscdel: "Removed chasm that spawns on killing ash walker tendril"
diff --git a/html/changelogs/AutoChangeLog-pr-4389.yml b/html/changelogs/AutoChangeLog-pr-4389.yml
deleted file mode 100644
index 36f17b95de..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4389.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Toriate"
-delete-after: True
-changes:
- - tweak: "NEBs now consistently alt click to recolor"
diff --git a/html/changelogs/AutoChangeLog-pr-4390.yml b/html/changelogs/AutoChangeLog-pr-4390.yml
deleted file mode 100644
index 89d3683a34..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4390.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "AverageJoe82"
-delete-after: True
-changes:
- - rscadd: "drones now have night vision"
- - rscdel: "drones no longer have lights"
diff --git a/html/changelogs/AutoChangeLog-pr-4394.yml b/html/changelogs/AutoChangeLog-pr-4394.yml
deleted file mode 100644
index 68d57a2d11..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4394.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "The shuttle will no longer be autocalled if the round has already ended."
diff --git a/html/changelogs/AutoChangeLog-pr-4412.yml b/html/changelogs/AutoChangeLog-pr-4412.yml
deleted file mode 100644
index 6280189218..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4412.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - tweak: "Vitality matrices don't have visible messages when someone crosses them anymore."
diff --git a/html/changelogs/AutoChangeLog-pr-4416.yml b/html/changelogs/AutoChangeLog-pr-4416.yml
deleted file mode 100644
index 543fe52edd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4416.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Robustin"
-delete-after: True
-changes:
- - bugfix: "The wizard event \"race swap\" should now stick to \"safer\" species."
diff --git a/html/changelogs/AutoChangeLog-pr-4417.yml b/html/changelogs/AutoChangeLog-pr-4417.yml
deleted file mode 100644
index 46b7019353..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4417.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - bugfix: "Clockcult power alerts will no longer show outside of the clockcult gamemode (they could be triggered by scarabs.)"
diff --git a/html/changelogs/AutoChangeLog-pr-4420.yml b/html/changelogs/AutoChangeLog-pr-4420.yml
deleted file mode 100644
index 305d701c7f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4420.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-author: "XDTM"
-delete-after: True
-changes:
- - rscadd: "A few new traumas have been added."
- - balance: "Thresholds to get brain traumas have been lowered, as they currently pretty much only trigger if you intentionally chug impedrezene."
- - tweak: "Melee head hits deal minor brain damage. Crits still do a significant amount."
- - tweak: "Nuke Op implants no longer trigger on deathgasp. (They still explode on death)"
- - tweak: "You'll now receive messages when crossing certain brain damage thresholds."
- - tweak: "Split Personalities are instructed not to suicide while in control."
- - tweak: "Godwoken Syndrome now randomly sends Voice of God commands, instead of being controllable."
diff --git a/html/changelogs/AutoChangeLog-pr-4433.yml b/html/changelogs/AutoChangeLog-pr-4433.yml
deleted file mode 100644
index 39bde17139..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4433.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ninjanomnom"
-delete-after: True
-changes:
- - bugfix: "Decals should now rotate the correct way around."
diff --git a/html/changelogs/AutoChangeLog-pr-4437.yml b/html/changelogs/AutoChangeLog-pr-4437.yml
deleted file mode 100644
index 9b11b0912e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4437.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "nicbn"
-delete-after: True
-changes:
- - bugfix: "Now the chem smoke machine uses stock parts for volume and range."
diff --git a/html/changelogs/AutoChangeLog-pr-4440.yml b/html/changelogs/AutoChangeLog-pr-4440.yml
new file mode 100644
index 0000000000..9d14363c8a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4440.yml
@@ -0,0 +1,4 @@
+author: "ninjanomnom"
+delete-after: True
+changes:
+ - bugfix: "Non movement keys pressed while moving no longer stop movement."
diff --git a/html/changelogs/AutoChangeLog-pr-4442.yml b/html/changelogs/AutoChangeLog-pr-4442.yml
deleted file mode 100644
index e480e91419..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4442.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "XDTM"
-delete-after: True
-changes:
- - rscadd: "Abductors can now see if people already have glands! Never worry about abducting the same guy twice again."
- - rscadd: "Added the Mind Interface Device to the abductor shop for 2 Credits. Only scientists can use it."
- - rscadd: "The MID has two modes: Transmit and Control."
- - rscadd: "Transmit will allow you to send a message anytime, anywhere to the mind of a target of your choice, regardless of language barriers. The message will be anonymous, but abductor-like."
- - rscadd: "Control allows you to give a temporary directive to a target with an implanted gland, that they MUST follow. Duration and amount of uses varies by gland type. When a gland is spent, it will no longer respond to Control signals. The target forgets ever receiving the objective when the duration ends."
diff --git a/html/changelogs/AutoChangeLog-pr-4445.yml b/html/changelogs/AutoChangeLog-pr-4445.yml
deleted file mode 100644
index 6dd7a7e486..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4445.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Fixed captain's PDA showing unusable Toggle Remote Door menu option"
diff --git a/html/changelogs/AutoChangeLog-pr-4446.yml b/html/changelogs/AutoChangeLog-pr-4446.yml
deleted file mode 100644
index 3811f7ffb7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4446.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "coiax"
-delete-after: True
-changes:
- - balance: "The codespeak manual now has unlimited uses and costs 3 TC."
- - bugfix: "Nuke ops can now purchase the codespeak manual, as was intended."
diff --git a/html/changelogs/AutoChangeLog-pr-4453.yml b/html/changelogs/AutoChangeLog-pr-4453.yml
deleted file mode 100644
index 24bce9c510..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4453.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "coiax"
-delete-after: True
-changes:
- - rscadd: "A changeling will learn all languages from anyone they absorb."
diff --git a/html/changelogs/AutoChangeLog-pr-4458.yml b/html/changelogs/AutoChangeLog-pr-4458.yml
deleted file mode 100644
index 4e51890691..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4458.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "XDTM"
-delete-after: True
-changes:
- - tweak: "The Disease Outbreak event now can generate random advanced viruses, with more symptoms and higher level as round time goes on."
diff --git a/html/changelogs/AutoChangeLog-pr-4464.yml b/html/changelogs/AutoChangeLog-pr-4464.yml
deleted file mode 100644
index 17f7d8fc07..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4464.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "You can enforce no smoking zones with a disarm aimed at the smokers mouth."
diff --git a/html/changelogs/AutoChangeLog-pr-4466.yml b/html/changelogs/AutoChangeLog-pr-4466.yml
deleted file mode 100644
index e8239ebfb4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4466.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Toriate"
-delete-after: True
-changes:
- - balance: "Roundstart xenos are no longer pierce immune, also no more extra damage from heat."
diff --git a/html/changelogs/AutoChangeLog-pr-4467.yml b/html/changelogs/AutoChangeLog-pr-4467.yml
deleted file mode 100644
index ae009bf26f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4467.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "improvedname"
-delete-after: True
-changes:
- - bugfix: "Corrects 357. speedloader in the autolathe"
diff --git a/html/changelogs/AutoChangeLog-pr-4475.yml b/html/changelogs/AutoChangeLog-pr-4475.yml
deleted file mode 100644
index f37e80ed55..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4475.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - bugfix: "Passing a space transition no longer interrupts pulls."
diff --git a/html/changelogs/AutoChangeLog-pr-4477.yml b/html/changelogs/AutoChangeLog-pr-4477.yml
deleted file mode 100644
index bba0dab724..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4477.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fox McCloud"
-delete-after: True
-changes:
- - bugfix: "Fixes arm implants being immune to EMPs"
diff --git a/html/changelogs/AutoChangeLog-pr-4479.yml b/html/changelogs/AutoChangeLog-pr-4479.yml
deleted file mode 100644
index 623a1ada72..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4479.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscdel: "Integrated circuit smoke circuits now require 10 units of reagents to fire."
diff --git a/html/changelogs/AutoChangeLog-pr-4482.yml b/html/changelogs/AutoChangeLog-pr-4482.yml
new file mode 100644
index 0000000000..210ad03b5b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4482.yml
@@ -0,0 +1,5 @@
+author: "Xhuis"
+delete-after: True
+changes:
+ - balance: "Floors blessed with holy water prevent servants from warping in and the Eminence from crossing them."
+ - balance: "The Eminence can never enter the Chapel."
diff --git a/html/changelogs/AutoChangeLog-pr-4487.yml b/html/changelogs/AutoChangeLog-pr-4487.yml
deleted file mode 100644
index 588566e15c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4487.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ganglyalexander"
-delete-after: True
-changes:
- - bugfix: "module icons for dog borgs now reference to a existing icon"
diff --git a/html/changelogs/AutoChangeLog-pr-4488.yml b/html/changelogs/AutoChangeLog-pr-4488.yml
deleted file mode 100644
index 21031f2cf3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4488.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "coiax"
-delete-after: True
-changes:
- - rscadd: "At the end of the round, all players can see who the antagonists
-are."
diff --git a/html/changelogs/AutoChangeLog-pr-4490.yml b/html/changelogs/AutoChangeLog-pr-4490.yml
deleted file mode 100644
index 6477196745..0000000000
--- a/html/changelogs/AutoChangeLog-pr-4490.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CitadelStationBot"
-delete-after: True
-changes:
- - rscadd: "You can adjust line height in chat settings"
- - tweak: "Default chat line height is slightly shorter, from 1.4 to 1.2"
diff --git a/html/changelogs/AutoChangeLog-pr-4491.yml b/html/changelogs/AutoChangeLog-pr-4491.yml
new file mode 100644
index 0000000000..3076537362
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4491.yml
@@ -0,0 +1,4 @@
+author: "Kor"
+delete-after: True
+changes:
+ - rscadd: "During Christmas you will be able to click on the tree in the Chapel to receive one present per round. That present can contain any item in the game."
diff --git a/html/changelogs/AutoChangeLog-pr-4492.yml b/html/changelogs/AutoChangeLog-pr-4492.yml
new file mode 100644
index 0000000000..3b8e0de7e3
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4492.yml
@@ -0,0 +1,4 @@
+author: "Awesine"
+delete-after: True
+changes:
+ - rscadd: "added some things which happen to be mining scanner things to that gulag thing"
diff --git a/html/changelogs/AutoChangeLog-pr-4494.yml b/html/changelogs/AutoChangeLog-pr-4494.yml
new file mode 100644
index 0000000000..d873e211a5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4494.yml
@@ -0,0 +1,6 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - bugfix: "Projectiles that pierce objects will no longer be thrown off course when doing so!"
+ - code_imp: "Projectiles now use /datum/point/vectors for trajectory calculations."
+ - bugfix: "Beam rifle reflections will no longer glitch out."
diff --git a/html/changelogs/AutoChangeLog-pr-4497.yml b/html/changelogs/AutoChangeLog-pr-4497.yml
new file mode 100644
index 0000000000..05673f222c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4497.yml
@@ -0,0 +1,4 @@
+author: "WJohnston"
+delete-after: True
+changes:
+ - tweak: "Syndicate nuke op infiltrator shuttle is no longer lopsided."
diff --git a/html/changelogs/AutoChangeLog-pr-4504.yml b/html/changelogs/AutoChangeLog-pr-4504.yml
new file mode 100644
index 0000000000..7da90cb88b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4504.yml
@@ -0,0 +1,4 @@
+author: "Naksu"
+delete-after: True
+changes:
+ - bugfix: "frying oil actually works"
diff --git a/html/changelogs/AutoChangeLog-pr-4505.yml b/html/changelogs/AutoChangeLog-pr-4505.yml
new file mode 100644
index 0000000000..baf8daa374
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4505.yml
@@ -0,0 +1,6 @@
+author: "coiax"
+delete-after: True
+changes:
+ - balance: "The kitchen gibber must be anchored in order to use."
+ - balance: "The gibber requires bodies to have no external items or
+equipment."
diff --git a/html/changelogs/AutoChangeLog-pr-4506.yml b/html/changelogs/AutoChangeLog-pr-4506.yml
new file mode 100644
index 0000000000..0b2d10fffe
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4506.yml
@@ -0,0 +1,4 @@
+author: "Dax Dupont"
+delete-after: True
+changes:
+ - bugfix: "Borgs will no longer have their metal/glass/etc stacks commit sudoku when it runs out of metal. They will also show the correct amount instead of a constant of \"1\" on menu interaction."
diff --git a/html/changelogs/AutoChangeLog-pr-4507.yml b/html/changelogs/AutoChangeLog-pr-4507.yml
new file mode 100644
index 0000000000..3076537362
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4507.yml
@@ -0,0 +1,4 @@
+author: "Kor"
+delete-after: True
+changes:
+ - rscadd: "During Christmas you will be able to click on the tree in the Chapel to receive one present per round. That present can contain any item in the game."
diff --git a/html/changelogs/AutoChangeLog-pr-4509.yml b/html/changelogs/AutoChangeLog-pr-4509.yml
new file mode 100644
index 0000000000..0be18e6c47
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4509.yml
@@ -0,0 +1,4 @@
+author: "Robustin"
+delete-after: True
+changes:
+ - tweak: "The EMP door shocking effect has a new formula. Heavy EMP's will no longer shock doors while light EMP's have a 10% chance (down from 13.33%)."
diff --git a/html/changelogs/AutoChangeLog-pr-4516.yml b/html/changelogs/AutoChangeLog-pr-4516.yml
new file mode 100644
index 0000000000..66e1e9c6f3
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4516.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - bugfix: "\"Download N research nodes\" objective is now checked correctly again."
diff --git a/html/changelogs/AutoChangeLog-pr-4519.yml b/html/changelogs/AutoChangeLog-pr-4519.yml
new file mode 100644
index 0000000000..aa0bf5a78d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4519.yml
@@ -0,0 +1,4 @@
+author: "Frozenguy5"
+delete-after: True
+changes:
+ - bugfix: "Soapstones now give the correct time they were placed down."
diff --git a/html/changelogs/AutoChangeLog-pr-4521.yml b/html/changelogs/AutoChangeLog-pr-4521.yml
new file mode 100644
index 0000000000..2b5553d55f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4521.yml
@@ -0,0 +1,4 @@
+author: "More Robust Than You"
+delete-after: True
+changes:
+ - tweak: "Vending machines now use TGUI"
diff --git a/icons/mob/landmarks.dmi b/icons/mob/landmarks.dmi
new file mode 100644
index 0000000000..120745ed44
Binary files /dev/null and b/icons/mob/landmarks.dmi differ
diff --git a/icons/obj/assemblies/electronic_components.dmi b/icons/obj/assemblies/electronic_components.dmi
index 1852079e73..a9dac06d6b 100644
Binary files a/icons/obj/assemblies/electronic_components.dmi and b/icons/obj/assemblies/electronic_components.dmi differ
diff --git a/icons/obj/flora/pinetrees.dmi b/icons/obj/flora/pinetrees.dmi
index e7fa58cb1a..a68e0388b0 100644
Binary files a/icons/obj/flora/pinetrees.dmi and b/icons/obj/flora/pinetrees.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index aadf2bf1b8..63cff3d902 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -306,6 +306,7 @@
#include "code\datums\mutable_appearance.dm"
#include "code\datums\mutations.dm"
#include "code\datums\outfit.dm"
+#include "code\datums\position_point_vector.dm"
#include "code\datums\profiling.dm"
#include "code\datums\progressbar.dm"
#include "code\datums\radiation_wave.dm"
@@ -318,6 +319,7 @@
#include "code\datums\verbs.dm"
#include "code\datums\weakrefs.dm"
#include "code\datums\world_topic.dm"
+#include "code\datums\actions\beam_rifle.dm"
#include "code\datums\actions\flightsuit.dm"
#include "code\datums\actions\ninja.dm"
#include "code\datums\antagonists\abductor.dm"
@@ -345,6 +347,7 @@
#include "code\datums\components\archaeology.dm"
#include "code\datums\components\caltrop.dm"
#include "code\datums\components\chasm.dm"
+#include "code\datums\components\cleaning.dm"
#include "code\datums\components\decal.dm"
#include "code\datums\components\infective.dm"
#include "code\datums\components\jousting.dm"
@@ -851,6 +854,7 @@
#include "code\game\objects\effects\temporary_visuals\clockcult.dm"
#include "code\game\objects\effects\temporary_visuals\cult.dm"
#include "code\game\objects\effects\temporary_visuals\miscellaneous.dm"
+#include "code\game\objects\effects\temporary_visuals\projectile_beam.dm"
#include "code\game\objects\effects\temporary_visuals\temporary_visual.dm"
#include "code\game\objects\items\AI_modules.dm"
#include "code\game\objects\items\airlock_painter.dm"
diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css
index 256b53c106..c73fc2adfa 100644
--- a/tgui/assets/tgui.css
+++ b/tgui/assets/tgui.css
@@ -1 +1 @@
-@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"}
\ No newline at end of file
+@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCA0MjUgMjAwIiBvcGFjaXR5PSIuMzMiPgogIDxwYXRoIGQ9Im0gMTc4LjAwMzk5LDAuMDM4NjkgLTcxLjIwMzkzLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM0LDYuMDI1NTUgbCAwLDE4Ny44NzE0NyBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgNi43NjEzNCw2LjAyNTU0IGwgNTMuMTA3MiwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTAxLjU0NDAxOCA3Mi4yMTYyOCwxMDQuNjk5Mzk4IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA1Ljc2MDE1LDIuODcwMTYgbCA3My41NTQ4NywwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzNSwtNi4wMjU1NSBsIC01NC43MTY0NCwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzMyw2LjAyNTU1IGwgMCwxMDIuNjE5MzUgTCAxODMuNzY0MTMsMi45MDg4NiBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTUuNzYwMTQsLTIuODcwMTcgeiIgLz4KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPgogIDxwYXRoIGQ9Im0gNDIwLjE1NTM1LDE3Ny44OTExOSBhIDEzLjQxMjAzOCwxMi41MDE4NDIgMCAwIDEgLTguNjMyOTUsMjIuMDY5NTEgbCAtNjYuMTE4MzIsMCBhIDUuMzY0ODE1Miw1LjAwMDczNyAwIDAgMSAtNS4zNjQ4MiwtNS4wMDA3NCBsIDAsLTc5Ljg3OTMxIHoiIC8+Cjwvc3ZnPgo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4KPCEtLSBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1zYS80LjAvIC0tPgo=") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCAyMDAgMjg5Ljc0MiIgb3BhY2l0eT0iLjMzIj4KICA8cGF0aCBkPSJtIDkzLjUzNzY3NywwIGMgLTE4LjExMzEyNSwwIC0zNC4yMjAxMzMsMy4xMTE2NCAtNDguMzIzNDg0LDkuMzM0MzcgLTEzLjk2NTA5Miw2LjIyMTY3IC0yNC42MTI0NDIsMTUuMDcxMTQgLTMxLjk0MDY1MSwyNi41NDcxIC03LjE4OTkzOTgsMTEuMzM3ODkgLTEwLjMwMTIyNjYsMjQuNzQ5MTEgLTEwLjMwMTIyNjYsNDAuMjM0NzggMCwxMC42NDY2MiAyLjcyNTAwMjYsMjAuNDY0NjUgOC4xNzUxMTE2LDI5LjQ1MjU4IDUuNjE1Mjc3LDguOTg2ODYgMTQuMDM4Mjc3LDE3LjM1MjA0IDI1LjI2ODgyMSwyNS4wOTQzNiAxMS4yMzA1NDQsNy42MDUzMSAyNi41MDc0MjEsMTUuNDE4MzUgNDUuODMwNTE0LDIzLjQzNzgyIDE5Ljk4Mzc0OCw4LjI5NTU3IDM0Ljg0ODg0OCwxNS41NTQ3MSA0NC41OTI5OTgsMjEuNzc2MzggOS43NDQxNCw2LjIyMjczIDE2Ljc2MTcsMTIuODU4NSAyMS4wNTU3MiwxOS45MDk1MSA0LjI5NDA0LDcuMDUyMDggNi40NDE5MywxNS43NjQwOCA2LjQ0MTkzLDI2LjEzNDU5IDAsMTYuMTc3MDIgLTUuMjAxOTYsMjguNDgyMjIgLTE1LjYwNjczLDM2LjkxNjgyIC0xMC4yMzk2LDguNDM0NyAtMjUuMDIyMDMsMTIuNjUyMyAtNDQuMzQ1MTY5LDEyLjY1MjMgLTE0LjAzODE3MSwwIC0yNS41MTUyNDcsLTEuNjU5NCAtMzQuNDMzNjE4LC00Ljk3NzcgLTguOTE4MzcsLTMuNDU2NiAtMTYuMTg1NTcyLC04LjcxMTMgLTIxLjgwMDgzOSwtMTUuNzYzMyAtNS42MTUyNzcsLTcuMDUyMSAtMTAuMDc0Nzk1LC0xNi42NjA4OCAtMTMuMzc3ODk5LC0yOC44MjgxMiBsIC0yNC43NzMxNjI2MjkzOTQ1LDAgMCw1Ni44MjYzMiBDIDMzLjg1Njc2OSwyODYuMDc2MDEgNjMuNzQ5MDQsMjg5Ljc0MjAxIDg5LjY3ODM4MywyODkuNzQyMDEgYyAxNi4wMjAwMjcsMCAzMC43MTk3ODcsLTEuMzgyNyA0NC4wOTczMzcsLTQuMTQ3OSAxMy41NDI3MiwtMi45MDQzIDI1LjEwNDEsLTcuNDY3NiAzNC42ODMwOSwtMTMuNjg5MyA5Ljc0NDEzLC02LjM1OTcgMTcuMzQwNDIsLTE0LjUxOTUgMjIuNzkwNTIsLTI0LjQ3NDggNS40NTAxLC0xMC4wOTMzMiA4LjE3NTExLC0yMi4zOTk1OSA4LjE3NTExLC0zNi45MTY4MiAwLC0xMi45OTc2NCAtMy4zMDIxLC0yNC4zMzUzOSAtOS45MDgyOSwtMzQuMDE0NiAtNi40NDEwNSwtOS44MTcyNSAtMTUuNTI1NDUsLTE4LjUyNzA3IC0yNy4yNTE0NiwtMjYuMTMxMzMgLTExLjU2MDg1LC03LjYwNDI3IC0yNy45MTA4MywtMTUuODMxNDIgLTQ5LjA1MDY2LC0yNC42ODAyMiAtMTcuNTA2NDQsLTcuMTkwMTIgLTMwLjcxOTY2OCwtMTMuNjg5NDggLTM5LjYzODAzOCwtMTkuNDk3MDEgLTguOTE4MzcxLC01LjgwNzUyIC0xOC42MDc0NzQsLTEyLjQzNDA5IC0yNC4wOTY1MjQsLTE4Ljg3NDE3IC01LjQyNjA0MywtNi4zNjYxNiAtOS42NTg4MjYsLTE1LjA3MDAzIC05LjY1ODgyNiwtMjQuODg3MjkgMCwtOS4yNjQwMSAyLjA3NTQxNCwtMTcuMjEzNDUgNi4yMjM0NTQsLTIzLjg1MDMzIDExLjA5ODI5OCwtMTQuMzk3NDggNDEuMjg2NjM4LC0xLjc5NTA3IDQ1LjA3NTYwOSwyNC4zNDc2MiA0LjgzOTM5Miw2Ljc3NDkxIDguODQ5MzUsMTYuMjQ3MjkgMTIuMDI5NTE1LDI4LjQxNTYgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTQuNDc4MjUsLTUuOTI0NDggLTkuOTU0ODgsLTEwLjYzMjIyIC0xNS45MDgzNywtMTQuMzc0MTEgMS42NDA1NSwwLjQ3OTA1IDMuMTkwMzksMS4wMjM3NiA0LjYzODY1LDEuNjQwMjQgNi40OTg2MSwyLjYyNjA3IDEyLjE2NzkzLDcuMzI3NDcgMTcuMDA3MywxNC4xMDM0NSA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNSwxNi4yNDU2NyAxMi4wMjk1MiwyOC40MTM5NyAwLDAgOC40ODEyOCwtMC4xMjg5NCA4LjQ4OTc4LC0wLjAwMiAwLjQxNzc2LDYuNDE0OTQgLTEuNzUzMzksOS40NTI4NiAtNC4xMjM0MiwxMi41NjEwNCAtMi40MTc0LDMuMTY5NzggLTUuMTQ0ODYsNi43ODk3MyAtNC4wMDI3OCwxMy4wMDI5IDEuNTA3ODYsOC4yMDMxOCAxMC4xODM1NCwxMC41OTY0MiAxNC42MjE5NCw5LjMxMTU0IC0zLjMxODQyLC0wLjQ5OTExIC01LjMxODU1LC0xLjc0OTQ4IC01LjMxODU1LC0xLjc0OTQ4IDAsMCAxLjg3NjQ2LDAuOTk4NjggNS42NTExNywtMS4zNTk4MSAtMy4yNzY5NSwwLjk1NTcxIC0xMC43MDUyOSwtMC43OTczOCAtMTEuODAxMjUsLTYuNzYzMTMgLTAuOTU3NTIsLTUuMjA4NjEgMC45NDY1NCwtNy4yOTUxNCAzLjQwMTEzLC0xMC41MTQ4MiAyLjQ1NDYyLC0zLjIxOTY4IDUuMjg0MjYsLTYuOTU4MzEgNC42ODQzLC0xNC40ODgyNCBsIDAuMDAzLDAuMDAyIDguOTI2NzYsMCAwLC01NS45OTk2NyBjIC0xNS4wNzEyNSwtMy44NzE2OCAtMjcuNjUzMTQsLTYuMzYwNDIgLTM3Ljc0NjcxLC03LjQ2NTg2IC05Ljk1NTMxLC0xLjEwNzU1IC0yMC4xODgyMywtMS42NTk4MSAtMzAuNjk2NjEzLC0xLjY1OTgxIHogbSA3MC4zMjE2MDMsMTcuMzA4OTMgMC4yMzgwNSw0MC4zMDQ5IGMgMS4zMTgwOCwxLjIyNjY2IDIuNDM5NjUsMi4yNzgxNSAzLjM0MDgxLDMuMTA2MDIgNC44MzkzOSw2Ljc3NDkxIDguODQ5MzQsMTYuMjQ1NjYgMTIuMDI5NTEsMjguNDEzOTcgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTYuNjc3MzEsLTQuNTkzODEgLTE5LjgzNjQzLC0xMC40NzMwOSAtMzYuMTQwNzEsLTE1LjgyNTIyIHogbSAtMjguMTIwNDksNS42MDU1MSA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM3LC02LjQ2Njk3IC0xMy44NDY3OCwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NzA1LDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiBtIDE1LjIyMTk1LDI0LjAwODQ4IDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzgsLTYuNDY2OTcgLTEzLjg0Njc5LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDQsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gLTk5LjExMzg0LDIuMjA3NjQgOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzODIsLTYuNDY2OTcgLTEzLjg0Njc4MiwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NTQyLDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiIgLz4KPC9zdmc+CjwhLS0gVGhpcyB3b3JrIGlzIGxpY2Vuc2VkIHVuZGVyIGEgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIC0tPgo8IS0tIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMC8gLS0+Cg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"}
\ No newline at end of file
diff --git a/tgui/package.json b/tgui/package.json
index 007ee04ab9..52662139a6 100644
--- a/tgui/package.json
+++ b/tgui/package.json
@@ -22,7 +22,7 @@
"es3ify": "0.2.1",
"fg-loadcss": "1.0.0-0",
"fontfaceobserver": "1.6.3",
- "gulp": "github:gulpjs/gulp#4.0",
+ "gulp": "github:gulpjs/gulp#6d71a65",
"gulp-bytediff": "1.0.0",
"gulp-cssnano": "2.1.2",
"gulp-if": "2.0.0",
]